1 找出动作数组的基址,里面包含攻击,为以后写自动打怪功能作准备。 我们先找到动作对象,可以先找到存放动作对象的地址,把动作拖起来应该是对象名,没拖起来是0
2 把动作点一下拖起来,搜增加的数值,放回去搜0,直到找到这两个地址,
10622250应该就是存放动作对象的地址。再多换几次动作,记录一下 动作对象的值
跑:2A5A8B78
运气:2698E718
攻击:2698EBA8
捡东西:2698EDF0
3 地址里的数值就是 动作对象。
然后我们要找动作数组的首地址。再搜它,找它的基址。找到4个,究竟哪个才是呢。
4 先浏览第一个的相关内存区域,可以,但不是。
5 浏览第二个的内存区域,不行
6 浏览第三个的内存区域,可以。而且发现这里总共有32*2+8=72个字节,72/4=18个动作对象。说明这里才是真正的动作数组。而309C4914正是动作数组的首地址。
7 浏览第四个的内存区域,可以,但不是。
8 我们现在已经找到动作数组的首地址了。现在要找它的基址。
我们要在OD中转到这个地址,给它下一个内存访问断点。
9 发现程序断在了此处,ecx来源于上面
10 我们给上面的语句下个CC断点,得到EDI=2685DC48
11 然后根据那个公式,dd ESI+43C+4*0转到相应的地址,看值是不是那18个对象。
很杯具,不是。这种情况可能是其它对象也从这里访问,导致我们这次没有找到那18个对象的地址。
12 然后我们dd 309C4914,再下一次内存访问断点,继续用上述方法,直到找到那个地址。
结果发现不管怎么试,它都会跑到这个地方
我们再看一下这次的EDI=309C68E0
13 dd 309C68E0+43C+4*0,发现还不是
14 保持这个CC断点,运行,又自动断下,看ESI,到内存窗口查看。反复几次,终于找到了这处有18个的。
公式为dd 309C44D8+43C+4*0。
那309C44D8就是我们要找的 动作对象数组的首地址 的 地址,就是不知道这个地址是不是基地址,是就直接拿来用,不是就还得继续找。
15 用CE搜一下不就知道是不是基地址了,这个数值不是绿色,所以它是普通地址。我们继续往下找,他的地址有两个是基址,那这两个总是有一个能用的了。问题来了,如何判断它是否能用呢?一般来说,我们可以在OD里进行常量搜索
比如说搜02E3DD58,找到了,那这个就可以用
再搜02E6B7A4,点完确定之后并没有跳转,说明代码没有调用过这个地址里的数据,不能用。
16 现在我们知道
309C44D8+43C+40 这个地址里装的是18个动作对象,或者说这个地址是动作数组对象的首地址
而02E3DD58是基址,[02E3DD58]=309C44D8
所以 动作数组对象的首地址,可以用含基址的表达式 表示为:[02E3DD58]+43C+40
17 接下来攻击动作对象 的 指针就可以偏移+8 找到,那么攻击动作对象 就是 2698EBA8
18 接下来找攻击CALL,它肯定要访问 攻击动作 对吧,而攻击动作对象就放在它的指针指向的地址。那我们对这个指针指向的地址按下F5
19 然后右击攻击按钮
00853AEE - 6A 01 - push 01
00853AF0 - E8 0B4AFBFF - call Client.exe+408500
00853AF5 - 8B 8C B7 3C040000 - mov ecx,[edi+esi4+0000043C] <<
00853AFC - 85 C9 - test ecx,ecx
00853AFE - 74 62 - je Client.exe+453B62
00854ED9 - 83 BF 34160000 35 - cmp dword ptr [edi+00001634],35
00854EE0 - 75 20 - jne Client.exe+454F02
00854EE2 - 8B 84 B7 3C040000 - mov eax,[edi+esi4+0000043C] <<
00854EE9 - 85 C0 - test eax,eax
00854EEB - 74 15 - je Client.exe+454F02
20 所以攻击CALL应该就在00853AF5 或 00854EE2 附近,用OD附加游戏,在此处下个断点,随便右击一个捡东西,断下,ESI=3,即下标为3
再运行,右击攻击,ESI=2,我们F8往下跟
21 找到了动作使用CALL,我们在传参前下个断点,
然后再右击攻击,看它具体传了哪些参数
这个mov ecx,31AD24F8 有点奇怪,看看里面装的是00AD3E8C,不知道是啥
再看看是什么装着31AD24F8,就是我们之前找的基址:02E3DD58,[02E3DD58]=31AD24F8
22 接下来用代码注入器来测试,执行成功,但没反应。EAX的值也很奇怪,说明不是,可能是这只是调用动作使用CALL前的一个小函数,用来作一些获取数据判断用的,我们还要再往下跟。
23 经过一番分析,下面的CALL 才是动作使用CALL
mov ebx,1
mov edi,02E3DD58
mov edi,[edi]
mov eax,[edi+43C+ebx*4]
mov ecx,[eax+54] //取动作ID 到ecx
mov edx,[0125456C]
push ecx //把 动作ID入栈
mov ecx,[edx+28C] //把 [0125456C]+28C 这个地址里的值给ecx
call 00714220 //调用函数的首地址
24 复制代码作为特征码
00854E9A 56 push esi
00854E9B 51 push ecx
00854E9C 89 95 38 mov dword ptr ss:[ebp-0x000050C8],edx
00854EA2 8B 15 6C mov edx,dword ptr ds:[Client.0125456C]
00854EA8 8D 8D 38 lea ecx,dword ptr ss:[ebp-0x000050C8]
00854EAE C7 85 3C mov dword ptr ss:[ebp-0x000050C4],0x00000000
00854EB8 51 push ecx
00854EB9 8B 8A 94 mov ecx,dword ptr ds:[edx+0x00000294]
00854EBF E8 EC E9 call Client.007A38B0
00854EC4 E9 B5 00 jmp Client.00854F7E
00854EC9 8B 87 60 mov eax,dword ptr ds:[edi+0x00001C60]
00854ECF 56 push esi ;下标
00854ED0 51 push ecx ;35
00854ED1 50 push eax ;5
00854ED2 8B CF mov ecx,edi ;[动作数组基址]
00854ED4 E8 C7 3F call Client.00838EA0 ;动作使用CALL No
00854ED9 83 BF 34 cmp dword ptr ds:[edi+0x00001634],0x35
00854EE0 75 20 jne Client.00854F02
00854EE2 8B 84 B7 mov eax,dword ptr ds:[edi+esi4+0x0000043C] ;取出动作对象给eax
00854EE9 85 C0 test eax,eax ;看eax是否为0
00854EEB 74 15 je Client.00854F02 ;为0则跳过下面这个CALL
00854EED 8B 48 54 mov ecx,dword ptr ds:[eax+0x54]
00854EF0 8B 15 6C mov edx,dword ptr ds:[Client.0125456C]
00854EF6 51 push ecx ;007A1202
00854EF7 8B 8A 8C mov ecx,dword ptr ds:[edx+0x0000028C] ;ds:[266EE8FC]=215E1128
00854EFD E8 1E F3 call Client.00714220 ;动作使用CALL YES
00854F02 83 BF 34 cmp dword ptr ds:[edi+0x00001634],0x36
00854F09 75 20 jne Client.00854F2B
00854F0B 8B 84 B7 mov eax,dword ptr ds:[edi+esi4+0x0000043C]
00854F12 85 C0 test eax,eax
00854F14 74 15 je Client.00854F2B