通过objcopy将2进制文件作为.o中的一个段

通过objcopy将2进制文件作为.o中的一个段(.data)

然后静态链接到执行文件,可以在文件中操作2进制文件的内容(文本,图片等)

objcopy

  1. -I –input-target 输入文件的格式
  2. -O –output-target 创造输出文件的格式
  3. -B –binary-architecture 设置输出的系统架构

例如:将文本文件(这里直接拿.c代码 ascii text)生成为data.o(目标文件)的一个段

在这之前要知道自己机器的架构,应该都是x64-linux

1

objcopy -I binary -O elf64-x86-64 -B i386:x86-64 test.c data.o

  1. 查看data.o所有的section

readelf -S data.o

2

  1. 查看data.o的data段(section)

readelf -x .data data.o

3

可以看到成功将2进制文本生成为.o文件的一个section(段),而且是.data段

3. 如何在代码中使用这段内存?

​ 使用生成.o文件时生成的符号,在符号表中查看

readelf -s data.o

4

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
extern char _binary_test_c_start;
extern char _binary_test_c_end;
extern char _binary_test_c_size;

#define pp(p) printf("%p\n",p)
#define pd(d) printf("%d\n",d)
#define ps(str) printf("%s",str)

int main()
{
ps((char*)&_binary_test_c_start);//将2进制数据作为字符串输出
//查看2进制数据的长度
pd((int)((char*)&_binary_test_c_end - (char*)&_binary_test_c_start));
return 0;
}

makefile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CC		= gcc

test: test.o data.o
$(CC) -g -o $@ $^

test.o:test.c
$(CC) -c -g $< -o $@

data.o:1.in
objcopy -I binary -O elf64-x86-64 -B i386:x86-64 test.c data.o

clean:
rm -f data.o test.o test

.PHONY:test data.o

make后运行,结果输出了.data段的大小,和size data.o的结果对比一下发现二进制数据大小是正确的


_binary_object_start符号是什么数据类型?

这里原以为是指针,找了找发现不是,是数据而不是地址,因为生成前是字符,所以这里用char声明这个符号,(其实无所谓,int也行,在输出时取地址后还是被转为char*)

_binary_object_end 同上

_binary_object_size

用gdb发现其值是0,地址也不在_start_end范围内

5


[1]:<<编译链接装载>>