usar seguidores pueden poner para los historias hashtags funcionan cuantos copiar conseguir como c linux gdb strip disassembly

pueden - hashtag instagram para conseguir seguidores



¿Cómo desmontar la función principal de una aplicación despojada? (4)

¿Qué tal si hacemos info files para obtener la lista de secciones (con direcciones) y vamos desde allí?

Ejemplo:

gdb) info files Symbols from "/home/bob/tmp/t". Local exec file: `/home/bob/tmp/t'', file type elf64-x86-64. Entry point: 0x400490 0x0000000000400270 - 0x000000000040028c is .interp 0x000000000040028c - 0x00000000004002ac is .note.ABI-tag .... 0x0000000000400448 - 0x0000000000400460 is .init ....

El desmonte .init :

(gdb) disas 0x0000000000400448,0x0000000000400460 Dump of assembler code from 0x400448 to 0x400460: 0x0000000000400448: sub $0x8,%rsp 0x000000000040044c: callq 0x4004bc 0x0000000000400451: callq 0x400550 0x0000000000400456: callq 0x400650 0x000000000040045b: add $0x8,%rsp 0x000000000040045f: retq

Luego adelante y desarme el resto.

Si yo fuera tú, y tuviera la misma versión de GCC con la que se construyó tu ejecutable, examinaría la secuencia de funciones llamadas en un ejecutable ficticio sin pelar. La secuencia de llamadas es probablemente similar en la mayoría de los casos habituales, por lo que podría ayudarlo a analizar la secuencia de inicio hasta su main por comparación. Sin embargo, las optimizaciones probablemente vendrán en el camino.

Si su binario está eliminado y optimizado, main podría no existir como una "entidad" en el binario; lo más probable es que no pueda ser mucho mejor que este tipo de procedimiento.

Digamos que compilé la aplicación a continuación y quité sus símbolos.

#include <stdio.h> int main() { printf("Hello/n"); }

Procedimiento de construcción:

gcc -o hello hello.c strip --strip-unneeded hello

Si la aplicación no se eliminó, desmontar la función principal sería fácil. Sin embargo, no tengo idea de cómo desmontar la función principal de una aplicación despojada.

(gdb) disas main No symbol table is loaded. Use the "file" command. (gdb) info line main Function "main" not defined.

¿Cómo podría hacerlo? ¿Es posible?

Notas : esto debe hacerse solo con GDB. Olvídate de objdump . Supongamos que no tengo acceso al código.

Un ejemplo paso a paso sería muy apreciado.


Hay una nueva herramienta gratuita llamada Unstrip from the paradyn project (revelación completa: trabajo en este proyecto) que reescribirá el programa binario, agregará información de símbolos y recuperará todas (o casi todas) las funciones en los binarios de Elf despojados Para ti, con gran exactitud. No identificará la función principal como "principal", pero la encontrará, y puede aplicar la heurística que ya mencionó anteriormente para averiguar qué función es la principal.

http://www.paradyn.org/html/tools/unstrip.html

Lo siento, esto no es una solución sólo para gdb.


IIRC, x/i <location> es tu amigo. Por supuesto, tienes que averiguar en qué lugar quieres desarmarte.


Ok, aquí una gran edición de mi respuesta anterior. Creo que encontré un camino ahora.

Usted (todavía :) tiene este problema específico:

(gdb) disas main No symbol table is loaded. Use the "file" command.

Ahora, si compilas el código (agregué un return 0 al final), obtendrás con gcc -S :

pushq %rbp movq %rsp, %rbp movl $.LC0, %edi call puts movl $0, %eax leave ret

Ahora, puedes ver que tu binario te da información:

A rayas:

(gdb) info files Symbols from "/home/beco/Documents/fontes/cpp/teste//distrip". Local exec file: `/home/beco/Documents/fontes/cpp/teste//distrip'', file type elf64-x86-64. Entry point: 0x400440 0x0000000000400238 - 0x0000000000400254 is .interp ... 0x00000000004003a8 - 0x00000000004003c0 is .rela.dyn 0x00000000004003c0 - 0x00000000004003f0 is .rela.plt 0x00000000004003f0 - 0x0000000000400408 is .init 0x0000000000400408 - 0x0000000000400438 is .plt 0x0000000000400440 - 0x0000000000400618 is .text ... 0x0000000000601010 - 0x0000000000601020 is .data 0x0000000000601020 - 0x0000000000601030 is .bss

