diff options
author | BDKPlayer <fabian.stotz@yahoo.de> | 2020-03-02 21:42:04 +0100 |
---|---|---|
committer | BDKPlayer <fabian.stotz@yahoo.de> | 2020-03-02 21:42:04 +0100 |
commit | 2eb506165d3d451d9daafdec8b499444bb34351b (patch) | |
tree | e38ec606fee7dc10fcff0fe94f431e70086a558e | |
parent | 29fd5947870063c106040afd2b3814488eeec2ab (diff) |
Added: x64 minimap text hook
-rw-r--r-- | AoE_imgui_DE.vcxproj | 4 | ||||
-rw-r--r-- | AoE_imgui_DE.vcxproj.filters | 12 | ||||
-rw-r--r-- | Classes.h | 10 | ||||
-rw-r--r-- | Core.cpp | 15 | ||||
-rw-r--r-- | DetourHook64.cpp | 92 | ||||
-rw-r--r-- | DetourHook64.h | 21 | ||||
-rw-r--r-- | ESP.cpp | 48 | ||||
-rw-r--r-- | ESP.h | 10 | ||||
-rw-r--r-- | FeatureManager.cpp | 2 | ||||
-rw-r--r-- | MinimapText.cpp | 46 | ||||
-rw-r--r-- | MinimapText.h | 13 | ||||
-rw-r--r-- | Source.cpp | 6 |
12 files changed, 253 insertions, 26 deletions
diff --git a/AoE_imgui_DE.vcxproj b/AoE_imgui_DE.vcxproj index 413db17..7b5f219 100644 --- a/AoE_imgui_DE.vcxproj +++ b/AoE_imgui_DE.vcxproj @@ -144,6 +144,7 @@ <ItemGroup> <ClInclude Include="Classes.h" /> <ClInclude Include="Core.h" /> + <ClInclude Include="DetourHook64.h" /> <ClInclude Include="detours.h" /> <ClInclude Include="Engine.h" /> <ClInclude Include="ESP.h" /> @@ -158,6 +159,7 @@ <ClInclude Include="imgui\imstb_textedit.h" /> <ClInclude Include="imgui\imstb_truetype.h" /> <ClInclude Include="main.h" /> + <ClInclude Include="MinimapText.h" /> <ClInclude Include="Offsets.h" /> <ClInclude Include="Renderer.h" /> <ClInclude Include="ResourceInformation.h" /> @@ -167,6 +169,7 @@ </ItemGroup> <ItemGroup> <ClCompile Include="Core.cpp" /> + <ClCompile Include="DetourHook64.cpp" /> <ClCompile Include="Engine.cpp" /> <ClCompile Include="ESP.cpp" /> <ClCompile Include="Feature.cpp" /> @@ -177,6 +180,7 @@ <ClCompile Include="imgui\imgui_impl_dx11.cpp" /> <ClCompile Include="imgui\imgui_impl_win32.cpp" /> <ClCompile Include="imgui\imgui_widgets.cpp" /> + <ClCompile Include="MinimapText.cpp" /> <ClCompile Include="Renderer.cpp" /> <ClCompile Include="ResourceInformation.cpp" /> <ClCompile Include="Source.cpp" /> diff --git a/AoE_imgui_DE.vcxproj.filters b/AoE_imgui_DE.vcxproj.filters index e51e3d6..e5ef37a 100644 --- a/AoE_imgui_DE.vcxproj.filters +++ b/AoE_imgui_DE.vcxproj.filters @@ -102,6 +102,12 @@ <ClInclude Include="ESP.h"> <Filter>Header Files\Feature</Filter> </ClInclude> + <ClInclude Include="MinimapText.h"> + <Filter>Header Files\Feature</Filter> + </ClInclude> + <ClInclude Include="DetourHook64.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="imgui\imgui.cpp"> @@ -146,5 +152,11 @@ <ClCompile Include="ESP.cpp"> <Filter>Source Files\Feature</Filter> </ClCompile> + <ClCompile Include="MinimapText.cpp"> + <Filter>Source Files\Feature</Filter> + </ClCompile> + <ClCompile Include="DetourHook64.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> </Project>
\ No newline at end of file @@ -99,9 +99,9 @@ public: char pad_0x0030[0x40]; //0x0030 Resources* pResources; //0x0070 char pad_0x0078[0xD8]; //0x0078 - int* Color1; //0x0150 - int* Color2; //0x0158 - int* Color3; //0x0160 + void* unk; //0x0150 + int* playerColor; //0x0158 + int* unk1; //0x0160 }; //Size=0x0188 @@ -217,8 +217,8 @@ class PlayerData { public: Player* player; //0x0000 - void* unk; //0x0004 -}; //Size: 0x0008 + void* unk; //0x0008 +}; class PlayerArray { @@ -15,20 +15,23 @@ //Features #include "ResourceInformation.h" #include "ESP.h" - +#include "MinimapText.h" Core::Core() { //Register Features here FeatureManager::Get()->registerFeature(new ResourceInformation()); FeatureManager::Get()->registerFeature(new ESP()); + FeatureManager::Get()->registerFeature(new MinimapText()); FeatureManager::Get()->OnInitialise(); } void createPlayerTreeNode(Player* player, int playerIndex) { - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1, 1, 1, 1)); + ImGui::PushStyleColor(ImGuiCol_Text, Engine::Get()->GetPlayerColorImGUI(*player->playerColor)); + + std::string playerText = "Player " + std::to_string(playerIndex); if (ImGui::TreeNode(playerText.c_str())) { @@ -83,6 +86,9 @@ void Core::OnPresent() //printf("mainScreen: %p\n", mainScreen); if (!mainScreen) { + ImGui::Begin("AoE Hackbase - BDKPlayer", (bool*)0, ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav); + ImGui::Text("Waiting for game to start..."); + ImGui::End(); return; } @@ -124,8 +130,9 @@ void Core::OnPresent() } printf("Iterating players\n"); - for (int i = 1; i < totalPlayers; i++) + for (int i = 1; i <= totalPlayers; i++) { + printf("PlayerIndex: %d\n", i); Player* player = playerArray->playerData[i].player; if (!player) { @@ -160,7 +167,7 @@ void Core::OnPresent() ImGui::Text("PlayerArray %p", playerArray); ImGui::Text("totalPlayers %d", totalPlayers); ImGui::Text("ScreenPos %f %f %f", mainScreen->pGameScreen->pMainView->ScreenPosX, mainScreen->pGameScreen->pMainView->ScreenPosY, mainScreen->pGameScreen->pMainView->ScreenPosZ); - for (int i = 0; i < totalPlayers; i++) + for (int i = 0; i <= totalPlayers; i++) { createPlayerTreeNode(playerArray->playerData[i].player, i); } diff --git a/DetourHook64.cpp b/DetourHook64.cpp new file mode 100644 index 0000000..0cd0f47 --- /dev/null +++ b/DetourHook64.cpp @@ -0,0 +1,92 @@ +#include "DetourHook64.h" +#include <cstdio> + + + +//Detours x64 functions. The shellcode passed is expected to be relocated already +BYTE* DetourHook64::Hook(BYTE* hookAddress, BYTE* shellcode, int shellcodeSize, uint64_t jmpBack, int length, int pageSize) +{ + //Save original to be able to unhook + this->shellcodeSize = shellcodeSize; + this->hookAddress = hookAddress; + this->pageSize = pageSize; + this->originalBytes = new BYTE[length]; + + + printf("MinimapText - Hook\n"); + + //Make original code writeable (.text segment usually read only). + DWORD oldProtection; + if (!VirtualProtect(hookAddress, length, PAGE_EXECUTE_READWRITE, &oldProtection)) + { + return NULL; //Couldn't make memory writeable + } + printf("MinimapText - VirtualProtect\n"); + + + for (int i = 0; i < length; i++) + { + this->originalBytes[i] = hookAddress[i]; + printf("Original Byte %i: %x\n", i, hookAddress[i]); + } + + + //Create VirtualMemoryPage somewhere (NULL) lets system decide + trampoline = (BYTE*)VirtualAlloc(NULL, pageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); + + printf("MinimapText - trampoline\n"); + + if (!trampoline) + { + return NULL; //Couldn't allocate virtual memory + } + + //Copy shellcode into new memory page + for (int i = 0; i < shellcodeSize; i++) + { + trampoline[i] = shellcode[i]; + } + + //Add jump back to original code into new memory + trampoline[shellcodeSize] = 0xFF; //opcodes = JMP [rip+0] + trampoline[shellcodeSize + 1] = 0x25; //opcodes = JMP [rip+0] + *(uint32_t*)(&trampoline[shellcodeSize + 2]) = 0; //relative distance from RIP (+0) + *(uint64_t*)(&trampoline[shellcodeSize + 2 + 4]) = jmpBack; //destination to jump to + + //Jump to allocated code + hookAddress[0] = 0xFF; //opcodes = JMP [rip+0] + hookAddress[1] = 0x25; //opcodes = JMP [rip+0] + *(uint32_t*)(&hookAddress[2]) = 0; //relative distance from RIP (+0) + *(uint64_t*)(&hookAddress[2 + 4]) = (uint64_t)trampoline; //destination to jump to + + //Restore page protection + if (!VirtualProtect(hookAddress, length, oldProtection, &oldProtection)) + { + VirtualFree(trampoline, pageSize, MEM_RELEASE); + return NULL; //Couldn't restore memory protection + } + + return trampoline; +} + + + +bool DetourHook64::Unhook() +{ + DWORD oldProtection; + if (!VirtualProtect(hookAddress, 14, PAGE_EXECUTE_READWRITE, &oldProtection)) + { + return false; //Couldn't make memory writeable + } + + memcpy(hookAddress, originalBytes, 14); + VirtualFree(trampoline, pageSize, MEM_RELEASE); + delete[] originalBytes; + + if (!VirtualProtect(hookAddress, 14, oldProtection, &oldProtection)) + { + return false; //Couldn't restore memory protection + } + + return true; +} diff --git a/DetourHook64.h b/DetourHook64.h new file mode 100644 index 0000000..7236608 --- /dev/null +++ b/DetourHook64.h @@ -0,0 +1,21 @@ +#pragma once +#include <Windows.h> +#include <cstdint> + + +class DetourHook64 +{ + BYTE* originalBytes; + BYTE* hookAddress; + BYTE* trampoline; + + int shellcodeSize; + int length = 14; + int pageSize = 4096; + +public: + //Detours x64 functions. The shellcode passed is expected to be relocated already + BYTE* Hook(BYTE* hookAddress, BYTE* shellcode, int shellcodeSize, uint64_t jmpBack, int length = 14, int pageSize = 4096); + bool Unhook(); + +};
\ No newline at end of file @@ -4,6 +4,7 @@ #include "Renderer.h" #include "Engine.h" +uint32_t ESP::colors_hex[8] = { 0xff0000ff, 0xffff0000,0xff00ff00,0xffffff00,0xff00ffff,0xffff00ff,0xffffffff,0xffffb400 }; void ESP::DrawBox(Unit* unit, int32_t color, bool drawName = false) { @@ -52,7 +53,7 @@ void ESP::OnUnitIteration(Unit* unit, Player* player, int playerIndex) { return; //Dont display annoying flares that Bots use } - DrawBox(unit, colors_hex[0], playerUnitNameEsp[playerIndex]); + DrawBox(unit, colors_hex[*player->playerColor], playerUnitNameEsp[playerIndex]); } } @@ -77,36 +78,65 @@ void ESP::OnNeutralUnit(Unit* unit) if (goldESP && strcmp(unitName.c_str(), "GOLDM") == 0) { DrawBox(unit, 0xFFFFD700); + return; } if (stoneESP && strcmp(unitName.c_str(), "STONM") == 0) { DrawBox(unit, 0xFF888c8d); + return; + } + if (stoneESP && strcmp(unitName.c_str(), "FORAG") == 0 || stoneESP && strcmp(unitName.c_str(), "FORAGM") == 0) + { + DrawBox(unit, 0xff00ff00); + return; } - if (strcmp(unitName.c_str(), "BOARX") == 0) + if (strcmp(unitName.c_str(), "FISHS") == 0 || strcmp(unitName.c_str(), "FISHX") == 0 || + strcmp(unitName.c_str(), "FISH1") == 0 || strcmp(unitName.c_str(), "FISH2") == 0 || + strcmp(unitName.c_str(), "FISH3") == 0 || strcmp(unitName.c_str(), "FISH4") == 0 || + strcmp(unitName.c_str(), "turtles") == 0) { - Renderer::Get()->RenderCircleFilled(ImVec2(screenPos.x, screenPos.y), 20, 0x4000ff00); + Renderer::Get()->RenderCircleFilled(ImVec2(screenPos.x, screenPos.y), 20, 0x400000ff); Renderer::Get()->RenderText(unitName, ImVec2(screenPos.x, screenPos.y), 16, 0xffffffff); } - if (strcmp(unitName.c_str(), "SHEEPG") == 0) + + if (strcmp(unitName.c_str(), "BOARX") == 0 || strcmp(unitName.c_str(), "RHINO") == 0 || + strcmp(unitName.c_str(), "BOAR") == 0 || strcmp(unitName.c_str(), "BOARJ") == 0) { - Renderer::Get()->RenderCircleFilled(ImVec2(screenPos.x, screenPos.y), 20, 0x400000ff); + Renderer::Get()->RenderCircleFilled(ImVec2(screenPos.x, screenPos.y), 20, 0x4000ff00); Renderer::Get()->RenderText(unitName, ImVec2(screenPos.x, screenPos.y), 16, 0xffffffff); } - if (strcmp(unitName.c_str(), "WOLFX") == 0) + + if (strcmp(unitName.c_str(), "DEERX") == 0 || strcmp(unitName.c_str(), "IBEX") == 0) { - Renderer::Get()->RenderCircleFilled(ImVec2(screenPos.x, screenPos.y), 20, 0x40ff0000); + Renderer::Get()->RenderCircleFilled(ImVec2(screenPos.x, screenPos.y), 20, 0x4000ffff); Renderer::Get()->RenderText(unitName, ImVec2(screenPos.x, screenPos.y), 16, 0xffffffff); } - if (strcmp(unitName.c_str(), "FISHX") == 0 || strcmp(unitName.c_str(), "FISH1") == 0 || strcmp(unitName.c_str(), "FISH2") == 0 || strcmp(unitName.c_str(), "FISH3") == 0 || strcmp(unitName.c_str(), "FISH4") == 0) + if (strcmp(unitName.c_str(), "SHEEPG") == 0 || strcmp(unitName.c_str(), "GOOSE") == 0 || + strcmp(unitName.c_str(), "PIG") == 0 || strcmp(unitName.c_str(), "LLAMAG") == 0 || + strcmp(unitName.c_str(), "Cow Black") == 0 || strcmp(unitName.c_str(), "Cow Brown") == 0 || + strcmp(unitName.c_str(), "Cow Black and White") == 0 || strcmp(unitName.c_str(), "BUFFALO") == 0 || + strcmp(unitName.c_str(), "TURKYG") == 0 || strcmp(unitName.c_str(), "Cow Black") == 0) { Renderer::Get()->RenderCircleFilled(ImVec2(screenPos.x, screenPos.y), 20, 0x400000ff); Renderer::Get()->RenderText(unitName, ImVec2(screenPos.x, screenPos.y), 16, 0xffffffff); } + + + if (strcmp(unitName.c_str(), "WOLFX") == 0 || strcmp(unitName.c_str(), "KOMODO") == 0 || + strcmp(unitName.c_str(), "GJAGR") == 0 || strcmp(unitName.c_str(), "SLEOPA") == 0 || + strcmp(unitName.c_str(), "BEAR") == 0 || + strcmp(unitName.c_str(), "LION") == 0 || strcmp(unitName.c_str(), "TIGER") == 0) + { + Renderer::Get()->RenderCircleFilled(ImVec2(screenPos.x, screenPos.y), 20, 0x40ff0000); + Renderer::Get()->RenderText(unitName, ImVec2(screenPos.x, screenPos.y), 16, 0xffffffff); + } + + if (strcmp(unitName.c_str(), "RELIC") == 0) { - Renderer::Get()->RenderCircleFilled(ImVec2(screenPos.x, screenPos.y), 20, 0x40ffffff); + Renderer::Get()->RenderCircleFilled(ImVec2(screenPos.x, screenPos.y), 50, 0x40ffffff); Renderer::Get()->RenderText(unitName, ImVec2(screenPos.x, screenPos.y), 16, 0xffffffff); } } @@ -3,16 +3,16 @@ class ESP : public Feature { - bool gaiaEsp = false; - bool goldESP = false; - bool stoneESP = false; - bool playerUnitEsp[8] = { false,true,true,true,true,true,true,true }; + bool gaiaEsp = true; + bool goldESP = true; + bool stoneESP = true; + bool playerUnitEsp[8] = { false,false,true,true,true,true,true,true }; bool playerUnitNameEsp[8] = { false,false,false,false,false,false,false,false }; //bool playerBuildingEsp[8] = { false,true,true,true,true,true,true,true }; //bool playerBuildingNameEsp[8] = { false,true,true,true,true,true,true,true }; float colors[8][3]; - uint32_t colors_hex[8] = { 0xff0000ff, 0xffff0000,0xff00ff00,0xffffff00,0xff00ffff,0xffff00ff,0xffffffff,0xffffb400 }; + static uint32_t colors_hex[8]; //Callbacks void OnUnitIteration(Unit* unit, Player* player, int playerIndex); diff --git a/FeatureManager.cpp b/FeatureManager.cpp index 4448f2c..c70b72d 100644 --- a/FeatureManager.cpp +++ b/FeatureManager.cpp @@ -22,6 +22,8 @@ FeatureManager* FeatureManager::Get() void FeatureManager::registerFeature(Feature* feature) { + static int feature_numer = 0; + printf("Registered feature %d\n", feature_numer); features.push_back(feature); } diff --git a/MinimapText.cpp b/MinimapText.cpp new file mode 100644 index 0000000..c5f3ae6 --- /dev/null +++ b/MinimapText.cpp @@ -0,0 +1,46 @@ + + + +#include "MinimapText.h" + +#include "Engine.h" +#include "Sdk.h" +#include "Renderer.h" +#include "Utility.h" + +#include "DetourHook64.h" + +#pragma warning( disable : 4244 ) + + +bool hookEnabled = true; + + +char* name = "NewName"; + + +void MinimapText::OnInitialise() +{ + const int shellcodeSize = 29; + BYTE shellcode[shellcodeSize] = { 0x8B, 0x84, 0xF5, 0x24, 0x1, 0x0, 0x0, // mov eax, [rbp+rsi*8+5F8h+var_4D4] <-- orginal code + 0x89, 0x44, 0x24, 0x20, // mov dword ptr[rsp + 6D0h + var_6B0], eax <-- orginal code + 0x44, 0x8B, 0x8C, 0xF5, 0x20, 0x1, 0x0, 0x0, // mov r9d, dword ptr[rbp + rsi * 8 + 5F8h + var_4DC + 4] <-- orginal code + 0x49, 0xB8, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }; //MOV R8, 0x1122334455667788 <-- new code (replaces string to print) + *(uint64_t*)(&shellcode[21]) = (uint64_t)name; + + //8B 84 F5 ? ? ? ? 89 + BYTE* hookAddress = (BYTE*)((int64_t)GetModuleHandle(NULL)+0xA429FD); + + minimapTextDetour = new DetourHook64(); + minimapTextDetour->Hook(hookAddress, shellcode, shellcodeSize, (uint64_t)(hookAddress + 23), 19); +} + +void MinimapText::OnShutdown() +{ + minimapTextDetour->Unhook(); +} + +void MinimapText::OnMenuMainWindow() +{ + ImGui::Checkbox("Minimap Ressource Information", &hookEnabled); +}
\ No newline at end of file diff --git a/MinimapText.h b/MinimapText.h new file mode 100644 index 0000000..808c11c --- /dev/null +++ b/MinimapText.h @@ -0,0 +1,13 @@ +#pragma once +#include "Feature.h" + +class DetourHook64; +class MinimapText : public Feature +{ + DetourHook64* minimapTextDetour; + + //Callbacks + void OnInitialise(); + void OnMenuMainWindow(); + void OnShutdown(); +};
\ No newline at end of file @@ -38,7 +38,7 @@ DWORD_PTR* pSwapChainVtable = NULL; VOID WINAPI OnDllAttach(PVOID base) { -#ifdef DEBUG +#ifdef _DEBUG AllocConsole(); freopen_s((FILE**)stdin, "CONIN$", "r", stdin); freopen_s((FILE**)stdout, "CONOUT$", "w", stdout); @@ -48,7 +48,7 @@ VOID WINAPI OnDllAttach(PVOID base) VOID WINAPI OnDllDetach() { -#ifdef DEBUG +#ifdef _DEBUG fclose((FILE*)stdin); fclose((FILE*)stdout); @@ -283,7 +283,7 @@ DWORD __stdcall InitHooks(LPVOID hModule) DWORD dwOld; VirtualProtect(phookD3D11Present, 2, PAGE_EXECUTE_READWRITE, &dwOld); - while (!(GetAsyncKeyState(VK_DELETE) & 0x8000)) { + while (!(GetAsyncKeyState(VK_F2) & 0x8000)) { Sleep(10); } |