悬念 发表于 2014-5-24 11:16:51

CALL的概念篇:堆栈的平衡(一)

*堆栈平衡 是一个很重要的东西,其实说白了也没有什么,只要自己反汇编看看执行过程中的变化 便能了解的一清二楚.
* 这章需要知道一些简单的汇编知识 ,比如说 EIP的作用 ESP的概念 这些我就不详细多说了,想要学习的请看 王爽老师的 汇编语言 非常经典的一本书

此次例子以武易打坐CALL为例
===========================开始分析============================

这个就是打坐CALL的原型 和 代码 当然了 这个寄存器的值是动态的,因为是做堆栈平衡的所以我们没有找基址,可能跟你的值会不一样.

这里是 打坐CALL的内部

我们来用 加了堆栈平衡 和没加堆栈平衡的 CALL分别调用看看 他们的堆栈 和寄存器的变化


这里是CALL内部中 头部 和尾部的 变化, 我们发现并没有任何的不同,看来 堆栈平衡跟CALL内部无关


这里不一样了, 我们发现, 有堆栈平衡的代码 里 多了一行 add esp,4
而执行到 RETN 时候 栈顶 也各不相同

当CPU 执行完 add esp,4 后就把栈顶的第一行挤出 堆栈.
而没有处理过堆栈平衡的 则跳转到了 9EC8950 这里

我们来看看这个正确指向代码地址的值是从哪里来的


图中9EC8818 是我们代码中PUSH进去的值
80f000a 则是 跳出这个CALL返回时候 所跳转的代码地址 当执行retn的时候 EIP指向这里
7C80B729 则是 跳出去以后 执行retn 时候 所指向的 代码地址.

如果 我们把 第一个堆栈 80f000a 换成 7c80b729 会如何?

呵呵 调用成功 也没有出错, 这是因为 在最后 执行retn的时候 我们帮他指向了 正确的 地址,当然了 也不是所有游戏都可以这样弄的,有些游戏压入的数值不是随意便可以CALL成功的.


好了 从上面的例子 可以看出 堆栈平衡其实就是 帮助 EIP 指向 正确的 地址, 如果你压入一个0 而不做堆栈平衡处理 那么 执行完后 EIP便会 执行 0 这个代码地址.说白了,堆栈平衡处理就是把压入的数值的空间去删去.因为ESP永远指向栈顶,RETN永远执行跳转到 栈顶的地址.

Forever" 发表于 2014-7-2 13:26:27

学习了,谢谢分享、、、

酸酸de快乐 发表于 2014-7-13 07:02:09

帮你顶下哈!!

ㄨ菲薄的青春 发表于 2014-7-14 18:58:29

我常来...支持 海论坛

神马都是白日梦 发表于 2014-7-15 22:46:23

前排支持一下

Patelixia 发表于 2014-7-17 10:38:05

看看..感谢楼主

f186111 发表于 2014-7-19 12:17:20

海论坛,我支持你!

miaozss 发表于 2014-7-20 20:41:01

海论坛,我支持你!

Ghajdix 发表于 2014-12-26 15:13:24

纯粹路过,没任何兴趣,仅仅是看在老用户份上回复一下

zhuzhuli 发表于 2014-12-26 15:17:58

无论是不是沙发都得回复下
页: [1] 2 3
查看完整版本: CALL的概念篇:堆栈的平衡(一)