Wednesday 7 May 2014

Finished decoding the initialization method, skipped over AI-ACT1 setup methods, working on decoding the game loop.
MIX Specification see page located on right panel.

Saturday 29 March 2014

I have successfully decoded the first image encountered in Blade Runner [SPLASH.IMG]. I'm working on a specification for Westwood's MIX file format that I will post soon.

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

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

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

MethodOffset
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

MethodOffset
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