Tengo un problema con las desviaciones. Los desvíos, como todos saben, solo pueden moverse entre 5 bytes de espacio (es decir, una llamada 'jmp' y una dirección de 4 bytes). Debido a esto, es imposible tener la función 'gancho' en una clase (un método), no puede suministrar el puntero 'esto' porque simplemente no hay suficiente espacio (here's el problema más explicado). Así que he estado buscando ideas todo el día para encontrar una solución, y ahora quiero sus pensamientos sobre el tema, así que no empiezo un proyecto de 3 a 5 días sin saber si sería posible o no.Funciones dinámicas C++ y TOTALMENTE
Tenía inicialmente 3 objetivos, quería que las funciones de 'gancho' fueran métodos de clase, quería que todo el enfoque estuviera orientado a objetos (sin funciones estáticas u objetos globales) y, la parte peor/más difícil, ser completamente dinámico. Esta es mi solución (en teoría); con el ensamblaje uno puede modificar funciones en tiempo de ejecución (un ejemplo perfecto es cualquier método de desvío). Entonces, como puedo modificar las funciones de forma dinámica, ¿no debería ser capaz de crearlas dinámicamente? Por ejemplo; Asigno memoria para, digamos ~ 30 bytes (a través de malloc/nuevo). ¿No sería posible simplemente reemplazar todos los bytes con números binarios correspondientes a diferentes operadores de ensamblaje (como 0xE9 es 'jmp') y luego llamar directamente a la dirección (ya que contendría una función)?
NOTA: Sé de antemano el valor de retorno, y todos los argumentos para todas las funciones que quiero desviar, y como estoy usando GCC, la convención thiscall es prácticamente idéntica a la de _cdecl.
Así que esta es mi idea/próxima implementación; Creo una clase 'Función'. Este constructor toma una cantidad variada de argumentos (excepto el primer argumento, que describe el valor de retorno de la función objetivo).
Cada argumento es una descripción de los argumentos que el gancho recibirá (el tamaño, y si es un puntero o no). Entonces digamos que quiero crear una clase de Función para un int * RandomClass::IntCheckNum(short arg1);
. Entonces solo tendría que hacer esto: Function func(Type(4, true), Type(4, true), Type(2, false));
. Donde 'Tipo' se define como Type(uint size, bool pointer)
. Luego, a través del ensamblaje pude crear dinámicamente la función (nota: esto sería todo usando la convención de llamadas _cdecl) ya que puedo calcular el número de argumentos y el tamaño total.
EDIT: Con el ejemplo, Type(4, true)
es el valor de retorno (int *), el scond Type(4, true)
es el RandomClass este puntero y Type(2, false)
describe el primer argumento (corto arg1).
Con esta implementación podría tener fácilmente métodos de clase como devoluciones de llamada, pero requeriría una gran cantidad de código de ensamblado (que ni siquiera tengo experiencia). Al final, la única cosa no dinámica serían los métodos en mi clase de devolución de llamada (que también requeriría devoluciones de llamada previas y posteriores).
Así que quería saber; ¿es posible? ¿Cuánto trabajo requeriría, y estoy por encima de mi cabeza aquí?
EDIT: Perdón si presenté todo un poco borroso, pero si hay algo que quieras explicar con más detalle, ¡pregunta!
EDIT2: ¿Me gustaría saber si puedo encontrar los valores hexadecimales para todos los operadores de ensamblaje en alguna parte? ¡Una lista ayudaría muchísimo! Y/o si es posible de alguna manera 'guardar' el asm (""); código en una dirección de memoria (que dudo mucho).
¿Por qué usar desvíos en absoluto? ¿No puedes usar una solución pura de C++ como 'std :: function' o me falta algo? –
No como si pudiera ayudarte solo para aclarar las cosas. ¿Desea una función regrabable en una clase? (Es decir, puede cambiarlos en tiempo de ejecución) Si es así, creo que (cuando termine) podría abrir oportunidades gigantes para la programación de IA en C++. +1 – akaltar
@akaltar Esto se conoce como [programación genética] (http://en.wikipedia.org/wiki/Genetic_programming) y en realidad no necesita funciones regrabables. –