├── .gitattributes ├── LICENSE ├── README.md └── src ├── GUI ├── GUIdefines.hpp ├── font-icons │ ├── font.hpp │ └── iconfont.hpp ├── gui.cpp └── gui.hpp ├── IL2CPP Scanner.sln ├── IL2CPP Scanner.vcxproj ├── IL2CPP Scanner.vcxproj.filters ├── config └── config.hpp ├── engine ├── Children.cpp ├── Components.cpp ├── Fields.cpp ├── GameObjects.cpp ├── Search.cpp └── engine.h ├── find.cpp ├── find.hpp ├── globals └── Globals.hpp ├── il2cppresolver ├── Cache.cpp ├── Cache.hpp ├── Data.cpp ├── Data.hpp ├── Defines.hpp ├── Functions │ ├── Callback.cpp │ ├── Callback.hpp │ ├── Class.cpp │ ├── Class.hpp │ ├── Domain.hpp │ ├── ResolveCall.hpp │ ├── String.cpp │ ├── String.hpp │ ├── Thread.cpp │ └── Thread.hpp ├── Il2CppResolver.cpp ├── Il2CppResolver.hpp ├── Includes.hpp ├── Unity │ ├── API │ │ ├── Camera.cpp │ │ ├── Camera.hpp │ │ ├── Component.cpp │ │ ├── Component.hpp │ │ ├── GameObject.cpp │ │ ├── GameObject.hpp │ │ ├── LayerMask.cpp │ │ ├── LayerMask.hpp │ │ ├── Object.cpp │ │ ├── Object.hpp │ │ ├── Rigidbody.cpp │ │ ├── Rigidbody.hpp │ │ ├── Transform.cpp │ │ ├── Transform.hpp │ │ ├── _TEMPLATE_API.cpp │ │ └── _TEMPLATE_API.hpp │ ├── Defines.hpp │ ├── Includes.hpp │ ├── Obfuscators.cpp │ ├── Obfuscators.hpp │ └── Structures │ │ ├── Engine.hpp │ │ ├── Includes.hpp │ │ ├── System_String.hpp │ │ ├── il2cpp.hpp │ │ ├── il2cppArray.hpp │ │ └── il2cppDictionary.hpp └── Utils │ ├── Helper.cpp │ ├── Helper.hpp │ ├── Joaat.hpp │ └── VFunc.hpp ├── imgui ├── imconfig.h ├── imgui.cpp ├── imgui.h ├── imgui_demo.cpp ├── imgui_draw.cpp ├── imgui_impl_dx11.cpp ├── imgui_impl_dx11.h ├── imgui_impl_win32.cpp ├── imgui_impl_win32.h ├── imgui_internal.h ├── imgui_stdlib.cpp ├── imgui_stdlib.h ├── imgui_tables.cpp ├── imgui_widgets.cpp ├── imstb_rectpack.h ├── imstb_textedit.h └── imstb_truetype.h ├── kiero ├── kiero.cpp ├── kiero.h └── minhook │ ├── dll_resources │ ├── MinHook.aps │ ├── MinHook.def │ └── MinHook.rc │ ├── include │ └── MinHook.h │ └── src │ ├── buffer.c │ ├── buffer.h │ ├── hde │ ├── hde32.c │ ├── hde32.h │ ├── hde64.c │ ├── hde64.h │ ├── pstdint.h │ ├── table32.h │ └── table64.h │ ├── hook.c │ ├── trampoline.c │ └── trampoline.h ├── loader.cpp ├── misc.cpp └── misc.hpp /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 ImAxel0 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IL2CPP Scanner for DX11 2 | 3 | [![Github All Releases](https://img.shields.io/github/downloads/ImAxel0/IL2CPP_Scanner_DX11/total.svg)]() 4 | [![Github All Releases](https://img.shields.io/github/v/release/ImAxel0/IL2CPP_Scanner_DX11)]() 5 | 6 | ### Project archived because I consider it unstable and ahead of a possible release of a better version in the future [(sneak peek)](https://youtu.be/qwHQ73sW3UM) 7 | ## Edit: [(newer version here)](https://github.com/ImAxel0/IL2CPP_Scanner_Reborn) 8 | 9 | An in game GUI tool based on [IL2CPP_Resolver](https://github.com/sneakyevil/IL2CPP_Resolver) made to modify il2cpp Unity games. 10 | 11 | ![IL2CPP Scanner](https://i.imgur.com/Fi5w9e7.png) 12 | 13 | ## Disclaimer 14 | The software is provided as is and was made as a personal project, crashes can occur at any time. 15 | 16 | ## Compatibility 17 | Works with Unity il2ccp games running on DirectX11. 18 | 19 | Game must be set to borderless window or windowed mode! 20 | 21 | ## Features 22 | - Find active GameObjects 23 | - Find GameObject components and children components 24 | - Find and tweak component fields, currently supported field types are: 25 | - integers 26 | - float 27 | - bool 28 | - List component properties (can't do anything with them at the moment) 29 | 30 | ## How to use 31 | The tool is meant to be used along with dnSpy/ILSpy to previously know what to search for. This means you will need to dump the GameAssembly.dll with any il2cpp dumper. 32 | 33 | 1. Download the latest version from the releases page 34 | 2. Run the game 35 | 3. Inject IL2CPP Scanner.dll in the game process with any injector 36 | 37 | To show/hide the menu press the insert key 38 | 39 | ### Basic Usage (find a GameObject individually) 40 | 1. Specify a module name 41 | 2. Search an active GameObject 42 | 3. Load the GameObject components (children components are excluded) 43 | 4. Play with the component fields 44 | 45 | ### Searching all GameObjects in a specific module 46 | 1. Specify a module name 47 | 2. Search all active GameObjects in the specified module name 48 | 3. Load the selected GameObject components (children components are included) 49 | 4. Play with the component fields 50 | 51 | ### Finding components in namespaces (in children of a gameobject) 52 | 1. Specify a module name 53 | 2. Specify a namespace containing the children component 54 | 3. Search for an active GameObject which children contain the desidered component 55 | 4. Play with the children component fields 56 | 57 | ### Usage video example on the game "Sons of the Forest" 58 | [![Video example](https://i.imgur.com/b3adTug.png)](https://youtu.be/TqL_u4I1ot8) 59 | 60 | ### Credits 61 | Thanks to [sneakyevil](https://github.com/sneakyevil) for [IL2CPP_Resolver](https://github.com/sneakyevil/IL2CPP_Resolver) 62 | -------------------------------------------------------------------------------- /src/GUI/GUIdefines.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | inline void AskRange(); 4 | inline void SearchEngine(); 5 | inline void GameObjectsEngine(); 6 | inline void ComponentsEngine(); 7 | inline void FieldsEngine(); 8 | inline void ChildrenEngine(); 9 | -------------------------------------------------------------------------------- /src/GUI/gui.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "memory.h" 6 | #include "font-icons/font.hpp" 7 | #include "GUIdefines.hpp" 8 | #include "../engine/engine.h" 9 | 10 | extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 11 | 12 | HWND window = NULL; 13 | WNDPROC oWndProc; 14 | ID3D11Device* pDevice = NULL; 15 | ID3D11DeviceContext* pContext = NULL; 16 | ID3D11RenderTargetView* mainRenderTargetView; 17 | 18 | namespace Colors 19 | { 20 | ImColor black(0, 0, 0); 21 | ImColor white(255, 255, 255); 22 | ImColor mainTheme(183, 64, 64); 23 | ImColor* color = &mainTheme; 24 | } 25 | 26 | void InitImGui() 27 | { 28 | ImGui::CreateContext(); 29 | ImGuiIO& io = ImGui::GetIO(); 30 | ImGui::GetIO().WantCaptureMouse || ImGui::GetIO().WantTextInput || ImGui::GetIO().WantCaptureKeyboard; 31 | io.Fonts->AddFontFromMemoryTTF(&OpenSans_Regular_ttf, 1, 18.0); 32 | float baseFontSize = 10.0f; 33 | float iconFontSize = baseFontSize * 2.0f / 3.0f; 34 | static const ImWchar icons_ranges[] = { ICON_MIN_FA, ICON_MAX_16_FA, 0 }; 35 | ImFontConfig config; 36 | config.MergeMode = true; 37 | config.GlyphMinAdvanceX = 10.0f; 38 | static const ImWchar icon_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; 39 | io.Fonts->AddFontFromMemoryTTF(&icon_font_ttf, sizeof icon_font_ttf, 10.0f, &config, icon_ranges); 40 | 41 | Globals::Gui::LogContent.append("Start searching for a ModuleName and a GameObject\nA ModuleName is always required!\nOnly active GameObjects can be found.\nYou can also find all active GameObjects in a specified ModuleName but you won't get the children components of the selected\nGameObject\nTo get them search the desidered GameObject individually specifying the namespace containing the children components\n\n"); 42 | 43 | ImGui_ImplWin32_Init(window); 44 | ImGui_ImplDX11_Init(pDevice, pContext); 45 | } 46 | 47 | LRESULT __stdcall WndProc(const HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 48 | 49 | if (Globals::Gui::showMenu) { 50 | ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam); 51 | return true; 52 | } 53 | 54 | return CallWindowProc(oWndProc, hWnd, uMsg, wParam, lParam); 55 | } 56 | 57 | bool init = false; 58 | HRESULT __stdcall hkPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags) 59 | { 60 | if (!init) 61 | { 62 | if (SUCCEEDED(pSwapChain->GetDevice(__uuidof(ID3D11Device), (void**)&pDevice))) 63 | { 64 | pDevice->GetImmediateContext(&pContext); 65 | DXGI_SWAP_CHAIN_DESC sd; 66 | pSwapChain->GetDesc(&sd); 67 | window = sd.OutputWindow; 68 | ID3D11Texture2D* pBackBuffer; 69 | pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); 70 | pDevice->CreateRenderTargetView(pBackBuffer, NULL, &mainRenderTargetView); 71 | pBackBuffer->Release(); 72 | oWndProc = (WNDPROC)SetWindowLongPtr(window, GWLP_WNDPROC, (LONG_PTR)WndProc); 73 | InitImGui(); 74 | init = true; 75 | } 76 | 77 | else 78 | return Globals::Gui::oPresent(pSwapChain, SyncInterval, Flags); 79 | } 80 | 81 | ImGui_ImplDX11_NewFrame(); 82 | ImGui_ImplWin32_NewFrame(); 83 | ImGui::NewFrame(); 84 | ImGui::GetMouseCursor(); 85 | ImGui::SetMouseCursor(ImGuiMouseCursor_Arrow); 86 | ImGui::GetIO().WantCaptureMouse = Globals::Gui::showMenu; 87 | ImGui::GetIO().MouseDrawCursor = Globals::Gui::showMenu; 88 | 89 | if (GetAsyncKeyState(VK_INSERT) & 1) 90 | { 91 | Globals::Gui::showMenu = !Globals::Gui::showMenu; 92 | } 93 | 94 | if (Globals::Gui::showMenu) 95 | { 96 | Globals::Gui::style = &ImGui::GetStyle(); 97 | 98 | Globals::Gui::style->WindowTitleAlign = ImVec2(0.5, 0.5); 99 | Globals::Gui::style->WindowBorderSize = 3.0f; 100 | Globals::Gui::style->Colors[ImGuiCol_Border] = *Colors::color; 101 | Globals::Gui::style->Colors[ImGuiCol_TitleBg] = *Colors::color; 102 | Globals::Gui::style->Colors[ImGuiCol_TitleBgActive] = *Colors::color; 103 | Globals::Gui::style->Colors[ImGuiCol_FrameBg] = ImColor(36, 36, 36); 104 | Globals::Gui::style->Colors[ImGuiCol_FrameBgActive] = ImColor(36, 36, 36); 105 | Globals::Gui::style->Colors[ImGuiCol_FrameBgHovered] = ImColor(45, 45, 45); 106 | Globals::Gui::style->Colors[ImGuiCol_Button] = ImColor(32, 32, 32); 107 | Globals::Gui::style->Colors[ImGuiCol_ButtonHovered] = ImColor(45, 45, 45); 108 | Globals::Gui::style->Colors[ImGuiCol_ChildBg] = ImColor(36, 36, 36); 109 | 110 | ImGui::SetNextWindowSize(ImVec2(1280, 720), ImGuiCond_Once); 111 | ImGui::Begin("IL2CPP SCANNER " ICON_FA_MAGNIFYING_GLASS, &Globals::Gui::isOpen, ImGuiWindowFlags_NoResize); 112 | 113 | ImGui::Columns(2, nullptr, true); 114 | ImGui::SetColumnOffset(1, 400); 115 | { 116 | // Left panel GUI from here 117 | SearchEngine(); // Search panel GUI 118 | 119 | Globals::Gui::style->Colors[ImGuiCol_Border] = ImColor(45, 45, 45); 120 | Globals::Gui::style->Colors[ImGuiCol_FrameBg] = ImColor(24, 24, 24); 121 | Globals::Gui::style->Colors[ImGuiCol_FrameBgActive] = ImColor(24, 24, 24); 122 | Globals::Gui::style->Colors[ImGuiCol_FrameBgHovered] = ImColor(45, 45, 45); 123 | 124 | GameObjectsEngine(); // GameObjects panel GUI 125 | 126 | ImGui::NextColumn(); // Right Column from here 127 | 128 | // Current right panel view check 129 | if (Globals::Gui::right_column == "component") { 130 | ImGui::Text(Globals::GameObjectName->ToString().c_str()); 131 | ImGui::SameLine(), 132 | ImGui::Text("Component List (Instantiated Only)"); 133 | } 134 | else if (Globals::Gui::right_column == "children") { 135 | ImGui::Text("Children List"); 136 | } 137 | else if (Globals::Gui::right_column == "inside_component") { 138 | ImGui::Text(Globals::Gui::CurrentComponentString.c_str()); 139 | } 140 | 141 | // Right panel GUI from here 142 | ImGui::BeginChild("right_panel", ImVec2(ImGui::GetContentRegionAvail().x, 438), true, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_MenuBar); 143 | 144 | Globals::Gui::style->Colors[ImGuiCol_MenuBarBg] = ImColor(50, 50, 50); 145 | 146 | ImGui::BeginMenuBar(); 147 | ImGui::EndMenuBar(); 148 | 149 | ComponentsEngine(); // Components view 150 | 151 | FieldsEngine(); // Fields view 152 | 153 | ChildrenEngine(); // Children view 154 | 155 | ImGui::EndChild(); 156 | 157 | ImGui::SetCursorPos(ImVec2(NULL, 500)); 158 | Globals::Gui::style->Colors[ImGuiCol_Separator] = ImColor(0, 0, 0, 0); 159 | Globals::Gui::style->Colors[ImGuiCol_SeparatorActive] = ImColor(0, 0, 0, 0); 160 | Globals::Gui::style->Colors[ImGuiCol_SeparatorHovered] = ImColor(0, 0, 0, 0); 161 | ImGui::Separator(); 162 | 163 | // Log panel GUI from here 164 | ImGui::Text("Log"); 165 | ImGui::SameLine(), ImGui::SetCursorPosX(800); 166 | if (ImGui::SmallButton("Clear")) 167 | { 168 | Globals::Gui::LogContent.clear(); 169 | } 170 | Globals::Gui::style->Colors[ImGuiCol_FrameBg] = ImColor(36, 36, 36); 171 | Globals::Gui::style->Colors[ImGuiCol_FrameBgActive] = ImColor(36, 36, 36); 172 | Globals::Gui::style->Colors[ImGuiCol_FrameBgHovered] = ImColor(45, 45, 45); 173 | ImGui::BeginChild("log", ImGui::GetContentRegionAvail(), true, ImGuiWindowFlags_NoResize); 174 | ImGui::InputTextMultiline("##", &Globals::Gui::LogContent, ImGui::GetContentRegionAvail(), ImGuiInputTextFlags_ReadOnly); 175 | ImGui::EndChild(); 176 | } 177 | 178 | if (!Globals::Gui::isOpen) 179 | { 180 | Globals::Gui::showMenu = false; 181 | Globals::Gui::isOpen = true; 182 | } 183 | ImGui::End(); 184 | } 185 | ImGui::Render(); 186 | 187 | pContext->OMSetRenderTargets(1, &mainRenderTargetView, NULL); 188 | ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); 189 | return Globals::Gui::oPresent(pSwapChain, SyncInterval, Flags); 190 | } 191 | -------------------------------------------------------------------------------- /src/GUI/gui.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | void InitImGui(); 5 | LRESULT __stdcall WndProc(const HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 6 | HRESULT __stdcall hkPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags); 7 | -------------------------------------------------------------------------------- /src/IL2CPP Scanner.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.2.32616.157 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IL2CPP Scanner", "IL2CPP Scanner\IL2CPP Scanner.vcxproj", "{C9889713-4B83-4106-8FB6-F230301FC7EB}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {C9889713-4B83-4106-8FB6-F230301FC7EB}.Debug|x64.ActiveCfg = Debug|x64 17 | {C9889713-4B83-4106-8FB6-F230301FC7EB}.Debug|x64.Build.0 = Debug|x64 18 | {C9889713-4B83-4106-8FB6-F230301FC7EB}.Debug|x86.ActiveCfg = Debug|Win32 19 | {C9889713-4B83-4106-8FB6-F230301FC7EB}.Debug|x86.Build.0 = Debug|Win32 20 | {C9889713-4B83-4106-8FB6-F230301FC7EB}.Release|x64.ActiveCfg = Release|x64 21 | {C9889713-4B83-4106-8FB6-F230301FC7EB}.Release|x64.Build.0 = Release|x64 22 | {C9889713-4B83-4106-8FB6-F230301FC7EB}.Release|x86.ActiveCfg = Release|Win32 23 | {C9889713-4B83-4106-8FB6-F230301FC7EB}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {7D4CC4FE-A34F-4E60-B4E1-B5DFD9336FB9} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /src/config/config.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../il2cppresolver/Il2CppResolver.hpp" 3 | 4 | namespace Config 5 | { 6 | namespace Values 7 | { 8 | inline std::vector floatFields = {}; 9 | inline std::vector intFields = {}; 10 | inline std::vector booleanFields = {}; 11 | inline std::vector stringFields = {}; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/engine/Children.cpp: -------------------------------------------------------------------------------- 1 | #include "engine.h" 2 | 3 | void ChildrenEngine() 4 | { 5 | if (Globals::Gui::right_column == "children") 6 | { 7 | if (Globals::childCount != 0 && Globals::GameObject) // Safety check 8 | { 9 | for (uintptr_t u{}; Globals::childCount > u; ++u) 10 | { 11 | ImGui::InputScalar("##", ImGuiDataType_U64, &Globals::Childs.at(u), NULL, NULL, NULL, ImGuiInputTextFlags_ReadOnly); 12 | } 13 | } 14 | else { 15 | ImGui::SetCursorPos(ImVec2((ImGui::GetContentRegionAvail().x / 2) - 90, ImGui::GetContentRegionAvail().y / 2)); 16 | ImGui::Text("Nothing to show here at the moment"); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/engine/Components.cpp: -------------------------------------------------------------------------------- 1 | #include "engine.h" 2 | 3 | void ComponentsEngine() 4 | { 5 | if (Globals::Gui::right_column == "component") 6 | { 7 | if (Globals::Gui::DisplayComponents) 8 | { 9 | if (Globals::GameObject != nullptr) // Safety check 10 | { 11 | for (uintptr_t u{}; Globals::Components.size() > u; ++u) // Components Buttons 12 | { 13 | if (Globals::Components.at(u) != nullptr) // Safety check 14 | { 15 | if (ImGui::Button(Globals::ComponentsName.at(u), ImVec2(ImGui::GetContentRegionAvail().x, NULL))) 16 | { 17 | // Cleaning for imminent search 18 | Globals::m_vFields.clear(); 19 | Globals::fieldType.clear(); 20 | Globals::m_vProperties.clear(); 21 | 22 | // Field vectors get emptied when a component is selected before filling them with new values 23 | Config::Values::floatFields.clear(); 24 | Config::Values::intFields.clear(); 25 | Config::Values::booleanFields.clear(); 26 | 27 | Globals::Gui::CurrentComponentString = Globals::ComponentsName.at(u); // Store the selected component name 28 | Globals::CurrentComponent = Globals::Components.at(u); // Store the selected component 29 | Globals::Gui::right_column = "inside_component"; 30 | 31 | FindFields(); 32 | FindProperties(); 33 | } 34 | } 35 | } 36 | 37 | // ----------------------------------------------------------------------------------------------------------- \\ 38 | 39 | for (uintptr_t u{}; Globals::ChildrenComponents.size() > u; ++u) // Children Components Buttons 40 | { 41 | if (Globals::ChildrenComponents.at(u) != nullptr) // Safety check 42 | { 43 | ImGui::Text(ICON_FA_CHILD); 44 | ImGui::SameLine(); 45 | if (ImGui::Button(Globals::ChildrenComponentsName.at(u), ImVec2(ImGui::GetContentRegionAvail().x, NULL))) 46 | { 47 | // Cleaning for imminent search 48 | Globals::m_vFields.clear(); 49 | Globals::fieldType.clear(); 50 | Globals::m_vProperties.clear(); 51 | 52 | // Field vectors get emptied when a component is selected before filling them with new values 53 | Config::Values::floatFields.clear(); 54 | Config::Values::intFields.clear(); 55 | Config::Values::booleanFields.clear(); 56 | 57 | Globals::Gui::CurrentComponentString = Globals::ChildrenComponentsName.at(u); // Store the selected component name 58 | Globals::CurrentComponent = Globals::ChildrenComponents.at(u); // Store the selected component 59 | Globals::Gui::right_column = "inside_component"; 60 | 61 | if (Globals::Gui::GameObjectTypeSearch_Current == 1) // All GameObjects search type 62 | { 63 | Globals::Gui::ModuleNamespaceTypeSearch_Current = 1; // To use FindFields() and FindProperties() with the current component namespace 64 | Globals::Temp::NameSpaceSearch = Globals::CurrentComponent->m_Object.m_pClass->m_pNamespace; // Get namespace of the selected component 65 | 66 | FindFields(); 67 | FindProperties(); 68 | 69 | // Restore 70 | Globals::Gui::ModuleNamespaceTypeSearch_Current = 0; 71 | Globals::Temp::NameSpaceSearch.clear(); 72 | } 73 | else // Defined GameObject search type 74 | { 75 | FindFields(); 76 | FindProperties(); 77 | } 78 | } 79 | } 80 | } 81 | } 82 | } 83 | else { 84 | ImGui::SetCursorPos(ImVec2((ImGui::GetContentRegionAvail().x / 2) - 90, ImGui::GetContentRegionAvail().y / 2)); 85 | ImGui::Text("Nothing to show here at the moment"); 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /src/engine/Fields.cpp: -------------------------------------------------------------------------------- 1 | #include "engine.h" 2 | 3 | void FieldsEngine() 4 | { 5 | if (Globals::Gui::right_column == "inside_component") 6 | { 7 | for (uintptr_t u{}; Globals::fieldType.size() > u; ++u) 8 | { 9 | if (Globals::fieldType.at(u) == 12) // type float 10 | { 11 | Config::Values::floatFields.push_back(Globals::CurrentComponent->GetMemberValue(Globals::m_vFields.at(u)->m_pName)); 12 | 13 | Globals::Gui::style->Colors[ImGuiCol_Text] = ImColor(48, 167, 24); 14 | ImGui::Text("Float"); 15 | Globals::Gui::style->Colors[ImGuiCol_Text] = ImColor(255, 255, 255); 16 | 17 | ImGui::SameLine(); 18 | 19 | if (ImGui::InputFloat(Globals::m_vFields.at(u)->m_pName, &Config::Values::floatFields.at(u), NULL, NULL, "%.3f", ImGuiInputTextFlags_EnterReturnsTrue)) 20 | { 21 | Globals::CurrentComponent->SetMemberValue(Globals::m_vFields.at(u)->m_pName, Config::Values::floatFields.at(u)); 22 | } 23 | } 24 | else { 25 | Config::Values::floatFields.push_back(NULL); // To fill other types as a dummy value of 0 26 | } 27 | 28 | if (Globals::fieldType.at(u) == 8) // type integer 29 | { 30 | Config::Values::intFields.push_back(Globals::CurrentComponent->GetMemberValue(Globals::m_vFields.at(u)->m_pName)); 31 | 32 | Globals::Gui::style->Colors[ImGuiCol_Text] = ImColor(0, 120, 212); 33 | ImGui::Text("Int"); 34 | Globals::Gui::style->Colors[ImGuiCol_Text] = ImColor(255, 255, 255); 35 | 36 | ImGui::SameLine(); 37 | 38 | if (ImGui::InputInt(Globals::m_vFields.at(u)->m_pName, &Config::Values::intFields.at(u), NULL, NULL, ImGuiInputTextFlags_EnterReturnsTrue)) 39 | { 40 | Globals::CurrentComponent->SetMemberValue(Globals::m_vFields.at(u)->m_pName, Config::Values::intFields.at(u)); 41 | } 42 | } 43 | else { 44 | Config::Values::intFields.push_back(NULL); // To fill other types as a dummy value of 0 45 | } 46 | 47 | if (Globals::fieldType.at(u) == 2) // type boolean 48 | { 49 | Config::Values::booleanFields.push_back(Globals::CurrentComponent->GetMemberValue(Globals::m_vFields.at(u)->m_pName)); 50 | 51 | Globals::Gui::style->Colors[ImGuiCol_Text] = ImColor(183, 64, 64); 52 | ImGui::Text("Bool"); 53 | Globals::Gui::style->Colors[ImGuiCol_Text] = ImColor(255, 255, 255); 54 | 55 | ImGui::SameLine(); 56 | 57 | if (ImGui::Checkbox(Globals::m_vFields.at(u)->m_pName, (bool*)&Config::Values::booleanFields.at(u))) 58 | { 59 | bool state; 60 | state = Globals::CurrentComponent->GetMemberValue(Globals::m_vFields.at(u)->m_pName); 61 | 62 | if (state) 63 | { 64 | Globals::CurrentComponent->SetMemberValue(Globals::m_vFields.at(u)->m_pName, false); 65 | } 66 | else 67 | { 68 | Globals::CurrentComponent->SetMemberValue(Globals::m_vFields.at(u)->m_pName, true); 69 | } 70 | } 71 | } 72 | else { 73 | Config::Values::booleanFields.push_back(NULL); // To fill other types as a dummy value of 0 74 | } 75 | 76 | /* // Disabled as unstable 77 | if (Globals::fieldType.at(u) == 14) // type string 78 | { 79 | Config::Values::stringFields.push_back(Globals::CurrentComponent->GetMemberValue(Globals::m_vFields.at(u)->m_pName)); 80 | 81 | Globals::Gui::style->Colors[ImGuiCol_Text] = ImColor(244, 202, 33); 82 | ImGui::Text("String"); 83 | Globals::Gui::style->Colors[ImGuiCol_Text] = ImColor(255, 255, 255); 84 | 85 | ImGui::SameLine(); 86 | 87 | ImGui::InputText(Globals::m_vFields.at(u)->m_pName, &Config::Values::stringFields.at(u).ToString()); 88 | } 89 | else { 90 | Unity::System_String dummy{}; 91 | Config::Values::stringFields.push_back(dummy); // To fill other types as a dummy value 92 | } 93 | */ 94 | } 95 | 96 | // Vectors need to be cleared after every for loop otherwise it goes above the current number of fields 97 | Config::Values::floatFields.clear(); 98 | Config::Values::intFields.clear(); 99 | Config::Values::booleanFields.clear(); 100 | //Config::Values::stringFields.clear(); 101 | 102 | // Properties list 103 | for (uintptr_t u{}; Globals::m_vProperties.size() > u; ++u) 104 | { 105 | Globals::Gui::style->Colors[ImGuiCol_Text] = ImColor(244, 202, 33); 106 | ImGui::Text("Property"); 107 | Globals::Gui::style->Colors[ImGuiCol_Text] = ImColor(255, 255, 255); 108 | 109 | ImGui::SameLine(); 110 | 111 | Globals::propertyName = Globals::m_vProperties.at(u)->m_pName; 112 | 113 | ImGui::InputText("##", &Globals::propertyName, ImGuiInputTextFlags_ReadOnly); 114 | } 115 | } 116 | } -------------------------------------------------------------------------------- /src/engine/GameObjects.cpp: -------------------------------------------------------------------------------- 1 | #include "engine.h" 2 | 3 | void GameObjectsEngine() 4 | { 5 | ImGui::BeginChild("GameObject List", ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y), true, ImGuiWindowFlags_NoResize); 6 | 7 | if (Globals::Gui::GameObjectTypeSearch_Current == 0) // Defined GameObject 8 | { 9 | if (Globals::GameObject != nullptr) // Safety check 10 | { 11 | Globals::GameObjectName = Globals::GameObject->GetName(); // Get GameObject Name 12 | 13 | if (ImGui::Button(Globals::GameObjectName->ToString().c_str(), ImVec2(ImGui::GetContentRegionAvail().x, NULL))) // Find Components + children in the GameObject 14 | { 15 | Globals::Gui::right_column = "component"; 16 | Globals::Gui::DisplayComponents = true; 17 | 18 | // Cleanup for imminent search 19 | Globals::ComponentsName.clear(); 20 | Globals::ChildrenComponentsName.clear(); 21 | Globals::Components.clear(); 22 | Globals::ChildrenComponents.clear(); 23 | 24 | if (Globals::Gui::ModuleNamespaceTypeSearch_Current == 1) // Namespace defined 25 | { 26 | FindChildrenComponents(); 27 | } 28 | else // Default or All namespaces 29 | { 30 | FindComponents(); 31 | //FindChildren(); 32 | } 33 | } 34 | } 35 | else { 36 | ImGui::SetCursorPos(ImVec2(70, ImGui::GetContentRegionAvail().y / 2)); 37 | ImGui::Text("No GameObject to show at the moment"); 38 | } 39 | } 40 | 41 | // ------------------------------------------------------------------------------------------------------------------------------- \\ 42 | 43 | if (Globals::Gui::GameObjectTypeSearch_Current == 1) // All GameObjects 44 | { 45 | if (Globals::GameObjects.size() > 0) 46 | { 47 | for (uintptr_t u{}; Globals::GameObjects.size() > u; ++u) 48 | { 49 | if (Globals::GameObjects.at(u) != nullptr) // Safety check 50 | { 51 | Globals::GameObjectsName.push_back(Globals::GameObjects.at(u)->GetName()); 52 | 53 | if (ImGui::Button(Globals::GameObjectsName.at(u)->ToString().c_str(), ImVec2(ImGui::GetContentRegionAvail().x, NULL))) 54 | { 55 | Globals::Gui::right_column = "component"; 56 | Globals::Gui::DisplayComponents = true; 57 | 58 | // Cleanup for imminent search 59 | Globals::ComponentsName.clear(); 60 | Globals::ChildrenComponentsName.clear(); 61 | Globals::Components.clear(); 62 | Globals::ChildrenComponents.clear(); 63 | 64 | Globals::GameObject = Globals::GameObjects.at(u); // Store the selected GameObject 65 | Globals::GameObjectName = Globals::GameObjectsName.at(u); // Store the selected GameObject name 66 | 67 | std::vector classesBackup = Globals::m_vClasses; // Backup the number of found classes in all namespaces 68 | Globals::m_vClasses.clear(); 69 | 70 | // Makes so FindComponents doesn't get invalid children components 71 | IL2CPP::Class::FetchClasses(&Globals::m_vClasses, Globals::Temp::ModuleNameSearch.c_str(), ""); 72 | 73 | FindComponents(); 74 | 75 | Globals::m_vClasses = classesBackup; // Restore the number of found classes in all namespaces 76 | 77 | FindNamespaces(); 78 | 79 | FindAllChildrenComponents(); 80 | } 81 | } 82 | } 83 | Globals::GameObjectsName.clear(); // Cleanup after every for loop to not go outbound 84 | } 85 | else { 86 | ImGui::SetCursorPos(ImVec2(70, ImGui::GetContentRegionAvail().y / 2)); 87 | ImGui::Text("No GameObject to show at the moment"); 88 | } 89 | } 90 | 91 | ImGui::EndChild(); 92 | } -------------------------------------------------------------------------------- /src/engine/Search.cpp: -------------------------------------------------------------------------------- 1 | #include "engine.h" 2 | 3 | void AskRange() 4 | { 5 | ImGui::SetNextWindowSize(ImVec2(800, 240)); 6 | ImGui::Begin("Range Input", NULL, ImGuiWindowFlags_NoResize); 7 | 8 | int classesSize = static_cast(Globals::m_vClasses.size()); 9 | 10 | ImGui::Text(std::to_string(classesSize).c_str()); 11 | ImGui::SameLine(), ImGui::Text("classes has been found in the specified ModuleName"); 12 | ImGui::Text("Please input a range to search. If the range is too large the game may crash, recommended max range is 1000.\nDo not exceed the number of found classes\nActive found GameObjects will be listed on the left panel"); 13 | 14 | ImGui::InputScalar("From", ImGuiDataType_U64, &Globals::rangeStart, NULL, NULL, NULL, ImGuiInputTextFlags_EnterReturnsTrue); 15 | ImGui::InputScalar("To", ImGuiDataType_U64, &Globals::rangeEnd, NULL, NULL, NULL, ImGuiInputTextFlags_EnterReturnsTrue); 16 | 17 | ImGui::End(); 18 | } 19 | 20 | void SearchEngine() 21 | { 22 | if (Globals::Gui::GameObjectTypeSearch_Current == 0) 23 | { 24 | ImGui::Combo("Module Namespace", &Globals::Gui::ModuleNamespaceTypeSearch_Current, Globals::Gui::ModuleNamespaceTypeSearch, 2); // Choose to include or not a Namespace in the search 25 | } 26 | 27 | ImGui::InputText("ModuleName", &Globals::Temp::ModuleNameSearch); 28 | 29 | if (Globals::Gui::GameObjectTypeSearch_Current == 0) 30 | { 31 | if (Globals::Gui::ModuleNamespaceTypeSearch_Current == 1) // Namespace Specified 32 | { 33 | ImGui::InputText("Namespace", &Globals::Temp::NameSpaceSearch, ImGuiInputTextFlags_EnterReturnsTrue); 34 | } 35 | else 36 | { 37 | Globals::Temp::NameSpaceSearch.clear(); 38 | } 39 | } 40 | 41 | ImGui::Combo("GameObject Search", &Globals::Gui::GameObjectTypeSearch_Current, Globals::Gui::GameObjectTypeSearch, 2); // Choose to search a defined GameObject or all 42 | 43 | if (Globals::Gui::GameObjectTypeSearch_Current == 0) // Defined GameObject 44 | { 45 | ImGui::InputText("GameObject", &Globals::Temp::GameObjectSearch); 46 | } 47 | 48 | // Search buttons 49 | if (Globals::Gui::GameObjectTypeSearch_Current == 0) // Defined GameObject 50 | { 51 | Globals::gotClasses = false; 52 | 53 | if (ImGui::SmallButton("Search GameObject")) 54 | { 55 | if (Globals::Temp::ModuleNameSearch == "") 56 | { 57 | Globals::Gui::LogContent.append("ModuleName field can't be empty\n\n"); 58 | DU_MessageBoxTimeout(NULL, L"ModuleName field can't be empty", L"Warning", MB_ICONINFORMATION, 3000); 59 | } 60 | else 61 | { 62 | Globals::m_vClasses.clear(); 63 | Globals::GameObjects.clear(); 64 | Globals::GameObjectsName.clear(); 65 | FindGameObject(); 66 | FindModule(); 67 | } 68 | } 69 | } 70 | else if (Globals::Gui::GameObjectTypeSearch_Current == 1) // Search all GameObjects 71 | { 72 | if (!Globals::gotClasses) { 73 | 74 | // Turn off defined namespace when in GameObject multi-search to prevent crashes on FindFields() 75 | Globals::Gui::ModuleNamespaceTypeSearch_Current = 0; 76 | Globals::Temp::NameSpaceSearch.clear(); 77 | 78 | if (Globals::Temp::ModuleNameSearch == "") 79 | { 80 | Globals::Gui::GameObjectTypeSearch_Current = 0; 81 | Globals::Gui::LogContent.append("ModuleName field can't be empty\n\n"); 82 | DU_MessageBoxTimeout(NULL, L"ModuleName field can't be empty", L"Warning", MB_ICONINFORMATION, 3000); 83 | Globals::gotClasses = false; 84 | return; 85 | } 86 | else 87 | { 88 | IL2CPP::Class::FetchClasses(&Globals::m_vClasses, Globals::Temp::ModuleNameSearch.c_str(), nullptr); 89 | 90 | if (Globals::m_vClasses.size() == 0) 91 | { 92 | Globals::Gui::GameObjectTypeSearch_Current = 0; 93 | Globals::Gui::LogContent.append("Specified ModuleName doesn't exist or is empty\nCheck for spelling mistakes\n\n"); 94 | DU_MessageBoxTimeout(NULL, L"Specified ModuleName doesn't exist or is empty\nCheck for spelling mistakes", L"Warning", MB_ICONINFORMATION, 3000); 95 | Globals::gotClasses = false; 96 | return; 97 | } 98 | else 99 | { 100 | Globals::rangeEnd = static_cast(Globals::m_vClasses.size()); // Auto set the End range number to the number of found classes 101 | } 102 | Globals::gotClasses = true; 103 | } 104 | } 105 | 106 | AskRange(); 107 | 108 | if (ImGui::SmallButton("Search all GameObjects in range (can be slow)")) 109 | { 110 | Globals::m_vClasses.clear(); 111 | Globals::GameObjects.clear(); 112 | Globals::GameObjectsName.clear(); 113 | FindAllGameObjects(); 114 | } 115 | } 116 | } -------------------------------------------------------------------------------- /src/engine/engine.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../imgui/imgui.h" 4 | #include "../imgui/imgui_impl_dx11.h" 5 | #include "../imgui/imgui_impl_win32.h" 6 | #include "../imgui/imgui_stdlib.h" 7 | #include "../config/config.hpp" 8 | #include "../globals/Globals.hpp" 9 | #include "../misc.hpp" 10 | #include "../find.hpp" 11 | #include "../GUI/font-icons/iconfont.hpp" 12 | -------------------------------------------------------------------------------- /src/find.cpp: -------------------------------------------------------------------------------- 1 | #include "globals/Globals.hpp" 2 | #include "../IL2CPP Scanner/GUI/GUIdefines.hpp" 3 | 4 | void FindModule() 5 | { 6 | Globals::Gui::LogContent.append("Fetching Classes...\n\n"); 7 | 8 | IL2CPP::Class::FetchClasses(&Globals::m_vClasses, Globals::Temp::ModuleNameSearch.c_str(), Globals::Temp::NameSpaceSearch.c_str()); 9 | 10 | for (uintptr_t u{}; Globals::m_vClasses.size() > u; ++u) 11 | { 12 | Globals::Gui::LogContent.append(Globals::m_vClasses.at(u)->m_pName).append("\n"); 13 | } 14 | 15 | if (Globals::m_vClasses.size() == 0) 16 | { 17 | Globals::Gui::LogContent.append("[-] Couldn't find ").append(Globals::Temp::ModuleNameSearch).append(" Module\n\n"); 18 | } 19 | } 20 | 21 | void FindGameObject() 22 | { 23 | Globals::Gui::LogContent.append("Searching ").append(Globals::Temp::GameObjectSearch).append(" GameObject...\n\n"); 24 | 25 | Globals::GameObject = Unity::GameObject::Find(Globals::Temp::GameObjectSearch.c_str()); 26 | 27 | if (Globals::GameObject != nullptr) 28 | { 29 | Globals::Gui::LogContent.append("[+] ").append(Globals::Temp::GameObjectSearch).append(" GameObject Found\n"); 30 | } 31 | 32 | else { 33 | Globals::Gui::LogContent.append("[-] ").append(Globals::Temp::GameObjectSearch).append(" GameObject not Found\n"); 34 | } 35 | 36 | Globals::Components.clear(); 37 | Globals::Gui::DisplayComponents = false; 38 | } 39 | 40 | void FindAllGameObjects() 41 | { 42 | Globals::Gui::LogContent.append("Searching all active GameObjects in the defined ModuleName...\n"); 43 | 44 | IL2CPP::Class::FetchClasses(&Globals::m_vClasses, Globals::Temp::ModuleNameSearch.c_str(), nullptr); 45 | 46 | Unity::CGameObject* tempGameObject; 47 | 48 | uintptr_t rangeStartBackup = Globals::rangeStart; 49 | 50 | for (Globals::rangeStart; Globals::rangeEnd > Globals::rangeStart; ++Globals::rangeStart) { 51 | 52 | tempGameObject = Unity::GameObject::Find(Globals::m_vClasses.at(Globals::rangeStart)->m_pName); 53 | 54 | if (tempGameObject != nullptr) 55 | { 56 | Globals::GameObjects.push_back(tempGameObject); 57 | } 58 | } 59 | 60 | Globals::rangeStart = rangeStartBackup; 61 | 62 | Globals::Components.clear(); 63 | Globals::Gui::DisplayComponents = false; 64 | } 65 | 66 | void FindComponents() 67 | { 68 | Unity::CComponent* tempComponent; 69 | 70 | for (uintptr_t u{}; Globals::m_vClasses.size() > u; ++u) 71 | { 72 | tempComponent = Globals::GameObject->GetComponent(Globals::m_vClasses.at(u)->m_pName); 73 | 74 | if (tempComponent != nullptr) 75 | { 76 | Globals::ComponentsName.push_back(Globals::m_vClasses.at(u)->m_pName); 77 | 78 | Globals::Components.push_back(tempComponent); 79 | } 80 | } 81 | } 82 | 83 | void FindChildren() 84 | { 85 | if (Globals::GameObject) 86 | { 87 | Globals::childCount = Globals::GameObject->GetTransform()->GetChildCount(); 88 | 89 | for (uintptr_t u{}; Globals::childCount > u; ++u) 90 | { 91 | Globals::Childs.push_back(Globals::GameObject->GetTransform()->GetChild(u)); 92 | } 93 | } 94 | } 95 | 96 | void FindFields() 97 | { 98 | if (Globals::Gui::ModuleNamespaceTypeSearch_Current == 1) // Namespace defined 99 | { 100 | Globals::Namespace = Globals::Temp::NameSpaceSearch; // Namespace text backup 101 | 102 | Unity::il2cppClass* classe = IL2CPP::Class::Find(Globals::Temp::NameSpaceSearch.append(".").append(Globals::Gui::CurrentComponentString).c_str()); 103 | IL2CPP::Class::FetchFields(classe, &Globals::m_vFields, nullptr); 104 | 105 | // Restore and Cleanup 106 | Globals::Temp::NameSpaceSearch = Globals::Namespace; 107 | Globals::Namespace.clear(); 108 | } 109 | 110 | else // Default namespace 111 | { 112 | Unity::il2cppClass* classe = IL2CPP::Class::Find(Globals::Gui::CurrentComponentString.c_str()); 113 | IL2CPP::Class::FetchFields(classe, &Globals::m_vFields, nullptr); 114 | } 115 | 116 | Globals::Gui::LogContent.append("Searching fields in ").append(Globals::Gui::CurrentComponentString).append(" component...\n\n"); 117 | 118 | for (uintptr_t u{}; Globals::m_vFields.size() > u; ++u) 119 | { 120 | Globals::Gui::LogContent.append(Globals::m_vFields.at(u)->m_pName).append("\n"); 121 | } 122 | 123 | if (Globals::m_vFields.size() == 0) 124 | { 125 | Globals::Gui::LogContent.append("[-] Couldn't find any ").append(Globals::Gui::CurrentComponentString).append(" field\n\n"); 126 | return; 127 | } 128 | 129 | for (uintptr_t u{}; Globals::m_vFields.size() > u; ++u) 130 | { 131 | Globals::fieldType.push_back(Globals::m_vFields.at(u)->m_pType->m_uType); 132 | } 133 | } 134 | 135 | void FindProperties() 136 | { 137 | if (Globals::Gui::ModuleNamespaceTypeSearch_Current == 1) // Namespace defined 138 | { 139 | Globals::Namespace = Globals::Temp::NameSpaceSearch; // Namespace text backup 140 | 141 | Unity::il2cppClass* classe = IL2CPP::Class::Find(Globals::Temp::NameSpaceSearch.append(".").append(Globals::Gui::CurrentComponentString).c_str()); 142 | IL2CPP::Class::FetchProperties(classe, &Globals::m_vProperties, nullptr); 143 | 144 | // Restore and Cleanup 145 | Globals::Temp::NameSpaceSearch = Globals::Namespace; 146 | Globals::Namespace.clear(); 147 | } 148 | 149 | else // Default namespace 150 | { 151 | Unity::il2cppClass* classe = IL2CPP::Class::Find(Globals::Gui::CurrentComponentString.c_str()); 152 | IL2CPP::Class::FetchProperties(classe, &Globals::m_vProperties, nullptr); 153 | } 154 | 155 | Globals::Gui::LogContent.append("Searching properties in ").append(Globals::Gui::CurrentComponentString).append(" component...\n\n"); 156 | 157 | for (uintptr_t u{}; Globals::m_vProperties.size() > u; ++u) 158 | { 159 | Globals::Gui::LogContent.append(Globals::m_vProperties.at(u)->m_pName).append("\n"); 160 | } 161 | 162 | if (Globals::m_vProperties.size() == 0) 163 | { 164 | Globals::Gui::LogContent.append("[-] Couldn't find any ").append(Globals::Gui::CurrentComponentString).append(" property\n\n"); 165 | return; 166 | } 167 | } 168 | 169 | void FindChildrenComponents() 170 | { 171 | Globals::Namespace = Globals::Temp::NameSpaceSearch; 172 | 173 | for (uintptr_t u{}; Globals::m_vClasses.size() > u; ++u) 174 | { 175 | Globals::ChildrenComponentsName.push_back(Globals::m_vClasses.at(u)->m_pName); 176 | 177 | Globals::ChildrenComponents.push_back(Globals::GameObject->GetComponentInChildren(Globals::Temp::NameSpaceSearch.append(".").append(Globals::m_vClasses.at(u)->m_pName).c_str())); 178 | Globals::Temp::NameSpaceSearch = Globals::Namespace; 179 | } 180 | } 181 | 182 | void FindAllChildrenComponents() 183 | { 184 | std::vector classesBackup = Globals::m_vClasses; 185 | std::string NamespaceBackup; 186 | Unity::CComponent* tempComponent; 187 | 188 | for (uintptr_t u{}; Globals::ClassesNamespaces.size() > u; ++u) 189 | { 190 | std::string tempNamespaceStr = Globals::ClassesNamespaces.at(u); 191 | 192 | IL2CPP::Class::FetchClasses(&Globals::m_vClasses, Globals::Temp::ModuleNameSearch.c_str(), tempNamespaceStr.c_str()); // To search classes (components) in their namespace only 193 | 194 | for (uintptr_t i{}; Globals::m_vClasses.size() > i; ++i) 195 | { 196 | NamespaceBackup = tempNamespaceStr; 197 | 198 | tempComponent = Globals::GameObject->GetComponentInChildren(tempNamespaceStr.append(".").append(Globals::m_vClasses.at(i)->m_pName).c_str()); 199 | 200 | if (tempComponent != nullptr) 201 | { 202 | Globals::ChildrenComponents.push_back(tempComponent); 203 | Globals::ChildrenComponentsName.push_back(tempComponent->m_Object.m_pClass->m_pName); 204 | } 205 | 206 | tempNamespaceStr.clear(); 207 | tempNamespaceStr = NamespaceBackup; 208 | } 209 | } 210 | 211 | Globals::m_vClasses = classesBackup; 212 | } 213 | 214 | void FindNamespaces() 215 | { 216 | std::string tempNamespace; 217 | 218 | for (uintptr_t u{}; Globals::m_vClasses.size() > u; ++u) 219 | { 220 | tempNamespace = Globals::m_vClasses.at(u)->m_pNamespace; 221 | 222 | if (tempNamespace == "\0" /*empty namespace*/) 223 | { 224 | continue; 225 | } 226 | 227 | if (std::find(Globals::ClassesNamespaces.begin(), Globals::ClassesNamespaces.end(), tempNamespace) != Globals::ClassesNamespaces.end()) // Skip if already present 228 | { 229 | continue; 230 | } 231 | 232 | Globals::ClassesNamespaces.push_back(tempNamespace); 233 | } 234 | } -------------------------------------------------------------------------------- /src/find.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | inline void FindModule(); 4 | inline void FindGameObject(); 5 | inline void FindAllGameObjects(); 6 | inline void FindComponents(); 7 | inline void FindChildren(); 8 | inline void FindFields(); 9 | inline void FindChildrenComponents(); 10 | inline void FindAllChildrenComponents(); 11 | inline void FindProperties(); 12 | inline void FindNamespaces(); 13 | -------------------------------------------------------------------------------- /src/globals/Globals.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "../il2cppresolver/Il2CppResolver.hpp" 8 | 9 | #include "../imgui/imgui.h" 10 | #include "../imgui/imgui_impl_dx11.h" 11 | #include "../imgui/imgui_impl_win32.h" 12 | 13 | typedef HRESULT(__stdcall* Present) (IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags); 14 | typedef LRESULT(CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM); 15 | typedef uintptr_t PTR; 16 | 17 | namespace Globals 18 | { 19 | // GameObjects related 20 | inline Unity::CGameObject* GameObject; 21 | inline Unity::System_String* GameObjectName; 22 | inline std::vector GameObjects; 23 | inline std::vector< Unity::System_String*> GameObjectsName; 24 | inline uintptr_t rangeStart{ 0 }; 25 | inline uintptr_t rangeEnd{ 100 }; 26 | inline bool gotClasses = false; 27 | 28 | // Components 29 | inline std::vector Components = {}; 30 | inline std::vector ComponentsName = {}; 31 | 32 | // Components of children 33 | inline std::vector ChildrenComponents = {}; 34 | inline std::vector ChildrenComponentsName = {}; 35 | 36 | inline std::string Namespace; // Namespace text backup for for loops 37 | 38 | // Current active/selected component 39 | inline Unity::CComponent* CurrentComponent; 40 | 41 | // Vector of module classes 42 | inline std::vector m_vClasses; 43 | 44 | // Vector of Namespaces 45 | inline std::vector ClassesNamespaces = {}; 46 | 47 | // Vector of properties 48 | inline std::vector m_vProperties; 49 | inline std::string propertyName; 50 | 51 | // Fields 52 | inline std::vector m_vFields; 53 | inline std::vector fieldType = {}; 54 | 55 | // Children 56 | inline int childCount{}; 57 | inline std::vector Childs = {}; 58 | 59 | namespace Temp // Search strings 60 | { 61 | inline std::string ModuleNameSearch; 62 | inline std::string NameSpaceSearch; 63 | inline std::string GameObjectSearch; 64 | inline std::string ComponentSearch; 65 | } 66 | namespace Gui 67 | { 68 | inline Present oPresent; 69 | inline ImGuiStyle* style; 70 | inline HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 71 | 72 | inline bool showMenu = false; 73 | inline bool isOpen = true; 74 | inline bool DisplayComponents = false; 75 | 76 | inline const char* ModuleNamespaceTypeSearch[] = { "Default (no namespace)", "Defined"}; 77 | inline int ModuleNamespaceTypeSearch_Current = 0; 78 | 79 | inline const char* GameObjectTypeSearch[] = { "Defined", "All" }; 80 | inline int GameObjectTypeSearch_Current = 0; 81 | 82 | inline std::string right_column = "component"; 83 | inline std::string LogContent = ""; 84 | inline std::string CurrentComponentString = ""; // The selected component text 85 | } 86 | 87 | inline bool il2cppStatus = false; 88 | } 89 | -------------------------------------------------------------------------------- /src/il2cppresolver/Cache.cpp: -------------------------------------------------------------------------------- 1 | #include "Includes.hpp" 2 | 3 | namespace IL2CPP 4 | { 5 | namespace SystemTypeCache 6 | { 7 | class CCache 8 | { 9 | public: 10 | unsigned int m_uHash = 0U; 11 | Unity::il2cppObject* m_pSystemType = nullptr; 12 | 13 | CCache() { } 14 | CCache(unsigned int m_uKey, Unity::il2cppObject* m_pValue) 15 | { 16 | m_uHash = m_uKey; 17 | m_pSystemType = m_pValue; 18 | } 19 | }; 20 | std::vector m_vCache; 21 | 22 | void Add(unsigned int m_uHash, Unity::il2cppObject* m_pSystemType) 23 | { 24 | if (!m_pSystemType) 25 | return; 26 | 27 | m_vCache.emplace_back(CCache(m_uHash, m_pSystemType)); 28 | } 29 | 30 | void Add(const char* m_pName, Unity::il2cppObject* m_pSystemType) 31 | { 32 | if (!m_pName) 33 | return; 34 | 35 | Add(Utils::JOAAT(m_pName), m_pSystemType); 36 | } 37 | 38 | Unity::il2cppObject* Find(unsigned int m_uHash) 39 | { 40 | size_t m_sSize = m_vCache.size(); 41 | if (m_sSize > 0) 42 | { 43 | CCache* m_pData = m_vCache.data(); 44 | for (size_t i = 0; m_sSize > i; ++i) 45 | { 46 | if (m_pData[i].m_uHash == m_uHash) 47 | return m_pData[i].m_pSystemType; 48 | } 49 | } 50 | 51 | return nullptr; 52 | } 53 | 54 | Unity::il2cppObject* Find(const char* m_pName) 55 | { 56 | return Find(Utils::JOAAT(m_pName)); 57 | } 58 | 59 | namespace Initializer 60 | { 61 | std::vector m_vList; 62 | 63 | void Add(const char* m_pName) { m_vList.emplace_back(m_pName); } 64 | 65 | void PreCache() 66 | { 67 | for (const char* m_pName : m_vList) 68 | SystemTypeCache::Add(m_pName, IL2CPP::Class::GetSystemType(m_pName)); 69 | 70 | m_vList.clear(); 71 | } 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Cache.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace IL2CPP 4 | { 5 | namespace SystemTypeCache 6 | { 7 | void Add(unsigned int m_uHash, Unity::il2cppObject* m_pSystemType); 8 | 9 | void Add(const char* m_pName, Unity::il2cppObject* m_pSystemType); 10 | 11 | Unity::il2cppObject* Find(unsigned int m_uHash); 12 | 13 | Unity::il2cppObject* Find(const char* m_pName); 14 | 15 | namespace Initializer 16 | { 17 | extern std::vector m_vList; 18 | 19 | /* 20 | * (WARNING) this needs to be called before actual IL2CPP Resolver Init, otherwise use function Add outside Initializer namespace! 21 | */ 22 | void Add(const char* m_pName); 23 | 24 | void PreCache(); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Data.cpp: -------------------------------------------------------------------------------- 1 | #include "Includes.hpp" 2 | 3 | namespace IL2CPP { SData Data; } -------------------------------------------------------------------------------- /src/il2cppresolver/Data.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace IL2CPP 4 | { 5 | struct SData 6 | { 7 | HMODULE m_hGameAseembly = 0; 8 | 9 | struct SFunctions 10 | { 11 | void* m_pClassFromName = nullptr; 12 | void* m_pClassGetFields = nullptr; 13 | void* m_pClassGetFieldFromName = nullptr; 14 | void* m_pClassGetMethods = nullptr; 15 | void* m_pClassGetMethodFromName = nullptr; 16 | void* m_pClassGetProperties = nullptr; 17 | void* m_pClassGetPropertyFromName = nullptr; 18 | void* m_pClassGetType = nullptr; 19 | void* m_pDomainGet = nullptr; 20 | void* m_pDomainGetAssemblies = nullptr; 21 | void* m_pFree = nullptr; 22 | void* m_pImageGetClass = nullptr; 23 | void* m_pImageGetClassCount = nullptr; 24 | void* m_pResolveFunction = nullptr; 25 | void* m_pStringNew = nullptr; 26 | void* m_pThreadAttach = nullptr; 27 | void* m_pThreadDetach = nullptr; 28 | void* m_pTypeGetObject = nullptr; 29 | }; 30 | SFunctions Functions; 31 | }; 32 | extern SData Data; 33 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Defines.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | // Disable Asserts 3 | //#define IL2CPP_ASSERT(x) assert(0) 4 | #ifndef IL2CPP_ASSERT 5 | #define IL2CPP_ASSERT(x) assert(x) 6 | #endif 7 | 8 | #ifndef IL2CPP_MAIN_MODULE 9 | #define IL2CPP_MAIN_MODULE "GameAssembly.dll" 10 | #endif 11 | 12 | #define IL2CPP_INIT_EXPORT "il2cpp_init" 13 | #define IL2CPP_CLASS_FROM_NAME_EXPORT "il2cpp_class_from_name" 14 | #define IL2CPP_CLASS_GET_FIELDS "il2cpp_class_get_fields" 15 | #define IL2CPP_CLASS_GET_FIELD_FROM_NAME_EXPORT "il2cpp_class_get_field_from_name" 16 | #define IL2CPP_CLASS_GET_METHODS "il2cpp_class_get_methods" 17 | #define IL2CPP_CLASS_GET_METHOD_FROM_NAME_EXPORT "il2cpp_class_get_method_from_name" 18 | #define IL2CPP_CLASS_GET_PROPERTIES "il2cpp_class_get_properties" 19 | #define IL2CPP_CLASS_GET_PROPERTY_FROM_NAME_EXPORT "il2cpp_class_get_property_from_name" 20 | #define IL2CPP_CLASS_GET_TYPE_EXPORT "il2cpp_class_get_type" 21 | #define IL2CPP_DOMAIN_GET_EXPORT "il2cpp_domain_get" 22 | #define IL2CPP_DOMAIN_GET_ASSEMBLIES_EXPORT "il2cpp_domain_get_assemblies" 23 | #define IL2CPP_FREE_EXPORT "il2cpp_free" 24 | #define IL2CPP_IMAGE_GET_CLASS_EXPORT "il2cpp_image_get_class" 25 | #define IL2CPP_IMAGE_GET_CLASS_COUNT_EXPORT "il2cpp_image_get_class_count" 26 | #define IL2CPP_RESOLVE_FUNC_EXPORT "il2cpp_resolve_icall" 27 | #define IL2CPP_STRING_NEW_EXPORT "il2cpp_string_new" 28 | #define IL2CPP_THREAD_ATTACH_EXPORT "il2cpp_thread_attach" 29 | #define IL2CPP_THREAD_DETACH_EXPORT "il2cpp_thread_detach" 30 | #define IL2CPP_TYPE_GET_OBJECT_EXPORT "il2cpp_type_get_object" 31 | 32 | // Calling Convention 33 | 34 | #ifdef _WIN64 35 | #define IL2CPP_CALLING_CONVENTION __fastcall* 36 | #elif _WIN32 37 | #define IL2CPP_CALLING_CONVENTION __cdecl* 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /src/il2cppresolver/Functions/Callback.cpp: -------------------------------------------------------------------------------- 1 | #include "../Includes.hpp" 2 | 3 | namespace IL2CPP 4 | { 5 | namespace Callback 6 | { 7 | struct _VFuncCallback 8 | { 9 | std::vector m_vFunctions; 10 | 11 | void** m_pVTable = nullptr; 12 | void* m_pOriginal = nullptr; 13 | }; 14 | 15 | namespace OnUpdate 16 | { 17 | _VFuncCallback Data; 18 | 19 | void Add(void* m_pFunction) { Data.m_vFunctions.emplace_back(m_pFunction); } 20 | 21 | void __fastcall Caller(void* rcx) 22 | { 23 | for (void* m_pFunction : Data.m_vFunctions) 24 | reinterpret_cast(m_pFunction)(); 25 | 26 | reinterpret_cast(Data.m_pOriginal)(rcx); 27 | } 28 | } 29 | 30 | namespace OnLateUpdate 31 | { 32 | _VFuncCallback Data; 33 | 34 | void Add(void* m_pFunction) { Data.m_vFunctions.emplace_back(m_pFunction); } 35 | 36 | void __fastcall Caller(void* rcx) 37 | { 38 | for (void* m_pFunction : Data.m_vFunctions) 39 | reinterpret_cast(m_pFunction)(); 40 | 41 | reinterpret_cast(Data.m_pOriginal)(rcx); 42 | } 43 | } 44 | 45 | void Replace_VFunc(void** m_pVTableFunc, void* m_pCaller, void** m_pCallbackOriginal) 46 | { 47 | DWORD m_dOldProtection = 0x0; 48 | if (m_pVTableFunc && VirtualProtect(m_pVTableFunc, sizeof(void*), PAGE_READWRITE, &m_dOldProtection)) 49 | { 50 | if (m_pCallbackOriginal) *m_pCallbackOriginal = *m_pVTableFunc; 51 | *m_pVTableFunc = m_pCaller; 52 | 53 | VirtualProtect(m_pVTableFunc, sizeof(void*), m_dOldProtection, &m_dOldProtection); 54 | } 55 | } 56 | 57 | void Initialize() 58 | { 59 | void* m_pThread = IL2CPP::Thread::Attach(IL2CPP::Domain::Get()); 60 | 61 | // Fetch 62 | { 63 | void** m_pMonoBehaviourVTable = *reinterpret_cast(IL2CPP::Helper::GetMonoBehaviour()->m_CachedPtr); 64 | if (m_pMonoBehaviourVTable) // x86: Hello my old friend :) 65 | { 66 | #ifdef _WIN64 67 | OnUpdate::Data.m_pVTable = VFunc::Find_ASM(m_pMonoBehaviourVTable, 99, { 0x33, 0xD2, 0xE9 }); // xor edx, edx | jmp 68 | OnLateUpdate::Data.m_pVTable = VFunc::Find_ASM(m_pMonoBehaviourVTable, 99, { 0xBA, 0x01, 0x00, 0x00, 0x00, 0xE9 }); // mov edx, 1 | jmp 69 | #elif _WIN32 70 | OnUpdate::Data.m_pVTable = VFunc::Find_ASM(m_pMonoBehaviourVTable, 99, { 0x6A, 0x00, 0xE8 }); // push 00 | call 71 | OnLateUpdate::Data.m_pVTable = VFunc::Find_ASM(m_pMonoBehaviourVTable, 99, { 0x6A, 0x01, 0xE8 }); // push 01 | call 72 | #endif 73 | } 74 | } 75 | 76 | IL2CPP::Thread::Detach(m_pThread); 77 | 78 | // Replace 79 | { 80 | Replace_VFunc(OnUpdate::Data.m_pVTable, OnUpdate::Caller, &OnUpdate::Data.m_pOriginal); 81 | Replace_VFunc(OnLateUpdate::Data.m_pVTable, OnLateUpdate::Caller, &OnLateUpdate::Data.m_pOriginal); 82 | } 83 | } 84 | 85 | void Uninitialize() 86 | { 87 | Replace_VFunc(OnUpdate::Data.m_pVTable, OnUpdate::Data.m_pOriginal, nullptr); 88 | Replace_VFunc(OnLateUpdate::Data.m_pVTable, OnLateUpdate::Data.m_pOriginal, nullptr); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/il2cppresolver/Functions/Callback.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace IL2CPP 4 | { 5 | namespace Callback 6 | { 7 | namespace OnUpdate 8 | { 9 | void Add(void* m_pFunction); 10 | } 11 | 12 | namespace OnLateUpdate 13 | { 14 | void Add(void* m_pFunction); 15 | } 16 | 17 | void Initialize(); 18 | 19 | void Uninitialize(); 20 | } 21 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Functions/Class.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace IL2CPP 4 | { 5 | namespace Class 6 | { 7 | Unity::il2cppFieldInfo* GetFields(Unity::il2cppClass* m_pClass, void** m_pIterator); 8 | 9 | void FetchFields(Unity::il2cppClass* m_pClass, std::vector* m_pVector, void* m_pFieldIterator = nullptr); 10 | 11 | Unity::il2cppPropertyInfo* GetProperties(Unity::il2cppClass* m_pClass, void** m_pIterator); 12 | 13 | void FetchProperties(Unity::il2cppClass* m_pClass, std::vector* m_pVector, void* m_pPropertiesIterator = nullptr); 14 | 15 | Unity::il2cppMethodInfo* GetMethods(Unity::il2cppClass* m_pClass, void** m_pIterator); 16 | 17 | void FetchMethods(Unity::il2cppClass* m_pClass, std::vector* m_pVector, void* m_pMethodIterator = nullptr); 18 | 19 | Unity::il2cppType* GetType(Unity::il2cppClass* m_pClass); 20 | 21 | Unity::il2cppObject* GetSystemType(Unity::il2cppClass* m_pClass); 22 | 23 | Unity::il2cppObject* GetSystemType(const char* m_pClassName); 24 | 25 | Unity::il2cppClass* GetFromName(Unity::il2cppImage* m_pImage, const char* m_pNamespace, const char* m_pName); 26 | 27 | Unity::il2cppClass* Find(const char* m_pName); 28 | 29 | /* 30 | * If you wanna fetch modules with custom classes use modulename: Assembly-CSharp 31 | * Nullptr namespace == pass any namespace 32 | */ 33 | void FetchClasses(std::vector* m_pVector, const char* m_pModuleName, const char* m_pNamespace); 34 | 35 | namespace Utils 36 | { 37 | int GetFieldOffset(Unity::il2cppClass* m_pClass, const char* m_pName); 38 | 39 | int GetFieldOffset(const char* m_pClassName, const char* m_pName); 40 | 41 | void* GetMethodPointer(Unity::il2cppClass* m_pClass, const char* m_pMethodName, int m_iArgs = -1); 42 | 43 | void* GetMethodPointer(const char* m_pClassName, const char* m_pMethodName, int m_iArgs = -1); 44 | 45 | /* 46 | * Usage: 47 | * m_vNames = { "arg1" , "arg2" , ... } 48 | */ 49 | void* GetMethodPointer(const char* m_pClassName, const char* m_pMethodName, std::initializer_list m_vNames); 50 | 51 | 52 | /* 53 | * Name Prefixes 54 | * (Field) ~ 55 | * (Method) - 56 | */ 57 | Unity::il2cppClass* FilterClass(std::vector* m_pClasses, std::initializer_list m_vNames, int m_iFoundCount = -1); 58 | 59 | void* FilterClassToMethodPointer(std::vector* m_pClasses, const char* m_pMethodName, int m_iArgs = -1); 60 | } 61 | } 62 | 63 | enum class m_eClassPropType : int 64 | { 65 | Unknown = 0, 66 | Field, // Member of class that can be accessed directly by RVA 67 | Property, // Member of class that can be accessed by calling function 68 | Method, // Function of class 69 | }; 70 | 71 | class CClass 72 | { 73 | public: 74 | Unity::il2cppObject m_Object = { 0 }; 75 | void* m_CachedPtr = nullptr; 76 | 77 | // Wrappers for namespace, ah... 78 | Unity::il2cppFieldInfo* GetFields(void** m_pIterator) 79 | { 80 | return Class::GetFields(m_Object.m_pClass, m_pIterator); 81 | } 82 | 83 | void FetchFields(std::vector* m_pVector, void* m_pFieldIterator = nullptr) 84 | { 85 | Class::FetchFields(m_Object.m_pClass, m_pVector, m_pFieldIterator); 86 | } 87 | 88 | Unity::il2cppMethodInfo* GetMethods(void** m_pIterator) 89 | { 90 | return Class::GetMethods(m_Object.m_pClass, m_pIterator); 91 | } 92 | 93 | void FetchMethods(std::vector* m_pVector, void* m_pMethodIterator = nullptr) 94 | { 95 | Class::FetchMethods(m_Object.m_pClass, m_pVector, m_pMethodIterator); 96 | } 97 | 98 | void* GetMethodPointer(const char* m_pMethodName, int m_iArgs = -1) 99 | { 100 | return Class::Utils::GetMethodPointer(m_Object.m_pClass, m_pMethodName, m_iArgs); 101 | } 102 | 103 | m_eClassPropType GetPropType(const char* m_pPropType) 104 | { 105 | Unity::il2cppFieldInfo* pField = reinterpret_cast(Data.Functions.m_pClassGetFieldFromName)(m_Object.m_pClass, m_pPropType); 106 | if (pField) 107 | return m_eClassPropType::Field; 108 | 109 | Unity::il2cppPropertyInfo* pProperty = reinterpret_cast(Data.Functions.m_pClassGetPropertyFromName)(m_Object.m_pClass, m_pPropType); 110 | if (pProperty) 111 | return m_eClassPropType::Property; 112 | 113 | Unity::il2cppMethodInfo* pMethod = reinterpret_cast(Data.Functions.m_pClassGetMethodFromName)(m_Object.m_pClass, m_pPropType, -1); 114 | if (pMethod) 115 | return m_eClassPropType::Method; 116 | 117 | return m_eClassPropType::Unknown; 118 | } 119 | 120 | // Call Method 121 | template 122 | TReturn CallMethod(void* m_pMethod, TArgs... tArgs) { return reinterpret_cast(m_pMethod)(this, tArgs...); } 123 | 124 | template 125 | TReturn CallMethod(const char* m_pMethodName, TArgs... tArgs) { return CallMethod(GetMethodPointer(m_pMethodName), tArgs...); } 126 | 127 | template 128 | TReturn CallMethodSafe(void* m_pMethod, TArgs... tArgs) 129 | { 130 | if (!m_pMethod) 131 | { 132 | #ifdef _DEBUG 133 | __debugbreak(); // remove it when you wanna step through your code and be like why the fuck it doesn't do anything. 134 | #endif 135 | 136 | TReturn m_tDefault = {}; // void goes like illegal use of type. (use void* and fuck them) 137 | return m_tDefault; 138 | } 139 | 140 | return CallMethod(m_pMethod, tArgs...); 141 | } 142 | 143 | template 144 | TReturn CallMethodSafe(const char* m_pMethodName, TArgs... tArgs) { return CallMethodSafe(GetMethodPointer(m_pMethodName), tArgs...); } 145 | 146 | // Properties/Fields 147 | 148 | template 149 | T GetPropertyValue(const char* m_pPropertyName) 150 | { 151 | Unity::il2cppPropertyInfo* pProperty = reinterpret_cast(Data.Functions.m_pClassGetPropertyFromName)(m_Object.m_pClass, m_pPropertyName); 152 | if (pProperty && pProperty->m_pGet) 153 | return reinterpret_cast(pProperty->m_pGet->m_pMethodPointer)(this); 154 | 155 | T tDefault = {}; 156 | return tDefault; 157 | } 158 | 159 | template 160 | void SetPropertyValue(const char* m_pPropertyName, T m_tValue) 161 | { 162 | Unity::il2cppPropertyInfo* pProperty = reinterpret_cast(Data.Functions.m_pClassGetPropertyFromName)(m_Object.m_pClass, m_pPropertyName); 163 | if (pProperty && pProperty->m_pSet) 164 | return reinterpret_cast(pProperty->m_pSet->m_pMethodPointer)(this, m_tValue); 165 | } 166 | 167 | template 168 | __inline T GetMemberValue(int m_iOffset) 169 | { 170 | return *reinterpret_cast(reinterpret_cast(this) + m_iOffset); 171 | } 172 | 173 | template 174 | __inline void SetMemberValue(int m_iOffset, T m_tValue) 175 | { 176 | *reinterpret_cast(reinterpret_cast(this) + m_iOffset) = m_tValue; 177 | } 178 | 179 | template 180 | __inline T GetMemberValue(Unity::il2cppFieldInfo* m_pField) 181 | { 182 | if (!m_pField || 0 > m_pField->m_iOffset) 183 | { 184 | T m_tDefault = {}; 185 | return m_tDefault; 186 | } 187 | 188 | return GetMemberValue(m_pField->m_iOffset); 189 | } 190 | 191 | template 192 | __inline void SetMemberValue(Unity::il2cppFieldInfo* m_pField, T m_tValue) 193 | { 194 | if (!m_pField || 0 > m_pField->m_iOffset) 195 | return; 196 | 197 | SetMemberValue(m_pField->m_iOffset, m_tValue); 198 | } 199 | 200 | template 201 | T GetMemberValue(const char* m_pMemberName) 202 | { 203 | Unity::il2cppFieldInfo* pField = reinterpret_cast(Data.Functions.m_pClassGetFieldFromName)(m_Object.m_pClass, m_pMemberName); 204 | if (pField) 205 | { 206 | if (pField->m_iOffset >= 0) return *reinterpret_cast(reinterpret_cast(this) + pField->m_iOffset); 207 | } 208 | else 209 | return GetPropertyValue(m_pMemberName); 210 | 211 | T tDefault = {}; 212 | return tDefault; 213 | } 214 | 215 | template 216 | void SetMemberValue(const char* m_pMemberName, T m_tValue) 217 | { 218 | Unity::il2cppFieldInfo* pField = reinterpret_cast(Data.Functions.m_pClassGetFieldFromName)(m_Object.m_pClass, m_pMemberName); 219 | if (pField) 220 | { 221 | if (pField->m_iOffset >= 0) *reinterpret_cast(reinterpret_cast(this) + pField->m_iOffset) = m_tValue; 222 | return; 223 | } 224 | 225 | SetPropertyValue(m_pMemberName, m_tValue); 226 | } 227 | 228 | template 229 | __inline T GetObscuredViaOffset(int m_iOffset) 230 | { 231 | if (m_iOffset >= 0) 232 | { 233 | switch (sizeof(T)) 234 | { 235 | case sizeof(double): 236 | { 237 | long long m_lKey = *reinterpret_cast(reinterpret_cast(this) + m_iOffset); 238 | long long m_lValue = *reinterpret_cast(reinterpret_cast(this) + m_iOffset + sizeof(m_lKey)); 239 | 240 | m_lValue ^= m_lKey; 241 | return *reinterpret_cast(&m_lValue); 242 | } 243 | break; 244 | case sizeof(int): 245 | { 246 | int m_iKey = *reinterpret_cast(reinterpret_cast(this) + m_iOffset); 247 | int m_iValue = *reinterpret_cast(reinterpret_cast(this) + m_iOffset + sizeof(m_iKey)); 248 | 249 | m_iValue ^= m_iKey; 250 | return *reinterpret_cast(&m_iValue); 251 | } 252 | break; 253 | case sizeof(bool): 254 | { 255 | unsigned char m_uKey = *reinterpret_cast(reinterpret_cast(this) + m_iOffset); 256 | int m_iValue = *reinterpret_cast(reinterpret_cast(this) + m_iOffset + sizeof(m_uKey)); 257 | 258 | m_iValue ^= m_uKey; 259 | return *reinterpret_cast(&m_iValue); 260 | } 261 | break; 262 | } 263 | } 264 | 265 | T m_tDefault = { 0 }; 266 | return m_tDefault; 267 | } 268 | 269 | template 270 | T GetObscuredValue(const char* m_pMemberName) 271 | { 272 | Unity::il2cppFieldInfo* m_pField = reinterpret_cast(Data.Functions.m_pClassGetFieldFromName)(m_Object.m_pClass, m_pMemberName); 273 | return GetObscuredViaOffset(m_pField ? m_pField->m_iOffset : -1); 274 | } 275 | 276 | template 277 | __inline void SetObscuredViaOffset(int m_iOffset, T m_tValue) 278 | { 279 | if (0 > m_iOffset) 280 | return; 281 | 282 | switch (sizeof(T)) 283 | { 284 | case sizeof(double): 285 | { 286 | long long m_lKey = *reinterpret_cast(reinterpret_cast(this) + m_iOffset); 287 | long long* m_pValue = reinterpret_cast(reinterpret_cast(this) + m_iOffset + sizeof(m_lKey)); 288 | 289 | *m_pValue = *reinterpret_cast(&m_tValue) ^ m_lKey; 290 | } 291 | break; 292 | case sizeof(int): 293 | { 294 | int m_iKey = *reinterpret_cast(reinterpret_cast(this) + m_iOffset); 295 | int* m_pValue = reinterpret_cast(reinterpret_cast(this) + m_iOffset + sizeof(m_iKey)); 296 | 297 | *m_pValue = *reinterpret_cast(&m_tValue) ^ m_iKey; 298 | } 299 | break; 300 | case sizeof(bool): 301 | { 302 | unsigned char m_uKey = *reinterpret_cast(reinterpret_cast(this) + m_iOffset); 303 | int* m_pValue = reinterpret_cast(reinterpret_cast(this) + m_iOffset + sizeof(m_uKey)); 304 | 305 | *m_pValue = *reinterpret_cast(&m_tValue) ^ m_uKey; 306 | } 307 | break; 308 | } 309 | } 310 | 311 | template 312 | void SetObscuredValue(const char* m_pMemberName, T m_tValue) 313 | { 314 | Unity::il2cppFieldInfo* m_pField = reinterpret_cast(Data.Functions.m_pClassGetFieldFromName)(m_Object.m_pClass, m_pMemberName); 315 | if (!m_pField) 316 | return; 317 | 318 | SetObscuredViaOffset(m_pField->m_iOffset, m_tValue); 319 | } 320 | }; 321 | } 322 | -------------------------------------------------------------------------------- /src/il2cppresolver/Functions/Domain.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace IL2CPP 4 | { 5 | namespace Domain 6 | { 7 | static void* Get() 8 | { 9 | return reinterpret_cast(Data.Functions.m_pDomainGet)(); 10 | } 11 | 12 | static Unity::il2cppAssembly** GetAssemblies(size_t* m_pSize) 13 | { 14 | return reinterpret_cast(Data.Functions.m_pDomainGetAssemblies)(Get(), m_pSize); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Functions/ResolveCall.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace IL2CPP 4 | { 5 | // Without this function, you're pretty much fucked up. 6 | static void* ResolveCall(const char* m_pName) 7 | { 8 | return reinterpret_cast(Data.Functions.m_pResolveFunction)(m_pName); 9 | } 10 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Functions/String.cpp: -------------------------------------------------------------------------------- 1 | #include "../Includes.hpp" 2 | #include 3 | 4 | namespace IL2CPP 5 | { 6 | namespace String 7 | { 8 | Unity::System_String* New(const char* m_pString) 9 | { 10 | return reinterpret_cast(Data.Functions.m_pStringNew)(m_pString); // return reinterpret_cast(Data.Functions.m_pStringNew)(m_pString); 11 | } 12 | 13 | Unity::System_String* New(std::string m_sString) { return New(&m_sString[0]); } 14 | 15 | namespace NoGC 16 | { 17 | Unity::System_String* New(const char* m_pString) 18 | { 19 | Unity::System_String* m_pNew = new Unity::System_String; 20 | m_pNew->m_pClass = IL2CPP::Class::Find("System.String"); 21 | m_pNew->m_iLength = swprintf_s(m_pNew->m_wString, (sizeof(Unity::System_String::m_wString) / 4), L"%hs", m_pString); 22 | 23 | return m_pNew; 24 | } 25 | 26 | Unity::System_String* New(std::string m_sString) { return New(&m_sString[0]); } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Functions/String.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace IL2CPP 4 | { 5 | namespace String 6 | { 7 | Unity::System_String* New(const char* m_pString); 8 | 9 | Unity::System_String* New(std::string m_sString); 10 | 11 | // Make sure to delete it after you done using it. 12 | namespace NoGC 13 | { 14 | Unity::System_String* New(const char* m_pString); 15 | 16 | Unity::System_String* New(std::string m_sString); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Functions/Thread.cpp: -------------------------------------------------------------------------------- 1 | #include "../Includes.hpp" 2 | 3 | namespace IL2CPP 4 | { 5 | DWORD __stdcall ThreadHandler(void* pReserved) 6 | { 7 | void* m_pIL2CPPThread = Thread::Attach(Domain::Get()); 8 | 9 | CThread* m_pThread = reinterpret_cast(pReserved); 10 | void* m_pThreadStart = m_pThread->m_pThreadOnStart; 11 | void* m_pThreadEnd = m_pThread->m_pThreadOnEnd; 12 | delete m_pThread; 13 | 14 | reinterpret_cast(m_pThreadStart)(); 15 | if (m_pThreadEnd) 16 | reinterpret_cast(m_pThreadEnd)(); 17 | 18 | Thread::Detach(m_pIL2CPPThread); 19 | return 0x0; 20 | } 21 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Functions/Thread.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace IL2CPP 4 | { 5 | DWORD __stdcall ThreadHandler(void* pReserved); 6 | 7 | class CThread 8 | { 9 | public: 10 | void* m_pThreadOnStart = nullptr; 11 | void* m_pThreadOnEnd = nullptr; 12 | 13 | CThread() { /* Why would you even do this? */ } 14 | CThread(void* m_pOnStart, void* m_pOnEnd) 15 | { 16 | m_pThreadOnStart = m_pOnStart; 17 | m_pThreadOnEnd = m_pOnEnd; 18 | 19 | if (!m_pThreadOnStart) 20 | { 21 | IL2CPP_ASSERT("IL2CPP::CThread - m_pThreadOnStart is nullptr"); 22 | return; 23 | } 24 | 25 | CreateThread(0, 0, ThreadHandler, this, 0, 0); 26 | } 27 | }; 28 | 29 | namespace Thread 30 | { 31 | static void Create(void* m_pOnStart, void* m_pOnEnd = nullptr) 32 | { 33 | CThread* pThread = new CThread(m_pOnStart, m_pOnEnd); 34 | IL2CPP_ASSERT(pThread && "IL2CPP::Thread::Create - Failed!"); 35 | } 36 | 37 | static void* Attach(void* m_pDomain) 38 | { 39 | return reinterpret_cast(IL2CPP::Data.Functions.m_pThreadAttach)(m_pDomain); 40 | } 41 | 42 | static void Detach(void* m_pThread) 43 | { 44 | reinterpret_cast(IL2CPP::Data.Functions.m_pThreadDetach)(m_pThread); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Il2CppResolver.cpp: -------------------------------------------------------------------------------- 1 | #include "Il2CppResolver.hpp" 2 | 3 | namespace IL2CPP 4 | { 5 | bool Initialize(bool m_bWaitForModule) 6 | { 7 | if (m_bWaitForModule) 8 | { 9 | while (!Data.m_hGameAseembly) 10 | { 11 | Data.m_hGameAseembly = GetModuleHandleA(IL2CPP_MAIN_MODULE); 12 | Sleep(1000); // Prevent high CPU usage! 13 | } 14 | } 15 | else 16 | { 17 | Data.m_hGameAseembly = GetModuleHandleA(IL2CPP_MAIN_MODULE); 18 | if (!Data.m_hGameAseembly) return false; 19 | } 20 | 21 | if (!UnityAPI::Initialize()) return false; 22 | 23 | return true; 24 | } 25 | 26 | namespace UnityAPI 27 | { 28 | m_eExportObfuscationType m_ExportObfuscation = m_eExportObfuscationType::None; 29 | int m_iROTObfuscationValue = -1; 30 | 31 | void* ResolveExport(const char* m_pName) 32 | { 33 | switch (m_ExportObfuscation) 34 | { 35 | case m_eExportObfuscationType::ROT: 36 | { 37 | if (m_iROTObfuscationValue == -1) // Bruteforce 38 | { 39 | for (int i = 1; 26 > i; ++i) 40 | { 41 | void* pReturn = GetProcAddress(Data.m_hGameAseembly, &Unity::Obfuscators::ROT_String(m_pName, i)[0]); 42 | if (pReturn) 43 | { 44 | m_iROTObfuscationValue = i; 45 | return pReturn; 46 | } 47 | } 48 | 49 | return nullptr; 50 | } 51 | 52 | return GetProcAddress(Data.m_hGameAseembly, &Unity::Obfuscators::ROT_String(m_pName, m_iROTObfuscationValue)[0]); 53 | } 54 | default: return GetProcAddress(Data.m_hGameAseembly, m_pName); 55 | } 56 | 57 | return nullptr; 58 | } 59 | 60 | bool ResolveExport_Boolean(void** m_pAddress, const char* m_pName) 61 | { 62 | *m_pAddress = ResolveExport(m_pName); 63 | IL2CPP_ASSERT(*m_pAddress != nullptr && "Couldn't resolve export!"); 64 | return *m_pAddress != nullptr; 65 | } 66 | 67 | bool Initialize() 68 | { 69 | bool m_bInitExportResolved = false; 70 | for (int i = 0; m_eExportObfuscationType::MAX > i; ++i) 71 | { 72 | m_ExportObfuscation = static_cast(i); 73 | if (ResolveExport(IL2CPP_INIT_EXPORT)) 74 | { 75 | m_bInitExportResolved = true; 76 | break; 77 | } 78 | } 79 | 80 | IL2CPP_ASSERT(m_bInitExportResolved && "Couldn't resolve il2cpp_init!"); 81 | if (!m_bInitExportResolved) return false; 82 | 83 | std::unordered_map m_uExports = 84 | { 85 | { IL2CPP_CLASS_FROM_NAME_EXPORT, &Data.Functions.m_pClassFromName }, 86 | { IL2CPP_CLASS_GET_FIELDS, &Data.Functions.m_pClassGetFields }, 87 | { IL2CPP_CLASS_GET_FIELD_FROM_NAME_EXPORT, &Data.Functions.m_pClassGetFieldFromName }, 88 | { IL2CPP_CLASS_GET_METHODS, &Data.Functions.m_pClassGetMethods }, 89 | { IL2CPP_CLASS_GET_METHOD_FROM_NAME_EXPORT, &Data.Functions.m_pClassGetMethodFromName }, 90 | { IL2CPP_CLASS_GET_PROPERTIES, &Data.Functions.m_pClassGetProperties }, // +++++++++++ 91 | { IL2CPP_CLASS_GET_PROPERTY_FROM_NAME_EXPORT, &Data.Functions.m_pClassGetPropertyFromName }, 92 | { IL2CPP_CLASS_GET_TYPE_EXPORT, &Data.Functions.m_pClassGetType }, 93 | { IL2CPP_DOMAIN_GET_EXPORT, &Data.Functions.m_pDomainGet }, 94 | { IL2CPP_DOMAIN_GET_ASSEMBLIES_EXPORT, &Data.Functions.m_pDomainGetAssemblies }, 95 | { IL2CPP_FREE_EXPORT, &Data.Functions.m_pFree }, 96 | { IL2CPP_IMAGE_GET_CLASS_EXPORT, &Data.Functions.m_pImageGetClass }, 97 | { IL2CPP_IMAGE_GET_CLASS_COUNT_EXPORT, &Data.Functions.m_pImageGetClassCount }, 98 | { IL2CPP_RESOLVE_FUNC_EXPORT, &Data.Functions.m_pResolveFunction }, 99 | { IL2CPP_STRING_NEW_EXPORT, &Data.Functions.m_pStringNew }, 100 | { IL2CPP_THREAD_ATTACH_EXPORT, &Data.Functions.m_pThreadAttach }, 101 | { IL2CPP_THREAD_DETACH_EXPORT, &Data.Functions.m_pThreadDetach }, 102 | { IL2CPP_TYPE_GET_OBJECT_EXPORT, &Data.Functions.m_pTypeGetObject }, 103 | }; 104 | 105 | for (std::pair m_pExport : m_uExports) 106 | { 107 | if (!ResolveExport_Boolean(m_pExport.second, m_pExport.first)) 108 | return false; 109 | } 110 | 111 | // Unity APIs 112 | Unity::Camera::Initialize(); 113 | Unity::Component::Initialize(); 114 | Unity::GameObject::Initialize(); 115 | Unity::LayerMask::Initialize(); 116 | Unity::Object::Initialize(); 117 | Unity::RigidBody::Initialize(); 118 | Unity::Transform::Initialize(); 119 | 120 | // Caches 121 | IL2CPP::SystemTypeCache::Initializer::PreCache(); 122 | 123 | return true; 124 | } 125 | } 126 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Il2CppResolver.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Includes.hpp" 3 | 4 | namespace IL2CPP 5 | { 6 | /* Must be called once before using any other functions! 7 | * Args: 8 | * bWaitForModule: (Wait for GameAssembly - can result in infinite loop!) 9 | */ 10 | bool Initialize(bool m_bWaitForModule = false); 11 | 12 | namespace UnityAPI 13 | { 14 | enum m_eExportObfuscationType 15 | { 16 | None = 0, 17 | ROT = 1, 18 | MAX = 2, 19 | }; 20 | 21 | extern m_eExportObfuscationType m_ExportObfuscation; 22 | 23 | void* ResolveExport(const char* m_pName); 24 | 25 | bool Initialize(); 26 | } 27 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Includes.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | // Disable Asserts 3 | // #define IL2CPP_ASSERT(x) ((void)(x)) 4 | #include "Defines.hpp" 5 | 6 | #define _USE_MATH_DEFINES 7 | #include 8 | #include 9 | #include 10 | #define WIN32_LEAN_AND_MEAN 11 | #include 12 | #include 13 | 14 | // Unity 15 | #include "Unity/Includes.hpp" 16 | 17 | // IL2CPP API 18 | #include "Data.hpp" // Pointers, Variables, etc... 19 | #include "Cache.hpp" 20 | 21 | // IL2CPP 22 | #include "Functions/Callback.hpp" 23 | #include "Functions/Class.hpp" 24 | #include "Functions/Domain.hpp" 25 | #include "Functions/ResolveCall.hpp" 26 | #include "Functions/String.hpp" 27 | #include "Functions/Thread.hpp" 28 | 29 | // Unity API - Include here so we have access to some cute IL2CPP Features 30 | #include "Unity/API/_TEMPLATE_API.hpp" 31 | #include "Unity/API/Object.hpp" 32 | #include "Unity/API/Component.hpp" 33 | #include "Unity/API/GameObject.hpp" 34 | #include "Unity/API/Camera.hpp" 35 | #include "Unity/API/LayerMask.hpp" 36 | #include "Unity/API/Rigidbody.hpp" 37 | #include "Unity/API/Transform.hpp" 38 | 39 | // Utils 40 | #include "Utils/Helper.hpp" 41 | #include "Utils/Joaat.hpp" 42 | #include "Utils/VFunc.hpp" -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/API/Camera.cpp: -------------------------------------------------------------------------------- 1 | #include "../../Includes.hpp" 2 | 3 | namespace Unity 4 | { 5 | SCameraFunctions CameraFunctions; 6 | 7 | namespace Camera 8 | { 9 | void Initialize() 10 | { 11 | IL2CPP::SystemTypeCache::Initializer::Add(UNITY_CAMERA_CLASS); 12 | 13 | CameraFunctions.m_pGetCurrent = IL2CPP::ResolveCall(UNITY_CAMERA_GETCURRENT); 14 | CameraFunctions.m_pGetMain = IL2CPP::ResolveCall(UNITY_CAMERA_GETMAIN); 15 | CameraFunctions.m_pGetDepth = IL2CPP::ResolveCall(UNITY_CAMERA_GETDEPTH); 16 | CameraFunctions.m_pSetDepth = IL2CPP::ResolveCall(UNITY_CAMERA_SETDEPTH); 17 | CameraFunctions.m_pGetFieldOfView = IL2CPP::ResolveCall(UNITY_CAMERA_GETFIELDOFVIEW); 18 | CameraFunctions.m_pSetFieldOfView = IL2CPP::ResolveCall(UNITY_CAMERA_SETFIELDOFVIEW); 19 | CameraFunctions.m_pWorldToScreen = IL2CPP::ResolveCall(UNITY_CAMERA_WORLDTOSCREEN); 20 | } 21 | 22 | CCamera* GetCurrent() 23 | { 24 | return reinterpret_cast(CameraFunctions.m_pGetCurrent)(); 25 | } 26 | 27 | CCamera* GetMain() 28 | { 29 | return reinterpret_cast(CameraFunctions.m_pGetMain)(); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/API/Camera.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Unity 4 | { 5 | struct SCameraFunctions 6 | { 7 | void* m_pGetCurrent = nullptr; 8 | void* m_pGetMain = nullptr; 9 | void* m_pGetDepth = nullptr; 10 | void* m_pSetDepth = nullptr; 11 | void* m_pGetFieldOfView = nullptr; 12 | void* m_pSetFieldOfView = nullptr; 13 | void* m_pWorldToScreen = nullptr; 14 | }; 15 | extern SCameraFunctions CameraFunctions; 16 | 17 | class CCamera : public CGameObject 18 | { 19 | public: 20 | float GetDepth() 21 | { 22 | return reinterpret_cast(CameraFunctions.m_pGetDepth)(this); 23 | } 24 | 25 | void SetDepth(float m_fValue) 26 | { 27 | reinterpret_cast(CameraFunctions.m_pSetDepth)(this, m_fValue); 28 | } 29 | 30 | float GetFieldOfView() 31 | { 32 | return reinterpret_cast(CameraFunctions.m_pGetFieldOfView)(this); 33 | } 34 | 35 | void SetFieldOfView(float m_fValue) 36 | { 37 | reinterpret_cast(CameraFunctions.m_pSetFieldOfView)(this, m_fValue); 38 | } 39 | 40 | void WorldToScreen(Vector3& m_vWorld, Vector3& m_vScreen, int m_iEye = 2) 41 | { 42 | reinterpret_cast(CameraFunctions.m_pWorldToScreen)(this, m_vWorld, m_iEye, m_vScreen); 43 | } 44 | }; 45 | 46 | namespace Camera 47 | { 48 | void Initialize(); 49 | 50 | CCamera* GetCurrent(); 51 | 52 | CCamera* GetMain(); 53 | } 54 | 55 | enum m_eCameraType : int 56 | { 57 | m_eCameraType_Game = 1, 58 | m_eCameraType_SceneView = 2, 59 | m_eCameraType_Preview = 4, 60 | m_eCameraType_VR = 8, 61 | m_eCameraType_Reflection = 16, 62 | }; 63 | 64 | enum m_eCameraEye : int 65 | { 66 | m_eCameraEye_Left = 0, 67 | m_eCameraEye_Right = 1, 68 | m_eCameraEye_Center = 2, 69 | }; 70 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/API/Component.cpp: -------------------------------------------------------------------------------- 1 | #include "../../Includes.hpp" 2 | 3 | namespace Unity 4 | { 5 | SComponentFunctions ComponentFunctions; 6 | 7 | namespace Component 8 | { 9 | void Initialize() 10 | { 11 | IL2CPP::SystemTypeCache::Initializer::Add(UNITY_COMPONENT_CLASS); 12 | 13 | ComponentFunctions.m_pGetGameObject = IL2CPP::ResolveCall(UNITY_COMPONENT_GETGAMEOBJECT); 14 | ComponentFunctions.m_pGetTransform = IL2CPP::ResolveCall(UNITY_COMPONENT_GETTRANSFORM); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/API/Component.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Unity 4 | { 5 | struct SComponentFunctions 6 | { 7 | void* m_pGetGameObject = nullptr; 8 | void* m_pGetTransform = nullptr; 9 | }; 10 | extern SComponentFunctions ComponentFunctions; 11 | 12 | class CComponent : public CObject 13 | { 14 | public: 15 | CGameObject* GetGameObject() 16 | { 17 | return reinterpret_cast(ComponentFunctions.m_pGetGameObject)(this); 18 | } 19 | 20 | CTransform* GetTransform() 21 | { 22 | return reinterpret_cast(ComponentFunctions.m_pGetTransform)(this); 23 | } 24 | }; 25 | 26 | namespace Component 27 | { 28 | void Initialize(); 29 | } 30 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/API/GameObject.cpp: -------------------------------------------------------------------------------- 1 | #include "../../Includes.hpp" 2 | 3 | namespace Unity 4 | { 5 | SGameObjectFunctions GameObjectFunctions; 6 | 7 | namespace GameObject 8 | { 9 | void Initialize() 10 | { 11 | IL2CPP::SystemTypeCache::Initializer::Add(UNITY_GAMEOBJECT_CLASS); 12 | 13 | GameObjectFunctions.m_pAddComponent = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_ADDCOMPONENT); 14 | GameObjectFunctions.m_pCreatePrimitive = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_CREATEPRIMITIVE); 15 | GameObjectFunctions.m_pFind = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_FIND); 16 | GameObjectFunctions.m_pFindGameObjectsWithTag = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_FINDGAMEOBJECTWITHTAG); 17 | GameObjectFunctions.m_pGetComponent = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_GETCOMPONENT); 18 | GameObjectFunctions.m_pGetComponents = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_GETCOMPONENTS); 19 | GameObjectFunctions.m_pGetComponentInChildren = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_GETCOMPONENTINCHILDREN); 20 | GameObjectFunctions.m_pGetActive = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_GETACTIVE); 21 | GameObjectFunctions.m_pGetLayer = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_GETLAYER); 22 | GameObjectFunctions.m_pGetTransform = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_GETTRANSFORM); 23 | GameObjectFunctions.m_pSetActive = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_SETACTIVE); 24 | GameObjectFunctions.m_pSetLayer = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_SETLAYER); 25 | } 26 | 27 | CGameObject* CreatePrimitive(m_ePrimitiveType m_eType) 28 | { 29 | return reinterpret_cast(GameObjectFunctions.m_pCreatePrimitive)(m_eType); 30 | } 31 | 32 | CGameObject* Find(const char* m_pName) 33 | { 34 | return reinterpret_cast(GameObjectFunctions.m_pFind)(IL2CPP::String::New(m_pName)); 35 | } 36 | 37 | il2cppArray* FindWithTag(const char* m_pTag) 38 | { 39 | return reinterpret_cast*(UNITY_CALLING_CONVENTION)(void*)>(GameObjectFunctions.m_pFindGameObjectsWithTag)(IL2CPP::String::New(m_pTag)); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/API/GameObject.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Unity 4 | { 5 | struct SGameObjectFunctions 6 | { 7 | void* m_pAddComponent = nullptr; 8 | void* m_pCreatePrimitive = nullptr; 9 | void* m_pFind = nullptr; 10 | void* m_pFindGameObjectsWithTag = nullptr; 11 | void* m_pGetComponent = nullptr; 12 | void* m_pGetComponents = nullptr; 13 | void* m_pGetComponentInChildren = nullptr; 14 | void* m_pGetActive = nullptr; 15 | void* m_pGetLayer = nullptr; 16 | void* m_pGetTransform = nullptr; 17 | void* m_pSetActive = nullptr; 18 | void* m_pSetLayer = nullptr; 19 | }; 20 | extern SGameObjectFunctions GameObjectFunctions; 21 | 22 | class CGameObject : public CObject 23 | { 24 | public: 25 | void AddComponent(il2cppObject* m_pSystemType) 26 | { 27 | reinterpret_cast(GameObjectFunctions.m_pAddComponent)(this, m_pSystemType); 28 | } 29 | 30 | CComponent* GetComponent(const char* m_pName) 31 | { 32 | return reinterpret_cast(GameObjectFunctions.m_pGetComponent)(this, IL2CPP::String::New(m_pName)); 33 | } 34 | 35 | CComponent* GetComponentInChildren(il2cppObject* m_pSystemType, bool includeInactive) 36 | { 37 | return reinterpret_cast(GameObjectFunctions.m_pGetComponentInChildren)(this, m_pSystemType, includeInactive); 38 | } 39 | 40 | // e.g CGameObject->GetComponentInChildren("Namespace.Component"); 41 | CComponent* GetComponentInChildren(const char* type) 42 | { 43 | il2cppClass* m_pClass = IL2CPP::Class::Find(type); 44 | if (!m_pClass) return nullptr; 45 | 46 | return GetComponentInChildren(IL2CPP::Class::GetSystemType(type), true); 47 | } 48 | 49 | il2cppArray* GetComponents(il2cppObject* m_pSystemType) 50 | { 51 | /* 52 | 0 - Object 53 | 1 - Type 54 | 2 - Use search type as array return type 55 | 3 - Recursive 56 | 4 - Include inactive 57 | 5 - Reverse 58 | 6 - Result list 59 | */ 60 | return reinterpret_cast*(UNITY_CALLING_CONVENTION)(void*, void*, bool, bool, bool, bool, void*)>(GameObjectFunctions.m_pGetComponents)(this, m_pSystemType, false, false, true, false, nullptr); 61 | } 62 | 63 | il2cppArray* GetComponents(const char* m_pSystemTypeName) 64 | { 65 | il2cppClass* m_pClass = IL2CPP::Class::Find(m_pSystemTypeName); 66 | if (!m_pClass) return nullptr; 67 | 68 | return GetComponents(IL2CPP::Class::GetSystemType(m_pClass)); 69 | } 70 | 71 | CComponent* GetComponentByIndex(il2cppObject* m_pSystemType, unsigned int m_uIndex = 0U) 72 | { 73 | il2cppArray* m_pComponents = GetComponents(m_pSystemType); 74 | if (!m_pComponents || m_uIndex >= m_pComponents->m_uMaxLength) return nullptr; 75 | 76 | return m_pComponents->operator[](m_uIndex); 77 | } 78 | 79 | CComponent* GetComponentByIndex(const char* m_pSystemTypeName, unsigned int m_uIndex = 0U) 80 | { 81 | il2cppClass* m_pClass = IL2CPP::Class::Find(m_pSystemTypeName); 82 | if (!m_pClass) return nullptr; 83 | 84 | return GetComponentByIndex(IL2CPP::Class::GetSystemType(m_pClass), m_uIndex); 85 | } 86 | 87 | CTransform* GetTransform() 88 | { 89 | return reinterpret_cast(GameObjectFunctions.m_pGetTransform)(this); 90 | } 91 | 92 | bool GetActive() 93 | { 94 | return reinterpret_cast(GameObjectFunctions.m_pGetActive)(this); 95 | } 96 | 97 | unsigned int GetLayer() 98 | { 99 | return reinterpret_cast(GameObjectFunctions.m_pGetLayer)(this); 100 | } 101 | 102 | /* 103 | * (WARNING) when you use GameObject::Find and you set the object to unactive, you won't find it anymore with that slow function. 104 | */ 105 | void SetActive(bool m_bActive) 106 | { 107 | reinterpret_cast(GameObjectFunctions.m_pSetActive)(this, m_bActive); 108 | } 109 | 110 | void SetLayer(unsigned int m_uLayer) 111 | { 112 | reinterpret_cast(GameObjectFunctions.m_pSetLayer)(this, m_uLayer); 113 | } 114 | }; 115 | 116 | namespace GameObject 117 | { 118 | enum class m_ePrimitiveType : int 119 | { 120 | Default = 0, 121 | Sphere = 0, 122 | Capsule, 123 | Cylinder, 124 | Cube, 125 | Plane, 126 | Quad, 127 | }; 128 | 129 | void Initialize(); 130 | 131 | CGameObject* CreatePrimitive(m_ePrimitiveType m_eType); 132 | 133 | CGameObject* Find(const char* m_pName); // CGameObject* Find(const char* m_pName); 134 | 135 | il2cppArray* FindWithTag(const char* m_pTag); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/API/LayerMask.cpp: -------------------------------------------------------------------------------- 1 | #include "../../Includes.hpp" 2 | 3 | namespace Unity 4 | { 5 | SLayerMaskFunctions LayerMaskFunctions; 6 | 7 | namespace LayerMask 8 | { 9 | void Initialize() 10 | { 11 | IL2CPP::SystemTypeCache::Initializer::Add(UNITY_LAYERMASK_CLASS); 12 | 13 | LayerMaskFunctions.m_pLayerToName = IL2CPP::ResolveCall(UNITY_LAYERMASK_LAYERTONAME); 14 | LayerMaskFunctions.m_pNameToLayer = IL2CPP::ResolveCall(UNITY_LAYERMASK_NAMETOLAYER); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/API/LayerMask.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Unity 4 | { 5 | struct SLayerMaskFunctions 6 | { 7 | void* m_pLayerToName = nullptr; 8 | void* m_pNameToLayer = nullptr; 9 | }; 10 | extern SLayerMaskFunctions LayerMaskFunctions; 11 | 12 | namespace LayerMask 13 | { 14 | void Initialize(); 15 | 16 | static System_String* LayerToName(unsigned int m_uLayer) 17 | { 18 | return reinterpret_cast(LayerMaskFunctions.m_pLayerToName)(m_uLayer); 19 | } 20 | 21 | static unsigned int NameToLayer(const char* m_pName) 22 | { 23 | return reinterpret_cast(LayerMaskFunctions.m_pNameToLayer)(IL2CPP::String::New(m_pName)); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/API/Object.cpp: -------------------------------------------------------------------------------- 1 | #include "../../Includes.hpp" 2 | 3 | namespace Unity 4 | { 5 | SObjectFunctions ObjectFunctions; 6 | 7 | namespace Object 8 | { 9 | void Initialize() 10 | { 11 | IL2CPP::SystemTypeCache::Initializer::Add(UNITY_OBJECT_CLASS); 12 | 13 | ObjectFunctions.m_pDestroy = IL2CPP::ResolveCall(UNITY_OBJECT_DESTROY); 14 | ObjectFunctions.m_pFindObjectsOfType = IL2CPP::ResolveCall(UNITY_OBJECT_FINDOBJECTSOFTYPE); 15 | ObjectFunctions.m_pGetName = IL2CPP::ResolveCall(UNITY_OBJECT_GETNAME); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/API/Object.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Unity 4 | { 5 | struct SObjectFunctions 6 | { 7 | void* m_pDestroy = nullptr; 8 | void* m_pFindObjectsOfType = nullptr; 9 | void* m_pGetName = nullptr; 10 | }; 11 | extern SObjectFunctions ObjectFunctions; 12 | 13 | class CObject : public IL2CPP::CClass 14 | { 15 | public: 16 | void Destroy(float fTimeDelay = 0.f) 17 | { 18 | reinterpret_cast(ObjectFunctions.m_pDestroy)(this, fTimeDelay); 19 | } 20 | 21 | System_String* GetName() 22 | { 23 | return reinterpret_cast(ObjectFunctions.m_pGetName)(this); 24 | } 25 | }; 26 | 27 | namespace Object 28 | { 29 | void Initialize(); 30 | 31 | template 32 | static il2cppArray* FindObjectsOfType(il2cppObject* m_pSystemType) 33 | { 34 | return reinterpret_cast*(UNITY_CALLING_CONVENTION)(void*)>(ObjectFunctions.m_pFindObjectsOfType)(m_pSystemType); 35 | } 36 | 37 | template 38 | static il2cppArray* FindObjectsOfType(const char* m_pSystemTypeName) 39 | { 40 | il2cppClass* m_pClass = IL2CPP::Class::Find(m_pSystemTypeName); 41 | if (!m_pClass) return nullptr; 42 | 43 | return FindObjectsOfType(IL2CPP::Class::GetSystemType(m_pClass)); 44 | } 45 | 46 | template 47 | static T* FindObjectOfType(il2cppObject* m_pSystemType) 48 | { 49 | il2cppArray* m_pArray = FindObjectsOfType(m_pSystemType); 50 | if (!m_pArray || m_pArray->m_uMaxLength == 0U) return nullptr; 51 | 52 | return m_pArray->m_pValues[0]; 53 | } 54 | 55 | template 56 | static T* FindObjectOfType(const char* m_pSystemTypeName) 57 | { 58 | il2cppClass* m_pClass = IL2CPP::Class::Find(m_pSystemTypeName); 59 | if (!m_pClass) return nullptr; 60 | 61 | return FindObjectOfType(IL2CPP::Class::GetSystemType(m_pClass)); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/API/Rigidbody.cpp: -------------------------------------------------------------------------------- 1 | #include "../../Includes.hpp" 2 | 3 | namespace Unity 4 | { 5 | SRigidbodyFunctions RigidbodyFunctions; 6 | 7 | namespace RigidBody 8 | { 9 | void Initialize() 10 | { 11 | IL2CPP::SystemTypeCache::Initializer::Add(UNITY_RIGIDBODY_CLASS); 12 | 13 | RigidbodyFunctions.m_pGetDetectCollisions = IL2CPP::ResolveCall(UNITY_RIGIDBODY_GETDETECTCOLLISIONS); 14 | RigidbodyFunctions.m_pGetVelocity = IL2CPP::ResolveCall(UNITY_RIGIDBODY_GETVELOCITY); 15 | RigidbodyFunctions.m_pSetDetectCollisions = IL2CPP::ResolveCall(UNITY_RIGIDBODY_SETDETECTCOLLISIONS); 16 | RigidbodyFunctions.m_pSetVelocity = IL2CPP::ResolveCall(UNITY_RIGIDBODY_SETVELOCITY); 17 | 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/API/Rigidbody.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Unity 4 | { 5 | struct SRigidbodyFunctions 6 | { 7 | void* m_pGetDetectCollisions = nullptr; 8 | void* m_pGetVelocity = nullptr; 9 | void* m_pSetDetectCollisions = nullptr; 10 | void* m_pSetVelocity = nullptr; 11 | }; 12 | extern SRigidbodyFunctions RigidbodyFunctions; 13 | 14 | class CRigidbody : public IL2CPP::CClass 15 | { 16 | public: 17 | bool GetDetectCollisions() 18 | { 19 | return reinterpret_cast(RigidbodyFunctions.m_pGetDetectCollisions)(this); 20 | } 21 | 22 | void SetDetectCollisions(bool m_bDetect) 23 | { 24 | reinterpret_cast(RigidbodyFunctions.m_pSetDetectCollisions)(this, m_bDetect); 25 | } 26 | 27 | Vector3 GetVelocity() 28 | { 29 | Vector3 vRet; 30 | reinterpret_cast(RigidbodyFunctions.m_pGetVelocity)(this, vRet); 31 | return vRet; 32 | } 33 | 34 | void SetVelocity(Vector3 m_vVector) 35 | { 36 | reinterpret_cast(RigidbodyFunctions.m_pSetVelocity)(this, m_vVector); 37 | } 38 | }; 39 | 40 | namespace RigidBody 41 | { 42 | void Initialize(); 43 | } 44 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/API/Transform.cpp: -------------------------------------------------------------------------------- 1 | #include "../../Includes.hpp" 2 | 3 | namespace Unity 4 | { 5 | STransformFunctions TransformFunctions; 6 | 7 | namespace Transform 8 | { 9 | void Initialize() 10 | { 11 | IL2CPP::SystemTypeCache::Initializer::Add(UNITY_TRANSFORM_CLASS); 12 | 13 | TransformFunctions.m_pGetParent = IL2CPP::ResolveCall(UNITY_TRANSFORM_GETPARENT); 14 | TransformFunctions.m_pGetRoot = IL2CPP::ResolveCall(UNITY_TRANSFORM_GETROOT); 15 | TransformFunctions.m_pGetChild = IL2CPP::ResolveCall(UNITY_TRANSFORM_GETCHILD); 16 | TransformFunctions.m_pGetChildCount = IL2CPP::ResolveCall(UNITY_TRANSFORM_GETCHILDCOUNT); 17 | TransformFunctions.m_pFindChild = IL2CPP::ResolveCall(UNITY_TRANSFORM_FINDCHILD); 18 | TransformFunctions.m_pGetPosition = IL2CPP::ResolveCall(UNITY_TRANSFORM_GETPOSITION); 19 | TransformFunctions.m_pGetRotation = IL2CPP::ResolveCall(UNITY_TRANSFORM_GETROTATION); 20 | TransformFunctions.m_pGetLocalPosition = IL2CPP::ResolveCall(UNITY_TRANSFORM_GETLOCALPOSITION); 21 | TransformFunctions.m_pGetLocalScale = IL2CPP::ResolveCall(UNITY_TRANSFORM_GETLOCALSCALE); 22 | TransformFunctions.m_pSetPosition = IL2CPP::ResolveCall(UNITY_TRANSFORM_SETPOSITION); 23 | TransformFunctions.m_pSetRotation = IL2CPP::ResolveCall(UNITY_TRANSFORM_SETROTATION); 24 | TransformFunctions.m_pSetLocalPosition = IL2CPP::ResolveCall(UNITY_TRANSFORM_SETLOCALPOSITION); 25 | TransformFunctions.m_pSetLocalScale = IL2CPP::ResolveCall(UNITY_TRANSFORM_SETLOCALSCALE); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/API/Transform.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Unity 4 | { 5 | struct STransformFunctions 6 | { 7 | void* m_pGetParent = nullptr; 8 | void* m_pGetRoot = nullptr; 9 | void* m_pGetChild = nullptr; 10 | void* m_pGetChildCount = nullptr; 11 | void* m_pFindChild = nullptr; 12 | void* m_pGetPosition = nullptr; 13 | void* m_pGetRotation = nullptr; 14 | void* m_pGetLocalPosition = nullptr; 15 | void* m_pGetLocalScale = nullptr; 16 | void* m_pSetPosition = nullptr; 17 | void* m_pSetRotation = nullptr; 18 | void* m_pSetLocalPosition = nullptr; 19 | void* m_pSetLocalScale = nullptr; 20 | }; 21 | extern STransformFunctions TransformFunctions; 22 | 23 | class CTransform : public IL2CPP::CClass 24 | { 25 | public: 26 | CTransform* GetParent() 27 | { 28 | return reinterpret_cast(TransformFunctions.m_pGetParent)(this); 29 | } 30 | 31 | CTransform* GetRoot() 32 | { 33 | return reinterpret_cast(TransformFunctions.m_pGetRoot)(this); 34 | } 35 | 36 | CTransform* GetChild(int m_iIndex) 37 | { 38 | return reinterpret_cast(TransformFunctions.m_pGetChild)(this, m_iIndex); 39 | } 40 | 41 | int GetChildCount() 42 | { 43 | return reinterpret_cast(TransformFunctions.m_pGetChildCount)(this); 44 | } 45 | 46 | CTransform* FindChild(const char* path, bool isActiveOnly) 47 | { 48 | return reinterpret_cast(TransformFunctions.m_pFindChild)(this, IL2CPP::String::New(path), isActiveOnly); 49 | } 50 | 51 | // e.g CGameObject->GetTransform()->FindChild("child1/child2/child3"); 52 | CTransform* FindChild(const char* path) 53 | { 54 | return FindChild(path, false); 55 | } 56 | 57 | Vector3 GetPosition() 58 | { 59 | Vector3 vRet; 60 | reinterpret_cast(TransformFunctions.m_pGetPosition)(this, vRet); 61 | return vRet; 62 | } 63 | 64 | Quaternion GetRotation() 65 | { 66 | Quaternion m_qRet; 67 | reinterpret_cast(TransformFunctions.m_pGetRotation)(this, m_qRet); 68 | return m_qRet; 69 | } 70 | 71 | Vector3 GetLocalPosition() 72 | { 73 | Vector3 vRet; 74 | reinterpret_cast(TransformFunctions.m_pGetLocalPosition)(this, vRet); 75 | return vRet; 76 | } 77 | 78 | Vector3 GetLocalScale() 79 | { 80 | Vector3 vRet; 81 | reinterpret_cast(TransformFunctions.m_pGetLocalScale)(this, vRet); 82 | return vRet; 83 | } 84 | 85 | void SetPosition(Vector3 m_vVector) 86 | { 87 | reinterpret_cast(TransformFunctions.m_pSetPosition)(this, m_vVector); 88 | } 89 | 90 | void SetRotation(Quaternion m_qQuat) 91 | { 92 | reinterpret_cast(TransformFunctions.m_pSetRotation)(this, m_qQuat); 93 | } 94 | 95 | void SetLocalPosition(Vector3 m_vVector) 96 | { 97 | reinterpret_cast(TransformFunctions.m_pSetLocalPosition)(this, m_vVector); 98 | } 99 | 100 | void SetLocalScale(Vector3 m_vVector) 101 | { 102 | reinterpret_cast(TransformFunctions.m_pSetLocalScale)(this, m_vVector); 103 | } 104 | }; 105 | 106 | namespace Transform 107 | { 108 | void Initialize(); 109 | } 110 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/API/_TEMPLATE_API.cpp: -------------------------------------------------------------------------------- 1 | #include "../../Includes.hpp" 2 | // C+P Ready Template 3 | 4 | namespace Unity 5 | { 6 | S_TEMPLATEFunctions _TEMPLATEFunctions; 7 | 8 | namespace _TEMPLATE 9 | { 10 | void Initialize() 11 | { 12 | 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/API/_TEMPLATE_API.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | // C+P Ready Template 3 | 4 | namespace Unity 5 | { 6 | struct S_TEMPLATEFunctions 7 | { 8 | 9 | }; 10 | extern S_TEMPLATEFunctions _TEMPLATEFunctions; 11 | 12 | class C_TEMPLATE : public IL2CPP::CClass 13 | { 14 | public: 15 | 16 | }; 17 | 18 | namespace _TEMPLATE 19 | { 20 | void Initialize(); 21 | } 22 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/Defines.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | // Calling Convention 3 | #ifdef _WIN64 4 | #define UNITY_CALLING_CONVENTION __fastcall* 5 | #elif _WIN32 6 | #define UNITY_CALLING_CONVENTION __cdecl* 7 | #endif 8 | 9 | 10 | 11 | // Camera 12 | #define UNITY_CAMERA_CLASS "UnityEngine.Camera" 13 | #define UNITY_CAMERA_GETCURRENT UNITY_CAMERA_CLASS"::get_current" 14 | #define UNITY_CAMERA_GETMAIN UNITY_CAMERA_CLASS"::get_main" 15 | #define UNITY_CAMERA_GETDEPTH UNITY_CAMERA_CLASS"::get_depth" 16 | #define UNITY_CAMERA_SETDEPTH UNITY_CAMERA_CLASS"::set_depth" 17 | #define UNITY_CAMERA_GETFIELDOFVIEW UNITY_CAMERA_CLASS"::get_fieldOfView" 18 | #define UNITY_CAMERA_SETFIELDOFVIEW UNITY_CAMERA_CLASS"::set_fieldOfView" 19 | #define UNITY_CAMERA_WORLDTOSCREEN UNITY_CAMERA_CLASS"::WorldToScreenPoint_Injected" 20 | 21 | // Component 22 | #define UNITY_COMPONENT_CLASS "UnityEngine.Component" 23 | #define UNITY_COMPONENT_GETGAMEOBJECT UNITY_COMPONENT_CLASS"::get_gameObject" 24 | #define UNITY_COMPONENT_GETTRANSFORM UNITY_COMPONENT_CLASS"::get_transform" 25 | 26 | // GameObject 27 | #define UNITY_GAMEOBJECT_CLASS "UnityEngine.GameObject" 28 | #define UNITY_GAMEOBJECT_ADDCOMPONENT UNITY_GAMEOBJECT_CLASS"::Internal_AddComponentWithType" 29 | #define UNITY_GAMEOBJECT_CREATEPRIMITIVE UNITY_GAMEOBJECT_CLASS"::CreatePrimitive" 30 | #define UNITY_GAMEOBJECT_FIND UNITY_GAMEOBJECT_CLASS"::Find" 31 | #define UNITY_GAMEOBJECT_GETCOMPONENT UNITY_GAMEOBJECT_CLASS"::GetComponentByName" 32 | #define UNITY_GAMEOBJECT_GETCOMPONENTS UNITY_GAMEOBJECT_CLASS"::GetComponentsInternal" 33 | #define UNITY_GAMEOBJECT_GETCOMPONENTINCHILDREN UNITY_GAMEOBJECT_CLASS"::GetComponentInChildren" 34 | #define UNITY_GAMEOBJECT_GETACTIVE UNITY_GAMEOBJECT_CLASS"::get_active" 35 | #define UNITY_GAMEOBJECT_GETLAYER UNITY_GAMEOBJECT_CLASS"::get_layer" 36 | #define UNITY_GAMEOBJECT_GETTRANSFORM UNITY_GAMEOBJECT_CLASS"::get_transform" 37 | #define UNITY_GAMEOBJECT_SETACTIVE UNITY_GAMEOBJECT_CLASS"::set_active" 38 | #define UNITY_GAMEOBJECT_SETLAYER UNITY_GAMEOBJECT_CLASS"::set_layer" 39 | #define UNITY_GAMEOBJECT_FINDGAMEOBJECTWITHTAG UNITY_GAMEOBJECT_CLASS"::FindGameObjectsWithTag" 40 | 41 | // LayerMask 42 | #define UNITY_LAYERMASK_CLASS "UnityEngine.LayerMask" 43 | #define UNITY_LAYERMASK_LAYERTONAME UNITY_LAYERMASK_CLASS"::LayerToName" 44 | #define UNITY_LAYERMASK_NAMETOLAYER UNITY_LAYERMASK_CLASS"::NameToLayer" 45 | 46 | // MonoBehaviour 47 | #define UNITY_MONOBEHAVIOUR_CLASS "UnityEngine.MonoBehaviour" 48 | 49 | // Object 50 | #define UNITY_OBJECT_CLASS "UnityEngine.Object" 51 | #define UNITY_OBJECT_DESTROY UNITY_OBJECT_CLASS"::Destroy" 52 | #define UNITY_OBJECT_FINDOBJECTSOFTYPE UNITY_OBJECT_CLASS"::FindObjectsOfType" 53 | #define UNITY_OBJECT_GETNAME UNITY_OBJECT_CLASS"::GetName" 54 | 55 | // Rigidbody 56 | #define UNITY_RIGIDBODY_CLASS "UnityEngine.Rigidbody" 57 | #define UNITY_RIGIDBODY_GETDETECTCOLLISIONS UNITY_RIGIDBODY_CLASS"::get_detectCollisions" 58 | #define UNITY_RIGIDBODY_GETVELOCITY UNITY_RIGIDBODY_CLASS"::get_velocity_Injected" 59 | #define UNITY_RIGIDBODY_SETDETECTCOLLISIONS UNITY_RIGIDBODY_CLASS"::set_detectCollisions" 60 | #define UNITY_RIGIDBODY_SETVELOCITY UNITY_RIGIDBODY_CLASS"::set_velocity_Injected" 61 | 62 | // Transform 63 | #define UNITY_TRANSFORM_CLASS "UnityEngine.Transform" 64 | #define UNITY_TRANSFORM_GETPARENT UNITY_TRANSFORM_CLASS"::GetParent" 65 | #define UNITY_TRANSFORM_GETROOT UNITY_TRANSFORM_CLASS"::GetRoot" 66 | #define UNITY_TRANSFORM_GETCHILD UNITY_TRANSFORM_CLASS"::GetChild" 67 | #define UNITY_TRANSFORM_GETCHILDCOUNT UNITY_TRANSFORM_CLASS"::get_childCount" 68 | #define UNITY_TRANSFORM_FINDCHILD UNITY_TRANSFORM_CLASS"::FindRelativeTransformWithPath" 69 | #define UNITY_TRANSFORM_GETPOSITION UNITY_TRANSFORM_CLASS"::get_position_Injected" 70 | #define UNITY_TRANSFORM_GETROTATION UNITY_TRANSFORM_CLASS"::get_rotation_Injected" 71 | #define UNITY_TRANSFORM_GETLOCALPOSITION UNITY_TRANSFORM_CLASS"::get_localPosition_Injected" 72 | #define UNITY_TRANSFORM_GETLOCALSCALE UNITY_TRANSFORM_CLASS"::get_localScale_Injected" 73 | #define UNITY_TRANSFORM_SETPOSITION UNITY_TRANSFORM_CLASS"::set_position_Injected" 74 | #define UNITY_TRANSFORM_SETROTATION UNITY_TRANSFORM_CLASS"::set_rotation_Injected" 75 | #define UNITY_TRANSFORM_SETLOCALPOSITION UNITY_TRANSFORM_CLASS"::set_localPosition_Injected" 76 | #define UNITY_TRANSFORM_SETLOCALSCALE UNITY_TRANSFORM_CLASS"::set_localScale_Injected" 77 | 78 | namespace Unity 79 | { 80 | enum m_eTypeEnum 81 | { 82 | Type_Void = 1, 83 | Type_Boolean = 2, 84 | Type_Character = 3, 85 | Type_Integer = 8, 86 | Type_Float = 12, 87 | Type_String = 14, 88 | Type_Pointer = 15, 89 | Type_ValueType = 17, 90 | Type_Class = 18, 91 | Type_Variable = 19, 92 | Type_Array = 20, 93 | Type_Enum = 85, 94 | }; 95 | 96 | enum m_eFieldAttribute 97 | { 98 | FieldAttribute_Compiler, 99 | FieldAttribute_Private, 100 | FieldAttribute_FamilyAndAssembly, 101 | FieldAttribute_Assembly, 102 | FieldAttribute_Family, 103 | FieldAttribute_FamilyOrAssembly, 104 | FieldAttribute_Public, 105 | FieldAttribute_AccessMask, 106 | FieldAttribute_Static = 16, 107 | FieldAttribute_InitOnly = 32, 108 | FieldAttribute_Literal = 64, 109 | FieldAttribute_NotSerialized = 128, 110 | FieldAttribute_HasRVA = 256, 111 | FieldAttribute_SpecialName = 512, 112 | FieldAttribute_RTSpecialName = 1024, 113 | FieldAttribute_HasMarshal = 4096, 114 | FieldAttribute_InvokeImpl = 8192, 115 | FieldAttribute_Default = 32768, 116 | FieldAttribute_Reserved = 38144, 117 | }; 118 | } 119 | -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/Includes.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Defines.hpp" 3 | #include "Obfuscators.hpp" 4 | 5 | // Structures 6 | #include "Structures/Includes.hpp" 7 | 8 | // Class APIs - So they're accessible everywhere 9 | namespace Unity 10 | { 11 | class CCamera; 12 | class CComponent; 13 | class CGameObject; 14 | class CObject; 15 | class CRigidbody; 16 | class CTransform; 17 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/Obfuscators.cpp: -------------------------------------------------------------------------------- 1 | #include "../Includes.hpp" 2 | 3 | namespace Unity 4 | { 5 | namespace Obfuscators 6 | { 7 | // Should do the basic work 8 | std::string ROT_String(const char* pString, int iValue) 9 | { 10 | std::string sRet; 11 | size_t sSize = strlen(pString); 12 | for (size_t i = 0; sSize > i; ++i) 13 | { 14 | bool bIsUppercase = pString[i] >= 'A' && 'Z' >= pString[i]; 15 | bool bIsLowercase = !bIsUppercase && pString[i] >= 'a' && 'z' >= pString[i]; 16 | if (!bIsUppercase && !bIsLowercase) 17 | { 18 | sRet += pString[i]; 19 | continue; 20 | } 21 | 22 | int iNewValue = static_cast(pString[i]) + iValue; 23 | if (bIsUppercase) 24 | { 25 | int iMaxValue = static_cast('Z'); 26 | while (iNewValue > iMaxValue) iNewValue = static_cast('A') + (iNewValue - iMaxValue); 27 | } 28 | else 29 | { 30 | int iMaxValue = static_cast('z'); 31 | while (iNewValue > iMaxValue) iNewValue = static_cast('a') + (iNewValue - iMaxValue); 32 | } 33 | 34 | sRet += static_cast(iNewValue); 35 | } 36 | 37 | sRet += '\0'; 38 | return sRet; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/Obfuscators.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Unity 4 | { 5 | namespace Obfuscators 6 | { 7 | std::string ROT_String(const char* pString, int iValue); 8 | } 9 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/Structures/Engine.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Unity 4 | { 5 | struct Vector2 6 | { 7 | float x, y; 8 | 9 | Vector2() { x = y = 0.f; } 10 | Vector2(float f1, float f2) { x = f1; y = f2; } 11 | }; 12 | 13 | struct Vector3 14 | { 15 | float x, y, z; 16 | 17 | Vector3() { x = y = z = 0.f; } 18 | Vector3(float f1, float f2, float f3) { x = f1; y = f2; z = f3; } 19 | 20 | void ToVectors(Vector3* m_pForward, Vector3* m_pRight, Vector3* m_pUp) 21 | { 22 | float m_fDeg2Rad = static_cast(M_PI) / 180.f; 23 | 24 | float m_fSinX = sinf(x * m_fDeg2Rad); 25 | float m_fCosX = cosf(x * m_fDeg2Rad); 26 | 27 | float m_fSinY = sinf(y * m_fDeg2Rad); 28 | float m_fCosY = cosf(y * m_fDeg2Rad); 29 | 30 | float m_fSinZ = sinf(z * m_fDeg2Rad); 31 | float m_fCosZ = cosf(z * m_fDeg2Rad); 32 | 33 | if (m_pForward) 34 | { 35 | m_pForward->x = m_fCosX * m_fCosY; 36 | m_pForward->y = -m_fSinX; 37 | m_pForward->z = m_fCosX * m_fSinY; 38 | } 39 | 40 | if (m_pRight) 41 | { 42 | m_pRight->x = -1.f * m_fSinZ * m_fSinX * m_fCosY + -1.f * m_fCosZ * -m_fSinY; 43 | m_pRight->y = -1.f * m_fSinZ * m_fCosX; 44 | m_pRight->z = -1.f * m_fSinZ * m_fSinX * m_fSinY + -1.f * m_fCosZ * m_fCosY; 45 | } 46 | 47 | if (m_pUp) 48 | { 49 | m_pUp->x = m_fCosZ * m_fSinX * m_fCosY + -m_fSinZ * -m_fSinY; 50 | m_pUp->y = m_fCosZ * m_fCosX; 51 | m_pUp->z = m_fCosZ * m_fSinX * m_fSinY + -m_fSinZ * m_fCosY; 52 | } 53 | } 54 | }; 55 | 56 | struct Vector4 57 | { 58 | float x, y, z, w; 59 | 60 | Vector4() { x = y = z = w = 0.f; } 61 | Vector4(float f1, float f2, float f3, float f4) { x = f1; y = f2; z = f3; w = f4; } 62 | }; 63 | 64 | struct Quaternion 65 | { 66 | float x, y, z, w; 67 | 68 | Quaternion() { x = y = z = w = 0.f; } 69 | Quaternion(float f1, float f2, float f3, float f4) { x = f1; y = f2; z = f3; w = f4; } 70 | 71 | Quaternion Euler(float m_fX, float m_fY, float m_fZ) 72 | { 73 | float m_fDeg2Rad = static_cast(M_PI) / 180.f; 74 | 75 | m_fX = m_fX * m_fDeg2Rad * 0.5f; 76 | m_fY = m_fY * m_fDeg2Rad * 0.5f; 77 | m_fZ = m_fZ * m_fDeg2Rad * 0.5f; 78 | 79 | float m_fSinX = sinf(m_fX); 80 | float m_fCosX = cosf(m_fX); 81 | 82 | float m_fSinY = sinf(m_fY); 83 | float m_fCosY = cosf(m_fY); 84 | 85 | float m_fSinZ = sinf(m_fZ); 86 | float m_fCosZ = cosf(m_fZ); 87 | 88 | x = m_fCosY * m_fSinX * m_fCosZ + m_fSinY * m_fCosX * m_fSinZ; 89 | y = m_fSinY * m_fCosX * m_fCosZ - m_fCosY * m_fSinX * m_fSinZ; 90 | z = m_fCosY * m_fCosX * m_fSinZ - m_fSinY * m_fSinX * m_fCosZ; 91 | w = m_fCosY * m_fCosX * m_fCosZ + m_fSinY * m_fSinX * m_fSinZ; 92 | 93 | return *this; 94 | } 95 | 96 | Quaternion Euler(Vector3 m_vRot) 97 | { 98 | return Euler(m_vRot.x, m_vRot.y, m_vRot.z); 99 | } 100 | 101 | Vector3 ToEuler() 102 | { 103 | Vector3 m_vEuler; 104 | 105 | float m_fDist = (x * x) + (y * y) + (z * z) + (w * w); 106 | 107 | float m_fTest = x * w - y * z; 108 | if (m_fTest > 0.4995f * m_fDist) 109 | { 110 | m_vEuler.x = static_cast(M_PI) * 0.5f; 111 | m_vEuler.y = 2.f * atan2f(y, x); 112 | m_vEuler.z = 0.f; 113 | } 114 | else if (m_fTest < -0.4995f * m_fDist) 115 | { 116 | m_vEuler.x = static_cast(M_PI) * -0.5f; 117 | m_vEuler.y = -2.f * atan2f(y, x); 118 | m_vEuler.z = 0.f; 119 | } 120 | else 121 | { 122 | m_vEuler.x = asinf(2.f * (w * x - y * z)); 123 | m_vEuler.y = atan2f(2.f * w * y + 2.f * z * x, 1.f - 2.f * (x * x + y * y)); 124 | m_vEuler.z = atan2f(2.f * w * z + 2.f * x * y, 1.f - 2.f * (z * z + x * x)); 125 | } 126 | 127 | float m_fRad2Deg = 180.f / static_cast(M_PI); 128 | m_vEuler.x *= m_fRad2Deg; 129 | m_vEuler.y *= m_fRad2Deg; 130 | m_vEuler.z *= m_fRad2Deg; 131 | 132 | return m_vEuler; 133 | } 134 | }; 135 | 136 | struct Bounds 137 | { 138 | Vector3 m_vCenter; 139 | Vector3 m_vExtents; 140 | }; 141 | 142 | struct Plane 143 | { 144 | Vector3 m_vNormal; 145 | float fDistance; 146 | }; 147 | 148 | struct Ray 149 | { 150 | Vector3 m_vOrigin; 151 | Vector3 m_vDirection; 152 | }; 153 | 154 | struct Rect 155 | { 156 | float fX, fY; 157 | float fWidth, fHeight; 158 | 159 | Rect() { fX = fY = fWidth = fHeight = 0.f; } 160 | Rect(float f1, float f2, float f3, float f4) { fX = f1; fY = f2; fWidth = f3; fHeight = f4; } 161 | }; 162 | 163 | struct Color 164 | { 165 | float r, g, b, a; 166 | 167 | Color() { r = g = b = a = 0.f; } 168 | Color(float fRed = 0.f, float fGreen = 0.f, float fBlue = 0.f, float fAlpha = 1.f) { r = fRed; g = fGreen; b = fBlue; a = fAlpha; } 169 | }; 170 | 171 | struct Matrix4x4 172 | { 173 | float m[4][4] = { 0 }; 174 | 175 | Matrix4x4() { } 176 | 177 | float* operator[](int i) { return m[i]; } 178 | }; 179 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/Structures/Includes.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "il2cpp.hpp" 3 | #include "il2cppArray.hpp" 4 | #include "il2cppDictionary.hpp" 5 | 6 | #include "Engine.hpp" 7 | #include "System_String.hpp" -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/Structures/System_String.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Unity 4 | { 5 | struct System_String : il2cppObject 6 | { 7 | int m_iLength; 8 | wchar_t m_wString[1024]; 9 | 10 | void Clear() 11 | { 12 | if (!this) return; 13 | 14 | memset(m_wString, 0, static_cast(m_iLength) * 2); 15 | m_iLength = 0; 16 | } 17 | 18 | std::string ToString() 19 | { 20 | if (!this) return ""; 21 | 22 | std::string sRet(static_cast(m_iLength) + 1, '\0'); 23 | WideCharToMultiByte(CP_UTF8, 0, m_wString, m_iLength, &sRet[0], m_iLength, 0, 0); 24 | return sRet; 25 | } 26 | }; 27 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/Structures/il2cpp.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Unity 4 | { 5 | struct il2cppImage 6 | { 7 | const char* m_pName; 8 | const char* m_pNameNoExt; 9 | }; 10 | 11 | struct il2cppAssemblyName 12 | { 13 | const char* m_pName; 14 | const char* m_pCulture; 15 | const char* m_pHash; 16 | const char* m_pPublicKey; 17 | unsigned int m_uHash; 18 | int m_iHashLength; 19 | unsigned int m_uFlags; 20 | int m_iMajor; 21 | int m_iMinor; 22 | int m_iBuild; 23 | int m_bRevision; 24 | unsigned char m_uPublicKeyToken[8]; 25 | }; 26 | 27 | struct il2cppAssembly 28 | { 29 | il2cppImage* m_pImage; 30 | unsigned int m_uToken; 31 | int m_ReferencedAssemblyStart; 32 | int m_ReferencedAssemblyCount; 33 | il2cppAssemblyName m_aName; 34 | }; 35 | 36 | struct il2cppClass 37 | { 38 | void* m_pImage; 39 | void* m_pGC; 40 | const char* m_pName; 41 | const char* m_pNamespace; 42 | void* m_pValue; 43 | void* m_pArgs; 44 | il2cppClass* m_pElementClass; 45 | il2cppClass* m_pCastClass; 46 | il2cppClass* m_pDeclareClass; 47 | il2cppClass* m_pParentClass; 48 | void* m_pGenericClass; 49 | void* m_pTypeDefinition; 50 | void* m_pInteropData; 51 | void* m_pFields; 52 | void* m_pEvents; 53 | void* m_pProperties; 54 | void** m_pMethods; 55 | il2cppClass** m_pNestedTypes; 56 | il2cppClass** m_ImplementedInterfaces; 57 | void* m_pInterfaceOffsets; 58 | void* m_pStaticFields; 59 | void* m_pRGCTX; 60 | }; 61 | 62 | struct il2cppObject 63 | { 64 | il2cppClass* m_pClass = nullptr; 65 | void* m_pMonitor = nullptr; 66 | }; 67 | 68 | struct il2cppType 69 | { 70 | union 71 | { 72 | void* m_pDummy; 73 | unsigned int m_uClassIndex; 74 | il2cppType* m_pType; 75 | void* m_pArray; 76 | unsigned int m_uGenericParameterIndex; 77 | void* m_pGenericClass; 78 | }; 79 | unsigned int m_uAttributes : 16; 80 | unsigned int m_uType : 8; 81 | unsigned int m_uMods : 6; 82 | unsigned int m_uByref : 1; 83 | unsigned int m_uPinned : 1; 84 | }; 85 | 86 | struct il2cppFieldInfo 87 | { 88 | const char* m_pName; 89 | il2cppType* m_pType; 90 | il2cppClass* m_pParentClass; 91 | int m_iOffset; 92 | int m_iAttributeIndex; 93 | unsigned int m_uToken; 94 | }; 95 | 96 | struct il2cppParameterInfo 97 | { 98 | const char* m_pName; 99 | int m_iPosition; 100 | unsigned int m_uToken; 101 | il2cppType* m_pParameterType; 102 | }; 103 | 104 | struct il2cppMethodInfo 105 | { 106 | void* m_pMethodPointer; 107 | void* m_pInvokerMethod; 108 | const char* m_pName; 109 | il2cppClass* m_pClass; 110 | il2cppType* m_pReturnType; 111 | il2cppParameterInfo* m_pParameters; 112 | 113 | union 114 | { 115 | void* m_pRGCTX; 116 | void* m_pMethodDefinition; 117 | }; 118 | 119 | union 120 | { 121 | void* m_pGenericMethod; 122 | void* m_pGenericContainer; 123 | }; 124 | 125 | unsigned int m_uToken; 126 | unsigned short m_uFlags; 127 | unsigned short m_uFlags2; 128 | unsigned short m_uSlot; 129 | unsigned char m_uArgsCount; 130 | unsigned char m_uGeneric : 1; 131 | unsigned char m_uInflated : 1; 132 | unsigned char m_uWrapperType : 1; 133 | unsigned char m_uMarshaledFromNative : 1; 134 | }; 135 | 136 | struct il2cppPropertyInfo 137 | { 138 | il2cppClass* m_pParentClass; 139 | const char* m_pName; 140 | il2cppMethodInfo* m_pGet; 141 | il2cppMethodInfo* m_pSet; 142 | unsigned int m_uAttributes; 143 | unsigned int m_uToken; 144 | }; 145 | 146 | struct il2cppArrayBounds 147 | { 148 | uintptr_t m_uLength; 149 | int m_iLowerBound; 150 | }; 151 | } 152 | -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/Structures/il2cppArray.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Unity 4 | { 5 | template 6 | struct il2cppArray : il2cppObject 7 | { 8 | il2cppArrayBounds* m_pBounds = nullptr; 9 | uintptr_t m_uMaxLength = 0; 10 | T* m_pValues = nullptr; 11 | 12 | uintptr_t GetData() 13 | { 14 | return reinterpret_cast(&m_pValues); 15 | } 16 | 17 | T& operator[](unsigned int m_uIndex) 18 | { 19 | return *reinterpret_cast(GetData() + sizeof(T) * m_uIndex); 20 | } 21 | 22 | T& At(unsigned int m_uIndex) 23 | { 24 | return operator[](m_uIndex); 25 | } 26 | 27 | void Insert(T* m_pArray, uintptr_t m_uSize, uintptr_t m_uIndex = 0) 28 | { 29 | if ((m_uSize + m_uIndex) >= m_uMaxLength) 30 | { 31 | if (m_uIndex >= m_uMaxLength) 32 | return; 33 | 34 | m_uSize = m_uMaxLength - m_uIndex; 35 | } 36 | 37 | for (uintptr_t u = 0; m_uSize > u; ++u) 38 | operator[](u + m_uIndex) = m_pArray[u]; 39 | } 40 | 41 | void Fill(T m_tValue) 42 | { 43 | for (uintptr_t u = 0; m_uMaxLength > u; ++u) 44 | operator[](u) = m_tValue; 45 | } 46 | 47 | void RemoveAt(unsigned int m_uIndex) 48 | { 49 | if (m_uIndex >= m_uMaxLength) 50 | return; 51 | 52 | if (m_uMaxLength > (m_uIndex + 1)) 53 | { 54 | for (unsigned int u = m_uIndex; (static_cast(m_uMaxLength) - m_uIndex) > u; ++u) 55 | operator[](u) = operator[](u + 1); 56 | } 57 | 58 | --m_uMaxLength; 59 | } 60 | 61 | void RemoveRange(unsigned int m_uIndex, unsigned int m_uCount) 62 | { 63 | if (m_uCount == 0) 64 | m_uCount = 1; 65 | 66 | unsigned int m_uTotal = m_uIndex + m_uCount; 67 | if (m_uTotal >= m_uMaxLength) 68 | return; 69 | 70 | if (m_uMaxLength > (m_uTotal + 1)) 71 | { 72 | for (unsigned int u = m_uIndex; (static_cast(m_uMaxLength) - m_uTotal) >= u; ++u) 73 | operator[](u) = operator[](u + m_uCount); 74 | } 75 | 76 | m_uMaxLength -= m_uCount; 77 | } 78 | 79 | void RemoveAll() 80 | { 81 | if (m_uMaxLength > 0) 82 | { 83 | memset(GetData(), 0, sizeof(T) * m_uMaxLength); 84 | m_uMaxLength = 0; 85 | } 86 | } 87 | }; 88 | 89 | // Defined here because its basically same shit 90 | template 91 | struct il2cppList : il2cppObject 92 | { 93 | il2cppArray* m_pListArray; 94 | 95 | il2cppArray* ToArray() { return m_pListArray; } 96 | }; 97 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Unity/Structures/il2cppDictionary.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Unity 4 | { 5 | template 6 | struct il2cppDictionary : il2cppObject 7 | { 8 | struct Entry 9 | { 10 | int m_iHashCode; 11 | int m_iNext; 12 | TKey m_tKey; 13 | TValue m_tValue; 14 | }; 15 | il2cppArray* m_pBuckets; 16 | il2cppArray* m_pEntries; 17 | int m_iCount; 18 | int m_iVersion; 19 | int m_iFreeList; 20 | int m_iFreeCount; 21 | void* m_pComparer; 22 | void* m_pKeys; 23 | void* m_pValues; 24 | 25 | Entry* GetEntry() 26 | { 27 | return (Entry*)m_pEntries->GetData(); 28 | } 29 | 30 | TKey GetKeyByIndex(int iIndex) 31 | { 32 | TKey tKey = { 0 }; 33 | 34 | Entry* pEntry = GetEntry(); 35 | if (pEntry) 36 | tKey = pEntry[iIndex].m_tKey; 37 | 38 | return tKey; 39 | } 40 | 41 | TValue GetValueByIndex(int iIndex) 42 | { 43 | TValue tValue = { 0 }; 44 | 45 | Entry* pEntry = GetEntry(); 46 | if (pEntry) 47 | tValue = pEntry[iIndex].m_tValue; 48 | 49 | return tValue; 50 | } 51 | 52 | TValue GetValueByKey(TKey tKey) 53 | { 54 | TValue tValue = { 0 }; 55 | for (int i = 0; i < m_iCount; i++) { 56 | if (GetEntry()[i].m_tKey == tKey) 57 | tValue = GetEntry()[i].m_tValue; 58 | } 59 | return tValue; 60 | } 61 | }; 62 | } 63 | -------------------------------------------------------------------------------- /src/il2cppresolver/Utils/Helper.cpp: -------------------------------------------------------------------------------- 1 | #include "../Includes.hpp" 2 | 3 | namespace IL2CPP 4 | { 5 | namespace Helper 6 | { 7 | Unity::CComponent* GetMonoBehaviour() 8 | { 9 | Unity::il2cppArray* m_pObjects = Unity::Object::FindObjectsOfType(UNITY_GAMEOBJECT_CLASS); 10 | for (uintptr_t u = 0U; m_pObjects->m_uMaxLength > u; ++u) 11 | { 12 | Unity::CGameObject* m_pObject = m_pObjects->operator[](static_cast(u)); 13 | if (!m_pObject) continue; 14 | 15 | Unity::CComponent* m_pMonoBehaviour = m_pObject->GetComponentByIndex(UNITY_MONOBEHAVIOUR_CLASS); 16 | if (m_pMonoBehaviour) 17 | return m_pMonoBehaviour; 18 | } 19 | 20 | return nullptr; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Utils/Helper.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace IL2CPP 4 | { 5 | namespace Helper 6 | { 7 | Unity::CComponent* GetMonoBehaviour(); 8 | } 9 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Utils/Joaat.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace IL2CPP 4 | { 5 | namespace Utils 6 | { 7 | inline unsigned int JOAAT(const char* str) 8 | { 9 | unsigned int m_uHash = 0; 10 | 11 | while (*str) 12 | { 13 | m_uHash += *(str++); 14 | m_uHash += (m_uHash << 10); 15 | m_uHash ^= (m_uHash >> 6); 16 | } 17 | 18 | m_uHash += (m_uHash << 3); 19 | m_uHash ^= (m_uHash >> 11); 20 | m_uHash += (m_uHash << 15); 21 | 22 | return m_uHash; 23 | } 24 | 25 | inline constexpr unsigned int JOAAT_CONSTEXPR(const char* str) 26 | { 27 | unsigned int m_uHash = 0; 28 | 29 | while (*str) 30 | { 31 | m_uHash += *(str++); 32 | m_uHash += (m_uHash << 10); 33 | m_uHash ^= (m_uHash >> 6); 34 | } 35 | 36 | m_uHash += (m_uHash << 3); 37 | m_uHash ^= (m_uHash >> 11); 38 | m_uHash += (m_uHash << 15); 39 | 40 | return m_uHash; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/il2cppresolver/Utils/VFunc.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace VFunc 4 | { 5 | static void** Find_ASM(void** m_pVTable, int m_iCount, std::initializer_list m_lASM) 6 | { 7 | int m_iASMSize = static_cast(m_lASM.size()); 8 | unsigned char* m_pBytes = const_cast(m_lASM.begin()); 9 | 10 | for (int i = 0; m_iCount > i; ++i) 11 | { 12 | void* m_pVFunc = m_pVTable[i]; 13 | unsigned char* m_pVFuncBytes = reinterpret_cast(m_pVFunc); 14 | 15 | bool m_bAllMatch = true; 16 | for (int b = 0; m_iASMSize > b; ++b) 17 | { 18 | if (m_pBytes[b] != m_pVFuncBytes[b]) 19 | { 20 | m_bAllMatch = false; 21 | break; 22 | } 23 | } 24 | 25 | if (m_bAllMatch) 26 | return &m_pVTable[i]; 27 | } 28 | 29 | return 0; 30 | } 31 | } -------------------------------------------------------------------------------- /src/imgui/imconfig.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // COMPILE-TIME OPTIONS FOR DEAR IMGUI 3 | // Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure. 4 | // You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions. 5 | //----------------------------------------------------------------------------- 6 | // A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it) 7 | // B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template. 8 | //----------------------------------------------------------------------------- 9 | // You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp 10 | // files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures. 11 | // Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts. 12 | // Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using. 13 | //----------------------------------------------------------------------------- 14 | 15 | #pragma once 16 | 17 | //---- Define assertion handler. Defaults to calling assert(). 18 | // If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement. 19 | //#define IM_ASSERT(_EXPR) MyAssert(_EXPR) 20 | //#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts 21 | 22 | //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows 23 | // Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility. 24 | // DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions() 25 | // for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details. 26 | //#define IMGUI_API __declspec( dllexport ) 27 | //#define IMGUI_API __declspec( dllimport ) 28 | 29 | //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names. 30 | //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS 31 | //#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87: disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This will be folded into IMGUI_DISABLE_OBSOLETE_FUNCTIONS in a few versions. 32 | 33 | //---- Disable all of Dear ImGui or don't implement standard windows/tools. 34 | // It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp. 35 | //#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty. 36 | //#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. 37 | //#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowStackToolWindow() will be empty (this was called IMGUI_DISABLE_METRICS_WINDOW before 1.88). 38 | 39 | //---- Don't implement some functions to reduce linkage requirements. 40 | //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a) 41 | //#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW) 42 | //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a) 43 | //#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime). 44 | //#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default). 45 | //#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf) 46 | //#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself. 47 | //#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies) 48 | //#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function. 49 | //#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions(). 50 | //#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available 51 | 52 | //---- Include imgui_user.h at the end of imgui.h as a convenience 53 | //#define IMGUI_INCLUDE_IMGUI_USER_H 54 | 55 | //---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another) 56 | //#define IMGUI_USE_BGRA_PACKED_COLOR 57 | 58 | //---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...) 59 | //#define IMGUI_USE_WCHAR32 60 | 61 | //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version 62 | // By default the embedded implementations are declared static and not available outside of Dear ImGui sources files. 63 | //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" 64 | //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" 65 | //#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if enabled 66 | //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION 67 | //#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION 68 | 69 | //---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined) 70 | // Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h. 71 | //#define IMGUI_USE_STB_SPRINTF 72 | 73 | //---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui) 74 | // Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided). 75 | // On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'. 76 | //#define IMGUI_ENABLE_FREETYPE 77 | 78 | //---- Use stb_truetype to build and rasterize the font atlas (default) 79 | // The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend. 80 | //#define IMGUI_ENABLE_STB_TRUETYPE 81 | 82 | //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4. 83 | // This will be inlined as part of ImVec2 and ImVec4 class declarations. 84 | /* 85 | #define IM_VEC2_CLASS_EXTRA \ 86 | constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \ 87 | operator MyVec2() const { return MyVec2(x,y); } 88 | 89 | #define IM_VEC4_CLASS_EXTRA \ 90 | constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \ 91 | operator MyVec4() const { return MyVec4(x,y,z,w); } 92 | */ 93 | //---- ...Or use Dear ImGui's own very basic math operators. 94 | //#define IMGUI_DEFINE_MATH_OPERATORS 95 | 96 | //---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices. 97 | // Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices). 98 | // Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer. 99 | // Read about ImGuiBackendFlags_RendererHasVtxOffset for details. 100 | //#define ImDrawIdx unsigned int 101 | 102 | //---- Override ImDrawCallback signature (will need to modify renderer backends accordingly) 103 | //struct ImDrawList; 104 | //struct ImDrawCmd; 105 | //typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data); 106 | //#define ImDrawCallback MyImDrawCallback 107 | 108 | //---- Debug Tools: Macro to break in Debugger 109 | // (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.) 110 | //#define IM_DEBUG_BREAK IM_ASSERT(0) 111 | //#define IM_DEBUG_BREAK __debugbreak() 112 | 113 | //---- Debug Tools: Enable slower asserts 114 | //#define IMGUI_DEBUG_PARANOID 115 | 116 | //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files. 117 | /* 118 | namespace ImGui 119 | { 120 | void MyFunction(const char* name, const MyMatrix44& v); 121 | } 122 | */ 123 | -------------------------------------------------------------------------------- /src/imgui/imgui_impl_dx11.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Renderer Backend for DirectX11 2 | // This needs to be used along with a Platform Backend (e.g. Win32) 3 | 4 | // Implemented features: 5 | // [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID! 6 | // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. 7 | 8 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. 9 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. 10 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. 11 | // Read online: https://github.com/ocornut/imgui/tree/master/docs 12 | 13 | #pragma once 14 | #include "imgui.h" // IMGUI_IMPL_API 15 | 16 | struct ID3D11Device; 17 | struct ID3D11DeviceContext; 18 | 19 | IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context); 20 | IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown(); 21 | IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame(); 22 | IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data); 23 | 24 | // Use if you want to reset your rendering device without losing Dear ImGui state. 25 | IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects(); 26 | IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects(); 27 | -------------------------------------------------------------------------------- /src/imgui/imgui_impl_win32.h: -------------------------------------------------------------------------------- 1 | // dear imgui: Platform Backend for Windows (standard windows API for 32-bits AND 64-bits applications) 2 | // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) 3 | 4 | // Implemented features: 5 | // [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui) 6 | // [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen. 7 | // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] 8 | // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. 9 | // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. 10 | 11 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. 12 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. 13 | // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. 14 | // Read online: https://github.com/ocornut/imgui/tree/master/docs 15 | 16 | #pragma once 17 | #include "imgui.h" // IMGUI_IMPL_API 18 | 19 | IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd); 20 | IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown(); 21 | IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame(); 22 | 23 | // Win32 message handler your application need to call. 24 | // - Intentionally commented out in a '#if 0' block to avoid dragging dependencies on from this helper. 25 | // - You should COPY the line below into your .cpp code to forward declare the function and then you can call it. 26 | // - Call from your application's message handler. Keep calling your message handler unless this function returns TRUE. 27 | 28 | #if 0 29 | extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 30 | #endif 31 | 32 | // DPI-related helpers (optional) 33 | // - Use to enable DPI awareness without having to create an application manifest. 34 | // - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps. 35 | // - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc. 36 | // but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime, 37 | // neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies. 38 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness(); 39 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd 40 | IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor 41 | 42 | // Transparency related helpers (optional) [experimental] 43 | // - Use to enable alpha compositing transparency with the desktop. 44 | // - Use together with e.g. clearing your framebuffer with zero-alpha. 45 | IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd 46 | -------------------------------------------------------------------------------- /src/imgui/imgui_stdlib.cpp: -------------------------------------------------------------------------------- 1 | // dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.) 2 | // This is also an example of how you may wrap your own similar types. 3 | 4 | // Changelog: 5 | // - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string 6 | 7 | // See more C++ related extension (fmt, RAII, syntaxis sugar) on Wiki: 8 | // https://github.com/ocornut/imgui/wiki/Useful-Extensions#cness 9 | 10 | #include "../imgui/imgui.h" 11 | #include "imgui_stdlib.h" 12 | 13 | struct InputTextCallback_UserData 14 | { 15 | std::string* Str; 16 | ImGuiInputTextCallback ChainCallback; 17 | void* ChainCallbackUserData; 18 | }; 19 | 20 | static int InputTextCallback(ImGuiInputTextCallbackData* data) 21 | { 22 | InputTextCallback_UserData* user_data = (InputTextCallback_UserData*)data->UserData; 23 | if (data->EventFlag == ImGuiInputTextFlags_CallbackResize) 24 | { 25 | // Resize string callback 26 | // If for some reason we refuse the new length (BufTextLen) and/or capacity (BufSize) we need to set them back to what we want. 27 | std::string* str = user_data->Str; 28 | IM_ASSERT(data->Buf == str->c_str()); 29 | str->resize(data->BufTextLen); 30 | data->Buf = (char*)str->c_str(); 31 | } 32 | else if (user_data->ChainCallback) 33 | { 34 | // Forward to user callback, if any 35 | data->UserData = user_data->ChainCallbackUserData; 36 | return user_data->ChainCallback(data); 37 | } 38 | return 0; 39 | } 40 | 41 | bool ImGui::InputText(const char* label, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) 42 | { 43 | IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); 44 | flags |= ImGuiInputTextFlags_CallbackResize; 45 | 46 | InputTextCallback_UserData cb_user_data; 47 | cb_user_data.Str = str; 48 | cb_user_data.ChainCallback = callback; 49 | cb_user_data.ChainCallbackUserData = user_data; 50 | return InputText(label, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data); 51 | } 52 | 53 | bool ImGui::InputTextMultiline(const char* label, std::string* str, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) 54 | { 55 | IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); 56 | flags |= ImGuiInputTextFlags_CallbackResize; 57 | 58 | InputTextCallback_UserData cb_user_data; 59 | cb_user_data.Str = str; 60 | cb_user_data.ChainCallback = callback; 61 | cb_user_data.ChainCallbackUserData = user_data; 62 | return InputTextMultiline(label, (char*)str->c_str(), str->capacity() + 1, size, flags, InputTextCallback, &cb_user_data); 63 | } 64 | 65 | bool ImGui::InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) 66 | { 67 | IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); 68 | flags |= ImGuiInputTextFlags_CallbackResize; 69 | 70 | InputTextCallback_UserData cb_user_data; 71 | cb_user_data.Str = str; 72 | cb_user_data.ChainCallback = callback; 73 | cb_user_data.ChainCallbackUserData = user_data; 74 | return InputTextWithHint(label, hint, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data); 75 | } -------------------------------------------------------------------------------- /src/imgui/imgui_stdlib.h: -------------------------------------------------------------------------------- 1 | // dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.) 2 | // This is also an example of how you may wrap your own similar types. 3 | 4 | // Changelog: 5 | // - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string 6 | 7 | // See more C++ related extension (fmt, RAII, syntaxis sugar) on Wiki: 8 | // https://github.com/ocornut/imgui/wiki/Useful-Extensions#cness 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | namespace ImGui 15 | { 16 | // ImGui::InputText() with std::string 17 | // Because text input needs dynamic resizing, we need to setup a callback to grow the capacity 18 | IMGUI_API bool InputText(const char* label, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr); 19 | IMGUI_API bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr); 20 | IMGUI_API bool InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr); 21 | } -------------------------------------------------------------------------------- /src/kiero/kiero.h: -------------------------------------------------------------------------------- 1 | #ifndef __KIERO_H__ 2 | #define __KIERO_H__ 3 | 4 | #include 5 | 6 | #define KIERO_VERSION "1.2.6" 7 | 8 | #define KIERO_INCLUDE_D3D9 0 // 1 if you need D3D9 hook 9 | #define KIERO_INCLUDE_D3D10 0 // 1 if you need D3D10 hook 10 | #define KIERO_INCLUDE_D3D11 1 // 1 if you need D3D11 hook 11 | #define KIERO_INCLUDE_D3D12 0 // 1 if you need D3D12 hook 12 | #define KIERO_INCLUDE_OPENGL 0 // 1 if you need OpenGL hook 13 | #define KIERO_INCLUDE_VULKAN 0 // 1 if you need Vulkan hook 14 | #define KIERO_USE_MINHOOK 1 // 1 if you will use kiero::bind function 15 | 16 | #define KIERO_ARCH_X64 0 17 | #define KIERO_ARCH_X86 0 18 | 19 | #if defined(_M_X64) 20 | # undef KIERO_ARCH_X64 21 | # define KIERO_ARCH_X64 1 22 | #else 23 | # undef KIERO_ARCH_X86 24 | # define KIERO_ARCH_X86 1 25 | #endif 26 | 27 | #if KIERO_ARCH_X64 28 | typedef uint64_t uint150_t; 29 | #else 30 | typedef uint32_t uint150_t; 31 | #endif 32 | 33 | namespace kiero 34 | { 35 | struct Status 36 | { 37 | enum Enum 38 | { 39 | UnknownError = -1, 40 | NotSupportedError = -2, 41 | ModuleNotFoundError = -3, 42 | 43 | AlreadyInitializedError = -4, 44 | NotInitializedError = -5, 45 | 46 | Success = 0, 47 | }; 48 | }; 49 | 50 | struct RenderType 51 | { 52 | enum Enum 53 | { 54 | None, 55 | 56 | D3D9, 57 | D3D10, 58 | D3D11, 59 | D3D12, 60 | 61 | OpenGL, 62 | Vulkan, 63 | 64 | Auto 65 | }; 66 | }; 67 | 68 | Status::Enum init(RenderType::Enum renderType); 69 | void shutdown(); 70 | 71 | Status::Enum bind(uint16_t index, void** original, void* function); 72 | void unbind(uint16_t index); 73 | 74 | RenderType::Enum getRenderType(); 75 | uint150_t* getMethodsTable(); 76 | } 77 | 78 | #endif // __KIERO_H__ -------------------------------------------------------------------------------- /src/kiero/minhook/dll_resources/MinHook.aps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImAxel0/IL2CPP_Scanner_DX11/0207e04c4cddf6680a6da8bc2a7349b75ad9831b/src/kiero/minhook/dll_resources/MinHook.aps -------------------------------------------------------------------------------- /src/kiero/minhook/dll_resources/MinHook.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | MH_Initialize 3 | MH_Uninitialize 4 | 5 | MH_CreateHook 6 | MH_CreateHookApi 7 | MH_CreateHookApiEx 8 | MH_RemoveHook 9 | MH_EnableHook 10 | MH_DisableHook 11 | MH_QueueEnableHook 12 | MH_QueueDisableHook 13 | MH_ApplyQueued 14 | MH_StatusToString 15 | -------------------------------------------------------------------------------- /src/kiero/minhook/dll_resources/MinHook.rc: -------------------------------------------------------------------------------- 1 | 1 VERSIONINFO 2 | FILEVERSION 1,3,3,0 3 | PRODUCTVERSION 1,3,3,0 4 | FILEFLAGSMASK 0x17L 5 | #ifdef _DEBUG 6 | FILEFLAGS 0x1L 7 | #else 8 | FILEFLAGS 0x0L 9 | #endif 10 | FILEOS 0x4L 11 | FILETYPE 0x2L 12 | FILESUBTYPE 0x0L 13 | BEGIN 14 | BLOCK "StringFileInfo" 15 | BEGIN 16 | BLOCK "040904b0" 17 | BEGIN 18 | VALUE "CompanyName", "Tsuda Kageyu" 19 | VALUE "FileDescription", "MinHook - The Minimalistic API Hook Library for x64/x86" 20 | VALUE "FileVersion", "1.3.3.0" 21 | VALUE "InternalName", "MinHookD" 22 | VALUE "LegalCopyright", "Copyright (C) 2009-2017 Tsuda Kageyu. All rights reserved." 23 | VALUE "LegalTrademarks", "Tsuda Kageyu" 24 | VALUE "ProductName", "MinHook DLL" 25 | VALUE "ProductVersion", "1.3.3.0" 26 | END 27 | END 28 | BLOCK "VarFileInfo" 29 | BEGIN 30 | VALUE "Translation", 0x409, 1200 31 | END 32 | END 33 | -------------------------------------------------------------------------------- /src/kiero/minhook/include/MinHook.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MinHook - The Minimalistic API Hooking Library for x64/x86 3 | * Copyright (C) 2009-2017 Tsuda Kageyu. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 20 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #if !(defined _M_IX86) && !(defined _M_X64) && !(defined __i386__) && !(defined __x86_64__) 32 | #error MinHook supports only x86 and x64 systems. 33 | #endif 34 | 35 | #include 36 | 37 | // MinHook Error Codes. 38 | typedef enum MH_STATUS 39 | { 40 | // Unknown error. Should not be returned. 41 | MH_UNKNOWN = -1, 42 | 43 | // Successful. 44 | MH_OK = 0, 45 | 46 | // MinHook is already initialized. 47 | MH_ERROR_ALREADY_INITIALIZED, 48 | 49 | // MinHook is not initialized yet, or already uninitialized. 50 | MH_ERROR_NOT_INITIALIZED, 51 | 52 | // The hook for the specified target function is already created. 53 | MH_ERROR_ALREADY_CREATED, 54 | 55 | // The hook for the specified target function is not created yet. 56 | MH_ERROR_NOT_CREATED, 57 | 58 | // The hook for the specified target function is already enabled. 59 | MH_ERROR_ENABLED, 60 | 61 | // The hook for the specified target function is not enabled yet, or already 62 | // disabled. 63 | MH_ERROR_DISABLED, 64 | 65 | // The specified pointer is invalid. It points the address of non-allocated 66 | // and/or non-executable region. 67 | MH_ERROR_NOT_EXECUTABLE, 68 | 69 | // The specified target function cannot be hooked. 70 | MH_ERROR_UNSUPPORTED_FUNCTION, 71 | 72 | // Failed to allocate memory. 73 | MH_ERROR_MEMORY_ALLOC, 74 | 75 | // Failed to change the memory protection. 76 | MH_ERROR_MEMORY_PROTECT, 77 | 78 | // The specified module is not loaded. 79 | MH_ERROR_MODULE_NOT_FOUND, 80 | 81 | // The specified function is not found. 82 | MH_ERROR_FUNCTION_NOT_FOUND 83 | } 84 | MH_STATUS; 85 | 86 | // Can be passed as a parameter to MH_EnableHook, MH_DisableHook, 87 | // MH_QueueEnableHook or MH_QueueDisableHook. 88 | #define MH_ALL_HOOKS NULL 89 | 90 | #ifdef __cplusplus 91 | extern "C" { 92 | #endif 93 | 94 | // Initialize the MinHook library. You must call this function EXACTLY ONCE 95 | // at the beginning of your program. 96 | MH_STATUS WINAPI MH_Initialize(VOID); 97 | 98 | // Uninitialize the MinHook library. You must call this function EXACTLY 99 | // ONCE at the end of your program. 100 | MH_STATUS WINAPI MH_Uninitialize(VOID); 101 | 102 | // Creates a Hook for the specified target function, in disabled state. 103 | // Parameters: 104 | // pTarget [in] A pointer to the target function, which will be 105 | // overridden by the detour function. 106 | // pDetour [in] A pointer to the detour function, which will override 107 | // the target function. 108 | // ppOriginal [out] A pointer to the trampoline function, which will be 109 | // used to call the original target function. 110 | // This parameter can be NULL. 111 | MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal); 112 | 113 | // Creates a Hook for the specified API function, in disabled state. 114 | // Parameters: 115 | // pszModule [in] A pointer to the loaded module name which contains the 116 | // target function. 117 | // pszTarget [in] A pointer to the target function name, which will be 118 | // overridden by the detour function. 119 | // pDetour [in] A pointer to the detour function, which will override 120 | // the target function. 121 | // ppOriginal [out] A pointer to the trampoline function, which will be 122 | // used to call the original target function. 123 | // This parameter can be NULL. 124 | MH_STATUS WINAPI MH_CreateHookApi( 125 | LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal); 126 | 127 | // Creates a Hook for the specified API function, in disabled state. 128 | // Parameters: 129 | // pszModule [in] A pointer to the loaded module name which contains the 130 | // target function. 131 | // pszTarget [in] A pointer to the target function name, which will be 132 | // overridden by the detour function. 133 | // pDetour [in] A pointer to the detour function, which will override 134 | // the target function. 135 | // ppOriginal [out] A pointer to the trampoline function, which will be 136 | // used to call the original target function. 137 | // This parameter can be NULL. 138 | // ppTarget [out] A pointer to the target function, which will be used 139 | // with other functions. 140 | // This parameter can be NULL. 141 | MH_STATUS WINAPI MH_CreateHookApiEx( 142 | LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal, LPVOID *ppTarget); 143 | 144 | // Removes an already created hook. 145 | // Parameters: 146 | // pTarget [in] A pointer to the target function. 147 | MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget); 148 | 149 | // Enables an already created hook. 150 | // Parameters: 151 | // pTarget [in] A pointer to the target function. 152 | // If this parameter is MH_ALL_HOOKS, all created hooks are 153 | // enabled in one go. 154 | MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget); 155 | 156 | // Disables an already created hook. 157 | // Parameters: 158 | // pTarget [in] A pointer to the target function. 159 | // If this parameter is MH_ALL_HOOKS, all created hooks are 160 | // disabled in one go. 161 | MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget); 162 | 163 | // Queues to enable an already created hook. 164 | // Parameters: 165 | // pTarget [in] A pointer to the target function. 166 | // If this parameter is MH_ALL_HOOKS, all created hooks are 167 | // queued to be enabled. 168 | MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget); 169 | 170 | // Queues to disable an already created hook. 171 | // Parameters: 172 | // pTarget [in] A pointer to the target function. 173 | // If this parameter is MH_ALL_HOOKS, all created hooks are 174 | // queued to be disabled. 175 | MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget); 176 | 177 | // Applies all queued changes in one go. 178 | MH_STATUS WINAPI MH_ApplyQueued(VOID); 179 | 180 | // Translates the MH_STATUS to its name as a string. 181 | const char * WINAPI MH_StatusToString(MH_STATUS status); 182 | 183 | #ifdef __cplusplus 184 | } 185 | #endif 186 | 187 | -------------------------------------------------------------------------------- /src/kiero/minhook/src/buffer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MinHook - The Minimalistic API Hooking Library for x64/x86 3 | * Copyright (C) 2009-2017 Tsuda Kageyu. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 20 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | #include "buffer.h" 31 | 32 | // Size of each memory block. (= page size of VirtualAlloc) 33 | #define MEMORY_BLOCK_SIZE 0x1000 34 | 35 | // Max range for seeking a memory block. (= 1024MB) 36 | #define MAX_MEMORY_RANGE 0x40000000 37 | 38 | // Memory protection flags to check the executable address. 39 | #define PAGE_EXECUTE_FLAGS \ 40 | (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) 41 | 42 | // Memory slot. 43 | typedef struct _MEMORY_SLOT 44 | { 45 | union 46 | { 47 | struct _MEMORY_SLOT *pNext; 48 | UINT8 buffer[MEMORY_SLOT_SIZE]; 49 | }; 50 | } MEMORY_SLOT, *PMEMORY_SLOT; 51 | 52 | // Memory block info. Placed at the head of each block. 53 | typedef struct _MEMORY_BLOCK 54 | { 55 | struct _MEMORY_BLOCK *pNext; 56 | PMEMORY_SLOT pFree; // First element of the free slot list. 57 | UINT usedCount; 58 | } MEMORY_BLOCK, *PMEMORY_BLOCK; 59 | 60 | //------------------------------------------------------------------------- 61 | // Global Variables: 62 | //------------------------------------------------------------------------- 63 | 64 | // First element of the memory block list. 65 | PMEMORY_BLOCK g_pMemoryBlocks; 66 | 67 | //------------------------------------------------------------------------- 68 | VOID InitializeBuffer(VOID) 69 | { 70 | // Nothing to do for now. 71 | } 72 | 73 | //------------------------------------------------------------------------- 74 | VOID UninitializeBuffer(VOID) 75 | { 76 | PMEMORY_BLOCK pBlock = g_pMemoryBlocks; 77 | g_pMemoryBlocks = NULL; 78 | 79 | while (pBlock) 80 | { 81 | PMEMORY_BLOCK pNext = pBlock->pNext; 82 | VirtualFree(pBlock, 0, MEM_RELEASE); 83 | pBlock = pNext; 84 | } 85 | } 86 | 87 | //------------------------------------------------------------------------- 88 | #if defined(_M_X64) || defined(__x86_64__) 89 | static LPVOID FindPrevFreeRegion(LPVOID pAddress, LPVOID pMinAddr, DWORD dwAllocationGranularity) 90 | { 91 | ULONG_PTR tryAddr = (ULONG_PTR)pAddress; 92 | 93 | // Round down to the allocation granularity. 94 | tryAddr -= tryAddr % dwAllocationGranularity; 95 | 96 | // Start from the previous allocation granularity multiply. 97 | tryAddr -= dwAllocationGranularity; 98 | 99 | while (tryAddr >= (ULONG_PTR)pMinAddr) 100 | { 101 | MEMORY_BASIC_INFORMATION mbi; 102 | if (VirtualQuery((LPVOID)tryAddr, &mbi, sizeof(mbi)) == 0) 103 | break; 104 | 105 | if (mbi.State == MEM_FREE) 106 | return (LPVOID)tryAddr; 107 | 108 | if ((ULONG_PTR)mbi.AllocationBase < dwAllocationGranularity) 109 | break; 110 | 111 | tryAddr = (ULONG_PTR)mbi.AllocationBase - dwAllocationGranularity; 112 | } 113 | 114 | return NULL; 115 | } 116 | #endif 117 | 118 | //------------------------------------------------------------------------- 119 | #if defined(_M_X64) || defined(__x86_64__) 120 | static LPVOID FindNextFreeRegion(LPVOID pAddress, LPVOID pMaxAddr, DWORD dwAllocationGranularity) 121 | { 122 | ULONG_PTR tryAddr = (ULONG_PTR)pAddress; 123 | 124 | // Round down to the allocation granularity. 125 | tryAddr -= tryAddr % dwAllocationGranularity; 126 | 127 | // Start from the next allocation granularity multiply. 128 | tryAddr += dwAllocationGranularity; 129 | 130 | while (tryAddr <= (ULONG_PTR)pMaxAddr) 131 | { 132 | MEMORY_BASIC_INFORMATION mbi; 133 | if (VirtualQuery((LPVOID)tryAddr, &mbi, sizeof(mbi)) == 0) 134 | break; 135 | 136 | if (mbi.State == MEM_FREE) 137 | return (LPVOID)tryAddr; 138 | 139 | tryAddr = (ULONG_PTR)mbi.BaseAddress + mbi.RegionSize; 140 | 141 | // Round up to the next allocation granularity. 142 | tryAddr += dwAllocationGranularity - 1; 143 | tryAddr -= tryAddr % dwAllocationGranularity; 144 | } 145 | 146 | return NULL; 147 | } 148 | #endif 149 | 150 | //------------------------------------------------------------------------- 151 | static PMEMORY_BLOCK GetMemoryBlock(LPVOID pOrigin) 152 | { 153 | PMEMORY_BLOCK pBlock; 154 | #if defined(_M_X64) || defined(__x86_64__) 155 | ULONG_PTR minAddr; 156 | ULONG_PTR maxAddr; 157 | 158 | SYSTEM_INFO si; 159 | GetSystemInfo(&si); 160 | minAddr = (ULONG_PTR)si.lpMinimumApplicationAddress; 161 | maxAddr = (ULONG_PTR)si.lpMaximumApplicationAddress; 162 | 163 | // pOrigin ± 512MB 164 | if ((ULONG_PTR)pOrigin > MAX_MEMORY_RANGE && minAddr < (ULONG_PTR)pOrigin - MAX_MEMORY_RANGE) 165 | minAddr = (ULONG_PTR)pOrigin - MAX_MEMORY_RANGE; 166 | 167 | if (maxAddr > (ULONG_PTR)pOrigin + MAX_MEMORY_RANGE) 168 | maxAddr = (ULONG_PTR)pOrigin + MAX_MEMORY_RANGE; 169 | 170 | // Make room for MEMORY_BLOCK_SIZE bytes. 171 | maxAddr -= MEMORY_BLOCK_SIZE - 1; 172 | #endif 173 | 174 | // Look the registered blocks for a reachable one. 175 | for (pBlock = g_pMemoryBlocks; pBlock != NULL; pBlock = pBlock->pNext) 176 | { 177 | #if defined(_M_X64) || defined(__x86_64__) 178 | // Ignore the blocks too far. 179 | if ((ULONG_PTR)pBlock < minAddr || (ULONG_PTR)pBlock >= maxAddr) 180 | continue; 181 | #endif 182 | // The block has at least one unused slot. 183 | if (pBlock->pFree != NULL) 184 | return pBlock; 185 | } 186 | 187 | #if defined(_M_X64) || defined(__x86_64__) 188 | // Alloc a new block above if not found. 189 | { 190 | LPVOID pAlloc = pOrigin; 191 | while ((ULONG_PTR)pAlloc >= minAddr) 192 | { 193 | pAlloc = FindPrevFreeRegion(pAlloc, (LPVOID)minAddr, si.dwAllocationGranularity); 194 | if (pAlloc == NULL) 195 | break; 196 | 197 | pBlock = (PMEMORY_BLOCK)VirtualAlloc( 198 | pAlloc, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 199 | if (pBlock != NULL) 200 | break; 201 | } 202 | } 203 | 204 | // Alloc a new block below if not found. 205 | if (pBlock == NULL) 206 | { 207 | LPVOID pAlloc = pOrigin; 208 | while ((ULONG_PTR)pAlloc <= maxAddr) 209 | { 210 | pAlloc = FindNextFreeRegion(pAlloc, (LPVOID)maxAddr, si.dwAllocationGranularity); 211 | if (pAlloc == NULL) 212 | break; 213 | 214 | pBlock = (PMEMORY_BLOCK)VirtualAlloc( 215 | pAlloc, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 216 | if (pBlock != NULL) 217 | break; 218 | } 219 | } 220 | #else 221 | // In x86 mode, a memory block can be placed anywhere. 222 | pBlock = (PMEMORY_BLOCK)VirtualAlloc( 223 | NULL, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 224 | #endif 225 | 226 | if (pBlock != NULL) 227 | { 228 | // Build a linked list of all the slots. 229 | PMEMORY_SLOT pSlot = (PMEMORY_SLOT)pBlock + 1; 230 | pBlock->pFree = NULL; 231 | pBlock->usedCount = 0; 232 | do 233 | { 234 | pSlot->pNext = pBlock->pFree; 235 | pBlock->pFree = pSlot; 236 | pSlot++; 237 | } while ((ULONG_PTR)pSlot - (ULONG_PTR)pBlock <= MEMORY_BLOCK_SIZE - MEMORY_SLOT_SIZE); 238 | 239 | pBlock->pNext = g_pMemoryBlocks; 240 | g_pMemoryBlocks = pBlock; 241 | } 242 | 243 | return pBlock; 244 | } 245 | 246 | //------------------------------------------------------------------------- 247 | LPVOID AllocateBuffer(LPVOID pOrigin) 248 | { 249 | PMEMORY_SLOT pSlot; 250 | PMEMORY_BLOCK pBlock = GetMemoryBlock(pOrigin); 251 | if (pBlock == NULL) 252 | return NULL; 253 | 254 | // Remove an unused slot from the list. 255 | pSlot = pBlock->pFree; 256 | pBlock->pFree = pSlot->pNext; 257 | pBlock->usedCount++; 258 | #ifdef _DEBUG 259 | // Fill the slot with INT3 for debugging. 260 | memset(pSlot, 0xCC, sizeof(MEMORY_SLOT)); 261 | #endif 262 | return pSlot; 263 | } 264 | 265 | //------------------------------------------------------------------------- 266 | VOID FreeBuffer(LPVOID pBuffer) 267 | { 268 | PMEMORY_BLOCK pBlock = g_pMemoryBlocks; 269 | PMEMORY_BLOCK pPrev = NULL; 270 | ULONG_PTR pTargetBlock = ((ULONG_PTR)pBuffer / MEMORY_BLOCK_SIZE) * MEMORY_BLOCK_SIZE; 271 | 272 | while (pBlock != NULL) 273 | { 274 | if ((ULONG_PTR)pBlock == pTargetBlock) 275 | { 276 | PMEMORY_SLOT pSlot = (PMEMORY_SLOT)pBuffer; 277 | #ifdef _DEBUG 278 | // Clear the released slot for debugging. 279 | memset(pSlot, 0x00, sizeof(*pSlot)); 280 | #endif 281 | // Restore the released slot to the list. 282 | pSlot->pNext = pBlock->pFree; 283 | pBlock->pFree = pSlot; 284 | pBlock->usedCount--; 285 | 286 | // Free if unused. 287 | if (pBlock->usedCount == 0) 288 | { 289 | if (pPrev) 290 | pPrev->pNext = pBlock->pNext; 291 | else 292 | g_pMemoryBlocks = pBlock->pNext; 293 | 294 | VirtualFree(pBlock, 0, MEM_RELEASE); 295 | } 296 | 297 | break; 298 | } 299 | 300 | pPrev = pBlock; 301 | pBlock = pBlock->pNext; 302 | } 303 | } 304 | 305 | //------------------------------------------------------------------------- 306 | BOOL IsExecutableAddress(LPVOID pAddress) 307 | { 308 | MEMORY_BASIC_INFORMATION mi; 309 | VirtualQuery(pAddress, &mi, sizeof(mi)); 310 | 311 | return (mi.State == MEM_COMMIT && (mi.Protect & PAGE_EXECUTE_FLAGS)); 312 | } 313 | -------------------------------------------------------------------------------- /src/kiero/minhook/src/buffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MinHook - The Minimalistic API Hooking Library for x64/x86 3 | * Copyright (C) 2009-2017 Tsuda Kageyu. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 20 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | // Size of each memory slot. 32 | #if defined(_M_X64) || defined(__x86_64__) 33 | #define MEMORY_SLOT_SIZE 64 34 | #else 35 | #define MEMORY_SLOT_SIZE 32 36 | #endif 37 | 38 | VOID InitializeBuffer(VOID); 39 | VOID UninitializeBuffer(VOID); 40 | LPVOID AllocateBuffer(LPVOID pOrigin); 41 | VOID FreeBuffer(LPVOID pBuffer); 42 | BOOL IsExecutableAddress(LPVOID pAddress); 43 | -------------------------------------------------------------------------------- /src/kiero/minhook/src/hde/hde32.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 32 C 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | */ 7 | 8 | #if defined(_M_IX86) || defined(__i386__) 9 | 10 | #include "hde32.h" 11 | #include "table32.h" 12 | 13 | unsigned int hde32_disasm(const void *code, hde32s *hs) 14 | { 15 | uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0; 16 | uint8_t *ht = hde32_table, m_mod, m_reg, m_rm, disp_size = 0; 17 | 18 | // Avoid using memset to reduce the footprint. 19 | #ifndef _MSC_VER 20 | memset((LPBYTE)hs, 0, sizeof(hde32s)); 21 | #else 22 | __stosb((LPBYTE)hs, 0, sizeof(hde32s)); 23 | #endif 24 | 25 | for (x = 16; x; x--) 26 | switch (c = *p++) { 27 | case 0xf3: 28 | hs->p_rep = c; 29 | pref |= PRE_F3; 30 | break; 31 | case 0xf2: 32 | hs->p_rep = c; 33 | pref |= PRE_F2; 34 | break; 35 | case 0xf0: 36 | hs->p_lock = c; 37 | pref |= PRE_LOCK; 38 | break; 39 | case 0x26: case 0x2e: case 0x36: 40 | case 0x3e: case 0x64: case 0x65: 41 | hs->p_seg = c; 42 | pref |= PRE_SEG; 43 | break; 44 | case 0x66: 45 | hs->p_66 = c; 46 | pref |= PRE_66; 47 | break; 48 | case 0x67: 49 | hs->p_67 = c; 50 | pref |= PRE_67; 51 | break; 52 | default: 53 | goto pref_done; 54 | } 55 | pref_done: 56 | 57 | hs->flags = (uint32_t)pref << 23; 58 | 59 | if (!pref) 60 | pref |= PRE_NONE; 61 | 62 | if ((hs->opcode = c) == 0x0f) { 63 | hs->opcode2 = c = *p++; 64 | ht += DELTA_OPCODES; 65 | } else if (c >= 0xa0 && c <= 0xa3) { 66 | if (pref & PRE_67) 67 | pref |= PRE_66; 68 | else 69 | pref &= ~PRE_66; 70 | } 71 | 72 | opcode = c; 73 | cflags = ht[ht[opcode / 4] + (opcode % 4)]; 74 | 75 | if (cflags == C_ERROR) { 76 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 77 | cflags = 0; 78 | if ((opcode & -3) == 0x24) 79 | cflags++; 80 | } 81 | 82 | x = 0; 83 | if (cflags & C_GROUP) { 84 | uint16_t t; 85 | t = *(uint16_t *)(ht + (cflags & 0x7f)); 86 | cflags = (uint8_t)t; 87 | x = (uint8_t)(t >> 8); 88 | } 89 | 90 | if (hs->opcode2) { 91 | ht = hde32_table + DELTA_PREFIXES; 92 | if (ht[ht[opcode / 4] + (opcode % 4)] & pref) 93 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 94 | } 95 | 96 | if (cflags & C_MODRM) { 97 | hs->flags |= F_MODRM; 98 | hs->modrm = c = *p++; 99 | hs->modrm_mod = m_mod = c >> 6; 100 | hs->modrm_rm = m_rm = c & 7; 101 | hs->modrm_reg = m_reg = (c & 0x3f) >> 3; 102 | 103 | if (x && ((x << m_reg) & 0x80)) 104 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 105 | 106 | if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { 107 | uint8_t t = opcode - 0xd9; 108 | if (m_mod == 3) { 109 | ht = hde32_table + DELTA_FPU_MODRM + t*8; 110 | t = ht[m_reg] << m_rm; 111 | } else { 112 | ht = hde32_table + DELTA_FPU_REG; 113 | t = ht[t] << m_reg; 114 | } 115 | if (t & 0x80) 116 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 117 | } 118 | 119 | if (pref & PRE_LOCK) { 120 | if (m_mod == 3) { 121 | hs->flags |= F_ERROR | F_ERROR_LOCK; 122 | } else { 123 | uint8_t *table_end, op = opcode; 124 | if (hs->opcode2) { 125 | ht = hde32_table + DELTA_OP2_LOCK_OK; 126 | table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; 127 | } else { 128 | ht = hde32_table + DELTA_OP_LOCK_OK; 129 | table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; 130 | op &= -2; 131 | } 132 | for (; ht != table_end; ht++) 133 | if (*ht++ == op) { 134 | if (!((*ht << m_reg) & 0x80)) 135 | goto no_lock_error; 136 | else 137 | break; 138 | } 139 | hs->flags |= F_ERROR | F_ERROR_LOCK; 140 | no_lock_error: 141 | ; 142 | } 143 | } 144 | 145 | if (hs->opcode2) { 146 | switch (opcode) { 147 | case 0x20: case 0x22: 148 | m_mod = 3; 149 | if (m_reg > 4 || m_reg == 1) 150 | goto error_operand; 151 | else 152 | goto no_error_operand; 153 | case 0x21: case 0x23: 154 | m_mod = 3; 155 | if (m_reg == 4 || m_reg == 5) 156 | goto error_operand; 157 | else 158 | goto no_error_operand; 159 | } 160 | } else { 161 | switch (opcode) { 162 | case 0x8c: 163 | if (m_reg > 5) 164 | goto error_operand; 165 | else 166 | goto no_error_operand; 167 | case 0x8e: 168 | if (m_reg == 1 || m_reg > 5) 169 | goto error_operand; 170 | else 171 | goto no_error_operand; 172 | } 173 | } 174 | 175 | if (m_mod == 3) { 176 | uint8_t *table_end; 177 | if (hs->opcode2) { 178 | ht = hde32_table + DELTA_OP2_ONLY_MEM; 179 | table_end = ht + sizeof(hde32_table) - DELTA_OP2_ONLY_MEM; 180 | } else { 181 | ht = hde32_table + DELTA_OP_ONLY_MEM; 182 | table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; 183 | } 184 | for (; ht != table_end; ht += 2) 185 | if (*ht++ == opcode) { 186 | if (*ht++ & pref && !((*ht << m_reg) & 0x80)) 187 | goto error_operand; 188 | else 189 | break; 190 | } 191 | goto no_error_operand; 192 | } else if (hs->opcode2) { 193 | switch (opcode) { 194 | case 0x50: case 0xd7: case 0xf7: 195 | if (pref & (PRE_NONE | PRE_66)) 196 | goto error_operand; 197 | break; 198 | case 0xd6: 199 | if (pref & (PRE_F2 | PRE_F3)) 200 | goto error_operand; 201 | break; 202 | case 0xc5: 203 | goto error_operand; 204 | } 205 | goto no_error_operand; 206 | } else 207 | goto no_error_operand; 208 | 209 | error_operand: 210 | hs->flags |= F_ERROR | F_ERROR_OPERAND; 211 | no_error_operand: 212 | 213 | c = *p++; 214 | if (m_reg <= 1) { 215 | if (opcode == 0xf6) 216 | cflags |= C_IMM8; 217 | else if (opcode == 0xf7) 218 | cflags |= C_IMM_P66; 219 | } 220 | 221 | switch (m_mod) { 222 | case 0: 223 | if (pref & PRE_67) { 224 | if (m_rm == 6) 225 | disp_size = 2; 226 | } else 227 | if (m_rm == 5) 228 | disp_size = 4; 229 | break; 230 | case 1: 231 | disp_size = 1; 232 | break; 233 | case 2: 234 | disp_size = 2; 235 | if (!(pref & PRE_67)) 236 | disp_size <<= 1; 237 | } 238 | 239 | if (m_mod != 3 && m_rm == 4 && !(pref & PRE_67)) { 240 | hs->flags |= F_SIB; 241 | p++; 242 | hs->sib = c; 243 | hs->sib_scale = c >> 6; 244 | hs->sib_index = (c & 0x3f) >> 3; 245 | if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) 246 | disp_size = 4; 247 | } 248 | 249 | p--; 250 | switch (disp_size) { 251 | case 1: 252 | hs->flags |= F_DISP8; 253 | hs->disp.disp8 = *p; 254 | break; 255 | case 2: 256 | hs->flags |= F_DISP16; 257 | hs->disp.disp16 = *(uint16_t *)p; 258 | break; 259 | case 4: 260 | hs->flags |= F_DISP32; 261 | hs->disp.disp32 = *(uint32_t *)p; 262 | } 263 | p += disp_size; 264 | } else if (pref & PRE_LOCK) 265 | hs->flags |= F_ERROR | F_ERROR_LOCK; 266 | 267 | if (cflags & C_IMM_P66) { 268 | if (cflags & C_REL32) { 269 | if (pref & PRE_66) { 270 | hs->flags |= F_IMM16 | F_RELATIVE; 271 | hs->imm.imm16 = *(uint16_t *)p; 272 | p += 2; 273 | goto disasm_done; 274 | } 275 | goto rel32_ok; 276 | } 277 | if (pref & PRE_66) { 278 | hs->flags |= F_IMM16; 279 | hs->imm.imm16 = *(uint16_t *)p; 280 | p += 2; 281 | } else { 282 | hs->flags |= F_IMM32; 283 | hs->imm.imm32 = *(uint32_t *)p; 284 | p += 4; 285 | } 286 | } 287 | 288 | if (cflags & C_IMM16) { 289 | if (hs->flags & F_IMM32) { 290 | hs->flags |= F_IMM16; 291 | hs->disp.disp16 = *(uint16_t *)p; 292 | } else if (hs->flags & F_IMM16) { 293 | hs->flags |= F_2IMM16; 294 | hs->disp.disp16 = *(uint16_t *)p; 295 | } else { 296 | hs->flags |= F_IMM16; 297 | hs->imm.imm16 = *(uint16_t *)p; 298 | } 299 | p += 2; 300 | } 301 | if (cflags & C_IMM8) { 302 | hs->flags |= F_IMM8; 303 | hs->imm.imm8 = *p++; 304 | } 305 | 306 | if (cflags & C_REL32) { 307 | rel32_ok: 308 | hs->flags |= F_IMM32 | F_RELATIVE; 309 | hs->imm.imm32 = *(uint32_t *)p; 310 | p += 4; 311 | } else if (cflags & C_REL8) { 312 | hs->flags |= F_IMM8 | F_RELATIVE; 313 | hs->imm.imm8 = *p++; 314 | } 315 | 316 | disasm_done: 317 | 318 | if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) { 319 | hs->flags |= F_ERROR | F_ERROR_LENGTH; 320 | hs->len = 15; 321 | } 322 | 323 | return (unsigned int)hs->len; 324 | } 325 | 326 | #endif // defined(_M_IX86) || defined(__i386__) 327 | -------------------------------------------------------------------------------- /src/kiero/minhook/src/hde/hde32.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 32 3 | * Copyright (c) 2006-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | * hde32.h: C/C++ header file 7 | * 8 | */ 9 | 10 | #ifndef _HDE32_H_ 11 | #define _HDE32_H_ 12 | 13 | /* stdint.h - C99 standard header 14 | * http://en.wikipedia.org/wiki/stdint.h 15 | * 16 | * if your compiler doesn't contain "stdint.h" header (for 17 | * example, Microsoft Visual C++), you can download file: 18 | * http://www.azillionmonkeys.com/qed/pstdint.h 19 | * and change next line to: 20 | * #include "pstdint.h" 21 | */ 22 | #include "pstdint.h" 23 | 24 | #define F_MODRM 0x00000001 25 | #define F_SIB 0x00000002 26 | #define F_IMM8 0x00000004 27 | #define F_IMM16 0x00000008 28 | #define F_IMM32 0x00000010 29 | #define F_DISP8 0x00000020 30 | #define F_DISP16 0x00000040 31 | #define F_DISP32 0x00000080 32 | #define F_RELATIVE 0x00000100 33 | #define F_2IMM16 0x00000800 34 | #define F_ERROR 0x00001000 35 | #define F_ERROR_OPCODE 0x00002000 36 | #define F_ERROR_LENGTH 0x00004000 37 | #define F_ERROR_LOCK 0x00008000 38 | #define F_ERROR_OPERAND 0x00010000 39 | #define F_PREFIX_REPNZ 0x01000000 40 | #define F_PREFIX_REPX 0x02000000 41 | #define F_PREFIX_REP 0x03000000 42 | #define F_PREFIX_66 0x04000000 43 | #define F_PREFIX_67 0x08000000 44 | #define F_PREFIX_LOCK 0x10000000 45 | #define F_PREFIX_SEG 0x20000000 46 | #define F_PREFIX_ANY 0x3f000000 47 | 48 | #define PREFIX_SEGMENT_CS 0x2e 49 | #define PREFIX_SEGMENT_SS 0x36 50 | #define PREFIX_SEGMENT_DS 0x3e 51 | #define PREFIX_SEGMENT_ES 0x26 52 | #define PREFIX_SEGMENT_FS 0x64 53 | #define PREFIX_SEGMENT_GS 0x65 54 | #define PREFIX_LOCK 0xf0 55 | #define PREFIX_REPNZ 0xf2 56 | #define PREFIX_REPX 0xf3 57 | #define PREFIX_OPERAND_SIZE 0x66 58 | #define PREFIX_ADDRESS_SIZE 0x67 59 | 60 | #pragma pack(push,1) 61 | 62 | typedef struct { 63 | uint8_t len; 64 | uint8_t p_rep; 65 | uint8_t p_lock; 66 | uint8_t p_seg; 67 | uint8_t p_66; 68 | uint8_t p_67; 69 | uint8_t opcode; 70 | uint8_t opcode2; 71 | uint8_t modrm; 72 | uint8_t modrm_mod; 73 | uint8_t modrm_reg; 74 | uint8_t modrm_rm; 75 | uint8_t sib; 76 | uint8_t sib_scale; 77 | uint8_t sib_index; 78 | uint8_t sib_base; 79 | union { 80 | uint8_t imm8; 81 | uint16_t imm16; 82 | uint32_t imm32; 83 | } imm; 84 | union { 85 | uint8_t disp8; 86 | uint16_t disp16; 87 | uint32_t disp32; 88 | } disp; 89 | uint32_t flags; 90 | } hde32s; 91 | 92 | #pragma pack(pop) 93 | 94 | #ifdef __cplusplus 95 | extern "C" { 96 | #endif 97 | 98 | /* __cdecl */ 99 | unsigned int hde32_disasm(const void *code, hde32s *hs); 100 | 101 | #ifdef __cplusplus 102 | } 103 | #endif 104 | 105 | #endif /* _HDE32_H_ */ 106 | -------------------------------------------------------------------------------- /src/kiero/minhook/src/hde/hde64.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 64 C 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | */ 7 | 8 | #if defined(_M_X64) || defined(__x86_64__) 9 | 10 | #include "hde64.h" 11 | #include "table64.h" 12 | 13 | unsigned int hde64_disasm(const void *code, hde64s *hs) 14 | { 15 | uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0; 16 | uint8_t *ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0; 17 | uint8_t op64 = 0; 18 | 19 | // Avoid using memset to reduce the footprint. 20 | #ifndef _MSC_VER 21 | memset((LPBYTE)hs, 0, sizeof(hde64s)); 22 | #else 23 | __stosb((LPBYTE)hs, 0, sizeof(hde64s)); 24 | #endif 25 | 26 | for (x = 16; x; x--) 27 | switch (c = *p++) { 28 | case 0xf3: 29 | hs->p_rep = c; 30 | pref |= PRE_F3; 31 | break; 32 | case 0xf2: 33 | hs->p_rep = c; 34 | pref |= PRE_F2; 35 | break; 36 | case 0xf0: 37 | hs->p_lock = c; 38 | pref |= PRE_LOCK; 39 | break; 40 | case 0x26: case 0x2e: case 0x36: 41 | case 0x3e: case 0x64: case 0x65: 42 | hs->p_seg = c; 43 | pref |= PRE_SEG; 44 | break; 45 | case 0x66: 46 | hs->p_66 = c; 47 | pref |= PRE_66; 48 | break; 49 | case 0x67: 50 | hs->p_67 = c; 51 | pref |= PRE_67; 52 | break; 53 | default: 54 | goto pref_done; 55 | } 56 | pref_done: 57 | 58 | hs->flags = (uint32_t)pref << 23; 59 | 60 | if (!pref) 61 | pref |= PRE_NONE; 62 | 63 | if ((c & 0xf0) == 0x40) { 64 | hs->flags |= F_PREFIX_REX; 65 | if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8) 66 | op64++; 67 | hs->rex_r = (c & 7) >> 2; 68 | hs->rex_x = (c & 3) >> 1; 69 | hs->rex_b = c & 1; 70 | if (((c = *p++) & 0xf0) == 0x40) { 71 | opcode = c; 72 | goto error_opcode; 73 | } 74 | } 75 | 76 | if ((hs->opcode = c) == 0x0f) { 77 | hs->opcode2 = c = *p++; 78 | ht += DELTA_OPCODES; 79 | } else if (c >= 0xa0 && c <= 0xa3) { 80 | op64++; 81 | if (pref & PRE_67) 82 | pref |= PRE_66; 83 | else 84 | pref &= ~PRE_66; 85 | } 86 | 87 | opcode = c; 88 | cflags = ht[ht[opcode / 4] + (opcode % 4)]; 89 | 90 | if (cflags == C_ERROR) { 91 | error_opcode: 92 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 93 | cflags = 0; 94 | if ((opcode & -3) == 0x24) 95 | cflags++; 96 | } 97 | 98 | x = 0; 99 | if (cflags & C_GROUP) { 100 | uint16_t t; 101 | t = *(uint16_t *)(ht + (cflags & 0x7f)); 102 | cflags = (uint8_t)t; 103 | x = (uint8_t)(t >> 8); 104 | } 105 | 106 | if (hs->opcode2) { 107 | ht = hde64_table + DELTA_PREFIXES; 108 | if (ht[ht[opcode / 4] + (opcode % 4)] & pref) 109 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 110 | } 111 | 112 | if (cflags & C_MODRM) { 113 | hs->flags |= F_MODRM; 114 | hs->modrm = c = *p++; 115 | hs->modrm_mod = m_mod = c >> 6; 116 | hs->modrm_rm = m_rm = c & 7; 117 | hs->modrm_reg = m_reg = (c & 0x3f) >> 3; 118 | 119 | if (x && ((x << m_reg) & 0x80)) 120 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 121 | 122 | if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { 123 | uint8_t t = opcode - 0xd9; 124 | if (m_mod == 3) { 125 | ht = hde64_table + DELTA_FPU_MODRM + t*8; 126 | t = ht[m_reg] << m_rm; 127 | } else { 128 | ht = hde64_table + DELTA_FPU_REG; 129 | t = ht[t] << m_reg; 130 | } 131 | if (t & 0x80) 132 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 133 | } 134 | 135 | if (pref & PRE_LOCK) { 136 | if (m_mod == 3) { 137 | hs->flags |= F_ERROR | F_ERROR_LOCK; 138 | } else { 139 | uint8_t *table_end, op = opcode; 140 | if (hs->opcode2) { 141 | ht = hde64_table + DELTA_OP2_LOCK_OK; 142 | table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; 143 | } else { 144 | ht = hde64_table + DELTA_OP_LOCK_OK; 145 | table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; 146 | op &= -2; 147 | } 148 | for (; ht != table_end; ht++) 149 | if (*ht++ == op) { 150 | if (!((*ht << m_reg) & 0x80)) 151 | goto no_lock_error; 152 | else 153 | break; 154 | } 155 | hs->flags |= F_ERROR | F_ERROR_LOCK; 156 | no_lock_error: 157 | ; 158 | } 159 | } 160 | 161 | if (hs->opcode2) { 162 | switch (opcode) { 163 | case 0x20: case 0x22: 164 | m_mod = 3; 165 | if (m_reg > 4 || m_reg == 1) 166 | goto error_operand; 167 | else 168 | goto no_error_operand; 169 | case 0x21: case 0x23: 170 | m_mod = 3; 171 | if (m_reg == 4 || m_reg == 5) 172 | goto error_operand; 173 | else 174 | goto no_error_operand; 175 | } 176 | } else { 177 | switch (opcode) { 178 | case 0x8c: 179 | if (m_reg > 5) 180 | goto error_operand; 181 | else 182 | goto no_error_operand; 183 | case 0x8e: 184 | if (m_reg == 1 || m_reg > 5) 185 | goto error_operand; 186 | else 187 | goto no_error_operand; 188 | } 189 | } 190 | 191 | if (m_mod == 3) { 192 | uint8_t *table_end; 193 | if (hs->opcode2) { 194 | ht = hde64_table + DELTA_OP2_ONLY_MEM; 195 | table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM; 196 | } else { 197 | ht = hde64_table + DELTA_OP_ONLY_MEM; 198 | table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; 199 | } 200 | for (; ht != table_end; ht += 2) 201 | if (*ht++ == opcode) { 202 | if (*ht++ & pref && !((*ht << m_reg) & 0x80)) 203 | goto error_operand; 204 | else 205 | break; 206 | } 207 | goto no_error_operand; 208 | } else if (hs->opcode2) { 209 | switch (opcode) { 210 | case 0x50: case 0xd7: case 0xf7: 211 | if (pref & (PRE_NONE | PRE_66)) 212 | goto error_operand; 213 | break; 214 | case 0xd6: 215 | if (pref & (PRE_F2 | PRE_F3)) 216 | goto error_operand; 217 | break; 218 | case 0xc5: 219 | goto error_operand; 220 | } 221 | goto no_error_operand; 222 | } else 223 | goto no_error_operand; 224 | 225 | error_operand: 226 | hs->flags |= F_ERROR | F_ERROR_OPERAND; 227 | no_error_operand: 228 | 229 | c = *p++; 230 | if (m_reg <= 1) { 231 | if (opcode == 0xf6) 232 | cflags |= C_IMM8; 233 | else if (opcode == 0xf7) 234 | cflags |= C_IMM_P66; 235 | } 236 | 237 | switch (m_mod) { 238 | case 0: 239 | if (pref & PRE_67) { 240 | if (m_rm == 6) 241 | disp_size = 2; 242 | } else 243 | if (m_rm == 5) 244 | disp_size = 4; 245 | break; 246 | case 1: 247 | disp_size = 1; 248 | break; 249 | case 2: 250 | disp_size = 2; 251 | if (!(pref & PRE_67)) 252 | disp_size <<= 1; 253 | } 254 | 255 | if (m_mod != 3 && m_rm == 4) { 256 | hs->flags |= F_SIB; 257 | p++; 258 | hs->sib = c; 259 | hs->sib_scale = c >> 6; 260 | hs->sib_index = (c & 0x3f) >> 3; 261 | if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) 262 | disp_size = 4; 263 | } 264 | 265 | p--; 266 | switch (disp_size) { 267 | case 1: 268 | hs->flags |= F_DISP8; 269 | hs->disp.disp8 = *p; 270 | break; 271 | case 2: 272 | hs->flags |= F_DISP16; 273 | hs->disp.disp16 = *(uint16_t *)p; 274 | break; 275 | case 4: 276 | hs->flags |= F_DISP32; 277 | hs->disp.disp32 = *(uint32_t *)p; 278 | } 279 | p += disp_size; 280 | } else if (pref & PRE_LOCK) 281 | hs->flags |= F_ERROR | F_ERROR_LOCK; 282 | 283 | if (cflags & C_IMM_P66) { 284 | if (cflags & C_REL32) { 285 | if (pref & PRE_66) { 286 | hs->flags |= F_IMM16 | F_RELATIVE; 287 | hs->imm.imm16 = *(uint16_t *)p; 288 | p += 2; 289 | goto disasm_done; 290 | } 291 | goto rel32_ok; 292 | } 293 | if (op64) { 294 | hs->flags |= F_IMM64; 295 | hs->imm.imm64 = *(uint64_t *)p; 296 | p += 8; 297 | } else if (!(pref & PRE_66)) { 298 | hs->flags |= F_IMM32; 299 | hs->imm.imm32 = *(uint32_t *)p; 300 | p += 4; 301 | } else 302 | goto imm16_ok; 303 | } 304 | 305 | 306 | if (cflags & C_IMM16) { 307 | imm16_ok: 308 | hs->flags |= F_IMM16; 309 | hs->imm.imm16 = *(uint16_t *)p; 310 | p += 2; 311 | } 312 | if (cflags & C_IMM8) { 313 | hs->flags |= F_IMM8; 314 | hs->imm.imm8 = *p++; 315 | } 316 | 317 | if (cflags & C_REL32) { 318 | rel32_ok: 319 | hs->flags |= F_IMM32 | F_RELATIVE; 320 | hs->imm.imm32 = *(uint32_t *)p; 321 | p += 4; 322 | } else if (cflags & C_REL8) { 323 | hs->flags |= F_IMM8 | F_RELATIVE; 324 | hs->imm.imm8 = *p++; 325 | } 326 | 327 | disasm_done: 328 | 329 | if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) { 330 | hs->flags |= F_ERROR | F_ERROR_LENGTH; 331 | hs->len = 15; 332 | } 333 | 334 | return (unsigned int)hs->len; 335 | } 336 | 337 | #endif // defined(_M_X64) || defined(__x86_64__) 338 | -------------------------------------------------------------------------------- /src/kiero/minhook/src/hde/hde64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 64 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | * hde64.h: C/C++ header file 7 | * 8 | */ 9 | 10 | #ifndef _HDE64_H_ 11 | #define _HDE64_H_ 12 | 13 | /* stdint.h - C99 standard header 14 | * http://en.wikipedia.org/wiki/stdint.h 15 | * 16 | * if your compiler doesn't contain "stdint.h" header (for 17 | * example, Microsoft Visual C++), you can download file: 18 | * http://www.azillionmonkeys.com/qed/pstdint.h 19 | * and change next line to: 20 | * #include "pstdint.h" 21 | */ 22 | #include "pstdint.h" 23 | 24 | #define F_MODRM 0x00000001 25 | #define F_SIB 0x00000002 26 | #define F_IMM8 0x00000004 27 | #define F_IMM16 0x00000008 28 | #define F_IMM32 0x00000010 29 | #define F_IMM64 0x00000020 30 | #define F_DISP8 0x00000040 31 | #define F_DISP16 0x00000080 32 | #define F_DISP32 0x00000100 33 | #define F_RELATIVE 0x00000200 34 | #define F_ERROR 0x00001000 35 | #define F_ERROR_OPCODE 0x00002000 36 | #define F_ERROR_LENGTH 0x00004000 37 | #define F_ERROR_LOCK 0x00008000 38 | #define F_ERROR_OPERAND 0x00010000 39 | #define F_PREFIX_REPNZ 0x01000000 40 | #define F_PREFIX_REPX 0x02000000 41 | #define F_PREFIX_REP 0x03000000 42 | #define F_PREFIX_66 0x04000000 43 | #define F_PREFIX_67 0x08000000 44 | #define F_PREFIX_LOCK 0x10000000 45 | #define F_PREFIX_SEG 0x20000000 46 | #define F_PREFIX_REX 0x40000000 47 | #define F_PREFIX_ANY 0x7f000000 48 | 49 | #define PREFIX_SEGMENT_CS 0x2e 50 | #define PREFIX_SEGMENT_SS 0x36 51 | #define PREFIX_SEGMENT_DS 0x3e 52 | #define PREFIX_SEGMENT_ES 0x26 53 | #define PREFIX_SEGMENT_FS 0x64 54 | #define PREFIX_SEGMENT_GS 0x65 55 | #define PREFIX_LOCK 0xf0 56 | #define PREFIX_REPNZ 0xf2 57 | #define PREFIX_REPX 0xf3 58 | #define PREFIX_OPERAND_SIZE 0x66 59 | #define PREFIX_ADDRESS_SIZE 0x67 60 | 61 | #pragma pack(push,1) 62 | 63 | typedef struct { 64 | uint8_t len; 65 | uint8_t p_rep; 66 | uint8_t p_lock; 67 | uint8_t p_seg; 68 | uint8_t p_66; 69 | uint8_t p_67; 70 | uint8_t rex; 71 | uint8_t rex_w; 72 | uint8_t rex_r; 73 | uint8_t rex_x; 74 | uint8_t rex_b; 75 | uint8_t opcode; 76 | uint8_t opcode2; 77 | uint8_t modrm; 78 | uint8_t modrm_mod; 79 | uint8_t modrm_reg; 80 | uint8_t modrm_rm; 81 | uint8_t sib; 82 | uint8_t sib_scale; 83 | uint8_t sib_index; 84 | uint8_t sib_base; 85 | union { 86 | uint8_t imm8; 87 | uint16_t imm16; 88 | uint32_t imm32; 89 | uint64_t imm64; 90 | } imm; 91 | union { 92 | uint8_t disp8; 93 | uint16_t disp16; 94 | uint32_t disp32; 95 | } disp; 96 | uint32_t flags; 97 | } hde64s; 98 | 99 | #pragma pack(pop) 100 | 101 | #ifdef __cplusplus 102 | extern "C" { 103 | #endif 104 | 105 | /* __cdecl */ 106 | unsigned int hde64_disasm(const void *code, hde64s *hs); 107 | 108 | #ifdef __cplusplus 109 | } 110 | #endif 111 | 112 | #endif /* _HDE64_H_ */ 113 | -------------------------------------------------------------------------------- /src/kiero/minhook/src/hde/pstdint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MinHook - The Minimalistic API Hooking Library for x64/x86 3 | * Copyright (C) 2009-2017 Tsuda Kageyu. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | */ 26 | 27 | #pragma once 28 | 29 | #include 30 | 31 | // Integer types for HDE. 32 | typedef INT8 int8_t; 33 | typedef INT16 int16_t; 34 | typedef INT32 int32_t; 35 | typedef INT64 int64_t; 36 | typedef UINT8 uint8_t; 37 | typedef UINT16 uint16_t; 38 | typedef UINT32 uint32_t; 39 | typedef UINT64 uint64_t; 40 | -------------------------------------------------------------------------------- /src/kiero/minhook/src/hde/table32.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 32 C 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | */ 7 | 8 | #define C_NONE 0x00 9 | #define C_MODRM 0x01 10 | #define C_IMM8 0x02 11 | #define C_IMM16 0x04 12 | #define C_IMM_P66 0x10 13 | #define C_REL8 0x20 14 | #define C_REL32 0x40 15 | #define C_GROUP 0x80 16 | #define C_ERROR 0xff 17 | 18 | #define PRE_ANY 0x00 19 | #define PRE_NONE 0x01 20 | #define PRE_F2 0x02 21 | #define PRE_F3 0x04 22 | #define PRE_66 0x08 23 | #define PRE_67 0x10 24 | #define PRE_LOCK 0x20 25 | #define PRE_SEG 0x40 26 | #define PRE_ALL 0xff 27 | 28 | #define DELTA_OPCODES 0x4a 29 | #define DELTA_FPU_REG 0xf1 30 | #define DELTA_FPU_MODRM 0xf8 31 | #define DELTA_PREFIXES 0x130 32 | #define DELTA_OP_LOCK_OK 0x1a1 33 | #define DELTA_OP2_LOCK_OK 0x1b9 34 | #define DELTA_OP_ONLY_MEM 0x1cb 35 | #define DELTA_OP2_ONLY_MEM 0x1da 36 | 37 | unsigned char hde32_table[] = { 38 | 0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3, 39 | 0xa8,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xac,0xaa,0xb2,0xaa,0x9f,0x9f, 40 | 0x9f,0x9f,0xb5,0xa3,0xa3,0xa4,0xaa,0xaa,0xba,0xaa,0x96,0xaa,0xa8,0xaa,0xc3, 41 | 0xc3,0x96,0x96,0xb7,0xae,0xd6,0xbd,0xa3,0xc5,0xa3,0xa3,0x9f,0xc3,0x9c,0xaa, 42 | 0xaa,0xac,0xaa,0xbf,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0x90, 43 | 0x82,0x7d,0x97,0x59,0x59,0x59,0x59,0x59,0x7f,0x59,0x59,0x60,0x7d,0x7f,0x7f, 44 | 0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x9a,0x88,0x7d, 45 | 0x59,0x50,0x50,0x50,0x50,0x59,0x59,0x59,0x59,0x61,0x94,0x61,0x9e,0x59,0x59, 46 | 0x85,0x59,0x92,0xa3,0x60,0x60,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59, 47 | 0x59,0x59,0x9f,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xcc,0x01,0xbc,0x03,0xf0, 48 | 0x10,0x10,0x10,0x10,0x50,0x50,0x50,0x50,0x14,0x20,0x20,0x20,0x20,0x01,0x01, 49 | 0x01,0x01,0xc4,0x02,0x10,0x00,0x00,0x00,0x00,0x01,0x01,0xc0,0xc2,0x10,0x11, 50 | 0x02,0x03,0x11,0x03,0x03,0x04,0x00,0x00,0x14,0x00,0x02,0x00,0x00,0xc6,0xc8, 51 | 0x02,0x02,0x02,0x02,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0xca, 52 | 0x01,0x01,0x01,0x00,0x06,0x00,0x04,0x00,0xc0,0xc2,0x01,0x01,0x03,0x01,0xff, 53 | 0xff,0x01,0x00,0x03,0xc4,0xc4,0xc6,0x03,0x01,0x01,0x01,0xff,0x03,0x03,0x03, 54 | 0xc8,0x40,0x00,0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00, 55 | 0x00,0x00,0x00,0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00, 56 | 0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 57 | 0x00,0xff,0xff,0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 58 | 0x7f,0x00,0x00,0xff,0x4a,0x4a,0x4a,0x4a,0x4b,0x52,0x4a,0x4a,0x4a,0x4a,0x4f, 59 | 0x4c,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x55,0x45,0x40,0x4a,0x4a,0x4a, 60 | 0x45,0x59,0x4d,0x46,0x4a,0x5d,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a, 61 | 0x4a,0x4a,0x4a,0x4a,0x4a,0x61,0x63,0x67,0x4e,0x4a,0x4a,0x6b,0x6d,0x4a,0x4a, 62 | 0x45,0x6d,0x4a,0x4a,0x44,0x45,0x4a,0x4a,0x00,0x00,0x00,0x02,0x0d,0x06,0x06, 63 | 0x06,0x06,0x0e,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x00,0x06,0x06,0x02,0x06, 64 | 0x00,0x0a,0x0a,0x07,0x07,0x06,0x02,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04, 65 | 0x04,0x04,0x00,0x00,0x00,0x0e,0x05,0x06,0x06,0x06,0x01,0x06,0x00,0x00,0x08, 66 | 0x00,0x10,0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01, 67 | 0x86,0x00,0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba, 68 | 0xf8,0xbb,0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00, 69 | 0xc4,0xff,0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00, 70 | 0x13,0x09,0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07, 71 | 0xb2,0xff,0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf, 72 | 0xe7,0x08,0x00,0xf0,0x02,0x00 73 | }; 74 | -------------------------------------------------------------------------------- /src/kiero/minhook/src/hde/table64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 64 C 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | */ 7 | 8 | #define C_NONE 0x00 9 | #define C_MODRM 0x01 10 | #define C_IMM8 0x02 11 | #define C_IMM16 0x04 12 | #define C_IMM_P66 0x10 13 | #define C_REL8 0x20 14 | #define C_REL32 0x40 15 | #define C_GROUP 0x80 16 | #define C_ERROR 0xff 17 | 18 | #define PRE_ANY 0x00 19 | #define PRE_NONE 0x01 20 | #define PRE_F2 0x02 21 | #define PRE_F3 0x04 22 | #define PRE_66 0x08 23 | #define PRE_67 0x10 24 | #define PRE_LOCK 0x20 25 | #define PRE_SEG 0x40 26 | #define PRE_ALL 0xff 27 | 28 | #define DELTA_OPCODES 0x4a 29 | #define DELTA_FPU_REG 0xfd 30 | #define DELTA_FPU_MODRM 0x104 31 | #define DELTA_PREFIXES 0x13c 32 | #define DELTA_OP_LOCK_OK 0x1ae 33 | #define DELTA_OP2_LOCK_OK 0x1c6 34 | #define DELTA_OP_ONLY_MEM 0x1d8 35 | #define DELTA_OP2_ONLY_MEM 0x1e7 36 | 37 | unsigned char hde64_table[] = { 38 | 0xa5,0xaa,0xa5,0xb8,0xa5,0xaa,0xa5,0xaa,0xa5,0xb8,0xa5,0xb8,0xa5,0xb8,0xa5, 39 | 0xb8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xac,0xc0,0xcc,0xc0,0xa1,0xa1, 40 | 0xa1,0xa1,0xb1,0xa5,0xa5,0xa6,0xc0,0xc0,0xd7,0xda,0xe0,0xc0,0xe4,0xc0,0xea, 41 | 0xea,0xe0,0xe0,0x98,0xc8,0xee,0xf1,0xa5,0xd3,0xa5,0xa5,0xa1,0xea,0x9e,0xc0, 42 | 0xc0,0xc2,0xc0,0xe6,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0xab, 43 | 0x8b,0x90,0x64,0x5b,0x5b,0x5b,0x5b,0x5b,0x92,0x5b,0x5b,0x76,0x90,0x92,0x92, 44 | 0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x6a,0x73,0x90, 45 | 0x5b,0x52,0x52,0x52,0x52,0x5b,0x5b,0x5b,0x5b,0x77,0x7c,0x77,0x85,0x5b,0x5b, 46 | 0x70,0x5b,0x7a,0xaf,0x76,0x76,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b, 47 | 0x5b,0x5b,0x86,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xd5,0x03,0xcc,0x01,0xbc, 48 | 0x03,0xf0,0x03,0x03,0x04,0x00,0x50,0x50,0x50,0x50,0xff,0x20,0x20,0x20,0x20, 49 | 0x01,0x01,0x01,0x01,0xc4,0x02,0x10,0xff,0xff,0xff,0x01,0x00,0x03,0x11,0xff, 50 | 0x03,0xc4,0xc6,0xc8,0x02,0x10,0x00,0xff,0xcc,0x01,0x01,0x01,0x00,0x00,0x00, 51 | 0x00,0x01,0x01,0x03,0x01,0xff,0xff,0xc0,0xc2,0x10,0x11,0x02,0x03,0x01,0x01, 52 | 0x01,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x10, 53 | 0x10,0x10,0x10,0x02,0x10,0x00,0x00,0xc6,0xc8,0x02,0x02,0x02,0x02,0x06,0x00, 54 | 0x04,0x00,0x02,0xff,0x00,0xc0,0xc2,0x01,0x01,0x03,0x03,0x03,0xca,0x40,0x00, 55 | 0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,0x00,0x00,0x00, 56 | 0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xff,0x00, 57 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, 58 | 0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00, 59 | 0xff,0x40,0x40,0x40,0x40,0x41,0x49,0x40,0x40,0x40,0x40,0x4c,0x42,0x40,0x40, 60 | 0x40,0x40,0x40,0x40,0x40,0x40,0x4f,0x44,0x53,0x40,0x40,0x40,0x44,0x57,0x43, 61 | 0x5c,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, 62 | 0x40,0x40,0x64,0x66,0x6e,0x6b,0x40,0x40,0x6a,0x46,0x40,0x40,0x44,0x46,0x40, 63 | 0x40,0x5b,0x44,0x40,0x40,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x01,0x06, 64 | 0x06,0x02,0x06,0x06,0x00,0x06,0x00,0x0a,0x0a,0x00,0x00,0x00,0x02,0x07,0x07, 65 | 0x06,0x02,0x0d,0x06,0x06,0x06,0x0e,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04, 66 | 0x04,0x04,0x05,0x06,0x06,0x06,0x00,0x00,0x00,0x0e,0x00,0x00,0x08,0x00,0x10, 67 | 0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,0x86,0x00, 68 | 0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,0xf8,0xbb, 69 | 0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,0xc4,0xff, 70 | 0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,0x13,0x09, 71 | 0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,0xb2,0xff, 72 | 0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,0xe7,0x08, 73 | 0x00,0xf0,0x02,0x00 74 | }; 75 | -------------------------------------------------------------------------------- /src/kiero/minhook/src/trampoline.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MinHook - The Minimalistic API Hooking Library for x64/x86 3 | * Copyright (C) 2009-2017 Tsuda Kageyu. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 20 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | 31 | #ifndef ARRAYSIZE 32 | #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) 33 | #endif 34 | 35 | #if defined(_M_X64) || defined(__x86_64__) 36 | #include "./hde/hde64.h" 37 | typedef hde64s HDE; 38 | #define HDE_DISASM(code, hs) hde64_disasm(code, hs) 39 | #else 40 | #include "./hde/hde32.h" 41 | typedef hde32s HDE; 42 | #define HDE_DISASM(code, hs) hde32_disasm(code, hs) 43 | #endif 44 | 45 | #include "trampoline.h" 46 | #include "buffer.h" 47 | 48 | // Maximum size of a trampoline function. 49 | #if defined(_M_X64) || defined(__x86_64__) 50 | #define TRAMPOLINE_MAX_SIZE (MEMORY_SLOT_SIZE - sizeof(JMP_ABS)) 51 | #else 52 | #define TRAMPOLINE_MAX_SIZE MEMORY_SLOT_SIZE 53 | #endif 54 | 55 | //------------------------------------------------------------------------- 56 | static BOOL IsCodePadding(LPBYTE pInst, UINT size) 57 | { 58 | UINT i; 59 | 60 | if (pInst[0] != 0x00 && pInst[0] != 0x90 && pInst[0] != 0xCC) 61 | return FALSE; 62 | 63 | for (i = 1; i < size; ++i) 64 | { 65 | if (pInst[i] != pInst[0]) 66 | return FALSE; 67 | } 68 | return TRUE; 69 | } 70 | 71 | //------------------------------------------------------------------------- 72 | BOOL CreateTrampolineFunction(PTRAMPOLINE ct) 73 | { 74 | #if defined(_M_X64) || defined(__x86_64__) 75 | CALL_ABS call = { 76 | 0xFF, 0x15, 0x00000002, // FF15 00000002: CALL [RIP+8] 77 | 0xEB, 0x08, // EB 08: JMP +10 78 | 0x0000000000000000ULL // Absolute destination address 79 | }; 80 | JMP_ABS jmp = { 81 | 0xFF, 0x25, 0x00000000, // FF25 00000000: JMP [RIP+6] 82 | 0x0000000000000000ULL // Absolute destination address 83 | }; 84 | JCC_ABS jcc = { 85 | 0x70, 0x0E, // 7* 0E: J** +16 86 | 0xFF, 0x25, 0x00000000, // FF25 00000000: JMP [RIP+6] 87 | 0x0000000000000000ULL // Absolute destination address 88 | }; 89 | #else 90 | CALL_REL call = { 91 | 0xE8, // E8 xxxxxxxx: CALL +5+xxxxxxxx 92 | 0x00000000 // Relative destination address 93 | }; 94 | JMP_REL jmp = { 95 | 0xE9, // E9 xxxxxxxx: JMP +5+xxxxxxxx 96 | 0x00000000 // Relative destination address 97 | }; 98 | JCC_REL jcc = { 99 | 0x0F, 0x80, // 0F8* xxxxxxxx: J** +6+xxxxxxxx 100 | 0x00000000 // Relative destination address 101 | }; 102 | #endif 103 | 104 | UINT8 oldPos = 0; 105 | UINT8 newPos = 0; 106 | ULONG_PTR jmpDest = 0; // Destination address of an internal jump. 107 | BOOL finished = FALSE; // Is the function completed? 108 | #if defined(_M_X64) || defined(__x86_64__) 109 | UINT8 instBuf[16]; 110 | #endif 111 | 112 | ct->patchAbove = FALSE; 113 | ct->nIP = 0; 114 | 115 | do 116 | { 117 | HDE hs; 118 | UINT copySize; 119 | LPVOID pCopySrc; 120 | ULONG_PTR pOldInst = (ULONG_PTR)ct->pTarget + oldPos; 121 | ULONG_PTR pNewInst = (ULONG_PTR)ct->pTrampoline + newPos; 122 | 123 | copySize = HDE_DISASM((LPVOID)pOldInst, &hs); 124 | if (hs.flags & F_ERROR) 125 | return FALSE; 126 | 127 | pCopySrc = (LPVOID)pOldInst; 128 | if (oldPos >= sizeof(JMP_REL)) 129 | { 130 | // The trampoline function is long enough. 131 | // Complete the function with the jump to the target function. 132 | #if defined(_M_X64) || defined(__x86_64__) 133 | jmp.address = pOldInst; 134 | #else 135 | jmp.operand = (UINT32)(pOldInst - (pNewInst + sizeof(jmp))); 136 | #endif 137 | pCopySrc = &jmp; 138 | copySize = sizeof(jmp); 139 | 140 | finished = TRUE; 141 | } 142 | #if defined(_M_X64) || defined(__x86_64__) 143 | else if ((hs.modrm & 0xC7) == 0x05) 144 | { 145 | // Instructions using RIP relative addressing. (ModR/M = 00???101B) 146 | 147 | // Modify the RIP relative address. 148 | PUINT32 pRelAddr; 149 | 150 | // Avoid using memcpy to reduce the footprint. 151 | #ifndef _MSC_VER 152 | memcpy(instBuf, (LPBYTE)pOldInst, copySize); 153 | #else 154 | __movsb(instBuf, (LPBYTE)pOldInst, copySize); 155 | #endif 156 | pCopySrc = instBuf; 157 | 158 | // Relative address is stored at (instruction length - immediate value length - 4). 159 | pRelAddr = (PUINT32)(instBuf + hs.len - ((hs.flags & 0x3C) >> 2) - 4); 160 | *pRelAddr 161 | = (UINT32)((pOldInst + hs.len + (INT32)hs.disp.disp32) - (pNewInst + hs.len)); 162 | 163 | // Complete the function if JMP (FF /4). 164 | if (hs.opcode == 0xFF && hs.modrm_reg == 4) 165 | finished = TRUE; 166 | } 167 | #endif 168 | else if (hs.opcode == 0xE8) 169 | { 170 | // Direct relative CALL 171 | ULONG_PTR dest = pOldInst + hs.len + (INT32)hs.imm.imm32; 172 | #if defined(_M_X64) || defined(__x86_64__) 173 | call.address = dest; 174 | #else 175 | call.operand = (UINT32)(dest - (pNewInst + sizeof(call))); 176 | #endif 177 | pCopySrc = &call; 178 | copySize = sizeof(call); 179 | } 180 | else if ((hs.opcode & 0xFD) == 0xE9) 181 | { 182 | // Direct relative JMP (EB or E9) 183 | ULONG_PTR dest = pOldInst + hs.len; 184 | 185 | if (hs.opcode == 0xEB) // isShort jmp 186 | dest += (INT8)hs.imm.imm8; 187 | else 188 | dest += (INT32)hs.imm.imm32; 189 | 190 | // Simply copy an internal jump. 191 | if ((ULONG_PTR)ct->pTarget <= dest 192 | && dest < ((ULONG_PTR)ct->pTarget + sizeof(JMP_REL))) 193 | { 194 | if (jmpDest < dest) 195 | jmpDest = dest; 196 | } 197 | else 198 | { 199 | #if defined(_M_X64) || defined(__x86_64__) 200 | jmp.address = dest; 201 | #else 202 | jmp.operand = (UINT32)(dest - (pNewInst + sizeof(jmp))); 203 | #endif 204 | pCopySrc = &jmp; 205 | copySize = sizeof(jmp); 206 | 207 | // Exit the function If it is not in the branch 208 | finished = (pOldInst >= jmpDest); 209 | } 210 | } 211 | else if ((hs.opcode & 0xF0) == 0x70 212 | || (hs.opcode & 0xFC) == 0xE0 213 | || (hs.opcode2 & 0xF0) == 0x80) 214 | { 215 | // Direct relative Jcc 216 | ULONG_PTR dest = pOldInst + hs.len; 217 | 218 | if ((hs.opcode & 0xF0) == 0x70 // Jcc 219 | || (hs.opcode & 0xFC) == 0xE0) // LOOPNZ/LOOPZ/LOOP/JECXZ 220 | dest += (INT8)hs.imm.imm8; 221 | else 222 | dest += (INT32)hs.imm.imm32; 223 | 224 | // Simply copy an internal jump. 225 | if ((ULONG_PTR)ct->pTarget <= dest 226 | && dest < ((ULONG_PTR)ct->pTarget + sizeof(JMP_REL))) 227 | { 228 | if (jmpDest < dest) 229 | jmpDest = dest; 230 | } 231 | else if ((hs.opcode & 0xFC) == 0xE0) 232 | { 233 | // LOOPNZ/LOOPZ/LOOP/JCXZ/JECXZ to the outside are not supported. 234 | return FALSE; 235 | } 236 | else 237 | { 238 | UINT8 cond = ((hs.opcode != 0x0F ? hs.opcode : hs.opcode2) & 0x0F); 239 | #if defined(_M_X64) || defined(__x86_64__) 240 | // Invert the condition in x64 mode to simplify the conditional jump logic. 241 | jcc.opcode = 0x71 ^ cond; 242 | jcc.address = dest; 243 | #else 244 | jcc.opcode1 = 0x80 | cond; 245 | jcc.operand = (UINT32)(dest - (pNewInst + sizeof(jcc))); 246 | #endif 247 | pCopySrc = &jcc; 248 | copySize = sizeof(jcc); 249 | } 250 | } 251 | else if ((hs.opcode & 0xFE) == 0xC2) 252 | { 253 | // RET (C2 or C3) 254 | 255 | // Complete the function if not in a branch. 256 | finished = (pOldInst >= jmpDest); 257 | } 258 | 259 | // Can't alter the instruction length in a branch. 260 | if (pOldInst < jmpDest && copySize != hs.len) 261 | return FALSE; 262 | 263 | // Trampoline function is too large. 264 | if ((newPos + copySize) > TRAMPOLINE_MAX_SIZE) 265 | return FALSE; 266 | 267 | // Trampoline function has too many instructions. 268 | if (ct->nIP >= ARRAYSIZE(ct->oldIPs)) 269 | return FALSE; 270 | 271 | ct->oldIPs[ct->nIP] = oldPos; 272 | ct->newIPs[ct->nIP] = newPos; 273 | ct->nIP++; 274 | 275 | // Avoid using memcpy to reduce the footprint. 276 | #ifndef _MSC_VER 277 | memcpy((LPBYTE)ct->pTrampoline + newPos, pCopySrc, copySize); 278 | #else 279 | __movsb((LPBYTE)ct->pTrampoline + newPos, pCopySrc, copySize); 280 | #endif 281 | newPos += copySize; 282 | oldPos += hs.len; 283 | } 284 | while (!finished); 285 | 286 | // Is there enough place for a long jump? 287 | if (oldPos < sizeof(JMP_REL) 288 | && !IsCodePadding((LPBYTE)ct->pTarget + oldPos, sizeof(JMP_REL) - oldPos)) 289 | { 290 | // Is there enough place for a short jump? 291 | if (oldPos < sizeof(JMP_REL_SHORT) 292 | && !IsCodePadding((LPBYTE)ct->pTarget + oldPos, sizeof(JMP_REL_SHORT) - oldPos)) 293 | { 294 | return FALSE; 295 | } 296 | 297 | // Can we place the long jump above the function? 298 | if (!IsExecutableAddress((LPBYTE)ct->pTarget - sizeof(JMP_REL))) 299 | return FALSE; 300 | 301 | if (!IsCodePadding((LPBYTE)ct->pTarget - sizeof(JMP_REL), sizeof(JMP_REL))) 302 | return FALSE; 303 | 304 | ct->patchAbove = TRUE; 305 | } 306 | 307 | #if defined(_M_X64) || defined(__x86_64__) 308 | // Create a relay function. 309 | jmp.address = (ULONG_PTR)ct->pDetour; 310 | 311 | ct->pRelay = (LPBYTE)ct->pTrampoline + newPos; 312 | memcpy(ct->pRelay, &jmp, sizeof(jmp)); 313 | #endif 314 | 315 | return TRUE; 316 | } 317 | -------------------------------------------------------------------------------- /src/kiero/minhook/src/trampoline.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MinHook - The Minimalistic API Hooking Library for x64/x86 3 | * Copyright (C) 2009-2017 Tsuda Kageyu. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 20 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #pragma pack(push, 1) 32 | 33 | // Structs for writing x86/x64 instructions. 34 | 35 | // 8-bit relative jump. 36 | typedef struct _JMP_REL_SHORT 37 | { 38 | UINT8 opcode; // EB xx: JMP +2+xx 39 | UINT8 operand; 40 | } JMP_REL_SHORT, *PJMP_REL_SHORT; 41 | 42 | // 32-bit direct relative jump/call. 43 | typedef struct _JMP_REL 44 | { 45 | UINT8 opcode; // E9/E8 xxxxxxxx: JMP/CALL +5+xxxxxxxx 46 | UINT32 operand; // Relative destination address 47 | } JMP_REL, *PJMP_REL, CALL_REL; 48 | 49 | // 64-bit indirect absolute jump. 50 | typedef struct _JMP_ABS 51 | { 52 | UINT8 opcode0; // FF25 00000000: JMP [+6] 53 | UINT8 opcode1; 54 | UINT32 dummy; 55 | UINT64 address; // Absolute destination address 56 | } JMP_ABS, *PJMP_ABS; 57 | 58 | // 64-bit indirect absolute call. 59 | typedef struct _CALL_ABS 60 | { 61 | UINT8 opcode0; // FF15 00000002: CALL [+6] 62 | UINT8 opcode1; 63 | UINT32 dummy0; 64 | UINT8 dummy1; // EB 08: JMP +10 65 | UINT8 dummy2; 66 | UINT64 address; // Absolute destination address 67 | } CALL_ABS; 68 | 69 | // 32-bit direct relative conditional jumps. 70 | typedef struct _JCC_REL 71 | { 72 | UINT8 opcode0; // 0F8* xxxxxxxx: J** +6+xxxxxxxx 73 | UINT8 opcode1; 74 | UINT32 operand; // Relative destination address 75 | } JCC_REL; 76 | 77 | // 64bit indirect absolute conditional jumps that x64 lacks. 78 | typedef struct _JCC_ABS 79 | { 80 | UINT8 opcode; // 7* 0E: J** +16 81 | UINT8 dummy0; 82 | UINT8 dummy1; // FF25 00000000: JMP [+6] 83 | UINT8 dummy2; 84 | UINT32 dummy3; 85 | UINT64 address; // Absolute destination address 86 | } JCC_ABS; 87 | 88 | #pragma pack(pop) 89 | 90 | typedef struct _TRAMPOLINE 91 | { 92 | LPVOID pTarget; // [In] Address of the target function. 93 | LPVOID pDetour; // [In] Address of the detour function. 94 | LPVOID pTrampoline; // [In] Buffer address for the trampoline and relay function. 95 | 96 | #if defined(_M_X64) || defined(__x86_64__) 97 | LPVOID pRelay; // [Out] Address of the relay function. 98 | #endif 99 | BOOL patchAbove; // [Out] Should use the hot patch area? 100 | UINT nIP; // [Out] Number of the instruction boundaries. 101 | UINT8 oldIPs[8]; // [Out] Instruction boundaries of the target function. 102 | UINT8 newIPs[8]; // [Out] Instruction boundaries of the trampoline function. 103 | } TRAMPOLINE, *PTRAMPOLINE; 104 | 105 | BOOL CreateTrampolineFunction(PTRAMPOLINE ct); 106 | -------------------------------------------------------------------------------- /src/loader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "globals/Globals.hpp" 4 | #include "misc.hpp" 5 | #include "kiero/kiero.h" 6 | #include "../IL2CPP Scanner/GUI/gui.hpp" 7 | 8 | DWORD WINAPI MainThread(LPVOID lpReserved) 9 | { 10 | CreateConsole(); 11 | 12 | HANDLE hCons = GetStdHandle(STD_OUTPUT_HANDLE); 13 | Globals::Gui::hConsole = hCons; 14 | 15 | SetConsoleTextAttribute(Globals::Gui::hConsole, 15); 16 | printf("Initializing IL2CPP...\n"); 17 | 18 | Globals::il2cppStatus = IL2CPP::Initialize(true); 19 | 20 | if (!Globals::il2cppStatus) { 21 | SetConsoleTextAttribute(Globals::Gui::hConsole, 4); 22 | printf("[-] Can't Initialize IL2CPP!\n\n"); 23 | exit(1); 24 | } 25 | 26 | SetConsoleTextAttribute(Globals::Gui::hConsole, 2); 27 | printf("[+] IL2CPP Initialized!\n\n"); 28 | 29 | bool init_hook = false; 30 | do 31 | { 32 | if (kiero::init(kiero::RenderType::D3D11) == kiero::Status::Success) 33 | { 34 | kiero::bind(8, (void**)&Globals::Gui::oPresent, hkPresent); 35 | init_hook = true; 36 | 37 | SetConsoleTextAttribute(Globals::Gui::hConsole, 2); 38 | printf("[+] IL2CPP Scanner loaded"); 39 | } 40 | } while (!init_hook); 41 | return TRUE; 42 | } 43 | 44 | 45 | BOOL WINAPI DllMain(HMODULE hMod, DWORD dwReason, LPVOID lpReserved) 46 | { 47 | switch (dwReason) 48 | { 49 | case DLL_PROCESS_ATTACH: 50 | DisableThreadLibraryCalls(hMod); 51 | CreateThread(nullptr, 0, MainThread, hMod, 0, nullptr); 52 | break; 53 | case DLL_PROCESS_DETACH: 54 | kiero::shutdown(); 55 | break; 56 | } 57 | return TRUE; 58 | } 59 | -------------------------------------------------------------------------------- /src/misc.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void CreateConsole() 5 | { 6 | AllocConsole(); 7 | FILE* f; 8 | freopen_s(&f, "CONOUT$", "w", stdout); 9 | } 10 | 11 | int DU_MessageBoxTimeout(HWND hWnd, const WCHAR* sText, const WCHAR* sCaption, UINT uType, DWORD dwMilliseconds) 12 | { 13 | // Displays a message box, and dismisses it after the specified timeout. 14 | typedef int(__stdcall* MSGBOXWAPI)(IN HWND hWnd, IN LPCWSTR lpText, IN LPCWSTR lpCaption, IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds); 15 | 16 | int iResult; 17 | 18 | HMODULE hUser32 = LoadLibraryA("user32.dll"); 19 | if (hUser32) 20 | { 21 | auto MessageBoxTimeoutW = (MSGBOXWAPI)GetProcAddress(hUser32, "MessageBoxTimeoutW"); 22 | 23 | iResult = MessageBoxTimeoutW(hWnd, sText, sCaption, uType, 0, dwMilliseconds); 24 | 25 | FreeLibrary(hUser32); 26 | } 27 | else 28 | iResult = MessageBoxW(hWnd, sText, sCaption, uType); // fallback to the standard function 29 | 30 | return iResult; 31 | } -------------------------------------------------------------------------------- /src/misc.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | inline void CreateConsole(); 4 | inline int DU_MessageBoxTimeout(HWND hWnd, const WCHAR* sText, const WCHAR* sCaption, UINT uType, DWORD dwMilliseconds); 5 | --------------------------------------------------------------------------------