Skip to content
This repository has been archived by the owner on Jul 6, 2023. It is now read-only.

Commit

Permalink
initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
ImAxel0 committed May 27, 2023
1 parent 9cdd4a1 commit 05c409c
Show file tree
Hide file tree
Showing 105 changed files with 115,656 additions and 0 deletions.
55 changes: 55 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# IL2CPP Scanner for DX11 <img src="https://i.imgur.com/k7Vr4yV.png" width="40" height="40">

An in game GUI tool based on [IL2CPP_Resolver](https://github.com/sneakyevil/IL2CPP_Resolver) made to modify il2cpp Unity games.

![IL2CPP Scanner](https://i.imgur.com/Fi5w9e7.png)

## Disclaimer
The software is provided as is and was made as a personal project, crashes can occur at any time.

## Compatibility
Works with Unity il2ccp games running on DirectX11.

Game must be set to borderless window or windowed mode!

## Features
- Find active GameObjects
- Find GameObject components and children components
- Find and tweak component fields, currently supported field types are:
- integers
- float
- bool
- List component properties (can't do anything with them at the moment)

## How to use
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.

1. Download the latest version from the releases page
2. Run the game
3. Inject IL2CPP Scanner.dll in the game process with any injector

To show/hide the menu press the insert key

### Basic Usage (find a GameObject individually)
1. Specify a module name
2. Search an active GameObject
3. Load the GameObject components (children components are excluded)
4. Play with the component fields

### Searching all GameObjects in a specific module
1. Specify a module name
2. Search all active GameObjects in the specified module name
3. Load the selected GameObject components (children components are excluded)
4. Play with the component fields

### Finding components in namespaces (in children of a gameobject)
1. Specify a module name
2. Specify a namespace containing the children component
3. Search for an active GameObject which children contain the desidered component
4. Play with the children component fields

### Usage video example on the game "Sons of the Forest"
[![Video example](https://i.imgur.com/b3adTug.png)](https://youtu.be/TqL_u4I1ot8)

### Credits
Thanks to [sneakyevil](https://github.com/sneakyevil) for [IL2CPP_Resolver](https://github.com/sneakyevil/IL2CPP_Resolver)
8 changes: 8 additions & 0 deletions src/GUI/GUIdefines.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

inline void AskRange();
inline void SearchEngine();
inline void GameObjectsEngine();
inline void ComponentsEngine();
inline void FieldsEngine();
inline void ChildrenEngine();
51,026 changes: 51,026 additions & 0 deletions src/GUI/font-icons/font.hpp

Large diffs are not rendered by default.

1,403 changes: 1,403 additions & 0 deletions src/GUI/font-icons/iconfont.hpp

Large diffs are not rendered by default.

235 changes: 235 additions & 0 deletions src/GUI/gui.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
#include <iostream>
#include <Windows.h>
#include <chrono>
#include <thread>
#include "memory.h"
#include "font-icons/font.hpp"
#include "GUIdefines.hpp"
#include "../engine/engine.h"

extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

HWND window = NULL;
WNDPROC oWndProc;
ID3D11Device* pDevice = NULL;
ID3D11DeviceContext* pContext = NULL;
ID3D11RenderTargetView* mainRenderTargetView;

namespace Colors
{
ImColor black(0, 0, 0);
ImColor white(255, 255, 255);
ImColor mainTheme(183, 64, 64);
ImColor* color = &mainTheme;
}

void InitImGui()
{
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
ImGui::GetIO().WantCaptureMouse || ImGui::GetIO().WantTextInput || ImGui::GetIO().WantCaptureKeyboard;
io.Fonts->AddFontFromMemoryTTF(&OpenSans_Regular_ttf, 1, 18.0);
float baseFontSize = 10.0f;
float iconFontSize = baseFontSize * 2.0f / 3.0f;
static const ImWchar icons_ranges[] = { ICON_MIN_FA, ICON_MAX_16_FA, 0 };
ImFontConfig config;
config.MergeMode = true;
config.GlyphMinAdvanceX = 10.0f;
static const ImWchar icon_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
io.Fonts->AddFontFromMemoryTTF(&icon_font_ttf, sizeof icon_font_ttf, 10.0f, &config, icon_ranges);

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");

ImGui_ImplWin32_Init(window);
ImGui_ImplDX11_Init(pDevice, pContext);
}

LRESULT __stdcall WndProc(const HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {

if (Globals::Gui::showMenu) {
ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam);
return true;
}

return CallWindowProc(oWndProc, hWnd, uMsg, wParam, lParam);
}

bool init = false;
HRESULT __stdcall hkPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags)
{
if (!init)
{
if (SUCCEEDED(pSwapChain->GetDevice(__uuidof(ID3D11Device), (void**)&pDevice)))
{
pDevice->GetImmediateContext(&pContext);
DXGI_SWAP_CHAIN_DESC sd;
pSwapChain->GetDesc(&sd);
window = sd.OutputWindow;
ID3D11Texture2D* pBackBuffer;
pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
pDevice->CreateRenderTargetView(pBackBuffer, NULL, &mainRenderTargetView);
pBackBuffer->Release();
oWndProc = (WNDPROC)SetWindowLongPtr(window, GWLP_WNDPROC, (LONG_PTR)WndProc);
InitImGui();
init = true;
}

else
return Globals::Gui::oPresent(pSwapChain, SyncInterval, Flags);
}

ImGui_ImplDX11_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
ImGui::GetMouseCursor();
ImGui::SetMouseCursor(ImGuiMouseCursor_Arrow);
ImGui::GetIO().WantCaptureMouse = Globals::Gui::showMenu;
ImGui::GetIO().MouseDrawCursor = Globals::Gui::showMenu;

if (GetAsyncKeyState(VK_INSERT) & 1)
{
Globals::Gui::showMenu = !Globals::Gui::showMenu;
}

if (Globals::Gui::showMenu)
{
Globals::Gui::style = &ImGui::GetStyle();

Globals::Gui::style->WindowTitleAlign = ImVec2(0.5, 0.5);
Globals::Gui::style->WindowBorderSize = 3.0f;
Globals::Gui::style->Colors[ImGuiCol_Border] = *Colors::color;
Globals::Gui::style->Colors[ImGuiCol_TitleBg] = *Colors::color;
Globals::Gui::style->Colors[ImGuiCol_TitleBgActive] = *Colors::color;
Globals::Gui::style->Colors[ImGuiCol_FrameBg] = ImColor(36, 36, 36);
Globals::Gui::style->Colors[ImGuiCol_FrameBgActive] = ImColor(36, 36, 36);
Globals::Gui::style->Colors[ImGuiCol_FrameBgHovered] = ImColor(45, 45, 45);
Globals::Gui::style->Colors[ImGuiCol_Button] = ImColor(32, 32, 32);
Globals::Gui::style->Colors[ImGuiCol_ButtonHovered] = ImColor(45, 45, 45);
Globals::Gui::style->Colors[ImGuiCol_ChildBg] = ImColor(36, 36, 36);

ImGui::SetNextWindowSize(ImVec2(1280, 720), ImGuiCond_Once);
ImGui::Begin("IL2CPP SCANNER " ICON_FA_MAGNIFYING_GLASS, &Globals::Gui::isOpen, ImGuiWindowFlags_NoResize);

ImGui::Columns(2, nullptr, true);
ImGui::SetColumnOffset(1, 400);
{
// Left panel GUI from here
SearchEngine(); // Search panel GUI

Globals::Gui::style->Colors[ImGuiCol_Border] = ImColor(45, 45, 45);
Globals::Gui::style->Colors[ImGuiCol_FrameBg] = ImColor(24, 24, 24);
Globals::Gui::style->Colors[ImGuiCol_FrameBgActive] = ImColor(24, 24, 24);
Globals::Gui::style->Colors[ImGuiCol_FrameBgHovered] = ImColor(45, 45, 45);

GameObjectsEngine(); // GameObjects panel GUI

ImGui::NextColumn(); // Right Column from here

// Current right panel view check
if (Globals::Gui::right_column == "component") {
ImGui::Text(Globals::GameObjectName->ToString().c_str());
ImGui::SameLine(),
ImGui::Text("Component List (Instantiated Only)");
}
else if (Globals::Gui::right_column == "children") {
ImGui::Text("Children List");
}
else if (Globals::Gui::right_column == "inside_component") {
ImGui::Text(Globals::Gui::CurrentComponentString.c_str());
}

// Right panel GUI from here
ImGui::BeginChild("right_panel", ImVec2(ImGui::GetContentRegionAvail().x, 438), true, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_MenuBar);

Globals::Gui::style->Colors[ImGuiCol_MenuBarBg] = ImColor(50, 50, 50);

ImGui::BeginMenuBar();
/* Disabled at the moment
if (ImGui::SmallButton("Components View"))
{
Globals::Gui::right_column = "component";
}
ImGui::SameLine();
if (ImGui::SmallButton("Children View"))
{
Globals::Gui::right_column = "children";
}
if (Globals::Gui::right_column != "inside_component")
{
ImGui::SetCursorPosX(800);
if (ImGui::SmallButton("Refresh"))
{
if (Globals::Gui::right_column == "component")
{
// Cleanup for imminent search
Globals::Components.clear();
Globals::ChildrenComponents.clear();
Globals::ComponentsName.clear();
Globals::ChildrenComponentsName.clear();
if (Globals::Gui::GameObjectTypeSearch_Current == 0) // Defined GameObject
{
if (Globals::Gui::ModuleNamespaceTypeSearch_Current == 1) // Defined Namespace
{
FindChildrenComponents();
}
}
else // Default namespace
{
FindComponents();
}
}
if (Globals::Gui::right_column == "children")
{
Globals::Childs.clear();
FindChildren();
}
}
}
*/
ImGui::EndMenuBar();

ComponentsEngine(); // Components view

FieldsEngine(); // Fields view

ChildrenEngine(); // Children view

ImGui::EndChild();

ImGui::SetCursorPos(ImVec2(NULL, 500));
Globals::Gui::style->Colors[ImGuiCol_Separator] = ImColor(0, 0, 0, 0);
Globals::Gui::style->Colors[ImGuiCol_SeparatorActive] = ImColor(0, 0, 0, 0);
Globals::Gui::style->Colors[ImGuiCol_SeparatorHovered] = ImColor(0, 0, 0, 0);
ImGui::Separator();

// Log panel GUI from here
ImGui::Text("Log");
ImGui::SameLine(), ImGui::SetCursorPosX(800);
if (ImGui::SmallButton("Clear"))
{
Globals::Gui::LogContent.clear();
}
Globals::Gui::style->Colors[ImGuiCol_FrameBg] = ImColor(36, 36, 36);
Globals::Gui::style->Colors[ImGuiCol_FrameBgActive] = ImColor(36, 36, 36);
Globals::Gui::style->Colors[ImGuiCol_FrameBgHovered] = ImColor(45, 45, 45);
ImGui::BeginChild("log", ImGui::GetContentRegionAvail(), true, ImGuiWindowFlags_NoResize);
ImGui::InputTextMultiline("##", &Globals::Gui::LogContent, ImGui::GetContentRegionAvail(), ImGuiInputTextFlags_ReadOnly);
ImGui::EndChild();
}

if (!Globals::Gui::isOpen)
{
Globals::Gui::showMenu = false;
Globals::Gui::isOpen = true;
}
ImGui::End();
}
ImGui::Render();

pContext->OMSetRenderTargets(1, &mainRenderTargetView, NULL);
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
return Globals::Gui::oPresent(pSwapChain, SyncInterval, Flags);
}
6 changes: 6 additions & 0 deletions src/GUI/gui.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once
#include <d3d11.h>

void InitImGui();
LRESULT __stdcall WndProc(const HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HRESULT __stdcall hkPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags);
31 changes: 31 additions & 0 deletions src/IL2CPP Scanner.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.2.32616.157
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IL2CPP Scanner", "IL2CPP Scanner\IL2CPP Scanner.vcxproj", "{C9889713-4B83-4106-8FB6-F230301FC7EB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C9889713-4B83-4106-8FB6-F230301FC7EB}.Debug|x64.ActiveCfg = Debug|x64
{C9889713-4B83-4106-8FB6-F230301FC7EB}.Debug|x64.Build.0 = Debug|x64
{C9889713-4B83-4106-8FB6-F230301FC7EB}.Debug|x86.ActiveCfg = Debug|Win32
{C9889713-4B83-4106-8FB6-F230301FC7EB}.Debug|x86.Build.0 = Debug|Win32
{C9889713-4B83-4106-8FB6-F230301FC7EB}.Release|x64.ActiveCfg = Release|x64
{C9889713-4B83-4106-8FB6-F230301FC7EB}.Release|x64.Build.0 = Release|x64
{C9889713-4B83-4106-8FB6-F230301FC7EB}.Release|x86.ActiveCfg = Release|Win32
{C9889713-4B83-4106-8FB6-F230301FC7EB}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7D4CC4FE-A34F-4E60-B4E1-B5DFD9336FB9}
EndGlobalSection
EndGlobal
Loading

0 comments on commit 05c409c

Please sign in to comment.