【发布时间】:2011-03-09 12:39:18
【问题描述】:
所以,在使用 IDA 反汇编一个 dll 时,我遇到了这个类函数:
mov eax, [ecx+4]
mov eax, [eax]
retn
我知道ecx 表示this 和eax 是返回值,但我不明白它返回什么。有什么帮助吗?
【问题讨论】:
标签: assembly reverse-engineering ida
所以,在使用 IDA 反汇编一个 dll 时,我遇到了这个类函数:
mov eax, [ecx+4]
mov eax, [eax]
retn
我知道ecx 表示this 和eax 是返回值,但我不明白它返回什么。有什么帮助吗?
【问题讨论】:
标签: assembly reverse-engineering ida
该函数从ecx 指向的任何偏移量4 处加载一个指针(到eax)。然后它跟随该指针将一个 32 位值加载到函数返回的 eax 中。
这就是函数的作用,但如果没有更多上下文,就不可能说出的含义。
【讨论】:
我的程序集有点生疏,但第一条指令将一些东西加载到 EAX 中……ECX 寄存器的内容指向的东西……但它是一个字(4 个字节)的偏移量。然后,下一条指令是使用 EAX 指向的任何内容加载(覆盖)EAX。
此符号(这些 MOV(加载)指令的第二个或“源”操作周围的方括号表示正在使用间接寻址模式。
我猜这只是一种实现双重间接的方式。寄存器 ECX 中的地址可能指向堆栈帧,或者可能指向您提到的 C++“this”的某个属性指针。反过来,该地址保存返回值的地址。因此,此代码将地址拉入寄存器,然后使用寄存器中的地址拉出一个值(同时进入同一个寄存器)。这种方法很好,因为它保留了所有其他寄存器。
(顺便提一下,大多数 x86 函数调用范例 --- 系统调用、DOS 函数调用等。在 stdlib C 库中的 EAX 寄存器中留下函数返回码或系统错误...errno)。
【讨论】:
真是个问题。如果 ecx 持有指向“this”结构的指针,您必须知道它是如何完成的。第一个instr,得到第二个dword,另一个指针;可能是什么?我们无法知道。这个指针现在保存在 eax 中,可能指向另一个结构或其他什么。第一个指向的值放在 eax 中,这就是 func 返回的内容。
ecx -------> dword dataA offset 0
dword dataB offset 4
mov eax, [ecx + 4]
eax = dataB ----> dword dataC offset 0
mov eax, [eax]
eax = dataC
dataC 到底是什么,取决于很多我们不知道的事情。
【讨论】:
class C
{
int a;
int *b; // ecx+4
int get_b()
{
return *b;
}
}
当然,a 和 *b 的实际类型未知,但它们都是 32 位类型。 a 也可以是指向 VMT 的指针,如果该类有任何虚方法或析构函数。
【讨论】:
a)。
这在很大程度上取决于原始编译器使用的调用约定。一个相当正常的设置,例如MSVC 将在 eax 寄存器中返回 32 位值。 @Gregs 回答说明了它的作用,但正如他所说,含义取决于了解实现语言和编译器的更多细节。
如果您想了解反汇编,请尝试使用您自己的 (C/C++) 代码查看结果。这确实是了解其他人的 DLL 中发生的情况的唯一方法。
【讨论】: