令人困惑的功能
所以,在使用IDA反汇编dll时,我遇到了这个类函数:
mov eax, [ecx+4]
mov eax, [eax]
retn
我知道ecx
意味着this
,而eax
是返回值,但我不明白它返回什么。有什么帮助吗?
So, while using IDA to disassemble a dll, I came across this class function:
mov eax, [ecx+4]
mov eax, [eax]
retn
I know ecx
means this
and eax
is the return value, but I fail to understand what it returns. Any help?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
该函数在
ecx
指向的偏移量 4 处加载一个指针(到eax
中)。然后跟随该指针将 32 位值加载到 eax 中,该值是从函数返回的。这就是该函数的作用,但是如果没有更多上下文,就不可能说出它的含义。
That function loads a pointer (into
eax
) at offset 4 from whateverecx
points to. Then it follows that pointer to load a 32-bit value intoeax
, which is returned from the function.That's what the function does, but it's impossible to say what that means without a lot more context.
当然,
a
和*b
的实际类型是未知的,但它们都是32位类型。如果类有任何虚方法或析构函数,a
也可以是指向 VMT 的指针。Of course, the actual type of
a
and*b
is unknown, but they're both 32-bit types.a
could also be the pointer to the VMT, if the class has any virtual methods or destructors.我的程序集有点生疏,但第一条指令将某些内容加载到 EAX 中……ECX 寄存器的内容所指向的内容……但它是一个字(4 个字节)的偏移量。然后,下一条指令将使用 EAX 所指向的内容加载(覆盖)EAX。
这种表示法(这些 MOV(加载)指令的第二个或“源”操作周围的方括号表示正在使用间接寻址模式。
我猜这只是实现某种双重间接寻址的一种方法。地址寄存器 ECX 可能指向堆栈帧,或者可能指向您所引用的 C++“this”的某个属性指针,该地址又保存返回值的地址。一个寄存器,然后使用寄存器中的该地址提取一个值(同时放入同一个寄存器中)。这种方法很好,因为它保留了所有其他寄存器
(顺便说一句,大多数 x86 函数调用范例 --- 系统)。调用、DOS 函数调用等。在 stdlib C 库中留下函数返回代码或系统错误... errno,在 EAX 寄存器中)。
My assembly is a bit rusty but the first instruction loads something into EAX ... something which is being pointed at by the contents of the ECX register ... but which is a word (4 bytes) offset therefrom. The next instruction is then loading (over-writing) EAX with whatever EAX is pointing at.
This notation (the square brackets surrounding the second or "source" operations of these MOV (load) instructions indicates that the indirect addressing modes are being used.
I'm guessing it's just a way to implement a sort of double-indirection. The address in register ECX may be pointing into the stack frame or perhaps into some attribute pointer of the C++ "this" to which you've referred. That address, in turn, holds the address of the return value. So this code pulls the address into a register, then uses that address in the register to pull a value (co-incidentally into the same register). This approach is nice in that it preserves all the other registers.
(Incidentally most of the x86 function calling paradigms --- system calls, DOS function calls, etc. leave function return codes or system errors ... errno in the stdlib C libraries, in the EAX register).
这是什么问题啊。如果 ecx 保存指向“this”结构的指针,您必须确切地知道它是如何完成的。第一个指令,获取第二个双字,另一个指针;它可能是什么?我们不知道。该指针现在保存在 eax 中,可能指向另一个结构或其他结构。第一个指向的值放入 eax 中,这就是 func 返回的值。
dataC 到底是什么,取决于很多我们无法知道的事情。
What a question. If ecx holds the pointer to a "this" structure, you have to know how it is done exactly. The first instr, gets the second dword, another pointer; what it could be? We can't know. This pointer now held in eax, likely points to another struct or whatever. The first pointed value is put in eax, and this is what the func returns.
What is dataC exactly, depends on a lot of things we can't know.
这很大程度上取决于原始编译器使用的调用约定。例如,MSVC 的一个相当正常的设置是在 eax 寄存器中返回 32 位值。 @Gregs 的回答说明了它的作用,但正如他所说,其含义取决于了解实现语言和编译器的更多细节。
如果您想了解反汇编,请尝试在您自己的 (C/C++) 代码上查看结果。这实际上是了解其他 DLL 中发生的情况的唯一方法。
This depends greatly on the calling convention used by the original compiler. A fairly normal setting for e.g. MSVC is to return 32 bit values in the eax register. @Gregs answer says what it does, but as he says, the meaning depends on knowing more details of the implementation language and compiler.
If you want to understand disassemblies, try viewing the results on your own (C/C++) code. It's really the only way to get a feeling for what happens in others' DLLs.