我正在使用 IDA Pro 6.3 对 Win32 .dll 进行静态分析,并将 Hex-Rays 反编译器与 IDA 反汇编器结合使用。我想了解这一行的作用。
v4 = (*(int (__thiscall **)(int, int))(*(_DWORD *)dword_10087418 + 4))(dword_10087418, v11);
它的格式类似于函数调用。当在子例程调用中使用指向函数的指针时,这就是反编译代码的样子吗?
谢谢。
最佳答案
这很可能是 C++,而不是普通的 C。这正是 Visual C++ 生成的虚拟方法调用的样子。我想说的是:
dword_10087418
是指向对象的指针。它要么是全局变量,要么是静态变量,而不是局部变量。- 该对象有一个虚拟方法表,代码正在调用该表中的第二个函数。
- 假设 Hex-Rays 已正确识别函数参数,则被调用的函数采用一个 32 位参数。返回类型不清楚。
- C++ 调用很可能非常简单,类似于
SomeClass::Instance->func(arg)
。
如果您不熟悉 C++ 对象布局,您应该阅读 C++ Under the Hood , Reversing: Secrets of Reverse Engineering或Inside the C++ Object Model 。 IDA Pro Book 也有一个关于该主题的简短部分。
如果您需要简短的摘要,请继续阅读。请记住,所有这些都是 MSVC 的实现细节,其他编译器的做法有所不同,他们可以随意更改它。 (另外,我通过不提及虚拟/多重继承来简化事情)。当类使用虚函数时,编译器会构建该类中所有此类函数的表,并将指向该表的指针作为该类的每个对象的第一个隐藏成员。然后,从表中调用虚函数就很简单:
mov ecx, esi ; pretend that esi contains a pointer
; to the object whose method is being called
; also known as "this"
; __thiscall functions expect to find this pointer in ecx
; and all later arguments on the stack
mov edx, [ecx] ; get the vtable address
push edi ; set up some integer-sized argument
call [edx + 4] ; call the second function in the vtable
这基本上就是这行代码正在做的事情:
(*(int (__thiscall **)(int, int))(*(_DWORD *)dword_10087418 + 4))(dword_10087418, v11)
^-----------------------^
dereference pointer to get the address of the vtable
(it's the first piece of data in the object)
^-----------------------------^
add 4 bytes to get address of the second function
^------------------------------------------------------------------------------------^
cast that pointer to a particular function pointer and call it
(cast is invisible in assembler code, so it's just a call)
请注意,由于成员函数需要访问 this
,因此编译器也必须传递它。这是一个在 C++ 中不可见的细节,但 this
被视为函数的附加参数 - 因此您会看到两个参数,但函数只接受一个(MSVC 的 thiscall
约定)要求 this
指针在 ecx
中传递)。 IDA 不会费心隐藏该指针,因为这会让人感到困惑。
更多建议:获取ms_rtti
IDA 的脚本并运行它以查找 DLL 中的虚拟方法表,然后搜索对 dword_10087418 的其他引用以查看写入了哪些值 - 您应该能够确定与哪个 vtable 关联该对象,然后找出正在调用哪个函数。
如果您为相关类和虚函数表定义 stub 结构类型,然后告诉 IDA 该指针使用该结构类型,则可以使 Hex-Rays 以更易读的方式显示代码。
关于decompiling - 反编译后的 __thiscall 表达式是指向函数的指针吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16576824/