elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Ingresar Registrarse
19 Julio 2008, 09:18  



+  Foro de elhacker.net
|-+  Seguridad Informática
| |-+  Bugs y Exploits (Moderadores: sirdarckcat, berz3k)
| | |-+  <-> Uso de GDB para analizar programas sencillos, complejos y vulnerabilidades
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Imprimir
Autor Tema: <-> Uso de GDB para analizar programas sencillos, complejos y vulnerabilidades  (Leído 1507 veces)
Anon

Desconectado Desconectado

Mensajes: 288


Is True BSD is UNIX xD!!


Ver Perfil WWW
<-> Uso de GDB para analizar programas sencillos, complejos y vulnerabilidades
« en: 14 Enero 2008, 01:33 »

Verificando ciertos temas recientes en los que he participado en gran parte

Reto para los Hackers

duda al seguir texto "Smashing The Stack For Fun And Profit"

No puedo sobrescribir EIP (Linux)

He decidido hacer un manual del uso del gdb para el reconocimiento de vulnerabilidades, y el mejor conocimiento de lo que hace nuestro hardware.

Aclarando no soy un experto en la materia, sin embargo tengo experiencia con estas cosas y la verdad que me gusta ayudar.

Bueno lo principal hay que hacer antes que nada es conseguir la documentacion oficial

http://sourceware.org/gdb/documentation/

Cabe mencionar tambien la existencia de verciones modificadas de GDB, las cuales puenden hacer que este trabajo se vea mas facil o bonito cabe mencionar algunos de los mas populares:

  • cgdb gdb en terminal, pero con colores usando ncurses
  • xxgdb gdb en modo Grafico sencillo y carismatico

Alguna duda de como Instalarlos me avisan y lo pongo en otro post


El siguente texto es esencial muchos manuales se basan en el, y el analisis de las Vulnerabilidades son casi exactamente lo mismo que otros textos de Lectura Obligada, que hay por la red asi que leer el siguiete texto

Smashing The Stack For Fun And Profit

Lo siguente esta realizado sobre una Maquina con FreeBSD, con arquitectura x86 clasica, y es muy parecido a los resultados que nos mostraria cualquier distro de linux, o cualquier sistema "like UNIX".

Todo lo aqui mostrado varia dependiendo del Sistema, Version del (kernel/gcc/gdb) que usemos.

Primeramente para los que no saben mucho del tema recomiendo buscar informacion sobre el mismo, no es un post de ensamblador ni mucho menos. solo es como usar el gdb (para/y) (analizar/el analisis) ( /de) programas vulnerables.



Importante
Hay que mencionar que la mayoria de los códigos aqui mostrados se compilan para que incluyan informacion de depuracion

Código:
gcc -o binario código.c -g

o con lo mismo pero con las funciones llamadas compiladas estaticamente

Código:
gcc -o binario código.c -g -static



Bien primeramente veremos como reconocer que es normal y que no es normal.

xgdb_001.c

Código
int main()	{
return 0;
}

ejecutamos gdb con el archivo binario como parametro

Código:
%gdb ./xgdb_001
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)

Despues de esto ejutamos un disassemble, o mas abreviado un disas, sinceramente no tengo la mas remota idea de porque en mi FreeBSD hace un chingo de madres despues del prologo, procedure prolog

Código:
(gdb) disas main
Dump of assembler code for function main:
0x080481b4 <main+0>:    push   %ebp
0x080481b5 <main+1>:    mov    %esp,%ebp
0x080481b7 <main+3>:    sub    $0x8,%esp
0x080481ba <main+6>:    and    $0xfffffff0,%esp
0x080481bd <main+9>:    mov    $0x0,%eax
0x080481c2 <main+14>:   add    $0xf,%eax
0x080481c5 <main+17>:   add    $0xf,%eax
0x080481c8 <main+20>:   shr    $0x4,%eax
0x080481cb <main+23>:   shl    $0x4,%eax
0x080481ce <main+26>:   sub    %eax,%esp
0x080481d0 <main+28>:   mov    $0x0,%eax
0x080481d5 <main+33>:   leave
0x080481d6 <main+34>:   ret
End of assembler dump.
(gdb)


