Cocoa 在运行时确定程序段(头、文本、常量等)

Cocoa 在运行时确定程序段(头、文本、常量等),cocoa,xcode,assembly,reverse-engineering,Cocoa,Xcode,Assembly,Reverse Engineering,因此,我意识到我可以在IDA Pro中打开一个二进制文件,并确定段的开始/停止位置。是否可以在Cocoa中的运行时确定这一点 我假设有一些c级库函数可以实现这一点,我翻遍了马赫数标题,但找不到太多:/ 提前谢谢 Cocoa不包括处理Mach-O文件的类。您需要使用系统提供的Mach-O功能。你读到马赫-奥标题是对的 我编写了一个小程序,它接受Mach-O文件名作为输入,并转储有关其段的信息。请注意,此程序仅处理x86_64体系结构的精简文件(即非fat/universal) 请注意,我也没有检查

因此,我意识到我可以在IDA Pro中打开一个二进制文件,并确定段的开始/停止位置。是否可以在Cocoa中的运行时确定这一点

我假设有一些c级库函数可以实现这一点,我翻遍了马赫数标题,但找不到太多:/


提前谢谢

Cocoa不包括处理Mach-O文件的类。您需要使用系统提供的Mach-O功能。你读到马赫-奥标题是对的

我编写了一个小程序,它接受Mach-O文件名作为输入,并转储有关其段的信息。请注意,此程序仅处理x86_64体系结构的精简文件(即非fat/universal)

请注意,我也没有检查每个操作,也没有检查文件是否是正确格式的Mach-O文件。做适当的检查留给读者作为练习

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <mach-o/loader.h>
#include <sys/mman.h>
#include <sys/stat.h>

int main(int argc, char *argv[]) {
    int fd;
    struct stat stat_buf;
    size_t size;

    char *addr = NULL;
    struct mach_header_64 *mh;
    struct load_command *lc;
    struct segment_command_64 *sc;

    // Open the file and get its size
    fd = open(argv[1], O_RDONLY);
    fstat(fd, &stat_buf);
    size = stat_buf.st_size;

    // Map the file to memory
    addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_PRIVATE, fd, 0);

    // The first bytes of a Mach-O file comprise its header
    mh = (struct mach_header_64 *)addr;

    // Load commands follow the header
    addr += sizeof(struct mach_header_64);

    printf("There are %d load commands\n", mh->ncmds);

    for (int i = 0; i < mh->ncmds; i++) {
        lc = (struct load_command *)addr;

        if (lc->cmdsize == 0) continue;

        // If the load command is a (64-bit) segment,
        // print information about the segment
        if (lc->cmd == LC_SEGMENT_64) {
            sc = (struct segment_command_64 *)addr;
            printf("Segment %s\n\t"
                "vmaddr 0x%llx\n\t"
                "vmsize 0x%llx\n\t"
                "fileoff %llu\n\t"
                "filesize %llu\n",
                sc->segname,
                sc->vmaddr,
                sc->vmsize,
                sc->fileoff,
                sc->filesize);
        }

        // Advance to the next load command    
        addr += lc->cmdsize;
    }

    printf("\nDone.\n");

    munmap(addr, size);
    close(fd);

    return 0;
}

如果你想要更多关于如何读取Mach-O文件的例子,这可能是你最好的选择。您还需要阅读。

我对您提到的框架没有任何经验,因此我最好不要将此作为答案发布,但据我所知,这些段是由可执行文件本身的头决定的。如果您想在运行时找到这些信息,我认为读取文件的常规功能应该足够了,只需为您正在使用的可执行文件格式制定一些规范,这样您就知道哪个字节是什么意思了。
$ clang test.c -arch x86_64 -o test
$ ./test ./test
There are 11 load commands
Segment __PAGEZERO
    vmaddr 0x0
    vmsize 0x100000000
    fileoff 0
    filesize 0
Segment __TEXT
    vmaddr 0x100000000
    vmsize 0x1000
    fileoff 0
    filesize 4096
Segment __DATA
    vmaddr 0x100001000
    vmsize 0x1000
    fileoff 4096
    filesize 4096
Segment __LINKEDIT
    vmaddr 0x100002000
    vmsize 0x1000
    fileoff 8192
    filesize 624

Done.