- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
模块 - 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:[esi+0xEC]
005FC93D |. 50 push eax
005FC93E |. 8D4E 34 lea ecx,dword ptr ds:[esi+0x34]
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:[esi+0x43C],0x1
005FC957 |. 75 2B jnz XGame.005FC984
005FC959 |. 8B0D 4CF72501 mov ecx,dword ptr ds:[0x125F74C]
005FC95F |. 8B41 30 mov eax,dword ptr ds:[ecx+0x30]
005FC962 |. 8B96 44040000 mov edx,dword ptr ds:[esi+0x444]
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:[esi+0xEC]
005FC93D |. 50 push eax
005FC93E |. 8D4E 34 lea ecx,dword ptr ds:[esi+0x34]
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:[0x125F74C]
即一个立即数,也是一个基址,使用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:[esi+0x43C],0x1
要设置 size=1 因为他在内存只占了一个字节
ordinal:
在你确定一个特征码时
使用Ctrl+s,Ctrl+l在OD中搜索这个特征码,假设他是第3次出现才是正确的位置
设置 ordinal=3
beginAddr,endAddr:
如果模块Game是一个dll,而你想从这个dll的基址开始搜索
设置 beginAddr = GetModuleHandle('Game')
当然也可以给他俩赋值任何可读地址
ordinal和beginAddr可以配合使用
|
|