La entrada más importante aquí es .text . Es un nombre común para el inicio del código de un ensamblado, y de nuestra explicación de la página principal, por su tamaño, puede ver que incluye main. Si lo desmonta, verá una llamada a __libc_start_main. Lo más importante es que está desarmando un buen punto de entrada que es código real (no es engañoso cambiar DATA a CODE).

disas 0x0000000000400440,0x0000000000400618 Dump of assembler code from 0x400440 to 0x400618: 0x0000000000400440: xor %ebp,%ebp 0x0000000000400442: mov %rdx,%r9 0x0000000000400445: pop %rsi 0x0000000000400446: mov %rsp,%rdx 0x0000000000400449: and $0xfffffffffffffff0,%rsp 0x000000000040044d: push %rax 0x000000000040044e: push %rsp 0x000000000040044f: mov $0x400540,%r8 0x0000000000400456: mov $0x400550,%rcx 0x000000000040045d: mov $0x400524,%rdi 0x0000000000400464: callq 0x400428 <__libc_start_main@plt> 0x0000000000400469: hlt ... 0x000000000040046c: sub $0x8,%rsp ... 0x0000000000400482: retq 0x0000000000400483: nop ... 0x0000000000400490: push %rbp .. 0x00000000004004f2: leaveq 0x00000000004004f3: retq 0x00000000004004f4: data32 data32 nopw %cs:0x0(%rax,%rax,1) ... 0x000000000040051d: leaveq 0x000000000040051e: jmpq *%rax ... 0x0000000000400520: leaveq 0x0000000000400521: retq 0x0000000000400522: nop 0x0000000000400523: nop 0x0000000000400524: push %rbp 0x0000000000400525: mov %rsp,%rbp 0x0000000000400528: mov $0x40062c,%edi 0x000000000040052d: callq 0x400418 <puts@plt> 0x0000000000400532: mov $0x0,%eax 0x0000000000400537: leaveq 0x0000000000400538: retq

La llamada a __libc_start_main obtiene como primer argumento un puntero a main (). Por lo tanto, el último argumento en la pila justo antes de la llamada es su dirección principal ().

0x000000000040045d: mov $0x400524,%rdi 0x0000000000400464: callq 0x400428 <__libc_start_main@plt>

Aquí está 0x400524 (como ya sabemos). Ahora establece un punto de interrupción e intente esto:

(gdb) break *0x400524 Breakpoint 1 at 0x400524 (gdb) run Starting program: /home/beco/Documents/fontes/cpp/teste//disassembly/d2 Breakpoint 1, 0x0000000000400524 in main () (gdb) n Single stepping until exit from function main, which has no line number information. hello 1 __libc_start_main (main=<value optimized out>, argc=<value optimized out>, ubp_av=<value optimized out>, init=<value optimized out>, fini=<value optimized out>, rtld_fini=<value optimized out>, stack_end=0x7fffffffdc38) at libc-start.c:258 258 libc-start.c: No such file or directory. in libc-start.c (gdb) n Program exited normally. (gdb)

Ahora puedes desmontarlo usando:

