some hooking struggles. still has random stackoverflow crashes.

This commit is contained in:
NukedBart 2025-12-14 18:51:20 +08:00
parent 1cd8378078
commit f29f966846
8 changed files with 180 additions and 1014 deletions

View file

@ -69,114 +69,43 @@ static IDXGISwapChain* g_pSwapChain = nullptr;
static ID3D11RenderTargetView* g_mainRenderTargetView = nullptr;
static WNDPROC g_oOriginalWndProc = nullptr;
// =======================
// MINHOOK
// =======================
static bool g_MinHookInitialized = false;
static bool g_Hooked = false;
/// GVARS END
#define STATIC_FIELDS_OFFSET 0xB8
// il2cpp patch
// Helper: pattern scan with mask ('x' == match, '?' == wildcard)
static uint8_t* find_pattern(uint8_t* base, SIZE_T size, const unsigned char* pattern, const char* mask, SIZE_T pattern_len)
/// RNG START
auto getRandomSeed()
-> std::seed_seq
{
if (!base || !pattern || !mask || pattern_len == 0) return nullptr;
SIZE_T max_scan = (size > pattern_len) ? (size - pattern_len) : 0;
for (SIZE_T i = 0; i <= max_scan; ++i)
{
bool matched = true;
for (SIZE_T j = 0; j < pattern_len; ++j)
{
if (mask[j] == '?') continue;
if (base[i + j] != pattern[j])
{
matched = false;
break;
}
}
if (matched)
return base + i;
}
return nullptr;
}
// This gets a source of actual, honest-to-god randomness
std::random_device source;
// Find the real il2cpp_class_from_name implementation by scanning GameAssembly for an IDA-provided signature.
// Returns the function pointer if found, otherwise nullptr.
static il2cpp_class_from_name_prot find_il2cpp_class_from_name(HMODULE handle)
{
if (!handle) return nullptr;
// Get module size via PE headers
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)handle;
if (dos->e_magic != IMAGE_DOS_SIGNATURE) return nullptr;
PIMAGE_NT_HEADERS nt = (PIMAGE_NT_HEADERS)((uint8_t*)handle + dos->e_lfanew);
if (nt->Signature != IMAGE_NT_SIGNATURE) return nullptr;
SIZE_T module_size = nt->OptionalHeader.SizeOfImage;
uint8_t* base = (uint8_t*)handle;
// IDA signature:
// 4C 89 44 24 ? 48 89 54 24 ? 53 55 56 57 41 54 41 55 41 56 41 57 48 81 EC ?? ?? ?? ??
// Build pattern and mask (use 0x00 as placeholder for wildcard bytes)
const unsigned char pattern[] = {
0x4C, 0x89, 0x44, 0x24, 0x00, // 4C 89 44 24 ?
0x48, 0x89, 0x54, 0x24, 0x00, // 48 89 54 24 ?
0x53, 0x55, 0x56, 0x57,
0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57,
0x48, 0x81, 0xEC, 0x00, 0x00, 0x00, 0x00 // 48 81 EC ?? ?? ?? ??
};
// Mask: 'x' for fixed bytes, '?' for wildcard
const char mask[] = "xxxx?xxxx?xxxxxxxxxxxx????";
const SIZE_T pattern_len = sizeof(pattern);
uint8_t* found = find_pattern(base, module_size, pattern, mask, pattern_len);
if (found)
{
// The found address should point to the real function entry. Return as function pointer.
return (il2cpp_class_from_name_prot)found;
// Here, we fill an array of random data from the source
unsigned int random_data[10];
for (auto& elem : random_data) {
elem = source();
}
// If not found with this signature, attempt a looser fallback:
// Search for the common prologue bytes "53 55 56 57 41 54 41 55 41 56 41 57" (function push regs)
const unsigned char fallback_pattern[] = {
0x53, 0x55, 0x56, 0x57, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57
};
const char fallback_mask[] = "xxxxxxxxxxxx";
uint8_t* fallback_found = find_pattern(base, module_size, fallback_pattern, fallback_mask, sizeof(fallback_pattern));
if (fallback_found)
{
// Walk backwards up to a small range to try to find the full expected prologue start (heuristic).
// Limit to 32 bytes back to avoid scanning too far.
for (int back = 0; back < 32; ++back)
{
uint8_t* candidate = fallback_found - back;
// Check the bytes before candidate for the 0x4C 0x89 sequence which often starts the prologue we expect.
if (candidate >= base && candidate[0] == 0x4C && candidate[1] == 0x89)
{
return (il2cpp_class_from_name_prot)candidate;
}
}
// Otherwise return the fallback_found as best-effort.
return (il2cpp_class_from_name_prot)fallback_found;
}
return nullptr;
// this creates the random seed sequence out of the random data
return std::seed_seq(random_data + 0, random_data + 10);
}
// Find the real il2cpp_class_get_methods.
// Returns the function pointer if found, otherwise nullptr.
static il2cpp_class_get_methods_prot find_il2cpp_class_get_methods(HMODULE handle)
{
double randomnumber() {
// Making rng static ensures that it stays the same
// Between different invocations of the function
static auto seed = getRandomSeed();
static std::default_random_engine rng(seed);
if (!handle) return nullptr;
return (il2cpp_class_get_methods_prot)GetProcAddress(handle, "mono_class_get_methods");
std::uniform_real_distribution<double> dist(0.0, 1.0);
return dist(rng);
}
static il2cpp_method_get_name_prot find_il2cpp_method_get_name(HMODULE handle)
{
if (!handle) return nullptr;
return (il2cpp_method_get_name_prot)GetProcAddress(handle, "mono_property_get_set_method");
}
// il2cpp patch end
/// RNG END
/// IMGUI START
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
@ -208,45 +137,47 @@ static PresentFn oPresent = nullptr;
HRESULT __stdcall hkPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags)
{
if (!g_pd3dDevice)
static bool initialized = false;
if (!initialized)
{
if (!pSwapChain)
return S_OK;
g_pSwapChain = pSwapChain;
// D3D11 Device
if (FAILED(pSwapChain->GetDevice(__uuidof(ID3D11Device), (void**)&g_pd3dDevice)))
return oPresent(pSwapChain, SyncInterval, Flags);
return S_OK;
g_pd3dDevice->GetImmediateContext(&g_pd3dDeviceContext);
// hwnd
DXGI_SWAP_CHAIN_DESC sd{};
pSwapChain->GetDesc(&sd);
HWND hWnd = sd.OutputWindow;
// WndProc for Insert key listener
g_oOriginalWndProc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)WndProc);
// ImGui
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange;
ImGui::StyleColorsDark();
ImGui_ImplWin32_Init(hWnd);
ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);
if (!ImGui_ImplWin32_Init(hWnd) || !ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext))
return S_OK;
// create RenderTargetView
ID3D11Texture2D* pBackBuffer = nullptr;
if (SUCCEEDED(pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pBackBuffer)))
if (FAILED(pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pBackBuffer)))
return S_OK;
if (FAILED(g_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &g_mainRenderTargetView)))
{
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &g_mainRenderTargetView);
pBackBuffer->Release();
return S_OK;
}
else
{
return oPresent(pSwapChain, SyncInterval, Flags);
}
pBackBuffer->Release();
initialized = true;
}
// render
@ -258,14 +189,12 @@ HRESULT __stdcall hkPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT
{
ImGui::SetNextWindowSize(ImVec2(500, 400), ImGuiCond_FirstUseEver);
ImGui::Begin("Operator PvE for v1.0 - build 0.0.1", &g_ShowMenu);
ImGui::TextColored(ImVec4(0, 1, 0, 1), "第一阶段彻底成功!");
ImGui::Separator();
ImGui::Text("FPS: %.1f", ImGui::GetIO().Framerate);
ImGui::Text("按 INSERT 键切换菜单");
ImGui::Text("所有初始化已完成,无 goto 漏洞");
ImGui::Text("所有初始化已完成,无递归漏洞");
ImGui::TextColored(ImVec4(1, 1, 0, 1), "你可以开始第二阶段了!");
ImGui::End();
}
@ -276,59 +205,77 @@ HRESULT __stdcall hkPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT
return oPresent(pSwapChain, SyncInterval, Flags);
}
// VTable Hook
void log_info(const char* fmt, ...);
void InitMinHook()
{
if (g_MinHookInitialized) return;
if (MH_Initialize() == MH_OK)
{
g_MinHookInitialized = true;
log_info("[+] MinHook initialized");
return;
}
log_info("[-] MinHook not initialized");
}
void HookPresent()
{
while (true)
if (g_Hooked) return;
HWND gameWindow = FindWindowA("UnityWndClass", nullptr);
if (!gameWindow)
{
// 1. 等待游戏窗口创建EFT 的窗口类名是 "UnityWndClass"
HWND gameWindow = FindWindowA("UnityWndClass", nullptr);
if (!gameWindow)
{
Sleep(1000);
continue;
}
// 2. 获取游戏真正的 SwapChain
IDXGISwapChain* pSwapChain = nullptr;
ID3D11Device* pDevice = nullptr;
// 用游戏窗口创建一个“伪”描述,但实际会返回游戏正在用的 SwapChain
DXGI_SWAP_CHAIN_DESC sd{};
sd.BufferCount = 1;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = gameWindow;
sd.SampleDesc.Count = 1;
sd.Windowed = TRUE;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
HRESULT hr = D3D11CreateDeviceAndSwapChain(
nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0,
D3D11_SDK_VERSION, &sd, &pSwapChain, &pDevice, nullptr, nullptr);
if (SUCCEEDED(hr) && pSwapChain && pDevice)
{
void** vtable = *(void***)pSwapChain;
oPresent = (PresentFn)vtable[8];
// 关键:用原子操作写内存,防止崩溃
DWORD oldProtect;
VirtualProtect(&vtable[8], 8, PAGE_EXECUTE_READWRITE, &oldProtect);
vtable[8] = (void*)hkPresent;
VirtualProtect(&vtable[8], 8, oldProtect, &oldProtect);
printf("[+] We're hooked @ %p\n", &hkPresent);
pSwapChain->Release();
pDevice->Release();
break;
}
if (pSwapChain) pSwapChain->Release();
if (pDevice) pDevice->Release();
std::cout << "Hit 4." << std::endl;
Sleep(1000);
return;
}
InitMinHook();
IDXGISwapChain* pSwapChain = nullptr;
ID3D11Device* pDevice = nullptr;
DXGI_SWAP_CHAIN_DESC sd{};
sd.BufferCount = 1;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = gameWindow;
sd.SampleDesc.Count = 1;
sd.Windowed = TRUE;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
HRESULT hr = D3D11CreateDeviceAndSwapChain(
nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0,
D3D11_SDK_VERSION, &sd, &pSwapChain, &pDevice, nullptr, nullptr);
if (FAILED(hr) || !pSwapChain || !pDevice)
{
if (pSwapChain) pSwapChain->Release();
if (pDevice) pDevice->Release();
return;
}
void** vtable = *(void***)pSwapChain;
void* presentAddr = vtable[8];
if (MH_CreateHook(presentAddr, hkPresent, (LPVOID*)&oPresent) != MH_OK)
{
log_info("[-] MinHook creation failed");
goto post;
}
if (MH_EnableHook(presentAddr) != MH_OK)
{
log_info("[-] MinHook enable failed");
goto post;
}
log_info("[+] MinHook Present hooked @ %p -> %p", presentAddr, hkPresent);
g_Hooked = true;
post:
pSwapChain->Release();
pDevice->Release();
}
/// IMGUI END
@ -515,14 +462,11 @@ const Il2CppMethod* find_battleye_init(Il2CppClass* main_application)
if ((unsigned(name[0]) & 0xFF) == 0xEE &&
(unsigned(name[1]) & 0xFF) == 0x80 &&
(unsigned(name[2]) & 0xFF) == 0x81)
{
return method;
}
// In other versions, it might be ValidateAnticheat
if (strcmp(name, "ValidateAnticheat") == 0)
{
return method;
}
}
return nullptr;
}
@ -643,15 +587,7 @@ void start()
FILE* conout = nullptr;
if (freopen_s(&conout, "CONOUT$", "w", stdout) != 0)
{
printf("freopen_s failed\n");
}
if (freopen_s(&conout, "CONOUT$", "w", stderr) != 0)
{
printf("freopen_s failed\n");
}
if (freopen_s(&conout, "CONIN$", "r", stdin) != 0)
{
printf("freopen_s failed\n");
log_info("freopen_s failed");
}
// 1. Wait for GameAssembly.dll to load and get IL2CPP API addresses
@ -670,29 +606,29 @@ void start()
il2cpp_class_from_name = find_il2cpp_class_from_name(il2cpp);
if (! il2cpp_class_from_name)
{
printf("[-] il2cpp_class_from_name was not found.");
log_info("[-] il2cpp_class_from_name was not found.");
Sleep(10000);
exit(-1);
}
printf("[+] il2cpp_class_from_name loaded.");
log_info("[+] il2cpp_class_from_name loaded.");
il2cpp_class_get_methods = find_il2cpp_class_get_methods(il2cpp);
if (!il2cpp_class_get_methods)
{
printf("[-] il2cpp_class_get_methods was not found.");
log_info("[-] il2cpp_class_get_methods was not found.");
Sleep(10000);
exit(-1);
}
printf("[+] il2cpp_class_get_methods loaded.");
log_info("[+] il2cpp_class_get_methods loaded.");
il2cpp_method_get_name = find_il2cpp_method_get_name(il2cpp);
if (!il2cpp_method_get_name)
{
printf("[-] il2cpp_method_get_name was not found.");
log_info("[-] il2cpp_method_get_name was not found.");
Sleep(10000);
exit(-1);
}
printf("[+] il2cpp_method_get_name loaded.");
log_info("[+] il2cpp_method_get_name loaded.");
il2cpp_assembly_get_image = (il2cpp_assembly_get_image_prot)GetProcAddress(il2cpp, "il2cpp_assembly_get_image");
il2cpp_image_get_name = (il2cpp_image_get_name_prot)GetProcAddress(il2cpp, "il2cpp_image_get_name");
@ -706,7 +642,7 @@ void start()
printf(".");
Sleep(100);
}
printf("\n");
log_info("");
Il2CppDomain* domain = il2cpp_get_root_domain();
if (!domain) {
@ -891,13 +827,29 @@ void start()
// 8. Idle Loop and CameraManager Tracking (Core Merge)
// =================================================================
log_info("\n[+] All patches applied. Entering idle tracking loop. Hooking menu.");
CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)HookPresent, nullptr, 0, nullptr);
log_info("\n[+] All patches applied. Entering idle tracking loop.");
log_info("[!] This cheat is free of charge and available on unknowncheats.me .");
log_info("[!] If you payed for this cheat, you've been scammed.");
log_info("[!] 此作弊模块在 unknowncheats.me 上免费公开共享。");
log_info("[!] 如果你花钱了,你被骗了,请举报卖家。");
// Keep the thread alive to prevent it from exiting the IL2CPP domain, avoiding fatal GC errors.
while (true)
{
// Keep the thread active, using 3-second sleep to minimize CPU usage and set the tracking interval
Sleep(3000);
HookPresent(); // yolo
// Signature repetition
if ((int)(randomnumber() * 10) < 2)
{
log_info("[!] This cheat is free of charge and available on unknowncheats.me .");
log_info("[!] If you payed for this cheat, you've been scammed.");
log_info("[!] 此作弊模块在 unknowncheats.me 上免费公开共享。");
log_info("[!] 如果你花钱了,你被骗了,请举报卖家。");
}
// TarkovApplication instance tracking
if (!g_TarkovApplicationInstance)
{
@ -908,23 +860,20 @@ void start()
// CameraManager tracking logic
void* cm = get_camera_manager_instance(image);
if (cm)
{
// Track CameraManager instance changes - print on initial detection OR when instance changes
if (cm != g_CameraManagerInstance)
{
if (!g_CameraManagerInstance) {
log_info("[+] CameraManager initial detection: 0x%llX", (uintptr_t)cm);
}
else {
log_info("[+] CameraManager instance updated: 0x%llX", (uintptr_t)cm);
}
g_CameraManagerInstance = cm;
}
if (!cm)
continue;
// Track CameraManager instance changes - print on initial detection OR when instance changes
if (cm == g_CameraManagerInstance)
continue;
if (!g_CameraManagerInstance) {
log_info("[+] CameraManager initial detection: 0x%llX", (uintptr_t)cm);
}
else {
log_info("[+] CameraManager instance updated: 0x%llX", (uintptr_t)cm);
}
// Keep the thread active, using 3-second sleep to minimize CPU usage and set the tracking interval
Sleep(3000);
g_CameraManagerInstance = cm;
}
}

View file

@ -23,7 +23,7 @@
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{e27a8a44-4579-488b-9d79-c5634c6a9650}</ProjectGuid>
<RootNamespace>battleyent</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>
<ProjectName>iOperator</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
@ -49,7 +49,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v145</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
@ -117,13 +117,14 @@
<LanguageStandard>stdcpplatest</LanguageStandard>
<LanguageStandard_C>stdclatest</LanguageStandard_C>
<CompileAs>CompileAsCpp</CompileAs>
<AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)\minhook\include</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalDependencies>$(CoreLibraryDependencies);%(AdditionalDependencies);d3d11.lib;
dxgi.lib</AdditionalDependencies>
<AdditionalDependencies>$(CoreLibraryDependencies);%(AdditionalDependencies);d3d11.lib;dxgi.lib;libMinHook.x64.lib</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)\minhook\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -132,15 +133,20 @@ dxgi.lib</AdditionalDependencies>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;BATTLEYENT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>NDEBUG;BATTLEYENT_EXPORTS;_WINDOWS;_USRDLL;IMGUI_USER_CONFIG="imconfig_custom.h";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<LanguageStandard>stdcpplatest</LanguageStandard>
<LanguageStandard_C>stdclatest</LanguageStandard_C>
<AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)\minhook\include</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalLibraryDirectories>$(ProjectDir)\minhook\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libMinHook.x64.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>

