Add a stack-frame hooking class
This commit is contained in:
parent
b912eb618b
commit
19b6a12c92
2
deps/protobuf
vendored
2
deps/protobuf
vendored
@ -1 +1 @@
|
||||
Subproject commit 452e2b2c5c607ab5d63cd813793f1aa960f19d1c
|
||||
Subproject commit 667f4a6282f9d7e7edb0acc8758e384b17a0359d
|
@ -2,6 +2,67 @@
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
std::map<void*, void*> Hook::Interceptor::IReturn;
|
||||
std::map<void*, void(*)()> Hook::Interceptor::ICallbacks;
|
||||
|
||||
void Hook::Interceptor::Install(void* place, void(*stub)())
|
||||
{
|
||||
return Hook::Interceptor::Install(reinterpret_cast<void**>(place), stub);
|
||||
}
|
||||
|
||||
void Hook::Interceptor::Install(void** place, void(*stub)())
|
||||
{
|
||||
Hook::Interceptor::IReturn[place] = *place;
|
||||
Hook::Interceptor::ICallbacks[place] = stub;
|
||||
*place = Hook::Interceptor::InterceptionStub;
|
||||
}
|
||||
|
||||
void __declspec(naked) Hook::Interceptor::InterceptionStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
sub esp, 4h // Reserve space on the stack for the return address
|
||||
pushad // Store registers
|
||||
|
||||
lea eax, [esp + 20h] // Load initial stack pointer
|
||||
push eax // Push it onto the stack
|
||||
|
||||
call RunCallback // Run the callback based on the given stack pointer
|
||||
call PopReturn // Get the initial return address according to the stack pointer
|
||||
|
||||
add esp, 4h // Clear the stack
|
||||
|
||||
mov [esp + 20h], eax // Store the return address at the reserves space
|
||||
popad // Restore the registers
|
||||
|
||||
retn // Return (jump to our return address)
|
||||
}
|
||||
}
|
||||
|
||||
void Hook::Interceptor::RunCallback(void* place)
|
||||
{
|
||||
auto iCallback = Hook::Interceptor::ICallbacks.find(place);
|
||||
if (iCallback != Hook::Interceptor::ICallbacks.end())
|
||||
{
|
||||
iCallback->second();
|
||||
Hook::Interceptor::ICallbacks.erase(iCallback);
|
||||
}
|
||||
}
|
||||
|
||||
void* Hook::Interceptor::PopReturn(void* place)
|
||||
{
|
||||
void* retVal = nullptr;
|
||||
|
||||
auto iReturn = Hook::Interceptor::IReturn.find(place);
|
||||
if (iReturn != Hook::Interceptor::IReturn.end())
|
||||
{
|
||||
retVal = iReturn->second;
|
||||
Hook::Interceptor::IReturn.erase(iReturn);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
Hook::~Hook()
|
||||
{
|
||||
if (Hook::Initialized)
|
||||
|
@ -8,6 +8,21 @@ namespace Utils
|
||||
class Hook
|
||||
{
|
||||
public:
|
||||
class Interceptor
|
||||
{
|
||||
public:
|
||||
static void Install(void* place, void(*stub)());
|
||||
static void Install(void** place, void(*stub)());
|
||||
|
||||
private:
|
||||
static std::map<void*, void*> IReturn;
|
||||
static std::map<void*, void(*)()> ICallbacks;
|
||||
|
||||
static void InterceptionStub();
|
||||
static void RunCallback(void* place);
|
||||
static void* PopReturn(void* place);
|
||||
};
|
||||
|
||||
Hook() : Place(nullptr), Stub(nullptr), Initialized(false), Installed(false), Original(0), UseJump(false), Protection(0) { ZeroMemory(Hook::Buffer, sizeof(Hook::Buffer)); }
|
||||
|
||||
Hook(void* place, void* stub, bool useJump = true) : Hook() { Hook::Initialize(place, stub, useJump); }
|
||||
|
Loading…
Reference in New Issue
Block a user