In continuation of the topic of extending the functionality of ready-made programs, I would like to talk about another way of changing the logic of the already compiled program, which does not require making changes in the executable file itself. This can come in handy when distributing your modification in the United States, where direct interference with the executable file is strongly condemned. It will be about creating a tiny proxy dll (just ≈4 kilobytes) to replace the library used by the application using the example ddraw.dll.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