A-new 发表于 2017-12-28 18:53

利用TitanEngine简单制作补丁

本帖最后由 A-new 于 2019-1-10 18:04 编辑

这个源于@mohao 的一个求助帖https://www.52pojie.cn/thread-649625-1-1.html
mohao想做一下它的内存注册机,不过网上常用的几款内存注册机工具都有局限性,不能在特定模块下断点读取注册码,也就是只能在主程序exe中读取注册码(也可能是我能力有限不会用),而帖子中提到的软件注册码出现在regcode.dll中,所以就有了此文,在此先感谢一下@Kido 牛,早些时候指导偶学会使用TitanEngine,扯多了开始正题吧
求助帖中软件获取注册码步骤仅需三步
1、主程序加了UPX,下断点到OEP
01BCCECC    FFD5            call    ebp
01BCCECE    58            pop   eax
01BCCECF    61            popad
01BCCED0    8D4424 80       lea   eax, dword ptr
01BCCED4    6A 00         push    0x0
01BCCED6    39C4            cmp   esp, eax
01BCCED8^ 75 FA         jnz   short 01BCCED4
01BCCEDA    83EC 80         sub   esp, -0x80
01BCCEDD- E9 78B8E0FE   jmp   009D875A                         ; 跳到OEP此处下断
01BCCEE2    0000            add   byte ptr , al


2、加载regcode.dll处下断点
010F5FA2    89A5 E4FEFFFF   mov   dword ptr , esp
010F5FA8    68 30C75D01   push    015DC730                         ; \RegCode.dll
010F5FAD    68 A4FB7D01   push    017DFBA4
010F5FB2    51            push    ecx
010F5FB3    E8 A8D532FF   call    00423560
010F5FB8    83C4 0C         add   esp, 0xC
010F5FBB    E8 50A50C00   call    011C0510
010F5FC0    83C4 04         add   esp, 0x4
010F5FC3    84C0            test    al, al
010F5FC5    0F84 92020000   je      010F625D
010F5FCB    68 30C75D01   push    015DC730                         ; \RegCode.dll
010F5FD0    8D95 E0FEFFFF   lea   edx, dword ptr
010F5FD6    68 A4FB7D01   push    017DFBA4
010F5FDB    52            push    edx
010F5FDC    E8 7FD532FF   call    00423560
010F5FE1    8B00            mov   eax, dword ptr
010F5FE3    83C4 0C         add   esp, 0xC
010F5FE6    50            push    eax
010F5FE7    FF15 94254A01   call    dword ptr             ; kernel32.LoadLibraryW
010F5FED    8BF0            mov   esi, eax                         ; 加载RegCode.dll完毕,此处下断点


3、RegCode.dll出现注册码的地方下断点
6F831281    85C9            test    ecx, ecx
6F831283    75 0A         jnz   short 6F83128F
6F831285    68 05400080   push    0x80004005
6F83128A    E8 910A0000   call    6F831D20
6F83128F    8B5D E4         mov   ebx, dword ptr
6F831292    50            push    eax
6F831293    53            push    ebx
6F831294    E8 885D0F00   call    6F927021
6F831299    83C4 08         add   esp, 0x8                         ; 注册码出现在ebx,此处下断点


具体如何找到此处自己慢慢找,不是本文讨论重点
关键部分
写注册机
TitanEngine的基本流程
初始化InitDebug
The InitDebug function is used to initialize the debugging process. This function is always used first and
it is creating a process which will be debugged.
然后开始调试流程DebugLoop
DebugLoop starts the debugging process. Always call this function or DebugLoopEx after initializing the
debugger with one of the initialization functions. Set at least one breakpoint before running the
debugged or the application whose process is being debugged will run. DebugLoop will not return until
the debugger is finished and the debugged application has been terminated.
初始化一般用InitDebugEx
void* __stdcall InitDebug(
char* szFileName,//调试文件
char* szCommandLine,//启动参数
char* szCurrentFolder,//调试进程工作路径
LPVOID EntryCallBack //回调函数
);
Return value
If it succeeds, InitDebugEx returns a pointer to a PROCESS_INFORMATION structure, otherwise
it returns NULL.
详细的自己查阅TitanEngine的SDK,这里就不一个一个复制粘贴了
这里就不多介绍了就几行代码注释也算比较详细了
#include <Windows.h>
#include "direct.h"
#include "TitanEngine.h"
#pragma comment (lib, "TitanEngine.lib")

////////////////////////////////////////////////////////
///////////////////全局变量/////////////////////////////
char *FileName,*CmdLine,*CurrentPath,*RegCode;
PE32Struct peInfo;
LPPROCESS_INFORMATION pInfo;
DWORD Upxbrk;
DWORD LoadDllbrk;
DWORD Dllbrk;
////////////////////////////////////////////////////////
////////////////////函数定义////////////////////////////

