diff options
author | BDKPlayer <fabian.stotz@yahoo.de> | 2020-04-01 11:29:39 +0200 |
---|---|---|
committer | BDKPlayer <fabian.stotz@yahoo.de> | 2020-04-01 11:29:39 +0200 |
commit | 1d01371aebc416819af2ddd8e77c86e762011314 (patch) | |
tree | be692883d4d09fa84c686a579cba76e3f2cde516 | |
parent | 78ddf8f82467c64d8653cea199e1f435afe41b76 (diff) |
Updated to game version 101.101.36202.0 4819260
-rw-r--r-- | Classes.h | 8 | ||||
-rw-r--r-- | Core.cpp | 16 | ||||
-rw-r--r-- | CustomLoadingScreen.cpp | 9 | ||||
-rw-r--r-- | ESP.cpp | 10 | ||||
-rw-r--r-- | ESP.h | 2 | ||||
-rw-r--r-- | MidfunctionHook.cpp | 21 | ||||
-rw-r--r-- | MidfunctionHook.h | 25 | ||||
-rw-r--r-- | MinimapText.cpp | 12 | ||||
-rw-r--r-- | Offsets.cpp | 30 | ||||
-rw-r--r-- | RelicManager.cpp | 2 | ||||
-rw-r--r-- | Utility.h | 15 |
11 files changed, 111 insertions, 39 deletions
@@ -303,7 +303,13 @@ public: return reinterpret_cast<Vector3*>(actionMoveTo + 0x38); } - + + typedef char(__fastcall* fhsMoveToCaller)(Unit* unit, Unit* targetUnit, World* world, int64_t zero, float xPos, float yPos, int zero2); + void MoveTo(World* world, float xPos, float yPos) + { + static fhsMoveToCaller moveUnitCaller = (fhsMoveToCaller)((int64_t)GetModuleHandle(NULL) + 0xc863a0); + moveUnitCaller(this, 0, world, 0, xPos, yPos, 0); + } }; //Size=0x0250 @@ -11,6 +11,7 @@ #include "Core.h" #include "Engine.h" #include "FeatureManager.h" +#include "Utility.h" //Features #include "ResourceInformation.h" @@ -57,6 +58,17 @@ void createPlayerTreeNode(Player* player, int playerIndex) ImGui::Text("%p", unit); ImGui::SameLine(); ImGui::Text("%s", unit->pUnitData->name); + ImGui::SameLine(); + std::string text = std::string("Copy##") + std::string(unit->pUnitData->name) + std::to_string(i); + /*if (ImGui::Button(text.c_str())) + { + unit->MoveTo(Engine::Get()->GetWorld(), 50.f, 50.f); + }*/ + + if (ImGui::Button(text.c_str())) + { + Utility::CopyToClipboard((uint64_t)unit); + } /* if (unit->pUnitData->Class == (int16_t)EnumUnitDataClass::Building) { @@ -122,7 +134,7 @@ void Core::OnPresent() for (int i = 0; i < gaiaPlayer->pObjectManager->Count; i++) { Unit* unit = gaiaPlayer->pObjectManager->units[i]; - if (!unit) + if (!unit || unit->pUnitData->Class == -1) { continue; } @@ -145,7 +157,7 @@ void Core::OnPresent() for (int j = 0; j < player->pObjectManager->Count; j++) { Unit* unit = player->pObjectManager->units[j]; - if (!unit) + if (!unit || unit->pUnitData->Class == -1) { continue; } diff --git a/CustomLoadingScreen.cpp b/CustomLoadingScreen.cpp index a3c0c44..2d1852e 100644 --- a/CustomLoadingScreen.cpp +++ b/CustomLoadingScreen.cpp @@ -10,15 +10,12 @@ CustomLoadingScreen::CustomLoadingScreen(char* imagePath) void CustomLoadingScreen::OnInitialise() { - //char* newLoadScreen = "C:\\Users\\Fahersto\\Pictures\\wallpaper.jpg"; - //char* newLoadScreen = "C:\\Users\\Fahersto\\Pictures\\wallpaper.jpg"; - //original string "/resources/loading_slash.png" - Patcher().Patch((BYTE*)GetModuleHandle(NULL) + 0x2088328,(int64_t)this->imagePath); + Patcher().Patch((BYTE*)GetModuleHandle(NULL) + 0x1dff178,(int64_t)this->imagePath); //change LEA to MOV by changing 0x8d to 0x8b - //E8 ? ? ? ? 4C 89 A5 ? ? ? ? 48 8D 15 ? ? ? ? 48 + 0xC (location where string is loaded) - Patcher().Patch((BYTE*)GetModuleHandle(NULL) + 0xD10DDA + 1, (int8_t)0x8b); + //E8 ? ? ? ? 90 48 8D 8D ? ? ? ? E8 ? ? ? ? 45 33 + 0x1c (location where string is loaded) + Patcher().Patch((BYTE*)GetModuleHandle(NULL) + 0xe966a6 + 1, (int8_t)0x8b); } void CustomLoadingScreen::OnMenuMainWindow() @@ -120,6 +120,16 @@ void ESP::OnUnitIteration(Unit* unit, Player* player, int playerIndex) if (siegeImpactLocation) { + if (std::string(unit->pUnitData->name).find("Projectile Scorpion") != std::string::npos) + { + Vector3* destination = unit->GetTargetPosition(); + if (destination) + { + Vector2 screenDestinationPos = Engine::Get()->worldToScreen(*destination); + Renderer::Get()->RenderCircleFilled(ImVec2(screenDestinationPos.x, screenDestinationPos.y), 10, colors_hex[*player->pColor] & 0x77ffffff); + } + } + if (std::string(unit->pUnitData->name).find("Projectile Mangonel") != std::string::npos) { Vector3* destination = unit->GetTargetPosition(); @@ -12,7 +12,7 @@ class ESP : public Feature bool siegeImpactLocation = true; bool playerUnitEsp[8] = { true,true,true,true,true,true,true,true }; - bool playerUnitDestinationEsp[8] = { true,true,true,true,true,true,true,true }; + bool playerUnitDestinationEsp[8] = { false,false,false,false,false,false,false,false }; bool playerUnitNameEsp[8] = { false,false,false,false,false,false,false,false }; //bool playerBuildingEsp[8] = { false,true,true,true,true,true,true,true }; diff --git a/MidfunctionHook.cpp b/MidfunctionHook.cpp index 4b5daea..9f20691 100644 --- a/MidfunctionHook.cpp +++ b/MidfunctionHook.cpp @@ -4,6 +4,15 @@ // +//Overwrites the VALUE of a register. To be used inside a proxy function. +//This function is required because changes like: registers->rdi = 0xdeadbeef will get restored by the trampoline (pop rdi) +//To change the value pointed to by a register just dereference it instead: *(int64*)registers->rdi = 0x4711 (usage of this function not required) +void MidfunctionHook::OverwriteRegister(int64_t rsp, Register reg, int64_t value) +{ + *((int64_t*)rsp + (int)reg) = value; +} + +// //Hooks a function anywhere by placing jumping to a trampoline. The trampoline saves all registers and then calls the proxy function //0xff, 0x25, 0x0, 0x0, 0x0, 0x0 JMP[rip + 0] //0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 absolute address of jump @@ -11,13 +20,13 @@ //Important: the overwritten bytes are NOT relocated meaning only position independet instructions can be overwritten // //TODO: -//When hooking within prologe or epicloge of a function the stack by not be aligned +//When hooking within prologe or epicloge of a function the stack may not be aligned //use BTR RSP, 3 to align stack and save RSP to then later restore it void MidfunctionHook::Hook(BYTE* sourceAddress, BYTE* targetAddress, const int hookLength) { - const int stubLength = 375; + const int stubLength = 380; const int stubJumpBackLength = 14; - const int proxyFunctionAddressIndex = 185; + const int proxyFunctionAddressIndex = 186; //14 bytes are required to place JMP[rip+0x] 0x1122334455667788 assert(hookLength >= stubJumpBackLength); @@ -76,11 +85,13 @@ void MidfunctionHook::Hook(BYTE* sourceAddress, BYTE* targetAddress, const int h 0x52, //push rdx 0x51, //push rcx 0x50, //push rax + 0x54, //push rsp 0x48, 0x89, 0xE1, //mov rcx,rsp - 0x48, 0x83, 0xEC, 0x20, //sub rsp,0x20 (allocate shadow space) + 0x48, 0x83, 0xEC, 0x28, //sub rsp,0x20 (allocate shadow space) 0x48, 0xB8, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, //movabs rax,0x1122334455667788 (use register to have an absolute 8 byte call) 0xFF, 0xD0, //call rax (call proxy function) - 0x48, 0x83, 0xC4, 0x20, //add rsp,0x20 (deallocate shadow space) + 0x48, 0x83, 0xC4, 0x28, //add rsp,0x20 (deallocate shadow space) + 0x48, 0x83, 0xC4, 0x08, //add rsp, 0x8 0x58, //pop rax 0x59, //pop rcx 0x5A, //pop rdx diff --git a/MidfunctionHook.h b/MidfunctionHook.h index 76ce1ee..d5e98f3 100644 --- a/MidfunctionHook.h +++ b/MidfunctionHook.h @@ -5,9 +5,28 @@ #include <iostream> #include <xmmintrin.h> +enum class Register +{ + RAX, + RCX, + RDX, + RBX, + RBP, + RSI, + RDI, + R8, + R9, + R10, + R11, + R12, + R13, + R14, + R15 +}; -struct registers +struct Registers { + int64_t rsp; int64_t rax; int64_t rcx; int64_t rdx; @@ -43,7 +62,8 @@ struct registers void print() { - printf("rax = %llx\nrcx = %llx\nrdx = %llx\nrbx = %llx\nrbp = %llx\nrsi = %llx\nrdi = %llx\nr8 = %llx\nr9 = %llx\nr10 = %llx\nr11 = %llx\nr12 = %llx\nr13 = %llx\nr14 = %llx\nr15 = %llx\n", + printf("rsp = %llx\nrax = %llx\nrcx = %llx\nrdx = %llx\nrbx = %llx\nrbp = %llx\nrsi = %llx\nrdi = %llx\nr8 = %llx\nr9 = %llx\nr10 = %llx\nr11 = %llx\nr12 = %llx\nr13 = %llx\nr14 = %llx\nr15 = %llx\n", + rsp, rax, rcx, rdx, @@ -78,6 +98,7 @@ class MidfunctionHook int hookLength; public: + static void OverwriteRegister(int64_t rsp, Register reg, int64_t value); void Hook(BYTE* sourceAddress, BYTE* targetAddress, const int length); void Unhook(); }; diff --git a/MinimapText.cpp b/MinimapText.cpp index a596d04..5131d52 100644 --- a/MinimapText.cpp +++ b/MinimapText.cpp @@ -26,7 +26,7 @@ bool displayStone = false; bool displayPopulation = false; -void __fastcall minimapProxy(registers* registers) +void __fastcall minimapProxy(Registers* registers) { if (!*hookEnabled) { @@ -48,7 +48,7 @@ void __fastcall minimapProxy(registers* registers) return; } - std::string woodString = std::to_string((int)player->pResources->wood); + std::string woodString = std::to_string((player->pResources->wood)); std::string foodString = std::to_string((int)player->pResources->food); std::string goldString = std::to_string((int)player->pResources->gold); std::string stoneString = std::to_string((int)player->pResources->stone); @@ -75,7 +75,7 @@ void __fastcall minimapProxy(registers* registers) { newName += " Pop: " + populationString; } - strcpy((char*)registers->rdi, newName.c_str()); + MidfunctionHook::OverwriteRegister(registers->rsp, Register::RDI, (int64_t)newName.c_str()); } void MinimapText::OnInitialise() @@ -88,13 +88,13 @@ void MinimapText::OnInitialise() //74 7F 48 8D 4B 01 48 85 C9 74 59 + 14 //Patch usage of short string optimizaation (playernames <= 15) - patcher.NOPBytes((BYTE*)(base + 0xA426EE), 6); + //patcher.NOPBytes((BYTE*)(base + 0xA426EE), 6); //74 7F 48 8D 4B 01 48 85 C9 74 59 + 18 //Increase space allocated for playernames to 0x120 bytes so we can write as much as we want to on screen - Patcher().Patch((BYTE*)(base + 0xA426F5), (int32_t)0x120); + //Patcher().Patch((BYTE*)(base + 0xA426F5), (int32_t)0x120); - minimapHook.Hook((BYTE*)(int64_t)GetModuleHandle(NULL) + Offsets::minimapHookOffset, (BYTE*)minimapProxy, 17); + minimapHook.Hook((BYTE*)(int64_t)GetModuleHandle(NULL) + Offsets::minimapHookOffset, (BYTE*)minimapProxy, 14); } void MinimapText::OnShutdown() diff --git a/Offsets.cpp b/Offsets.cpp index be54037..b9288b0 100644 --- a/Offsets.cpp +++ b/Offsets.cpp @@ -2,27 +2,27 @@ namespace Offsets { - //48 8D 0D ? ? ? ? 41 B8 ? ? ? ? E8 ? ? ? ? 33 C0 - //48 8D 0D ? ? ? ? E8 ? ? ? ? 0F B6 C0 - int64_t pathfindingSystem = 0x2A070F0; //PathingSystem, World and map correct + //48 8D 0D ? ? ? ? 41 B8 ? ? ? ? E8 ? ? ? ? 33 C0 //1 + //48 8D 0D ? ? ? ? E8 ? ? ? ? 0F B6 C0 //1 + int64_t pathfindingSystem = 0x2921690; //correct - //48 8B 0D ? ? ? ? E8 ? ? ? ? C6 85 - //48 83 3D ? ? ? ? ? 0F 84 ? ? ? ? 45 0F - int64_t mainScreen = 0x29C50F8; //MainScreenCorrect, MainView COrrect + //48 8B 0D ? ? ? ? E8 ? ? ? ? C6 85 //1 + int64_t mainScreen = 0x290f160; // - //44 89 25 ? ? ? ? 2B - //41 8B 45 28 99 - int64_t totalPlayers = 0x28900D4; //correct + //44 89 25 ? ? ? ? 2B //1 + //41 8B 45 28 99 + c //1 + int64_t totalPlayers = 0x2793064; // - //48 8B 0D ? ? ? ? 48 85 C9 74 0C 45 - int64_t tribePanelInven = 0x29c5110; + //48 8B 0D ? ? ? ? 48 85 C9 0F 84 ? ? ? ? 40 + int64_t tribePanelInven = 0x2910550; //48 8B 83 ? ? ? ? 48 8B 48 70 F3 0F 10 int64_t tribePanelInven_localPlayer = 0x208; - //Pattern - int64_t unit_actionlist = 0x278; //48 8B 8B ? ? ? ? E8 ? ? ? ? 48 85 FF + //ESP + //48 8B 8B ? ? ? ? E8 ? ? ? ? 48 85 FF + int64_t unit_actionlist = 0x278; - //88 85 ? ? ? ? 8B 84 - int64_t minimapHookOffset = 0xA429F7; + //MinimapText + int64_t minimapHookOffset = 0xBE6F99; }
\ No newline at end of file diff --git a/RelicManager.cpp b/RelicManager.cpp index 1075c0e..0f8b881 100644 --- a/RelicManager.cpp +++ b/RelicManager.cpp @@ -9,7 +9,7 @@ void RelicManager::OnNeutralUnit(Unit* unit) void RelicManager::OnMenuMainWindow() { - if (true) //Need OnGameStart() + if (true) //TODO Need OnGameStart() { relics.clear(); Player* gaia = Engine::Get()->GetPlayerByName("Gaia"); @@ -62,4 +62,19 @@ public: return Scan(pattern, mask, 0x0, (uintptr_t)kernelMemory); } + static void CopyToClipboard(uint64_t addy) + { + char szBuffer[2048]; + sprintf(szBuffer, "0x%llx", addy); + const char* output = szBuffer; + const size_t len = strlen(output) + 1; + HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len); + memcpy(GlobalLock(hMem), output, len); + GlobalUnlock(hMem); + OpenClipboard(0); + EmptyClipboard(); + SetClipboardData(CF_TEXT, hMem); + CloseClipboard(); + } + };
\ No newline at end of file |