Mr.C 发表于 2011-12-21 00:17:13

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后,清淅多了。

现在请看第四楼的问题。

ytrfamli 发表于 2011-12-21 00:17:14

嘿...这...以我的猜想是...

低                                                                                                      高
地                                                                                                      地
址                                                                                                      址
EDI ESI EBX 16个0xCCCCCCCC EBP 旧EIP 0x00000001 0x00000002
                                                          CALL         x               y
                                                   呼叫子程序
                                                   因此EIP入栈

:o 不过老实说我的汇编最後一章課程設計2最近才马马虎虎的完成(真的折腾人)...WIN32汇编基本上是零基础...:loveliness:
总之看起来是个合理(而大胆)的假设,哈哈.

小鸟江月 发表于 2011-12-21 01:28:46

其实是有两段4Ch的空间的,第一段用来填充CC,另一段作为安全栈使用。

ytrfamli 发表于 2011-12-21 02:04:39

呵,果然还是不要先看解释的好,看了LZ一步一步的说明反而我也把数据入栈时
ESP寄存器改变的方向搞混了,纠结了一下.

搞懂了也就清晰很多,以左边为低地址,右边为高地址来作说明的话
对於ESP,EBP作减法她们的指向的位置都是往左移动,
数据入栈(等同於ESP减4)也是一样,并且数据是一个一个往左堆
相反的, rep stos指令执行时,被填入栈的数据是一个一个往右堆
因此把指令执行完毕之後,记忆体中的状况应该是

EDX ESI EBX 0xCCCCCCCC 0xCCCCCCCC .....0xCCCCCCCC EBP
                           [一开始入栈的EBP]

其实是有两段4Ch的空间的,第一段用来填充CC,另一段作为安全栈使用。

我想你的意思是指EES:跟ESS:两个空间?(因为DI默认的关联段空间是ES)
呵呵,我纠结时候曾经有过这样的想法,但是总体考虑起来总觉得好像不太对,又想了一下才恍然大悟.
也拿纸出来画下吧,相信你也会豁然开朗的~

Mr.C 发表于 2011-12-21 02:54:47

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:40:30

本帖最后由 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:}

小B同学 发表于 2011-12-21 12:20:40

没看就先留个言{:1_1:}{:1_1:}

bafengao 发表于 2011-12-21 20:22:21

学知识了 嘿嘿:lol

无敌小枫枫 发表于 2011-12-23 21:43:07

{:5_100:}{:5_96:}
页: [1]
查看完整版本: 2011年十大未解之迷。。。。(反汇编问题)