Linux C++ 調試神技--如何將Linux C++ 可執行文件逆向工程到Intel格式彙編

Linux C++ 調試神技--如何將Linux C++ 可執行文件逆向工程到Intel格式彙編ios

 

對於許多在windows 上調試代碼的人而言, Intel IA32格式的彙編代碼可能並不陌生,由於種種的緣由,不少軟件工程師不得不去嘗試理解彙編代碼。Windows PE的反彙編格式默認是Intel格式的,可是因爲歷史的緣由,在這個世界上還存在另一種彙編,ATT格式,這也是Linux C++ 可執行代碼的默認反彙編格式。windows

 

難道還真須要哥們學習兩種格式的彙編麼?一種學會了已經很NB了?sass

 

難道哥們在Windows上學的彙編到Linux上就白費了麼?玩不轉了麼?架構

 

底層的處理器都是一個架構的,機器碼都是同樣的,這兩種彙編代碼必定能夠互相轉換,不然工具設計者智商必定低到寫不出來工具。工具

 

對於這個問題且聽兄弟以一個例子詳細到道來。假設有以下的C++代碼,咱們將其在Linux上編譯爲一個名字爲hellod的執行文件。學習

1    #include<iostream>
2    int main()
3    {
4    std::cout << "Enter two numbers:" << std::endl;
5    int v1 = 0, v2 = 0;
6    std::cin >> v1 >> v2;
7    std::cout << "The sum of " << v1 << " and " << v2
8    << " is " << v1 + v2 << std::endl;
9    return 0;
10    }

若是想看看如今的默認反彙編格式是什麼,能夠使用以下命令,能夠看到Linux默認的是ATT格式的ui

(gdb) show disassembly-flavor
The disassembly flavor is "att".

反彙編結果以下:spa

(gdb) disassemble main
Dump of assembler code for function main():
   0x000000000040092d <+0>:    push   %rbp
   0x000000000040092e <+1>:    mov    %rsp,%rbp
   0x0000000000400931 <+4>:    push   %r13
   0x0000000000400933 <+6>:    push   %r12
   0x0000000000400935 <+8>:    push   %rbx
   0x0000000000400936 <+9>:    sub    $0x18,%rsp
   0x000000000040093a <+13>:    mov    $0x400ad4,%esi
   0x000000000040093f <+18>:    mov    $0x6011a0,%edi
   0x0000000000400944 <+23>:    callq  0x400800 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
   0x0000000000400949 <+28>:    mov    $0x400830,%esi
   0x000000000040094e <+33>:    mov    %rax,%rdi
   0x0000000000400951 <+36>:    callq  0x400820 <_ZNSolsEPFRSoS_E@plt>
   0x0000000000400956 <+41>:    movl   $0x0,-0x28(%rbp)
   0x000000000040095d <+48>:    movl   $0x0,-0x24(%rbp)
   0x0000000000400964 <+55>:    lea    -0x28(%rbp),%rax
   0x0000000000400968 <+59>:    mov    %rax,%rsi
   0x000000000040096b <+62>:    mov    $0x601080,%edi
   0x0000000000400970 <+67>:    callq  0x400810 <_ZNSirsERi@plt>
   0x0000000000400975 <+72>:    lea    -0x24(%rbp),%rdx
   0x0000000000400979 <+76>:    mov    %rdx,%rsi
   0x000000000040097c <+79>:    mov    %rax,%rdi
---Type <return> to continue, or q <return> to quit---
   0x000000000040097f <+82>:    callq  0x400810 <_ZNSirsERi@plt>
   0x0000000000400984 <+87>:    mov    -0x28(%rbp),%edx
   0x0000000000400987 <+90>:    mov    -0x24(%rbp),%eax
   0x000000000040098a <+93>:    lea    (%rdx,%rax,1),%r13d
   0x000000000040098e <+97>:    mov    -0x24(%rbp),%ebx
   0x0000000000400991 <+100>:    mov    -0x28(%rbp),%r12d
   0x0000000000400995 <+104>:    mov    $0x400ae7,%esi
   0x000000000040099a <+109>:    mov    $0x6011a0,%edi
   0x000000000040099f <+114>:    callq  0x400800 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
   0x00000000004009a4 <+119>:    mov    %r12d,%esi
   0x00000000004009a7 <+122>:    mov    %rax,%rdi
   0x00000000004009aa <+125>:    callq  0x4007a0 <_ZNSolsEi@plt>
   0x00000000004009af <+130>:    mov    $0x400af3,%esi
   0x00000000004009b4 <+135>:    mov    %rax,%rdi
   0x00000000004009b7 <+138>:    callq  0x400800 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
   0x00000000004009bc <+143>:    mov    %ebx,%esi
   0x00000000004009be <+145>:    mov    %rax,%rdi
   0x00000000004009c1 <+148>:    callq  0x4007a0 <_ZNSolsEi@plt>
   0x00000000004009c6 <+153>:    mov    $0x400af9,%esi
   0x00000000004009cb <+158>:    mov    %rax,%rdi
   0x00000000004009ce <+161>:    callq  0x400800 <_ZStlsISt11char_traitsIcEERSt13---Type <return> to continue, or q <return> to quit---
