登录  | 立即注册

游客您好!登录后享受更多精彩

查看: 32|回复: 0

CALL参数的跟踪

[复制链接]

78

主题

2

回帖

103

积分

网站编辑

积分
103
发表于 4 天前 | 显示全部楼层 |阅读模式
多时候CALL里的一些数值,都是变化的,或者不同的电脑值也不一样,如何寻找这些值的基址呢?不同的值有不同的找法下面就列出几条常用的方法。

1.CE搜索

这个方法在我找CALL入门篇一中就有说过而且,很多篇章中都用过这种方法,例子:模拟器 游戏找CALL练习实例ONE


1.png
这里我们找的是EAX的值,EAX的值 是不同电脑他的值也是不同的。这个我在找CALL篇一中说过。
2.png


绿色的就是基址了, 如果搜出来没有绿色如何?可以用找血基址的方法找偏移,然后跟踪出他的基址。
2.代码分析
从汇编代码中顺藤摸瓜摸出基址,这个也是比较常用的方法。例子:CALL入门篇一
武易打坐
例子:
3.png
从上面我们要找EAX的值,才能得到CALL的地址,EAX是如何来的呢?这要往上寻找了
首先  我们找到的是 mov eax,[ecx]   这里 把ECX里的值 赋值给EAX  那么EAX的来源就确定了,但这还不是明确的地址,我们继续往上找
然后  到了mov ecx,[4fa818]    这里我们找到了 赋值给ECX的值  ,而且也是 明确的地址。(摸到瓜了)
好了  EAX的值就是   [4fa818]里的值  赋值给ECX   在从[ECX]里的值赋值给EAX
公式   [[4fa818]+0]   (读了2次基址)
3.CALL的返回值
如果你寻找某个寄存器的值,苦苦追了3层还追不到,那么你就要注意了,其实这个值可能就在你原来CALL的附近。
详细的请看 CALL提升篇一:剑侠3的喊话CALL分析后部分
4.子程序参数的跟踪
4.png
这个是 入门篇三中的模拟器代码, 我们要找EBX的值
从代码上可以很清楚的找到  EBX的值 是 [EBP+8] 中传入的,而EBP  确实从ESP传入,大家都知道ESP是堆栈指针的寄存器,是不断变化的,但如何取到这个值呢?
首先,我们要明白[EBP+*]  这种偏移的含义,  其实我前面也讲到过 这个就是 参数的值
5.png
这个子程序 被传入 包头 和 数据   2个参数,然后组合。
代码中  [ebp+8] 其实就等于  数据  值,  而[ebp+c]就是 包头的参数值(如果是ebp-*)这种类型 就是  临时变量
从这里我们可以看出,EBX的值 并不是系统里的,而是我们自己应该写入的参数堆栈值,固也无法跟踪了(因为这个值是需要你自己写入的)
这里有朋友可能要问了  如果我要写这个CALL 而不写上面那一层的CALL这里改如何写呢? 其实直接赋值就可以了, 比如说  PUSH [ebx]     这里如果需要传入40这个值 那么直接  PUSH 40便可,  (我在前面几篇中强调过,CALL只要传入适当的参数,便可以调用)这里适当的参数就是这层CALL所需要的参数数据,而不是傻傻的跟上去找原值。
这里 具体的可以看看 提升篇一   文章中后期 对寄存器值的跟踪过程
寄存器eax值的跟踪! R)Dh;XA  
FYH^axpp  
在调用约定里 所有CALL的返回值都是靠EAX返回的,如果EAX放不下就放在EDX里。如果返回的结果是文本类型的话就会返回一个指针地址。在游戏里,一般的功能CALL返回值很少有。
1~vv<`
-  
如 iO iXo6YE  
int myadd(int a, int b) :fQN_*B4@4  
{ *2Q x69`  
int c=a+b; e‑ r"gPW  
return c;  29NP!W /g  
} \$ :)Ka  
Pcr;+'q  
在反汇编的表现形式大概就是 vr$z6m
^  
[H>/N7v19*  
push ebp                        //寄存器环境保护 ‑ 3,Bm"'b6  
mov  ebp,esp              //将堆栈指针的值传给EBP用于开辟临时变量 %Z(lTvqG  
sub esp,4                  //开辟一个临时空间 也就是我们定义的临时变量C Y 4*?QBYA  
mov [esp-4],0            //将 c 初始化 也就是C=0 尽管我们没有写不过编译器会自动完成 {>l`P{{y  
mov eax,a                //将A放入寄存器EAX里 op|x~Thf  
add eax,b              //将EAX加上B w4Ku1G#jC  
mov [esp-4],eax              // 将计算结果保存到临时变量C k)JwCt.%  
mov eax,[esp-4]    //将保存结果的变量C传递到EAX n/IDq$[1]/P  
mov esp,ebp        //将堆栈指针恢复到调用CALL之前。
pop ebp              //将寄存器保存的值取出来。 9wv 7 HD|  
jI807g+  
retn ­P 4~C0z  
这个就是一个简单加法子程序的运行过程。所以很多时候我们跟踪一下自己写的程序,看看机器是如何运行你的代码的,这个是一件很有趣的事情,也会增加你对编程和汇编的了解。这里的反汇编代码是我手动写的可能和真正的有误差,但大概的过程是应该没有错的。 7 *HBb-  
所以很多人在跟踪寄存器EAX的时候往往会放过挨着的CALL指令,直接找上面的汇编代码。要看看EAX是否是一个CALL的返回值其实很简单,看看运行CALL指令后EAX的值是否有变化就可以了。
寄存器esp,ebp值的跟踪! i‑'$V'x'k  
上面说到 堆栈参数的传递,当参数压入到堆栈CALL的内部是如何读取的呢? o-))R| ~z  
很多朋友都看见过这样的寻址指令 mov ebx,[esp+1c]  这个时候很多朋友都去寻找赋值 ESP 相关的指令去了,但找了半天都没找到.其实这里直接指向了堆栈. ESP是一个特殊的寄存器,他永远指向了堆栈顶部.  I‑wfJDJJ  
所以一般轻易不会去变动这个值.  当 CPU 执行 PUSH指令时 ,ESP就会-4 然后把数据存放到当前ESP的地址里.这个时候如果读取刚刚压入的参数 就是 mov ,eax,[esp]  这样堆栈顶部的数据就会被读取. %q~YJ*\  
但是这个时候又压入一个数据呢?  压入的时候ESP会-4  那么 指向刚刚那个参数就是 mov ebx,[esp+4] ,co~@a@9  
如果压入了5个 要指向第一个参数 就是 [esp+10]  没错就是10  一个堆栈是4字节 4个就是16字节 16在16进制里就是10 Rd?8LLz[1]  
这里要说明的一下是 CALL指令也会压入一个数值.所以
PUSH EAX 3tO= [1]  
CALL ******** =N62 ){{  
在CALL内部指向 EAX 就是 [ESP+4]  这里其实压入了2个堆栈 ,一个是PUSH EAX  还有一个是CALL. r%c[1]raf  
临时参数的表达方式是 [ebp-*]  一般是在CALL头部把ESP的数值赋值到EBP  那么 EBP永远指向CALL头部时的堆栈指针,对于下面新增的堆栈就是 以减法表示 因为 压入一个堆栈ESP就会-4  .故[EBP-*]在反汇编里代表临时变量. sew0n`d1  






您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|断点社区 |网站地图

GMT+8, 2025-1-24 07:15 , Processed in 0.051874 second(s), 30 queries .

Powered by XiunoBBS

Copyright © 2001-2025, 断点社区.

快速回复 返回顶部 返回列表