这是最接近Linux链接器命令的翻译,用于执行二进制嵌入到OSX链接器中:
touch stub.c
gcc -o stub.o -c stub.c
ld -r -o foo.o -sectcreate binary foo_bin foo.bin stub.o
foo.bin
将被存储在foo.o
对象的段binary
、节foo_bin
中(这些名称是任意选择的,但被选为模仿Linux上ELF的GNU ld)。
stub
是必需的,因为ld
拒绝创建仅自定义段/节。如果您直接链接真正的代码对象,则不需要它。
要从节中获取数据,请使用getsectbyname(结构体在mach-o/loader.h
中定义):
#include <mach-o/getsect.h>
const struct section_64 *sect = getsectbyname("binary", "foo_bin");
char *buffer = calloc(1, sect->size+1);
memcpy(buffer, sect->addr, sect->size);
或getsectdata:
#include <mach-o/getsect.h>
size_t size;
char *data = getsectdata("binary", "foo_bin", &size);
char *buffer = calloc(1, size+1);
memcpy(buffer, data, size);
(我将其用于存储文本数据,因此通过 calloc
的字符串化,可将大小加1并复制块)
警告:自10.7以来,ASLR变得更加强大,并且与 getsect*
函数混淆在一起,导致段错误。在 run
之前,在GDB中 set disable-aslr off
以在调试条件下重现EXC_BAD_ACCESS(SIGSEGV)。人们不得不费尽周折才能找到真正的地址并再次使其正常工作。
一个简单的解决方法是获取偏移量和大小,打开二进制文件并直接从磁盘读取数据。以下是一个可工作的示例:
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <mach-o/getsect.h>
int main() {
char *filename = "main";
const struct section_64 *sect = getsectbyname("binary", "foo_bin");
if (sect == NULL) {
exit(1);
}
char *buffer = calloc(1, sect->size+1);
int fd = open(filename, O_RDONLY);
if (fd < 0) {
exit(1);
}
lseek(fd, sect->offset, SEEK_SET);
if (read(fd, buffer, sect->size) != sect->size) {
close(fd);
exit(1);
}
printf("%s", buffer);
}
ld -dylib -o libFoo.dylib fooSource*.o
的操作。问题似乎出在 foo.bin 上 - 如果你执行file foo.bin
呢?它会显示什么? - Mike Kfoo.bit:Xilinx BIT数据 - 来自foo.ncd;HW_TIMEOUT=FALSE;Us - 用于0xFFFFFFFF - 构建slx16ftg256(011/03/15) - 数据长度0x31373a35
- Satpal