所以,在使用 IDA 反汇编一个 dll 时,我遇到了这个类函数:
mov eax, [ecx+4]
mov eax, [eax]
retn
我知道ecx
手段this
和eax
是返回值,但我不明白它返回什么。有什么帮助吗?
所以,在使用 IDA 反汇编一个 dll 时,我遇到了这个类函数:
mov eax, [ecx+4]
mov eax, [eax]
retn
我知道ecx
手段this
和eax
是返回值,但我不明白它返回什么。有什么帮助吗?
该函数在从任何指向eax
的偏移量 4 处加载一个指针(到)。ecx
然后它跟随该指针将 32 位值加载到eax
从函数返回的 中。
这就是函数的作用,但如果没有更多上下文,就不可能说出这意味着什么。
class C
{
int a;
int *b; // ecx+4
int get_b()
{
return *b;
}
}
当然,a
and的实际类型*b
是未知的,但它们都是 32 位类型。a
如果类有任何虚方法或析构函数,也可以是指向 VMT 的指针。
我的程序集有点生疏,但第一条指令将某些内容加载到 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,取决于很多我们不知道的事情。
这在很大程度上取决于原始编译器使用的调用约定。例如,MSVC 的一个相当正常的设置是在 eax 寄存器中返回 32 位值。@Gregs 回答说明了它的作用,但正如他所说,含义取决于了解实现语言和编译器的更多细节。
如果您想了解反汇编,请尝试在您自己的 (C/C++) 代码上查看结果。这确实是了解其他人的 DLL 中发生的情况的唯一方法。