修复 objcopy 输出二进制文件上的 elf 段地址

问题描述 投票:0回答:1

我正在尝试将一些编译的代码注入到 elf 可执行文件中。该策略是在“代码”段的末尾写入一些字节。我选择该段的原因是因为我也需要执行我的有效负载。当段之间的填充太小时,我想将段扩展所需的量,以便它可以承载我的有效负载。

objcopy
objcopy <exec> --update-section <name>=<file>
一起就可以做到这一点。

我的主持人将是第

.fini
部分,该部分之后的部分是
.rodata
。执行 objcopy 后,代码段的文件大小和内存映像大小是正确的大小。部分和段偏移也会在需要时进行修补。并且代码出现在预期的偏移处(由
objdump
确认)。

我的问题是没有对任何段的虚拟地址进行修补,这会导致代码段与下一个段/段重叠,从而导致

_dl_start
期间出现段错误,因为代码被认为处于只读状态部分。 以下是
readelf
.

生成的输出的一些片段

在 objcopy 之前:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [16] .fini             PROGBITS         00000000000a3e84  000a3e84
       0000000000000009  0000000000000000  AX       0     0     4
  [17] .rodata           PROGBITS         00000000000a4000  000a4000
       000000000003b488  0000000000000000   A       0     0     32

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000063000 0x0000000000063000 0x0000000000063000
                 0x0000000000040e8d 0x0000000000040e8d  R E    0x1000
  LOAD           0x00000000000a4000 0x00000000000a4000 0x00000000000a4000
                 0x0000000000043ccc 0x0000000000043ccc  R      0x1000

及之后:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [16] .fini             PROGBITS         00000000000a3e84  000a3e84
       00000000000002bd  0000000000000000  AX       0     0     4
  [17] .rodata           PROGBITS         00000000000a4000  000a5000
       000000000003b488  0000000000000000   A       0     0     32

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000063000 0x0000000000063000 0x0000000000063000
                 0x0000000000041141 0x0000000000041141  R E    0x1000
  LOAD           0x00000000000a5000 0x00000000000a4000 0x00000000000a4000
                 0x0000000000043ccc 0x0000000000043ccc  R      0x1000

我的系统:

Linux 6.1.0-13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.55-1 (2023-09-29) x86_64 GNU/Linux

有人知道如何进一步修补二进制文件以使其发挥作用,同时最终仍然拥有有效的精灵吗?

code-injection elf objcopy readelf
1个回答
0
投票

有人知道如何进一步修补二进制文件以使其正常工作吗

这是行不通的——你有一个linked二进制文件,这意味着链接器已将数据地址“烘焙”到代码中。

您希望将数据移动到不同的地址,但这需要更新所有“内置”地址,并且执行此类更新所需的信息(重定位)已被丢弃。

您需要做的是添加一个new可执行段(这些段在运行时并不重要),并将您的有效负载放入该新段中。

© www.soinside.com 2019 - 2024. All rights reserved.