-
Notifications
You must be signed in to change notification settings - Fork 1
/
cvarUnlocker.cpp
136 lines (119 loc) · 3.49 KB
/
cvarUnlocker.cpp
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
133
134
135
136
// To make importing things work
#define _WIN32_WINNT 0x0600
#include <windows.h>
#include <iostream>
#include <windowsx.h>
#include <commctrl.h>
#include <shellapi.h>
#include <tlhelp32.h>
#include <string>
// Address of the method to patch
// Debug build of OpenJK
/*
.text : 00D67E54 cmp dword ptr[edx + 24h], 0
.text : 00D67E58 jnz short loc_D67E73
*/
#define ADDR ((void *)0x00D67E58)
// JNZ rel 8
unsigned char EXPECTED_MEM[] = "\x75";
// JMP rel 8
unsigned char PATCHED[] = "\xEB";
main(int argc, char const *argv[])
{
PROCESSENTRY32 entry;
DWORD PID = -1;
BOOL found = FALSE;
// Do Windows things
entry.dwSize = sizeof(PROCESSENTRY32);
// Get all processes
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot == INVALID_HANDLE_VALUE)
{
std::cerr << "Can't get list of running processes" << std::endl;
exit(1);
}
// Search for the process using the exe file name
if (Process32First(snapshot, &entry))
{
do
{
if (strcmp((char *)entry.szExeFile, "openjk.x86.exe") == 0)
{
found = TRUE;
PID = entry.th32ProcessID;
std::cout << "Got process: " << PID << " " << entry.szExeFile << std::endl;
break;
}
} while (Process32Next(snapshot, &entry));
}
else
{
std::cerr << "Can't process list of running processes" << std::endl;
exit(2);
}
if (!found)
{
std::cerr << "Can't find process" << std::endl;
exit(3);
}
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, false, PID);
if (!hProc)
{
std::cerr << "Cannot open process." << std::endl;
exit(4);
}
else
{
// Make the process halt
BOOL res_dbg = DebugActiveProcess(PID);
if (!res_dbg)
{
std::cerr << "Can't debug" << std::endl;
CloseHandle(hProc);
exit(5);
}
DebugSetProcessKillOnExit(FALSE);
// try reading first to check for expected values
unsigned char read_mem[sizeof(EXPECTED_MEM) / sizeof(unsigned char) - 1];
// read from the address that's about to be patched
BOOL res_read = ReadProcessMemory(hProc, ADDR, &read_mem, sizeof(read_mem), NULL);
if (res_read)
{
std::cout << "Got memory:" << std::endl;
for (int i = 0; i < sizeof(read_mem); i++)
{
std::cout << "\t" << std::hex << (int)read_mem[i] << " ";
}
std::cout << std::endl;
}
else
{
std::cerr << "Memory couldn't be read from process: " << GetLastError() << std::endl;
exit(88);
}
// Check if it has the expected value
if (memcmp(EXPECTED_MEM, read_mem, sizeof(read_mem)) != 0)
{
std::cerr << "Invalid bytes read" << std::endl;
exit(99);
}
else
{
std::cout << "Memory verified" << std::endl;
}
// Patch the memory
BOOL res_write = WriteProcessMemory(hProc, ADDR, &PATCHED, sizeof(PATCHED) - 1, NULL);
if (res_write)
{
std::clog << "Memory written to process." << std::endl;
}
else
{
std::cerr << "Memory couldn't be written to process: " << GetLastError() << std::endl;
}
// Stop debugging
DebugActiveProcessStop(PID);
CloseHandle(hProc);
}
return 0;
}