Skip to content
This repository was archived by the owner on Aug 4, 2023. It is now read-only.

Commit 57aac43

Browse files
committed
The great hack to hopefully get rid of failing to find address
1 parent 6c21a8e commit 57aac43

File tree

1 file changed

+209
-92
lines changed

1 file changed

+209
-92
lines changed

libs/anno-api/src/random_game_functions.cc

Lines changed: 209 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,20 @@
99
#include <algorithm>
1010
#include <atomic>
1111
#include <cctype>
12+
#include <filesystem>
13+
#include <fstream>
1214
#include <functional>
1315
#include <future>
1416
#include <locale>
1517
#include <mutex>
1618
#include <sstream>
1719
#include <vector>
18-
#include <fstream>
19-
#include <filesystem>
2020

2121
namespace anno
2222
{
2323
struct AddressInfo {
24-
std::function<uintptr_t(std::string_view)> pattern_lookup;
25-
uintptr_t address = 0;
24+
std::function<uintptr_t(std::optional<std::string_view>)> pattern_lookup;
25+
uintptr_t address = 0;
2626
};
2727

2828
static AddressInfo ADDRESSES[Address::SIZE] = {};
@@ -40,142 +40,259 @@ inline uint64_t adjust_address(uint64_t address)
4040
return base_address + offset;
4141
}
4242

