gpt4 book ai didi

macos - 编译用于链接 OSX 的二进制文件

转载 作者:行者123 更新时间:2023-12-01 22:10:17 31 4
gpt4 key购买 nike

我正在尝试将二进制文件编译为 MACH_O 目标文件,以便可以将其链接到 dylib 中。 dylib 是用 c/c++ 编写的。

在 Linux 上使用以下命令:ld -r -b 二进制 -o foo.o foo.bin

我在 OSX 上尝试了各种选项,但没有成功:

ld -r foo.bin -o foo.o
gives:
ld: warning: -arch not specified
ld: warning: ignoring file foo.bin, file was built for unsupported file format which is not the architecture being linked (x86_64)

创建一个空的 .o 文件

ld -arch x86_64 -r foo.bin -o foo.o 
ld: warning: ignoring file foo.bin, file was built for unsupported file format which is not the architecture being linked (x86_64)

再次创建空的 .o 文件。使用 nm 检查文件给出:nm foo.onm:无名单

二进制文件实际上是将下载到外部设备的固件。

感谢您的浏览

最佳答案

以下是与 OSX 链接器执行二进制嵌入的 Linux 链接器命令最接近的翻译:

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 将存储在 binary 段、foo_bin 部分(两个名称都是任意的,但选择模仿 GNU ld for ELF Linux) foo.o 对象。

stub 是必要的,因为 ld 拒绝仅创建自定义段/部分。如果您link directly with a real code object,则不需要它.

要从该部分取回数据,请使用 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); // whatever

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); // whatever

(我用它来存储文本数据,因此通过 calloc 大小归零 + 1 加上 blob 复制进行字符串化)

警告:自 10.7 起,ASLR 变得更强,并且与 getsect* 函数发生严重困惑,导致段错误。在调试条件下运行以重现 EXC_BAD_ACCESS (SIGSEGV) 之前,在 GDB 中将禁用 aslr 设置为关闭。人们不得不jump through inordinate hoops找到真实地址并使其再次运行。

一个simple workaround是获取偏移量和大小,打开二进制文件并直接从磁盘读取数据。这是一个工作示例:

// main.c, build with gcc -o main main.c foo.o
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <mach-o/getsect.h>

int main() {
// finding the filename of the running binary is left as an exercise to the reader
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);
}

关于macos - 编译用于链接 OSX 的二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8923097/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com