是否可以在命令 objcopy 的帮助下进行硬编码

Posted

技术标签:

【中文标题】是否可以在命令 objcopy 的帮助下进行硬编码【英文标题】:Is it possible to make a hardcoding with the help of the command objcopy 【发布时间】:2020-02-19 07:25:16 【问题描述】:

我在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。例如,是否可以在不调用 I/O 函数的情况下立即读取文件custom.config.o 的内容,例如openreadwrite。如果可能的话,我认为这可能会成为某种硬编码风格并避免调用 I/O 函数?

【问题讨论】:

【参考方案1】:

即使我在 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] = '\0';
  printf("config = \"%s\"\n", config);
  return 0;

因为“二进制”文件(实际上是一个文本)没有最后的'\0' 字符,所以您需要附加一个以获得正确终止的 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

【讨论】:

以上是关于是否可以在命令 objcopy 的帮助下进行硬编码的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PHP 中没有硬编码密钥的情况下进行对称加密

是否可以将数组元素与没有循环的硬编码初始化列表进行比较? [关闭]

WITH 子句可以在不使用 Select 语句的情况下具有硬编码值吗?

如何为 sde-objcopy 指定架构?

我可以在没有硬编码的情况下在 Windows 上运行的 Java 中构建 Linux 路径吗?

objcopy --gap-fill 仅用于特殊部分