Ce n'est pas une fonction particulière de EasyHook mais de l'accrochage en général. Je veux accrocher une fonction avec cette signature:Accroissement de fonction non géré, problème de pile/enregistrement avec convention d'appel?
public: int __thiscall Connection_t::Send(unsigned int,unsigned int,void const *)
Ceci est clairement le code non managé et je suis en train de le brancher avec mon code managé C# en utilisant EasyHook.But Je pense que ça EasyHook ne pas causer de problèmes ici, mais mon knowlegde sur les conventions d'appel etc ...
Voilà comment je définis DllImport et supprimer:
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);
Mais le programm accroché continue à s'écraser dès que j'Injecter le crochet - pas une grande surprise. Je suppose que c'est un problème de la convention d'appel et que ma fonction d'accrochage interfère d'une manière ou d'une autre avec la pile du programme accroché.
J'ai regardé un autre projet qui ne crochet la même fonction, mais avec des détours en C++ (la partie d'accrochage):
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();
Et la fonction appelée:
__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];
}
}
(cible assembly et l'exemple C++ sont tous deux compilés avec visual C++). Je suppose que je vais devoir enregistrer des registres et réparer la pile avant d'appeler la fonction d'origine? Ou toute autre idée de ce que je fais mal ici?
passant: Merci. Voyant EXC comme le premier argument était la solution :) – Fge