Initial commit, hook into StarWarsI.exe

This commit is contained in:
2026-02-27 21:53:08 -06:00
parent f4c90a15cd
commit cb9c3879ce
14 changed files with 690 additions and 1 deletions

8
.gitignore vendored
View File

@@ -1,3 +1,11 @@
x64/
powrprof/
.vscode/
.vs/
*.vcxproj.filters
*.vcxproj.user
# Prerequisites # Prerequisites
*.d *.d

19
CLAUDE.md Normal file
View 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.

View File

@@ -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
View 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
View 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
View 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
View 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
View 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

Binary file not shown.

BIN
minhook/bin/MinHook.x86.exp Normal file

Binary file not shown.

185
minhook/include/MinHook.h Normal file
View 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
View File

@@ -0,0 +1,8 @@
LIBRARY powrprof
EXPORTS
CallNtPowerInformation
PowerReadACValueIndex
PowerReadDCValueIndex
PowerGetActiveScheme
PowerSettingRegisterNotification
PowerSettingUnregisterNotification

100
proxy.cpp Normal file
View 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;
}
}

7
proxy.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
extern HMODULE g_hRealPowrprof;
bool Proxy_Init();
void Proxy_Shutdown();