在运行时确定程序段(HEADER、TEXT、CONST 等)

发布于 2024-10-27 00:24:30 字数 134 浏览 2 评论 0原文

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

我假设有一些 C 级库函数可以实现这一点,我在 mach 头中查找但找不到太多:/

提前感谢!

So i realize I can open a binary up in IDA Pro and determine where the segments start/stop. Is it possible to determine this at run-time in Cocoa?

I'm assuming there are some c-level library functions that enable this, I poked around in the mach headers but couldn't find much :/

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦中楼上月下 2024-11-03 00:24:30

Cocoa 不包含用于处理 Mach-O 文件的类。需要使用系统提供的Mach-O函数。您读对了 Mach-O 标头。

我编写了一个小程序,它接受 Mach-O 文件名作为输入并转储有关其段的信息。请注意,该程序仅处理 x86_64 架构的瘦文件(即,不是胖/通用)。

请注意,我也不会检查每个操作以及文件是否是格式正确的 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;
}

您只需为 x86_64 位编译此程序,然后针对 x86_64 Mach-O 二进制文件运行它。例如,假设您已将此程序保存为 test.c:

$ 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.

如果您需要有关如何读取 Mach-O 文件的更多示例,Apple 开源网站上的 cctools 可能是您最好的选择。您还需要阅读 Mac OS X ABI Mach-O 文件格式参考

Cocoa doesn’t include classes for handling Mach-O files. You need to use the Mach-O functions provided by the system. You were right in read the Mach-O headers.

I’ve coded a small program that accepts as input a Mach-O file name and dumps information about its segments. Note that this program deals with thin files (i.e., not fat/universal) for the x86_64 architecture only.

Note that I’m also not checking every operation and whether the file is a correctly formed Mach-O file. Doing the appropriate checks are left as an exercise to the reader.

#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;
}

You need to compile this program for x86_64 bit only and run it against a x86_64 Mach-O binary. For instance, assuming you’ve saved this program as test.c:

$ 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.

If you want more examples on how to read Mach-O files, cctools on Apple’s Open Source Web site is probably your best bet. You’ll also want to read the Mac OS X ABI Mach-O File Format Reference as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文