Skip to content

Commit d86d5ad

Browse files
Evasion3356Evasion3356
authored andcommitted
Redesigned LoadPointers to be signature based instead of hardcoded offsets.
Fixed ExampleDLLPlugin project failing to build after DXGI conversion. Removed Shutdown function, as DXGI.dll hijacked DLLs cannot be ejected.
1 parent b0e219e commit d86d5ad

File tree

9 files changed

+229
-108
lines changed

9 files changed

+229
-108
lines changed

ExampleDLLPlugin/ExampleDLLPlugin.vcxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
</ClCompile>
5757
<Link>
5858
<GenerateDebugInformation>true</GenerateDebugInformation>
59-
<AdditionalDependencies>$(SolutionDir)build\$(Configuration)\M2DEScriptHook.lib;%(AdditionalDependencies)</AdditionalDependencies>
59+
<AdditionalDependencies>$(SolutionDir)build\$(Configuration)\dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
6060
</Link>
6161
<PostBuildEvent>
6262
<Command>$(SolutionDir)\copydebug.bat</Command>
@@ -74,7 +74,7 @@
7474
<GenerateDebugInformation>true</GenerateDebugInformation>
7575
<EnableCOMDATFolding>true</EnableCOMDATFolding>
7676
<OptimizeReferences>true</OptimizeReferences>
77-
<AdditionalDependencies>$(SolutionDir)build\$(Configuration)\M2DEScriptHook.lib;%(AdditionalDependencies)</AdditionalDependencies>
77+
<AdditionalDependencies>$(SolutionDir)build\$(Configuration)\dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
7878
</Link>
7979
<PostBuildEvent>
8080
<Command>$(SolutionDir)\copyrelease.bat</Command>

M2DEScriptHook.sln

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio Version 17
4-
VisualStudioVersion = 17.13.35913.81 d17.13
4+
VisualStudioVersion = 17.13.35913.81
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "M2DEScriptHook", "M2DEScriptHook\M2DEScriptHook.vcxproj", "{8D715BC3-5BBC-42E2-9F0D-29FBAFB6490B}"
77
ProjectSection(ProjectDependencies) = postProject

M2DEScriptHook/M2DEScriptHook.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@
131131
<ClInclude Include="include/LuaStateManager.h" />
132132
<ClInclude Include="include\M2DEScriptHook.h" />
133133
<ClInclude Include="include/PluginSystem.h" />
134+
<ClInclude Include="include\PatternScanner.h" />
134135
<ClInclude Include="include\ScriptSystem.h" />
135136
</ItemGroup>
136137
<ItemGroup>

M2DEScriptHook/M2DEScriptHook.vcxproj.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@
144144
<ClInclude Include="include\M2DEScriptHook.h">
145145
<Filter>Header Files</Filter>
146146
</ClInclude>
147+
<ClInclude Include="include\PatternScanner.h">
148+
<Filter>Header Files</Filter>
149+
</ClInclude>
147150
</ItemGroup>
148151
<ItemGroup>
149152
<ClCompile Include="src/LuaFunctions.cpp">

M2DEScriptHook/include/LuaFunctions.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535

