windows游戏调试之QQHX角色属性分析

前言

技术交流,请勿非法用途!

由于call分析得烂,所以就分析一下角色属性,不知道后面能不能把call分析出来。

开始

WndMgr.dll+55EBA - DB 45 F0              - fild dword ptr [ebp-10]
WndMgr.dll+55EBD - 8B 45 F8              - mov eax,[ebp-08]
WndMgr.dll+55EC0 - 2B 45 F0              - sub eax,[ebp-10]
WndMgr.dll+55EC3 - 89 45 C8              - mov [ebp-38],eax
WndMgr.dll+55EC6 - DB 45 C8              - fild dword ptr [ebp-38]
WndMgr.dll+55EC9 - 8B 4D CC              - mov ecx,[ebp-34]
WndMgr.dll+55ECC - 8B 55 CC              - mov edx,[ebp-34]
WndMgr.dll+55ECF - 8B 41 6C              - mov eax,[ecx+6C]
WndMgr.dll+55ED2 - 2B 42 64              - sub eax,[edx+64]
WndMgr.dll+55ED5 - 89 45 C4              - mov [ebp-3C],eax
WndMgr.dll+55ED8 - DB 45 C4              - fild dword ptr [ebp-3C]
WndMgr.dll+55EDB - 8B 4D CC              - mov ecx,[ebp-34]
WndMgr.dll+55EDE - 8B 55 CC              - mov edx,[ebp-34]
WndMgr.dll+55EE1 - 8B 41 68              - mov eax,[ecx+68]
WndMgr.dll+55EE4 - 2B 42 64              - sub eax,[edx+64]
WndMgr.dll+55EE7 - 89 45 C0              - mov [ebp-40],eax
WndMgr.dll+55EEA - DB 45 C0              - fild dword ptr [ebp-40]

上面是代码中WndMgr.dll+55ECF - 8B 41 6C - mov eax,[ecx+6C]就是访问地址。
我们在sub eax,[edx+64]下条件断点eax==蓝值的十六进制。用OD断直接游戏异常,然后发现OD采用的异常断点。
我直接用CE断,软断,硬断都没事。然后查看eax的值进行放行。
后来查看ecx的来源的时候发现,ecx来自ebp,ebp来自esp。
这个要往上层函数追,我追了一会发现是从堆栈中取的值(工作量有点大)我就没有分析了。
就直接用ce指针扫描工具扫描指针。过滤就把它扫出来了。

image
我们把对象计算出来了,我们就搜索这个对象。
[ecx+6C]就是当前蓝的地址,然后我们-6C就拿到ecx的地址,这样我们就拿到对象地址了。


搜索出来小的地址一般都是堆栈。(还是要具体分析)
这里就两个地址,所以都看下访问。

2076813F:
2076813A - 6A 00 - push 00
2076813C - 8B 45 E8 - mov eax,[ebp-18]
2076813F - 8B 88 14010000 - mov ecx,[eax+00000114] <<
20768145 - E8 44DAFDFF - call 20745B8E
2076814A - 6A 09 - push 09

然后谁访问了这个地址。我们得到一个114的偏移。把上面的记下来

2076812E - 8B 45 08              - mov eax,[ebp+08]
20768131 - 8B 10                 - mov edx,[eax]
20768133 - 8B 4D 08              - mov ecx,[ebp+08]
20768136 - FF 52 64              - call dword ptr [edx+64]
20768139 - 50                    - push eax
2076813A - 6A 00                 - push 00 { 0 }
2076813C - 8B 45 E8              - mov eax,[ebp-18]
2076813F - 8B 88 14010000        - mov ecx,[eax+00000114]
20768145 - E8 44DAFDFF           - call 20745B8E
2076814A - 6A 09                 - push 09 { 9 }
2076814C - 8B 4D 08              - mov ecx,[ebp+08]
2076814F - 8B 11                 - mov edx,[ecx]
20768151 - 8B 4D 08              - mov ecx,[ebp+08]

看了下反汇编,发现eax来自于上面一个call,然后这个需要分析call的参数和调用这个call,有点麻烦,没有分析。

1002A30D:
1002A305 - 8D 4D E8  - lea ecx,[ebp-18]
1002A308 - E8 2311FEFF - call 1000B430
1002A30D - 8B 10  - mov edx,[eax] <<
1002A30F - 89 55 D8  - mov [ebp-28],edx
1002A312 - 8B 45 D8  - mov eax,[ebp-28]

另外一个地址我们直接拿到一个call,call 1000B430这个call的返回值[eax],又懒的分析参数,没有继续分析。

typedef struct T角色属性
{
.....
DWORD 力量,
DWORD 体质,    +4
DWORD 敏捷,    +8
DWORD 智力,    +C
DWORD 精神    +10
.....
}

