Actualización : parece que esperas más información concreta, así que amplié un poco mi publicación. Por lo que sé, sin embargo, ningún código, aparte del programa real, las bibliotecas y el código del kernel, generalmente se asigna a la memoria cuando su programa se ejecuta en modo de usuario.
Hay varios lugares a los que podría redireccionar el flujo de control, en caso de que la pila no sea ejecutable:
-
ret2data : coloque el código de explotación en la sección de datos y luego apunte la dirección de retorno allí. A menudo no es posible.
-
ret2text : salte al código existente en la sección
.text
del binario explotado. Esto incluye saltar a DLL y otras bibliotecas compartidas (y, en teoría, incluso el código del kernel, sin un cambio de modo).
-
devoluciones en cadena : una técnica que se puede utilizar para combinar varios métodos. Básicamente, prepara la pila para que la instrucción de retorno de la primera función salte a la segunda función, y así sucesivamente.
-
devoluciones parciales : Otra técnica. No tienes que saltar al principio de una función, sino que también puedes saltar en el medio o cerca del final.
-
ret2syscall : un ejemplo práctico de lo que puedes hacer. Básicamente, tiene una instrucción
int 0x80
(una llamada al sistema Linux que espera sus argumentos en los registros) y cualquier función que limpia la pila, por ejemplo, pop eax; pop ecx; pop edx; pop ebx; ret;
Llena la pila con la dirección de la instrucción pop eax
, luego los valores de los registros y luego la dirección del syscall.