5

I'm reversing an old DirectDraw game that uses DirectX 7.

I have a LPDIRECTDRAWSURFACE7 g_lpDDSBack and g_lpDDSBack->BltFast is being called but this is how it is decompiled in HexRays:

(*(int (__stdcall **)(struct IDirectDrawSurface7Vtbl *, int, int, LPDIRECTDRAWSURFACE7, RECT *, MACRO_DDBLTFAST))((int (__stdcall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD))g_lpDDSBack->QueryInterface + 7))(
                                      g_lpDDSBack,
                                      x,
                                      y,
                                      pgf2->lpDDSrcSurface,
                                      &pgf2->rect,
                                      DDBLTFAST_SRCCOLORKEY);

For reference, here is the interface:

DECLARE_INTERFACE_( IDirectDrawSurface7, IUnknown )
{
    /*** IUnknown methods ***/
    STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; // 0
    STDMETHOD_(ULONG,AddRef) (THIS)  PURE; // 1
    STDMETHOD_(ULONG,Release) (THIS) PURE; // 2
    /*** IDirectDrawSurface methods ***/
    STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE7) PURE; // 3
    STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT) PURE; // 4
    STDMETHOD(Blt)(THIS_ LPRECT,LPDIRECTDRAWSURFACE7, LPRECT,DWORD, LPDDBLTFX) PURE; // 5
    STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH, DWORD, DWORD ) PURE; // 6
    STDMETHOD(BltFast)(THIS_ DWORD,DWORD,LPDIRECTDRAWSURFACE7, LPRECT,DWORD) PURE; // 7
    // etc ...

So from the HexRays code g_lpDDSBack->QueryInterface + 7, we can see it's calling g_lpDDSBack->BltFast. But why doesn't HexRays directly call BltFast?

2

HexRays doesn't call it because it doesn't know what is the value of g_lpDDSBack->QueryInterface in the common case.

Generally speaking you can define a structure as a QueryInterface type, where members of this structure are named according to the related function names and than you'll see the call as g_lpDDSBack->QueryInterface->BltFast .

0

It turned out to be a bug in IDA pro. I can't seem to edit my original question so first, I want to point out an error I made in the original question.


When g_lpDDSBack is defined as struct IDirectDrawSurface7Vtbl *g_lpDDSBack;, then this was the output HexRays was showing:

(*(int (__stdcall **)(struct IDirectDrawSurface7Vtbl *, int, int, LPDIRECTDRAWSURFACE7, RECT *, MACRO_DDBLTFAST))((int (__stdcall **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD))g_lpDDSBack->QueryInterface + 7))(
                                      g_lpDDSBack,
                                      x,
                                      y,
                                      pgf2->lpDDSrcSurface,
                                      &pgf2->rect,
                                      DDBLTFAST_SRCCOLORKEY);

When g_lpDDSBack is defined as LPDIRECTDRAWSURFACE7 g_lpDDSBack;, then this was the output HexRays was showing:

(*((int (__stdcall **)(int, int, int, _DWORD, int, signed int))g_lpDDSBack->lpVtbl + 7))(
                       g_lpDDSBack,
                       x,
                       y,
                       pgf2->lpDDSrcSurface,
                       &pgf2->rect,
                       DDBLTFAST_SRCCOLORKEY);

Alright, now here are the instructions to fixing the bug (g_lpDDSBack is defined as LPDIRECTDRAWSURFACE7 g_lpDDSBack;):

  1. Select lpVtbl in g_lpDDSBack->lpVtbl, press y and then copy the contents of the textbox to a notepad. In this case, the contents were struct IDirectDrawSurface7::IDirectDrawSurface7Vtbl *lpVtbl.
  2. Change the type to int lpVtbl and press OK
  3. Press y again on lpVtbl and change the type back to its original type stored in notepad. In this case, it is struct IDirectDrawSurface7::IDirectDrawSurface7Vtbl *lpVtbl.

After doing this, this is how it looks like in HexRays (you might have to press F5 first):

g_lpDDSBack->lpVtbl->BltFast(g_lpDDSBack,
                                      x,
                                      y,
                                      pgf2->lpDDSrcSurface,
                                      &pgf2->rect,
                                      DDBLTFAST_SRCCOLORKEY);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.