如何使用gdb调试原始二进制文件

如何使用gdb调试原始二进制文件,gdb,arm,Gdb,Arm,我有一个嵌入式设备的可执行文件。 它没有gdb识别的头信息,而是使用供应商指定的专有头 我可以使用IDA pro很好地分析文件,但我想运行一些代码来看看它的作用 可执行文件在地址0x52000000处加载 但是,如果我只是使用 exec-file myfile 我明白了 “myfile”:不是可执行格式:无法识别文件格式 如果我使用以下方法将内存恢复到正确的位置: restore myfile 52000000 我得到: 如果没有要调试的进程,您就无法做到这一点 我如何摆脱这个鸡和蛋的问题?

我有一个嵌入式设备的可执行文件。
它没有gdb识别的头信息,而是使用供应商指定的专有头

我可以使用IDA pro很好地分析文件,但我想运行一些代码来看看它的作用

可执行文件在地址0x52000000处加载

但是,如果我只是使用

exec-file myfile
我明白了

“myfile”:不是可执行格式:无法识别文件格式

如果我使用以下方法将内存恢复到正确的位置:

restore myfile 52000000
我得到:

如果没有要调试的进程,您就无法做到这一点

我如何摆脱这个鸡和蛋的问题?

<>我只想跳进代码的中间,把一些寄存器设置成预定值,然后运行一些代码看看发生了什么。
请注意,我使用的是ARM本身的gdb ARM工具链。

根据@artless\u noise建议,我做了以下工作:

objcopy.exe 
--output-target=elf32-bigarm 
--input-target=binary 
--change-start=0x52000000 
INPUTFILE OUTPUTFILE
这会将
elf
头添加到文件中。
但是,它并不能解决整个问题。
产量

readelf.exe -a OUTPUTFILE 
给出:

ELF Header:
  Magic:   7f 45 4c 46 01 02 01 61 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, big endian
  Version:                           1 (current)
  OS/ABI:                            ARM
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x52000000
  Start of program headers:          0 (bytes into file)
  Start of section headers:          57316 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           40 (bytes)
  Number of section headers:         5
  Section header string table index: 2

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .data             PROGBITS        00000000 000034 00df8c 00  WA  0   0  1
.....
请注意,
.data
部分的地址仍然是
0x00000000
。这应该是
0x52000000

为了解决这个问题,我在地址0xdf8c打开了一个十六进制编辑器。
这将关闭节标题所在的位置。 部分标题的结构如下所示,以及我希望在那里看到的数据

typedef struct {
  Elf32_Word sh_name;    
  Elf32_Word sh_type;    = 1 {.data}
  Elf32_Word sh_flags;   = ?
  Elf32_Addr sh_addr;    = 0x00000000
  Elf32_Off sh_offset;   = 0x00000034
  Elf32_Word sh_size;    = 0x0000df8c
  Elf32_Word sh_link;
  Elf32_Word sh_info;
  Elf32_Word sh_addralign;
  Elf32_Word sh_entsize;
} Elf32_Shdr;
第一个标题总是全零,第二个标题是
.data
部分。 因此,我寻找神奇的数字并填写起始地址,保存文件并将其重新加载到gdb中


现在它可以工作了

注意,我对符号表、源代码链接等不感兴趣。我可以很好地阅读ARM程序集,我只想运行一段代码。只提取二进制部分(带专有标题)。您可以使用
objcopy
从二进制文件创建对象文件;特别是
-O二进制
-j节
。与对象链接并使用Linux
mmap
memcpy
(与
dsb
dmb
isb
等齐平),然后跳转到0x52000000处的代码,在那里设置断点。可能还有很多其他方法可以做到这一点。不清楚您希望用什么环境承载gdb和代码?实际上,您可能可以通过使用链接器文件将二进制文件放置在0x52000000来避免
memcpy()
mmap
。您是只想让它单独使用
gdb
还是想使用其他工具?