2011年十大未解之迷。。。。(反汇编问题)
本帖最后由 Mr.C 于 2011-12-21 02:55 编辑2: void main()
3: {
0040B510 push ebp
0040B511 mov ebp,esp
0040B513 sub esp,4Ch
0040B516 push ebx
0040B517 push esi
0040B518 push edi
0040B519 lea edi,
0040B51C mov ecx,13h
0040B521 mov eax,0CCCCCCCCh
0040B526 rep stos dword ptr
这段代码,对于玩过反汇编的人再熟悉不过了。
为了加深理解,边看代码,边在纸上一步一步画了堆栈中的排布情况,以及寄存器的值
问题如下:
1---3行汇编代码理解:ebp入栈保存; ebp和esp同时指向当前栈顶; esp下移4CH的空间
4---6行汇编代码理解:ebx,esi,edi分别入栈保存。 此时esp上移了3*4字节位移。相当于或=ebp-40h
【也就是至存放有用的数据】
第7行代码的理解:edi获取到的地址
8---10行代码的理解:从开始到用0CCCCCCCh填充
相当于
【也就是开始到被0CCCCCCCh全部填充】
最后一步的填充,不是把这三个值覆盖了?!!
我哪里理解有偏差?
****************************************************************
自己弄明白了{:5_109:}我把栈方向弄反了。看了OD后,清淅多了。
现在请看第四楼的问题。
嘿...这...以我的猜想是...
低 高
地 地
址 址
EDI ESI EBX 16个0xCCCCCCCC EBP 旧EIP 0x00000001 0x00000002
CALL x y
呼叫子程序
因此EIP入栈
:o 不过老实说我的汇编最後一章課程設計2最近才马马虎虎的完成(真的折腾人)...WIN32汇编基本上是零基础...:loveliness:
总之看起来是个合理(而大胆)的假设,哈哈.
其实是有两段4Ch的空间的,第一段用来填充CC,另一段作为安全栈使用。 呵,果然还是不要先看解释的好,看了LZ一步一步的说明反而我也把数据入栈时
ESP寄存器改变的方向搞混了,纠结了一下.
搞懂了也就清晰很多,以左边为低地址,右边为高地址来作说明的话
对於ESP,EBP作减法她们的指向的位置都是往左移动,
数据入栈(等同於ESP减4)也是一样,并且数据是一个一个往左堆
相反的, rep stos指令执行时,被填入栈的数据是一个一个往右堆
因此把指令执行完毕之後,记忆体中的状况应该是
EDX ESI EBX 0xCCCCCCCC 0xCCCCCCCC .....0xCCCCCCCC EBP
[一开始入栈的EBP]
其实是有两段4Ch的空间的,第一段用来填充CC,另一段作为安全栈使用。
我想你的意思是指EES:跟ESS:两个空间?(因为DI默认的关联段空间是ES)
呵呵,我纠结时候曾经有过这样的想法,但是总体考虑起来总觉得好像不太对,又想了一下才恍然大悟.
也拿纸出来画下吧,相信你也会豁然开朗的~ ytrfamli 发表于 2011-12-21 02:04 static/image/common/back.gif
呵,果然还是不要先看解释的好,看了LZ一步一步的说明反而我也把数据入栈时
ESP寄存器改变的方向搞混了,纠结 ...
这个问题解决了,那另外一个问题。劳驾大伙给个说法。
一个调用子程序的
具体过程是这样的。
9: x = 1;
0040B566 mov dword ptr ,1
10: y = 2;
0040B56D mov dword ptr ,2
11: z = add(x,y);
关键从这里开始看:
0040B574 mov eax,dword ptr
0040B577 push eax
0040B578 mov ecx,dword ptr
0040B57B push ecx
0040B57C call @ILT+10(add) (0040100f)
在进入CALL前,栈的最顶端没错就是存着两个参数吧?
然后进入CALL
1: int add(int a,int b)
2: {
0040B510 push ebp
0040B511 mov ebp,esp
此时,栈顶是(原)ebp,参数一,参数二,没错吧。 并且(现)ebp指向栈顶
0040B513 sub esp,40h
0040B516 push ebx
0040B517 push esi
0040B518 push edi
0040B519 lea edi,
0040B51C mov ecx,10h
0040B521 mov eax,0CCCCCCCCh
0040B526 rep stos dword ptr
3: return a+b;
问题在这里,中途ebp变动,我的理解,或者说,我纸上画出来的情况是这样的
ebp-------->(原)ebp
参数一
参数二
但是下面的代码显示,在“(原)ebp”和“参数一”之间,还有什么东西?
0040B528 mov eax,dword ptr
0040B52B add eax,dword ptr
4: }
我一直研究这段代码,现在睡不着了。
这是我的汇编的C代码int add(int a,int b)
{
return a+b;
}
void main()
{
int x = 0, y = 0;
int z;
x = 1;
y = 2;
z = add(x,y);
} 本帖最后由 Mr.C 于 2011-12-21 08:42 编辑
ytrfamli 发表于 2011-12-21 03:15 http://bbs.fishc.com/static/image/common/back.gif
嘿...这...以我的猜想是...
低 ...
明白了明白了。
CALL指令,就是一个集成指令,其中包含一个 push和一个 jmp
这不是猜想,是事实。
分给你了。
谢谢你。{:5_95:}
没看就先留个言{:1_1:}{:1_1:} 学知识了 嘿嘿:lol {:5_100:}{:5_96:}
页:
[1]