以前懒神在seraph论坛写过一篇海上技能的文章,思路大概就是根据已释放技能的数量变化来找内存地址。我今天试了一下,能找到技能数的最终内存地址,但偏移格式已经变了,无法逆推基址。那么今天再来重新找基址。
还是用搜索已释放技能的数量变化方法来找。也可以按照懒神已找出的技能ID变化来找,但万一技能ID变了咋办?所以还是用最原始的方法最好。
确定海上技能数内存地址
进游戏,出海,开CE。
- 海上先开满3个技能,CE搜索4字节未知初始数值。
- 停止1个技能,CE搜索数值减少了1
- 停止1个技能,CE搜索数值减少了1
- 停止1个技能,CE搜索数值减少了1
- 开启1个技能,CE搜索数值增加了1
- 重复上面几步,可找出唯一的地址
确定调用堆栈
对这个唯一的地址CE下什么改写地址。游戏里停止1个技能。
从00D406B3 dec dword ptr ds:[ecx+0xC] 往回追踪,找基址。
上面截图里ECX==0x063C4364,在CE里设置条件断点
减少技能,CE里中断下来。记录右下角的堆栈信息。记录堆栈是为了知道代码是如何一层一层调用CALL的。如果直接在x64dbg里逆推往回找比较麻烦,不如CE直观。
回溯代码
要从最终指令中的ECX回溯找基址。一步步回溯。换x64dbg。
记录和最终内存地址有关的寄存器改变指令。
1 2 3 4 5 | 00BA8A77 | 8B47 04 | mov eax,dword ptr ds:[edi+0x4] | 00BA8A80 | 8B30 | mov esi,dword ptr ds:[eax] | 00BA8A97 | 8B4E 04 | mov ecx,dword ptr ds:[esi+0x4] | breakif([[[esi+4]]+10]==0xBC0250) 调用 00D406B3 | FF49 0C | dec dword ptr ds:[ecx+0xC] | |
找到这里时,发现EDI的值是一个静态地址,红框处代码是一个循环。被循环绕晕了好一会,最后发现[EDI+4]+40地址的值就等于ESI的值。
这个12294B0地址的数据结构不做研究。
另外[EDI+4]+40地址是固定的,不会出现这次启动是[EDI+4]+40,下次就变成[EDI+4]+44。原因是程序源代码不变那地址就不变。比如:
1 2 3 | int a=10; int b=20; int c=30; |
不管变量的值如何改变,只要创建变量时abc的顺序不变,那么地址就不变。
技能的偏移格式
最后技能有关的偏移格式:
技能数:[[[[基址+4]+40]+4]+40]
技能1: [[[[基址+4]+40]+4]+C]
技能2: [[[[基址+4]+40]+4]+14]
技能3: [[[[基址+4]+40]+4]+1C]
技能4: [[[[基址+4]+40]+4]+24]
用CE扫描指针方法找基址
技能数也可以用CE扫描指针方法找基址,下面结果的第2个就和我手动跟踪的结果一样。
特征码
为了防止未来版本变更时,又要重头找一遍,提取特征码。直接在x64dbg里搜索特征码,定位到语句,下断点看一下edi的值就是基址。
特征码:8B 47 04 8D 9B 00 00 00 00 8B 30 85 F6 75 ?? 41 83 C0 04 3B CA
1 2 3 4 5 6 7 8 | 00BA8A77 | 8B47 04 | mov eax,dword ptr ds:[edi+0x4] | 00BA8A7A | 8D9B 00000000 | lea ebx,dword ptr ds:[ebx] | 00BA8A80 | 8B30 | mov esi,dword ptr ds:[eax] | 00BA8A82 | 85F6 | test esi,esi | 00BA8A84 | 75 0C | jne gvo12019.BA8A92 | 00BA8A86 | 41 | inc ecx | 00BA8A87 | 83C0 04 | add eax,0x4 | 00BA8A8A | 3BCA | cmp ecx,edx | |
文章评论
请问下我下send断的时候如何跳出线程到达真实的功能call那,我一直ctrl+F9 和F8最后都是在线程的循环里
@ct 用send找是很麻烦的,不会很轻易的追踪到。因为航海并不是每个CALL直接调用send,而是把所有要发的包丢到一个数据队列里,再由独立线程无限循环读取队列并发包。
多谢,那大佬能不能给个思路来追航海的call,例如组队,最近试了下用TAB的id来追点击组队call,但是追不出来,找到几个像的,但加了参数后注入都是失败
@ct TAB的ID追组队,可以在ID的内存地址上下访问断点,看谁访问ID,但这个方法需要过滤很多其他函数。或者追踪按钮。这里有一篇文章可以看看作为参考,我也是跟着这个思路学的https://bbs.kanxue.com/thread-212398.htm
@ct 我在内存找了个加载数据时鼠标形状变换的地址,然后断他向上翻一层来找到这个函数入口。后面就可以用这个函数入口下断点找到一系列call了。
好的多谢,我学习下,现在TAB+确认选中的call已经实现了,现在在追邀请组队的,我再学习下你推荐的文章
@Keo 居然还可以这样追,又增加了思路了,多谢