basic_ostreamIcT_ES5_PKc@plt>
   0x00000000004009d3 <+166>:    mov    %r13d,%esi
   0x00000000004009d6 <+169>:    mov    %rax,%rdi
   0x00000000004009d9 <+172>:    callq  0x4007a0 <_ZNSolsEi@plt>
   0x00000000004009de <+177>:    mov    $0x400830,%esi
   0x00000000004009e3 <+182>:    mov    %rax,%rdi
   0x00000000004009e6 <+185>:    callq  0x400820 <_ZNSolsEPFRSoS_E@plt>
   0x00000000004009eb <+190>:    mov    $0x0,%eax
   0x00000000004009f0 <+195>:    add    $0x18,%rsp
   0x00000000004009f4 <+199>:    pop    %rbx
   0x00000000004009f5 <+200>:    pop    %r12
   0x00000000004009f7 <+202>:    pop    %r13
   0x00000000004009f9 <+204>:    pop    %rbp
   0x00000000004009fa <+205>:    retq   
End of assembler dump.

那若是我看不懂,我想使用Intel格式的彙編怎麼辦呢?下面的命令就能夠作到,牛X吧?哈哈設計

(gdb) set disassembly-flavor intel 
(gdb) show disassembly-flavor
The disassembly flavor is "intel".

再來看看這下咱們反出來的彙編代碼, 已經變成Intel 格式的了3d

(gdb) disassemble main
Dump of assembler code for function main():
   0x000000000040092d <+0>:    push   rbp
   0x000000000040092e <+1>:    mov    rbp,rsp
   0x0000000000400931 <+4>:    push   r13
   0x0000000000400933 <+6>:    push   r12
   0x0000000000400935 <+8>:    push   rbx
   0x0000000000400936 <+9>:    sub    rsp,0x18
   0x000000000040093a <+13>:    mov    esi,0x400ad4
   0x000000000040093f <+18>:    mov    edi,0x6011a0
   0x0000000000400944 <+23>:    call   0x400800 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
   0x0000000000400949 <+28>:    mov    esi,0x400830
   0x000000000040094e <+33>:    mov    rdi,rax
   0x0000000000400951 <+36>:    call   0x400820 <_ZNSolsEPFRSoS_E@plt>
   0x0000000000400956 <+41>:    mov    DWORD PTR [rbp-0x28],0x0
   0x000000000040095d <+48>:    mov    DWORD PTR [rbp-0x24],0x0
   0x0000000000400964 <+55>:    lea    rax,[rbp-0x28]
   0x0000000000400968 <+59>:    mov    rsi,rax
   0x000000000040096b <+62>:    mov    edi,0x601080
   0x0000000000400970 <+67>:    call   0x400810 <_ZNSirsERi@plt>
   0x0000000000400975 <+72>:    lea    rdx,[rbp-0x24]
   0x0000000000400979 <+76>:    mov    rsi,rdx
   0x000000000040097c <+79>:    mov    rdi,rax
---Type <return> to continue, or q <return> to quit---
   0x000000000040097f <+82>:    call   0x400810 <_ZNSirsERi@plt>
   0x0000000000400984 <+87>:    mov    edx,DWORD PTR [rbp-0x28]
   0x0000000000400987 <+90>:    mov    eax,DWORD PTR [rbp-0x24]
   0x000000000040098a <+93>:    lea    r13d,[rdx+rax*1]
   0x000000000040098e <+97>:    mov    ebx,DWORD PTR [rbp-0x24]
   0x0000000000400991 <+100>:    mov    r12d,DWORD PTR [rbp-0x28]
   0x0000000000400995 <+104>:    mov    esi,0x400ae7
   0x000000000040099a <+109>:    mov    edi,0x6011a0
   0x000000000040099f <+114>:    call   0x400800 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
   0x00000000004009a4 <+119>:    mov    esi,r12d
   0x00000000004009a7 <+122>:    mov    rdi,rax
   0x00000000004009aa <+125>:    call   0x4007a0 <_ZNSolsEi@plt>
   0x00000000004009af <+130>:    mov    esi,0x400af3
   0x00000000004009b4 <+135>:    mov    rdi,rax
   0x00000000004009b7 <+138>:    call   0x400800 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
   0x00000000004009bc <+143>:    mov    esi,ebx
   0x00000000004009be <+145>:    mov    rdi,rax
   0x00000000004009c1 <+148>:    call   0x4007a0 <_ZNSolsEi@plt>
   0x00000000004009c6 <+153>:    mov    esi,0x400af9
   0x00000000004009cb <+158>:    mov    rdi,rax
   0x00000000004009ce <+161>:    call   0x400800 <_ZStlsISt11char_traitsIcEERSt13---Type <return> to continue, or q <return> to quit---
basic_ostreamIcT_ES5_PKc@plt>
   0x00000000004009d3 <+166>:    mov    esi,r13d
   0x00000000004009d6 <+169>:    mov    rdi,rax
   0x00000000004009d9 <+172>:    call   0x4007a0 <_ZNSolsEi@plt>
   0x00000000004009de <+177>:    mov    esi,0x400830
   0x00000000004009e3 <+182>:    mov    rdi,rax
   0x00000000004009e6 <+185>:    call   0x400820 <_ZNSolsEPFRSoS_E@plt>
   0x00000000004009eb <+190>:    mov    eax,0x0
   0x00000000004009f0 <+195>:    add    rsp,0x18
   0x00000000004009f4 <+199>:    pop    rbx
   0x00000000004009f5 <+200>:    pop    r12
   0x00000000004009f7 <+202>:    pop    r13
   0x00000000004009f9 <+204>:    pop    rbp
   0x00000000004009fa <+205>:    ret    
End of assembler dump.

 

總結

對於不少計算機工程領域的技術問題,理解原理是最重要的,軟件工程師很忙,忙着學東西,可是有的東西你一旦知道了道理,靠分析已經能節省不少的時間,根本不用去再學一遍,就拿本例來講,若是不去分析,再去學一遍另外一個版本的,可能也是事倍功半,站的高方能望的遠,和你們共勉。

相關文章
相關標籤/搜索