Хотя это решение не использует метод переполнения для перезаписи адреса возврата функции в стеке, оно все равно заставляет g()
вызываться из f()
при его возвращении в main()
только путем изменения f()
и не звонить g()
напрямую.
Функция эпилога -подобная встроенная сборка добавлена к f()
для изменения значения адреса возврата в стеке, так что f()
вернется через g()
.
#include <stdio.h>
void g()
{
printf("now inside g()!\n");
}
void f()
{
printf("now inside f()!\n");
// can only modify this section
// cant call g(), maybe use g (pointer to function)
/* x86 function epilogue-like inline assembly */
/* Causes f() to return to g() on its way back to main() */
asm(
"mov %%ebp,%%esp;"
"pop %%ebp;"
"push %0;"
"ret"
: /* no output registers */
: "r" (&g)
: "%ebp", "%esp"
);
}
int main (int argc, char *argv[])
{
f();
return 0;
}
Понимание того, как работает этот код, может привести к лучшему пониманию того, как настраивается фрейм стека функции для конкретной архитектуры, которая лежит в основе методов переполнения буфера.