2011-03-25 29 views
2

所以我意识到我可以在IDA Pro中打开一个二进制文件,并确定段开始/停止的位置。有没有可能在Cocoa的运行时间确定这一点?在运行时确定程序段(HEADER,TEXT,CONST等)

我假设有一些C级库功能,使这一点,我在马赫头探出周围也没有找到多少:提前/

谢谢!

+0

我对你提到的框架没有经验,所以我不会更好地发布这个答案,但据我所知,这些段是由可执行文件本身的头文件决定的。如果你想在运行时找到这些信息,我认为通常阅读文件的功能应该是足够的,只需要为你使用的可执行文件格式制定一些规范,以便知道哪个字节意味着什么。 – Pyjong 2011-03-25 21:54:33

回答

10

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文件的更多例子,cctools on Apple’s Open Source Web site可能是你最好的选择。您还需要阅读Mac OS X ABI Mach-O File Format Reference