从二进制文件中提取数组数据的正确方法
Correct way to extract array data from binary?
有一种经典的方法可以将资源文件作为C语言数组嵌入二进制文件中,这样我们就可以将一些外部资源文件(如.jpeg
或.txt
文件)存储到二进制文件中。
例如,在头文件中,我们可以定义一个数组:
const unsigned char xd_data[] = {
77,90,144,0,3,0,0,0,4,0,0,0,255,255,0,0,184,0,0,0,0,0,0,0,64,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240,0,0,
0,14,31,186,14,0,180,9,205,33,184,1,76,205,33,84,104,105,115,32,112,114,
111,103,114,97,109,32,99,97,110,110,111,116,32,98,101,32,114,117,110,
32,105,110,32,68,79,83,32,109,111,100,101,46,13,13,10,36,0,0,0,0,0,0,
0,66,163,223,218,6,194,177,137,6,194,177,137,6,194,177,137,105,221,187,
137,13,194,177,137,133,222,191,137,3,194,177,137,105,221,181,137,4,194,
177,137,136,202,238,137,4,194,177,137,6,194,176,137,73,194,177,137,133,
202,236,137,13,194,177,137,48,228,187,137,11,194,177,137,193,196,183,
137,7,194,177,137,82,105,99,104,6,194,177,137,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,80,69,0,0,76,1,4,0,65,162,32,86,0,0,0,0,0,0,0,
0,224,0,47,1,11,1,6,0,0,100,0,0,0,74,0,0,0,0,0,0,228,113,0,0,0,16,0,0,
0,128,0,0,0,0,64,0,0,16,0,0,0,2,0,0,4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,
224,0,0,0,4,0,0,0,0,0,0,2,0,0,0,0,0,16,0,0,16,0,0,0,0,16,0,0,16,0,0,0,
0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,124,140,0,0,140,0,0,0,0,208,0,0,0,16,0
};
它包含资源文件的内容,并将被编译成最终的二进制文件。
网上有很多关于这个老把戏的工具和教程,比如:http://www.rowleydownload.co.uk/arm/documentation/index.htm?http://www.rowleydownload.co.uk/arm/documentation/embed.htm,https://www.fourmilab.ch/xd/和http://gareus.org/wiki/embedding_resources_in_executables#c_include_method.
然而,看起来这些页面中的大多数都在讨论如何使用C样式数组将数据嵌入到二进制文件中。
我的问题是,在编译的二进制文件中找到资源文件的起始地址以便提取它们的正确方法是什么?即,如何在编译后的二进制文件中找到xd_data
的起始地址?
如果您的意思是在文件中查找数据块启动的字节地址,就像objdump
一样,但以编程方式启动,那么您可以使用二进制文件描述符库(BFD),请参阅此处和此处。
如果你存储了数据,例如图像,并且你想加载它(用于打印或任何你想要的),那么如果你有一个从内存加载它的函数(库),例如void loadResImage(void * mem);
,只做loadResImage(xd_data)
,如果没有,但你有一种从文件加载它的功能,在这种情况下,将它保存到临时文件中,例如:
int fd=open("tmpfile");
int ret=write(fd,xd_data, sizeof(xd_data));
close(fd);
loadImageFile("tmpfile");
但是,如果您想访问程序本身之外的数据(例如,十六进制编辑器或其他程序),在这种情况下,您必须添加一个开始标记和一个结束标记或数据大小。例如:
const unsigned char xd_data[]={
...
'M','A','G','I','C'};
在上面的例子中,数据的末尾是已知的,你只需要做一个搜索就可以找到它。同样的方法,四处寻找合适的方法来存储数据的大小。但要注意编译器的优化。
- 通过JNI传递数据数组的最快方法是什么
- 如何使用curlpp通过POST方法上传文件和json数据
- 有哪些有效的方法可以消除一组 100 万个字符串>重复数据?
- 拥有映射的现代方法,该映射可以指向或引用已在堆栈上分配的不同类型的数据
- 将线程中的数据存储到全局容器的最佳方法?
- 将复杂的非基元C++数据类型转换为 Erlang/Elixir 格式,以使用 NIF 导出方法
- 在C++中查找像素 RGB 数据的最快方法是什么?
- 构造智能点数据类型以及普通数据类型的通用方法
- 将传入的网络"char*"数据转换为"uint8_t"并返回的安全方法是什么?
- 读取大文件(>2GB)(文本文件包含以太网数据)并通过不同参数随机访问数据的最佳方法是什么?
- 在 c++ 中解析数据包数据的最佳方法是什么?
- 处理编译器关于可能丢失数据的警告的最优雅方法是什么
- 创建异构顶点数据数组的可移植方法
- 使用 memcpy 将矢量数据复制到 wstring 的正确方法
- 在 std::vector<无符号字符中存储任意数据的方法>
- 在C++事务之间存储大量字符数据的有效方法
- 学习数据结构和算法的简单方法
- C++中的多维数据集:从 std::vector 的 2D 数据到 std::vector 的 2D 网格的最干净方法?
- C++ 使用派生类方法更改基类数据成员
- 类方法 - 数据结构中 For 循环的运行时错误