(gdb) disas 0x0000000000400524,0x0000000000400600 Dump of assembler code from 0x400524 to 0x400600: 0x0000000000400524: push %rbp 0x0000000000400525: mov %rsp,%rbp 0x0000000000400528: sub $0x10,%rsp 0x000000000040052c: movl $0x1,-0x4(%rbp) 0x0000000000400533: mov $0x40064c,%eax 0x0000000000400538: mov -0x4(%rbp),%edx 0x000000000040053b: mov %edx,%esi 0x000000000040053d: mov %rax,%rdi 0x0000000000400540: mov $0x0,%eax 0x0000000000400545: callq 0x400418 <printf@plt> 0x000000000040054a: mov $0x0,%eax 0x000000000040054f: leaveq 0x0000000000400550: retq 0x0000000000400551: nop 0x0000000000400552: nop 0x0000000000400553: nop 0x0000000000400554: nop 0x0000000000400555: nop ...

Esta es principalmente la solución.

Por cierto, este es un código diferente, para ver si funciona. Es por eso que el montaje anterior es un poco diferente. El código de arriba es de este archivo c:

#include <stdio.h> int main(void) { int i=1; printf("hello %d/n", i); return 0; }

¡Pero!

Si esto no funciona, entonces todavía tienes algunos consejos:

Debería estar buscando establecer puntos de interrupción al comienzo de todas las funciones a partir de ahora. Están justo antes de un ret o se leave . El primer punto de entrada es el propio .text . Este es el inicio de la asamblea, pero no el principal.

El problema es que no siempre un punto de interrupción permitirá que su programa se ejecute. Como este en el .text :

(gdb) break *0x0000000000400440 Breakpoint 2 at 0x400440 (gdb) run Starting program: /home/beco/Documents/fontes/cpp/teste//disassembly/d2 Breakpoint 2, 0x0000000000400440 in _start () (gdb) n Single stepping until exit from function _start, which has no line number information. 0x0000000000400428 in __libc_start_main@plt () (gdb) n Single stepping until exit from function __libc_start_main@plt, which has no line number information. 0x0000000000400408 in ?? () (gdb) n Cannot find bounds of current function

Por lo tanto, debe seguir intentando hasta que encuentre su camino, estableciendo puntos de interrupción en:

0x400440 0x40046c 0x400490 0x4004f4 0x40051e 0x400524

De la otra respuesta, debemos mantener esta información:

En la versión no rayada del archivo, vemos:

(gdb) disas main Dump of assembler code for function main: 0x0000000000400524 <+0>: push %rbp 0x0000000000400525 <+1>: mov %rsp,%rbp 0x0000000000400528 <+4>: mov $0x40062c,%edi 0x000000000040052d <+9>: callq 0x400418 <puts@plt> 0x0000000000400532 <+14>: mov $0x0,%eax 0x0000000000400537 <+19>: leaveq 0x0000000000400538 <+20>: retq End of assembler dump.

Ahora sabemos que el principal está en 0x0000000000400524,0x0000000000400539 . Si usamos el mismo desplazamiento para ver el binario con bandas obtenemos los mismos resultados:

(gdb) disas 0x0000000000400524,0x0000000000400539 Dump of assembler code from 0x400524 to 0x400539: 0x0000000000400524: push %rbp 0x0000000000400525: mov %rsp,%rbp 0x0000000000400528: mov $0x40062c,%edi 0x000000000040052d: callq 0x400418 <puts@plt> 0x0000000000400532: mov $0x0,%eax 0x0000000000400537: leaveq 0x0000000000400538: retq End of assembler dump.

Por lo tanto, a menos que pueda obtener alguna sugerencia donde comienza el inicio (como usar otro código con símbolos), otra forma es si puede tener alguna información acerca de las primeras instrucciones de ensamblaje, así puede desensamblar en lugares específicos y ver si coinciden. Si no tiene acceso al código, puede leer la definición ELF para comprender cuántas secciones deben aparecer en el código y probar una dirección calculada. Aún así, ¡necesitas información sobre secciones en el código!

Eso es un trabajo duro, mi amigo! ¡Buena suerte!

Beco