para mi hubiese bastado con lo siguente, sin embargo que mas le hacemos!

Código:
push   %ebp
mov    %esp,%ebp
mov    $0x0,%eax
leave
ret


Bien lo que nos hubiese dado el disas main, es lo normal que nos debe de aparecer, en nuestro sistema.

Analizare aqui, algunos códigos de Smashing The Stack For Fun And Profit, y otros mas sencillos y complejos para verificar lo aprendido.

Primeramente en el sistema donde estemos debemos de identificar las zonas de memoria en las que vamos a trabajar.

Code
Data
Stack
Heap

ya en ejecucion hay poca diferencia entre la 4, solo es neceario identificar 2 tipos de regiones, y tratar de subdividirlas mentalmente o por lo menos tenerlas presentes..

xgdb_001.c

Código
char *cadena="Variable Global, definida";
 
int main() {
int a;
return 0;
}


Código:
%gdb xgdb_002
GNU gdb 6.1.1 [FreeBSD]
.....
(gdb) list
1
2       char *cadena="Variable Global, definida";
3
4       int main()      {
5               int a;
6               return 0;
7       }
(gdb) break 5
Breakpoint 1 at 0x80481d0: file xgdb_002.c, line 5.
(gdb) run
Starting program: /usr/home/luis/gdb/xgdb_002

Breakpoint 1, main () at xgdb_002.c:6
6               return 0;
(gdb) printf "0x%x\n", &a
0xbfbfe924
(gdb) printf "0x%x\n", cadena
0x805b40a
(gdb) printf "%s\n", cadena
Variable Global, definida
(gdb) printf "0x%x\n", main
0x80481b4

Bien, en nuestro sistema, como en el de la mayoria de ustedes, la region del stack esta claramene en el rango de memorias que nos dio, generalmente < 0xbfffffff por ejemplo 0xbfbfe924, Estas direccions son las direcciones que nos ofrece el sistema operativo, mas no son direcciones fisicas...

El code, data, y el heap generalemen > 0x8000000, por ejemplo 0x80481b4 etc en mi caso.

He estado en equipos con muchas medidas de seguridad instaladas como la ejecucucion desde la pila desabilidada, y librerias como libsafe entre otras, esto es bueno, sin embargo si tu las tienes instaladas es posible que no te aparescan los mismos resultados que ami.

Bien ya conocidas los tipos de direcciones que tenemos disponibles podemos analizar ya nuestros códigos.

pintar.c

Código
#include<stdio.h>
 
int main(int argc,char **argv)  {
       if(argc<2)      {
               printf("Se esperaban Parametros!!\nUso:\n\t%s <algo>\n",argv[0]);
               exit(0);
       }
       else    {
               char cadena[1024];
               strcpy(cadena,argv[1]);
               printf("Usted paso como parametro lo siguiente:\n\n%s\n",cadena);
       }
       return 0;
}


El clasico BOF, el cual use para poner un reto hace unos dias descrito en el post Reto para los Hackers

Muchas veces con solo ver un código sencillo en este caso es sufuciente para ver si es o no vulnerable. Sin embargo para los usuarios que usaron el gdb sin exito o con el, lo analizare aqui para mostrar que es lo que se busca exactamente.


Código:
%gdb pintar
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       #include<stdio.h>
2
3       int main(int argc,char **argv)  {
4               if(argc<2)      {
5                       printf("Se esperaban Parametros!!\nUso:\n\t%s <algo>\n",argv[0]);
6                       exit(0);
7               }
8               else    {
9                       char cadena[1024];
10                      strcpy(cadena,argv[1]);
11                      printf("Usted paso como parametro lo siguiente:\n\n%s\n",cadena);
12              }
13              return 0;
14      }
15

