diff --git a/DDraw/dllmain.cpp b/DDraw/dllmain.cpp index b644584..306719d 100644 --- a/DDraw/dllmain.cpp +++ b/DDraw/dllmain.cpp @@ -21,99 +21,6 @@ extern "C" HRESULT WINAPI DirectDrawCreateEx(GUID FAR *lpGUID, LPVOID *lplpDD, R HMODULE hLib = LoadLibraryW(wcSystemPath); pDirectDrawCreateEx = (HRESULT(WINAPI*)(GUID FAR*, LPVOID*, REFIID, IUnknown FAR*))GetProcAddress(hLib, "DirectDrawCreateEx"); - - static char aNoDesktopMode[64]; - - RECT desktop; - GetWindowRect(GetDesktopWindow(), &desktop); - sprintf(aNoDesktopMode, "Cannot find %dx%dx32 video mode", desktop.right, desktop.bottom); - - using namespace MemoryVP; - - if (*(DWORD*)0x5C1E70 == 0x53E58955) - { - // III 1.0 - Patch(0x581E5E, desktop.right); - Patch(0x581E68, desktop.bottom); - Patch(0x581E72, 32); - Patch(0x581EA8, aNoDesktopMode); - - // No 12mb vram check - Patch(0x581411, 0xEB); - } - else if (*(DWORD*)0x5C2130 == 0x53E58955) - { - // III 1.1 - Patch(0x58219E, desktop.right); - Patch(0x5821A8, desktop.bottom); - Patch(0x5821B2, 32); - Patch(0x5821E8, aNoDesktopMode); - - // No 12mb vram check - Patch(0x581753, 0xEB); - } - else if (*(DWORD*)0x5C6FD0 == 0x53E58955) - { - // III Steam - Patch(0x58208E, desktop.right); - Patch(0x582098, desktop.bottom); - Patch(0x5820A2, 32); - Patch(0x5820D8, aNoDesktopMode); - - // No 12mb vram check - Patch(0x581653, 0xEB); - } - - else if (*(DWORD*)0x667BF0 == 0x53E58955) - { - // VC 1.0 - Patch(0x600E7E, desktop.right); - Patch(0x600E88, desktop.bottom); - Patch(0x600E92, 32); - Patch(0x600EC8, aNoDesktopMode); - - // No 12mb vram check - Patch(0x601E26, 0xEB); - } - else if (*(DWORD*)0x667C40 == 0x53E58955) - { - // VC 1.1 - Patch(0x600E9E, desktop.right); - Patch(0x600EA8, desktop.bottom); - Patch(0x600EB2, 32); - Patch(0x600EE8, aNoDesktopMode); - - // No 12mb vram check - Patch(0x601E56, 0xEB); - } - else if (*(DWORD*)0x666BA0 == 0x53E58955) - { - // VC Steam - Patch(0x600ADE, desktop.right); - Patch(0x600AE8, desktop.bottom); - Patch(0x600AF2, 32); - Patch(0x600B28, aNoDesktopMode); - - // No 12mb vram check - Patch(0x601A96, 0xEB); - } - - // Give _rwcseg proper access rights - HMODULE hModule = GetModuleHandle(nullptr); - IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)((ptrdiff_t)hModule + ((IMAGE_DOS_HEADER*)hModule)->e_lfanew); - WORD NumberOfSections = ntHeader->FileHeader.NumberOfSections; - IMAGE_SECTION_HEADER* pSection = IMAGE_FIRST_SECTION(ntHeader); - - for ( WORD i = 0; i < NumberOfSections; i++ ) - { - if ( *(uint64_t*)(pSection->Name) == 0x006765736377725F ) // _rwcseg - { - DWORD dwProtect; - VirtualProtect((LPVOID)((ptrdiff_t)hModule + pSection->VirtualAddress), pSection->Misc.VirtualSize, PAGE_EXECUTE_READ, &dwProtect); - break; - } - pSection++; - } } return pDirectDrawCreateEx(lpGUID, lplpDD, iid, pUnkOuter); } @@ -128,11 +35,209 @@ char* GetMyDocumentsPath() { SHGetFolderPath(nullptr, CSIDL_MYDOCUMENTS, nullptr, SHGFP_TYPE_CURRENT, cUserFilesPath); PathAppend(cUserFilesPath, *ppUserFilesDir); + CreateDirectory(cUserFilesPath, nullptr); } return cUserFilesPath; } + +void InjectHooks() +{ + using namespace MemoryVP; + + static char aNoDesktopMode[64]; + + RECT desktop; + GetWindowRect(GetDesktopWindow(), &desktop); + sprintf(aNoDesktopMode, "Cannot find %dx%dx32 video mode", desktop.right, desktop.bottom); + + if (*(DWORD*)0x5C1E75 == 0xB85548EC) + { + // III 1.0 + ppUserFilesDir = (char**)0x580C16; + InjectHook(0x580BB0, GetMyDocumentsPath, PATCH_JUMP); + + Patch(0x581E5E, desktop.right); + Patch(0x581E68, desktop.bottom); + Patch(0x581E72, 32); + Patch(0x581EA8, aNoDesktopMode); + + // No 12mb vram check + Patch(0x581411, 0xEB); + + // No DirectPlay dependency + Patch(0x5812D6, 0xB8); + Patch(0x5812D7, 0x900); + } + else if (*(DWORD*)0x5C2135 == 0xB85548EC) + { + // III 1.1 + ppUserFilesDir = (char**)0x580F66; + InjectHook(0x580F00, GetMyDocumentsPath, PATCH_JUMP); + + Patch(0x58219E, desktop.right); + Patch(0x5821A8, desktop.bottom); + Patch(0x5821B2, 32); + Patch(0x5821E8, aNoDesktopMode); + + // No 12mb vram check + Patch(0x581753, 0xEB); + + // No DirectPlay dependency + Patch(0x581620, 0xB8); + Patch(0x581621, 0x900); + } + else if (*(DWORD*)0x5C6FD5 == 0xB85548EC) + { + // III Steam + ppUserFilesDir = (char**)0x580E66; + InjectHook(0x580E00, GetMyDocumentsPath, PATCH_JUMP); + + Patch(0x58208E, desktop.right); + Patch(0x582098, desktop.bottom); + Patch(0x5820A2, 32); + Patch(0x5820D8, aNoDesktopMode); + + // No 12mb vram check + Patch(0x581653, 0xEB); + + // No DirectPlay dependency + Patch(0x581520, 0xB8); + Patch(0x581521, 0x900); + } + + else if (*(DWORD*)0x667BF5 == 0xB85548EC) + { + // VC 1.0 + ppUserFilesDir = (char**)0x6022AA; + InjectHook(0x602240, GetMyDocumentsPath, PATCH_JUMP); + + InjectHook(0x601A40, GetMyDocumentsPath, PATCH_CALL); + InjectHook(0x601A45, 0x601B2F, PATCH_JUMP); + + Patch(0x600E7E, desktop.right); + Patch(0x600E88, desktop.bottom); + Patch(0x600E92, 32); + Patch(0x600EC8, aNoDesktopMode); + + // No 12mb vram check + Patch(0x601E26, 0xEB); + + // No DirectPlay dependency + Patch(0x601CA0, 0xB8); + Patch(0x601CA1, 0x900); + } + else if (*(DWORD*)0x667C45 == 0xB85548EC) + { + // VC 1.1 + ppUserFilesDir = (char**)0x60228A; + InjectHook(0x602220, GetMyDocumentsPath, PATCH_JUMP); + + InjectHook(0x601A70, GetMyDocumentsPath, PATCH_CALL); + InjectHook(0x601A75, 0x601B5F, PATCH_JUMP); + + Patch(0x600E9E, desktop.right); + Patch(0x600EA8, desktop.bottom); + Patch(0x600EB2, 32); + Patch(0x600EE8, aNoDesktopMode); + + // No 12mb vram check + Patch(0x601E56, 0xEB); + + // No DirectPlay dependency + Patch(0x601CD0, 0xB8); + Patch(0x601CD1, 0x900); + } + else if (*(DWORD*)0x666BA5 == 0xB85548EC) + { + // VC Steam + ppUserFilesDir = (char**)0x601ECA; + InjectHook(0x601E60, GetMyDocumentsPath, PATCH_JUMP); + + InjectHook(0x6016B0, GetMyDocumentsPath, PATCH_CALL); + InjectHook(0x6016B5, 0x60179F, PATCH_JUMP); + + Patch(0x600ADE, desktop.right); + Patch(0x600AE8, desktop.bottom); + Patch(0x600AF2, 32); + Patch(0x600B28, aNoDesktopMode); + + // No 12mb vram check + Patch(0x601A96, 0xEB); + + // No DirectPlay dependency + Patch(0x601910, 0xB8); + Patch(0x601911, 0x900); + } +} + + +static VOID (WINAPI* pOrgGetStartupInfoA)(LPSTARTUPINFOA); +VOID WINAPI GetStartupInfoA_Hook(LPSTARTUPINFOA lpStartupInfo) +{ + static bool bPatched = false; + if ( !bPatched ) + { + using namespace MemoryVP; + + bPatched = true; + + InjectHooks(); + } + pOrgGetStartupInfoA(lpStartupInfo); +} + +static HINSTANCE hInstance; +void PatchIAT() +{ + IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)((DWORD)hInstance + ((IMAGE_DOS_HEADER*)hInstance)->e_lfanew); + + // Give _rwcseg proper access rights + WORD NumberOfSections = ntHeader->FileHeader.NumberOfSections; + IMAGE_SECTION_HEADER* pSection = IMAGE_FIRST_SECTION(ntHeader); + + for ( WORD i = 0; i < NumberOfSections; i++, pSection++ ) + { + if ( *(uint64_t*)(pSection->Name) == 0x006765736377725F ) // _rwcseg + { + DWORD dwProtect; + VirtualProtect((LPVOID)((ptrdiff_t)hInstance + pSection->VirtualAddress), pSection->Misc.VirtualSize, PAGE_EXECUTE_READ, &dwProtect); + break; + } + } + + // Find IAT + IMAGE_IMPORT_DESCRIPTOR* pImports = (IMAGE_IMPORT_DESCRIPTOR*)((DWORD)hInstance + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); + + // Find kernel32.dll + for ( ; pImports->Name != 0; pImports++ ) + { + if ( !_stricmp((const char*)((DWORD)hInstance + pImports->Name), "KERNEL32.DLL") ) + { + IMAGE_IMPORT_BY_NAME** pFunctions = (IMAGE_IMPORT_BY_NAME**)((DWORD)hInstance + pImports->OriginalFirstThunk); + + // kernel32.dll found, find GetStartupInfoA + for ( ptrdiff_t j = 0; pFunctions[j] != nullptr; j++ ) + { + if ( !strcmp((const char*)((DWORD)hInstance + pFunctions[j]->Name), "GetStartupInfoA") ) + { + // Overwrite the address with the address to a custom GetStartupInfoA + DWORD dwProtect[2]; + DWORD_PTR* pAddress = &((DWORD_PTR*)((DWORD)hInstance + pImports->FirstThunk))[j]; + + VirtualProtect(pAddress, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &dwProtect[0]); + pOrgGetStartupInfoA = **(VOID(WINAPI**)(LPSTARTUPINFOA))pAddress; + *pAddress = (DWORD)GetStartupInfoA_Hook; + VirtualProtect(pAddress, sizeof(DWORD), dwProtect[0], &dwProtect[1]); + + return; + } + } + } + } +} + BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { UNREFERENCED_PARAMETER(hinstDLL); @@ -140,79 +245,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) if ( fdwReason == DLL_PROCESS_ATTACH ) { - using namespace MemoryVP; DisableThreadLibraryCalls(hinstDLL); - if (*(DWORD*)0x5C1E75 == 0xB85548EC) - { - // III 1.0 - ppUserFilesDir = (char**)0x580C16; - InjectHook(0x580BB0, GetMyDocumentsPath, PATCH_JUMP); - - // No DirectPlay dependency - Patch(0x5812D6, 0xB8); - Patch(0x5812D7, 0x900); - } - else if (*(DWORD*)0x5C2135 == 0xB85548EC) - { - // III 1.1 - ppUserFilesDir = (char**)0x580F66; - InjectHook(0x580F00, GetMyDocumentsPath, PATCH_JUMP); - - // No DirectPlay dependency - Patch(0x581620, 0xB8); - Patch(0x581621, 0x900); - } - else if (*(DWORD*)0x5C6FD5 == 0xB85548EC) - { - // III Steam - ppUserFilesDir = (char**)0x580E66; - InjectHook(0x580E00, GetMyDocumentsPath, PATCH_JUMP); - - // No DirectPlay dependency - Patch(0x581520, 0xB8); - Patch(0x581521, 0x900); - } - - else if (*(DWORD*)0x667BF5 == 0xB85548EC) - { - // VC 1.0 - ppUserFilesDir = (char**)0x6022AA; - InjectHook(0x602240, GetMyDocumentsPath, PATCH_JUMP); - - InjectHook(0x601A40, GetMyDocumentsPath, PATCH_CALL); - InjectHook(0x601A45, 0x601B2F, PATCH_JUMP); - - // No DirectPlay dependency - Patch(0x601CA0, 0xB8); - Patch(0x601CA1, 0x900); - } - else if (*(DWORD*)0x667C45 == 0xB85548EC) - { - // VC 1.1 - ppUserFilesDir = (char**)0x60228A; - InjectHook(0x602220, GetMyDocumentsPath, PATCH_JUMP); - - InjectHook(0x601A70, GetMyDocumentsPath, PATCH_CALL); - InjectHook(0x601A75, 0x601B5F, PATCH_JUMP); - - // No DirectPlay dependency - Patch(0x601CD0, 0xB8); - Patch(0x601CD1, 0x900); - } - else if (*(DWORD*)0x666BA5 == 0xB85548EC) - { - // VC Steam - ppUserFilesDir = (char**)0x601ECA; - InjectHook(0x601E60, GetMyDocumentsPath, PATCH_JUMP); - - InjectHook(0x6016B0, GetMyDocumentsPath, PATCH_CALL); - InjectHook(0x6016B5, 0x60179F, PATCH_JUMP); - - // No DirectPlay dependency - Patch(0x601910, 0xB8); - Patch(0x601911, 0x900); - } + hInstance = GetModuleHandle(nullptr); + PatchIAT(); } return TRUE;