テスト

extern struct mach_header_t _mh_execute_header;

@implementation TaskAccess(MachO)
+ (vm_address_t)defaultMachHeaderOffset
{
    return (vm_address_t)&_mh_execute_header;
}

- (vm_address_t)addressForSymbolNamed:(NSString *)aName
{
    vm_address_t base = [[self class] defaultMachHeaderOffset];
    vm_address_t ptr;
    int vmoffset = base;
    struct mach_header mh;
    unsigned long ncmds;
    struct load_command cmd;
    const char *nameAsCString = [aName cString];


    // get mach_header at first
    mh = *(struct mach_header *)[[self dataWithAddress:base length:sizeof(struct mach_header)] bytes];
    ncmds = mh.ncmds;

    // find SYMTAB in load commands
    ptr = base + sizeof(struct mach_header);
    while(ncmds--) {
        cmd = *(struct load_command *)[[self dataWithAddress:ptr length:sizeof(struct load_command)] ytes];
        if (cmd.cmd == LC_SEGMENT) {
            struct segment_command seg_cmd = *(struct segment_command *)[[self dataWithAddress:ptr ength:sizeof(struct segment_command)] bytes];
            if (!strcmp(seg_cmd.segname, "__LINKEDIT")) {
                vmoffset = seg_cmd.vmaddr - seg_cmd.fileoff;
            }
        } else if (cmd.cmd == LC_SYMTAB) {
            struct symtab_command sym_cmd = *(struct symtab_command *)[[self dataWithAddress:ptr length:sizeof(struct symtab_command)] bytes];
            const char *sym;
            struct nlist *nl_ptr = NULL;
            int nsyms;
            nsyms = sym_cmd.nsyms;
            nl_ptr = (struct nlist *)[[self dataWithAddress:vmoffset + sym_cmd.symoff length:sym_cmd.nsyms * sizeof(struct nlist)] bytes];
            sym = [[self dataWithAddress:vmoffset + sym_cmd.stroff length:sym_cmd.strsize] bytes];

            while(nsyms--){
                const char *name;
                if (! nl_ptr) {
                   break;
                }
                if (! nl_ptr->n_un.n_strx) {
                    // null named symbol
                    nl_ptr++;
                    continue;
                }
                name = sym + nl_ptr->n_un.n_strx;
                if (!strcmp(name, nameAsCString)) {
                    // hit
                    return (vm_address_t)nl_ptr->n_value;
                }
                nl_ptr++;
            }
        }
        ptr += cmd.cmdsize;
    }
    return 0;
}

@end

selfとか@implementationは判別されるらしい