Bien en primera instancia, con list, se puede obtener el código fuente.

Código:
(gdb) break 10
Breakpoint 1 at 0x80481f8: file pintar.c, line 10.

con break 10, de decimos al programa que ponga un breakpoint. en determiada linea del código.

Código:
(gdb) run `perl -e '{ print "A"x1024}'`
Starting program: /usr/home/buffer/bin/pintar `perl -e '{ print "A"x1024}'`

Breakpoint 1, main (argc=2, argv=0xbfbfe768) at pintar.c:10
10                      strcpy(cadena,argv[1]);

El programa lo ejecutamos con un parametro de 1024 bytes, justo el espacioque tiene el buffer.

Código:
(gdb) bt
#0  main (argc=2, argv=0xbfbfe568) at pintar.c:10


Si verificamos la que hay de interesante en la pila con bt y vemos que solo estan las direcciones del parametro que pasamos, y cerca de ahi esta el sp, y el ret, el cual nos interesa sobrescribir.

Código:
(gdb) next
11                      printf("Usted paso como parametro lo siguiente:\n\n%s\n",cadena);

Depues de ejecutar next nos informa que esta por ejecutar el printf, lo que nos indica que ya se ejecuto el strcpy, vemos nuevamente la pila, y todo sigue bien, ya que el buffer que le metimos no sobrescrio nada.

Código:
(gdb) bt
#0  main (argc=2, argv=0xbfbfe768) at pintar.c:11
(gdb) next
Usted paso como parametro lo siguiente:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
13              return 0;
(gdb) next
14      }
(gdb) next
0x080480fe in _start ()
(gdb) next
Single stepping until exit from function _start,
which has no line number information.

Program exited normally.

Bien vemos que esto esta bien, y no salio error.

Código:
(gdb) run `perl -e '{ print "A"x1600}'`
Starting program: /usr/home/buffer/bin/pintar `perl -e '{ print "A"x1600}'`

Breakpoint 1, main (argc=2, argv=0xbfbfe328) at pintar.c:10
10                      strcpy(cadena,argv[1]);


Ahora vemos que nuestro breakpoint sigue activo, y ademas que le hemos paso 1600 bytes como parametro.


Código:
(gdb) next
11                      printf("Usted paso como parametro lo siguiente:\n\n%s\n",cadena);
(gdb) bt
#0  main (argc=1094795585, argv=0x41414141) at pintar.c:11
(gdb) printf "0x%x\n"
Wrong number of arguments for specified format-string
(gdb) printf "0x%x\n", argv
0x41414141
(gdb) printf "0x%x\n", argc
0x41414141
(gdb) printf "0x%x\n", &argc
0xbfbfe2e0
(gdb) x 0xbfbfe2e4
0xbfbfe2e4:     0x41414141
(gdb) x 0xbfbfe2e0
0xbfbfe2e0:     0x41414141
(gdb) x 0xbfbfe2dc
0xbfbfe2dc:     0x41414141
(gdb) x 0xbfbfe2d8
0xbfbfe2d8:     0x41414141
(gdb) x 0xbfbfe2d4
0xbfbfe2d4:     0x41414141
(gdb) printf "0x%x\n", cadena
0xbfbfded0
(gdb) printf "0x%x\n", cadena + 4
0xbfbfded4
(gdb) printf "0x%x\n", cadena + 8
0xbfbfded8
(gdb) printf "0x%x\n", cadena + 16
0xbfbfdee0
(gdb) printf "0x%x\n", cadena + 1024
0xbfbfe2d0
(gdb) x 0xbfbfe2d0
0xbfbfe2d0:     0x41414141
(gdb) printf "0x%x\n", cadena + 1600
0xbfbfe510
(gdb) printf "0x%x\n", cadena + 1592
0xbfbfe508
(gdb) x 0xbfbfe508
0xbfbfe508:     0x41414141
(gdb) x 0xbfbfe50c
0xbfbfe50c:     0x41414141
Vemos que sobreescribimos un monton de datos... xD