力量,体质,智力,精神,敏捷(这是我们在游戏中至上而下的顺序)
3,42,3,48,76 //十进制
3,2a,3,30,4c //十六进制 0…255
3,0,2a,0,3,0,30,0,4c,0 //2字节
3,0,0,0,2a,0,0,0,3,0,0,0,30,0,0,0,4c,0,0,0 //4字节
力量,体质,敏捷,智力,精神(但是在内存中是这样的)
3,42,76,3,48 //十进制
3,2a,4c,3,30 //十六进制 0…255
3,0,2a,0,4c,0,3,0,30,0 //2字节
3,0,0,0,2a,0,0,0,4c,0,0,0,3,0,0,0,30,0,0,0 //4字节

这个顺序我是之前搜索过一次,搜索到临时得才知道它得格式得,所以可以临时搜索一下。

总结一下,我们对搜索到的蓝地址,进行访问然后查看第一个偏移,然后使用指针扫描工具扫描这个地址,过滤掉最后偏移是我们查看到的那个,这个大概率就是我们要找的基址。

然后要记得多重启几次游戏。

而且偏移一定要取小的,因为小就代表近,近就不容易出错。


没有结果。
image

image
这样我们就搜出来结果了。看下地址,小的地址一般都不是,要找和角色对象比较近的。

之前分析的时候发现这个有一个临时存储属性的内存,所以就215F4141这个离角色对象最近,应该就是它了
image
我们对地址进行访问,我们分析到三行。

ThingClient.dll+804A - E9 A7040000           - jmp ThingClient.dll+84F6
ThingClient.dll+804F - 6A 04                 - push 04 { 00000004 }
ThingClient.dll+8051 - 8B 4D E0              - mov ecx,[ebp-20]
ThingClient.dll+8054 - 81 C1 B0040000        - add ecx,000004B0 { 1200 }
ThingClient.dll+805A - E8 100B0300           - call ThingClient.dll+38B6F
ThingClient.dll+805F - E9 92040000           - jmp ThingClient.dll+84F6
ThingClient.dll+8064 - 8B 55 E0              - mov edx,[ebp-20]
ThingClient.dll+8067 - 8B 42 4D              - mov eax,[edx+4D]
ThingClient.dll+806A - E9 87040000           - jmp ThingClient.dll+84F6
ThingClient.dll+806F - 8B 45 E0              - mov eax,[ebp-20]
ThingClient.dll+8072 - 8B 40 51              - mov eax,[eax+51]
ThingClient.dll+8075 - E9 7C040000           - jmp ThingClient.dll+84F6
ThingClient.dll+807A - 8B 4D E0              - mov ecx,[ebp-20]
ThingClient.dll+807D - 8B 41 79              - mov eax,[ecx+79]
ThingClient.dll+8080 - E9 71040000           - jmp ThingClient.dll+84F6
ThingClient.dll+8085 - 8B 55 E0              - mov edx,[ebp-20]
ThingClient.dll+8088 - 8B 42 7D              - mov eax,[edx+7D]
ThingClient.dll+808B - E9 66040000           - jmp ThingClient.dll+84F6
ThingClient.dll+8090 - 8B 45 E0              - mov eax,[ebp-20]
ThingClient.dll+8093 - 8B 80 81000000        - mov eax,[eax+00000081]
ThingClient.dll+8099 - E9 58040000           - jmp ThingClient.dll+84F6
ThingClient.dll+809E - 8B 4D E0              - mov ecx,[ebp-20]
ThingClient.dll+80A1 - 8B 81 85000000        - mov eax,[ecx+00000085]
ThingClient.dll+80A7 - E9 4A040000           - jmp ThingClient.dll+84F6
20BA8088:
20BA8080 - E9 71040000 - jmp ThingClient.dll+84F6
20BA8085 - 8B 55 E0  - mov edx,[ebp-20]
20BA8088 - 8B 42 7D  - mov eax,[edx+7D] <<215F40C8+7d
20BA808B - E9 66040000 - jmp ThingClient.dll+84F6
20BA8090 - 8B 45 E0  - mov eax,[ebp-20]
EAX=0000002A
EBX=0040BDBB
ECX=00000008
EDX=215F40C8
ESI=004908C4
EDI=00000100
ESP=0019E710
EBP=0019E744
EIP=20BA808B

我们ce搜索一下这个值EDX=215F40C8。


我们把其实位置设置成对象地址,在搜索,第一个离得近得就是。
image
计算出偏移。
[[[“Controller.dll”+00056218]+30]+0]+8]+18]+228+7d
为什么要选偏移小得?

因为可能在我当前这台电脑可以用,可能换一台电脑就不行了。这个偏移有可能发生变化得,它没有这个小偏移这个稳定。
image
我计算出来到体质了,力量+4的位置,所以要从访问地址的第一个计算应该就是力量了。

等级[[[“Controller.dll”+00056218]+30]+0]+8]+18]+228+50


这个改了过后要从新打开窗口才会刷新。