天道酬勤 发表于 2025-3-22 12:07:19

CALL返回值的应用

*CALL返回值首先考虑的是 EAX:EDX,在这里我就不班门弄斧了.详情请问百度,或者参考一些相关的书籍如 看雪出版的 加密与解密第三版等等.

*其实CALL返回值的应用在,CALL提升篇中找剑侠3喊话CALL的时候就应用到过.
目标:剑侠3血值基址的寻找
目的:找到血值基址的产生,来达到理解CALL返回值的应用.





打怪去掉一点血,我们来搜索减少的血值

好了 这里第一个就是我们要找的值,不过现在是动态的我们要找他的基址

查找写入的值,然后打怪去掉一点血.监视窗口便会出现 一条写入信息 EAX+184 便是血的地址我们要找EAX的值

我们来搜下 EAX的值,发现搜出3W多个来,没办法只好用OD来找,先把CE在加载游戏一次,因为刚刚监视血值的时候注入了CE的DLL所以,不在加载一次卸载的话 OD是无法注入的


重新加载一次

图中下段的地方, 就是刚刚找血值代码的地方,这里EDX里是血的值.而EAX+184 则是血的地址.

图中EDX=135 是血的16进制.而EAX则是我们要找的地址

如何找EAX的值呢?我们先来看看他啥时候开始变化的,我们断了几次发现EAX的值并没有发生改变


我们现在头部下段,去打怪让血发生变化,然后断下来了

这里有个对比EAX,如果不为0则跳转.

好了,我们开始来找EAX的值,我们先记下EAX的值(这里跟你的不同) EAX=FBB0C8

在头部下段后,去打个怪 去血 然后断在头部了, 这个时候我们发现EAX的值并不=FBB0C8


我们按F8 一直运行一直这里 运行这个CALL后 EAX发生了改变.变成了FBB0C8
然后加上偏移 184 便是我们要找的血偏移

首先来看所有的调用规范都遵循的规定:返回值存储在EAX:EDX中,如果EAX放不下会放到EDX里
而上面的CALL便是 基址的计算CALL 然后返回 基址信息 存放在EAX里.

========================CALL的分析====================

一,先处理堆栈

      这里堆栈只有一个所以我们只需要写一个就可以了
push ecx
call 4265b0

二,堆栈中寄存器值的处理

      这里ECX的值往上找是 赋给他的.而EAX的值则是读取了51f1b8这个基址
mov eax,
mov ecx,
push ecx
call 4265b0

三,寄存器的处理


图中 灰色的寄存器是 寄存器环境的保护.对应下面的POP.
其实这里也是调用约定的范畴.

红色的是需要传入的值,而ESI则是 由ECX传入.所以我们只需要给ECX传值就可以了

这里只有一条 lea    ecx, dword ptr EAX 的值 已经赋值了
      
mov eax,
mov ecx,
push ecx
lea ecx,
call 4265b0

四,内存指针地址的处理
    这里没有往内存里写的代码所以略过
五,堆栈的处理

    这里CALL下面没有 堆栈处理.所以可以略过.


=================================分析结束========================

好了 根据调用约定 返回的值一般都放在EAX里 ,而刚刚的跟踪也说明了这一点.

所以我们返回EAX的值加上偏移就等于 血的地址

mov eax,
mov ecx,
push ecx
lea ecx,
call 4265b0
add eax,184      '加上184的偏移 相当于 EAX+184
mov eax,      '读取EAX里的值

好了 血的值就已经读出来了 ,现在我们用CE开辟一个空的地址 来存放血值

用CE搜0 的值 等CE的搜索按钮能暂停了 立马暂停 然后随便选一个地址

这里我们选的是50f09c


mov eax,
mov ecx,
push ecx
lea ecx,
call 4265b0
add eax,184
mov eax,
mov ,eax      '往50f09c的指针地址里写入血的值


我们来看看运行的效果


好了,值我们已经读出来了,如果这里我们转换地图或者等其他操作 不会改变基址的时候,那么我们在程序里只要读一次就够了

xxxxbzn1 发表于 2025-3-23 10:47:38

膜拜神贴,后面的请保持队形~
页: [1]
查看完整版本: CALL返回值的应用