vcvars32 dumpbin /EXPORTS c:\windows\system32\ddraw.dll
As a result, we get: ordinal hint RVA name 1 0 00002E69 AcquireDDThreadLock 2 1 000327FA CompleteCreateSysmemSurface 3 2 00032FAE D3DParseUnknownCommand 4 3 00033EEF DDGetAttachedSurfaceLcl 5 4 000325D7 DDInternalLock 6 5 0003258C DDInternalUnlock 7 6 000363FC DSoundHelp 8 7 0000859D DirectDrawCreate 9 8 00037851 DirectDrawCreateClipper 10 9 0000EBC6 DirectDrawCreateEx 11 A 000338C9 DirectDrawEnumerateA 12 B 00033368 DirectDrawEnumerateExA 13 C 00032CB2 DirectDrawEnumerateExW 14 D 0003333B DirectDrawEnumerateW 15 E 000387C1 DllCanUnloadNow 16 F 00038607 DllGetClassObject 17 10 00032675 GetDDSurfaceLocal 18 11 0003A5F9 GetOLEThunkData 19 12 0000E927 GetSurfaceFromDC 20 13 00027CC4 RegisterSpecialCase 21 14 00002EA8 ReleaseDDThreadLock 22 15 000421A6 SetAppCompatData
/NODEFAULTLIB
parameter and specifying the DllMain
entry DllMain
. This will greatly benefit in volume. Further in the DEF file we indicate the exported functions in the following form: LIBRARY "ddraw" EXPORTS AcquireDDThreadLock = FakeAcquireDDThreadLock @1 CheckFullscreen = FakeCheckFullscreen @2 CompleteCreateSysmemSurface = FakeCompleteCreateSysmemSurface @3 D3DParseUnknownCommand = FakeD3DParseUnknownCommand @4 ...
__declspec(naked) void FakeAcquireDDThreadLock() { _asm { jmp [ddraw.AcquireDDThreadLock] } }
Using __declspec(naked)
we force the compiler to not generate the standard prologue and epilogue code that insert data onto the stack. As a result, the data in the stack is already stored in a suitable form, and we can simply transfer control of the original function with one jmp
command without jmp
parameters to the stack. struct ddraw_dll { HMODULE dll; FARPROC AcquireDDThreadLock; FARPROC CheckFullscreen; FARPROC CompleteCreateSysmemSurface; FARPROC D3DParseUnknownCommand; // ... ... } ddraw;
This structure is filled in DllMain at the time of loading our proxy dll. First we load the original library, then in turn we get the addresses of all the exported functions. The code will look something like this: BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { char path[MAX_PATH]; switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: CopyMemory(path+GetSystemDirectory(path,MAX_PATH-10), "\\ddraw.dll",11); ddraw.dll = LoadLibrary(path); if (ddraw.dll == false) { MessageBox(0, "Cannot load original ddraw.dll library", APP_NAME, MB_ICONERROR); ExitProcess(0); } ddraw.AcquireDDThreadLock = GetProcAddress(ddraw.dll, "AcquireDDThreadLock"); ddraw.CheckFullscreen = GetProcAddress(ddraw.dll, "CheckFullscreen"); ddraw.CompleteCreateSysmemSurface = GetProcAddress(ddraw.dll, "CompleteCreateSysmemSurface"); ddraw.D3DParseUnknownCommand = GetProcAddress(ddraw.dll, "D3DParseUnknownCommand"); // ... ... break; case DLL_PROCESS_DETACH: FreeLibrary(ddraw.dll); break; } return TRUE; }
DirectDrawCreate
function so that it returns the IDirectDraw structure with the replaced addresses of methods whose behavior we would like to change to achieve the final goal.DllMain
by adding one line to the case DLL_PROCESS_ATTACH
: LoadLibrary("wndmode.dll");
The rest of the changes to your taste :) [WINDOWMODE] UseWindowMode=1 UseGDI=0 UseDirect3D=0 UseDirectInput=0 UseDirectDraw=1 UseDDrawColorEmulate=1 UseDDrawFlipBlt=0 UseDDrawColorConvert=1 UseDDrawPrimaryBlt=1 UseDDrawAutoBlt=0 UseDDrawEmulate=0 UseDDrawPrimaryLost=0 UseCursorMsg=0 UseCursorSet=0 UseCursorGet=0 UseSpeedHack=0 SpeedHackMultiple=10 UseBackgroundResize=0 UseForegroundControl=0 UseFGCGetActiveWindow=0 UseFGCGetForegroundWindow=0 UseFGCFixedWindowPosition=0 EnableExtraKey=0 ShowFps=0 UseCursorClip=0 UseBackgroundPriority=0 DDrawBltWait=-1 Border=1
Source: https://habr.com/ru/post/133956/
All Articles