3636
class LuaFunctions : public singleton<LuaFunctions> {
3737
private:
38-
bool m_mainScriptMachineReady = false;
3938
std::map<unsigned char, std::string> keyBinds = {};
4039

4140
static int32_t PrintToLog(lua_State*);
@@ -58,4 +57,4 @@ __declspec(dllexport) int lua_pcall_(lua_State *L, int nargs, int nresults, int
5857
__declspec(dllexport) const char *lua_tostring_(lua_State *L, int32_t idx);
5958
__declspec(dllexport) uint32_t lua_isstring_(lua_State *L, int32_t idx);
6059
__declspec(dllexport) lua_State *lua_newthread_(lua_State *L);
61-
__declspec(dllexport) void logPointer(std::string name, uint64_t pointer);
60+
__declspec(dllexport) void logPointer(std::string name, void* pointer);

M2DEScriptHook/include/M2DEScriptHook.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ class M2DEScriptHook : public singleton<M2DEScriptHook>
112112
static uint32_t WINAPI mainThread(LPVOID);
113113
void StartThreads();
114114
bool HasEnded();
115-
void Shutdown();
116115

117116
void CreateKeyBind(const char *key, const char *context);
118117
void DestroyKeyBind(const char *key, const char *context);
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
#pragma once
2+
3+
#include <Windows.h>
4+
#include <Psapi.h>
5+
#include <cstdint>
6+
#include <sstream>
7+
8+
/**
9+
* \brief Provides compact utility to scan patterns and manipulate addresses.
10+
*/
11+
struct PatternScanner
12+
{
13+
struct module_info_helper
14+
{
15+
static inline void GetModuleBaseAndSize(DWORD64* lpBase, DWORD64* lpSize)
16+
{
17+
MODULEINFO moduleInfo = {};
18+
19+
HMODULE module = GetModuleHandle(nullptr);
20+
GetModuleInformation(GetCurrentProcess(), module, &moduleInfo, sizeof MODULEINFO);
21+
22+
if (lpBase)
23+
{
24+
*lpBase = DWORD64(moduleInfo.lpBaseOfDll);
25+
}
26+
if (lpSize)
27+
{
28+
*lpSize = DWORD64(moduleInfo.SizeOfImage);
29+
}
30+
}
31+
};
32+
33+
uint64_t Value = 0;
34+
35+
PatternScanner(uint64_t value) :
36+
Value(value)
37+
{
38+
}
39+
40+
PatternScanner() :
41+
PatternScanner(0)
42+
{
43+
}
44+
45+
static inline PatternScanner Scan(const char* patternStr, const char* debugName = nullptr)
46+
{
47+
static uint64_t s_ModuleSize;
48+
static uint64_t s_ModuleBase;
49+
static bool s_Init = false;
50+
if (!s_Init)
51+
{
52+
module_info_helper::GetModuleBaseAndSize(&s_ModuleBase, &s_ModuleSize);
53+
s_Init = true;
54+
}
55+
56+
// Convert string pattern into byte array form
57+
int16_t pattern[256];
58+
uint8_t patternSize = 0;
59+
for (size_t i = 0; i < strlen(patternStr); i += 3)
60+
{
61+
const char* cursor = patternStr + i;
62+
63+
if (cursor[0] == '?')
64+
{
65+
pattern[patternSize] = -1;
66+
}
67+
else
68+
{
69+
pattern[patternSize] = static_cast<int16_t>(strtol(cursor, nullptr, 16));
70+
}
71+
72+
// Support single '?' (we're incrementing by 3 expecting ?? and space, but with ? we must increment by 2)
73+
if (cursor[1] == ' ')
74+
{
75+
i--;
76+
}
77+
78+
patternSize++;
79+
}
80+
81+
// In two-end comparison we approach from both sides (left & right) so size is twice smaller
82+
uint8_t scanSize = patternSize;
83+
if (scanSize % 2 == 0)
84+
{
85+
scanSize /= 2;
86+
}
87+
else
88+
{
89+
scanSize = patternSize / 2 + 1;
90+
}
91+
92+
// Search for string through whole module
93+
// We use two-end comparison, nothing fancy but better than just brute force
94+
for (uint64_t i = 0; i < s_ModuleSize; i += 1)
95+
{
96+
const uint8_t* modulePos = (uint8_t*)(s_ModuleBase + i);
97+
for (uint8_t j = 0; j < scanSize; j++)
98+
{
99+
int16_t lExpected = pattern[j];
100+
int16_t lActual = modulePos[j];
101+
102+
if (lExpected != -1 && lActual != lExpected)
103+
{
104+
goto miss;
105+
}
106+
107+
int16_t rExpected = pattern[patternSize - j - 1];
108+
int16_t rActual = modulePos[patternSize - j - 1];
109+
110+
if (rExpected != -1 && rActual != rExpected)
111+
{
112+
goto miss;
113+
}
114+
}
115+
return { s_ModuleBase + i };
116+
miss:;
117+
}
118+
119+
std::stringstream ss;
120+
ss << "Failed to find " << (debugName) ? debugName : patternStr;
121+
MessageBox(NULL, ss.str().c_str(), "SIGNATURE FAILURE!", MB_ICONERROR | MB_OK);
122+
123+
return { 0 };
124+
}
125+
126+
PatternScanner GetAt(int32_t offset) const
127+
{
128+
return Value + offset;
129+
}
130+
131+
PatternScanner GetRef(int32_t offset = 0) const
132+
{
133+
return Value + offset + sizeof(DWORD) + *(int32_t*)(Value + offset);
134+
}
135+
136+
PatternScanner GetCall() const
137+
{
138+
return GetRef(1);
139+
}
140+
141+
template<typename T>
142+
T To() const
143+
{
144+
return (T)Value;
145+
}
146+
147+
template<typename T>
148+
T* ToFunc() const
149+
{
150+
return To<T*>();
151+
}
152+
153+
PatternScanner& operator=(uint64_t value)
154+
{
155+
Value = value;
156+
return *this;
157+
}
158+
159+
operator uint64_t() const
160+
{
161+
return Value;
162+
}
163+
164+
operator void* () const
165+
{
166+
return (void*)Value;
167+
}
168+
};

0 commit comments

Comments
 (0)