Giter Club home page Giter Club logo

polyhook's Introduction

PolyHook - x86/x64 Hooking Library

Provides abstract C++ 11 interface for various hooking methods

Technical Writeup: https://www.codeproject.com/articles/1100579/polyhook-the-cplusplus-x-x-hooking-library

OUTDATED

Please use V2: https://github.com/stevemk14ebr/PolyHook_2_0. Consider sponsoring my development by clicking sponsor up in the top right!

Hooking Methods*:

  1. Detour
  • Description: Modifies opcode to jmp to hook and allocates a trampoline for jmp back
  • Length Disassembler Support (Capstone)
  • Supports Code Relocation, including EIP/RIP relative instructions
  1. Virtual Function Detour :
  • Description: Detours the function pointed to by the Vtable
  1. Virtual Function Pointer Swap
  • Description: Swaps the pointer in the Vtable to your hook
  1. Virtual Table Pointer Swap
  • Description: Swaps the Vtable pointer after copying pointers in source Vtable, then swaps virtual function pointer in the new copy
  1. Import Address Table
  • Description: Swaps pointer in the import address table to the hook
  1. VEH
  • Description: Intercepts an exception generated on purpose, sets instruction pointer to handler, then resets exception generating mechanism

  • Methods to generate exception: INT3 Breakpoints, Guard Page violations.

  • Note: it is important to call the GetProtectionObject function INSIDE of your callback as per my example for all VEH hooks

  • Other exception generation methods are in development

  • All methods support x86 and x64

  • Relies on modified capstone branch https://github.com/stevemk14ebr/capstone

  • More Information can be found at the wiki to the right

Credits to DarthTon, evolution536, Dogmatt

Samples:

