Dưới đây là bản dịch gần nhất với lệnh linker Linux để thực hiện nhúng nhị phân với các mối liên kết 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
sẽ được lưu trữ trong phân khúc binary
, phần foo_bin
(cả hai tên là tùy ý nhưng được chọn để bắt chước GNU ld cho ELF trên Linux) của đối tượng foo.o
.
stub
là cần thiết vì ld
từ chối chỉ tạo phân đoạn/mục tùy chỉnh. Bạn không cần nó nếu bạn link directly with a real code object.
Để có được dữ liệu trở lại từ phần, sử dụng getsectbyname (struct được định nghĩa trong 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
hoặc 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
(tôi đã sử dụng nó để lưu trữ dữ liệu văn bản, vì thế mà stringification via calloc
zeroing of size + 1 plus blob copy)
Cảnh báo: Kể từ 10.7, ASLR trở nên mạnh hơn và gây rối với các chức năng getsect*
, dẫn đến các segfaults. set disable-aslr off
trong GDB trước run
ning để tái tạo EXC_BAD_ACCESS (SIGSEGV) trong điều kiện gỡ lỗi. Mọi người đã phải jump through inordinate hoops để tìm địa chỉ thực và làm cho địa chỉ này hoạt động trở lại.
A simple workaround là lấy độ lệch và kích thước, mở tệp nhị phân và đọc dữ liệu trực tiếp từ đĩa. Dưới đây là ví dụ hoạt động:
// 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);
}
bạn chỉ cần thực hiện một việc như 'ld -dylib -o libFoo.dylib fooSource * .o'. vấn đề có vẻ là với foo.bin - nếu bạn làm 'tập tin foo.bin' nó nói gì? –
Đầu ra của tệp foo.bin là: 'foo.bit: Dữ liệu BIT Xilinx - từ foo.ncd; HW_TIMEOUT = FALSE; Hệ với chúng tôi - cho 0xFFFFFFFF - được xây dựng slx16ftg256 (011/03/15) - chiều dài dữ liệu 0x31373a35' – Satpal
hmm , Tôi sợ nó không giống như LLVM clang ld hiện blob nhị phân nhúng rằng ld gnu không.bạn có thể thử cài đặt gcc từ macports (http://www.macports.org/)? không chắc chắn nếu điều đó sẽ giúp ích, nhưng có thể đáng để thử. –