[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[escepticos] endian-ness



Hola Eloy,

  siento romper el thread, pero estoy en el trabajo y he leido tu correo
nada más salir de casa. Por el camino, he pensado como hace un ejemplo
de pocas líneas que enseñe lo que digo sin mostrar un pantallazo de un
editor hexadecimal. La verdad es que cuando nos ponemos con historias a
bajo nivel, todo es un poco farragoso, pero voy a intentarlo...

Experimento: Mostrar la endian-ness de las arquitecturas IA-32 y
PowerPC en 5 minutos.

1) Bajamos el juego xjump para i386 y para powerpc de
packages.debian.org, y los copiamos en xjump-i386 y xjump-ppc.

2) Escribimos un pequeño programa que lea los 28 primeros bytes de la
cabecera de esos ficheros ejecutables. 

Esos ficheros ejecutables son ELFs, lo estándar en UNIX. Conociendo un
poco del estándar ELF, sabemos que el punto de entrada (entry point, es
decir, lo primero que se ejecuta al cargar ese ejecutable en memoria) de
un ejecutable ELF está en el offset 18h, es decir 24 en decimal. Por lo
tanto, si mostramos el byte 24, 25, 26 y 27 por pantalla, estaremos
mostrando el punto de entrada del ejecutable ELF.

Creamos un programita que muestre estos bytes, y comparamos lo mostrado
con la salida de objdump, programa que hace algo similar, pero de forma
más evolucionada, teniendo en cuenta la endian-ness del ejecutable ELF.

3) Prueba:

txipi@pc-garaizar:~$ cat cabecera.c 
main(int argc, char *argv[])
{
        unsigned char cabecera[28];
        int fd, i;

        fd = open(argv[1], 0);
        
        read(fd, cabecera, 28);

        printf("entry_point: 0x%02x%02x%02x%02x\n", cabecera[24],
cabecera[25], cabecera[26], cabecera[27]); 
}
        
txipi@pc-garaizar:~$ make cabecera
cc     cabecera.c   -o cabecera
txipi@pc-garaizar:~$ ./cabecera xjump-i386 
entry_point: 0xe0910408
txipi@pc-garaizar:~$ ./cabecera xjump-ppc  
entry_point: 0x100010b8
txipi@pc-garaizar:~$ objdump -f xjump-i386 

xjump-i386:     formato del fichero elf32-i386
arquitectura: i386, opciones 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
dirección de inicio 0x080491e0

txipi@pc-garaizar:~$ objdump -f xjump-ppc  

xjump-ppc:     formato del fichero elf32-big
arquitectura: UNKNOWN!, opciones 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
dirección de inicio 0x100010b8

4) Explicación:

Como podemos ver, nuestro programita (cabecera) ha mostrado el valor
0x100010b8 para el entry_point del ejecutable de PowerPC. Este valor
coincide con lo mostrado por objdump, que tiene en cuenta la
endian-ness. Es decir, en el ejecutable PowerPC, sin tener en cuenta la
endian-ness vemos que el valor está en el mismo orden que como luego va
a ser empleado.

El caso contrario ocurre en el ejecutable para i386 (arquitectura
IA-32): nuestro programita muestra 0xe0910408 como valor del
entry_point, mientras que el objdump muestra 0x080491e0, que es
precisamente el equivalente a tomar los bytes 0xAABBCCDD como
0xDDCCBBAA, que es lo que sucede cuando se trabaja en una arquitectura
little-endian.

5) Aclaración: 

El hecho de trabajar con una arquitectura big-endian o
little-endian es transparente al programador en la mayoría de los casos,
puesto que las conversiones son automáticas. Sólo cuando trabajamos con
ficheros binarios tomados como ficheros de entrada o de salida, o cuando
trabajamos programando herramientas de red podemos notar problemas a
causa de la endian-ness.

-- 
Agur
  txipi