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