1+ #include < windows.h>
2+ #include < thread>
3+ #include < psapi.h>
4+ #include " ext/random.h"
5+
6+ const char * GAMEDATAMAN_AOB = " \x48\x8B\x05\x00\x00\x00\x00\x48\x85\xC0\x74\x05\x48\x8B\x40\x58\xC3\xC3 " ;
7+ const char * GAMEDATAMAN_MASK = " xxx????xxxxxxxxxxx" ;
8+
9+ struct Offsets {
10+ static const uintptr_t StatBasePtr = 0x8 ;
11+ static const uintptr_t Vigor = 0x3C ;
12+ static const uintptr_t Level = 0x68 ;
13+ static const uintptr_t DeathCount = 0x94 ;
14+ };
15+
16+ int GetRandomInt (random_state* state, int min, int max) {
17+ return min + (random_next (state) % (max - min + 1 ));
18+ }
19+
20+ uintptr_t FindPattern (const char * pattern, const char * mask) {
21+ MODULEINFO modInfo = { 0 };
22+ GetModuleInformation (GetCurrentProcess (), GetModuleHandle (NULL ), &modInfo, sizeof (MODULEINFO ));
23+ uintptr_t start = (uintptr_t )modInfo.lpBaseOfDll ;
24+ uintptr_t size = (uintptr_t )modInfo.SizeOfImage ;
25+ size_t patternLen = strlen (mask);
26+ for (uintptr_t i = 0 ; i < size - patternLen; i++) {
27+ bool found = true ;
28+ for (size_t j = 0 ; j < patternLen; j++) {
29+ if (mask[j] != ' ?' && pattern[j] != *(char *)(start + i + j)) {
30+ found = false ; break ;
31+ }
32+ }
33+ if (found) return start + i;
34+ }
35+ return 0 ;
36+ }
37+
38+ uintptr_t GetRIPRelative (uintptr_t address) {
39+ if (!address) return 0 ;
40+ int32_t offset = *(int32_t *)(address + 3 );
41+ return address + offset + 7 ;
42+ }
43+
44+ void RandomizeStatsAndLevel (uintptr_t gameDataManAddr, random_state* rng) {
45+ uintptr_t gameDataMan = *(uintptr_t *)gameDataManAddr;
46+ if (!gameDataMan) return ;
47+ uintptr_t statBase = *(uintptr_t *)(gameDataMan + Offsets::StatBasePtr);
48+ if (!statBase) return ;
49+
50+ for (int i = 0 ; i < 8 ; i++) {
51+ *(int *)(statBase + Offsets::Vigor + (i * 4 )) = GetRandomInt (rng, 1 , 99 );
52+ }
53+
54+ *(int *)(statBase + Offsets::Level) = GetRandomInt (rng, 1 , 713 );
55+ }
56+
57+ void ModThread () {
58+ uintptr_t gameDataManInst = FindPattern (GAMEDATAMAN_AOB , GAMEDATAMAN_MASK );
59+ if (!gameDataManInst) return ;
60+
61+ uintptr_t gameDataManAddr = GetRIPRelative (gameDataManInst);
62+ int lastDeathCount = -1 ;
63+
64+ random_state rng;
65+ random_autoseed (&rng);
66+
67+ while (true ) {
68+ uintptr_t gameDataMan = *(uintptr_t *)gameDataManAddr;
69+ if (gameDataMan) {
70+ int currentDeaths = *(int *)(gameDataMan + Offsets::DeathCount);
71+
72+ if (lastDeathCount == -1 ) {
73+ lastDeathCount = currentDeaths;
74+ }
75+
76+ if (currentDeaths > lastDeathCount) {
77+ std::this_thread::sleep_for (std::chrono::milliseconds (2000 ));
78+
79+ RandomizeStatsAndLevel (gameDataManAddr, &rng);
80+
81+ lastDeathCount = currentDeaths;
82+ }
83+ }
84+ std::this_thread::sleep_for (std::chrono::milliseconds (500 ));
85+ }
86+ }
87+
88+ BOOL APIENTRY DllMain (HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
89+ if (ul_reason_for_call == DLL_PROCESS_ATTACH ) {
90+ CreateThread (nullptr , 0 , (LPTHREAD_START_ROUTINE )ModThread, nullptr , 0 , nullptr );
91+ }
92+ return TRUE ;
93+ }
0 commit comments