The file Tests.cpp provides examples for every type of hooking method. Accompanied with these examples is unit testing code provided by the fantastic library Catch (https://github.com/philsquared/Catch/blob/master/docs/tutorial.md). With the addition of this code the example may look a little complex, the general interface is extremely simple, all hook types expose setup, hook, and unhook methods:

std::shared_ptr<PLH::Detour> Detour_Ex(new PLH::Detour);
Detour_Ex->SetupHook((BYTE*)&MessageBoxA,(BYTE*) &hkMessageBoxA); //can cast to byte* to
Detour_Ex->Hook();
oMessageBoxA = Detour_Ex->GetOriginal<tMessageBoxA>();
Detour_Ex->UnHook();

LICENSE:

MIT

polyhook's People

Contributors

stevemk14ebr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

polyhook's Issues

Other cpu types

Are there any plans for other cpu types, specifically
Intel 960
MPC 8245 (PowerPC)
P2041 (PowerPC)

Regards, Even

VEH::HARDWARE_BP hook gets called once

When I try to hook a function through your HWBP method, it gets called only once / hook setup.
Used your example:

typedef int(__stdcall* tVEH)(int intparam);
tVEH oVEHTest;
__declspec(noinline) int __stdcall VEHTest(int param)
{
	printf("original called.\n");
	return 3;
}

std::shared_ptr<PLH::VEHHook> VEHHook_Ex;
__declspec(noinline) int __stdcall hkVEHTest(int param)
{
	auto ProtectionObject = VEHHook_Ex->GetProtectionObject();
	printf("hook called.\n");
	return oVEHTest(param) + 1;
}
SECTION("Hardware Type Breakpoint")
{
	VEHHook_Ex->SetupHook((BYTE*)&VEHTest, (BYTE*)&hkVEHTest, PLH::VEHHook::VEHMethod::HARDWARE_BP);
	REQUIRE(VEHHook_Ex->Hook());
	oVEHTest = VEHHook_Ex->GetOriginal<tVEH>();
	VEHTest(0);
	VEHTest(1);
	VEHTest(2);

	VEHHook_Ex->UnHook();
}

Output: Image

Usage of VEH hook

why do i need to loop the ->hook to update the screen :( .. in d3d good hook i use VEHHook i dont need to loop because its permanent;
now i try to use it on different lvl like

VEHHook = new PLH::VEHHook;
    VEHHook->SetupHook((BYTE*)WriteServerConsole, (BYTE*)&hWriteServerConsole);
    VEHHook->Hook();
    oWriteServerConsole = VEHHook->GetOriginal<tWriteServerConsole>();

server response but you need to make thread

CreateThread( NULL, NULL, (LPTHREAD_START_ROUTINE)OverwriteValues, NULL, NULL, NULL );  

and do this for

DWORD WINAPI OverwriteValues()
{

for (;;Sleep(150))
{

    VEHHook->Hook();
}

}

how to make this permanent hook :( do i really need this "for (;;Sleep(150))" or there's something i dint know ?

DLL Console Debug Purpose
Engine Started
[SERVER] @ - Call CGameGuardMgr::CGameGuardMgr(): Before
[SERVER] @ - Call CTextInfoMgr::GetText_FromMiscMsgW() -> szName = %s
[SERVER] @ - Version = %s
etc ...........

[SERVER] @ - Call NetComponent_CreateGameStage< %s >::OnEvent

Trampoline memory region doesn't get allocated (x64)

Hey there,

I am having some issues with PolyHook.
When I try hooking a particular function, the trampoline memory region doesn't seem to get allocated.
The PolyHook output shows the fixed trampoline, but when I go to the trampoline address, the region isn't allocated. The original function also doesn't get patched.

PolyHook output:

PolyHook x64Detour: Allocation within +-2GB Succeeded Delta:[0.019124 GB] Percent Tolerance Used[3.824848 % out of 2GB]

ORIGINAL:
7FF6A713D010 [5]: 48 89 5C 24 10 mov qword ptr [rsp + 0x10], rbx
7FF6A713D015 [5]: 48 89 74 24 18 mov qword ptr [rsp + 0x18], rsi
7FF6A713D01A [5]: 48 89 7C 24 20 mov qword ptr [rsp + 0x20], rdi
7FF6A713D01F [1]: 55 push rbp

Trampoline:
7FF6A5F00000: 48 89 5C 24 10 mov qword ptr [rsp + 0x10], rbx
7FF6A5F00005: 48 89 74 24 18 mov qword ptr [rsp + 0x18], rsi
7FF6A5F0000A: 48 89 7C 24 20 mov qword ptr [rsp + 0x20], rdi
7FF6A5F0000F: 55 push rbp
7FF6A5F00010: 50 push rax
7FF6A5F00011: 48 B8 20 D0 13 A7 F6 7F 00 00 movabs rax, 0x7ff6a713d020
7FF6A5F0001B: 48 87 04 24 xchg qword ptr [rsp], rax
7FF6A5F0001F: C3 ret

Fixed Trampoline
7FF6A5F00000: 48 89 5C 24 10 mov qword ptr [rsp + 0x10], rbx
7FF6A5F00005: 48 89 74 24 18 mov qword ptr [rsp + 0x18], rsi
7FF6A5F0000A: 48 89 7C 24 20 mov qword ptr [rsp + 0x20], rdi
7FF6A5F0000F: 55 push rbp
7FF6A5F00010: 50 push rax
7FF6A5F00011: 48 B8 20 D0 13 A7 F6 7F 00 00 movabs rax, 0x7ff6a713d020
7FF6A5F0001B: 48 87 04 24 xchg qword ptr [rsp], rax
7FF6A5F0001F: C3 ret
Posted Error [SEVERITY:0]:
PolyHook x64Detour: Relocation can be out of range

Additionally, when I try including "PolyHook.hpp" in more than one file, I get linking errors (something with 'already defined'). This also happens when I put the include in my Includes.h or stdafx.h file.

DLL for C# pinvoke usage

Would be good to have a DLL to be able to pinvoke it from c# or better a nuget with a c# wrapper in place

Cannot build on Visual Studio 2017

Your modified capstone build was compiled with an older version of the compiler.

The error is:

Error C1047: The object or library file 'capstone.lib' was created with an older compiler than other objects; rebuild old objects and libraries

Do you perhaps have the source files for this capstone version that Polyhook is using? The latest versions of capstone are not compatible with your library so this is pretty much unusable right now.

I should clarify that this only happens on Release mode. Debug compiles fine.

Question about WSA hooking using IAT

I am trying to hook recv() or send() on ws_s32.dll using IAT method, although the hook succeeds, the function is not being called...

typedef int(*WINAPI oldrecv)(SOCKET s, const char* buf, int len, int flags);
oldrecv oGetOriginalRecv;

DWORD __stdcall MyRecv2(SOCKET s, char* buf, int len, int flags)
{
	return oGetOriginalRecv(s, buf, len, flags);
}
std::shared_ptr<PLH::IATHook> IATHook_Ex(new PLH::IATHook);

 IATHook_Ex->SetupHook("ws2_32.dll", "recv", (BYTE*)&MyRecv2);
 IATHook_Ex->Hook();
	
 oGetOriginalRecv = IATHook_Ex->GetOriginal<oldrecv>();

Is the hook being made in the wrong way ? Or is there a bug somewhere ?

Any help is much appreciated :)

Relocation can go out of bounds

if code is relocated greater than the max displacement size of the operand then relocation will fail, this case is currently not handled. Ex: if relocation is >2GB 32bit instructions may fail, attempts are made to prevent this case but it is a possibility.

Hook CreateProcess in child process

Hi, is it possible to hook CreateProcess in child process I created with CreateProcess? I want to detect if my child process are spawning other processes

how to make this work for VS2013?

auto GetProtectionObject() { //Return an object to restore INT3_BP after callback is done return finally([&]() {

'auto' gives error

Member function hook

Sorry maybe for the stupid question.
Is it possible to hook not virtual member function using PolyHook?
If this is possible there is no example in Tests.cpp

IAT Hooking doesn't work

iat_hook_createmutex->SetupHook("kernel32.dll", "CreateMutexA", (BYTE*)&HkCreateMutex, "Game.exe");
if (!iat_hook_createmutex->Hook())
{
    auto error = iat_hook_createmutex->GetLastError();
    iat_hook_createmutex->PostError(error);
}

Console output:

Import By Name: [Ordinal:34156] [Name:gluOrtho2D]
Posted Error [SEVERITY:2]:
PolyHook IATHook:Failed to find import
Posted Error [SEVERITY:2]:
PolyHook IATHook: Failed to find import
Posted Error [SEVERITY:2]:
PolyHook IATHook: Failed to find import
Import By Name: [Ordinal:34156] [Name:gluOrtho2D]
Posted Error [SEVERITY:2]:
PolyHook IATHook:Failed to find import

Example of hook variadic function.

Hi,

I am wondering how to hook variadic function. For example int printf(char const* const format, ...) in the standard library or VALUE rb_funcall(VALUE, ID, int, ...) in the ruby c api.
There is no such examples in the test.
Is it even possible to do this?

Thanks,
Han

How to use vmt hook?

Hi. How to use vmt hook? I have a pDevice (DirectX) address, how can I get present?

PAGE_GUARD implementation is incomplete

Because of the 0x1000 minimal page size the PAGE_GUARD flag will silently fall off if anything near the hook gets touched and the lib doesn't do anything to stop it.

One way around it is if the RIP doesn't match our hooked function set the single step trap(via eflags), and restore PAGE_GUARD later inside EXCEPTION_SINGLE_STEP.

Also it would be wise to reuse existing page read/write flags instead of making hooked page writable for no reason.

VFuncSwap doesn't work on x64?

So am trying to hook a Virtual method but its not work on 64 builds.
I get an exception when trying to delete the "delete shimTrackedDevice;"
Also the "thisptr" is invalid
My system is Win10 x64, Visual Studio 2017.

referencing: https://www.codeproject.com/articles/1100579/polyhook-the-cplusplus-x-x-hooking-library

// ----------------------------------------------------------
// hooks
// ----------------------------------------------------------
void** trackedDeviceVTable = nullptr;
constexpr int trackedDeviceVTableIndex_GetPose_Index = 5;
typedef DriverPose_t(__thiscall *GetPose_Org)(ITrackedDeviceServerDriver* thisptr);
GetPose_Org GetPose_Ptr = nullptr;

float x = 0;
ITrackedDeviceServerDriver* thisptr__ = nullptr;
static DriverPose_t __fastcall GetPose_Hook(ITrackedDeviceServerDriver* thisptr)//, int edx)
{
	if (thisptr__ == thisptr) cout << "Valid This Ptr!!!" << endl;
	else cout << "Invalid This Ptr!!!" << endl;
	return GetPose_Ptr(thisptr);
}

PLH::VFuncSwap* VFuncSwap_Ex = new PLH::VFuncSwap;
void HookDriver(ITrackedDeviceServerDriver* driver, bool usePolyHook)
{
	thisptr__ = driver;

	if (usePolyHook)
	{
		VFuncSwap_Ex->SetupHook(*(BYTE***)driver, trackedDeviceVTableIndex_GetPose_Index, (BYTE*)&GetPose_Hook);
		VFuncSwap_Ex->Hook();
		GetPose_Ptr = VFuncSwap_Ex->GetOriginal<GetPose_Org>();
	}
	else
	{
		trackedDeviceVTable = *(void***)(driver);
		#ifdef _32BIT
		MEMORY_BASIC_INFORMATION32 trackedDeviceMBI;
		VirtualQuery((LPCVOID)trackedDeviceVTable, (PMEMORY_BASIC_INFORMATION)&trackedDeviceMBI, sizeof(MEMORY_BASIC_INFORMATION32));
		#else
		MEMORY_BASIC_INFORMATION64 trackedDeviceMBI;
		VirtualQuery((LPCVOID)trackedDeviceVTable, (PMEMORY_BASIC_INFORMATION)&trackedDeviceMBI, sizeof(MEMORY_BASIC_INFORMATION64));
		#endif
		VirtualProtect((LPVOID)trackedDeviceMBI.BaseAddress, trackedDeviceMBI.RegionSize, PAGE_EXECUTE_READWRITE, &trackedDeviceMBI.Protect);// unlock
		GetPose_Ptr = (GetPose_Org)trackedDeviceVTable[trackedDeviceVTableIndex_GetPose_Index];
		trackedDeviceVTable[trackedDeviceVTableIndex_GetPose_Index] = &GetPose_Hook;// Hook!
		VirtualProtect((LPVOID)trackedDeviceMBI.BaseAddress, trackedDeviceMBI.RegionSize, trackedDeviceMBI.Protect, &trackedDeviceMBI.Protect);// lock
	}
}

static ShimTrackedDevice* shimTrackedDevice = new ShimTrackedDevice();
int main()
{
	cout << "Call before hook..." << endl;
	auto result = shimTrackedDevice->GetPose();

	cout << "Hooking..." << endl;
	HookDriver(shimTrackedDevice, true);

	cout << "Calling Hooked..." << endl;
	result = shimTrackedDevice->GetPose();

	cout << "Deleting..." << endl;
	delete shimTrackedDevice;
	shimTrackedDevice = nullptr;

	cout << "Finished!" << endl;
    return 0;
}

Runtime error

I'm getting a post error:
PolyHook x64Detour: Relocation can be out of range

unsure what would cause this or what it means, could you please clarify?
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.