Código:
(gdb) x 0xbfbfe510
0xbfbfe510:     0x41414100

Sin embargo si solo mandamos 1600 bytes por que en la posicion  0xbfbfe510, todavia encontramos nuestras letras A, bueno eso sera otro tema.

Código:
(gdb) next
Usted paso como parametro lo siguiente:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
13              return 0;
(gdb)
14      }
(gdb)
Warning:
Cannot insert breakpoint 0.
Error accessing memory address 0x41414141: Bad address.

(gdb)
Cannot find bounds of current function

Lo interante es que hemos sobre escrito el retorno con mucho exito. y el programa trato de saltar a la dieccion de memoria 0x41414141, el cual nos informa que es una direccion incorrecta.
tendriamos que insertar la direccion del código que queramos ejecutar.

Pues como vemos sobre escribimos el ret de main y un muchos datos mas, bueno por hoy le dejo.
« Última modificación: 06 Febrero 2008, 04:23 por Anon » En línea

Anon

Desconectado Desconectado

Mensajes: 288


Is True BSD is UNIX xD!!


Ver Perfil WWW
Re: <-> Uso de GDB para analizar programas sencillos, complejos y vulnerabilidad
« Respuesta #1 en: 17 Enero 2008, 04:33 »

Para iniciar este tema, voy a usar los ejemplos que he visto, y expuesto en el tema No puedo sobrescribir EIP (Linux), bueno como padran ver tenemos que identificar el tipo de vulnerabilidad que quermos explotar, y despues tendremos que ver como lo explotamos por que ahora ya visto es diferente el resultado de compilar determinado codigo con gcc 3.x.x que con un gcc 4.x

Código
#include <stdio.h>
 
int main(int argc, char **argv) {
char buff[12];
strcpy(buff,argv[1]);
printf("\nHas escrito:   %s\n",buff);
return 0;
}


Veremos a continuacion lo que se se conoce como Procedure Prolog y Procedure Epilog, (El principio y el Fin de una Funcion)

Primero con gcc 3.4.6

Código:
%gcc -v
Using built-in specs.
Configured with: FreeBSD/i386 system compiler
Thread model: posix
gcc version 3.4.6 [FreeBSD] 20060305
...
(gdb) disas main
0x080481b4 <main+0>:    push   %ebp
0x080481b5 <main+1>:    mov    %esp,%ebp
...
0x08048200 <main+76>:   leave
0x08048201 <main+77>:   ret

Ahora con gcc 4.1.3

Código:
%gcc41 -v
Using built-in specs.
Target: i386-portbld-freebsd6.2
Thread model: posix
gcc version 4.1.3 20070820 (prerelease)


(gdb) disas main
0x08048528 <main+0>:    lea    0x4(%esp),%ecx
0x0804852c <main+4>:    and    $0xfffffff0,%esp
0x0804852f <main+7>:    pushl  0xfffffffc(%ecx)
0x08048532 <main+10>:   push   %ebp
0x08048533 <main+11>:   mov    %esp,%ebp
...
0x0804856a <main+66>:   mov    0xfffffffc(%ebp),%ecx
0x0804856d <main+69>:   leave
0x0804856e <main+70>:   lea    0xfffffffc(%ecx),%esp
0x08048571 <main+73>:   ret

La forma de explotar un clasico BoF es un poco diferente para el codigo generado en gcc version 4.1.3  que en gcc version 3.4.6

« Última modificación: 05 Febrero 2008, 21:24 por Anon » En línea

Anon

Desconectado Desconectado

Mensajes: 288


Is True BSD is UNIX xD!!


