Add a stack-frame hooking class

This commit is contained in:
momo5502 2016-04-08 16:15:01 +02:00
parent b912eb618b
commit 19b6a12c92
3 changed files with 77 additions and 1 deletions

2
deps/protobuf vendored

@ -1 +1 @@
Subproject commit 452e2b2c5c607ab5d63cd813793f1aa960f19d1c Subproject commit 667f4a6282f9d7e7edb0acc8758e384b17a0359d

View File

@ -2,6 +2,67 @@
namespace Utils 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() Hook::~Hook()
{ {
if (Hook::Initialized) if (Hook::Initialized)

View File

@ -8,6 +8,21 @@ namespace Utils
class Hook class Hook
{ {
public: 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() : 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); } Hook(void* place, void* stub, bool useJump = true) : Hook() { Hook::Initialize(place, stub, useJump); }