From 8221a6522b7dc5f58f56239f4180634538c4c4e9 Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Tue, 13 Dec 2016 17:47:59 -0700 Subject: [PATCH] Save this pointer on windows after calling original function ecx might get cleared before the original function returns leading to garbage in the post handler. --- DynamicHooks/convention.h | 3 +++ DynamicHooks/conventions/x86MsThiscall.cpp | 12 ++++++++++++ DynamicHooks/conventions/x86MsThiscall.h | 4 ++++ DynamicHooks/hook.cpp | 4 ++++ 4 files changed, 23 insertions(+) diff --git a/DynamicHooks/convention.h b/DynamicHooks/convention.h index 6157a1c..16adcc7 100644 --- a/DynamicHooks/convention.h +++ b/DynamicHooks/convention.h @@ -225,6 +225,9 @@ public: ReturnPtrChanged(pRegisters, m_pSavedReturnBuffer); } + virtual void SavePostCallRegisters(CRegisters* pRegisters) {} + virtual void RestorePostCallRegisters(CRegisters* pRegisters) {} + public: ke::Vector m_vecArgTypes; DataTypeSized_t m_returnType; diff --git a/DynamicHooks/conventions/x86MsThiscall.cpp b/DynamicHooks/conventions/x86MsThiscall.cpp index 4ea6386..56aced7 100644 --- a/DynamicHooks/conventions/x86MsThiscall.cpp +++ b/DynamicHooks/conventions/x86MsThiscall.cpp @@ -49,6 +49,7 @@ x86MsThiscall::x86MsThiscall(ke::Vector &vecArgTypes, DataTypeS { m_pReturnBuffer = NULL; } + m_pSavedThisPointer = malloc(sizeof(size_t)); } x86MsThiscall::~x86MsThiscall() @@ -57,6 +58,7 @@ x86MsThiscall::~x86MsThiscall() { free(m_pReturnBuffer); } + free(m_pSavedThisPointer); } ke::Vector x86MsThiscall::GetRegisters() @@ -159,3 +161,13 @@ void x86MsThiscall::ReturnPtrChanged(CRegisters* pRegisters, void* pReturnPtr) memcpy(pRegisters->m_edx, (void *) ((unsigned long) m_pReturnBuffer + 4), 4); } } + +void x86MsThiscall::SavePostCallRegisters(CRegisters* pRegisters) +{ + memcpy(m_pSavedThisPointer, GetArgumentPtr(0, pRegisters), sizeof(size_t)); +} + +void x86MsThiscall::RestorePostCallRegisters(CRegisters* pRegisters) +{ + memcpy(GetArgumentPtr(0, pRegisters), m_pSavedThisPointer, sizeof(size_t)); +} \ No newline at end of file diff --git a/DynamicHooks/conventions/x86MsThiscall.h b/DynamicHooks/conventions/x86MsThiscall.h index e809c92..167abd1 100644 --- a/DynamicHooks/conventions/x86MsThiscall.h +++ b/DynamicHooks/conventions/x86MsThiscall.h @@ -78,8 +78,12 @@ public: virtual void* GetReturnPtr(CRegisters* pRegisters); virtual void ReturnPtrChanged(CRegisters* pRegisters, void* pReturnPtr); + virtual void SavePostCallRegisters(CRegisters* pRegisters); + virtual void RestorePostCallRegisters(CRegisters* pRegisters); + private: void* m_pReturnBuffer; + void* m_pSavedThisPointer; }; #endif // _X86_MS_THISCALL_H \ No newline at end of file diff --git a/DynamicHooks/hook.cpp b/DynamicHooks/hook.cpp index af4cefe..8d96d21 100644 --- a/DynamicHooks/hook.cpp +++ b/DynamicHooks/hook.cpp @@ -157,6 +157,8 @@ ReturnAction_t CHook::HookHandler(HookType_t eHookType) { if (m_LastPreReturnAction == ReturnAction_Override) m_pCallingConvention->RestoreReturnValue(m_pRegisters); + if (m_LastPreReturnAction < ReturnAction_Supercede) + m_pCallingConvention->RestorePostCallRegisters(m_pRegisters); } ReturnAction_t returnAction = ReturnAction_Ignored; @@ -177,6 +179,8 @@ ReturnAction_t CHook::HookHandler(HookType_t eHookType) m_LastPreReturnAction = returnAction; if (returnAction == ReturnAction_Override) m_pCallingConvention->SaveReturnValue(m_pRegisters); + if (returnAction < ReturnAction_Supercede) + m_pCallingConvention->SavePostCallRegisters(m_pRegisters); } return returnAction;