11#include < Windows.h>
22#include < iostream>
33
4+ volatile bool gameIsAlive = false ; // this is hacky but it's non-essential
5+
46typedef HRESULT (__stdcall *DIRECTINPUT8CREATE )(HINSTANCE , DWORD , REFIID , LPVOID *, LPUNKNOWN );
57DIRECTINPUT8CREATE fpDirectInput8Create;
68extern " C" __declspec(dllexport) HRESULT __stdcall DirectInput8Create (
@@ -11,6 +13,7 @@ extern "C" __declspec(dllexport) HRESULT __stdcall DirectInput8Create(
1113 LPUNKNOWN punkOuter
1214)
1315{
16+ gameIsAlive = true ;
1417 return fpDirectInput8Create (hinst, dwVersion, riidltf, ppvOut, punkOuter);
1518}
1619
@@ -36,7 +39,17 @@ int patchLength = 7;
3639
3740DWORD WINAPI doPatching (LPVOID lpParam)
3841{
39- Sleep (10000 ); // wait for exe to deobfuscate (mainly sekiro) and scan controllers at least once
42+ // we need to wait for the game to fully load/deobfuscate and scan controllers
43+ // if loaded as dinput8, we'll know this because the create hook was hit
44+ // otherwise we'll just wait up to 15 seconds
45+ // TODO: consider checking if the game window has opened instead. this will happen after loading but before the scan
46+ // alternatively, we could hook EnumDevices itself, but steam also hooks this and it seems more likely to crash the game
47+ for (int i = 0 ; i < 15 ; i++)
48+ {
49+ if (gameIsAlive) { break ; }
50+ Sleep (1000 );
51+ }
52+ Sleep (1500 ); // wait a bit longer as the scan may not have run immediately, though it's safe to patch if the scan is already underway.
4053
4154 bool success = false ;
4255
@@ -48,17 +61,18 @@ DWORD WINAPI doPatching(LPVOID lpParam)
4861 if (pNtHeaders->Signature != IMAGE_NT_SIGNATURE ) { return 1 ; }
4962 auto pSectionHeader = IMAGE_FIRST_SECTION (pNtHeaders);
5063
64+ // int patchCount = 0;
5165 for (auto i = 0 ; i < pNtHeaders->FileHeader .NumberOfSections ; i++, pSectionHeader++)
5266 {
5367 if (strncmp ((char *)pSectionHeader->Name , " .text" , IMAGE_SIZEOF_SHORT_NAME ) == 0 )
5468 {
5569 BYTE * sectionStart = (BYTE *)hModule + pSectionHeader->VirtualAddress ;
56- DWORD sectionSize = pSectionHeader->Misc .VirtualSize ;
70+ int sectionSize = ( int ) pSectionHeader->Misc .VirtualSize ;
5771
58- for (DWORD j = 0 ; j < sectionSize - patternlength + 1 ; ++j)
72+ for (int j = 0 ; j < sectionSize - patternlength + 1 ; ++j)
5973 {
6074 bool found = true ;
61- for (size_t k = 0 ; k < patternlength; ++k)
75+ for (int k = 0 ; k < patternlength; ++k)
6276 {
6377 if (!mask[k] && sectionStart[j + k] != aob[k])
6478 {
@@ -76,7 +90,10 @@ DWORD WINAPI doPatching(LPVOID lpParam)
7690 VirtualProtect (patchAddr, patchLength, oldFlags, &oldFlags);
7791
7892 success = true ;
79- break ; // AC6 may need this patched in two places but i don't have the game
93+
94+ // patchCount++;
95+ // if (patchCount >= 2) { break; } //AC6 can be patched in two places, but this is untested
96+ break ; // for now just break on first match
8097 }
8198 }
8299 }
0 commit comments