Desvío y uso de _thiscall como gancho (convención de llamadas GCC)

Recientemente he estado trabajando en funciones de desvío (solo en Linux) y hasta ahora he tenido un gran éxito. Estaba desarrollando mi propia clase de desvío hasta que encontré este. Modernicé un poco el código y lo convertí a C++ (como una clase, por supuesto). Ese código es como cualquier otra implementación de desvío, reemplaza la dirección de la función original con un JMP a mi propia función de 'gancho' especificada. También crea un 'trampolín' para la función original.

Todo funciona a la perfección, pero me gustaría hacer un ajuste simple. Programo en C++ puro, no uso funciones globales y todo está encerrado en clases (al igual que Java/C#). El problema es que este método de desvío rompe mi patrón. La función 'gancho' ser una función estática/no de clase.

Lo que quiero hacer es implementar soporte para _thiscall hooks (que debería ser bastante simple con el GCC _esta llamada convención). No he tenido éxito al modificar este código para que funcione con ganchos _thiscall. Lo que quiero como resultado final es algo tan simple como esto; PatchAddress(void * target, void * hook, void * class);. No le estoy pidiendo a nadie que haga esto por mí, pero me gustaría saber cómo resolver/abordar mi problema.

Por lo que sé, solo debería necesitar aumentar el tamaño del 'parche' (es decir, ahora son 5 bytes, ¿y debería requerir 5 bytes adicionales?), Y luego, antes de usar la llamada JMP (a mi función de enlace), yo empuje mi puntero 'esto' a la pila (que debería ser como si lo llamara como una función miembro). Para ilustrar:

push 'my class pointer'
jmp <my hook function>

En lugar de solo tener la llamada 'jmp' directamente/solo. ¿Es ese el enfoque correcto o hay algo más debajo que debe tenerse en cuenta (nota: no me importa el soporte para VC++ _thiscall)?

NOTA: aquí está mi implementación del código mencionado anteriormente: encabezamiento : fuente, usos libudis86

preguntado el 03 de mayo de 12 a las 18:05

Lo que usted llama "C++ puro" es discutible. Encerrar todo en clases no tiene sentido en C++. Pure C ++ usa módulos correctamente. -

@KonradRudolph Me recuerda el antiguo eslogan "C ++ para escribir mejor C", pero reemplace C por Java. :) Pero sí apruebo la pregunta (pl1) -

1 Respuestas

Probé varios métodos diferentes y entre estos estaba la compilación JIT (usando libre) que resultó exitoso pero el método no proporcionó suficiente rendimiento para que fuera utilizable. En cambio, me volví hacia libffi, que se utiliza para llamar funciones dinámicamente en tiempo de ejecución. los libffi biblioteca tenía una API de cierre (ffi_prep_closure_loc) que me permitió proporcionar mi puntero 'este' a cada cierre generado. Así que usé una función de devolución de llamada estática y convertí el void puntero a mi tipo de objeto y desde allí podría llamar a cualquier función no estática que desee.

Respondido el 26 de junio de 12 a las 22:06

Excelente, solo traté de automatizar la generación de 70 ganchos (enganché la función de registro de devolución de llamada) usando cierres lambda, pero me dijeron que no funcionaría. Mi siguiente paso también fue libjit, pero veré si su solución puede ayudarme. No usamos clases para nuestros ganchos, pero usamos un espacio de nombres para mantenerlo semi-organizado, la idea de tener ganchos como clases es una locura absoluta (es lo que hubiera dicho si no lo hubieras hecho funcionar) . - orwellófilo

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.