Ver Perfil WWW
Re: <-> Uso de GDB para analizar programas sencillos, complejos y vulnerabilidad
« Respuesta #2 en: 05 Febrero 2008, 00:29 »

Bien, para seguir con el uso de GBD vamos a analizar una version modificada de un codigo que hice para probar una idea loca que se me vino a la mente en ese momento para mas informacion ver  BoF en inet_network(), afecta a Servidor DNS: BIND.

El codigo es el siguiente:

Código
int main()	{
unsigned long prueba;
long i;
prueba = 1;
i = 0;
while(i < 32) {
printf("Prueba[%i]: %u\n",i+1,prueba);
i++;
prueba = (prueba << 1);
}
return 0;
}
 

Como vemos es una aplicaion sencilla sin embargo tiene lo necesario para poder identificar ciertos valores y funciones.

Código:
%gdb corribits
GNU gdb 6.1.1 [FreeBSD]
....
This GDB was configured as "i386-marcel-freebsd"...
(gdb) list
1
2   int main()  {
3       unsigned long prueba;
4       long i;
5       prueba = 1;
6       i = 0;
7       while(i < 32)   {
8               printf("Prueba[%i]: %u\n",i+1,prueba);
9               i++;
10              prueba = (prueba << 1);
11      }
12      return 0;
13  }

En los ejemplo posteriores no pondre ya el comando list, el cual nos lista el codigo Fuente de un archivo binario en caso de que este este compilado con la opcion -ggdb

Cabe mencionar que vamos a tener un reencuentro con el Ensamblador para verlo paso por paso.

Código:
(gdb) disas main
Dump of assembler code for function main:
0x080481b4 <main+0>:    push   %ebp
0x080481b5 <main+1>:    mov    %esp,%ebp
0x080481b7 <main+3>:    sub    $0x8,%esp
0x080481ba <main+6>:    and    $0xfffffff0,%esp
0x080481bd <main+9>:    mov    $0x0,%eax
0x080481c2 <main+14>:   add    $0xf,%eax
0x080481c5 <main+17>:   add    $0xf,%eax
0x080481c8 <main+20>:   shr    $0x4,%eax
0x080481cb <main+23>:   shl    $0x4,%eax
0x080481ce <main+26>:   sub    %eax,%esp
0x080481d0 <main+28>:   movl   $0x1,0xfffffffc(%ebp)
0x080481d7 <main+35>:   movl   $0x0,0xfffffff8(%ebp)
0x080481de <main+42>:   cmpl   $0x1f,0xfffffff8(%ebp)
0x080481e2 <main+46>:   jg     0x8048208 <main+84>
0x080481e4 <main+48>:   sub    $0x4,%esp
0x080481e7 <main+51>:   pushl  0xfffffffc(%ebp)
0x080481ea <main+54>:   mov    0xfffffff8(%ebp),%eax
0x080481ed <main+57>:   inc    %eax
0x080481ee <main+58>:   push   %eax
0x080481ef <main+59>:   push   $0x805b46a
0x080481f4 <main+64>:   call   0x8049714 <printf>
0x080481f9 <main+69>:   add    $0x10,%esp
0x080481fc <main+72>:   lea    0xfffffff8(%ebp),%eax
0x080481ff <main+75>:   incl   (%eax)
0x08048201 <main+77>:   lea    0xfffffffc(%ebp),%eax
0x08048204 <main+80>:   shll   (%eax)
0x08048206 <main+82>:   jmp    0x80481de <main+42>
0x08048208 <main+84>:   mov    $0x0,%eax
0x0804820d <main+89>:   leave
0x0804820e <main+90>:   ret
End of assembler dump.

Bien desensamblamos la funcion main, que es Practicamente toda nuestra funcion xD.

Olvidandonos del Procedure Prolog y Procedure Epilog. que ya lo vimos en un post Anterior a este

