これはEasyHookについての特定の機能ではなく、一般的なフックについての機能です。私はそれがEasyHookはここに問題を引き起こしていないと思う。これは明らかに、アンマネージコードであると私はEasyHook.Butを使用して、私のマネージC#のコードでそれをフックしようとしているアンマネージド関数のフック、呼び出し規約のスタック/レジスタの問題?
public: int __thiscall Connection_t::Send(unsigned int,unsigned int,void const *)
が、私のknowlegde:私はこのシグネチャを持つ関数をフックしたいです
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);
しかし、フックプログラムの開発は、すぐに私はフックを注入としてクラッシュしないを続けている - は大きな驚きを:
...規則などを呼び出すにこれは私がDLLIMPORTを定義し、削除する方法です。私はそれが呼び出し規約の問題であり、フック関数が何らかの形でフックされたプログラムのスタックに干渉していると思います。
だから私は(フック部分)++と同じ機能をフックが、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++でコンパイルされています)。元の関数を呼び出す前に、いくつかのレジスタを保存してスタックを修復する必要があると思いますか?または私がここで間違っている何か他のアイデア?
passant:ありがとう。最初の議論としてEXCを見ているのは解決策でした:) – Fge