Skip to content

Commit ad2684d

Browse files
committed
DQXISHook 0.6a, add dev console support
1 parent 40706c1 commit ad2684d

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

DQXIHook/DQXIHook.vcxproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@
146146
<SubSystem>Windows</SubSystem>
147147
<EnableCOMDATFolding>true</EnableCOMDATFolding>
148148
<OptimizeReferences>true</OptimizeReferences>
149-
<GenerateDebugInformation>true</GenerateDebugInformation>
149+
<GenerateDebugInformation>false</GenerateDebugInformation>
150150
<ModuleDefinitionFile>proxy.def</ModuleDefinitionFile>
151151
</Link>
152152
</ItemDefinitionGroup>

DQXIHook/dllmain.cpp

+33
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,36 @@ bool FileExists(LPCWSTR path)
1717

1818
char* exe_base = nullptr;
1919

20+
const size_t AddrStaticConstructObject_Internal = 0xF4E960;
21+
const size_t AddrGEngine = 0x5DA17D8;
22+
const size_t AddrUGameViewportClient__SetupInitialLocalPlayer = 0x1B02430;
23+
const size_t OffsetUEngine_ConsoleClass = 0x108; // offset to ConsoleClass field inside UEngine class
24+
const size_t OffsetUGameViewportClient_ViewportConsole = 0x48; // offset to ViewportConsole field inside UGameViewportClient class
25+
26+
typedef void* (*TStaticConstructObject_Internal)(void* InClass, void* InOuter, void* InName, void* InFlags, void* InternalSetFlags, void* InTemplate, bool bCopyTransientsFromClassDefaults, void* InInstanceGraph, bool bAssumeTemplateIsArchetype);
27+
typedef void* (*TUGameViewportClient__SetupInitialLocalPlayer)(void* thisptr, void* OutError);
28+
TUGameViewportClient__SetupInitialLocalPlayer RealUGameViewportClient__SetupInitialLocalPlayer;
29+
30+
// UGameViewportClient::SetupInitialLocalPlayer hook: in UE4 builds with ALLOW_CONSOLE=1, this function inits the UGameViewportClient::ViewportConsole field
31+
// so we just recreate the code that does that, and luckily that's all we need to re-enable the console!
32+
void* __fastcall HookUGameViewportClient__SetupInitialLocalPlayer(char* thisptr, void* OutError)
33+
{
34+
// create UConsole class
35+
TStaticConstructObject_Internal StaticConstructObject_Internal = (TStaticConstructObject_Internal)(exe_base + AddrStaticConstructObject_Internal);
36+
37+
char* engine = *(char**)(exe_base + AddrGEngine);
38+
void* consoleClass = *(void**)(engine + OffsetUEngine_ConsoleClass);
39+
40+
void* console = StaticConstructObject_Internal(consoleClass, thisptr, 0, 0, 0, 0, 0, 0, 0);
41+
42+
// set ViewportConsole field in this UGameViewportClient instance
43+
*(void**)(thisptr + OffsetUGameViewportClient_ViewportConsole) = console;
44+
45+
// call rest of SetupInitialLocalPlayer
46+
auto ret = RealUGameViewportClient__SetupInitialLocalPlayer(thisptr, OutError);
47+
return ret;
48+
}
49+
2050
const size_t AddrFPakPlatformFile__FindFileInPakFiles = 0x1FC7A30; // address of FPakPlatformFile::FindFileInPakFiles func (hooked)
2151
const size_t AddrFPakPlatformFile__IsNonPakFilenameAllowed = 0x1FCA930; // address of FPakPlatformFile::IsNonPakFilenameAllowed func (hooked)
2252
const size_t AddrWindowTitle = 0x3FC1BC8;
@@ -52,6 +82,9 @@ __int64 __fastcall HookFPakPlatformFile__IsNonPakFilenameAllowed(void* thisptr,
5282

5383
void HookPakFile()
5484
{
85+
char* UGameViewportClient__SetupInitialLocalPlayer = exe_base + AddrUGameViewportClient__SetupInitialLocalPlayer;
86+
MH_CreateHook((void*)UGameViewportClient__SetupInitialLocalPlayer, HookUGameViewportClient__SetupInitialLocalPlayer, (LPVOID*)&RealUGameViewportClient__SetupInitialLocalPlayer);
87+
5588
char* FPakPlatformFile__FindFileInPakFiles = exe_base + AddrFPakPlatformFile__FindFileInPakFiles;
5689
MH_CreateHook((void*)FPakPlatformFile__FindFileInPakFiles, HookFPakPlatformFile__FindFileInPakFiles, (LPVOID*)&RealFPakPlatformFile__FindFileInPakFiles);
5790

0 commit comments

Comments
 (0)