Initial commit, hook into StarWarsI.exe
This commit is contained in:
8
.gitignore
vendored
8
.gitignore
vendored
@@ -1,3 +1,11 @@
|
||||
x64/
|
||||
powrprof/
|
||||
.vscode/
|
||||
.vs/
|
||||
|
||||
*.vcxproj.filters
|
||||
*.vcxproj.user
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
|
||||
19
CLAUDE.md
Normal file
19
CLAUDE.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# SWEaW Hooks
|
||||
|
||||
## Project Overview
|
||||
|
||||
This project is a hook API for Star Wars: Empire at War: Forces of Corruption to expose custom Lua functions available for scripting.
|
||||
|
||||
## Client and Debug Kits
|
||||
|
||||
- StarWarsG.exe -- the binary shipped with the game for all clients. PDB unavailable.
|
||||
- StarWarsI.exe -- the debug kit binary which comes with debug functionality but is too slow to run normally. PDB available.
|
||||
|
||||
## DLL Hook
|
||||
|
||||
- Uses MinHook to create the DLL hook into the game via powerprof.dll
|
||||
- Using IDA Free to find addresses of function calls.
|
||||
|
||||
## Empire at War Lua Scripting Engine
|
||||
|
||||
The source code for the Lua scripting engine in Empire at War was leaked at: https://github.com/PetroglyphGames/GlyphX-Reference. Use this as a guide for what Lua functions and variables are already available, and how the engine hooks Lua scripting into the rest of the game. No other engine source code is available.
|
||||
13
README.md
13
README.md
@@ -1 +1,12 @@
|
||||
# SWEAW Hooks
|
||||
# SWEaW Hooks
|
||||
|
||||
A powrprof.dll hook which adds custom Lua functions to Forces of Corruption.
|
||||
|
||||
## Usage
|
||||
|
||||
Drop powrprof.dll and MinHooks.x64.dll into the `/corruption/` folder of your Empire at War installation.
|
||||
Currently only works with the debug kit `StarWarsI.exe`; `StarWarsG.exe` support is coming soon.
|
||||
|
||||
## Functions
|
||||
|
||||
- Global `WriteToFile(str a, str b)` - Appends a line of text `b` to the file name `a` in the game directory.
|
||||
31
SWEAW Hooks.sln
Normal file
31
SWEAW Hooks.sln
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.14.36127.28 d17.14
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SWEAW Hooks", "SWEAW Hooks.vcxproj", "{F2C4477F-C9F1-4AF0-A04C-9D6ADD14E783}"
|
||||
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
|
||||
{F2C4477F-C9F1-4AF0-A04C-9D6ADD14E783}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F2C4477F-C9F1-4AF0-A04C-9D6ADD14E783}.Debug|x64.Build.0 = Debug|x64
|
||||
{F2C4477F-C9F1-4AF0-A04C-9D6ADD14E783}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{F2C4477F-C9F1-4AF0-A04C-9D6ADD14E783}.Debug|x86.Build.0 = Debug|Win32
|
||||
{F2C4477F-C9F1-4AF0-A04C-9D6ADD14E783}.Release|x64.ActiveCfg = Release|x64
|
||||
{F2C4477F-C9F1-4AF0-A04C-9D6ADD14E783}.Release|x64.Build.0 = Release|x64
|
||||
{F2C4477F-C9F1-4AF0-A04C-9D6ADD14E783}.Release|x86.ActiveCfg = Release|Win32
|
||||
{F2C4477F-C9F1-4AF0-A04C-9D6ADD14E783}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {A512788C-5D26-42E2-BCB7-1459395B6B39}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
165
SWEAW Hooks.vcxproj
Normal file
165
SWEAW Hooks.vcxproj
Normal file
@@ -0,0 +1,165 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{f2c4477f-c9f1-4af0-a04c-9d6add14e783}</ProjectGuid>
|
||||
<RootNamespace>SWEAWHooks</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>powrprof</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v145</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v145</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v145</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v145</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IncludePath>C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>C:\Program Files (x86)\Windows Kits\10\Lib\10.0.26100.0\ucrt\x64;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IncludePath>C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>C:\Program Files (x86)\Windows Kits\10\Lib\10.0.26100.0\ucrt\x64;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;SWEAWHOOKS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;SWEAWHOOKS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;SWEAWHOOKS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalLibraryDirectories>minhook\bin\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<ModuleDefinitionFile>powrprof.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;SWEAWHOOKS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalLibraryDirectories>minhook\bin\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<ModuleDefinitionFile>powrprof.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="lua_hook.h" />
|
||||
<ClInclude Include="proxy.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="lua_hook.cpp" />
|
||||
<ClCompile Include="proxy.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="powrprof.def" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
26
dllmain.cpp
Normal file
26
dllmain.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "proxy.h"
|
||||
#include "lua_hook.h"
|
||||
#include <windows.h>
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) {
|
||||
switch (fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(hinstDll);
|
||||
|
||||
if (!Proxy_Init()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!LuaHook_Init()) {
|
||||
OutputDebugStringA("[SWEAW Hooks] WARNING: LuaHook_Init() failed - Lua hooks are not active.\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
LuaHook_Shutdown();
|
||||
Proxy_Shutdown();
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
116
lua_hook.cpp
Normal file
116
lua_hook.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
#include "lua_hook.h"
|
||||
#include "minhook/include/MinHook.h"
|
||||
#include <windows.h>
|
||||
|
||||
#if defined _M_X64
|
||||
#pragma comment(lib, "MinHook.x64.lib")
|
||||
#elif defined _M_IX86
|
||||
#pragma comment(lib, "MinHook.x86.lib")
|
||||
#endif
|
||||
|
||||
// Opaque Lua state - never dereferenced, just passed around
|
||||
struct lua_State;
|
||||
typedef int (*lua_CFunction)(lua_State*);
|
||||
|
||||
// Function pointer types
|
||||
typedef lua_State* (*fn_lua_open)();
|
||||
typedef void (*fn_lua_pushstring)(lua_State*, const char*);
|
||||
typedef void (*fn_lua_pushcclosure)(lua_State*, lua_CFunction, int);
|
||||
typedef void (*fn_lua_settable)(lua_State*, int);
|
||||
typedef const char* (*fn_lua_tostring)(lua_State*, int);
|
||||
|
||||
// Resolved function pointers
|
||||
static fn_lua_open real_lua_open = nullptr;
|
||||
static fn_lua_pushstring pfn_pushstring = nullptr;
|
||||
static fn_lua_pushcclosure pfn_pushcclosure = nullptr;
|
||||
static fn_lua_settable pfn_settable = nullptr;
|
||||
static fn_lua_tostring pfn_tostring = nullptr;
|
||||
|
||||
// Helper, equivalent of lua_setglobal
|
||||
static void register_global(lua_State* L, const char* name, lua_CFunction fn) {
|
||||
pfn_pushstring(L, name);
|
||||
pfn_pushcclosure(L, fn, 0);
|
||||
pfn_settable(L, LUA_GLOBALSINDEX);
|
||||
}
|
||||
|
||||
// =========================
|
||||
// Custom Lua file functions
|
||||
// =========================
|
||||
|
||||
// WriteToFile(path, text) - appends text to a file
|
||||
static int L_WriteToFile(lua_State* L) {
|
||||
const char* path = pfn_tostring(L, 1);
|
||||
const char* text = pfn_tostring(L, 2);
|
||||
|
||||
if (!path || !text) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
HANDLE hFile = CreateFileA(
|
||||
path,
|
||||
GENERIC_WRITE,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
|
||||
if (hFile != INVALID_HANDLE_VALUE) {
|
||||
DWORD written;
|
||||
|
||||
SetFilePointer(hFile, 0, NULL, FILE_END);
|
||||
WriteFile(hFile, text, lstrlenA(text), &written, NULL);
|
||||
WriteFile(hFile, "\n", 1, &written, NULL);
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// =========================
|
||||
// Hooks
|
||||
// =========================
|
||||
|
||||
// Fired every time the game creates a new Lua state
|
||||
static lua_State* Hook_lua_open() {
|
||||
lua_State* L = real_lua_open();
|
||||
|
||||
if (!L) {
|
||||
return L;
|
||||
}
|
||||
|
||||
// Register custom Lua functions
|
||||
register_global(L, "WriteToFile", L_WriteToFile);
|
||||
|
||||
return L;
|
||||
}
|
||||
|
||||
bool LuaHook_Init() {
|
||||
uintptr_t base = (uintptr_t)GetModuleHandleA(nullptr);
|
||||
|
||||
pfn_pushstring = (fn_lua_pushstring)(base + RVA_lua_pushstring);
|
||||
pfn_pushcclosure = (fn_lua_pushcclosure)(base + RVA_lua_pushcclosure);
|
||||
pfn_settable = (fn_lua_settable)(base + RVA_lua_settable);
|
||||
pfn_tostring = (fn_lua_tostring)(base + RVA_lua_tostring);
|
||||
|
||||
void* const target = (void*)(base + RVA_lua_open);
|
||||
|
||||
if (MH_Initialize() != MH_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MH_CreateHook(target, &Hook_lua_open, (void**)&real_lua_open) != MH_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MH_EnableHook(target) != MH_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LuaHook_Shutdown() {
|
||||
MH_DisableHook(MH_ALL_HOOKS);
|
||||
MH_Uninitialize();
|
||||
}
|
||||
13
lua_hook.h
Normal file
13
lua_hook.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
constexpr uintptr_t RVA_lua_open = 0x12AB790;
|
||||
constexpr uintptr_t RVA_lua_pushstring = 0x12AC930;
|
||||
constexpr uintptr_t RVA_lua_pushcclosure = 0x12AC6E0;
|
||||
constexpr uintptr_t RVA_lua_settable = 0x12AD020;
|
||||
constexpr uintptr_t RVA_lua_tostring = 0x12AD430;
|
||||
|
||||
constexpr int LUA_GLOBALSINDEX = -10001;
|
||||
|
||||
bool LuaHook_Init();
|
||||
void LuaHook_Shutdown();
|
||||
BIN
minhook/bin/MinHook.x64.exp
Normal file
BIN
minhook/bin/MinHook.x64.exp
Normal file
Binary file not shown.
BIN
minhook/bin/MinHook.x86.exp
Normal file
BIN
minhook/bin/MinHook.x86.exp
Normal file
Binary file not shown.
185
minhook/include/MinHook.h
Normal file
185
minhook/include/MinHook.h
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* MinHook - The Minimalistic API Hooking Library for x64/x86
|
||||
* Copyright (C) 2009-2017 Tsuda Kageyu.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !(defined _M_IX86) && !(defined _M_X64) && !(defined __i386__) && !(defined __x86_64__)
|
||||
#error MinHook supports only x86 and x64 systems.
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// MinHook Error Codes.
|
||||
typedef enum MH_STATUS
|
||||
{
|
||||
// Unknown error. Should not be returned.
|
||||
MH_UNKNOWN = -1,
|
||||
|
||||
// Successful.
|
||||
MH_OK = 0,
|
||||
|
||||
// MinHook is already initialized.
|
||||
MH_ERROR_ALREADY_INITIALIZED,
|
||||
|
||||
// MinHook is not initialized yet, or already uninitialized.
|
||||
MH_ERROR_NOT_INITIALIZED,
|
||||
|
||||
// The hook for the specified target function is already created.
|
||||
MH_ERROR_ALREADY_CREATED,
|
||||
|
||||
// The hook for the specified target function is not created yet.
|
||||
MH_ERROR_NOT_CREATED,
|
||||
|
||||
// The hook for the specified target function is already enabled.
|
||||
MH_ERROR_ENABLED,
|
||||
|
||||
// The hook for the specified target function is not enabled yet, or already
|
||||
// disabled.
|
||||
MH_ERROR_DISABLED,
|
||||
|
||||
// The specified pointer is invalid. It points the address of non-allocated
|
||||
// and/or non-executable region.
|
||||
MH_ERROR_NOT_EXECUTABLE,
|
||||
|
||||
// The specified target function cannot be hooked.
|
||||
MH_ERROR_UNSUPPORTED_FUNCTION,
|
||||
|
||||
// Failed to allocate memory.
|
||||
MH_ERROR_MEMORY_ALLOC,
|
||||
|
||||
// Failed to change the memory protection.
|
||||
MH_ERROR_MEMORY_PROTECT,
|
||||
|
||||
// The specified module is not loaded.
|
||||
MH_ERROR_MODULE_NOT_FOUND,
|
||||
|
||||
// The specified function is not found.
|
||||
MH_ERROR_FUNCTION_NOT_FOUND
|
||||
}
|
||||
MH_STATUS;
|
||||
|
||||
// Can be passed as a parameter to MH_EnableHook, MH_DisableHook,
|
||||
// MH_QueueEnableHook or MH_QueueDisableHook.
|
||||
#define MH_ALL_HOOKS NULL
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Initialize the MinHook library. You must call this function EXACTLY ONCE
|
||||
// at the beginning of your program.
|
||||
MH_STATUS WINAPI MH_Initialize(VOID);
|
||||
|
||||
// Uninitialize the MinHook library. You must call this function EXACTLY
|
||||
// ONCE at the end of your program.
|
||||
MH_STATUS WINAPI MH_Uninitialize(VOID);
|
||||
|
||||
// Creates a hook for the specified target function, in disabled state.
|
||||
// Parameters:
|
||||
// pTarget [in] A pointer to the target function, which will be
|
||||
// overridden by the detour function.
|
||||
// pDetour [in] A pointer to the detour function, which will override
|
||||
// the target function.
|
||||
// ppOriginal [out] A pointer to the trampoline function, which will be
|
||||
// used to call the original target function.
|
||||
// This parameter can be NULL.
|
||||
MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal);
|
||||
|
||||
// Creates a hook for the specified API function, in disabled state.
|
||||
// Parameters:
|
||||
// pszModule [in] A pointer to the loaded module name which contains the
|
||||
// target function.
|
||||
// pszProcName [in] A pointer to the target function name, which will be
|
||||
// overridden by the detour function.
|
||||
// pDetour [in] A pointer to the detour function, which will override
|
||||
// the target function.
|
||||
// ppOriginal [out] A pointer to the trampoline function, which will be
|
||||
// used to call the original target function.
|
||||
// This parameter can be NULL.
|
||||
MH_STATUS WINAPI MH_CreateHookApi(
|
||||
LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal);
|
||||
|
||||
// Creates a hook for the specified API function, in disabled state.
|
||||
// Parameters:
|
||||
// pszModule [in] A pointer to the loaded module name which contains the
|
||||
// target function.
|
||||
// pszProcName [in] A pointer to the target function name, which will be
|
||||
// overridden by the detour function.
|
||||
// pDetour [in] A pointer to the detour function, which will override
|
||||
// the target function.
|
||||
// ppOriginal [out] A pointer to the trampoline function, which will be
|
||||
// used to call the original target function.
|
||||
// This parameter can be NULL.
|
||||
// ppTarget [out] A pointer to the target function, which will be used
|
||||
// with other functions.
|
||||
// This parameter can be NULL.
|
||||
MH_STATUS WINAPI MH_CreateHookApiEx(
|
||||
LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal, LPVOID *ppTarget);
|
||||
|
||||
// Removes an already created hook.
|
||||
// Parameters:
|
||||
// pTarget [in] A pointer to the target function.
|
||||
MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget);
|
||||
|
||||
// Enables an already created hook.
|
||||
// Parameters:
|
||||
// pTarget [in] A pointer to the target function.
|
||||
// If this parameter is MH_ALL_HOOKS, all created hooks are
|
||||
// enabled in one go.
|
||||
MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget);
|
||||
|
||||
// Disables an already created hook.
|
||||
// Parameters:
|
||||
// pTarget [in] A pointer to the target function.
|
||||
// If this parameter is MH_ALL_HOOKS, all created hooks are
|
||||
// disabled in one go.
|
||||
MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget);
|
||||
|
||||
// Queues to enable an already created hook.
|
||||
// Parameters:
|
||||
// pTarget [in] A pointer to the target function.
|
||||
// If this parameter is MH_ALL_HOOKS, all created hooks are
|
||||
// queued to be enabled.
|
||||
MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget);
|
||||
|
||||
// Queues to disable an already created hook.
|
||||
// Parameters:
|
||||
// pTarget [in] A pointer to the target function.
|
||||
// If this parameter is MH_ALL_HOOKS, all created hooks are
|
||||
// queued to be disabled.
|
||||
MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget);
|
||||
|
||||
// Applies all queued changes in one go.
|
||||
MH_STATUS WINAPI MH_ApplyQueued(VOID);
|
||||
|
||||
// Translates the MH_STATUS to its name as a string.
|
||||
const char * WINAPI MH_StatusToString(MH_STATUS status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
8
powrprof.def
Normal file
8
powrprof.def
Normal file
@@ -0,0 +1,8 @@
|
||||
LIBRARY powrprof
|
||||
EXPORTS
|
||||
CallNtPowerInformation
|
||||
PowerReadACValueIndex
|
||||
PowerReadDCValueIndex
|
||||
PowerGetActiveScheme
|
||||
PowerSettingRegisterNotification
|
||||
PowerSettingUnregisterNotification
|
||||
100
proxy.cpp
Normal file
100
proxy.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
#include "proxy.h"
|
||||
|
||||
HMODULE g_hRealPowrprof = nullptr;
|
||||
|
||||
// NTSTATUS = LONG, POWER_INFORMATION_LEVEL = int; using primitive types
|
||||
// avoids pulling in powerbase.h / ntstatus.h for a simple passthrough.
|
||||
typedef LONG (WINAPI* fn_CallNtPowerInformation)(int, PVOID, ULONG, PVOID, ULONG);
|
||||
typedef DWORD (WINAPI* fn_PowerReadACValueIndex)(HKEY, const GUID*, const GUID*, const GUID*, LPDWORD);
|
||||
typedef DWORD (WINAPI* fn_PowerGetActiveScheme)(HKEY, GUID**);
|
||||
typedef DWORD (WINAPI* fn_PowerSettingRegisterNotification)(LPCGUID, DWORD, HANDLE, HANDLE*);
|
||||
typedef DWORD (WINAPI* fn_PowerSettingUnregisterNotification)(HANDLE);
|
||||
|
||||
static fn_CallNtPowerInformation real_CallNtPowerInformation = nullptr;
|
||||
static fn_PowerReadACValueIndex real_PowerReadACValueIndex = nullptr;
|
||||
static fn_PowerReadACValueIndex real_PowerReadDCValueIndex = nullptr;
|
||||
static fn_PowerGetActiveScheme real_PowerGetActiveScheme = nullptr;
|
||||
static fn_PowerSettingRegisterNotification real_PowerSettingRegisterNotification = nullptr;
|
||||
static fn_PowerSettingUnregisterNotification real_PowerSettingUnregisterNotification = nullptr;
|
||||
|
||||
bool Proxy_Init() {
|
||||
char path[MAX_PATH];
|
||||
|
||||
GetSystemDirectoryA(path, MAX_PATH);
|
||||
lstrcatA(path, "\\powrprof.dll");
|
||||
g_hRealPowrprof = LoadLibraryA(path);
|
||||
|
||||
if (!g_hRealPowrprof) {
|
||||
return false;
|
||||
}
|
||||
|
||||
real_CallNtPowerInformation = (fn_CallNtPowerInformation)
|
||||
GetProcAddress(g_hRealPowrprof, "CallNtPowerInformation");
|
||||
real_PowerReadACValueIndex = (fn_PowerReadACValueIndex)
|
||||
GetProcAddress(g_hRealPowrprof, "PowerReadACValueIndex");
|
||||
real_PowerReadDCValueIndex = (fn_PowerReadACValueIndex)
|
||||
GetProcAddress(g_hRealPowrprof, "PowerReadDCValueIndex");
|
||||
real_PowerGetActiveScheme = (fn_PowerGetActiveScheme)
|
||||
GetProcAddress(g_hRealPowrprof, "PowerGetActiveScheme");
|
||||
real_PowerSettingRegisterNotification = (fn_PowerSettingRegisterNotification)
|
||||
GetProcAddress(g_hRealPowrprof, "PowerSettingRegisterNotification");
|
||||
real_PowerSettingUnregisterNotification = (fn_PowerSettingUnregisterNotification)
|
||||
GetProcAddress(g_hRealPowrprof, "PowerSettingUnregisterNotification");
|
||||
|
||||
return real_CallNtPowerInformation != nullptr;
|
||||
}
|
||||
|
||||
void Proxy_Shutdown() {
|
||||
if (g_hRealPowrprof) {
|
||||
FreeLibrary(g_hRealPowrprof);
|
||||
g_hRealPowrprof = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
__declspec(dllexport) LONG WINAPI CallNtPowerInformation(
|
||||
int level, PVOID inBuf, ULONG inSize, PVOID outBuf, ULONG outSize)
|
||||
{
|
||||
return real_CallNtPowerInformation(level, inBuf, inSize, outBuf, outSize);
|
||||
}
|
||||
|
||||
__declspec(dllexport) DWORD WINAPI PowerReadACValueIndex(
|
||||
HKEY rootKey, const GUID* scheme, const GUID* subgroup, const GUID* setting, LPDWORD index)
|
||||
{
|
||||
if (real_PowerReadACValueIndex)
|
||||
return real_PowerReadACValueIndex(rootKey, scheme, subgroup, setting, index);
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
__declspec(dllexport) DWORD WINAPI PowerReadDCValueIndex(
|
||||
HKEY rootKey, const GUID* scheme, const GUID* subgroup, const GUID* setting, LPDWORD index)
|
||||
{
|
||||
if (real_PowerReadDCValueIndex)
|
||||
return real_PowerReadDCValueIndex(rootKey, scheme, subgroup, setting, index);
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
__declspec(dllexport) DWORD WINAPI PowerGetActiveScheme(
|
||||
HKEY userRootPowerKey, GUID** activePolicyGuid)
|
||||
{
|
||||
if (real_PowerGetActiveScheme)
|
||||
return real_PowerGetActiveScheme(userRootPowerKey, activePolicyGuid);
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
__declspec(dllexport) DWORD WINAPI PowerSettingRegisterNotification(
|
||||
LPCGUID settingGuid, DWORD flags, HANDLE recipient, HANDLE* registrationHandle)
|
||||
{
|
||||
if (real_PowerSettingRegisterNotification)
|
||||
return real_PowerSettingRegisterNotification(settingGuid, flags, recipient, registrationHandle);
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
__declspec(dllexport) DWORD WINAPI PowerSettingUnregisterNotification(
|
||||
HANDLE registrationHandle)
|
||||
{
|
||||
if (real_PowerSettingUnregisterNotification)
|
||||
return real_PowerSettingUnregisterNotification(registrationHandle);
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user