Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Use https://github.com/emoose/DQXIHook as a base, and replace dllmain.cpp with below:
- #include "stdafx.h"
- #include <stdint.h>
- #include <stdio.h>
- #include <unordered_set>
- #include <filesystem>
- #include <fstream>
- #include "MinHook/MinHook.h"
- #include "proxy.h"
- std::unordered_set<std::string> extensions = {
- "ddsc", "inputkeymapdefsc", "inputc", "gtoc", "bl", "bin", "stringlookup",
- "gfx", "worldaudioinfo_xmlc", "vegetationinfo", "gadfc", "rawc", "fmod_bankc",
- "roadgraphc", "routec", "aicoversettingsc", "aisystunec", "vocals_settingsc",
- "intentstablec", "gameregionsc", "light_infoc", "meproc", "hrmeshc", "atx1",
- "bmpc", "world", "terrainsystemc", "ee", "asb", "meshc", "brdd", "json",
- "featuresc", "streampatch", "bikc", "ogg", "nl", "fl", "navmeshc", "wavc",
- "ban", "physicsc", "stoc", "atx2", "resourcesetsc", "fmod_sbankc", "uitunec",
- "environc", "hikcc", "vocalsc", "graphc"
- };
- bool FileExists(const char* path)
- {
- DWORD dwAttrib = GetFileAttributesA(path);
- return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
- }
- bool DirectoryExists(const char* path)
- {
- DWORD dwAttrib = GetFileAttributesA(path);
- return (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
- }
- void dbglog(const char *format, ...)
- {
- char str[4096];
- va_list ap;
- va_start(ap, format);
- vsnprintf(str, 4096, format, ap);
- va_end(ap);
- FILE* file;
- if (fopen_s(&file, "rage2hook.log", "a") != 0)
- return;
- fwrite(str, strlen(str), 1, file);
- fwrite("\n", 1, 1, file);
- fclose(file);
- }
- void strlog(const char* buffer, size_t size)
- {
- FILE* file;
- if (fopen_s(&file, "rage2hook.log", "a") != 0)
- return;
- fwrite(buffer, size, 1, file);
- fwrite("\n", 1, 1, file);
- fclose(file);
- }
- bool StringValid(const char* buffer, size_t size)
- {
- for (size_t i = 0; i < size; i++)
- {
- if (!isprint(buffer[i]))
- return false;
- }
- return true;
- }
- bool StringContains(const char* buffer, size_t size, char c)
- {
- for (size_t i = 0; i < size; i++)
- {
- if (buffer[i] == c)
- return true;
- }
- return false;
- }
- char* exe_base = nullptr;
- typedef uint64_t(*Murmur3Hash_ptr)(const char* buffer, size_t size, size_t seed);
- Murmur3Hash_ptr Murmur3Hash_orig;
- size_t Murmur3Hash_addrs[] = {
- 0x107F3B0, // 1.2?
- 0x107EF10, // 1.1?
- 0x107ABF0, // 1.0?
- };
- size_t Murmur3Hash_addr = 0;
- std::unordered_set<uint64_t> known_hashes;
- char newbuf[1024];
- uint64_t Murmur3Hash_Hook(const char* buffer, size_t size, size_t seed)
- {
- uint64_t hash = Murmur3Hash_orig(buffer, size, seed);
- if (StringValid(buffer, size))
- {
- // Murmur3 is used for lots of things, so check if this is a path (contains /) or ends with a known extension
- memcpy(newbuf, buffer, size);
- newbuf[size] = '\0';
- std::string buf = newbuf;
- auto pos = buf.find_last_of(".");
- bool known_extension = pos != std::string::npos && extensions.find(buf.substr(pos + 1)) != extensions.end();
- if (known_extension || StringContains(buffer, size, '/'))
- {
- if (known_hashes.find(hash) == known_hashes.end())
- {
- strlog(buffer, size);
- known_hashes.insert(hash);
- }
- }
- }
- return hash;
- }
- bool LoadFileList(const std::string& list_path)
- {
- if (!FileExists(list_path.c_str()) || !Murmur3Hash_addr)
- return false;
- Murmur3Hash_ptr hasher = (Murmur3Hash_ptr)(exe_base + Murmur3Hash_addr);
- std::ifstream infile(list_path);
- std::string line;
- while (std::getline(infile, line))
- {
- if (line.length() <= 0)
- continue;
- if (line.at(0) == ';')
- continue;
- auto hash = hasher(line.c_str(), line.length(), 0);
- if (known_hashes.find(hash) == known_hashes.end())
- known_hashes.insert(hash);
- }
- return true;
- }
- bool LoadFileLists(const std::string& dir)
- {
- if (!DirectoryExists(dir.c_str()))
- return false;
- std::experimental::filesystem::directory_iterator end_itr;
- for (std::experimental::filesystem::directory_iterator i(dir); i != end_itr; ++i)
- {
- if (std::experimental::filesystem::is_regular_file(i->status()))
- {
- if (i->path().extension() == ".filelist")
- LoadFileList(i->path().string());
- continue;
- }
- if (std::experimental::filesystem::is_directory(i->status()))
- {
- LoadFileLists(i->path().string());
- }
- }
- return true;
- }
- bool IsMurmur3Func(BYTE* addr)
- {
- return addr[0] == 0x48 && addr[1] == 0x89 && addr[2] == 0x5C && addr[3] == 0x24;
- }
- bool HookHashFuncs()
- {
- BYTE* Murmur3Hash = 0;
- for (auto addr : Murmur3Hash_addrs)
- {
- auto* funcdata = (BYTE*)(exe_base + addr);
- if (IsMurmur3Func(funcdata))
- {
- Murmur3Hash = funcdata;
- Murmur3Hash_addr = addr;
- break;
- }
- }
- if (!Murmur3Hash)
- return false;
- // Load previous names from log if it exists
- LoadFileList("rage2hook.log");
- // Load Rage2Unpack filelists if they exist, so we won't log already known names
- LoadFileLists("projects\\RAGE 2\\");
- // Hook Murmur3 function!
- MH_Initialize();
- MH_CreateHook((void*)Murmur3Hash, Murmur3Hash_Hook, (LPVOID*)&Murmur3Hash_orig);
- MH_EnableHook((void*)Murmur3Hash);
- return true;
- }
- void InitHooks()
- {
- if (exe_base)
- return;
- exe_base = (char*)GetModuleHandleA("RAGE2.exe");
- if (!exe_base)
- {
- MessageBoxA(0, "Rage2Hook: Failed to get handle for \"RAGE2.exe\" process? :(", "Rage2Hook", 0);
- return;
- }
- if (!HookHashFuncs())
- {
- MessageBoxA(0, "Rage2Hook: unsupported Rage2 version, Rage2Hook features disabled.\r\nPlease check for a new Rage2Hook build!", "Rage2Hook", 0);
- return;
- }
- }
- HMODULE ourModule = 0;
- BOOL APIENTRY DllMain(HMODULE hModule, int ul_reason_for_call, LPVOID lpReserved)
- {
- if (ul_reason_for_call == DLL_PROCESS_ATTACH)
- {
- ourModule = hModule;
- Proxy_Attach();
- InitHooks();
- }
- if (ul_reason_for_call == DLL_PROCESS_DETACH)
- Proxy_Detach();
- return TRUE;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement