這不是關於EasyHook的特殊功能,而是關於通用鉤子的特殊功能。我要掛鉤函數與此簽名:非託管函數掛鉤,堆棧/註冊調用約定的問題?
public: int __thiscall Connection_t::Send(unsigned int,unsigned int,void const *)
這顯然是託管代碼,我想用我的EasyHook.But託管的C#代碼,把它掛,我認爲它不是EasyHook這裏造成的問題,但我knowlegde在調用約定等...
我這是怎麼定義的DllImport和刪除:
public static int Send_Hooked(uint connection, uint size, IntPtr pDataBlock)
{
return Send(connection, size, pDataBlock);
}
[DllImport("Connection.dll", EntryPoint = "[email protected][email protected]@[email protected]", CallingConvention = CallingConvention.ThisCall)]
static extern int Send(uint connection, uint size, IntPtr pDataBlock);
[UnmanagedFunctionPointer(CallingConvention.ThisCall, CharSet = CharSet.Unicode, SetLastError = true)]
delegate int DSend(uint connection, uint size, IntPtr pDataBlock);
但迷上PROGRAMM不斷,只要我注入鉤崩潰 - 沒有什麼大的驚喜。我認爲這是調用約定的問題,並且我的掛鉤函數以某種方式干擾了所掛鉤的程序堆棧。
所以我不得不來看看另一個項目誰做勾相同的功能,但在C彎路++(掛鉤部):
Func = (int (__stdcall *)(unsigned int, unsigned short, void const))::GetProcAddress(::GetModuleHandle("Connection.dll"), "[email protected][email protected]@[email protected]");
PVOID DetourPtr;
PVOID TargetPtr;
DetourTransactionBegin();
DetourAttachEx(&Func, SendConnectionHook, &Trampoline, &TargetPtr, &DetourPtr);
DetourTransactionCommit();
和被調用函數:
__declspec(naked) void SendConnectionHook (CPU_CONTEXT saved_regs, void * ret_addr, WORD arg1, DWORD arg2, DWORD arg3)
{
DWORD edi_value;
DWORD old_last_error;
__asm
{
pushad; /* first "argument", which is also used to store registers */
push ecx; /* padding so that ebp+8 refers to the first "argument" */
/* set up standard prologue */
push ebp;
mov ebp, esp;
sub esp, __LOCAL_SIZE;
}
edi_value = saved_regs.edi;
old_last_error = GetLastError();
OnConnectionSend((void *) saved_regs.ecx, (unsigned char *) arg3, arg2);
SetLastError(old_last_error);
__asm
{
/* standard epilogue */
mov esp, ebp;
pop ebp;
pop ecx; /* clear padding */
popad; /* clear first "argument" */
jmp [Trampoline];
}
}
(目標彙編和C++的例子都是用visual C++編譯的)。我想在調用原始函數之前,我必須保存一些寄存器並修復堆棧?或者其他任何想法我在這裏做錯了嗎?
傳承者:謝謝。看到EXC作爲第一個參數是解決方案:) – Fge 2010-12-04 23:15:17