Ahora el siguente codigo sinceramente no se por que lo hace pero me imagino que es para alinear la pila o algo asi :/ asi que si alguien lo puede explicar recibiremos su aporte con gusto, en caso contrario yo lo explicare cuando pueda.

Código:
0x080481bd <main+9>:    mov    $0x0,%eax
0x080481c2 <main+14>:   add    $0xf,%eax
0x080481c5 <main+17>:   add    $0xf,%eax
0x080481c8 <main+20>:   shr    $0x4,%eax
0x080481cb <main+23>:   shl    $0x4,%eax
0x080481ce <main+26>:   sub    %eax,%esp

Nos quedamos con un codigo en ASM en Modalidad AT&T, ya saben de eso me imagino y si no buscar en google.

Código:
movl   $0x1,0xfffffffc(%ebp)
prueba = 1;

Código:
movl   $0x0,0xfffffff8(%ebp)
i = 0;

Código:
cmpl   $0x1f,0xfffffff8(%ebp)
Esta es la comparacion que se realiza en el while (i < 32)

Código:
jg     0x8048208 <main+84>
En caso de que no se cumpla saltamos a esa direccion. al return 0;


Código:
sub    $0x4,%esp
Esta accion reserva 4 bytes a la Pila para despues meter las variables usadas en por el printf

Código:
pushl  0xfffffffc(%ebp)
Ponemos en la pila, el valor de la Variable Prueba

Código:
mov    0xfffffff8(%ebp),%eax
inc    %eax
El valor de la variable i es pasado a un registro del microprocesaro y posteriormente Incrementado.

Código:
push   %eax
Una vez Incrementado lo Agregamos a la Pila

Código:
push   $0x805b46a
Ingresamos la Direccion de la Cadena "Prueba[%i]: %u\n" en la pila.

Código:
call   0x8049714 <printf>
Llamamos a printf con todos los parametros metidos en la pila.

Código:
add    $0x10,%esp
Recuperamos parte del espacio que reservamos en la pila

Código:
lea    0xfffffff8(%ebp),%eax
asignamos a eax la direccion en memoria de la variable i

Código:
incl   (%eax)
Incrementamos el valor en 1.

Código:
lea    0xfffffffc(%ebp),%eax
asignamos a eax la direccion en memoria de la variable Prueba

Código:
shll   (%eax)
recorrimiento de bits a la derecha de una variable long

Código:
jmp    0x80481de <main+42>
Regresamos a la compracion para que si sea un while :D

Código:
mov    $0x0,%eax
Movemos 0 al registro eax, para que se cumpla el return 0;

Si vemos el valo de la variable Prueba, vemos que este aumenta en potencias de 2 en cada iteracion.
Si lo vemos en binario veriamos algo asi

00000000000000000000000000000001
00000000000000000000000000000010
00000000000000000000000000000100
...
10000000000000000000000000000000


Bueno como lo mensione antes este ejemplo lo realize con la intencion de ver si al hacer el recorrimiento de bits era capaz de sobreescribir en la memoria que no le correspondia a la variable, pero inmediatamente despues recorde que esto se hace en el micro :P uno esta deseperado por ideas a la hora de tratar de encontrar un bug. Sin embargo se me hizo buen ejemplo para ponerlo aqui y ver paso un ejemplo sencillo de programacion.
« Última modificación: 05 Febrero 2008, 21:24 por Anon » En línea

Páginas: [1] Ir Arriba Imprimir 
Ir a:  








Consolas     La Web de Goku     MilW0rm     MundoDivx

Hispabyte     Truzone     TodoReviews     ZonaPhotoshop

hard-h2o modding    Foros de ayuda    Yashira.org    Videojuegos    indetectables.net   

Noticias Informatica    Seguridad Informática    ADSL    Foros en español    eNYe Sec

Todas las webs afiliadas están libres de publicidad engañosa.

Powered by SMF 1.1.5 | SMF © 2006-2008, Simple Machines LLC