我使用“ld -r -b binary -o binary.o foo.jpeg”将资源嵌入到我的程序中。效果非常棒。我只是想知道为什么 int _binary_size 符号永远不会正确读取、负数或太大的数字,但在程序运行之间保持不变。 我总是必须执行 _binary_end - _binary_start,这可以完美地工作。看来它对任何人都不起作用... like here ....这是为什么?
没有理由不使用结束开始,因为它取代了大小符号,但它仍然让我好奇。
编辑:代码示例。
extern const unsigned char _binary_scna4_jpg_start;
extern const unsigned char _binary_scna4_jpg_end;
extern const int _binary_scna4_jpg_size;
int size = &_binary_scna4_jpg_end - &_binary_scna4_jpg_start;
printf("Size is %d vs %d \n", size, _binary_scna4_jpg_size);
打印:
Size is 1192071 vs -385906356
第一个数字是二进制文件的正确大小,我的所有图像都可以完美读取。
nm 的输出用于良好测量:
0000000000123087 D _binary_scna4_jpg_end
0000000000123087 A _binary_scna4_jpg_size
0000000000000000 D _binary_scna4_jpg_start
最佳答案
出现此问题的原因是 Position-Independent Executables (馅饼)。早期的可执行文件被加载到相同的内存地址(在编译/链接时确定),这导致可能的攻击,因为攻击者知道程序的特定部分位于哪个地址。因此Address Space Layout Randomization已实现。这具有副作用,即被定义为绝对地址的大小符号(_binary_scna4_jpg_size
不是整数值,它是一个“指针”,就像 _start 和 _end 一样)也会得到加载时重新定位。
如果您使用选项 -no-pie
编译代码,您可以禁用位置无关性,并且 _binary_scna4_jpg_size
将输出正确的值,因为它不会被重新定位。由于 PIE 现在默认处于打开状态,因此指针的值基本上是垃圾。如果您知道重定位内存的开头,也可以使用它,但由于您已经有了 _binary_scna4_jpg_start
和 _binary_scna4_jpg_end
,所以使用它们是一样的。
关于c - 为什么链接的二进制文件的 _size 符号不能正常工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54844677/