所有这些代码是做什么用的?

逆向工程 部件 C++ 编译器
2021-06-12 17:26:27

为了能够有效地逆向汇编,需要了解不同编译器的工作方式,以及常见的代码生成模式是什么。如果您不了解它们,那么您将花费更多的时间来弄清楚一些只是编译器代码生成的产物。

鉴于上述情况,我想了解以下代码的含义。它来自lzham_codec库,但稍后您将看到它并不是特定于它的。我克隆了这个 git repo,然后我用 VS2015 编译了代码。我将断点设置为lzham_codec\lzhamdll\lzham_api.cpp(第 9 行)

然后我运行 lzhamtest 并且断点命中。我打开反汇编窗口,这是我看到的:

在此处输入图片说明

对于一个只返回一个常量的函数来说,这是非常多的代码。所有这些代码是做什么用的?

1个回答

我假设您对 x86 处理器体系结构、寄存器以及堆栈的工作方式有一个大致的了解。如果你不知道,那里有很多介绍、教程和书籍,它们比我在这篇文章中更好地解释了事情。

前 2 条和后 3 条指令是标准函数进入/退出代码:

push ebp
mov ebp, esp
....
mov esp, ebp
pop ebp
ret

他们分别为函数设置了堆栈。撤消此操作并返回给调用者。

sub esp, 0C0h

为堆栈上的 192 (0xC0) 个字节的局部变量腾出空间。

pushpop指令保存寄存器作为要由功能打一顿,事后恢复它们的堆栈:

push ebx
push esi
push edi
...
pop edi
pop esi
pop ebx

请注意,其他代码甚至没有触及ebxesi但看起来你编译没有优化;abi 声明这些寄存器不应该被过程改变,所以编译器会保存它们,如果没有优化,它不会意识到以后不需要它们并且不会push? /从代码中删除pop`。

lea edi, [ebp-0C0h]
mov ecx, 30h
mov eax, 0cccccccch
rep stos dword ptr es:[edi]

这会用 填充所有局部变量0xCCCCCCCC,但您的 C 代码没有说明原因。也许它与代码中未显示的一些变量声明有关,或者编译器只是初始化局部变量0xCCCCCCCC以防止“未初始化的变量具有未定义的值,不要让代码假设它们为零”错误。

剩下的是

mov eax,1010h

这是返回指令 - 函数结果通常在eax寄存器中返回,并且0x1010似乎LZHAM_DLL_VERSION是定义的内容。