1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include "MinHook.h"
#include <string>
#include <sstream>
#include <filesystem>
#include <iostream>
#include <iomanip>
#define DLL_NAME L"Northstar.dll"
typedef BOOL(WINAPI *CreateProcessWType)(
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
CreateProcessWType CreateProcessWOriginal;
HMODULE ownHModule;
std::filesystem::path tf2DirPath;
BOOL WINAPI CreateProcessWHook(
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
)
{
bool isTitanfallProcess = false;
// origin doesn't use lpApplicationName
if (lpApplicationName)
{
std::wcout << lpApplicationName << std::endl;
isTitanfallProcess = wcsstr(lpApplicationName, L"Titanfall2\\Titanfall2.exe");
}
else
{
std::wcout << lpCommandLine << std::endl;
isTitanfallProcess = wcsstr(lpCommandLine, L"Titanfall2\\Titanfall2.exe");
}
// steam will start processes suspended
bool alreadySuspended = dwCreationFlags & CREATE_SUSPENDED;
// suspend process on creation so we can hook
if (isTitanfallProcess && !alreadySuspended)
dwCreationFlags |= CREATE_SUSPENDED;
BOOL ret = CreateProcessWOriginal(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
if (isTitanfallProcess)
{
std::cout << "Creating titanfall process!" << std::endl;
std::cout << "Handle: " << lpProcessInformation->hProcess << " ID: " << lpProcessInformation->dwProcessId << " Thread: " << lpProcessInformation->hThread << std::endl;
STARTUPINFO si;
memset(&si, 0, sizeof(si));
PROCESS_INFORMATION pi;
memset(&pi, 0, sizeof(pi));
std::stringstream argStr;
argStr << lpProcessInformation->dwProcessId;
argStr << " ";
argStr << lpProcessInformation->dwThreadId;
CreateProcessA((tf2DirPath / "InjectionProxy64.exe").string().c_str(), (LPSTR)(argStr.str().c_str()), 0, 0, false, 0, 0, tf2DirPath.string().c_str(), (LPSTARTUPINFOA)&si, &pi);
WaitForSingleObject(pi.hThread, INFINITE);
// this doesn't seem to work super well
//if (!alreadySuspended)
ResumeThread(lpProcessInformation->hThread);
MH_DisableHook(&CreateProcessW);
MH_RemoveHook(&CreateProcessW);
MH_Uninitialize();
FreeLibrary(ownHModule);
}
return ret;
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
DisableThreadLibraryCalls(hModule);
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
AllocConsole();
freopen("CONOUT$", "w", stdout);
ownHModule = hModule;
char ownDllPath[MAX_PATH];
GetModuleFileNameA(hModule, ownDllPath, MAX_PATH);
tf2DirPath = std::filesystem::path(ownDllPath).parent_path();
// hook CreateProcessW
if (MH_Initialize() > MH_ERROR_ALREADY_INITIALIZED) // MH_ERROR_ALREADY_INITIALIZED = 1, MH_OK = 0, these are the only results we should expect
return TRUE;
MH_CreateHook(&CreateProcessW, &CreateProcessWHook, reinterpret_cast<LPVOID*>(&CreateProcessWOriginal));
MH_EnableHook(&CreateProcessW);
return TRUE;
}
|