mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-12-29 15:23:02 +05:00
UPX-friendly ddraw (should be cleaned up a bit though)
This commit is contained in:
parent
a5380e3c5f
commit
01dfbda6fd
3 changed files with 97 additions and 19 deletions
|
@ -150,6 +150,7 @@ copy /y "$(TargetPath)" "D:\Steam\steamapps\common\Grand Theft Auto Vice City\dd
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\SilentPatch\Patterns.cpp" />
|
||||||
<ClCompile Include="dllmain.cpp" />
|
<ClCompile Include="dllmain.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -157,6 +158,7 @@ copy /y "$(TargetPath)" "D:\Steam\steamapps\common\Grand Theft Auto Vice City\dd
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\SilentPatch\MemoryMgr.h" />
|
<ClInclude Include="..\SilentPatch\MemoryMgr.h" />
|
||||||
|
<ClInclude Include="..\SilentPatch\Patterns.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
|
|
@ -18,11 +18,17 @@
|
||||||
<ClCompile Include="dllmain.cpp">
|
<ClCompile Include="dllmain.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\SilentPatch\Patterns.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\SilentPatch\MemoryMgr.h">
|
<ClInclude Include="..\SilentPatch\MemoryMgr.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\SilentPatch\Patterns.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="..\SilentPatch\SilentPatch.rc">
|
<ResourceCompile Include="..\SilentPatch\SilentPatch.rc">
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <Shlwapi.h>
|
#include <Shlwapi.h>
|
||||||
#include <ShlObj.h>
|
#include <ShlObj.h>
|
||||||
#include "MemoryMgr.h"
|
#include "MemoryMgr.h"
|
||||||
|
#include "Patterns.h"
|
||||||
|
|
||||||
#pragma comment(lib, "shlwapi.lib")
|
#pragma comment(lib, "shlwapi.lib")
|
||||||
|
|
||||||
|
@ -173,8 +174,10 @@ void InjectHooks()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static VOID (WINAPI* pOrgGetStartupInfoA)(LPSTARTUPINFOA);
|
static bool FixRwcseg_Patterns();
|
||||||
VOID WINAPI GetStartupInfoA_Hook(LPSTARTUPINFOA lpStartupInfo)
|
static bool rwcsegUnprotected = false;
|
||||||
|
|
||||||
|
static void ProcHook()
|
||||||
{
|
{
|
||||||
static bool bPatched = false;
|
static bool bPatched = false;
|
||||||
if ( !bPatched )
|
if ( !bPatched )
|
||||||
|
@ -182,24 +185,44 @@ VOID WINAPI GetStartupInfoA_Hook(LPSTARTUPINFOA lpStartupInfo)
|
||||||
bPatched = true;
|
bPatched = true;
|
||||||
|
|
||||||
InjectHooks();
|
InjectHooks();
|
||||||
|
|
||||||
|
if ( !rwcsegUnprotected )
|
||||||
|
{
|
||||||
|
rwcsegUnprotected = FixRwcseg_Patterns();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID (WINAPI* pOrgGetStartupInfoA)(LPSTARTUPINFOA);
|
||||||
|
VOID WINAPI GetStartupInfoA_Hook(LPSTARTUPINFOA lpStartupInfo)
|
||||||
|
{
|
||||||
|
ProcHook();
|
||||||
pOrgGetStartupInfoA(lpStartupInfo);
|
pOrgGetStartupInfoA(lpStartupInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatchIAT()
|
static uint8_t orgCode[5];
|
||||||
|
static decltype(SystemParametersInfoA)* pOrgSystemParametersInfoA;
|
||||||
|
BOOL WINAPI SystemParametersInfoA_OverwritingHook( UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni )
|
||||||
|
{
|
||||||
|
ProcHook();
|
||||||
|
Memory::VP::Patch( pOrgSystemParametersInfoA, { orgCode[0], orgCode[1], orgCode[2], orgCode[3], orgCode[4] } );
|
||||||
|
return pOrgSystemParametersInfoA( uiAction, uiParam, pvParam, fWinIni );
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool FixRwcseg_Header()
|
||||||
{
|
{
|
||||||
HINSTANCE hInstance = GetModuleHandle(nullptr);
|
HINSTANCE hInstance = GetModuleHandle(nullptr);
|
||||||
IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)((DWORD)hInstance + ((IMAGE_DOS_HEADER*)hInstance)->e_lfanew);
|
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)hInstance + ((PIMAGE_DOS_HEADER)hInstance)->e_lfanew);
|
||||||
|
|
||||||
// Give _rwcseg proper access rights
|
// Give _rwcseg proper access rights
|
||||||
IMAGE_SECTION_HEADER* pSection = IMAGE_FIRST_SECTION(ntHeader);
|
PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(ntHeader);
|
||||||
|
|
||||||
for ( SIZE_T i = 0, j = ntHeader->FileHeader.NumberOfSections; i < j; i++, pSection++ )
|
for ( SIZE_T i = 0, j = ntHeader->FileHeader.NumberOfSections; i < j; i++, pSection++ )
|
||||||
{
|
{
|
||||||
if ( *(uint64_t*)(pSection->Name) == 0x006765736377725F ) // _rwcseg
|
if ( *(uint64_t*)(pSection->Name) == 0x006765736377725F ) // _rwcseg
|
||||||
{
|
{
|
||||||
DWORD dwProtect;
|
DWORD dwProtect;
|
||||||
VirtualProtect((LPVOID)((ptrdiff_t)hInstance + pSection->VirtualAddress), pSection->Misc.VirtualSize, PAGE_EXECUTE_READ, &dwProtect);
|
VirtualProtect((LPVOID)((DWORD_PTR)hInstance + pSection->VirtualAddress), pSection->Misc.VirtualSize, PAGE_EXECUTE_READ, &dwProtect);
|
||||||
|
|
||||||
DWORD Characteristics = pSection->Characteristics;
|
DWORD Characteristics = pSection->Characteristics;
|
||||||
if ( (Characteristics & IMAGE_SCN_CNT_CODE) == 0 )
|
if ( (Characteristics & IMAGE_SCN_CNT_CODE) == 0 )
|
||||||
|
@ -218,39 +241,88 @@ void PatchIAT()
|
||||||
Memory::VP::Patch( &ntHeader->OptionalHeader.SizeOfUninitializedData, ntHeader->OptionalHeader.SizeOfUninitializedData - pSection->Misc.VirtualSize );
|
Memory::VP::Patch( &ntHeader->OptionalHeader.SizeOfUninitializedData, ntHeader->OptionalHeader.SizeOfUninitializedData - pSection->Misc.VirtualSize );
|
||||||
}
|
}
|
||||||
Memory::VP::Patch( &pSection->Characteristics, Characteristics );
|
Memory::VP::Patch( &pSection->Characteristics, Characteristics );
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool FixRwcseg_Patterns()
|
||||||
|
{
|
||||||
|
using namespace hook;
|
||||||
|
|
||||||
|
auto begin = pattern( "55 8B EC 50 53 51 52 8B 5D 14 8B 4D 10 8B 45 0C 8B 55 08" ).count_hint(1000);
|
||||||
|
auto end = pattern( "9B D9 3D ? ? ? ? 81 25 ? ? ? ? FF FC FF FF 83 0D ? ? ? ? 3F" ).count_hint(1000);
|
||||||
|
|
||||||
|
if ( begin.count_hint(1).size() == 1 && end.count_hint(1).size() == 1 )
|
||||||
|
{
|
||||||
|
const ptrdiff_t size = (intptr_t)end.get_first( 24 ) - (intptr_t)begin.get_first();
|
||||||
|
if ( size > 0 )
|
||||||
|
{
|
||||||
|
DWORD dwProtect;
|
||||||
|
VirtualProtect( begin.get_first(), size, PAGE_EXECUTE_READ, &dwProtect );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool PatchIAT()
|
||||||
|
{
|
||||||
|
HINSTANCE hInstance = GetModuleHandle(nullptr);
|
||||||
|
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)hInstance + ((PIMAGE_DOS_HEADER)hInstance)->e_lfanew);
|
||||||
|
|
||||||
// Find IAT
|
// Find IAT
|
||||||
IMAGE_IMPORT_DESCRIPTOR* pImports = (IMAGE_IMPORT_DESCRIPTOR*)((DWORD)hInstance + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
|
PIMAGE_IMPORT_DESCRIPTOR pImports = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD_PTR)hInstance + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
|
||||||
|
|
||||||
// Find kernel32.dll
|
// Find kernel32.dll
|
||||||
for ( ; pImports->Name != 0; pImports++ )
|
for ( ; pImports->Name != 0; pImports++ )
|
||||||
{
|
{
|
||||||
if ( !_stricmp((const char*)((DWORD)hInstance + pImports->Name), "KERNEL32.DLL") )
|
if ( !_stricmp((const char*)((DWORD_PTR)hInstance + pImports->Name), "KERNEL32.DLL") )
|
||||||
{
|
{
|
||||||
IMAGE_IMPORT_BY_NAME** pFunctions = (IMAGE_IMPORT_BY_NAME**)((DWORD)hInstance + pImports->OriginalFirstThunk);
|
if ( pImports->OriginalFirstThunk == 0 ) return false;
|
||||||
|
|
||||||
|
PIMAGE_IMPORT_BY_NAME* pFunctions = (PIMAGE_IMPORT_BY_NAME*)((DWORD_PTR)hInstance + pImports->OriginalFirstThunk);
|
||||||
|
|
||||||
// kernel32.dll found, find GetStartupInfoA
|
// kernel32.dll found, find GetStartupInfoA
|
||||||
for ( ptrdiff_t j = 0; pFunctions[j] != nullptr; j++ )
|
for ( ptrdiff_t j = 0; pFunctions[j] != nullptr; j++ )
|
||||||
{
|
{
|
||||||
if ( !strcmp((const char*)((DWORD)hInstance + pFunctions[j]->Name), "GetStartupInfoA") )
|
if ( !strcmp((const char*)((DWORD_PTR)hInstance + pFunctions[j]->Name), "GetStartupInfoA") )
|
||||||
{
|
{
|
||||||
// Overwrite the address with the address to a custom GetStartupInfoA
|
// Overwrite the address with the address to a custom GetStartupInfoA
|
||||||
DWORD dwProtect[2];
|
DWORD dwProtect[2];
|
||||||
DWORD_PTR* pAddress = &((DWORD_PTR*)((DWORD)hInstance + pImports->FirstThunk))[j];
|
DWORD_PTR* pAddress = &((DWORD_PTR*)((DWORD_PTR)hInstance + pImports->FirstThunk))[j];
|
||||||
|
|
||||||
VirtualProtect(pAddress, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &dwProtect[0]);
|
VirtualProtect(pAddress, sizeof(DWORD_PTR), PAGE_EXECUTE_READWRITE, &dwProtect[0]);
|
||||||
pOrgGetStartupInfoA = **(VOID(WINAPI**)(LPSTARTUPINFOA))pAddress;
|
pOrgGetStartupInfoA = **(VOID(WINAPI**)(LPSTARTUPINFOA))pAddress;
|
||||||
*pAddress = (DWORD)GetStartupInfoA_Hook;
|
*pAddress = (DWORD_PTR)GetStartupInfoA_Hook;
|
||||||
VirtualProtect(pAddress, sizeof(DWORD), dwProtect[0], &dwProtect[1]);
|
VirtualProtect(pAddress, sizeof(DWORD_PTR), dwProtect[0], &dwProtect[1]);
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool PatchIAT_ByPointers()
|
||||||
|
{
|
||||||
|
pOrgSystemParametersInfoA = SystemParametersInfoA;
|
||||||
|
memcpy( orgCode, pOrgSystemParametersInfoA, sizeof(orgCode) );
|
||||||
|
Memory::VP::InjectHook( pOrgSystemParametersInfoA, SystemParametersInfoA_OverwritingHook, PATCH_JUMP );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ApplyDDrawHooks()
|
||||||
|
{
|
||||||
|
rwcsegUnprotected = FixRwcseg_Header();
|
||||||
|
|
||||||
|
bool getStartupInfoHooked = PatchIAT();
|
||||||
|
if ( !getStartupInfoHooked )
|
||||||
|
{
|
||||||
|
PatchIAT_ByPointers();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
|
@ -260,9 +332,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
|
|
||||||
if ( fdwReason == DLL_PROCESS_ATTACH )
|
if ( fdwReason == DLL_PROCESS_ATTACH )
|
||||||
{
|
{
|
||||||
DisableThreadLibraryCalls(hinstDLL);
|
ApplyDDrawHooks();
|
||||||
|
|
||||||
PatchIAT();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
Loading…
Reference in a new issue