Páginas: [1] 2
|
 |
|
Autor
|
Tema: duda al seguir texto "Smashing The Stack For Fun And Profit" (Leído 1062 veces)
|
cualqueircosa
Desconectado
Mensajes: 6
|
saludos a todos, escribo esto porque estoy siguiendo el tuto: "Smashing The Stack For Fun And Profit" el problema es en el siguiente codigo:
example1.c: ------------------------------------------------------------------------------ void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; }
void main() { function(1,2,3); }
se el codigo que esta abajo, lo compilo "gcc -S example1.c -o example1.s" y miro el example1.s y veo un "sub $0x16,%esp" y no un "subl $20,%esp" en function, y supongo que es porque cada palabra(word) es de 2 bytes y no 4 como dice el texto, porque serian 6 bytes es decir 3 palabras para buffer1 y 5 palabras para buffer2, es decir un total de 16 bytes.
que alguien me corrija si estoy mal hasta este momento.
continuo:
asi que el problema mayor lo tengo con el siguiente codigo:
example3.c: ------------------------------------------------------------------------------ void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; int *ret;
ret = buffer1 + 12; (*ret) += 8; }
void main() { int x;
x = 0; function(1,2,3); x = 1; printf("%d\n",x); } ------------------------------------------------------------------------------
en la intruccion "ret=buffer1+12" se supone que se esta asignando la direccion de retorno a ret, 4 bytes por el sfp, y 8 por el tamaño del buffer1 suponiendo que cada palabra tiene 4 bytes, pero como tiene 2 deberia ser "ret=buffer1+10" 4 por el sfp y 6 del buffer1.
si no entendi mal la idea del anterior codigo es saltarse la instruccion x=1 e ir directamente al printf y asi obtener un "0" y no un "1", listo asi que se le suma 8 a la direccion de retorno dado que usando el gdb se obtiene:
[aleph1]$ gdb example3 GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details. GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc... (no debugging symbols found)... (gdb) disassemble main Dump of assembler code for function main: 0x8000490 : pushl %ebp 0x8000491 : movl %esp,%ebp 0x8000493 : subl $0x4,%esp 0x8000496 : movl $0x0,0xfffffffc(%ebp) 0x800049d : pushl $0x3 0x800049f : pushl $0x2 0x80004a1 : pushl $0x1 0x80004a3 : call 0x8000470 0x80004a8 : addl $0xc,%esp 0x80004ab : movl $0x1,0xfffffffc(%ebp) 0x80004b2 : movl 0xfffffffc(%ebp),%eax 0x80004b5 : pushl %eax 0x80004b6 : pushl $0x80004f8 0x80004bb : call 0x8000378 0x80004c0 : addl $0x8,%esp 0x80004c3 : movl %ebp,%esp 0x80004c5 : popl %ebp 0x80004c6 : ret 0x80004c7 : nop ------------------------------------------------------------------------------ se quiere saltar la instruccion 0x80004ab que pone la variable x=1, asi que se quiere ir a 0x80004b2. esto no se como interpretarlo pero segun el texto solo seria sumarle la distancia entre 0x80004b2 y 0x80004ab y personalmente obtengo A y no 8, no se si estoy interpretando algo mal o que, por favor alguien entonces me diga en que me estoy equivocando???
y otra cosa mas jejejeje, yo no obtengo el mismo codigo pero cuando desensamblo el main (supongo que es por las versiones del gcc y gdb) obtengo un codigo diferente es por eso o me equivoco??
estaria muy agradecido si alguien me ayudara.
|
|
|
|
« Última modificación: 06 Enero 2008, 05:02 por cualqueircosa »
|
En línea
|
|
|
|
zhynar_X
Desconectado
Mensajes: 516
Use linux my friend...
|
miro el example1.s y veo un "sub $0x16,%esp" y no un "sub $0x20,%esp" en function, y supongo que es porque cada palabra(word) es de 2 bytes y no 4 como dice el texto, porque serian 6 bytes es decir 3 palabras para buffer1 y 5 palabras para buffer2, es decir un total de 16 bytes.
Por lo que tengo entendido te equibocas. 5 bytes (del buffer 1) + 10 (del buffer 2) suman 15 bytes y como se reserva de 4 en 4 se queda en 16 bytes. Y la segunda duda no se responder xD  Saludos 
|
|
|
|
|
En línea
|
Me he creado un blog: http://zhynar.blogspot.com Aver si os gusta!  Optimista es aquel que cree poder resolver un atasco de trafico tocando el claxon (Anonimo)
|
|
|
|
Ertai
|
Recuerda que tienes un puntero a entero (4bytes) y los buffers son de chars (1byte)
|
|
|
|
|
En línea
|
Si la felicidad se comprara, entonces el dinero sería noble. void rotar_by_ref(int& a, int& b) { /* Quien dijo que no se podia sin una variable temporal? */ *a = *a ^ *b; *b = *a ^ *b; *a = *a ^ *b; }
|
|
|
cualqueircosa
Desconectado
Mensajes: 6
|
el texto dice: "We must remember that memory can only be addressed in multiples of the word size. A word in our case is 4 bytes, or 32 bits. So our 5 byte buffer is really going to take 8 bytes (2 words) of memory, and our 10 byte buffer is going to take 12 bytes (3 words) of memory. That is why SP is being subtracted by 20...." 1- asi que se supone que un word es de 4 bytes, en general lo es porque segun tenia entendido es de 2 bytes??? 2- si es de 4 bytes y dado que la pila solo puede ser direccionada por multiplos de un word por que obtengo un "sub $0x16,%esp" y no un "subl $20,%esp" como se muestra en el texto??, como se puede ver hay un 0x es decir el 16 esta en hexadecimal y entonces seria un 22 (en decimal) es decir 22 bytes?? entonces el 20 estaria en decimal o me equivoco??. 3- zhynar_X no creo que los valores que se guardan en la pila se puedan mezclar asi no creo que sea valido simplemente sumar los 5 y 10 bytes y dado que se reservan de a 4 (si un word es de 4) finalmente se ocupen 16 bytes, me parece mas logico el procedimiento seguido en el texto en el cual se van guardando asi no se utilicen 2 words para 5 bytes (si el word es de 4 bytes) y asi sucesivamente, entonces porque obtengo el "sub $0x16,%esp"?????. 4- sigo sin entender de donde obtuvieron un 8 como resultado de la resta, la cual supongo es entre 0x80004b2 y 0x80004ab, me da un A y no un 8. 5- Ertai creo que lo que me dices lo he tenido en cuenta sin embargo no veo un problema con esto en este caso. gracias por las respuestas y agradeceria mucho cualquier ayuda porque estoy estancado.
|
|
|
|
« Última modificación: 06 Enero 2008, 05:17 por cualqueircosa »
|
En línea
|
|
|
|
zhynar_X
Desconectado
Mensajes: 516
Use linux my friend...
|
Diria que se mezclan los valores en la pila, haz la prueba: void main() {
char a[60]; // En la pila primero se almacena b y luego a char b[4];
strcpy(b,"AAAAAAAAAAAAAAAAAAAAAAAAAA"); // deberia haber un overflow pero no lo hay por que los datos que sobran de b continuan escribiendose en a.
printf("\nValor de b ---> %s",b); printf("\n\nValor de a ----> %s",a); // En a estaran los bytes que sobran de b
}
Saludos
|
|
|
|
« Última modificación: 06 Enero 2008, 12:59 por zhynar_X »
|
En línea
|
Me he creado un blog: http://zhynar.blogspot.com Aver si os gusta!  Optimista es aquel que cree poder resolver un atasco de trafico tocando el claxon (Anonimo)
|
|
|
vacio
Visitante
|
aunque no tengo mucha experiencia en el tema creo que en el caso de zhynar_X la pila estaria asi:
bottom of top of memory memory a b sfp ret *a *cadenadeAs <------ [ ] [ ] [ ] [ ] [ ] [ ] top of bottom of stack stack
entonces se escribira la cadena "AAAAAAAAAAAAA..." empezando en la direccion dada por *a, seguiría en la cadena b y como no se sobreescribe el ret (no hay suficientes As) no se obtiene la violacion de segmento.
en este caso no hay variables locales y a la pila no se pasan las As, solo los dos punteros a las cadenas (a y cadenadeAs) asi que de este ejemplo no se podria concluir que los datos se "mezclan" en la pila.
|
|
|
|
|
En línea
|
|
|
|
Anon
Desconectado
Mensajes: 294
Is True BSD is UNIX xD!!
|
Bueno, estuve haciendo una prueba, y la verdad si se ponen las variables continuas en la Pila, modifique el programa que puso zhynar_X, para demostrar que si se sobre escribe, y va en mi caso, de b[4], luego un int, (temp), y luego un a[60], el cual solo llenamos 18 bytes, los que estan despues de "ABCD", en la cadena que se copia int main() { char a[60]; // En la pila primero se almacena b, luego temp y luego a unsigned int temp = 0xaabbccdd; char b[4]; printf("Valor de temp = 0x%x\n",temp); strcpy(b,"AAAAABCD--------------AAAA"); // deberia haber un overflow pero no lo hay por que los datos que sobran de b continuan escribiendose en a. printf("Contenido de b -> %s\n",b); printf("Contenido de a -> %s\n",a); // En a estaran los bytes que sobran de b printf("Valor de temp = 0x%x\n",temp); return 0; } y lo ejecutamos: [luis@hackmeifyoucan ~]$ gcc -o duda duda.c -g -static [luis@hackmeifyoucan ~]$ ./duda Valor de temp = 0xaabbccdd Contenido de b -> AAAAABCD--------------AAAA Contenido de a -> --------------AAAA Valor de temp = 0x44434241 bottom of top of memory memory a b sfp ret *a *cadenadeAs <------ [ ] [ ] [ ] [ ] [ ] [ ] top of bottom of stack stack
en este caso no hay variables locales y a la pila no se pbasan las As, solo los dos punteros a las cadenas (a y cadenadeAs) asi que de este ejemplo no se podria concluir que los datos se "mezclan" en la pila.
En realidad quedaria asi... bottom of top of memory memory <------ [ char b[4] ][ unsigned int temp ][ char a[64] ][ sfp ][ ret ] top of bottom of stack stack [ entonces se escribira la cadena "AAAAAAAAAAAAA..." empezando en la direccion dada por *a, seguiría en la cadena b y como no se sobreescribe el ret (no hay suficientes As) no se obtiene la violacion de segmento.
Efectivamente no se sobrescribe el ret por eso no hay bufferoverflow, bueno no del todo si fue buffer overflow, ya que l buffer de char b[4] que originalmente es de 4 bytes muestra toda la cadena que metimos "AAAAABCD--------------AAAA", eso es un buffer overflow de datos, tambien sobre escribimos la variable unsigned int temp, y 18 bytes de char a[60], quiere decir que con 42 bytes mas se llena b, si agregas mas vas a sobreescribes algunas variables que estan despues sfp, ret estos mismos incluidos, y tenemos un bonito buffer overflow.
|
|
|
|
« Última modificación: 07 Enero 2008, 00:03 por Anon »
|
En línea
|
|
|
|
cualqueircosa
Desconectado
Mensajes: 6
|
bueno hasta el momento todo me ha quedado claro, pero sigo con las mismas preguntas y no he podido continuar  agradeceria cualquier tipo de ayuda, tambien me serviria que me dijeran algun otro sitio donde pudieran resolverme las dudas.
|
|
|
|
« Última modificación: 07 Enero 2008, 03:06 por cualqueircosa »
|
En línea
|
|
|
|
Anon
Desconectado
Mensajes: 294
Is True BSD is UNIX xD!!
|
y otra cosa mas jejejeje, yo no obtengo el mismo codigo pero cuando desensamblo el main (supongo que es por las versiones del gcc y gdb) obtengo un codigo diferente es por eso o me equivoco??
Si, dependiendo de la version del gcc y de la plataforma que utilises, linux, bsd etc. ademas de la version del kernel. bueno hasta el momento todo me ha quedado claro, pero sigo con las mismas preguntas y no he podido continuar  agradeceria cualquier tipo de ayuda, tambien me serviria que me dijeran algun otro sitio donde pudieran resolverme las dudas. La primera pregunta no es muy clara, podrias ser mas especifico, si gustas vemos que hace cada instruccion del Codigo, paso a paso para que no te pierdas, y sobre todo tu duda quede aclarada.
|
|
|
|
|
En línea
|
|
|
|
cualqueircosa
Desconectado
Mensajes: 6
|
gracias Anon por el apoyo, asi que voy a intentar aclarar la primera pregunta en la cual digo: 1- asi que se supone que un word es de 4 bytes, en general lo es?? porque segun tenia entendido es de 2 bytes. en el texto "Smashing The Stack For Fun And Profit" dicen: "....A word in our case is 4 bytes, or 32 bits..... " y en el texto "Lenguaje Ensamblador para PC" de paul a. carter que puede ser encontrado aqui: http://www.drpaulcarter.com/pcasm/ dicen que un word es de 2 bytes, a cual de los dos le hago caso???? asi aparece en "Lenguaje Ensamblador para PC" word 2 bytes palabra double word 4 bytes palabra doble quad word 8 bytes palabra cuadruple paragraph 16 bytes parrafo creo que las otras 3 preguntas son claras, en caso contrario dime y las intento explicar un poco mas detalladamente. gracias otra vez por la respuesta.
|
|
|
|
|
En línea
|
|
|
|
Anon
Desconectado
Mensajes: 294
Is True BSD is UNIX xD!!
|
Bueno en realidad, yo tambien considero qu son de 4 byte, sin embaro por el texto, en su pagina 5, estoy confundido, ademas el autor, no esta especificando si es sobre una arquitectura de 16 bits, o de 32. En caso de ser el primero si esta en lo correcto, en caso de ser el segungo pues ni idea...  Lo demas, lo vemos luego...
|
|
|
|
|
En línea
|
|
|
|
cualqueircosa
Desconectado
Mensajes: 6
|
lo vemos luego?? como asi?? realmente estoy desesperado no se que hacer  cualquier ayuda me servirira mucho
|
|
|
|
|
En línea
|
|
|
|
cualqueircosa
Desconectado
Mensajes: 6
|
si al parecer no me pueden ayudar ¿podrian decirme donde mas podria preguntar para salir de estas dudas??
gracias.
|
|
|
|
|
En línea
|
|
|
|
|
RaiSe
|
Buenas. saludos a todos, escribo esto porque estoy siguiendo el tuto: "Smashing The Stack For Fun And Profit" el problema es en el siguiente codigo:
example1.c: ------------------------------------------------------------------------------ void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; }
void main() { function(1,2,3); }
se el codigo que esta abajo, lo compilo "gcc -S example1.c -o example1.s" y miro el example1.s y veo un "sub $0x16,%esp" y no un "subl $20,%esp" en function, y supongo que es porque cada palabra(word) es de 2 bytes y no 4 como dice el texto, porque serian 6 bytes es decir 3 palabras para buffer1 y 5 palabras para buffer2, es decir un total de 16 bytes.
La cantidad de bytes que reserva el gcc para la pila depende mucho de la versión del mismo. Mas o menos siempre es el tamaño de las variables + alineación, aunque puede cambiar y meter unos pocos bytes más o unos pocos bytes menos dependiente de la versión, opciones del gcc al compilar, etc. Para explotarlo no creo que tenga importancia. example3.c: ------------------------------------------------------------------------------ void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; int *ret;
ret = buffer1 + 12; (*ret) += 8; }
void main() { int x;
x = 0; function(1,2,3); x = 1; printf("%d\n",x); } ------------------------------------------------------------------------------
en la intruccion "ret=buffer1+12" se supone que se esta asignando la direccion de retorno a ret, 4 bytes por el sfp, y 8 por el tamaño del buffer1 suponiendo que cada palabra tiene 4 bytes, pero como tiene 2 deberia ser "ret=buffer1+10" 4 por el sfp y 6 del buffer1.
Respecto a lo que se supone que hace ese código, tiene toda la pinta de hacer lo que dices. Lo del +12 volvemos a lo mismo, depende de la cantidad de stack que haya reservado el gcc. En una versión gcc/opciones_compilación pueden ser +12, y en otra +16. Creo que esto no tiene importancia, siempre puedes depurar el programa para ver cual es la distancia real, y asunto solucionado. [aleph1]$ gdb example3 GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details. GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc... (no debugging symbols found)... (gdb) disassemble main Dump of assembler code for function main: 0x8000490 : pushl %ebp 0x8000491 : movl %esp,%ebp 0x8000493 : subl $0x4,%esp 0x8000496 : movl $0x0,0xfffffffc(%ebp) 0x800049d : pushl $0x3 0x800049f : pushl $0x2 0x80004a1 : pushl $0x1 0x80004a3 : call 0x8000470 0x80004a8 : addl $0xc,%esp 0x80004ab : movl $0x1,0xfffffffc(%ebp) 0x80004b2 : movl 0xfffffffc(%ebp),%eax 0x80004b5 : pushl %eax 0x80004b6 : pushl $0x80004f8 0x80004bb : call 0x8000378 0x80004c0 : addl $0x8,%esp 0x80004c3 : movl %ebp,%esp 0x80004c5 : popl %ebp 0x80004c6 : ret 0x80004c7 : nop ------------------------------------------------------------------------------ se quiere saltar la instruccion 0x80004ab que pone la variable x=1, asi que se quiere ir a 0x80004b2. esto no se como interpretarlo pero segun el texto solo seria sumarle la distancia entre 0x80004b2 y 0x80004ab y personalmente obtengo A y no 8, no se si estoy interpretando algo mal o que, por favor alguien entonces me diga en que me estoy equivocando???
Yo tambien obtengo 0xa, eso que esta copiado del texto?. Que raro, salta al medio de la instruccion movl $0x1,0xfffffffc(%ebp)  . y otra cosa mas jejejeje, yo no obtengo el mismo codigo pero cuando desensamblo el main (supongo que es por las versiones del gcc y gdb) obtengo un codigo diferente es por eso o me equivoco??
Es por la versión del gcc. Un saludo.
|
|
|
|
|
En línea
|
|
|
|
Anon
Desconectado
Mensajes: 294
Is True BSD is UNIX xD!!
|
lo vemos luego?? como asi?? realmente estoy desesperado no se que hacer  cualquier ayuda me servirira mucho Si lo vemos luego.. si mira ya se que estas desesperado por el conocimiento, yo ese dia esta que me moria de sueño ademas tengo vida, y un trabajo para mantenerme...Y trato de ayudar a personas como tu la mayoria de los dias, no solo en el foro, algunos me hablan por telefono otros por msn, los mismos compañeros del trabajo muchas veces me preguntan cosas como esa y otras mas faciles. pero bueno eso es otro tema. si al parecer no me pueden ayudar, podrian decirme donde mas podria preguntar para salir de estas dudas??
gracias.
La verdad no me gusta que pienses de esa manera ni mucho menos la idea de que vallas del foro solo por que no te dan tu respuesta que buscas, pero anda ve a buscar quien te de el conocimiento ya masticado, que te lo de asi. "ahi viene la A, con sus patitas muy abiertas al marchar, le sigue la E, con ..." NO MAMES we tienes todo lo nesesario para apreder, Tienes ojos para leer, un Cerebro para analizar y comprender, y manos para escribir y practicar... No te lo tomes a mal, no es por ofender ni mucho menos. Nadie nace sabiendo, y la logica es muy de cada quien, no se los demas, pero ese texto lo tuve que leer 7 veces y lei algunos articulos mas, otras tantas veces a lo largo de 2 años apara poder entender y reconocer un codigo vulnerable, crear un shellcode, y crear un exploit local, no digas uno por red. sino me crees mira : http://foro.elhacker.net/index.php/topic,193045.0.htmlNo se que edad tengas ni me interesa, yo me entere de la existencia de los Buffer Overflow cuando tenia 15 años, practique, busque, leei, hice mil cosas antes de poder hacer un shellcode, y despues muchas otras cosas mas para poder explotar un buffer Overflow, y unos 2 años despues por fin pude, tal vez fue un exceso y me apena decirlo, muchas veces estaba desesperado por lograr resultados, sin embargo despues del tiempo pude, yo nunca puse mis dudas en un foro, asi que si alguien te esta ayudando, agradecele, ya que es el tiempo que el esta invirtiendo en eso, "Ayudarte" en la intruccion "ret=buffer1+12" se supone que se esta asignando la direccion de retorno a ret, 4 bytes por el sfp, y 8 por el tamaño del buffer1 suponiendo que cada palabra tiene 4 bytes, pero como tiene 2 deberia ser "ret=buffer1+10" 4 por el sfp y 6 del buffer1.
si no entendi mal la idea del anterior codigo es saltarse la instruccion x=1 e ir directamente al printf y asi obtener un "0" y no un "1", listo asi que se le suma 8 a la direccion de retorno dado que usando el gdb se obtiene:
Si la Idea es esa. cabe mencionar algo, que todas las direcciones de Retorno, Apuntadores etc.. siempre tienen 4 bytes en arquitecturas intel con 32 bits en el procesardor.. example1.c: void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; }
void main() { function(1,2,3); }
%gcc -g -static example1.c -o example1 %gdb ./example1 GNU gdb 6.1.1 [FreeBSD] Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-marcel-freebsd"... (gdb) disas main Dump of assembler code for function main: 0x080481bc <main+0>: push %ebp 0x080481bd <main+1>: mov %esp,%ebp 0x080481bf <main+3>: sub $0x8,%esp 0x080481c2 <main+6>: and $0xfffffff0,%esp 0x080481c5 <main+9>: mov $0x0,%eax 0x080481ca <main+14>: add $0xf,%eax 0x080481cd <main+17>: add $0xf,%eax 0x080481d0 <main+20>: shr $0x4,%eax 0x080481d3 <main+23>: shl $0x4,%eax 0x080481d6 <main+26>: sub %eax,%esp 0x080481d8 <main+28>: sub $0x4,%esp 0x080481db <main+31>: push $0x3 0x080481dd <main+33>: push $0x2 0x080481df <main+35>: push $0x1 0x080481e1 <main+37>: call 0x80481b4 <function> 0x080481e6 <main+42>: add $0x10,%esp 0x080481e9 <main+45>: leave 0x080481ea <main+46>: ret End of assembler dump. (gdb) disas function Dump of assembler code for function function: 0x080481b4 <function+0>: push %ebp 0x080481b5 <function+1>: mov %esp,%ebp 0x080481b7 <function+3>: sub $0x28,%esp 0x080481ba <function+6>: leave 0x080481bb <function+7>: ret End of assembler dump.
Bien todo bien ahora mi propio example2 void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; }
int main() { int x; x = 0; function(1,2,3); x = 1; printf("%d\n",x); return 0; } Este esta sin el ret, para ver que pasa exactamente. %gcc -g -static example2.c -o example2 %./example2 1
Buen todo se ejecuta normal. Lo desensamblamos %gdb ./example2 GNU gdb 6.1.1 [FreeBSD] Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-marcel-freebsd"... (gdb) disas main Dump of assembler code for function main: 0x080481bc <main+0>: push %ebp 0x080481bd <main+1>: mov %esp,%ebp 0x080481bf <main+3>: sub $0x8,%esp 0x080481c2 <main+6>: and $0xfffffff0,%esp 0x080481c5 <main+9>: mov $0x0,%eax 0x080481ca <main+14>: add $0xf,%eax 0x080481cd <main+17>: add $0xf,%eax 0x080481d0 <main+20>: shr $0x4,%eax 0x080481d3 <main+23>: shl $0x4,%eax 0x080481d6 <main+26>: sub %eax,%esp 0x080481d8 <main+28>: movl $0x0,0xfffffffc(%ebp) 0x080481df <main+35>: sub $0x4,%esp 0x080481e2 <main+38>: push $0x3 0x080481e4 <main+40>: push $0x2 0x080481e6 <main+42>: push $0x1 0x080481e8 <main+44>: call 0x80481b4 <function> 0x080481ed <main+49>: add $0x10,%esp 0x080481f0 <main+52>: movl $0x1,0xfffffffc(%ebp) 0x080481f7 <main+59>: sub $0x8,%esp 0x080481fa <main+62>: pushl 0xfffffffc(%ebp) 0x080481fd <main+65>: push $0x805b46a 0x08048202 <main+70>: call 0x8049718 <printf> 0x08048207 <main+75>: add $0x10,%esp 0x0804820a <main+78>: mov $0x0,%eax 0x0804820f <main+83>: leave 0x08048210 <main+84>: ret End of assembler dump. (gdb) disas function Dump of assembler code for function function: 0x080481b4 <function+0>: push %ebp 0x080481b5 <function+1>: mov %esp,%ebp 0x080481b7 <function+3>: sub $0x28,%esp 0x080481ba <function+6>: leave 0x080481bb <function+7>: ret End of assembler dump.
La instruccion donde pone 0 en x 0x080481d8 <main+28>: movl $0x0,0xfffffffc(%ebp) el chiste es saltar directamente a la instruccion 0x080481f7 <main+59>: sub $0x8,%esp La solo reserva espacio en la pila para ingresar los argumentos necesarios... esto para despues ejecutar lo siguiente 0x080481fa <main+62>: pushl 0xfffffffc(%ebp) 0x080481fd <main+65>: push $0x805b46a 0x08048202 <main+70>: call 0x8049718 <printf> que en realida es poner a x en la pila 0x080481fa <main+62>: pushl 0xfffffffc(%ebp) poner la cadena "%d\n" 0x080481fd <main+65>: push $0x805b46a Si quieren lo comprobamos... (gdb) printf "%s\n", 0x805b46a %d
(gdb) printf "%s\n", 0x805b46b d
(gdb) printf "%s\n", 0x805b46c
(gdb) Y por ultimo llamamos a printf 0x08048202 <main+70>: call 0x8049718 <printf> entonces, en mi ejemplo nosotros deseamos regresar a 0x080481f7 <main+59>: sub $0x8,%esp por lo cual tendriamos que agregar el siguente codigo a la funcion "function" de nuestro codigo en c. %gdb ./example2 GNU gdb 6.1.1 [FreeBSD] Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-marcel-freebsd"... (gdb) list 1 void function(int a, int b, int c) { 2 char buffer1[5]; 3 char buffer2[10]; 4 } 5 6 int main() { 7 int x; 8 x = 0; 9 function(1,2,3); 10 x = 1; (gdb) break 5 Breakpoint 1 at 0x80481bc: file example2.c, line 5. (gdb) run Starting program: /usr/home/luis/smashing/example2
Breakpoint 1, main () at example2.c:6 6 int main() { (gdb) bt #0 main () at example2.c:6 (gdb) next 8 x = 0; (gdb) bt #0 main () at example2.c:8 (gdb) step 9 function(1,2,3); (gdb) bt #0 main () at example2.c:9 (gdb) step function (a=1, b=2, c=3) at example2.c:4 4 } (gdb) bt #0 function (a=1, b=2, c=3) at example2.c:4 #1 0x080481ed in main () at example2.c:9 (gdb) disas main Dump of assembler code for function main: 0x080481bc <main+0>: push %ebp 0x080481bd <main+1>: mov %esp,%ebp 0x080481bf <main+3>: sub $0x8,%esp 0x080481c2 <main+6>: and $0xfffffff0,%esp 0x080481c5 <main+9>: mov $0x0,%eax 0x080481ca <main+14>: add $0xf,%eax 0x080481cd <main+17>: add $0xf,%eax 0x080481d0 <main+20>: shr $0x4,%eax 0x080481d3 <main+23>: shl $0x4,%eax 0x080481d6 <main+26>: sub %eax,%esp 0x080481d8 <main+28>: movl $0x0,0xfffffffc(%ebp) 0x080481df <main+35>: sub $0x4,%esp 0x080481e2 <main+38>: push $0x3 0x080481e4 <main+40>: push $0x2 0x080481e6 <main+42>: push $0x1 0x080481e8 <main+44>: call 0x80481b4 <function> 0x080481ed <main+49>: add $0x10,%esp 0x080481f0 <main+52>: movl $0x1,0xfffffffc(%ebp) 0x080481f7 <main+59>: sub $0x8,%esp 0x080481fa <main+62>: pushl 0xfffffffc(%ebp) 0x080481fd <main+65>: push $0x805b46a 0x08048202 <main+70>: call 0x8049718 <printf> 0x08048207 <main+75>: add $0x10,%esp 0x0804820a <main+78>: mov $0x0,%eax 0x0804820f <main+83>: leave 0x08048210 <main+84>: ret End of assembler dump. (gdb) disas function Dump of assembler code for function function: 0x080481b4 <function+0>: push %ebp 0x080481b5 <function+1>: mov %esp,%ebp 0x080481b7 <function+3>: sub $0x28,%esp 0x080481ba <function+6>: leave 0x080481bb <function+7>: ret End of assembler dump. (gdb) printf "%d\n",0x28 40 (gdb) printf "%s\n", buffer1
(gdb) printf "%s\n", buffer2
(gdb) printf "0x%x\n", buffer1 0xbfbfe8d0 (gdb) printf "0x%x\n", buffer2 0xbfbfe8c0 (gdb) x 0xbfbfe8d0 0xbfbfe8d0: 0x00000000 (gdb) x 0xbfbfe8d4 0xbfbfe8d4: 0x00000000 (gdb) x 0xbfbfe8d8 0xbfbfe8d8: 0x00000000 (gdb) x 0xbfbfe8dc 0xbfbfe8dc: 0x08064030 (gdb) bt #0 function (a=1, b=2, c=3) at example2.c:4 #1 0x080481ed in main () at example2.c:9 (gdb) x 0xbfbfe8e0 0xbfbfe8e0: 0x08064030 (gdb) x 0xbfbfe8e4 0xbfbfe8e4: 0x08064030 (gdb) x 0xbfbfe8e8 0xbfbfe8e8: 0xbfbfe918 (gdb) x 0xbfbfe8ec 0xbfbfe8ec: 0x080481ed (gdb) x 0xbfbfe8f0 0xbfbfe8f0: 0x00000001 (gdb) x 0xbfbfe8f4 0xbfbfe8f4: 0x00000002 (gdb) x 0xbfbfe8f8 0xbfbfe8f8: 0x00000003 (gdb) x 0xbfbfe8fc 0xbfbfe8fc: 0x00000001 (gdb) x 0xbfbfe900 0xbfbfe900: 0xbfbfe970 (gdb) printf "%d\n", 0xbfbfe8ec - 0xbfbfe8d0 28 (gdb) x 0xbfbfe8ec 0xbfbfe8ec: 0x080481ed (gdb) printf "%d\n", 0x080481f7 - 0x080481ed 10 Bien si quieren que muestre paso por paso que ise en el gdb ahi me dicen y abro otro post, por lo que pude averiguar, van a ser 28 bytes, en mi sistema. Nota esto varia dependiendo del Sistema Operativo (Linux, FreeBSD, etc) version del Kernel, y version del GCC.veamos mi example3.c quedaria asi. %cat example3.c void function(int a, int b, int c) { char buffer1[5]; char buffer2[10]; int *ret; ret = buffer1 + 28; (*ret) += 10; }
int main() { int x; x = 0; function(1,2,3); x = 1; printf("%d\n",x); return 0; } %gcc example3.c -g -static -o example3 example3.c: In function `function': example3.c:5: warning: assignment from incompatible pointer type %./example3 0
Vemos que funciona.
|
|
|
|
|
En línea
|
|
|
|
|
Páginas: [1] 2
|
|
|
|