2012-02-08 13 views
19

Un poco de fondo. Soy un principiante con c y código ensamblador, tenemos una asignación "bomba" (escrita en c) que llama a métodos que requieren ciertas contraseñas, pero el código no está visible y necesito determinar la contraseña correcta mirando el código ensamblador .Descifrando y comprendiendo el código de ensamblaje

El código indica que la contraseña para este método es de 6 números, que se pasa como "entrada" a la fase 2 del método (estoy tratando de evitar el disparo).

La parte en la que me estoy confundiendo es saltar de +64 a +42. Parece ser un bucle, pero no estoy seguro de cómo se ve afectada la pila con cada pase. Parece que el ciclo sale si los dos últimos números son iguales y tiene algo que ver con sumar y restar 4, pero no estoy seguro de cómo se cruzan las direcciones. Si alguien puede traducir qué está sucediendo exactamente, o si debo buscar en algún registro/ubicación en particular, sería de gran ayuda. Hay 4 fases más que se supone que son más complejas, por lo que quiero obtener una buena comprensión de cómo leerlas.

Además, si alguien tiene un buen recurso (como una tabla imprimible) con código de ensamblaje, las palabras clave también serían útiles, y si hay alguna diferencia entre los registros de 32 y 64 bits, me tengo que preocupar por los nombres de los registros ..

82   phase_2(input); 
(gdb) disas phase_2 
Dump of assembler code for function phase_2: 
0x000000000040106b <phase_2+0>: push %rbp 
0x000000000040106c <phase_2+1>: push %rbx 
0x000000000040106d <phase_2+2>: sub $0x28,%rsp 
0x0000000000401071 <phase_2+6>: mov %rsp,%rsi 
0x0000000000401074 <phase_2+9>: callq 0x401457 <read_six_numbers> 
0x0000000000401079 <phase_2+14>:  cmpl $0x0,(%rsp) 
0x000000000040107d <phase_2+18>:  jne 0x401086  <phase_2+27> 
0x000000000040107f <phase_2+20>:  cmpl $0x1,0x4(%rsp) 
0x0000000000401084 <phase_2+25>:  je  0x40108b <phase_2+32> 
0x0000000000401086 <phase_2+27>:  callq 0x401421 <explode_bomb> 
0x000000000040108b <phase_2+32>:  lea 0x8(%rsp),%rbx 
0x0000000000401090 <phase_2+37>:  lea 0x18(%rsp),%rbp 
0x0000000000401095 <phase_2+42>:  mov -0x8(%rbx),%eax 
0x0000000000401098 <phase_2+45>:  add -0x4(%rbx),%eax 
0x000000000040109b <phase_2+48>:  cmp %eax,(%rbx) 
0x000000000040109d <phase_2+50>:  je  0x4010a4 <phase_2+57> 
0x000000000040109f <phase_2+52>:  callq 0x401421 <explode_bomb> 
0x00000000004010a4 <phase_2+57>:  add $0x4,%rbx 
0x00000000004010a8 <phase_2+61>:  cmp %rbp,%rbx 
0x00000000004010ab <phase_2+64>:  jne 0x401095 <phase_2+42> 
0x00000000004010ad <phase_2+66>:  add $0x28,%rsp 
0x00000000004010b1 <phase_2+70>:  pop %rbx 
0x00000000004010b2 <phase_2+71>:  pop %rbp 
0x00000000004010b3 <phase_2+72>:  retq 
+0

Si estuviera usando Windows lo recomendaría: http://www.ollydbg.de/ con gdb (me acabo de enterar) use TUI, http://stackoverflow.com/a/2422063/1149736 y : 'layout asm'' start' 'layout regs'' ni' 'ni'' ni' :) y sigue la pila cuidadosamente http://www.chemie.fu-berlin.de/chemnet/use/info/gdb/gdb_7 .html – Vyktor

+9

Tienes una profesora genial :) –

Respuesta

45

Aquí es un C equivalente de fase 2:

int t[6]; 
read_six_numbers (t); 
if ((t[0] != 0) || (t[1] != 1)) { 
    explode_bomb(); 
} 

for (int i = 2; i < 6; i++) { 
     if (t[i] != t[i - 2] + t[i - 1]) { 
      explode_bomb(); 
    } 
} 

Así que la contraseña es 0, 1, 1, 2, 3, 5.

Cómo d id Yo hago esto? Al reemplazar gradualmente el ensamblaje con C.

Observará que el puntero de la pila (rsp) nunca cambia. Puede ver la pila como una matriz t de números de 32 bits. Es decir, cada vez que te mueves por 4 bytes pasas al siguiente elemento. es decir, 0 (% rsp), 4 (% rsp), ... son equivalentes a t [0], t [1], ...

Le mostraré una posible transformación gradual del bit que tiene problemas con:

   lea 0x8(%rsp),%rbx 
       lea 0x18(%rsp),%rbp 
<phase_2+42>: mov -0x8(%rbx),%eax 
       add -0x4(%rbx),%eax 
       cmp %eax,(%rbx) 
       je  <phase_2+57> 
       callq explode_bomb 
<phase_2+57>: add $0x4,%rbx 
       cmp %rbp,%rbx 
       jne phase_2+42 
------------------------------------------------------ 
        rbx = rsp + 8; 
        rbp = rsp + 24; 
<phase_2+42>:  eax = [rbx - 8]; 
        eax += [rbx - 4]; 
        if (eax == [rbx]) goto <phase_2+57>; 
        explode_bomb(); 
<phase_2+57>:  rbx += 4; 
        if (rbx != rbp) goto phase_2+42; 
------------------------------------------------------ 
rbx = rsp + 8; 
rbp = rsp + 24; 
do { 
    eax = [rbx - 8] + [rbx - 4]; 
     if (eax != [rbx]) { 
     explode_bomb(); 
    } 
     rbx += 4; 
} while (rbx != rbp); 
------------------------------------------------------ 
rbx = 8; 
do { 
    eax = [rsp + rbx - 8] + [rsp + rbx - 4]; 
     if (eax != [rsp + rbx]) { 
     explode_bomb(); 
    } 
     rbx += 4; 
} while (rbx < 24); 
------------------------------------------------------ 
i = 2; 
do { 
    eax = t[i - 2] + t[i - 1]; 
     if (eax != t[i]) { 
     explode_bomb(); 
    } 
     i += 1; 
} while (i < 6); 
------------------------------------------------------ 
for (int i = 2; i < 6; i++) { 
    if (t[i] != t[i - 2] + t[i - 1]) { 
      explode_bomb(); 
     } 
} 

Si se toma el tiempo para entender estas transformaciones que usted será capaz de transformar y entender cualquier pieza de montaje.

+1

Bien escrito, +1. –

Cuestiones relacionadas