遗失记忆 发表于 2013-1-10 19:22:19

c++特征码搜索函数

模块 - Game
005FC930/$55                     push ebp
005FC931|.8BEC                     mov ebp,esp
005FC933|.51                     push ecx
005FC934|.56                     push esi
005FC935|.8BF1                     mov esi,ecx
005FC937|.8D86 EC000000            lea eax,dword ptr ds:
005FC93D|.50                     push eax
005FC93E|.8D4E 34                  lea ecx,dword ptr ds:
005FC941|.E8 AAC20600            call Game.00668BF0
005FC946|.50                     push eax
005FC947|.E8 A6F51600            call Game.0076BEF2            
005FC94C|.85C0                     test eax,eax
005FC94E|.74 6D                  je XGame.005FC9BD
005FC950|.83BE 3C040000 01         cmp dword ptr ds:,0x1
005FC957|.75 2B                  jnz XGame.005FC984
005FC959|.8B0D 4CF72501            mov ecx,dword ptr ds:
005FC95F|.8B41 30                  mov eax,dword ptr ds:
005FC962|.8B96 44040000            mov edx,dword ptr ds:
005FC968|.50                     push eax


假设特征码是绿色框部分
005FC933|.51                     push ecx
005FC934|.56                     push esi
005FC935|.8BF1                     mov esi,ecx
005FC937|.8D86 EC000000            lea eax,dword ptr ds:
005FC93D|.50                     push eax
005FC93E|.8D4E 34                  lea ecx,dword ptr ds:

char* opcode="51568BF18D86EC000000508D4E34" // 第二列连起来

要查找红色框内容:
005FC930/$55                     push ebp
即一个内存地址,也是函数的首地址,所以使用ScanAddr
先计算出目标到opcode首地址的偏移
005FC933 - 005FC930 = 0x3 因为目标是在opcode上面 所以是-0x3
调用 ScanAddr(process, opcode, -0x3); 就能获得


要查找黄色框内容:
005FC947|.E8 A6F51600            call Game.0076BEF2
即一个调用call,使用ScanCall
同样要计算出目标地址到opcode的首地址偏移
首先这里目标0076BEF2的地址为 005FC947+1 因为call指令也占用了一个字节的内存
所以偏移 = 005FC948 - 005FC933 = 0x15 因为目标在opcode下面 所以是正的
(这里谁减谁不重要,主要看目标是在opcode之上还是下)
调用 ScanCall(process, opcode, 0x15)


要查找蓝色框的内容:
005FC959|.8B0D 4CF72501            mov ecx,dword ptr ds:
即一个立即数,也是一个基址,使用ScanImme
计算目标地址:005FC959 + 2 = 005FC95B
计算偏移:005FC95B - 005FC933 = 0x28 正值
调用 ScanImme(process, opcode, 0x28)

一般情况下使用前面3个参数就可以了

基础函数:
/************************************************************************/
/* 函数说明:查找特征码
/* process: 要查找的进程
/* markCode: 特征码字符串,不能有空格
/* distinct:特征码首地址离目标地址的距离 负数在特征码在上
/* offset: 返回目标地址
/* size: 设置返回数据为几个BYTE 1 2 3 4
/* ordinal: 特征码出现的次数
/* beginAddr: 开始搜索地址
/* endAddr: 结束地址
/* ret:返回目标地址的内容
/************************************************************************/
DWORD ScanOpcode(HANDLE process, const char *markCode,
                  int distinct,
                  LPDWORD offset = NULL,
                  DWORD size = 4,
                  DWORD ordinal = 1,
                  DWORD beginAddr = 0x00400000, DWORD endAddr = 0x7FFFFFFF);

使用后面参数的情况:

size:
如果想查找白色框的内容0x1
005FC950|.83BE 3C040000 01         cmp dword ptr ds:,0x1
要设置 size=1 因为他在内存只占了一个字节

ordinal:
在你确定一个特征码时
使用Ctrl+s,Ctrl+l在OD中搜索这个特征码,假设他是第3次出现才是正确的位置
设置 ordinal=3

beginAddr,endAddr:
如果模块Game是一个dll,而你想从这个dll的基址开始搜索
设置 beginAddr = GetModuleHandle('Game')
当然也可以给他俩赋值任何可读地址
ordinal和beginAddr可以配合使用

**** Hidden Message *****

xdsci_00001 发表于 2013-5-15 13:57:07

学习VC技术

panshengbest 发表于 2013-6-3 22:48:32

回复 1# 遗失记忆


    学习VC的特征码是必须的

xdsci_000001 发表于 2013-7-23 14:22:37

学习一下,谢谢共享

blgz0410 发表于 2013-9-24 21:59:03

beginAddr,endAddr:
如果模块Game是一个dll,而你想从这个dll的基址开始搜索
设置 beginAddr = GetModuleHandle('Game')
当然也可以给他俩赋值任何可读地

waitoo 发表于 2014-3-19 09:09:53

看看!!!!!!!

jzsh 发表于 2014-4-21 09:53:20

看看喽!!!!!!!

compagis 发表于 2014-5-3 13:06:52

回复 1# 遗失记忆


    是打发士大夫斯蒂芬

xing19881104 发表于 2014-8-1 21:55:36

回复 1# 遗失记忆


    仍玩儿仍仍仍

洗洗睡啦 发表于 2015-5-5 15:54:29

看看你学的
页: [1] 2 3 4 5 6 7
查看完整版本: c++特征码搜索函数