是否可以借助命令 objcopy 进行硬编码

Is it possible to make a hardcoding with the help of the command objcopy

我正在 Linux 工作,我刚刚听说有一个命令 objcopy,我在我的 x86_64 PC 上找到了相关命令:x86_64-linux-gnu-objcopy.

在它的帮助下,我可以将文件转换为 obj 文件:x86_64-linux-gnu-objcopy -I binary -O elf64-x86-64 custom.config custom.config.o

文件 custom.config 是人类可读的文件。它包含两行:

name titi
password 123

现在我可以执行objdump -x -s custom.config.o查看它的信息了

custom.config.o:     file format elf64-little
custom.config.o
architecture: UNKNOWN!, flags 0x00000010:
HAS_SYMS
start address 0x0000000000000000

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .data         00000017  0000000000000000  0000000000000000  00000040  2**0
                  CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
0000000000000000 l    d  .data  0000000000000000 .data
0000000000000000 g       .data  0000000000000000 _binary_custom_config_start
0000000000000017 g       .data  0000000000000000 _binary_custom_config_end
0000000000000017 g       *ABS*  0000000000000000 _binary_custom_config_size


Contents of section .data:
 0000 6e616d65 20746974 690a7061 7373776f  name titi.passwo
 0010 72642031 32330a                      rd 123.

众所周知,我们可以在任何C/C++项目中打开、读取或写入文件,例如custom.config。现在,我在考虑是否可以在 C/C++ 项目中立即使用此 obj 文件 custom.config.o。比如,是否可以不调用openreadwrite等I/O函数,直接读取文件custom.config.o的内容。如果可能的话,我认为这可能会变成某种硬编码风格并避免调用 I/O 函数?

即使我在 Win10 上用 MinGW(MinGW-W64 项目,GCC 8.1.0)试过这个,这对你来说应该只需要很小的调整。

正如您从 objdump 给您的信息中看到的那样,文件的内容位于 .data 部分,该部分是非常量变量的公共部分。

并为它定义了一些符号。您可以在 C 源代码中声明这些符号。

绝对值_binary_custom_config_size比较特殊,因为它被标记为*ABS*。目前,除了声明任何类型的变量并获取其地址之外,我不知道还有什么其他方法可以获取它的值。

这是我的 show_config.c:

#include <stdio.h>
#include <string.h>

extern const char _binary_custom_config_start[];
extern const char _binary_custom_config_size;

int main(void) {
  size_t size = (size_t)&_binary_custom_config_size;
  char config[size + 1];
  strncpy(config, _binary_custom_config_start, size);
  config[size] = '[=10=]';
  printf("config = \"%s\"\n", config);
  return 0;
}

因为 "binary" 文件(实际上是一个文本)没有最终的 '[=18=]' 字符,您需要追加一个字符才能获得正确终止的 C 字符串。

您也可以声明 _binary_custom_config_end 并使用它来计算大小,或作为限制。

构建一切都是这样的(我使用 -g 选项进行调试):

$ objcopy -I binary -O elf64-x86-64 -B i386 custom.config custom.config.o
$ gcc -Wall -Wextra -pedantic -g show_config.c custom.config.o -o show_config

并且输出显示成功:

$ show_config.exe
config = "name titi
password 123"

如果您需要其他部分中的文件内容,您将添加选项以将部分重命名为 objcopy 的调用。添加您需要的任何标志,示例显示用于只读数据的 .rodata

--rename-section .data=.rodata,alloc,load,readonly,data,contents