<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 134,comments - 22,trackbacks - 0

    1. 最簡單的代碼:

    //// test1.c

    int main(){

        return 1;

    }

     

    編譯、反匯編:

    gcc test1.c

    gdb ./a.out

    (gdb) disassemble main

     

    0x08048344 <main+0>:        lea    0x4(%esp),%ecx   ;取出esp寄存器里的值加上4將得到值傳遞給ecx

    0x08048348 <main+4>:        and    $0xfffffff0,%esp  ;使棧地址16字節對齊

    0x0804834b <main+7>:       pushl  -0x4(%ecx)  ;取出寄存器ecx的值減去4esp的值,將得到的值作為地址在內存找到該地址對應的值將其壓入棧中。

    0x0804834e <main+10>:      push   %ebp

    0x0804834f <main+11>:      mov    %esp,%ebp  ;創建Stack Frame(棧框架)

    0x08048351 <main+13>:      push   %ecx

    0x08048352 <main+14>:      mov    $0x1,%eax

    0x08048357 <main+19>:      pop    %ecx

    0x08048358 <main+20>:      pop    %ebp

    0x08048359 <main+21>:      lea    -0x4(%ecx),%esp  ;取出ecx 寄存器里的值減去4將得到值傳遞給esp還原esp的值

    0x0804835c <main+24>:      ret 

     

    常用指令解釋:

    CALL指令:

    用來調用一個函數或過程,此時,下一條指令地址會被壓入堆棧,以備返回時能恢復執行下條指令。
    RET
    指令:

    用來從一個函數或過程返回,之前CALL保存的下條指令地址會從棧內彈出到EIP寄存器中,程序轉到CALL之前下條指令處執行

    ENTER指令:

    建立當前函數的棧框架,即相當于以下兩條指令:
            pushl   %ebp
            movl    %esp,%ebp

    LEAVE
    指令:

    釋放當前函數或者過程的棧框架,即相當于以下兩條指令:
            movl ebp esp
            popl ebp

     

    2. 函數間的調用代碼:

    假如函數A調用函數B,函數B調用函數C

    ///// test2.c

    void c(){}

     

    void b(){c();}

     

    void a(){b();}

     

    int main(){

       a();

       return 1;

    }

    編譯、反匯編:

    gcc test1.c

    gdb ./a.out

    (gdb) disassemble main

    Dump of assembler code for function main:

    0x0804835d <main+0>:       lea    0x4(%esp),%ecx

    0x08048361 <main+4>:        and    $0xfffffff0,%esp

    0x08048364 <main+7>:        pushl  -0x4(%ecx)

    0x08048367 <main+10>:      push   %ebp

    0x08048368 <main+11>:      mov    %esp,%ebp

    0x0804836a <main+13>:      push   %ecx

    0x0804836b <main+14>:     call   0x8048353 <a>

    0x08048370 <main+19>:      mov    $0x1,%eax

    0x08048375 <main+24>:      pop    %ecx

    0x08048376 <main+25>:      pop    %ebp

    0x08048377 <main+26>:      lea    -0x4(%ecx),%esp

    0x0804837a <main+29>:      ret   

    End of assembler dump.

    (gdb) disassemble a

    Dump of assembler code for function a:

    0x08048353 <a+0>:  push   %ebp

    0x08048354 <a+1>:  mov    %esp,%ebp

    0x08048356 <a+3>:  call   0x8048349 <b>

    0x0804835b <a+8>:  pop    %ebp

    0x0804835c <a+9>:  ret   

    End of assembler dump.

    (gdb) disassemble b

    Dump of assembler code for function b:

    0x08048349 <b+0>:  push   %ebp

    0x0804834a <b+1>:  mov    %esp,%ebp

    0x0804834c <b+3>:  call   0x8048344 <c>

    0x08048351 <b+8>:  pop    %ebp

    0x08048352 <b+9>:  ret   

    End of assembler dump.

    (gdb) disassemble c

    Dump of assembler code for function c:

    0x08048344 <c+0>:  push   %ebp

    0x08048345 <c+1>:  mov    %esp,%ebp

    0x08048347 <c+3>:  pop    %ebp

    0x08048348 <c+4>:  ret   

    End of assembler dump.

     

    函數調用棧的狀態:

        +-------------------------+----> 高地址
        | EIP (Main
    函數返回地址)   |
        +-------------------------+
        | EBP (Main
    函數的EBP)      | --+ <------當前函數AEBPA (SFP框架指針)
        +-------------------------+   +-->offsetA
        | A
    中的局部變量           | --+ <------ESP指向函數A新分配的局部變量,局部變量可以通過EBPA-offsetA訪問
        +-------------------------+
        | Arg .(
    函數B的參數)     |   --+ <------ B函數的參數可以由BEBPB+offsetB訪問
        +-------------------------+   +--> offsetB

       | EIP (A函數的返回地址)    |   |
        +-------------------------+ --+
        | EBP (A
    函數的EBP)        |<--+ <------ 當前函數BEBPB (SFP框架指針)
        +-------------------------+

        | B
    中的局部變量          |  
        +-------------------------+  
        | Arg .(
    函數C的參數)     |  
        +-------------------------+  
        | EIP (B
    函數的返回地址)   |  
        +-------------------------+ 
        | EBP (B
    函數的EBP)       | --+ <------ 當前函數CEBPC (SFP框架指針)
        +-------------------------+
        | C 中的局部變量          |
        | ..........              | <------ ESP
    指向函數C新分配的局部變量

     +-------------------------+----> 低地址

    函數被調用時
        1) EIP/EBP
    成為新函數棧的邊界
       
    函數被調用時,返回時的EIP首先被壓入堆棧;創建棧框架時,上級函數棧的EBP被壓入堆棧,與EIP一道行成新函數棧框架的邊界
        2) EBP
    成為棧框架指針SFP,用來指示新函數棧的邊界
       
    棧框架建立后,EBP指向的棧的內容就是上一級函數棧的EBP,可以想象,通過EBP就可以把層層調用函數的棧都回朔遍歷一遍,調試器就是利用這個特性實現 backtrace功能的
        3) ESP
    總是作為棧指針指向棧頂,用來分配棧空間
       
    棧分配空間給函數局部變量時的語句通常就是給ESP減去一個常數值,例如,分配一個整型數據就是 ESP-4
        4)
    函數的參數傳遞和局部變量訪問可以通過SFPEBP來實現
       
    由于棧框架指針永遠指向當前函數的棧基地址,參數和局部變量訪問通常為如下形式:
            +8+xx(%ebp)         ;
    函數入口參數的的訪問
            -xx(%ebp)           ; 函數局部變量訪問

     

    3含局部變量時:

    int main(){

      int a = 3;

      int b = 5;

    return 1;

    }

     

    (gdb) disassemble main

    Dump of assembler code for function main:

    0x08048344 <main+0>:        lea    0x4(%esp),%ecx

    0x08048348 <main+4>:        and    $0xfffffff0,%esp

    0x0804834b <main+7>:       pushl  -0x4(%ecx)

    0x0804834e <main+10>:      push   %ebp

    0x0804834f <main+11>:      mov    %esp,%ebp

    0x08048351 <main+13>:      push   %ecx

    0x08048352 <main+14>:      sub    $0x10,%esp

    0x08048355 <main+17>:      movl   $0x3,-0x8(%ebp)  ; a = 3

    0x0804835c <main+24>:      movl   $0x5,-0xc(%ebp) ; b = 5;

    0x08048363 <main+31>:      mov    $0x1,%eax ;return 1;

    0x08048368 <main+36>:      add    $0x10,%esp

    0x0804836b <main+39>:     pop    %ecx

    0x0804836c <main+40>:      pop    %ebp

    0x0804836d <main+41>:     lea    -0x4(%ecx),%esp

    0x08048370 <main+44>:      ret   

    End of assembler dump.

    通過反匯編代碼對程序運行時的寄存器和棧的觀察和分析,可以得出局部變量在棧中的訪問和分配及釋放方式:
            1.
    局部變量的分配,可以通過esp減去所需字節數
               sub    $0x10,%esp

            2.局部變量的釋放,可以通過esp加上已分配的字節
               add    $0x10,%esp     
            3.
    局部變量的訪問,可以通過ebp減去偏移量
               movl   $0x3,-0x8(%ebp)

               

    4. 函數調用時有參數

    int func(int m, int n)

    {

       return m+n;

    }

     

    int main(){

      int a = 3;

      int b = 5;

      int c = 0;

      c = func(a, b);

      return c;

    }

     

    (gdb) disassemble main

    Dump of assembler code for function main:

    0x0804834f <main+0>:        lea    0x4(%esp),%ecx

    0x08048353 <main+4>:        and    $0xfffffff0,%esp

    0x08048356 <main+7>:        pushl  -0x4(%ecx)

    0x08048359 <main+10>:      push   %ebp

    0x0804835a <main+11>:      mov    %esp,%ebp

    0x0804835c <main+13>:      push   %ecx

    0x0804835d <main+14>:     sub    $0x18,%esp

    0x08048360 <main+17>:      movl   $0x3,-0x8(%ebp)  ;a = 3

    0x08048367 <main+24>:      movl   $0x5,-0xc(%ebp)  ;b = 5

    0x0804836e <main+31>:      movl   $0x0,-0x10(%ebp)  ;c = 0;

    0x08048375 <main+38>:      mov    -0xc(%ebp),%eax  

    0x08048378 <main+41>:      mov    %eax,0x4(%esp)  ; n = b

    0x0804837c <main+45>:      mov    -0x8(%ebp),%eax

    0x0804837f <main+48>:      mov    %eax,(%esp)    ; m = a;

    0x08048382 <main+51>:      call   0x8048344 <func>  ;func(a,b);

    0x08048387 <main+56>:      mov    %eax,-0x10(%ebp) ; c = func(a, b);

    0x0804838a <main+59>:      mov    -0x10(%ebp),%eax ; return c

    0x0804838d <main+62>:     add    $0x18,%esp

    0x08048390 <main+65>:      pop    %ecx

    0x08048391 <main+66>:      pop    %ebp

    0x08048392 <main+67>:      lea    -0x4(%ecx),%esp

    0x08048395 <main+70>:      ret   

    End of assembler dump.

    (gdb) disassemble func

    Dump of assembler code for function func:

    0x08048344 <func+0>:        push   %ebp

    0x08048345 <func+1>:        mov    %esp,%ebp

    0x08048347 <func+3>:        mov    0xc(%ebp),%eax ; n

    0x0804834a <func+6>:        add    0x8(%ebp),%eax ; m+n

    0x0804834d <func+9>:        pop    %ebp

    0x0804834e <func+10>:      ret   

    End of assembler dump.

    參數的訪問,可以通過ebp加上減去偏移量:

    mov    0xc(%ebp),%eax
    add     0x8(%ebp),%eax

    posted on 2010-07-29 11:41 何克勤 閱讀(1336) 評論(0)  編輯  收藏 所屬分類: C/C++GNU Linux/Unix
    主站蜘蛛池模板: 国产美女无遮挡免费网站| 亚洲av日韩av无码| 亚洲中文无码永久免费| 亚洲天堂免费在线| 色影音免费色资源| 亚洲第一页在线视频| 羞羞漫画小舞被黄漫免费| 扒开双腿猛进入爽爽免费视频| 亚洲人成人网毛片在线播放| 一区二区无码免费视频网站| 亚洲三级在线播放| 暖暖免费高清日本中文| 国产亚洲精品美女| 久久久久亚洲AV综合波多野结衣| 九九久久精品国产免费看小说| 亚洲精品99久久久久中文字幕| 亚洲精品视频免费看| 美女视频黄的全免费视频| 亚洲s码欧洲m码吹潮| 亚洲国产天堂久久综合| 中出五十路免费视频| 亚洲天天做日日做天天看| 免费无码又黄又爽又刺激 | 亚洲国产综合人成综合网站00| 青青草国产免费国产是公开| 亚洲日韩中文字幕日韩在线| 三上悠亚在线观看免费| 亚洲美女一区二区三区| 中国国语毛片免费观看视频| 久久亚洲精品中文字幕无码| 无码乱肉视频免费大全合集 | 亚洲爆乳AAA无码专区| 国产亚洲自拍一区| 99热这里只有精品6免费| 亚洲 欧洲 日韩 综合在线| 亚洲国产91精品无码专区| 亚洲欧美国产日韩av野草社区| 伊人久久亚洲综合影院| 午夜视频在线免费观看| 亚洲色中文字幕在线播放| 国内精品99亚洲免费高清|