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.
This commit is contained in:
parent
b18e3284e1
commit
8221a6522b
@ -225,6 +225,9 @@ public:
|
|||||||
ReturnPtrChanged(pRegisters, m_pSavedReturnBuffer);
|
ReturnPtrChanged(pRegisters, m_pSavedReturnBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void SavePostCallRegisters(CRegisters* pRegisters) {}
|
||||||
|
virtual void RestorePostCallRegisters(CRegisters* pRegisters) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ke::Vector<DataTypeSized_t> m_vecArgTypes;
|
ke::Vector<DataTypeSized_t> m_vecArgTypes;
|
||||||
DataTypeSized_t m_returnType;
|
DataTypeSized_t m_returnType;
|
||||||
|
@ -49,6 +49,7 @@ x86MsThiscall::x86MsThiscall(ke::Vector<DataTypeSized_t> &vecArgTypes, DataTypeS
|
|||||||
{
|
{
|
||||||
m_pReturnBuffer = NULL;
|
m_pReturnBuffer = NULL;
|
||||||
}
|
}
|
||||||
|
m_pSavedThisPointer = malloc(sizeof(size_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
x86MsThiscall::~x86MsThiscall()
|
x86MsThiscall::~x86MsThiscall()
|
||||||
@ -57,6 +58,7 @@ x86MsThiscall::~x86MsThiscall()
|
|||||||
{
|
{
|
||||||
free(m_pReturnBuffer);
|
free(m_pReturnBuffer);
|
||||||
}
|
}
|
||||||
|
free(m_pSavedThisPointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
ke::Vector<Register_t> x86MsThiscall::GetRegisters()
|
ke::Vector<Register_t> x86MsThiscall::GetRegisters()
|
||||||
@ -159,3 +161,13 @@ void x86MsThiscall::ReturnPtrChanged(CRegisters* pRegisters, void* pReturnPtr)
|
|||||||
memcpy(pRegisters->m_edx, (void *) ((unsigned long) m_pReturnBuffer + 4), 4);
|
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));
|
||||||
|
}
|
@ -78,8 +78,12 @@ public:
|
|||||||
virtual void* GetReturnPtr(CRegisters* pRegisters);
|
virtual void* GetReturnPtr(CRegisters* pRegisters);
|
||||||
virtual void ReturnPtrChanged(CRegisters* pRegisters, void* pReturnPtr);
|
virtual void ReturnPtrChanged(CRegisters* pRegisters, void* pReturnPtr);
|
||||||
|
|
||||||
|
virtual void SavePostCallRegisters(CRegisters* pRegisters);
|
||||||
|
virtual void RestorePostCallRegisters(CRegisters* pRegisters);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void* m_pReturnBuffer;
|
void* m_pReturnBuffer;
|
||||||
|
void* m_pSavedThisPointer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _X86_MS_THISCALL_H
|
#endif // _X86_MS_THISCALL_H
|
@ -157,6 +157,8 @@ ReturnAction_t CHook::HookHandler(HookType_t eHookType)
|
|||||||
{
|
{
|
||||||
if (m_LastPreReturnAction == ReturnAction_Override)
|
if (m_LastPreReturnAction == ReturnAction_Override)
|
||||||
m_pCallingConvention->RestoreReturnValue(m_pRegisters);
|
m_pCallingConvention->RestoreReturnValue(m_pRegisters);
|
||||||
|
if (m_LastPreReturnAction < ReturnAction_Supercede)
|
||||||
|
m_pCallingConvention->RestorePostCallRegisters(m_pRegisters);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnAction_t returnAction = ReturnAction_Ignored;
|
ReturnAction_t returnAction = ReturnAction_Ignored;
|
||||||
@ -177,6 +179,8 @@ ReturnAction_t CHook::HookHandler(HookType_t eHookType)
|
|||||||
m_LastPreReturnAction = returnAction;
|
m_LastPreReturnAction = returnAction;
|
||||||
if (returnAction == ReturnAction_Override)
|
if (returnAction == ReturnAction_Override)
|
||||||
m_pCallingConvention->SaveReturnValue(m_pRegisters);
|
m_pCallingConvention->SaveReturnValue(m_pRegisters);
|
||||||
|
if (returnAction < ReturnAction_Supercede)
|
||||||
|
m_pCallingConvention->SavePostCallRegisters(m_pRegisters);
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnAction;
|
return returnAction;
|
||||||
|
Loading…
Reference in New Issue
Block a user