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 <vector>
- #include <filesystem>
- #include <fstream>
- #include "MinHook/MinHook.h"
- #include "proxy.h"
- std::vector<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(LPCWSTR path)
- {
- DWORD dwAttrib = GetFileAttributesW(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_addr_10 = 0x107ABF0; // 1.0?
- size_t Murmur3Hash_addr_11 = 0x107EF10; // 1.1?
- size_t Murmur3Hash_addr = Murmur3Hash_addr_11; // todo: detect version based on what bytes we read at the addr...
- std::vector<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))
- {
- bool is_valid = false;
- memcpy(newbuf, buffer, size);
- newbuf[size] = '\0';
- std::string buf = newbuf;
- auto pos = buf.find_last_of(".");
- if (pos != std::string::npos)
- {
- auto ext = buf.substr(pos + 1);
- for(auto known_ext : extensions)
- {
- if (ext == known_ext)
- {
- is_valid = true;
- break;
- }
- }
- }
- if(is_valid || StringContains(buffer, size, '/')) // lots of other stuff uses Murmur3, so filter out only the paths
- {
- bool hash_isknown = false;
- for (auto known_hash : known_hashes)
- {
- if (known_hash == hash)
- {
- hash_isknown = true;
- break;
- }
- }
- if (!hash_isknown)
- {
- strlog(buffer, size);
- known_hashes.push_back(hash);
- }
- }
- }
- return hash;
- }
- bool HookHashFuncs()
- {
- BYTE* Murmur3Hash = (BYTE*)(exe_base + Murmur3Hash_addr);
- // Make sure murmur function begins how we expect...
- if (Murmur3Hash[0] != 0x48 || Murmur3Hash[1] != 0x89 || Murmur3Hash[2] != 0x5C || Murmur3Hash[3] != 0x24)
- return false;
- MH_Initialize();
- MH_CreateHook((void*)Murmur3Hash, Murmur3Hash_Hook, (LPVOID*)&Murmur3Hash_orig);
- MH_EnableHook((void*)Murmur3Hash);
- return true;
- }
- void LoadFileList(const std::string& list_path)
- {
- 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);
- bool hash_isknown = false;
- for (auto known_hash : known_hashes)
- {
- if (known_hash == hash)
- {
- hash_isknown = true;
- break;
- }
- }
- if (!hash_isknown)
- known_hashes.push_back(hash);
- }
- }
- void LoadFileLists(const std::string& dir)
- {
- 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());
- }
- }
- }
- 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;
- }
- // Load previous names from log if it exists
- LoadFileList("rage2hook.log");
- // Load Rage2Unpack filelists if they exist, so we won't log any already known names
- LoadFileLists("projects\\RAGE 2\\");
- 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;
- }
Add Comment
Please, Sign In to add comment