Wednesday, 7 May 2014
Saturday, 29 March 2014
Monday, 17 March 2014
DirectDraw and Assembly
Below is the DirectDraw interface being initialized in the method sub_41A7F0. It tells us that dword_47FF3C is an IDirectDraw object.
mov edx, offset dword_47FF3C
push 0
push edx
push 0
call DirectDrawCreate
push 0
push edx
push 0
call DirectDrawCreate
With that knowledge it is now easier to decode the following:
mov esi, [ebp+arg_0]
mov edx, ds:dword_47FF3C
push 11h
push esi
push edx
mov edx, [edx]
mov eax, [edx+50h]
call eax
mov edx, ds:dword_47FF3C
push 11h
push esi
push edx
mov edx, [edx]
mov eax, [edx+50h]
call eax
Using the IDirectDraw Method Offsets chart below and the ddraw.h file to look up the DDSCL value the above assembly decodes to:
dword_47FF3C->SetCooperativeLevel( arg_0_hWnd, DDSCL_FULLSCREEN );
Now when a method uses dword_47FF3C we know it is part of the video sub-system.
IDirectDraw Method Offsets
Method | Offset | |
---|---|---|
IDirectDraw7_QueryInterface(p, a, b) | (p)->QueryInterface(a, b) | 0 |
IDirectDraw7_AddRef(p) | (p)->AddRef() | 4 |
IDirectDraw7_Release(p) | (p)->Release() | 8 |
IDirectDraw7_Compact(p) | (p)->Compact() | 12 |
IDirectDraw7_CreateClipper(p, a, b, c) | (p)->CreateClipper(a, b, c) | 16 |
IDirectDraw7_CreatePalette(p, a, b, c, d) | (p)->CreatePalette(a, b, c, d) | 20 |
IDirectDraw7_CreateSurface(p, a, b, c) | (p)->CreateSurface(a, b, c) | 24 |
IDirectDraw7_DuplicateSurface(p, a, b) | (p)->DuplicateSurface(a, b) | 28 |
IDirectDraw7_EnumDisplayModes(p, a, b, c, d) | (p)->EnumDisplayModes(a, b, c, d) | 32 |
IDirectDraw7_EnumSurfaces(p, a, b, c, d) | (p)->EnumSurfaces(a, b, c, d) | 36 |
IDirectDraw7_FlipToGDISurface(p) | (p)->FlipToGDISurface() | 40 |
IDirectDraw7_GetCaps(p, a, b) | (p)->GetCaps(a, b) | 44 |
IDirectDraw7_GetDisplayMode(p, a) | (p)->GetDisplayMode(a) | 48 |
IDirectDraw7_GetFourCCCodes(p, a, b) | (p)->GetFourCCCodes(a, b) | 52 |
IDirectDraw7_GetGDISurface(p, a) | (p)->GetGDISurface(a) | 56 |
IDirectDraw7_GetMonitorFrequency(p, a) | (p)->GetMonitorFrequency(a) | 60 |
IDirectDraw7_GetScanLine(p, a) | (p)->GetScanLine(a) | 64 |
IDirectDraw7_GetVerticalBlankStatus(p, a) | (p)->GetVerticalBlankStatus(a) | 68 |
IDirectDraw7_Initialize(p, a) | (p)->Initialize(a) | 72 |
IDirectDraw7_RestoreDisplayMode(p) | (p)->RestoreDisplayMode() | 76 |
IDirectDraw7_SetCooperativeLevel(p, a, b) | (p)->SetCooperativeLevel(a, b) | 80 |
IDirectDraw7_SetDisplayMode(p, a, b, c, d, e) | (p)->SetDisplayMode(a, b, c, d, e) | 84 |
IDirectDraw7_WaitForVerticalBlank(p, a, b) | (p)->WaitForVerticalBlank(a, b) | 88 |
IDirectDraw7_GetAvailableVidMem(p, a, b, c) | (p)->GetAvailableVidMem(a, b, c) | 92 |
IDirectDraw7_GetSurfaceFromDC(p, a, b) | (p)->GetSurfaceFromDC(a, b) | 96 |
IDirectDraw7_RestoreAllSurfaces(p) | (p)->RestoreAllSurfaces() | 100 |
IDirectDraw7_TestCooperativeLevel(p) | (p)->TestCooperativeLevel() | 104 |
IDirectDraw7_GetDeviceIdentifier(p,a,b) | (p)->GetDeviceIdentifier(a,b) | 108 |
IDirectDraw7_StartModeTest(p,a,b,c) | (p)->lpVtbl->StartModeTest(a,b,c) | 112 |
IDirectDraw7_EvaluateMode(p,a,b) | (p)->lpVtbl->EvaluateMode(a,b) | 116 |
IDirectDrawSurface Method Offsets
Method | Offset | |
---|---|---|
IDirectDrawSurface7_QueryInterface(p,a,b) | (p)->lpVtbl->QueryInterface(p,a,b) | 0 |
IDirectDrawSurface7_AddRef(p) | (p)->lpVtbl->AddRef(p) | 4 |
IDirectDrawSurface7_Release(p) | (p)->lpVtbl->Release(p) | 8 |
IDirectDrawSurface7_AddAttachedSurface(p,a) | (p)->lpVtbl->AddAttachedSurface(p,a) | 12 |
IDirectDrawSurface7_AddOverlayDirtyRect(p,a) | (p)->lpVtbl->AddOverlayDirtyRect(p,a) | 16 |
IDirectDrawSurface7_Blt(p,a,b,c,d,e) | (p)->lpVtbl->Blt(p,a,b,c,d,e) | 20 |
IDirectDrawSurface7_BltBatch(p,a,b,c) | (p)->lpVtbl->BltBatch(p,a,b,c) | 24 |
IDirectDrawSurface7_BltFast(p,a,b,c,d,e) | (p)->lpVtbl->BltFast(p,a,b,c,d,e) | 28 |
IDirectDrawSurface7_DeleteAttachedSurface(p,a,b) | (p)->lpVtbl->DeleteAttachedSurface(p,a,b) | 32 |
IDirectDrawSurface7_EnumAttachedSurfaces(p,a,b) | (p)->lpVtbl->EnumAttachedSurfaces(p,a,b) | 36 |
IDirectDrawSurface7_EnumOverlayZOrders(p,a,b,c) | (p)->lpVtbl->EnumOverlayZOrders(p,a,b,c) | 40 |
IDirectDrawSurface7_Flip(p,a,b) | (p)->lpVtbl->Flip(p,a,b) | 44 |
IDirectDrawSurface7_GetAttachedSurface(p,a,b) | (p)->lpVtbl->GetAttachedSurface(p,a,b) | 48 |
IDirectDrawSurface7_GetBltStatus(p,a) | (p)->lpVtbl->GetBltStatus(p,a) | 52 |
IDirectDrawSurface7_GetCaps(p,b) | (p)->lpVtbl->GetCaps(p,b) | 56 |
IDirectDrawSurface7_GetClipper(p,a) | (p)->lpVtbl->GetClipper(p,a) | 60 |
IDirectDrawSurface7_GetColorKey(p,a,b) | (p)->lpVtbl->GetColorKey(p,a,b) | 64 |
IDirectDrawSurface7_GetDC(p,a) | (p)->lpVtbl->GetDC(p,a) | 68 |
IDirectDrawSurface7_GetFlipStatus(p,a) | (p)->lpVtbl->GetFlipStatus(p,a) | 72 |
IDirectDrawSurface7_GetOverlayPosition(p,a,b) | (p)->lpVtbl->GetOverlayPosition(p,a,b) | 76 |
IDirectDrawSurface7_GetPalette(p,a) | (p)->lpVtbl->GetPalette(p,a) | 80 |
IDirectDrawSurface7_GetPixelFormat(p,a) | (p)->lpVtbl->GetPixelFormat(p,a) | 84 |
IDirectDrawSurface7_GetSurfaceDesc(p,a) | (p)->lpVtbl->GetSurfaceDesc(p,a) | 88 |
IDirectDrawSurface7_Initialize(p,a,b) | (p)->lpVtbl->Initialize(p,a,b) | 92 |
IDirectDrawSurface7_IsLost(p) | (p)->lpVtbl->IsLost(p) | 96 |
IDirectDrawSurface7_Lock(p,a,b,c,d) | (p)->lpVtbl->Lock(p,a,b,c,d) | 100 |
IDirectDrawSurface7_ReleaseDC(p,a) | (p)->lpVtbl->ReleaseDC(p,a) | 104 |
IDirectDrawSurface7_Restore(p) | (p)->lpVtbl->Restore(p) | 108 |
IDirectDrawSurface7_SetClipper(p,a) | (p)->lpVtbl->SetClipper(p,a) | 112 |
IDirectDrawSurface7_SetColorKey(p,a,b) | (p)->lpVtbl->SetColorKey(p,a,b) | 116 |
IDirectDrawSurface7_SetOverlayPosition(p,a,b) | (p)->lpVtbl->SetOverlayPosition(p,a,b) | 120 |
IDirectDrawSurface7_SetPalette(p,a) | (p)->lpVtbl->SetPalette(p,a) | 124 |
IDirectDrawSurface7_Unlock(p,b) | (p)->lpVtbl->Unlock(p,b) | 128 |
IDirectDrawSurface7_UpdateOverlay(p,a,b,c,d,e) | (p)->lpVtbl->UpdateOverlay(p,a,b,c,d,e) | 132 |
IDirectDrawSurface7_UpdateOverlayDisplay(p,a) | (p)->lpVtbl->UpdateOverlayDisplay(p,a) | 136 |
IDirectDrawSurface7_UpdateOverlayZOrder(p,a,b) | (p)->lpVtbl->UpdateOverlayZOrder(p,a,b) | 140 |
IDirectDrawSurface7_GetDDInterface(p,a) | (p)->lpVtbl->GetDDInterface(p,a) | 144 |
IDirectDrawSurface7_PageLock(p,a) | (p)->lpVtbl->PageLock(p,a) | 148 |
IDirectDrawSurface7_PageUnlock(p,a) | (p)->lpVtbl->PageUnlock(p,a) | 152 |
IDirectDrawSurface7_SetSurfaceDesc(p,a,b) | (p)->lpVtbl->SetSurfaceDesc(p,a,b) | 156 |
IDirectDrawSurface7_SetPrivateData(p,a,b,c,d) | (p)->lpVtbl->SetPrivateData(p,a,b,c,d) | 160 |
IDirectDrawSurface7_GetPrivateData(p,a,b,c) | (p)->lpVtbl->GetPrivateData(p,a,b,c) | 164 |
IDirectDrawSurface7_FreePrivateData(p,a) | (p)->lpVtbl->FreePrivateData(p,a) | 168 |
IDirectDrawSurface7_GetUniquenessValue(p, a) | (p)->lpVtbl->GetUniquenessValue(p, a) | 172 |
IDirectDrawSurface7_ChangeUniquenessValue(p) | (p)->lpVtbl->ChangeUniquenessValue(p) | 176 |
IDirectDrawSurface7_SetPriority(p,a) | (p)->lpVtbl->SetPriority(p,a) | 180 |
IDirectDrawSurface7_GetPriority(p,a) | (p)->lpVtbl->GetPriority(p,a) | 184 |
IDirectDrawSurface7_SetLOD(p,a) | (p)->lpVtbl->SetLOD(p,a) | 188 |
IDirectDrawSurface7_GetLOD(p,a) | (p)->lpVtbl->GetLOD(p,a) | 192 |
Blade Runner shipped with DirectX 5, so be careful.
Sunday, 9 March 2014
I'm decoding the file sub-system now. When I'm done I will post my notes on how it works. Most of the reverse engineering has taken place in notepad++ by reading the ASM file in one tab and writing pseudo code in another tab. I use hex editor plugin for notepad++ to view the resource files.
Architecture
From an architecture perspective BLADE.EXE is a black box that receives input (mouse/keyboard) and generates output (screen and files). As this project progresses the diagram below will show the internal architecture of BLADE.EXE.Sunday, 23 February 2014
Goals
The goal of this project is to reverse engineer Westwood Studios' Blade Runner and reimplement the game logic in a framework such as ScummVM or ResidualVM.Tools
The tools that I'm going to use to decode Blade Runner's game logic are OllyDbg and Hex-Rays IDA Freeware 5.0.Files
The core of this project revolves around two files (to view click link on side panel under Pages):BLADE.ASM --assembly code generated by Hex-Rays IDA 5.0.
BLADE.CPP --pseudo C/C++ code derived from BLADE.ASM
Subscribe to:
Posts (Atom)