テスト
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は判別されるらしい