¿Por qué hay 8 bytes entre el final de un búfer y el puntero de cuadro guardado?
Estoy haciendo un ejercicio de machacar pilas para el trabajo del curso, y ya he completado la tarea, pero hay un aspecto que no entiendo.
Aquí está el programa objetivo:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int bar(char *arg, char *out)
{
strcpy(out, arg);
return 0;
}
void foo(char *argv[])
{
char buf[256];
bar(argv[1], buf);
}
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "target1: argc != 2\n");
exit(EXIT_FAILURE);
}
foo(argv);
return 0;
}
Aquí están los comandos utilizados para compilarlo, en unx86
máquina virtual en funcionamientoUbuntu 12.04
, conASLR
discapacitado.
gcc -ggdb -m32 -g -std=c99 -D_GNU_SOURCE -fno-stack-protector -m32 target1.c -o target1
execstack -s target1
Cuando miro la memoria de este programa en la pila, veo quebuf
tiene la dirección0xbffffc40
. Además, el puntero de cuadro guardado se almacena en0xbffffd48
, y la dirección de devolución se almacena en0xbffffd4c
.
Estas direcciones específicas no son relevantes, pero observo que aunquebuf
solo tiene longitud256
, la distancia0xbffffd48 - 0xbffffc40 = 264
. Simbólicamente, este cálculo es$fp - buf
.
Por qué hay8
bytes adicionales entre el final debuf
y el puntero de marco almacenado en la pila?
Aquí hay un desmontaje de la función.foo
. Ya lo he examinado, pero no vi ningún uso obvio de esa región de memoria, a menos que fuera implícito (es decir, un efecto secundario de alguna instrucción).
0x080484ab <+0>: push %ebp
0x080484ac <+1>: mov %esp,%ebp
0x080484ae <+3>: sub $0x118,%esp
0x080484b4 <+9>: mov 0x8(%ebp),%eax
0x080484b7 <+12>: add $0x4,%eax
0x080484ba <+15>: mov (%eax),%eax
0x080484bc <+17>: lea -0x108(%ebp),%edx
0x080484c2 <+23>: mov %edx,0x4(%esp)
0x080484c6 <+27>: mov %eax,(%esp)
0x080484c9 <+30>: call 0x804848c <bar>
0x080484ce <+35>: leave
0x080484cf <+36>: ret