如何修复 Hex-Rays 反编译器中函数指针调用的类型?

逆向工程 艾达 拆卸
2021-06-26 20:02:25

在调用DirectDraw->BltFast函数的反汇编中,我遇到了以下情况:

(*(void (__stdcall **)(LPDIRECTDRAWSURFACE7, _DWORD, _DWORD, _DWORD, _DWORD, signed int, int, int, int, int))
((void (__stdcall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD))v17->lpVtbl + 7))(
v17,
0,
0,
*(&g_COREvidSurf + 25),
0,
16,
v75,
v77,
v79,
v81);

演员有太多的论点。如何编辑调用的演员表以修复反汇编?

编辑:将结构应用于代码后:

.text:00540825 030                 cmp     [esp+30h+arg_8], ecx
.text:00540829 030                 mov     edx, g_COREvidSurf+64h
.text:0054082F 030                 mov     eax, g_CoreVidsurf_6
.text:00540834 030                 push    10h
.text:00540836 034                 push    0
.text:00540838 038                 push    edx
.text:00540839 03C                 push    0
.text:0054083B 040                 push    0
.text:00540844 044                 mov     ecx, [eax]
.text:00540846 044                 push    eax
.text:00540847 048                 mov     eax,[ecx+IDirectDrawSurface7Vtbl.BltFast]
.text:0054084A 048                 call    eax

和反编译:

v17.lpVtbl = (struct IDirectDrawSurface7::IDirectDrawSurface7Vtbl *)g_surface2;
(*(void (__stdcall **)(struct IDirectDrawSurface7::IDirectDrawSurface7Vtbl *, _DWORD, _DWORD, _DWORD, _DWORD, signed int, int, int, int, int))(*(_DWORD *)v17.lpVtbl + offsetof(IDirectDrawSurface7Vtbl, BltFast)))(
v17.lpVtbl,
0,
0,
*(&g_COREvidSurf + 25),
0,
16,
v75,
v77,
v79,
v81);

使用的结构是从 IDA 中的标准结构选择中选择的,如果我在结构声明中的 BltFast 声明上按“Y”,则调用声明如下:

HRESULT (__stdcall *BltFast)(IDirectDrawSurface7 *This, DWORD, DWORD, LPDIRECTDRAWSURFACE7, LPRECT, DWORD)

这是正确的,但如上所示,IDA 仍然显示太多参数。

1个回答

我会定义一个 vtable 结构,其中包含正确的函数指针。我假设这是一个IDirectDrawSurfaceX? 命名的变量v17->lpVtbl需要有一个类型 IDirectDrawSurfaceX *如果 IDA 已导入 DirectX C 接口定义,则根据 MSDN 上的接口定义创建此函数指针结构或从标准结构加载它。v17->lpVtbl通过y在任何结构类型中按下lpVtbl 的定义来设置的类型v17那么你可能需要将函数指针调用的类型强制为vtable中使用的接口成员的类型。您可以通过右键单击呼叫站点并选择 来执行此操作Force call type