View file

@ -1,719 +0,0 @@
#include "kiero.h"
#include <Windows.h>
#include <assert.h>
#if KIERO_INCLUDE_D3D9
# include <d3d9.h>
#endif
#if KIERO_INCLUDE_D3D10
# include <dxgi.h>
# include <d3d10_1.h>
# include <d3d10.h>
#endif
#if KIERO_INCLUDE_D3D11
# include <dxgi.h>
# include <d3d11.h>
#endif
#if KIERO_INCLUDE_D3D12
# include <dxgi.h>
# include <d3d12.h>
#endif
#if KIERO_INCLUDE_OPENGL
# include <gl/GL.h>
#endif
#if KIERO_INCLUDE_VULKAN
# include <vulkan/vulkan.h>
#endif
#if KIERO_USE_MINHOOK
# include "minhook/include/MinHook.h"
#endif
#ifdef _UNICODE
# define KIERO_TEXT(text) L##text
#else
# define KIERO_TEXT(text) text
#endif
#define KIERO_ARRAY_SIZE(arr) ((size_t)(sizeof(arr)/sizeof(arr[0])))
static kiero::RenderType::Enum g_renderType = kiero::RenderType::None;
static uint150_t* g_methodsTable = NULL;
kiero::Status::Enum kiero::init(RenderType::Enum _renderType)
{
if (g_renderType != RenderType::None)
{
return Status::AlreadyInitializedError;
}
if (_renderType != RenderType::None)
{
if (_renderType >= RenderType::D3D9 && _renderType <= RenderType::D3D12)
{
WNDCLASSEX windowClass;
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = DefWindowProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = GetModuleHandle(NULL);
windowClass.hIcon = NULL;
windowClass.hCursor = NULL;
windowClass.hbrBackground = NULL;
windowClass.lpszMenuName = NULL;
windowClass.lpszClassName = KIERO_TEXT("Kiero");
windowClass.hIconSm = NULL;
::RegisterClassEx(&windowClass);
HWND window = ::CreateWindow(windowClass.lpszClassName, KIERO_TEXT("Kiero DirectX Window"), WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, NULL, NULL, windowClass.hInstance, NULL);
if (_renderType == RenderType::D3D9)
{
#if KIERO_INCLUDE_D3D9
HMODULE libD3D9;
if ((libD3D9 = ::GetModuleHandle(KIERO_TEXT("d3d9.dll"))) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::ModuleNotFoundError;
}
void* Direct3DCreate9;
if ((Direct3DCreate9 = ::GetProcAddress(libD3D9, "Direct3DCreate9")) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
LPDIRECT3D9 direct3D9;
if ((direct3D9 = ((LPDIRECT3D9(__stdcall*)(uint32_t))(Direct3DCreate9))(D3D_SDK_VERSION)) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
D3DPRESENT_PARAMETERS params;
params.BackBufferWidth = 0;
params.BackBufferHeight = 0;
params.BackBufferFormat = D3DFMT_UNKNOWN;
params.BackBufferCount = 0;
params.MultiSampleType = D3DMULTISAMPLE_NONE;
params.MultiSampleQuality = NULL;
params.SwapEffect = D3DSWAPEFFECT_DISCARD;
params.hDeviceWindow = window;
params.Windowed = 1;
params.EnableAutoDepthStencil = 0;
params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
params.Flags = NULL;
params.FullScreen_RefreshRateInHz = 0;
params.PresentationInterval = 0;
LPDIRECT3DDEVICE9 device;
if (direct3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, window, D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_DISABLE_DRIVER_MANAGEMENT, &params, &device) < 0)
{
direct3D9->Release();
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
g_methodsTable = (uint150_t*)::calloc(119, sizeof(uint150_t));
::memcpy(g_methodsTable, *(uint150_t**)device, 119 * sizeof(uint150_t));
#if KIERO_USE_MINHOOK
MH_Initialize();
#endif
device->Release();
device = NULL;
direct3D9->Release();
direct3D9 = NULL;
g_renderType = RenderType::D3D9;
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::Success;
#endif
}
else if (_renderType == RenderType::D3D10)
{
#if KIERO_INCLUDE_D3D10
HMODULE libDXGI;
HMODULE libD3D10;
if ((libDXGI = ::GetModuleHandle(KIERO_TEXT("dxgi.dll"))) == NULL || (libD3D10 = ::GetModuleHandle(KIERO_TEXT("d3d10.dll"))) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::ModuleNotFoundError;
}
void* CreateDXGIFactory;
if ((CreateDXGIFactory = ::GetProcAddress(libDXGI, "CreateDXGIFactory")) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
IDXGIFactory* factory;
if (((long(__stdcall*)(const IID&, void**))(CreateDXGIFactory))(__uuidof(IDXGIFactory), (void**)&factory) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
IDXGIAdapter* adapter;
if (factory->EnumAdapters(0, &adapter) == DXGI_ERROR_NOT_FOUND)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
void* D3D10CreateDeviceAndSwapChain;
if ((D3D10CreateDeviceAndSwapChain = ::GetProcAddress(libD3D10, "D3D10CreateDeviceAndSwapChain")) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
DXGI_RATIONAL refreshRate;
refreshRate.Numerator = 60;
refreshRate.Denominator = 1;
DXGI_MODE_DESC bufferDesc;
bufferDesc.Width = 100;
bufferDesc.Height = 100;
bufferDesc.RefreshRate = refreshRate;
bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
DXGI_SAMPLE_DESC sampleDesc;
sampleDesc.Count = 1;
sampleDesc.Quality = 0;
DXGI_SWAP_CHAIN_DESC swapChainDesc;
swapChainDesc.BufferDesc = bufferDesc;
swapChainDesc.SampleDesc = sampleDesc;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 1;
swapChainDesc.OutputWindow = window;
swapChainDesc.Windowed = 1;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
IDXGISwapChain* swapChain;
ID3D10Device* device;
if (((long(__stdcall*)(
IDXGIAdapter*,
D3D10_DRIVER_TYPE,
HMODULE,
UINT,
UINT,
DXGI_SWAP_CHAIN_DESC*,
IDXGISwapChain**,
ID3D10Device**))(D3D10CreateDeviceAndSwapChain))(adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION, &swapChainDesc, &swapChain, &device) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
g_methodsTable = (uint150_t*)::calloc(116, sizeof(uint150_t));
::memcpy(g_methodsTable, *(uint150_t**)swapChain, 18 * sizeof(uint150_t));
::memcpy(g_methodsTable + 18, *(uint150_t**)device, 98 * sizeof(uint150_t));
#if KIERO_USE_MINHOOK
MH_Initialize();
#endif
swapChain->Release();
swapChain = NULL;
device->Release();
device = NULL;
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
g_renderType = RenderType::D3D10;
return Status::Success;
#endif
}
else if (_renderType == RenderType::D3D11)
{
#if KIERO_INCLUDE_D3D11
HMODULE libD3D11;
if ((libD3D11 = ::GetModuleHandle(KIERO_TEXT("d3d11.dll"))) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::ModuleNotFoundError;
}
void* D3D11CreateDeviceAndSwapChain;
if ((D3D11CreateDeviceAndSwapChain = ::GetProcAddress(libD3D11, "D3D11CreateDeviceAndSwapChain")) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
D3D_FEATURE_LEVEL featureLevel;
const D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_11_0 };
DXGI_RATIONAL refreshRate;
refreshRate.Numerator = 60;
refreshRate.Denominator = 1;
DXGI_MODE_DESC bufferDesc;
bufferDesc.Width = 100;
bufferDesc.Height = 100;
bufferDesc.RefreshRate = refreshRate;
bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
DXGI_SAMPLE_DESC sampleDesc;
sampleDesc.Count = 1;
sampleDesc.Quality = 0;
DXGI_SWAP_CHAIN_DESC swapChainDesc;
swapChainDesc.BufferDesc = bufferDesc;
swapChainDesc.SampleDesc = sampleDesc;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 1;
swapChainDesc.OutputWindow = window;
swapChainDesc.Windowed = 1;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
IDXGISwapChain* swapChain;
ID3D11Device* device;
ID3D11DeviceContext* context;
if (((long(__stdcall*)(
IDXGIAdapter*,
D3D_DRIVER_TYPE,
HMODULE,
UINT,
const D3D_FEATURE_LEVEL*,
UINT,
UINT,
const DXGI_SWAP_CHAIN_DESC*,
IDXGISwapChain**,
ID3D11Device**,
D3D_FEATURE_LEVEL*,
ID3D11DeviceContext**))(D3D11CreateDeviceAndSwapChain))(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, featureLevels, 2, D3D11_SDK_VERSION, &swapChainDesc, &swapChain, &device, &featureLevel, &context) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
g_methodsTable = (uint150_t*)::calloc(205, sizeof(uint150_t));
::memcpy(g_methodsTable, *(uint150_t**)swapChain, 18 * sizeof(uint150_t));
::memcpy(g_methodsTable + 18, *(uint150_t**)device, 43 * sizeof(uint150_t));
::memcpy(g_methodsTable + 18 + 43, *(uint150_t**)context, 144 * sizeof(uint150_t));
#if KIERO_USE_MINHOOK
MH_Initialize();
#endif
swapChain->Release();
swapChain = NULL;
device->Release();
device = NULL;
context->Release();
context = NULL;
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
g_renderType = RenderType::D3D11;
return Status::Success;
#endif
}
else if (_renderType == RenderType::D3D12)
{
#if KIERO_INCLUDE_D3D12
HMODULE libDXGI;
HMODULE libD3D12;
if ((libDXGI = ::GetModuleHandle(KIERO_TEXT("dxgi.dll"))) == NULL || (libD3D12 = ::GetModuleHandle(KIERO_TEXT("d3d12.dll"))) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::ModuleNotFoundError;
}
void* CreateDXGIFactory;
if ((CreateDXGIFactory = ::GetProcAddress(libDXGI, "CreateDXGIFactory")) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
IDXGIFactory* factory;
if (((long(__stdcall*)(const IID&, void**))(CreateDXGIFactory))(__uuidof(IDXGIFactory), (void**)&factory) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
IDXGIAdapter* adapter;
if (factory->EnumAdapters(0, &adapter) == DXGI_ERROR_NOT_FOUND)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
void* D3D12CreateDevice;
if ((D3D12CreateDevice = ::GetProcAddress(libD3D12, "D3D12CreateDevice")) == NULL)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
ID3D12Device* device;
if (((long(__stdcall*)(IUnknown*, D3D_FEATURE_LEVEL, const IID&, void**))(D3D12CreateDevice))(adapter, D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), (void**)&device) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
D3D12_COMMAND_QUEUE_DESC queueDesc;
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
queueDesc.Priority = 0;
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
queueDesc.NodeMask = 0;
ID3D12CommandQueue* commandQueue;
if (device->CreateCommandQueue(&queueDesc, __uuidof(ID3D12CommandQueue), (void**)&commandQueue) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
ID3D12CommandAllocator* commandAllocator;
if (device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(ID3D12CommandAllocator), (void**)&commandAllocator) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
ID3D12GraphicsCommandList* commandList;
if (device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, commandAllocator, NULL, __uuidof(ID3D12GraphicsCommandList), (void**)&commandList) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
DXGI_RATIONAL refreshRate;
refreshRate.Numerator = 60;
refreshRate.Denominator = 1;
DXGI_MODE_DESC bufferDesc;
bufferDesc.Width = 100;
bufferDesc.Height = 100;
bufferDesc.RefreshRate = refreshRate;
bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
DXGI_SAMPLE_DESC sampleDesc;
sampleDesc.Count = 1;
sampleDesc.Quality = 0;
DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
swapChainDesc.BufferDesc = bufferDesc;
swapChainDesc.SampleDesc = sampleDesc;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 2;
swapChainDesc.OutputWindow = window;
swapChainDesc.Windowed = 1;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
IDXGISwapChain* swapChain;
if (factory->CreateSwapChain(commandQueue, &swapChainDesc, &swapChain) < 0)
{
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::UnknownError;
}
g_methodsTable = (uint150_t*)::calloc(150, sizeof(uint150_t));
::memcpy(g_methodsTable, *(uint150_t**)device, 44 * sizeof(uint150_t));
::memcpy(g_methodsTable + 44, *(uint150_t**)commandQueue, 19 * sizeof(uint150_t));
::memcpy(g_methodsTable + 44 + 19, *(uint150_t**)commandAllocator, 9 * sizeof(uint150_t));
::memcpy(g_methodsTable + 44 + 19 + 9, *(uint150_t**)commandList, 60 * sizeof(uint150_t));
::memcpy(g_methodsTable + 44 + 19 + 9 + 60, *(uint150_t**)swapChain, 18 * sizeof(uint150_t));
#if KIERO_USE_MINHOOK
MH_Initialize();
#endif
device->Release();
device = NULL;
commandQueue->Release();
commandQueue = NULL;
commandAllocator->Release();
commandAllocator = NULL;
commandList->Release();
commandList = NULL;
swapChain->Release();
swapChain = NULL;
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
g_renderType = RenderType::D3D12;
return Status::Success;
#endif
}
::DestroyWindow(window);
::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance);
return Status::NotSupportedError;
}
else if (_renderType != RenderType::Auto)
{
if (_renderType == RenderType::OpenGL)
{
#if KIERO_INCLUDE_OPENGL
HMODULE libOpenGL32;
if ((libOpenGL32 = ::GetModuleHandle(KIERO_TEXT("opengl32.dll"))) == NULL)
{
return Status::ModuleNotFoundError;
}
const char* const methodsNames[] = {
"glAccum", "glAlphaFunc", "glAreTexturesResident", "glArrayElement", "glBegin", "glBindTexture", "glBitmap", "glBlendFunc", "glCallList", "glCallLists", "glClear", "glClearAccum",
"glClearColor", "glClearDepth", "glClearIndex", "glClearStencil", "glClipPlane", "glColor3b", "glColor3bv", "glColor3d", "glColor3dv", "glColor3f", "glColor3fv", "glColor3i", "glColor3iv",
"glColor3s", "glColor3sv", "glColor3ub", "glColor3ubv", "glColor3ui", "glColor3uiv", "glColor3us", "glColor3usv", "glColor4b", "glColor4bv", "glColor4d", "glColor4dv", "glColor4f",
"glColor4fv", "glColor4i", "glColor4iv", "glColor4s", "glColor4sv", "glColor4ub", "glColor4ubv", "glColor4ui", "glColor4uiv", "glColor4us", "glColor4usv", "glColorMask", "glColorMaterial",
"glColorPointer", "glCopyPixels", "glCopyTexImage1D", "glCopyTexImage2D", "glCopyTexSubImage1D", "glCopyTexSubImage2D", "glCullFaceglCullFace", "glDeleteLists", "glDeleteTextures",
"glDepthFunc", "glDepthMask", "glDepthRange", "glDisable", "glDisableClientState", "glDrawArrays", "glDrawBuffer", "glDrawElements", "glDrawPixels", "glEdgeFlag", "glEdgeFlagPointer",
"glEdgeFlagv", "glEnable", "glEnableClientState", "glEnd", "glEndList", "glEvalCoord1d", "glEvalCoord1dv", "glEvalCoord1f", "glEvalCoord1fv", "glEvalCoord2d", "glEvalCoord2dv",
"glEvalCoord2f", "glEvalCoord2fv", "glEvalMesh1", "glEvalMesh2", "glEvalPoint1", "glEvalPoint2", "glFeedbackBuffer", "glFinish", "glFlush", "glFogf", "glFogfv", "glFogi", "glFogiv",
"glFrontFace", "glFrustum", "glGenLists", "glGenTextures", "glGetBooleanv", "glGetClipPlane", "glGetDoublev", "glGetError", "glGetFloatv", "glGetIntegerv", "glGetLightfv", "glGetLightiv",
"glGetMapdv", "glGetMapfv", "glGetMapiv", "glGetMaterialfv", "glGetMaterialiv", "glGetPixelMapfv", "glGetPixelMapuiv", "glGetPixelMapusv", "glGetPointerv", "glGetPolygonStipple",
"glGetString", "glGetTexEnvfv", "glGetTexEnviv", "glGetTexGendv", "glGetTexGenfv", "glGetTexGeniv", "glGetTexImage", "glGetTexLevelParameterfv", "glGetTexLevelParameteriv",
"glGetTexParameterfv", "glGetTexParameteriv", "glHint", "glIndexMask", "glIndexPointer", "glIndexd", "glIndexdv", "glIndexf", "glIndexfv", "glIndexi", "glIndexiv", "glIndexs", "glIndexsv",
"glIndexub", "glIndexubv", "glInitNames", "glInterleavedArrays", "glIsEnabled", "glIsList", "glIsTexture", "glLightModelf", "glLightModelfv", "glLightModeli", "glLightModeliv", "glLightf",
"glLightfv", "glLighti", "glLightiv", "glLineStipple", "glLineWidth", "glListBase", "glLoadIdentity", "glLoadMatrixd", "glLoadMatrixf", "glLoadName", "glLogicOp", "glMap1d", "glMap1f",
"glMap2d", "glMap2f", "glMapGrid1d", "glMapGrid1f", "glMapGrid2d", "glMapGrid2f", "glMaterialf", "glMaterialfv", "glMateriali", "glMaterialiv", "glMatrixMode", "glMultMatrixd",
"glMultMatrixf", "glNewList", "glNormal3b", "glNormal3bv", "glNormal3d", "glNormal3dv", "glNormal3f", "glNormal3fv", "glNormal3i", "glNormal3iv", "glNormal3s", "glNormal3sv",
"glNormalPointer", "glOrtho", "glPassThrough", "glPixelMapfv", "glPixelMapuiv", "glPixelMapusv", "glPixelStoref", "glPixelStorei", "glPixelTransferf", "glPixelTransferi", "glPixelZoom",
"glPointSize", "glPolygonMode", "glPolygonOffset", "glPolygonStipple", "glPopAttrib", "glPopClientAttrib", "glPopMatrix", "glPopName", "glPrioritizeTextures", "glPushAttrib",
"glPushClientAttrib", "glPushMatrix", "glPushName", "glRasterPos2d", "glRasterPos2dv", "glRasterPos2f", "glRasterPos2fv", "glRasterPos2i", "glRasterPos2iv", "glRasterPos2s",
"glRasterPos2sv", "glRasterPos3d", "glRasterPos3dv", "glRasterPos3f", "glRasterPos3fv", "glRasterPos3i", "glRasterPos3iv", "glRasterPos3s", "glRasterPos3sv", "glRasterPos4d",
"glRasterPos4dv", "glRasterPos4f", "glRasterPos4fv", "glRasterPos4i", "glRasterPos4iv", "glRasterPos4s", "glRasterPos4sv", "glReadBuffer", "glReadPixels", "glRectd", "glRectdv", "glRectf",
"glRectfv", "glRecti", "glRectiv", "glRects", "glRectsv", "glRenderMode", "glRotated", "glRotatef", "glScaled", "glScalef", "glScissor", "glSelectBuffer", "glShadeModel", "glStencilFunc",
"glStencilMask", "glStencilOp", "glTexCoord1d", "glTexCoord1dv", "glTexCoord1f", "glTexCoord1fv", "glTexCoord1i", "glTexCoord1iv", "glTexCoord1s", "glTexCoord1sv", "glTexCoord2d",
"glTexCoord2dv", "glTexCoord2f", "glTexCoord2fv", "glTexCoord2i", "glTexCoord2iv", "glTexCoord2s", "glTexCoord2sv", "glTexCoord3d", "glTexCoord3dv", "glTexCoord3f", "glTexCoord3fv",
"glTexCoord3i", "glTexCoord3iv", "glTexCoord3s", "glTexCoord3sv", "glTexCoord4d", "glTexCoord4dv", "glTexCoord4f", "glTexCoord4fv", "glTexCoord4i", "glTexCoord4iv", "glTexCoord4s",
"glTexCoord4sv", "glTexCoordPointer", "glTexEnvf", "glTexEnvfv", "glTexEnvi", "glTexEnviv", "glTexGend", "glTexGendv", "glTexGenf", "glTexGenfv", "glTexGeni", "glTexGeniv", "glTexImage1D",
"glTexImage2D", "glTexParameterf", "glTexParameterfv", "glTexParameteri", "glTexParameteriv", "glTexSubImage1D", "glTexSubImage2D", "glTranslated", "glTranslatef", "glVertex2d",
"glVertex2dv", "glVertex2f", "glVertex2fv", "glVertex2i", "glVertex2iv", "glVertex2s", "glVertex2sv", "glVertex3d", "glVertex3dv", "glVertex3f", "glVertex3fv", "glVertex3i", "glVertex3iv",
"glVertex3s", "glVertex3sv", "glVertex4d", "glVertex4dv", "glVertex4f", "glVertex4fv", "glVertex4i", "glVertex4iv", "glVertex4s", "glVertex4sv", "glVertexPointer", "glViewport"
};
size_t size = KIERO_ARRAY_SIZE(methodsNames);
g_methodsTable = (uint150_t*)::calloc(size, sizeof(uint150_t));
for (int i = 0; i < size; i++)
{
g_methodsTable[i] = (uint150_t)::GetProcAddress(libOpenGL32, methodsNames[i]);
}
#if KIERO_USE_MINHOOK
MH_Initialize();
#endif
g_renderType = RenderType::OpenGL;
return Status::Success;
#endif
}
else if (_renderType == RenderType::Vulkan)
{
#if KIERO_INCLUDE_VULKAN
HMODULE libVulkan;
if ((libVulkan = GetModuleHandle(KIERO_TEXT("vulkan-1.dll"))) == NULL)
{
return Status::ModuleNotFoundError;
}
const char* const methodsNames[] = {
"vkCreateInstance", "vkDestroyInstance", "vkEnumeratePhysicalDevices", "vkGetPhysicalDeviceFeatures", "vkGetPhysicalDeviceFormatProperties", "vkGetPhysicalDeviceImageFormatProperties",
"vkGetPhysicalDeviceProperties", "vkGetPhysicalDeviceQueueFamilyProperties", "vkGetPhysicalDeviceMemoryProperties", "vkGetInstanceProcAddr", "vkGetDeviceProcAddr", "vkCreateDevice",
"vkDestroyDevice", "vkEnumerateInstanceExtensionProperties", "vkEnumerateDeviceExtensionProperties", "vkEnumerateDeviceLayerProperties", "vkGetDeviceQueue", "vkQueueSubmit", "vkQueueWaitIdle",
"vkDeviceWaitIdle", "vkAllocateMemory", "vkFreeMemory", "vkMapMemory", "vkUnmapMemory", "vkFlushMappedMemoryRanges", "vkInvalidateMappedMemoryRanges", "vkGetDeviceMemoryCommitment",
"vkBindBufferMemory", "vkBindImageMemory", "vkGetBufferMemoryRequirements", "vkGetImageMemoryRequirements", "vkGetImageSparseMemoryRequirements", "vkGetPhysicalDeviceSparseImageFormatProperties",
"vkQueueBindSparse", "vkCreateFence", "vkDestroyFence", "vkResetFences", "vkGetFenceStatus", "vkWaitForFences", "vkCreateSemaphore", "vkDestroySemaphore", "vkCreateEvent", "vkDestroyEvent",
"vkGetEventStatus", "vkSetEvent", "vkResetEvent", "vkCreateQueryPool", "vkDestroyQueryPool", "vkGetQueryPoolResults", "vkCreateBuffer", "vkDestroyBuffer", "vkCreateBufferView", "vkDestroyBufferView",
"vkCreateImage", "vkDestroyImage", "vkGetImageSubresourceLayout", "vkCreateImageView", "vkDestroyImageView", "vkCreateShaderModule", "vkDestroyShaderModule", "vkCreatePipelineCache",
"vkDestroyPipelineCache", "vkGetPipelineCacheData", "vkMergePipelineCaches", "vkCreateGraphicsPipelines", "vkCreateComputePipelines", "vkDestroyPipeline", "vkCreatePipelineLayout",
"vkDestroyPipelineLayout", "vkCreateSampler", "vkDestroySampler", "vkCreateDescriptorSetLayout", "vkDestroyDescriptorSetLayout", "vkCreateDescriptorPool", "vkDestroyDescriptorPool",
"vkResetDescriptorPool", "vkAllocateDescriptorSets", "vkFreeDescriptorSets", "vkUpdateDescriptorSets", "vkCreateFramebuffer", "vkDestroyFramebuffer", "vkCreateRenderPass", "vkDestroyRenderPass",
"vkGetRenderAreaGranularity", "vkCreateCommandPool", "vkDestroyCommandPool", "vkResetCommandPool", "vkAllocateCommandBuffers", "vkFreeCommandBuffers", "vkBeginCommandBuffer", "vkEndCommandBuffer",
"vkResetCommandBuffer", "vkCmdBindPipeline", "vkCmdSetViewport", "vkCmdSetScissor", "vkCmdSetLineWidth", "vkCmdSetDepthBias", "vkCmdSetBlendConstants", "vkCmdSetDepthBounds",
"vkCmdSetStencilCompareMask", "vkCmdSetStencilWriteMask", "vkCmdSetStencilReference", "vkCmdBindDescriptorSets", "vkCmdBindIndexBuffer", "vkCmdBindVertexBuffers", "vkCmdDraw", "vkCmdDrawIndexed",
"vkCmdDrawIndirect", "vkCmdDrawIndexedIndirect", "vkCmdDispatch", "vkCmdDispatchIndirect", "vkCmdCopyBuffer", "vkCmdCopyImage", "vkCmdBlitImage", "vkCmdCopyBufferToImage", "vkCmdCopyImageToBuffer",
"vkCmdUpdateBuffer", "vkCmdFillBuffer", "vkCmdClearColorImage", "vkCmdClearDepthStencilImage", "vkCmdClearAttachments", "vkCmdResolveImage", "vkCmdSetEvent", "vkCmdResetEvent", "vkCmdWaitEvents",
"vkCmdPipelineBarrier", "vkCmdBeginQuery", "vkCmdEndQuery", "vkCmdResetQueryPool", "vkCmdWriteTimestamp", "vkCmdCopyQueryPoolResults", "vkCmdPushConstants", "vkCmdBeginRenderPass", "vkCmdNextSubpass",
"vkCmdEndRenderPass", "vkCmdExecuteCommands"
};
size_t size = KIERO_ARRAY_SIZE(methodsNames);
g_methodsTable = (uint150_t*)::calloc(size, sizeof(uint150_t));
for (int i = 0; i < size; i++)
{
g_methodsTable[i] = (uint150_t)::GetProcAddress(libVulkan, methodsNames[i]);
}
#if KIERO_USE_MINHOOK
MH_Initialize();
#endif
g_renderType = RenderType::Vulkan;
return Status::Success;
#endif
}
return Status::NotSupportedError;
}
else
{
RenderType::Enum type = RenderType::None;
if (::GetModuleHandle(KIERO_TEXT("d3d9.dll")) != NULL)
{
type = RenderType::D3D9;
}
else if (::GetModuleHandle(KIERO_TEXT("d3d10.dll")) != NULL)
{
type = RenderType::D3D10;
}
else if (::GetModuleHandle(KIERO_TEXT("d3d11.dll")) != NULL)
{
type = RenderType::D3D11;
}
else if (::GetModuleHandle(KIERO_TEXT("d3d12.dll")) != NULL)
{
type = RenderType::D3D12;
}
else if (::GetModuleHandle(KIERO_TEXT("opengl32.dll")) != NULL)
{
type = RenderType::OpenGL;
}
else if (::GetModuleHandle(KIERO_TEXT("vulkan-1.dll")) != NULL)
{
type = RenderType::Vulkan;
}
else
{
return Status::NotSupportedError;
}
return init(type);
}
}
return Status::Success;
}
void kiero::shutdown()
{
if (g_renderType != RenderType::None)
{
#if KIERO_USE_MINHOOK
MH_DisableHook(MH_ALL_HOOKS);
#endif
::free(g_methodsTable);
g_methodsTable = NULL;
g_renderType = RenderType::None;
}
}
kiero::Status::Enum kiero::bind(uint16_t _index, void** _original, void* _function)
{
// TODO: Need own detour function
assert(_original != NULL && _function != NULL);
if (g_renderType != RenderType::None)
{
#if KIERO_USE_MINHOOK
void* target = (void*)g_methodsTable[_index];
if (MH_CreateHook(target, _function, _original) != MH_OK || MH_EnableHook(target) != MH_OK)
{
return Status::UnknownError;
}
#endif
return Status::Success;
}
return Status::NotInitializedError;
}
void kiero::unbind(uint16_t _index)
{
if (g_renderType != RenderType::None)
{
#if KIERO_USE_MINHOOK
MH_DisableHook((void*)g_methodsTable[_index]);
#endif
}
}
kiero::RenderType::Enum kiero::getRenderType()
{
return g_renderType;
}
uint150_t* kiero::getMethodsTable()
{
return g_methodsTable;
}

View file

@ -1,78 +0,0 @@
#ifndef __KIERO_H__
#define __KIERO_H__
#include <stdint.h>
#define KIERO_VERSION "1.2.12"
#define KIERO_INCLUDE_D3D9 0 // 1 if you need D3D9 hook
#define KIERO_INCLUDE_D3D10 0 // 1 if you need D3D10 hook
#define KIERO_INCLUDE_D3D11 0 // 1 if you need D3D11 hook
#define KIERO_INCLUDE_D3D12 0 // 1 if you need D3D12 hook
#define KIERO_INCLUDE_OPENGL 0 // 1 if you need OpenGL hook
#define KIERO_INCLUDE_VULKAN 0 // 1 if you need Vulkan hook
#define KIERO_USE_MINHOOK 0 // 1 if you will use kiero::bind function
#define KIERO_ARCH_X64 0
#define KIERO_ARCH_X86 0
#if defined(_M_X64)
# undef KIERO_ARCH_X64
# define KIERO_ARCH_X64 1
#else
# undef KIERO_ARCH_X86
# define KIERO_ARCH_X86 1
#endif
#if KIERO_ARCH_X64
typedef uint64_t uint150_t;
#else
typedef uint32_t uint150_t;
#endif
namespace kiero
{
struct Status
{
enum Enum
{
UnknownError = -1,
NotSupportedError = -2,
ModuleNotFoundError = -3,
AlreadyInitializedError = -4,
NotInitializedError = -5,
Success = 0,
};
};
struct RenderType
{
enum Enum
{
None,
D3D9,
D3D10,
D3D11,
D3D12,
OpenGL,
Vulkan,
Auto
};
};
Status::Enum init(RenderType::Enum renderType);
void shutdown();
Status::Enum bind(uint16_t index, void** original, void* function);
void unbind(uint16_t index);
RenderType::Enum getRenderType();
uint150_t* getMethodsTable();
}
#endif // __KIERO_H__

View file

@ -25,6 +25,11 @@
#include <cstdio>
#include <mutex> // Include for thread synchronization, optimizing logging safety
// =======================
// IL2CPP
// =======================
#include "il2cpp.h"
// =======================
// IMGUI
// =======================
@ -32,11 +37,6 @@
#include "imgui/imgui_impl_win32.h"
#include "imgui/imgui_impl_dx11.h"
// =======================
// KIERO
// =======================
#include "kiero/kiero.h"
// =======================
// MINHOOK
// =======================
@ -47,4 +47,6 @@
// =======================
#include "offsets.h"
// RNG
#include <random>
#endif // PCH_H

View file

@ -9,6 +9,10 @@ int main()
LOG_I("Battleyen't for il2cpp - Suchi96");
LOG_I("This cheat is free on UnknownCheats.me . If you payed for it, you've been scammed!");
LOG_I("此作弊程序在UnknownCheats.me上免费发布。如果您付费购买此作弊程序您被骗了。请检举卖家。");
LOG_I("");
LOG_I("");
LOG_I("");
LOG_I("Join my Discord server: https://discord.gg/8WnvhuYb2k (100 Uses!) or add me(@nukedbart) instead.");
while (!PrivilegeManager::ElevateNow())
{

View file

@ -23,7 +23,7 @@
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{74bbba60-a5fb-4621-8389-40dcef552cc0}</ProjectGuid>
<RootNamespace>operator</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@ -48,7 +48,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v145</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
@ -120,7 +120,8 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<LanguageStandard>stdcpplatest</LanguageStandard>
<LanguageStandard_C>stdclatest</LanguageStandard_C>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>

View file

@ -23,7 +23,7 @@
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{7cd1f94c-601c-4c92-baea-56fa5a8f09f6}</ProjectGuid>
<RootNamespace>service</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>
<ProjectName>service</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
@ -49,7 +49,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v145</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
@ -121,7 +121,8 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<LanguageStandard>stdcpplatest</LanguageStandard>
<LanguageStandard_C>stdclatest</LanguageStandard_C>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>