我正在尝试学习 RE,我决定通过逆向工程一个简单的 C++ 程序来探索这个领域,我在这里发布:
简单的 C++ 程序
#include <iostream>
int main()
{
int value;
std::cout << "Hello Word";
std::cin >> value;
return 0;
}
我使用 MSVC 编译器(VS 2017,x86 版本)编译它。我想了解它背后的汇编语言。
对于 RE,我使用 Ghidra 工具。我目前只专注于理解汇编部分,而不是反编译部分,因为目前那个对我来说意义不大,但也许如果我理解了汇编部分,我将能够解码反编译的输出。
组装输出:
//
// .text
// ram: 00401000-00401f9a
//
**************************************************************
* FUNCTION *
**************************************************************
int __cdecl main(void)
int EAX:4 <RETURN>
int EAX:4 value XREF[1]: 00401032(W)
char * Stack[-0x8]:4 hello_string XREF[2]: 0040100d(W),
0040102b(R)
undefined1 Stack[-0xc]:1 local_c XREF[1]: 00401021(*)
.text$mn XREF[3]: 0040012c(*), 00400204(*),
main __scrt_common_main_seh:00401500(
00401000 55 PUSH EBP
00401001 8b ec MOV EBP,ESP
00401003 83 ec 08 SUB ESP,0x8
00401006 a1 04 30 MOV EAX,[___security_cookie] = BB40E64Eh
40 00
0040100b 33 c5 XOR EAX,EBP
0040100d 89 45 fc MOV dword ptr [EBP + hello_string],EAX
00401010 8b 0d 54 MOV ECX,dword ptr [->MSVCP140.DLL::std::cout] = 000027ec
20 40 00
00401016 e8 25 00 CALL std::operator<<<struct_std::char_traits<char>_> basic_ostream<char,struct_std::c
00 00
0040101b 8b 0d 4c MOV ECX,dword ptr [->MSVCP140.DLL::std::cin] = 0000284a
20 40 00
00401021 8d 45 f8 LEA EAX=>local_c,[EBP + -0x8]
00401024 50 PUSH EAX
00401025 ff 15 34 CALL dword ptr [->MSVCP140.DLL::std::basic_istream<
20 40 00
0040102b 8b 4d fc MOV ECX,dword ptr [EBP + hello_string]
0040102e 33 c0 XOR EAX,EAX
00401030 33 cd XOR ECX,EBP
00401032 e8 fe 02 CALL @__security_check_cookie@4 undefined @__security_check_cook
00 00
00401037 8b e5 MOV ESP,EBP
00401039 5d POP EBP
0040103a c3 RET
我正在尝试逐行遵循汇编代码。我了解那里提到的寄存器和堆栈分配的一些基础知识,但是我在dword ptr MOV指令和CALL指令中迷失了方向。
如果有人可以向我详细说明那里实际发生的事情,我将开始更好地理解在执行 RE 任务时如何处理汇编代码。