Хорошо, вот большое издание моего предыдущего ответа.Я думаю, что нашел способ сейчас.
У вас (все еще :) есть эта конкретная проблема:
(gdb) disas main
No symbol table is loaded. Use the "file" command.
Теперь, если вы скомпилируете код (я добавил return 0
в конце), вы получите с gcc -S
:
pushq %rbp
movq %rsp, %rbp
movl $.LC0, %edi
call puts
movl $0, %eax
leave
ret
Теперь вы можете видеть, что ваш двоичный файл дает вам некоторую информацию:
Полосатый:
(gdb) info files
Symbols from "/home/beco/Documents/fontes/cpp/teste/stackoverflow/distrip".
Local exec file:
`/home/beco/Documents/fontes/cpp/teste/stackoverflow/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
самая важная запись здесь .text
.Это общее название для начала сборки кода, и из нашего объяснения main ниже, из его размера, вы можете видеть, что он включает main.Если вы разберете его, вы увидите вызов __libc_start_main.Самое главное, вы разбираете хорошую точку входа, которая является реальным кодом (вы не вводите в заблуждение, чтобы изменить DATA на 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
Вызов __ libc_start_main получает в качестве первого аргументауказатель на main ().Итак, последний аргумент в стеке непосредственно перед вызовом - это ваш адрес main ().
0x000000000040045d: mov $0x400524,%rdi
0x0000000000400464: callq 0x400428 <__libc_start_main@plt>
Здесь это 0x400524 (как мы уже знаем).Теперь вы устанавливаете точку останова и попробуйте это:
(gdb) break *0x400524
Breakpoint 1 at 0x400524
(gdb) run
Starting program: /home/beco/Documents/fontes/cpp/teste/stackoverflow/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)
Теперь вы можете разобрать его, используя:
(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
...
Это в первую очередь решение.
Кстати, это другой код, чтобы посмотреть, работает ли он.Вот почему сборка выше немного отличается.Код выше взят из этого файла c:
#include <stdio.h>
int main(void)
{
int i=1;
printf("hello %d\n", i);
return 0;
}
Но!
, если это не работает, то у вас все еще есть некоторые подсказки:
Вы должныищите установить точки останова в начале всех функций с этого момента.Они как раз перед ret
или leave
.Первая точка входа - это .text
.Это начало сборки, но не главное.
Проблема в том, что не всегда точка останова будет запускать вашу программу.Как этот в очень .text
:
(gdb) break *0x0000000000400440
Breakpoint 2 at 0x400440
(gdb) run
Starting program: /home/beco/Documents/fontes/cpp/teste/stackoverflow/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
Так что вам нужно продолжать пытаться, пока вы не найдете свой путь, устанавливая точки останова в:
0x400440
0x40046c
0x400490
0x4004f4
0x40051e
0x400524
Из другогоответ, мы должны сохранить эту информацию:
В не полосатой версии файла мы видим:
(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.
Теперь мы знаем, что main находится в 0x0000000000400524,0x0000000000400539
.Если мы используем одно и то же смещение для просмотра полосатого двоичного файла, мы получим те же результаты:
(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.
Так что, если вы не можете получить какой-либо совет, где начинается основное (например, с использованием другого кода с символами), другим способомесли у вас есть некоторая информация о первых инструкциях по сборке, так что вы можете разобрать в определенных местах и посмотреть, соответствует ли он.Если у вас вообще нет доступа к коду, вы все равно можете прочитать определение ELF , чтобы понять, сколько разделов должно появиться в коде, и попробовать вычисленный адрес.Тем не менее, вам нужна информация о разделах в коде!
Это тяжелая работа, мой друг!Удачи!
Beco