void init();                        //初始化
void GetRegCode();
void SetupDebug();
void cbSetupDebug();      //初始化回调函数设置0x01BCCEDD处断点
void cbLoadDll();                //UPX跳转OEP处回调函数设置0x010F5FED 处加载RegCode.dll断点
void cbDllbrk();                //设置RegCode.dll 0x6F831299 处注册码出现处断点
void cbGetRegCode();      //读取注册码

int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in LPSTR lpCmdLine, __in int nShowCmd )
{
      GetRegCode();
      return 0;
}

void GetRegCode()
{
      init();
      SetupDebug();
}

void SetupDebug()
{
      pInfo = (LPPROCESS_INFORMATION)InitDebugEx(FileName,CmdLine,CurrentPath,cbSetupDebug);
      DebugLoop();
}

void init()
{
      FileName = (char *)malloc(MAX_PATH);
      CmdLine = (char *)malloc(MAX_PATH);
      CurrentPath = (char *)malloc(MAX_PATH);
      memset(FileName,0,MAX_PATH);
      memset(CmdLine,0,MAX_PATH);
      memset(CurrentPath,0,MAX_PATH);
      CurrentPath = _getcwd(NULL,0);
      strcpy_s(FileName,MAX_PATH,CurrentPath);
      strcat(FileName,"\\SjmsCAD.exe");
}
void cbLoadDll()
{
      LoadDllbrk = (DWORD)GetDebuggedFileBaseAddress();      //基址
      LoadDllbrk += 0x00CF5FED;
      SetBPX(LoadDllbrk,UE_BREAKPOINT_TYPE_INT3,cbDllbrk);
}
void cbDllbrk()
{
      Dllbrk = GetContextData(UE_EAX);//基址
      Dllbrk += 0x1299;
      SetBPX(Dllbrk,UE_BREAKPOINT_TYPE_INT3,cbGetRegCode);
}

void cbGetRegCode()
{
      RegCode = (char *)malloc(MAX_PATH);
      memset(RegCode,0,MAX_PATH);
      GetRemoteString(pInfo->hProcess,(LPVOID)GetContextData(UE_EBX),RegCode,256);      //读取注册码
      RemoveAllBreakPoints(UE_OPTION_REMOVEALL);      //清除所有断点
      DetachDebuggerEx(pInfo->dwProcessId);                //剥离进程
      StopDebug();                                                                //结束调试
      MessageBoxA(NULL,RegCode,"SN",MB_OK);
}

void cbSetupDebug()
{
      Upxbrk += (DWORD)GetDebuggedFileBaseAddress();      //基址
      Upxbrk += 0x017CCEDD;
      SetBPX(Upxbrk,UE_BREAKPOINT_TYPE_INT3,cbLoadDll);      //设置断点
}

代码比较挫,能用就好
TitanEngine建议用x64dbg的pluginsdk中的
TitanEngine SDK文档在原版:TitanEngine v. 2.0.3
link:https://www.reversinglabs.com/open-source/titanengine

x64dbg用的版本修正了原版的一些bug等,其实可以直接使用x64dbg里的X64dbg\pluginsdk\TitanEngine就好了
https://bitbucket.org/titanengineupdate/titanengine-update
源码打包

Catshark 发表于 2017-12-30 17:33

six six six

A-new 发表于 2019-1-10 17:47

springwillow 发表于 2019-1-10 08:02
loadlibrary

菜鸟而已,如果要对系统函数下断点,应该有两种方法
方法一:

是断在引用处比如00403E50|.E8 AFFCFFFF   CALL    <JMP.&kernel32.LoadLibraryW>   ; \LoadLibraryW


或者
00403B04   $- FF25 74714000 JMP   NEAR DWORD PTR DS:[<&kernel32.Lo>;kernel32.LoadLibraryW


00407174 >754E481Bkernel32.LoadLibraryW

这种的话你可以先获取LoadLibraryW的函数地址(754E481B)然后搜索这个地址找到(00407174 )再根据(00407174 )找到call或者jmp引用的地址下断,这种的话需要输入表中有这个函数才有用。
方法二:

直接获取LoadLibraryW的函数地址(754E481B),然后直接对这个地址下断点。这种方法未测试过。

方法一,根据之前的代码,方法一麻烦点,如果他是导入函数,应该是可用的,你可以测试反馈一下,偶很少写代码,只做原理性研究

yuanmengxiaozi 发表于 2017-12-28 19:26

前排沙发第一位,支持楼主

pxhb 发表于 2017-12-28 19:41

感谢分享

xlxxb 发表于 2017-12-28 19:48

谢谢分享{:1_893:}

苏紫方璇 发表于 2017-12-28 20:36

支持下A牛大神,以前我用过这种方法

zchpojie 发表于 2017-12-28 20:37

看不懂,但是支持

DCO 发表于 2017-12-28 23:09

前排膜拜A牛

mohao 发表于 2017-12-29 00:02

谢谢版主,但那个内存补丁怎么用的啊?

mygod123 发表于 2017-12-29 08:29

感谢分享

xiangniao10 发表于 2017-12-29 08:46

论坛里的大神真多,学习中
页: [1] 2 3 4
查看完整版本: 利用TitanEngine简单制作补丁