diff --git a/NOTES.md b/NOTES.md index 2ac61ba..59243ca 100644 --- a/NOTES.md +++ b/NOTES.md @@ -65,7 +65,7 @@ Points to GameState struct ## Entity Hash Table -Hashfunction used: [strhash](http://www.cs.ecu.edu/karl/3300/spr16/Notes/DataStructure/hashtable.html) +Hashfunction used: [PJW](https://en.wikipedia.org/wiki/PJW_hash_function) (Same parameters as the example implementation) Entry format: @@ -81,6 +81,7 @@ Data format: | ------ | ----------- | -------------------- | | 0x0 | void** | Virtual Method Table | | 0x4 | const char* | name as string | +| 0x14 | void* | pointer to self | | 0x28 | float[3] | Position | # File Formats diff --git a/ScrapHacks/Injector/Injector/Injector.cpp b/ScrapHacks/Injector/Injector/Injector.cpp index f235d2c..040a863 100644 --- a/ScrapHacks/Injector/Injector/Injector.cpp +++ b/ScrapHacks/Injector/Injector/Injector.cpp @@ -156,7 +156,7 @@ bool Injected(DWORD PID) return HasModule(PID, DLL_NAME); } -void InjectDll(DWORD PID, bool do_resume = false) +void InjectDll(DWORD PID) { HANDLE hRemThread, hProc; const char *dll_name = DLL_NAME; @@ -175,42 +175,34 @@ void InjectDll(DWORD PID, bool do_resume = false) if (HasModule(PID, dll_name)) { cout << "[*] DLL already Loaded" << endl; - } - else + CloseHandle(hProc); + return; + }; + if (!fexists(dll_full_path)) { - if (!fexists(dll_full_path)) - { - cout << "[!] DLL file not found!" << endl; - return; - } - HINSTANCE hK32 = LoadLibraryA("kernel32"); - cout << "[*] Getting Address of LoadLibrary" << endl; - LPVOID LoadLibrary_Address = (LPVOID)GetProcAddress(hK32, "LoadLibraryA"); - FreeLibrary(hK32); - cout << "[+] LoadLibrary is at " << LoadLibrary_Address << endl; - cout << "[*] Allocating " << strlen(dll_full_path) << " Bytes of Memory" << endl; - LPVOID mem = VirtualAllocEx(hProc, NULL, strlen(dll_full_path), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); - if (mem == NULL) - { - cout << "[!] Could not Allocate Memory: " << GetLastErrorAsString() << endl; - return; - } - cout << "[*] Writing DLL Name to Process Memory at " << mem << endl; - WriteProcessMemory(hProc, mem, dll_full_path, strlen(dll_full_path), 0); - cout << "[*] Creating Thread to Load DLL" << endl; - if (do_resume) - { - hRemThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibrary_Address, mem, CREATE_SUSPENDED, 0); - ResumeThread(hRemThread); - } - else - { - hRemThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibrary_Address, mem, 0, 0); - } - cout << "[*] Waiting for DLL to load" << endl; - WaitForSingleObject(hRemThread, INFINITE); - CloseHandle(hRemThread); + cout << "[!] DLL file not found!" << endl; + CloseHandle(hProc); + return; } + HINSTANCE hK32 = LoadLibraryA("kernel32"); + cout << "[*] Getting Address of LoadLibrary" << endl; + LPVOID LoadLibrary_Address = (LPVOID)GetProcAddress(hK32, "LoadLibraryA"); + FreeLibrary(hK32); + cout << "[+] LoadLibrary is at " << LoadLibrary_Address << endl; + cout << "[*] Allocating " << strlen(dll_full_path) << " Bytes of Memory" << endl; + LPVOID mem = VirtualAllocEx(hProc, NULL, strlen(dll_full_path), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if (mem == NULL) + { + cout << "[!] Could not Allocate Memory: " << GetLastErrorAsString() << endl; + return; + } + cout << "[*] Writing DLL Name to Process Memory at " << mem << endl; + WriteProcessMemory(hProc, mem, dll_full_path, strlen(dll_full_path), 0); + cout << "[*] Creating Thread to Load DLL" << endl; + hRemThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibrary_Address, mem, 0, 0); + cout << "[*] Waiting for DLL to load" << endl; + WaitForSingleObject(hRemThread, INFINITE); + CloseHandle(hRemThread); cout << "[*] Closing Process Handle" << endl; CloseHandle(hProc); return; diff --git a/ScrapHacks/ScrapHack/D3D8_Hook.h b/ScrapHacks/ScrapHack/D3D8_Hook.h index 6f760fe..7b658f0 100644 --- a/ScrapHacks/ScrapHack/D3D8_Hook.h +++ b/ScrapHacks/ScrapHack/D3D8_Hook.h @@ -5,72 +5,89 @@ uintmax_t frame = 0; DWORD* GetVTable(void* addr) { return (DWORD*)(*(DWORD*)addr); } +bool overlay = false; +LPD3DXFONT m_pFont; +HFONT hFont; +HBRUSH hBrush; +D3DCOLOR color = D3DCOLOR_XRGB(255, 0, 0); +RECT Rect = { 0,0,0,0 }; +D3DRECT panel; void Render(LPDIRECT3DDEVICE8 dev) { - char text[MAX_PATH]; - LPD3DXFONT m_pFont; - HFONT hFont; - RECT Rect={0,0,0,0}; - D3DCOLOR color = D3DCOLOR_XRGB(255, 0, 0); - hFont = CreateFont(50, 0, 0, 0, FW_BOLD, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, "Verdana"); - D3DXCreateFont(dev, hFont, &m_pFont); - snprintf(text, MAX_PATH, "Frame: %d", ++frame); - if (m_pFont) { - m_pFont->Begin(); - m_pFont->DrawTextA(text, -1, &Rect, DT_CALCRECT, 0); - m_pFont->DrawTextA(text, -1, &Rect, DT_LEFT, color); - m_pFont->End(); - m_pFont->Release(); - m_pFont = nullptr; + if (!overlay) { + return; } - + char text[MAX_PATH]; + snprintf(text, MAX_PATH, "Frame: [%lld]\nTest", ++frame); + if (m_pFont == nullptr) { + D3DXCreateFont(dev, hFont, &m_pFont); + CloseHandle(hFont); + } + m_pFont->Begin(); + m_pFont->DrawTextA(text, -1, &Rect, DT_CALCRECT, 0); + + dev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(25, 0, 0, 0),0.5,0); + + m_pFont->DrawTextA(text, -1, &Rect, DT_LEFT, color); + m_pFont->End(); } HRESULT WINAPI H_EndScene(LPDIRECT3DDEVICE8 dev) { typedef HRESULT(WINAPI *t_func)(LPDIRECT3DDEVICE8); shared_ptr hook = Hook::get(H_EndScene); - t_func func = reinterpret_cast(hook->func()); + _asm push esi; + _asm pushad; Render(dev); hook->disable(); - HRESULT ret = func(dev); + HRESULT ret = hook->func()(dev); hook->enable(); + _asm popad; + _asm pop esi; return ret; - } HRESULT WINAPI H_CreateDevice(void* pDirect3D, unsigned int uiAdapter, D3DDEVTYPE pDeviceType, HWND hFocusWindow, unsigned long ulBehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, LPDIRECT3DDEVICE8* ppReturnedDeviceInterface) { + _asm push esi; + _asm pushad; typedef HRESULT(WINAPI *t_func)(void*, unsigned int, D3DDEVTYPE, HWND, unsigned long, D3DPRESENT_PARAMETERS*, LPDIRECT3DDEVICE8*); shared_ptr hook = Hook::get(H_CreateDevice); - t_func func = reinterpret_cast(hook->func()); hook->disable(); - HRESULT ret = func(pDirect3D, uiAdapter, pDeviceType, hFocusWindow, ulBehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); - cout << "Ret:" << ret << endl; - DWORD *vtable = GetVTable(ppReturnedDeviceInterface[0]); - cout << "Dev VTable @ " << vtable << endl; - cout << "Dev VTable[35]: " << (void*)(vtable[35]) << endl; // EndScene - Hook::addr((void*)vtable[35], H_EndScene); + HRESULT ret = hook->func()(pDirect3D, uiAdapter, pDeviceType, hFocusWindow, ulBehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); + cout << "CreateDevice ->" << ret << endl; + void* EndScene = reinterpret_cast(GetVTable(ppReturnedDeviceInterface[0])[35]); + cout << "EndScene @ " << EndScene << endl; // EndScene + Hook::addr(EndScene, H_EndScene); Hook::drop(H_CreateDevice); + _asm popad; + _asm pop esi; + return ret; } LPDIRECT3D8 WINAPI H_Direct3DCreate8(unsigned int SDKVersion) { typedef LPDIRECT3D8(_stdcall *t_func)(unsigned int); shared_ptr hook = Hook::get(H_Direct3DCreate8); - t_func func = reinterpret_cast(hook->func()); + + _asm push esi; + _asm pushad; + hook->disable(); - D3DPRESENT_PARAMETERS D3D_Present_Param = { 0,0,D3DFMT_UNKNOWN,0,D3DMULTISAMPLE_NONE,D3DSWAPEFFECT_DISCARD,0,1,0,D3DFMT_UNKNOWN,0,0,0 }; - LPDIRECT3D8 ret = func(SDKVersion); + LPDIRECT3D8 ret = hook->func()(SDKVersion); cout << "D3D8-Create: " << SDKVersion << " -> " << ret << endl; - DWORD *vtable = GetVTable(ret); - cout << "ID3D8 VTable @ " << vtable << endl; - cout << "ID3D8 VTable[15]: " << (void*)(vtable[15]) << endl; // CreateDevice - Hook::addr((void*)vtable[15], reinterpret_cast(H_CreateDevice)); + void *CreateDevice = reinterpret_cast(GetVTable(ret)[15]); + cout << "CreateDevice @ " << CreateDevice << endl; // CreateDevice + Hook::addr(CreateDevice, H_CreateDevice); Hook::drop(H_Direct3DCreate8); + _asm popad; + _asm pop esi; + return ret; } void hook_d3d8() { + hFont = CreateFont(20, 0, 0, 0, FW_BOLD, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, "Verdana"); + hBrush = CreateSolidBrush(D3DCOLOR_ARGB(25, 0, 0, 0)); Hook::module("d3d8.dll","Direct3DCreate8", H_Direct3DCreate8); } diff --git a/ScrapHacks/ScrapHack/Hook.h b/ScrapHacks/ScrapHack/Hook.h index bf675f0..64e719e 100644 --- a/ScrapHacks/ScrapHack/Hook.h +++ b/ScrapHacks/ScrapHack/Hook.h @@ -1,19 +1,18 @@ #pragma once #include -class Hook; - class Hook { private: - DWORD protect; + MEMORY_BASIC_INFORMATION mbi; void* orig; void* detour; bool enabled; uint8_t orig_bytes[6]; uint8_t jmp_bytes[6]; static map> hooks; - + public: + Hook(void* func, void* detour) { uintptr_t dest = reinterpret_cast(detour); uintptr_t src = reinterpret_cast(func); @@ -25,16 +24,18 @@ public: this->jmp_bytes[3] = (dest >> 16) & 0xff; this->jmp_bytes[4] = (dest >> 24) & 0xff; this->jmp_bytes[5] = 0xC3; // ret - VirtualProtect(func, 16, PAGE_EXECUTE_READWRITE, &(this->protect)); + VirtualQuery(func, &mbi, sizeof(mbi)); + VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &mbi.Protect); memcpy(this->orig_bytes, this->orig, 1 + 4 + 1); - VirtualProtect(func, 16, this->protect, NULL); + VirtualProtect(mbi.BaseAddress, mbi.RegionSize, mbi.Protect, NULL); this->enabled = false; } ~Hook() { + cout << "Unhooking: [" << this->orig << " <- " << this->detour << "]" << endl; this->disable(); } - + static void addr(void* addr, void* detour) { cout << "Hooking: [" << addr << " -> " << detour <<"]" << endl; uintptr_t key = reinterpret_cast(detour); @@ -72,31 +73,35 @@ public: } static void clear() { + cout << "Clearing Hooks" << endl; + for (pair> h : hooks) { + h.second->disable(); + } return hooks.clear(); } - void disable() { if (enabled) { //cout << "Disabling: [" << this->orig << " <- " << this->detour << "]" << endl; - VirtualProtect(this->orig, 16, PAGE_EXECUTE_READWRITE, NULL); + VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, NULL); memcpy(this->orig, this->orig_bytes, 1 + 4 + 1); - VirtualProtect(this->orig, 16, this->protect, NULL); + VirtualProtect(mbi.BaseAddress, mbi.RegionSize, mbi.Protect, NULL); enabled = false; } } void enable() { if (!enabled) { //cout << "Enabling: [" << this->orig << " -> " << this->detour << "]" << endl; - VirtualProtect(this->orig, 16, PAGE_EXECUTE_READWRITE, NULL); + VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, NULL); memcpy(this->orig, this->jmp_bytes, 1 + 4 + 1); - VirtualProtect(this->orig, 16, this->protect, NULL); + VirtualProtect(mbi.BaseAddress, mbi.RegionSize, mbi.Protect, NULL); enabled = true; } } - - void* func() { - return this->orig; + + template + T func() { + return reinterpret_cast(this->orig); } }; diff --git a/ScrapHacks/ScrapHack/ScrapHack.cpp b/ScrapHacks/ScrapHack/ScrapHack.cpp index 8c2ecd5..409011c 100644 --- a/ScrapHacks/ScrapHack/ScrapHack.cpp +++ b/ScrapHacks/ScrapHack/ScrapHack.cpp @@ -22,6 +22,7 @@ using namespace std; #include "Structures.h" #include "Py_Utils.h" #include "Hook.h" +#include "VMT_Hook.h" #include "D3D8_Hook.h" HMODULE hD3D8Dll = 0; @@ -30,29 +31,58 @@ bool initialized = false; bool running = true; HMODULE mod = 0; +void dump_ht(HashTable* ht) { + size_t cnt = 0; + for (size_t i = 0; i < ht->size; ++i) { + HashTableEntry* ent = ht->chains[i]; + if (ent != NULL) { + cout << i << ": "; + while (ent != NULL) { + ++cnt; + cout << ent->name; + if (ent->next) { + cout << " -> "; + }; + ent = ent->next; + } + cout << endl; + } + } + cout << cnt << " Entities" << endl; + return; +} + void MainLoop(HMODULE mod) { Sleep(100); cout << "[*] Starting main Loop" << endl; cout << endl; cout << "[F3 ] Unload ScrapHacks" << endl; + cout << "[F5 ] Show Overlay" << endl; cout << "[F6 ] Show Alarm status" << endl; cout << "[F7 ] Set Money to 0x7fffffff" << endl; cout << "[F8 ] Dump python modules" << endl; + cout << "[F9 ] Dump Entity hashtable" << endl; cout << "[F10] Enable python tracing" << endl; cout << "[ F ] \"Handbrake\" (*Will* crash the game after some time!)" << endl; while (running) { Sleep(100); - if (key_down_norepeat(VK_F10)) - { - scrap_exec("dbg.settrace()"); - } + while (key_down('F')) { scrap_exec("dbg.brake()"); } + if (key_down_norepeat(VK_F3)) + { + break; + } + + if (key_down_norepeat(VK_F5)) + { + overlay = !overlay; + } if (key_down_norepeat(VK_F6)) { @@ -75,17 +105,16 @@ void MainLoop(HMODULE mod) } } } - if (key_down_norepeat(VK_F3)) + + if (key_down_norepeat(VK_F9)) { + HashTable *ht = ptr(P_WORLD,O_HASHTABLE); + dump_ht(ht); + } + if (key_down_norepeat(VK_F10)) { - break; + scrap_exec("dbg.settrace()"); } } - SetConsoleCtrlHandler(NULL, false); - Hook::clear(); - scrap_log(0xff0000, "ScrapHacks unloaded!\n"); - cout << "[+] ScrapHacks unloaded, you can now close the console!" << endl; - FreeConsole(); - PostQuitMessage(0); FreeLibraryAndExitThread(mod, 0); } @@ -107,13 +136,12 @@ void handle_command(const char* cmd) { int hooked_console(const char* cmd) { typedef int(_cdecl *t_func)(const char*); shared_ptr hook = Hook::get(hooked_console); - t_func func= reinterpret_cast(hook->func()); if (cmd[0] == '$') { handle_command(++cmd); return 0; } hook->disable(); - int ret=func(cmd); + int ret= hook->func()(cmd); hook->enable(); return ret; } @@ -122,7 +150,6 @@ void hook_console() { Hook::addr(reinterpret_cast(P_CON_HANDLER) , hooked_console); } - void DllPreInit(HMODULE _mod) { char mfn[1024]; InitConsole(); @@ -151,4 +178,14 @@ void DllInit(HMODULE _mod) DispatchMessage(&msg); } return; +} + +void DllUnload(HMODULE _mod) { + SetConsoleCtrlHandler(NULL, false); + Hook::clear(); + scrap_log(0xff0000, "ScrapHacks unloaded!\n"); + cout << "[+] ScrapHacks unloaded, you can now close the console!" << endl; + FreeConsole(); + PostQuitMessage(0); + return; } \ No newline at end of file diff --git a/ScrapHacks/ScrapHack/ScrapHack.vcxproj b/ScrapHacks/ScrapHack/ScrapHack.vcxproj index 6d983f1..31c19a7 100644 --- a/ScrapHacks/ScrapHack/ScrapHack.vcxproj +++ b/ScrapHacks/ScrapHack/ScrapHack.vcxproj @@ -154,6 +154,7 @@ + diff --git a/ScrapHacks/ScrapHack/ScrapHack.vcxproj.filters b/ScrapHacks/ScrapHack/ScrapHack.vcxproj.filters index 962bf28..042a2e6 100644 --- a/ScrapHacks/ScrapHack/ScrapHack.vcxproj.filters +++ b/ScrapHacks/ScrapHack/ScrapHack.vcxproj.filters @@ -39,6 +39,9 @@ Headerdateien + + Headerdateien + diff --git a/ScrapHacks/ScrapHack/Scrapland.h b/ScrapHacks/ScrapHack/Scrapland.h index a55cd3f..08d6b44 100644 --- a/ScrapHacks/ScrapHack/Scrapland.h +++ b/ScrapHacks/ScrapHack/Scrapland.h @@ -1,8 +1,10 @@ #pragma once + //OFFSETS #define O_MONEY 0x2090 #define O_ALARM 0x1C6C #define O_ALARM_GROW 0x1C68 +#define O_HASHTABLE 0x4 //POINTERS #define P_WORLD 0x7FE944 diff --git a/ScrapHacks/ScrapHack/Structures.h b/ScrapHacks/ScrapHack/Structures.h index 850f63b..df3affb 100644 --- a/ScrapHacks/ScrapHack/Structures.h +++ b/ScrapHacks/ScrapHack/Structures.h @@ -1,5 +1,5 @@ #pragma once - +struct HashTableEntry; struct Vector3 { float x; float y; @@ -32,3 +32,19 @@ struct Module PyMod *mod; map methods; }; + +struct Entity { + void* VMT; + +}; + +struct HashTable { + uint32_t size; + HashTableEntry** chains; +}; + +struct HashTableEntry { + Entity* data; + const char* name; + HashTableEntry* next; +}; \ No newline at end of file diff --git a/ScrapHacks/ScrapHack/VMT_Hook.h b/ScrapHacks/ScrapHack/VMT_Hook.h new file mode 100644 index 0000000..1759cc8 --- /dev/null +++ b/ScrapHacks/ScrapHack/VMT_Hook.h @@ -0,0 +1,91 @@ + +#pragma once +class VMT_Hook +{ +private: + MEMORY_BASIC_INFORMATION mbi; + void* orig; + void* detour; + DWORD* vtable; + size_t ord; + bool enabled; + static map> hooks; + static DWORD* GetVTable(void* addr) { + return (DWORD *)*(DWORD *)addr; + }; + + +public: + + VMT_Hook(void* obj, size_t ord, void* detour) { + this->vtable = GetVTable(obj); + this->detour = detour; + this->orig = reinterpret_cast(vtable[ord]); + this->ord = ord; + this->enabled = false; + + VirtualQuery(&this->vtable[this->ord], &mbi, sizeof(mbi)); + cout << "Hooking: " << this->vtable << "[" << this->ord << "]: (" << this->orig << " -> " << this->detour << ")" << endl; + } + + ~VMT_Hook() { + cout << "Unhooking: " << this->vtable << "[" << this->ord << "]: (" << this->orig << " -> " << this->detour << ")" << endl; + this->disable(); + } + + static void create(void* obj, size_t ord, void* detour) { + uintptr_t key = reinterpret_cast(detour); + hooks[key] = make_shared(obj,ord, detour); + hooks[key]->enable(); + } + + static shared_ptr get(void* func) { + uintptr_t addr = reinterpret_cast(func); + return VMT_Hook::get(addr); + } + + static shared_ptr get(uintptr_t addr) { + return hooks.at(addr); + } + + static size_t drop(void* func) { + uintptr_t addr = reinterpret_cast(func); + return VMT_Hook::drop(addr); + } + + static size_t drop(uintptr_t addr) { + return hooks.erase(addr); + } + + static void clear() { + return hooks.clear(); + } + + void disable() { + if (enabled) { + cout << "Disabling: " << this->vtable << "[" << this->ord << "]: (" << this->orig << " -> " << this->detour<<")" << endl; + VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, NULL); + this->vtable[ord] = reinterpret_cast(this->orig); + VirtualProtect(mbi.BaseAddress, mbi.RegionSize, mbi.Protect, NULL); + enabled = false; + } + } + void enable() { + if (!enabled) { + cout << "Enabling: " << this->vtable << "[" << this->ord << "]: (" << this->orig << " -> " << this->detour <<")" << endl; + VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, NULL); + this->vtable[ord] = reinterpret_cast(this->detour); + VirtualProtect(mbi.BaseAddress, mbi.RegionSize, mbi.Protect, NULL); + enabled = true; + } + } + + template + T func() { + return reinterpret_cast(this->orig); + } + +}; + +map> VMT_Hook::hooks; + diff --git a/ScrapHacks/ScrapHack/dllmain.cpp b/ScrapHacks/ScrapHack/dllmain.cpp index 6fab88b..b11b433 100644 --- a/ScrapHacks/ScrapHack/dllmain.cpp +++ b/ScrapHacks/ScrapHack/dllmain.cpp @@ -2,6 +2,8 @@ #define DLL_EXPORT extern "C" __declspec(dllexport) void DllInit(HMODULE); void DllPreInit(HMODULE); +void DllUnload(HMODULE); + BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, @@ -16,6 +18,8 @@ BOOL APIENTRY DllMain(HMODULE hModule, hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)DllInit, hModule, 0, 0); break; case DLL_PROCESS_DETACH: + DllUnload(hModule); + break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; diff --git a/ScrapHacks/Scrapland_Tools.sln b/ScrapHacks/Scrapland_Tools.sln index 3c2d8c4..f526d15 100644 --- a/ScrapHacks/Scrapland_Tools.sln +++ b/ScrapHacks/Scrapland_Tools.sln @@ -9,24 +9,30 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Injector", "Injector\Inject EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {72CB1B9E-50C7-4010-BEAD-82FACF87A87A}.Debug|Any CPU.ActiveCfg = Debug|Win32 {72CB1B9E-50C7-4010-BEAD-82FACF87A87A}.Debug|x64.ActiveCfg = Debug|x64 {72CB1B9E-50C7-4010-BEAD-82FACF87A87A}.Debug|x64.Build.0 = Debug|x64 {72CB1B9E-50C7-4010-BEAD-82FACF87A87A}.Debug|x86.ActiveCfg = Debug|Win32 {72CB1B9E-50C7-4010-BEAD-82FACF87A87A}.Debug|x86.Build.0 = Debug|Win32 + {72CB1B9E-50C7-4010-BEAD-82FACF87A87A}.Release|Any CPU.ActiveCfg = Release|Win32 {72CB1B9E-50C7-4010-BEAD-82FACF87A87A}.Release|x64.ActiveCfg = Release|x64 {72CB1B9E-50C7-4010-BEAD-82FACF87A87A}.Release|x64.Build.0 = Release|x64 {72CB1B9E-50C7-4010-BEAD-82FACF87A87A}.Release|x86.ActiveCfg = Release|Win32 {72CB1B9E-50C7-4010-BEAD-82FACF87A87A}.Release|x86.Build.0 = Release|Win32 + {7C91C225-D95C-4B7A-9251-0CE358BAF556}.Debug|Any CPU.ActiveCfg = Debug|Win32 {7C91C225-D95C-4B7A-9251-0CE358BAF556}.Debug|x64.ActiveCfg = Debug|x64 {7C91C225-D95C-4B7A-9251-0CE358BAF556}.Debug|x64.Build.0 = Debug|x64 {7C91C225-D95C-4B7A-9251-0CE358BAF556}.Debug|x86.ActiveCfg = Debug|Win32 {7C91C225-D95C-4B7A-9251-0CE358BAF556}.Debug|x86.Build.0 = Debug|Win32 + {7C91C225-D95C-4B7A-9251-0CE358BAF556}.Release|Any CPU.ActiveCfg = Release|Win32 {7C91C225-D95C-4B7A-9251-0CE358BAF556}.Release|x64.ActiveCfg = Release|x64 {7C91C225-D95C-4B7A-9251-0CE358BAF556}.Release|x64.Build.0 = Release|x64 {7C91C225-D95C-4B7A-9251-0CE358BAF556}.Release|x86.ActiveCfg = Release|Win32