aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBDKPlayer <fabian.stotz@yahoo.de>2020-03-27 22:09:57 +0100
committerBDKPlayer <fabian.stotz@yahoo.de>2020-03-27 22:09:57 +0100
commit78ddf8f82467c64d8653cea199e1f435afe41b76 (patch)
tree39d6eb7d140d19efa572e63fdd1006f047a2e3ad
parente95f90c028b40f39a41f18533f7cc921f4f37dd3 (diff)
Added: Custom Loading Screen
Fixed: Minimaphook now works in release/debug
-rw-r--r--AoE_imgui_DE.vcxproj19
-rw-r--r--AoE_imgui_DE.vcxproj.filters24
-rw-r--r--Classes.h10
-rw-r--r--Core.cpp25
-rw-r--r--CustomLoadingScreen.cpp32
-rw-r--r--CustomLoadingScreen.h20
-rw-r--r--ESP.cpp19
-rw-r--r--Engine.cpp4
-rw-r--r--MidfunctionHook.cpp210
-rw-r--r--MidfunctionHook.h84
-rw-r--r--MinimapText.cpp121
-rw-r--r--Offsets.cpp28
-rw-r--r--Offsets.h27
-rw-r--r--Patcher.cpp112
-rw-r--r--Patcher.h20
-rw-r--r--RelicManager.cpp4
-rw-r--r--ResourceInformation.cpp1
-rw-r--r--Resources.h43
-rw-r--r--SDK.h3
19 files changed, 672 insertions, 134 deletions
diff --git a/AoE_imgui_DE.vcxproj b/AoE_imgui_DE.vcxproj
index bc4b41c..81ce97e 100644
--- a/AoE_imgui_DE.vcxproj
+++ b/AoE_imgui_DE.vcxproj
@@ -30,6 +30,7 @@
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
+ <InterproceduralOptimization>false</InterproceduralOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -37,12 +38,14 @@
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
+ <InterproceduralOptimization>false</InterproceduralOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
+ <InterproceduralOptimization>false</InterproceduralOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -50,6 +53,7 @@
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
+ <InterproceduralOptimization>false</InterproceduralOptimization>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -86,7 +90,7 @@
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
- <Optimization>Disabled</Optimization>
+ <Optimization>MinSpace</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;AoE_imgui_DE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
@@ -101,6 +105,7 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;AoE_imgui_DE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -112,7 +117,7 @@
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
- <Optimization>MaxSpeed</Optimization>
+ <Optimization>MinSpace</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;AoE_imgui_DE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -129,7 +134,7 @@
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
- <Optimization>MaxSpeed</Optimization>
+ <Optimization>MinSpace</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;AoE_imgui_DE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -144,6 +149,7 @@
<ItemGroup>
<ClInclude Include="Classes.h" />
<ClInclude Include="Core.h" />
+ <ClInclude Include="CustomLoadingScreen.h" />
<ClInclude Include="DetourHook64.h" />
<ClInclude Include="detours.h" />
<ClInclude Include="Engine.h" />
@@ -159,17 +165,19 @@
<ClInclude Include="imgui\imstb_textedit.h" />
<ClInclude Include="imgui\imstb_truetype.h" />
<ClInclude Include="main.h" />
+ <ClInclude Include="MidfunctionHook.h" />
<ClInclude Include="MinimapText.h" />
<ClInclude Include="Offsets.h" />
+ <ClInclude Include="Patcher.h" />
<ClInclude Include="RelicManager.h" />
<ClInclude Include="Renderer.h" />
<ClInclude Include="ResourceInformation.h" />
- <ClInclude Include="Resources.h" />
<ClInclude Include="SDK.h" />
<ClInclude Include="Utility.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Core.cpp" />
+ <ClCompile Include="CustomLoadingScreen.cpp" />
<ClCompile Include="DetourHook64.cpp" />
<ClCompile Include="Engine.cpp" />
<ClCompile Include="ESP.cpp" />
@@ -181,7 +189,10 @@
<ClCompile Include="imgui\imgui_impl_dx11.cpp" />
<ClCompile Include="imgui\imgui_impl_win32.cpp" />
<ClCompile Include="imgui\imgui_widgets.cpp" />
+ <ClCompile Include="MidfunctionHook.cpp" />
<ClCompile Include="MinimapText.cpp" />
+ <ClCompile Include="Offsets.cpp" />
+ <ClCompile Include="Patcher.cpp" />
<ClCompile Include="RelicManager.cpp" />
<ClCompile Include="Renderer.cpp" />
<ClCompile Include="ResourceInformation.cpp" />
diff --git a/AoE_imgui_DE.vcxproj.filters b/AoE_imgui_DE.vcxproj.filters
index ec3121a..abb66d8 100644
--- a/AoE_imgui_DE.vcxproj.filters
+++ b/AoE_imgui_DE.vcxproj.filters
@@ -96,9 +96,6 @@
<ClInclude Include="Classes.h">
<Filter>Header Files\SDK</Filter>
</ClInclude>
- <ClInclude Include="Resources.h">
- <Filter>Header Files\SDK</Filter>
- </ClInclude>
<ClInclude Include="ESP.h">
<Filter>Header Files\Feature</Filter>
</ClInclude>
@@ -111,6 +108,15 @@
<ClInclude Include="RelicManager.h">
<Filter>Header Files\Feature</Filter>
</ClInclude>
+ <ClInclude Include="MidfunctionHook.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Patcher.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="CustomLoadingScreen.h">
+ <Filter>Header Files\Feature</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="imgui\imgui.cpp">
@@ -164,5 +170,17 @@
<ClCompile Include="RelicManager.cpp">
<Filter>Source Files\Feature</Filter>
</ClCompile>
+ <ClCompile Include="MidfunctionHook.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Offsets.cpp">
+ <Filter>Source Files\SDK</Filter>
+ </ClCompile>
+ <ClCompile Include="Patcher.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="CustomLoadingScreen.cpp">
+ <Filter>Source Files\Feature</Filter>
+ </ClCompile>
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/Classes.h b/Classes.h
index ba01391..fee51b8 100644
--- a/Classes.h
+++ b/Classes.h
@@ -155,8 +155,14 @@ public:
float stone; //0x0008
float gold; //0x000C
float popSpaceLeft; //0x0010
-
-}; //Size=0x00C8
+ char pad_0x0014[0x4]; //0x0014
+ float age; //0x0018
+ char pad_0x001C[0x10]; //0x001C
+ float currentPop; //0x002C
+ char pad_0x0030[0x64]; //0x0030
+ float villagerCount; //0x0094
+
+}; //Size=0x0098
class Player
{
diff --git a/Core.cpp b/Core.cpp
index 394d15a..69e4571 100644
--- a/Core.cpp
+++ b/Core.cpp
@@ -17,14 +17,18 @@
#include "ESP.h"
#include "MinimapText.h"
#include "RelicManager.h"
+#include "CustomLoadingScreen.h"
Core::Core()
{
+ FeatureManager* featureManager = FeatureManager::Get();
//Register Features here
- FeatureManager::Get()->registerFeature(new ResourceInformation());
- FeatureManager::Get()->registerFeature(new ESP());
- //FeatureManager::Get()->registerFeature(new MinimapText());
- FeatureManager::Get()->registerFeature(new RelicManager());
+ featureManager->registerFeature(new ResourceInformation());
+ featureManager->registerFeature(new ESP());
+ featureManager->registerFeature(new MinimapText());
+ featureManager->registerFeature(new RelicManager());
+ featureManager->registerFeature(new CustomLoadingScreen("C:\\wallpaper.jpg"));
+
FeatureManager::Get()->OnInitialise();
}
@@ -37,11 +41,6 @@ void createPlayerTreeNode(Player* player, int playerIndex)
{
ImGui::PushStyleColor(ImGuiCol_Text, 0xffffffff);
ImGui::Text("Player %p (%f, %f)", player, player->xScreenPos, player->yScreenPos);
- if (ImGui::Button("Set camera to 0"))
- {
- player->xScreenPos = 0;
- player->yScreenPos = 0;
- }
FeatureManager::Get()->OnMenuPlayerTreenode(player, playerIndex);
if (ImGui::TreeNode("Units"))
{
@@ -89,26 +88,26 @@ void Core::OnPresent()
{
__try
{
- printf("Valid: ");
+ //printf("Valid: ");
MainScreen* mainScreen = Engine::Get()->GetMainScreen();
if (!mainScreen)
{
return;
}
- printf("mainScreen %p", mainScreen);
+ //printf("mainScreen %p", mainScreen);
World* world = Engine::Get()->GetWorld();
if (!world)
{
return;
}
- printf(" world %p", world);
+ //printf(" world %p", world);
PlayerArray* playerArray = world->pPlayerArray;
if (!playerArray)
{
return;
}
- printf(" playerArray %p", playerArray);
+ //printf(" playerArray %p", playerArray);
int totalPlayers = Engine::Get()->GetTotalPlayers();
static bool openOverlay = true;
diff --git a/CustomLoadingScreen.cpp b/CustomLoadingScreen.cpp
new file mode 100644
index 0000000..a3c0c44
--- /dev/null
+++ b/CustomLoadingScreen.cpp
@@ -0,0 +1,32 @@
+#include "CustomLoadingScreen.h"
+
+#include "Patcher.h"
+
+
+CustomLoadingScreen::CustomLoadingScreen(char* imagePath)
+{
+ this->imagePath = 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);
+
+ //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);
+}
+
+void CustomLoadingScreen::OnMenuMainWindow()
+{
+
+}
+
+void CustomLoadingScreen::OnShutdown()
+{
+ //Restart the game
+} \ No newline at end of file
diff --git a/CustomLoadingScreen.h b/CustomLoadingScreen.h
new file mode 100644
index 0000000..66737b0
--- /dev/null
+++ b/CustomLoadingScreen.h
@@ -0,0 +1,20 @@
+#pragma once
+#pragma once
+#include "Feature.h"
+
+class CustomLoadingScreen : public Feature
+{
+private:
+ CustomLoadingScreen();
+
+ char* imagePath;
+
+public:
+ //Supports .gif, .bmp, .jpg, .png
+ CustomLoadingScreen(char* imagePath);
+
+ //Callbacks
+ void OnInitialise();
+ void OnMenuMainWindow();
+ void OnShutdown();
+}; \ No newline at end of file
diff --git a/ESP.cpp b/ESP.cpp
index f669fef..fe94f0c 100644
--- a/ESP.cpp
+++ b/ESP.cpp
@@ -146,6 +146,12 @@ void ESP::OnUnitIteration(Unit* unit, Player* player, int playerIndex)
return;
}
+ if (strcmp(unit->pUnitData->name, "CSTL") == 0)
+ {
+ DrawBox(unit, colors_hex[*player->pColor], true);
+ return;
+ }
+
DrawBox(unit, colors_hex[*player->pColor], playerUnitNameEsp[playerIndex]);
if (trebuchetESP && (std::string(unit->pUnitData->name).find("TREBU") != std::string::npos || std::string(unit->pUnitData->name).find("PTREB") != std::string::npos))
@@ -259,12 +265,15 @@ void ESP::OnNeutralUnit(Unit* unit)
void ESP::OnMenuMainWindow()
{
ImGui::Separator();
- ImGui::Checkbox("Siege Impact ESP", &siegeImpactLocation);
- ImGui::Checkbox("Trebuchet range ESP", &trebuchetESP);
+ ImGui::Text("Siege ESP");
+ ImGui::Checkbox("Siege Impact", &siegeImpactLocation);
+ ImGui::Checkbox("Trebuchet range", &trebuchetESP);
ImGui::Separator();
ImGui::Text("Resource ESP");
- ImGui::Checkbox("GaiaESP", &gaiaEsp);
- ImGui::Checkbox("GoldESP", &goldESP);
- ImGui::Checkbox("StoneESP", &stoneESP);
+ ImGui::Checkbox("Gaia##ESP", &gaiaEsp);
+ ImGui::SameLine();
+ ImGui::Checkbox("Gold##ESP", &goldESP);
+ ImGui::SameLine();
+ ImGui::Checkbox("Stone##ESP", &stoneESP);
ImGui::Separator();
} \ No newline at end of file
diff --git a/Engine.cpp b/Engine.cpp
index b5b9f5c..ee9d2b4 100644
--- a/Engine.cpp
+++ b/Engine.cpp
@@ -25,7 +25,7 @@ Engine* Engine::Get()
World* Engine::GetWorld()
{
PathfindingSystem* pathfindingSystem = reinterpret_cast<PathfindingSystem*>(base + Offsets::pathfindingSystem);
- printf("pathfindingSystem: %p\n", pathfindingSystem);
+ //printf("pathfindingSystem: %p\n", pathfindingSystem);
if (!pathfindingSystem)
{
return NULL;
@@ -147,7 +147,7 @@ Player* Engine::GetPlayerByName(char* playerName)
int totalPlayers = GetTotalPlayers();
- for (int i = 0; i < totalPlayers; i++)
+ for (int i = 0; i <= totalPlayers; i++)
{
Player* player = playerArray->playerData[i].player;
if (!player)
diff --git a/MidfunctionHook.cpp b/MidfunctionHook.cpp
new file mode 100644
index 0000000..4b5daea
--- /dev/null
+++ b/MidfunctionHook.cpp
@@ -0,0 +1,210 @@
+#include "MidfunctionHook.h"
+
+#include <cassert>
+
+
+//
+//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
+//The proxy functions signature is expected to be: void __fastcall proxyFunction(registers* registers)
+//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
+//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 stubJumpBackLength = 14;
+ const int proxyFunctionAddressIndex = 185;
+
+ //14 bytes are required to place JMP[rip+0x] 0x1122334455667788
+ assert(hookLength >= stubJumpBackLength);
+
+ //1. save xmm registers
+ //2. save general purpose registers
+ //3. call proxy function
+ //4. restore all registers
+ //5. jump back to orignal function
+ BYTE stub[stubLength] = {
+ 0x9C, //pushfq
+ 0x48, 0x83, 0xEC, 0x10, //sub rsp,0x10
+ 0xF3, 0x44, 0x0F, 0x7F, 0x3C, 0x24, //movdqu XMMWORD PTR [rsp],xmm15
+ 0x48, 0x83, 0xEC, 0x10, //sub rsp,0x10
+ 0xF3, 0x44, 0x0F, 0x7F, 0x34, 0x24, //movdqu XMMWORD PTR [rsp],xmm14
+ 0x48, 0x83, 0xEC, 0x10, //sub rsp,0x10
+ 0xF3, 0x44, 0x0F, 0x7F, 0x2C, 0x24, //movdqu XMMWORD PTR [rsp],xmm13
+ 0x48, 0x83, 0xEC, 0x10, //sub rsp,0x10
+ 0xF3, 0x44, 0x0F, 0x7F, 0x24, 0x24, //movdqu XMMWORD PTR [rsp],xmm12
+ 0x48, 0x83, 0xEC, 0x10, //sub rsp,0x10
+ 0xF3, 0x44, 0x0F, 0x7F, 0x1C, 0x24, //movdqu XMMWORD PTR [rsp],xmm11
+ 0x48, 0x83, 0xEC, 0x10, //sub rsp,0x10
+ 0xF3, 0x44, 0x0F, 0x7F, 0x14, 0x24, //movdqu XMMWORD PTR [rsp],xmm10
+ 0x48, 0x83, 0xEC, 0x10, //sub rsp,0x10
+ 0xF3, 0x44, 0x0F, 0x7F, 0x0C, 0x24, //movdqu XMMWORD PTR [rsp],xmm9
+ 0x48, 0x83, 0xEC, 0x10, //sub rsp,0x10
+ 0xF3, 0x44, 0x0F, 0x7F, 0x04, 0x24, //movdqu XMMWORD PTR [rsp],xmm8
+ 0x48, 0x83, 0xEC, 0x10, //sub rsp,0x10
+ 0xF3, 0x0F, 0x7F, 0x3C, 0x24, //movdqu XMMWORD PTR [rsp],xmm7
+ 0x48, 0x83, 0xEC, 0x10, //sub rsp,0x10
+ 0xF3, 0x0F, 0x7F, 0x34, 0x24, //movdqu XMMWORD PTR [rsp],xmm6
+ 0x48, 0x83, 0xEC, 0x10, //sub rsp,0x10
+ 0xF3, 0x0F, 0x7F, 0x2C, 0x24, //movdqu XMMWORD PTR [rsp],xmm5
+ 0x48, 0x83, 0xEC, 0x10, //sub rsp,0x10
+ 0xF3, 0x0F, 0x7F, 0x24, 0x24, //movdqu XMMWORD PTR [rsp],xmm4
+ 0x48, 0x83, 0xEC, 0x10, //sub rsp,0x10
+ 0xF3, 0x0F, 0x7F, 0x1C, 0x24, //movdqu XMMWORD PTR [rsp],xmm3
+ 0x48, 0x83, 0xEC, 0x10, //sub rsp,0x10
+ 0xF3, 0x0F, 0x7F, 0x14, 0x24, //movdqu XMMWORD PTR [rsp],xmm2
+ 0x48, 0x83, 0xEC, 0x10, //sub rsp,0x10
+ 0xF3, 0x0F, 0x7F, 0x0C, 0x24, //movdqu XMMWORD PTR [rsp],xmm1
+ 0x48, 0x83, 0xEC, 0x10, //sub rsp,0x10
+ 0xF3, 0x0F, 0x7F, 0x04, 0x24, //movdqu XMMWORD PTR [rsp],xmm0
+ 0x41, 0x57, //push r15
+ 0x41, 0x56, //push r14
+ 0x41, 0x55, //push r13
+ 0x41, 0x54, //push r12
+ 0x41, 0x53, //push r11
+ 0x41, 0x52, //push r10
+ 0x41, 0x51, //push r9
+ 0x41, 0x50, //push r8
+ 0x57, //push rdi
+ 0x56, //push rsi
+ 0x55, //push rbp
+ 0x53, //push rbx
+ 0x52, //push rdx
+ 0x51, //push rcx
+ 0x50, //push rax
+ 0x48, 0x89, 0xE1, //mov rcx,rsp
+ 0x48, 0x83, 0xEC, 0x20, //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)
+ 0x58, //pop rax
+ 0x59, //pop rcx
+ 0x5A, //pop rdx
+ 0x5B, //pop rbx
+ 0x5D, //pop rbp
+ 0x5E, //pop rsi
+ 0x5F, //pop rdi
+ 0x41, 0x58, //pop r8
+ 0x41, 0x59, //pop r9
+ 0x41, 0x5A, //pop r10
+ 0x41, 0x5B, //pop r11
+ 0x41, 0x5C, //pop r12
+ 0x41, 0x5D, //pop r13
+ 0x41, 0x5E, //pop r14
+ 0x41, 0x5F, //pop r15
+ 0xF3, 0x0F, 0x6F, 0x04, 0x24, //movdqu xmm0,XMMWORD PTR[rsp]
+ 0x48, 0x83, 0xC4, 0x10, //add rsp,0x10
+ 0xF3, 0x0F, 0x6F, 0x0C, 0x24, //movdqu xmm1,XMMWORD PTR[rsp]
+ 0x48, 0x83, 0xC4, 0x10, //add rsp,0x10
+ 0xF3, 0x0F, 0x6F, 0x14, 0x24, //movdqu xmm2,XMMWORD PTR[rsp]
+ 0x48, 0x83, 0xC4, 0x10, //add rsp,0x10
+ 0xF3, 0x0F, 0x6F, 0x1C, 0x24, //movdqu xmm3,XMMWORD PTR[rsp]
+ 0x48, 0x83, 0xC4, 0x10, //add rsp,0x10
+ 0xF3, 0x0F, 0x6F, 0x24, 0x24, //movdqu xmm4,XMMWORD PTR[rsp]
+ 0x48, 0x83, 0xC4, 0x10, //add rsp,0x10
+ 0xF3, 0x0F, 0x6F, 0x2C, 0x24, //movdqu xmm5,XMMWORD PTR[rsp]
+ 0x48, 0x83, 0xC4, 0x10, //add rsp,0x10
+ 0xF3, 0x0F, 0x6F, 0x34, 0x24, //movdqu xmm6,XMMWORD PTR[rsp]
+ 0x48, 0x83, 0xC4, 0x10, //add rsp,0x10
+ 0xF3, 0x0F, 0x6F, 0x3C, 0x24, //movdqu xmm7,XMMWORD PTR[rsp]
+ 0x48, 0x83, 0xC4, 0x10, //add rsp,0x10
+ 0xF3, 0x44, 0x0F, 0x6F, 0x04, 0x24, //movdqu xmm8,XMMWORD PTR[rsp]
+ 0x48, 0x83, 0xC4, 0x10, //add rsp,0x10
+ 0xF3, 0x44, 0x0F, 0x6F, 0x0C, 0x24, //movdqu xmm9,XMMWORD PTR[rsp]
+ 0x48, 0x83, 0xC4, 0x10, //add rsp,0x10
+ 0xF3, 0x44, 0x0F, 0x6F, 0x14, 0x24, //movdqu xmm10,XMMWORD PTR[rsp]
+ 0x48, 0x83, 0xC4, 0x10, //add rsp,0x10
+ 0xF3, 0x44, 0x0F, 0x6F, 0x1C, 0x24, //movdqu xmm11,XMMWORD PTR[rsp]
+ 0x48, 0x83, 0xC4, 0x10, //add rsp,0x10
+ 0xF3, 0x44, 0x0F, 0x6F, 0x24, 0x24, //movdqu xmm12,XMMWORD PTR[rsp]
+ 0x48, 0x83, 0xC4, 0x10, //add rsp,0x10
+ 0xF3, 0x44, 0x0F, 0x6F, 0x2C, 0x24, //movdqu xmm13,XMMWORD PTR[rsp]
+ 0x48, 0x83, 0xC4, 0x10, //add rsp,0x10
+ 0xF3, 0x44, 0x0F, 0x6F, 0x34, 0x24, //movdqu xmm14,XMMWORD PTR[rsp]
+ 0x48, 0x83, 0xC4, 0x10, //add rsp,0x10
+ 0xF3, 0x44, 0x0F, 0x6F, 0x3C, 0x24, //movdqu xmm15,XMMWORD PTR[rsp]
+ 0x48, 0x83, 0xC4, 0x10, //add rsp,0x10
+ 0x9D //popfq
+ };
+
+
+
+ BYTE stubJumpBack[stubJumpBackLength] = {
+ 0xff, 0x25, 0x0, 0x0, 0x0,0x0, //JMP[rip + 0]
+ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 //absolute address of jump
+ };
+
+ //remember for unhooking
+ this->hookLength = hookLength;
+ this->sourceAddress = sourceAddress;
+
+ //save original bytes
+ originalBytes = new BYTE[hookLength];
+ memcpy(originalBytes, sourceAddress, hookLength);
+
+ //allocate space for stub + space for overwritten bytes + jumpback
+ trampoline = (BYTE*)VirtualAlloc(NULL, stubLength + hookLength + stubJumpBackLength, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+
+ //copy stub to trampoline
+ memcpy(trampoline, stub, stubLength);
+
+ //copy original bytes to trampoline
+ memcpy(&trampoline[stubLength], originalBytes, hookLength);
+
+ //copy jump back to original code
+ memcpy(&trampoline[stubLength + hookLength], stubJumpBack, hookLength);
+
+ //insert address of proxy function to call instruction
+ *(int64_t*)&trampoline[proxyFunctionAddressIndex] = (int64_t)targetAddress;
+
+ //write jump from trampoline to original code
+ *(int64_t*)&trampoline[stubLength + hookLength + 6] = (int64_t)&sourceAddress[hookLength];
+
+ //make trampoline executable
+ //DWORD pageProtection;
+ //VirtualProtect(trampoline, stubLength + hookLength + stubJumpBackLength, PAGE_EXECUTE_READWRITE, &pageProtection);
+
+ //make page of original code writeable
+ DWORD pageProtection;
+ VirtualProtect(sourceAddress, hookLength, PAGE_READWRITE, &pageProtection);
+
+ //write JMP from original code to trampoline
+ sourceAddress[0] = 0xFF; //opcodes = JMP [rip+0]
+ sourceAddress[1] = 0x25; //opcodes = JMP [rip+0]
+ *(uint32_t*)(&sourceAddress[2]) = 0; //relative distance from RIP (+0)
+ *(uint64_t*)(&sourceAddress[2 + 4]) = (uint64_t)(trampoline); //destination to jump to
+
+ //NOP left over bytes
+ for (int i = stubJumpBackLength; i < hookLength; i++)
+ {
+ sourceAddress[i] = 0x90;
+ }
+
+ //restore page protection of original code
+ VirtualProtect(sourceAddress, hookLength, pageProtection, &pageProtection);
+}
+
+//
+//Unhooks a previously hooked function by copying back the original bytes
+void MidfunctionHook::Unhook()
+{
+ //make page writeable
+ DWORD dwback;
+ VirtualProtect(sourceAddress, hookLength, PAGE_READWRITE, &dwback);
+
+ //copy back original bytes
+ memcpy(sourceAddress, originalBytes, hookLength);
+
+ //restore page protection
+ VirtualProtect(sourceAddress, hookLength, dwback, &dwback);
+
+ //clean up allocated memory
+ delete[] originalBytes;
+
+ //memory leak but enables unhooking inside hooked function and makes it threadsafe?
+ //delete[] trampoline;
+}
diff --git a/MidfunctionHook.h b/MidfunctionHook.h
new file mode 100644
index 0000000..76ce1ee
--- /dev/null
+++ b/MidfunctionHook.h
@@ -0,0 +1,84 @@
+#pragma once
+
+#include <Windows.h>
+#include <cstdint>
+#include <iostream>
+#include <xmmintrin.h>
+
+
+struct registers
+{
+ int64_t rax;
+ int64_t rcx;
+ int64_t rdx;
+ int64_t rbx;
+ int64_t rbp;
+ int64_t rsi;
+ int64_t rdi;
+ int64_t r8;
+ int64_t r9;
+ int64_t r10;
+ int64_t r11;
+ int64_t r12;
+ int64_t r13;
+ int64_t r14;
+ int64_t r15;
+
+ __m128 xmm0;
+ __m128 xmm1;
+ __m128 xmm2;
+ __m128 xmm3;
+ __m128 xmm4;
+ __m128 xmm5;
+ __m128 xmm6;
+ __m128 xmm7;
+ __m128 xmm8;
+ __m128 xmm9;
+ __m128 xmm10;
+ __m128 xmm11;
+ __m128 xmm12;
+ __m128 xmm13;
+ __m128 xmm14;
+ __m128 xmm15;
+
+ 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",
+ rax,
+ rcx,
+ rdx,
+ rbx,
+ rbp,
+ rsi,
+ rdi,
+ r8,
+ r9,
+ r10,
+ r11,
+ r12,
+ r13,
+ r14,
+ r15);
+ }
+};
+
+
+class MidfunctionHook
+{
+ //bytes overwritten by placing the detour
+ BYTE* originalBytes;
+
+ //location where hook is placed
+ BYTE* sourceAddress;
+
+ //runs overwritten instructions
+ BYTE* trampoline;
+
+ //number of bytes to overwrite (don't cut instructions in half)
+ int hookLength;
+
+public:
+ void Hook(BYTE* sourceAddress, BYTE* targetAddress, const int length);
+ void Unhook();
+};
+
diff --git a/MinimapText.cpp b/MinimapText.cpp
index 1d13635..a596d04 100644
--- a/MinimapText.cpp
+++ b/MinimapText.cpp
@@ -7,70 +7,113 @@
#include "Sdk.h"
#include "Renderer.h"
#include "Utility.h"
+#include "Offsets.h"
#include "DetourHook64.h"
+#include "MidfunctionHook.h"
+#include "Patcher.h"
#include <map>
#pragma warning( disable : 4244 )
+MidfunctionHook minimapHook;
+bool* hookEnabled;
+bool displayWood = false;
+bool displayFood = false;
+bool displayGold = true;
+bool displayStone = false;
+bool displayPopulation = false;
-char* name = "NewName";
-
-typedef int(__fastcall* printMinimap)(void* that, char* format, ...);
-printMinimap oPrintMinimap;
-
-int __fastcall hookedWrapper(void* that, char* format, char* playername, int currentPoints, int maxPoints)
+void __fastcall minimapProxy(registers* registers)
{
- printf("In da Hook\n");
-
- return oPrintMinimap(that, format, playername, currentPoints, maxPoints); //call original call
+ if (!*hookEnabled)
+ {
+ return;
+ }
+ if (!displayWood && !displayFood && !displayGold && !displayStone && !displayPopulation)
+ {
+ return;
+ }
+
+ Player* player = Engine::Get()->GetPlayerByName((char*)registers->rdi);
+ if (!player)
+ {
+ return;
+ }
+
+ if (!player->pResources)
+ {
+ return;
+ }
+
+ std::string woodString = std::to_string((int)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);
+ std::string populationString = std::to_string((int)player->pResources->currentPop) + "/" + std::to_string((int)player->pResources->currentPop + (int)player->pResources->popSpaceLeft);
+
+ std::string newName = std::string(player->name) + " -";
+ if (displayWood)
+ {
+ newName += " Wood: " + woodString;
+ }
+ if (displayFood)
+ {
+ newName += " Food: " + foodString;
+ }
+ if (displayGold)
+ {
+ newName += " Gold: " + goldString;
+ }
+ if (displayStone)
+ {
+ newName += " Stone: " + stoneString;
+ }
+ if (displayPopulation)
+ {
+ newName += " Pop: " + populationString;
+ }
+ strcpy((char*)registers->rdi, newName.c_str());
}
void MinimapText::OnInitialise()
{
- //Working
- //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*)Utility::Scan("\x8B\x84\xF5\x00\x00\x00\x00\x89", "xxx????x", (char*)0x7ff000000000, 0x800000000000 - 0x7ff000000000);
- //printf("hookAddress: %p\n", hookAddress);
- //minimapTextDetour = new DetourHook64();
- //minimapTextDetour->Hook(hookAddress, shellcode, shellcodeSize, (uint64_t)(hookAddress + 23), 19);
-
- BYTE* callAddress = (BYTE*)Utility::Scan("\xE8\x00\x00\x00\x00\x49\x8B\x9D\x00\x00\x00\x00\x33\xD2\x44", "x????xxx????xxx", (char*)0x7ff000000000, 0x800000000000 - 0x7ff000000000);
-
- BYTE* function = (BYTE*)Utility::Scan("\xFF\x15\x00\x00\x00\x00\x85\xC0\x0F\x48", "xx????xxxx", (char*)0x7ff000000000, 0x800000000000 - 0x7ff000000000);
-
- function = function - 0x4b;
- printf("callAddress: %p\n", callAddress);
- printf("function: %p\n", function);
- printf("hookedWrapper: %p\n", hookedWrapper);
-
+ hookEnabled = &enabled;
- oPrintMinimap = (printMinimap)(function);
+ int64_t base = (int64_t)GetModuleHandle(NULL);
- int32_t callRelativeOffset = (int64_t)hookedWrapper - (int64_t)callAddress - 5;
+ Patcher patcher;
+ //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);
- getchar();
- //*(int32_t*)(callAddress + 1) = callRelativeOffset; //override original call
+ //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);
- //TO CALL E8 ? ? ? ? 49 8B 9D ? ? ? ? 33 D2 44
+ minimapHook.Hook((BYTE*)(int64_t)GetModuleHandle(NULL) + Offsets::minimapHookOffset, (BYTE*)minimapProxy, 17);
}
void MinimapText::OnShutdown()
{
- //minimapTextDetour->Unhook();
+ minimapHook.Unhook();
}
void MinimapText::OnMenuMainWindow()
{
- //ImGui::Checkbox("Minimap Ressource Information", &hookEnabled);
+ ImGui::Separator();
+ ImGui::Checkbox("Minimap Ressource Information", &enabled);
+ ImGui::Checkbox("Wood##Minimap", &displayWood);
+ ImGui::SameLine();
+ ImGui::Checkbox("Food##Minimap", &displayFood);
+ ImGui::SameLine();
+ ImGui::Checkbox("Gold##Minimap", &displayGold);
+ ImGui::SameLine();
+ ImGui::Checkbox("Stone##Minimap", &displayStone);
+ ImGui::SameLine();
+ ImGui::Checkbox("Population##Minimap", &displayPopulation);
+ ImGui::Separator();
} \ No newline at end of file
diff --git a/Offsets.cpp b/Offsets.cpp
new file mode 100644
index 0000000..be54037
--- /dev/null
+++ b/Offsets.cpp
@@ -0,0 +1,28 @@
+#include "Offsets.h"
+
+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 8B 0D ? ? ? ? E8 ? ? ? ? C6 85
+ //48 83 3D ? ? ? ? ? 0F 84 ? ? ? ? 45 0F
+ int64_t mainScreen = 0x29C50F8; //MainScreenCorrect, MainView COrrect
+
+ //44 89 25 ? ? ? ? 2B
+ //41 8B 45 28 99
+ int64_t totalPlayers = 0x28900D4; //correct
+
+ //48 8B 0D ? ? ? ? 48 85 C9 74 0C 45
+ int64_t tribePanelInven = 0x29c5110;
+
+ //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
+
+ //88 85 ? ? ? ? 8B 84
+ int64_t minimapHookOffset = 0xA429F7;
+} \ No newline at end of file
diff --git a/Offsets.h b/Offsets.h
index 3a4885f..b6bee2d 100644
--- a/Offsets.h
+++ b/Offsets.h
@@ -3,25 +3,14 @@
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
+ extern int64_t pathfindingSystem;
+ extern int64_t mainScreen;
+ extern int64_t totalPlayers;
- //48 8B 0D ? ? ? ? E8 ? ? ? ? C6 85
- //48 83 3D ? ? ? ? ? 0F 84 ? ? ? ? 45 0F
- int64_t mainScreen = 0x29C50F8; //MainScreenCorrect, MainView COrrect
+ extern int64_t tribePanelInven;
+ extern int64_t tribePanelInven_localPlayer;
- //44 89 25 ? ? ? ? 2B
- //41 8B 45 28 99
- int64_t totalPlayers = 0x28900D4; //correct
-
- //48 8B 0D ? ? ? ? 48 85 C9 74 0C 45
- int64_t tribePanelInven = 0x29c5110;
-
- //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
+ extern int64_t unit_actionlist ;
+
+ extern int64_t minimapHookOffset;
} \ No newline at end of file
diff --git a/Patcher.cpp b/Patcher.cpp
new file mode 100644
index 0000000..cefeeb1
--- /dev/null
+++ b/Patcher.cpp
@@ -0,0 +1,112 @@
+#include "Patcher.h"
+
+void Patcher::PatchBytes(BYTE* address, BYTE* shellcode, const int shellCodeSize, bool modifyPageProtection, DWORD newPageProtection, bool restorePageProtection)
+{
+ DWORD oldProtection;
+ if (modifyPageProtection)
+ {
+ //apply new page protection
+ VirtualProtect(address, shellCodeSize, newPageProtection, &oldProtection);
+ }
+ else
+ {
+ //there is nothing to restore if page protection wasn't changed
+ restorePageProtection = false;
+ }
+
+ //apply patch
+ memcpy(address, shellcode, shellCodeSize);
+
+ if (restorePageProtection)
+ {
+ //restore page protection
+ VirtualProtect(address, shellCodeSize, oldProtection, &oldProtection);
+ }
+}
+
+void Patcher::NOPBytes(BYTE* address, const int amount, bool modifyPageProtection, DWORD newPageProtection, bool restorePageProtection)
+{
+ DWORD oldProtection;
+ if (modifyPageProtection)
+ {
+ //apply new page protection
+ VirtualProtect(address, amount, newPageProtection, &oldProtection);
+ }
+ else
+ {
+ //there is nothing to restore if page protection wasn't changed
+ restorePageProtection = false;
+ }
+
+ //apply patch
+ for (int i = 0; i < amount; i++)
+ {
+ address[i] = 0x90; //NOP
+ }
+
+ if (restorePageProtection)
+ {
+ //restore page protection
+ VirtualProtect(address, amount, oldProtection, &oldProtection);
+ }
+}
+
+//Writes a 1 byte value using local endianess
+void Patcher::Patch(BYTE* address, int8_t value)
+{
+ DWORD oldProtection;
+
+ //apply new page protection
+ VirtualProtect(address, sizeof(value), PAGE_EXECUTE_READWRITE, &oldProtection);
+
+ //write value
+ *(int8_t*)address = value;
+
+ //restore page protection
+ VirtualProtect(address, sizeof(value), oldProtection, &oldProtection);
+}
+
+//Writes a 2 byte value using local endianess
+void Patcher::Patch(BYTE* address, int16_t value)
+{
+ DWORD oldProtection;
+
+ //apply new page protection
+ VirtualProtect(address, sizeof(value), PAGE_EXECUTE_READWRITE, &oldProtection);
+
+ //write value
+ *(int16_t*)address = value;
+
+ //restore page protection
+ VirtualProtect(address, sizeof(value), oldProtection, &oldProtection);
+}
+
+//Writes a 4 byte value using local endianess
+void Patcher::Patch(BYTE* address, int32_t value)
+{
+ DWORD oldProtection;
+
+ //apply new page protection
+ VirtualProtect(address, sizeof(value), PAGE_EXECUTE_READWRITE, &oldProtection);
+
+ //write value
+ *(int32_t*)address = value;
+
+ //restore page protection
+ VirtualProtect(address, sizeof(value), oldProtection, &oldProtection);
+}
+
+//Writes a 8 byte value using local endianess
+void Patcher::Patch(BYTE* address, int64_t value)
+{
+ DWORD oldProtection;
+
+ //apply new page protection
+ VirtualProtect(address, sizeof(value), PAGE_EXECUTE_READWRITE, &oldProtection);
+
+ //write value
+ *(int64_t*)address = value;
+
+ //restore page protection
+ VirtualProtect(address, sizeof(value), oldProtection, &oldProtection);
+} \ No newline at end of file
diff --git a/Patcher.h b/Patcher.h
new file mode 100644
index 0000000..706c9ba
--- /dev/null
+++ b/Patcher.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <Windows.h>
+#include <cstdint>
+
+class Patcher
+{
+public:
+
+ void PatchBytes(BYTE* address, BYTE* shellcode, const int shellCodeSize, bool modifyPageProtection = true, DWORD newPageProtection = PAGE_EXECUTE_READWRITE, bool restorePageProtection = true);
+
+ void NOPBytes(BYTE* address, const int amount, bool modifyPageProtection = true, DWORD newPageProtection = PAGE_EXECUTE_READWRITE, bool restorePageProtection = true);
+
+
+ //TODO: template?
+ void Patch(BYTE* address, int8_t value);
+ void Patch(BYTE* address, int16_t value);
+ void Patch(BYTE* address, int32_t value);
+ void Patch(BYTE* address, int64_t value);
+};
diff --git a/RelicManager.cpp b/RelicManager.cpp
index 10f41d2..1075c0e 100644
--- a/RelicManager.cpp
+++ b/RelicManager.cpp
@@ -37,9 +37,9 @@ void RelicManager::OnMenuMainWindow()
currentRelic = (currentRelic - 1) % relics.size();
Engine::Get()->GetLocalPlayer()->SetCameraPosition(relics[currentRelic]->position);
}
- ImGui::SameLine(24);
+ ImGui::SameLine();
ImGui::Text("%d/%d", currentRelic + 1, relics.size());
- ImGui::SameLine(48);
+ ImGui::SameLine();
if (ImGui::Button(">"))
{
currentRelic = (currentRelic + 1) % relics.size();
diff --git a/ResourceInformation.cpp b/ResourceInformation.cpp
index 57ff2d0..dcaf470 100644
--- a/ResourceInformation.cpp
+++ b/ResourceInformation.cpp
@@ -8,6 +8,7 @@
void ResourceInformation::OnMenuPlayerTreenode(Player* player, int playerIndex)
{
+ ImGui::Text("Resources: %p", player->pResources);
ImGui::Text("Wood: %.f", player->pResources->wood);
ImGui::Text("Food: %.f", player->pResources->food);
ImGui::Text("Gold: %.f", player->pResources->gold);
diff --git a/Resources.h b/Resources.h
deleted file mode 100644
index 3acbc85..0000000
--- a/Resources.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#pragma once
-
-
-class Ressources
-{
-public:
- float food; //0x0000
- float wood; //0x0004
- float stone; //0x0008
- float gold; //0x000C
- float popSpaceLeft; //0x0010
- char pad_0014[4]; //0x0014
- float age; //0x0018
- char pad_001C[16]; //0x001C
- float CurrentPop; //0x002C
- char pad_0030[28]; //0x0030
- float unitProduced; //0x004C
- char pad_0050[4]; //0x0050
- float techUpgradeCount; //0x0054
- float percentExplored; //0x0058
- char pad_005C[36]; //0x005C
- float gameMaxPop; //0x0080
- char pad_0084[12]; //0x0084
- float farmFoodAmount; //0x0090
- float villagerCount; //0x0094
- char pad_0098[8]; //0x0098
- float infantryCount; //0x00A0
- char pad_00A4[24]; //0x00A4
- float goldRate; //0x00BC
- char pad_00C0[124]; //0x00C0
- float stoneRate; //0x013C
- float unitsQueueCount; //0x0140
- float builingProducingCount; //0x0144
- char pad_0148[24]; //0x0148
- float fishTrapAmount; //0x0160
- char pad_0164[400]; //0x0164
- float chopRate; //0x02F4
- float foodRate; //0x02F8
- float relicGoldRate; //0x02FC
- char pad_0300[12]; //0x0300
- float construcRateMaybe; //0x030C
- char pad_0310[48]; //0x0310
-}; //Size: 0x0340
diff --git a/SDK.h b/SDK.h
index 88a2575..88cec1f 100644
--- a/SDK.h
+++ b/SDK.h
@@ -2,6 +2,5 @@
#include <Windows.h>
#include <vector>
-#include "Resources.h"
#include "Classes.h"
-#pragma once
+