43-
bool FindAddresses() {
43+
static uintptr_t RebaseFileOffsetToMemoryAddess(uintptr_t file_offset)
44+
{
45+
auto executable_address = GetModuleHandle(NULL);
46+
47+
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)(executable_address);
48+
if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
49+
throw std::runtime_error("Invalid DOS Signature");
50+
}
51+
52+
PIMAGE_NT_HEADERS header =
53+
(PIMAGE_NT_HEADERS)(((char *)executable_address + (dosHeader->e_lfanew * sizeof(char))));
54+
if (header->Signature != IMAGE_NT_SIGNATURE) {
55+
throw std::runtime_error("Invalid NT Signature");
56+
}
57+
58+
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(header);
59+
60+
for (int32_t i = 0; i < header->FileHeader.NumberOfSections; i++, section++) {
61+
bool executable = (section->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0;
62+
bool readable = (section->Characteristics & IMAGE_SCN_MEM_READ) != 0;
63+
spdlog::debug("{}, {} -> {}", section->PointerToRawData,
64+
section->PointerToRawData + section->SizeOfRawData);
65+
if (file_offset >= section->PointerToRawData
66+
&& file_offset <= section->PointerToRawData + section->SizeOfRawData) {
67+
return (uintptr_t)executable_address + file_offset
68+
+ ((intptr_t)section->VirtualAddress - (intptr_t)section->PointerToRawData);
69+
}
70+
}
71+
return 0xDEAD;
72+
}
73+
74+
bool FindAddresses()
75+
{
4476
if (!initialized) {
4577
std::scoped_lock lk{initialization_mutex};
4678
if (initialized) {
4779
return true;
4880
}
4981
initialized = true;
5082

51-
ADDRESSES[GET_CONTAINER_BLOCK_INFO] = {[](std::string_view game_file) {
52-
auto cont = meow_hook::pattern(
53-
"48 89 5C 24 08 48 89 74 24 10 57 48 83 EC 20 48 83 79 78 00 44 89 C6")
54-
.count(1)
55-
.get(0)
56-
.as<uintptr_t>();
57-
return cont;
83+
ADDRESSES[GET_CONTAINER_BLOCK_INFO] = {[](std::optional<std::string_view> game_file) {
84+
auto match = meow_hook::pattern(
85+
"48 89 5C 24 08 48 89 74 24 10 57 48 83 EC 20 48 83 79 78 00 44 89 C6",
86+
game_file)
87+
.count(1)
88+
.get(0)
89+
.as<uintptr_t>();
90+
if (game_file) {
91+
return RebaseFileOffsetToMemoryAddess(
92+
match - reinterpret_cast<intptr_t>(game_file->data()));
93+
}
94+
return match;
5895
}}; //
5996

60-
ADDRESSES[READ_FILE_FROM_CONTAINER] = {[](std::string_view game_file) {
97+
ADDRESSES[READ_FILE_FROM_CONTAINER] = {[](std::optional<std::string_view> game_file) {
6198
// Post Game Update 7
6299
try {
63-
return meow_hook::pattern("E8 ? ? ? ? 0F B6 F8 48 8D 4D C0")
64-
.count(1)
65-
.get(0)
66-
.extract_call();
100+
auto match = meow_hook::pattern("E8 ? ? ? ? 0F B6 F8 48 8D 4D C0", game_file)
101+
.count(1)
102+
.get(0);
103+
if (game_file) {
104+
match = match.adjust(
105+
RebaseFileOffsetToMemoryAddess(
106+
match.as<uintptr_t>() - reinterpret_cast<intptr_t>(game_file->data()))
107+
- match.as<uintptr_t>());
108+
}
109+
return match.extract_call();
67110
} catch (...) {
68-
return meow_hook::pattern("E8 ? ? ? ? 0F B6 D8 48 8D 4D C0")
69-
.count(1)
70-
.get(0)
71-
.extract_call();
111+
auto match = meow_hook::pattern("E8 ? ? ? ? 0F B6 D8 48 8D 4D C0", game_file)
112+
.count(1)
113+
.get(0);
114+
if (game_file) {
115+
match = match.adjust(
116+
RebaseFileOffsetToMemoryAddess(
117+
match.as<uintptr_t>() - reinterpret_cast<intptr_t>(game_file->data()))
118+
- match.as<uintptr_t>());
119+
}
120+
return match.extract_call();
72121
}
73122
}};
74123

75-
ADDRESSES[SOME_GLOBAL_STRUCTURE_ARCHIVE] = {[](std::string_view game_file) {
124+
ADDRESSES[SOME_GLOBAL_STRUCTURE_ARCHIVE] = {[](std::optional<std::string_view> game_file) {
76125
// Post Game Update 7
77126
try {
78-
return meow_hook::pattern("75 4F B9 18 00 00 00")
79-
.count(1)
80-
.get(0)
81-
.adjust(-8)
82-
.adjust(3)
83-
.add_disp()
84-
.adjust(13)
85-
.as<uintptr_t>();
127+
auto match = meow_hook::pattern("75 4F B9 18 00 00 00", game_file).count(1).get(0);
128+
if (game_file) {
129+
match = match.adjust(
130+
RebaseFileOffsetToMemoryAddess(
131+
match.as<uintptr_t>() - reinterpret_cast<intptr_t>(game_file->data()))
132+
- match.as<uintptr_t>());
133+
}
134+
return match.adjust(-8).adjust(3).add_disp().adjust(13).as<uintptr_t>();
86135
} catch (...) {
87-
return meow_hook::pattern("75 3B B9 18 00 00 00")
88-
.count(1)
89-
.get(0)
90-
.adjust(-8)
91-
.adjust(3)
92-
.add_disp()
93-
.adjust(13)
94-
.as<uintptr_t>();
136+
auto match = meow_hook::pattern("75 3B B9 18 00 00 00", game_file).count(1).get(0);
137+
if (game_file) {
138+
match = match.adjust(
139+
RebaseFileOffsetToMemoryAddess(
140+
match.as<uintptr_t>() - reinterpret_cast<intptr_t>(game_file->data()))
141+
- match.as<uintptr_t>());
142+
}
143+
return match.adjust(-8).adjust(3).add_disp().adjust(13).as<uintptr_t>();
95144
}
96145
}};
97-
ADDRESSES[TOOL_ONE_DATA_HELPER_RELOAD_DATA] = {[](std::string_view game_file) {
98-
//
99-
// Post Game Update 7
100-
try {
101-
return meow_hook::pattern(
102-
"48 8B C4 55 48 8D 68 A1 48 81 EC ? ? ? ? 48 C7 45 ? ? ? ? "
103-
"? 48 89 58 08 48 89 70 18 48 89 78 20 48 8D 45 9F")
104-
.count(1)
105-
.get(0)
106-
.as<uintptr_t>();
107-
} catch (...) {
108-
// Pre Game Update 7
146+
ADDRESSES[TOOL_ONE_DATA_HELPER_RELOAD_DATA] = {
147+
[](std::optional<std::string_view> game_file) {
148+
//
149+
// Post Game Update 7
109150
try {
110-
return meow_hook::pattern(
111-
"40 55 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 C7 45 ? ? ? ? ? 48 "
112-
"89 9C 24 ? ? ? ? 48 8D 45 9F")
113-
.count(1)
114-
.get(0)
115-
.as<uintptr_t>();
151+
auto match = meow_hook::pattern(
152+
"48 8B C4 55 48 8D 68 A1 48 81 EC ? ? ? ? 48 C7 45 ? ? ? ? "
153+
"? 48 89 58 08 48 89 70 18 48 89 78 20 48 8D 45 9F",
154+
game_file)
155+
.count(1)
156+
.get(0);
157+
if (game_file) {
158+
match = match.adjust(RebaseFileOffsetToMemoryAddess(
159+
match.as<uintptr_t>()
160+
- reinterpret_cast<intptr_t>(game_file->data()))
161+
- match.as<uintptr_t>());
162+
}
163+
return match.as<uintptr_t>();
116164
} catch (...) {
117-
return meow_hook::pattern("48 8B C4 55 48 8D 68 A1 48 81 EC ? ? ? ? 48 C7 45 ? ? ? ? "
118-
"? 48 89 58 08 48 89 70 18 48 89 78 20 48 8D 45 9F")
119-
.count(1)
120-
.get(0)
121-
.as<uintptr_t>();
165+
// Pre Game Update 7
166+
try {
167+
auto match =
168+
meow_hook::pattern(
169+
"40 55 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 C7 45 ? ? ? ? ? 48 "
170+
"89 9C 24 ? ? ? ? 48 8D 45 9F",
171+
game_file)
172+
.count(1)
173+
.get(0);
174+
if (game_file) {
175+
match =
176+
match.adjust(RebaseFileOffsetToMemoryAddess(
177+
match.as<uintptr_t>()
178+
- reinterpret_cast<intptr_t>(game_file->data()))
179+
- match.as<uintptr_t>());
180+
}
181+
return match.as<uintptr_t>();
182+
} catch (...) {
183+
auto match =
184+
meow_hook::pattern(
185+
"48 8B C4 55 48 8D 68 A1 48 81 EC ? ? ? ? 48 C7 45 ? ? ? ? "
186+
"? 48 89 58 08 48 89 70 18 48 89 78 20 48 8D 45 9F",
187+
game_file)
188+
.count(1)
189+
.get(0);
190+
if (game_file) {
191+
match =
192+
match.adjust(RebaseFileOffsetToMemoryAddess(
193+
match.as<uintptr_t>()
194+
- reinterpret_cast<intptr_t>(game_file->data()))
195+
- match.as<uintptr_t>());
196+
}
197+
return match.as<uintptr_t>();
198+
}
122199
}
200+
}};
201+
ADDRESSES[FILE_GET_FILE_SIZE] = {[](std::optional<std::string_view> game_file) {
202+
auto match =
203+
meow_hook::pattern("E8 ? ? ? ? 0F B6 D8 48 8D 4D B0", game_file).count(1).get(0);
204+
if (game_file) {
205+
match = match.adjust(
206+
RebaseFileOffsetToMemoryAddess(match.as<uintptr_t>()
207+
- reinterpret_cast<intptr_t>(game_file->data()))
208+
- match.as<uintptr_t>());
123209
}
210+
return match.extract_call();
124211
}};
125-
ADDRESSES[FILE_GET_FILE_SIZE] = {[](std::string_view game_file) {
126-
return meow_hook::pattern("E8 ? ? ? ? 0F B6 D8 48 8D 4D B0")
127-
.count(1)
128-
.get(0)
129-
.extract_call();
130-
}};
131-
ADDRESSES[READ_GAME_FILE] = {[](std::string_view game_file) {
132-
return meow_hook::pattern("48 89 5C 24 ? 48 89 6C 24 ? 56 48 83 EC 30 48 8B 81 ? ? ? ?")
133-
.count(1)
134-
.get(0)
135-
.as<uintptr_t>();
212+
ADDRESSES[READ_GAME_FILE] = {[](std::optional<std::string_view> game_file) {
213+
auto match =
214+
meow_hook::pattern("48 89 5C 24 ? 48 89 6C 24 ? 56 48 83 EC 30 48 8B 81 ? ? ? ?",
215+
game_file)
216+
.count(1)
217+
.get(0);
218+
if (game_file) {
219+
match = match.adjust(
220+
RebaseFileOffsetToMemoryAddess(match.as<uintptr_t>()
221+
- reinterpret_cast<intptr_t>(game_file->data()))
222+
- match.as<uintptr_t>());
223+
}
224+
return match.as<uintptr_t>();
136225
}};
137-
ADDRESSES[SOME_GLOBAL_STRUCT_TOOL_ONE_HELPER_MAYBE] = {[](std::string_view game_file) {
226+
ADDRESSES[SOME_GLOBAL_STRUCT_TOOL_ONE_HELPER_MAYBE] = {[](std::optional<std::string_view>
227+
game_file) {
138228
// Post Game Update 7
139-
;
140-
;
141229
try {
142-
return meow_hook::pattern("48 8B 3D ? ? ? ? 4C 8B 5D DF")
143-
.count(1)
144-
.get(0)
145-
.adjust(3)
146-
.add_disp()
147-
.adjust(4)
148-
.as<uintptr_t>();
230+
auto match =
231+
meow_hook::pattern("48 8B 3D ? ? ? ? 4C 8B 5D DF", game_file).count(1).get(0);
232+
if (game_file) {
233+
match = match.adjust(
234+
RebaseFileOffsetToMemoryAddess(
235+
match.as<uintptr_t>() - reinterpret_cast<intptr_t>(game_file->data()))
236+
- match.as<uintptr_t>());
237+
}
238+
return match.adjust(3).add_disp().adjust(4).as<uintptr_t>();
149239
} catch (...) {
150240
// Pre Game Update 7
151-
return meow_hook::pattern("48 8B 0D ? ? ? ? E8 ? ? ? ? 90 48 8D 4D FF")
152-
.count(1)
153-
.get(0)
154-
.adjust(3)
155-
.add_disp()
156-
.adjust(4)
157-
.as<uintptr_t>(); }
241+
auto match =
242+
meow_hook::pattern("48 8B 0D ? ? ? ? E8 ? ? ? ? 90 48 8D 4D FF", game_file)
243+
.count(1)
244+
.get(0);
245+
if (game_file) {
246+
match = match.adjust(
247+
RebaseFileOffsetToMemoryAddess(
248+
match.as<uintptr_t>() - reinterpret_cast<intptr_t>(game_file->data()))
249+
- match.as<uintptr_t>());
250+
}
251+
return match.adjust(3).add_disp().adjust(4).as<uintptr_t>();
252+
}
158253
}};
159254

255+
std::filesystem::path process_file_path;
256+
257+
{
258+
wchar_t process_name[1024] = {0};
259+
DWORD process_name_size = 1024;
260+
QueryFullProcessImageNameW(GetCurrentProcess(), 0, process_name, &process_name_size);
261+
process_file_path = process_name;
262+
}
263+
264+
std::fstream is(process_file_path, std::ios::in | std::ios::binary);
265+
is.seekg(0, std::ios::end);
266+
size_t data_size = is.tellg();
267+
is.seekg(0, std::ios::beg);
268+
std::unique_ptr<char[]> data(new char[data_size]);
269+
is.read(data.get(), data_size);
270+
271+
std::string_view game_file(data.get(), data_size);
160272
//
161273
bool any_address_failed = false;
162274
for (int attempt = 0; attempt < 5; ++attempt) {
163275
any_address_failed = false;
164-
int index = 0;
276+
int index = 0;
165277
for (auto &address : ADDRESSES) {
166278
uintptr_t pattern_matched_address = 0;
167279
//
168280
try {
169281
pattern_matched_address = address.pattern_lookup({});
170282
} catch (...) {
171-
pattern_matched_address = 0xDEAD;
283+
try {
284+
spdlog::debug("Address search fallback to file search");
285+
pattern_matched_address = address.pattern_lookup(game_file);
286+
} catch (...) {
287+
pattern_matched_address = 0xDEAD;
288+
}
172289
}
173290

174291
// If we fail to find an address, we are in trouble :)
175292
// Mod loader needs updating
176293
if (pattern_matched_address != 0xDEAD && pattern_matched_address != 0) {
177294
address.address = pattern_matched_address;
178-
spdlog::debug("Matched address {}", (void*)pattern_matched_address);
295+
spdlog::debug("Matched address {}", (void *)pattern_matched_address);
179296
} else {
180297
any_address_failed = true;
181298
spdlog::error("Failed to find address, please create an issue on GitHub {}",

0 commit comments

Comments
 (0)