int parse_lc(t_sym **sym_lst, t_sect **sect_lst, char *ptr, uint8_t mask) { int i; int ncmds; struct load_command *lc; struct mach_header *header; header = (struct mach_header *)ptr; ncmds = IS_BE(mask) ? swap_uint32(header->ncmds) : header->ncmds; swap_load_command(lc = ((void *)ptr + (IS_ARCH_64(mask) ? sizeof(struct mach_header_64) : sizeof(struct mach_header))), IS_BE(mask)); ncmds = IS_BE(mask) ? swap_uint32(header->ncmds) : header->ncmds; i = 0; while (i < ncmds) { if (lc->cmd == LC_SEGMENT_64 || lc->cmd == LC_SEGMENT) add_sect_lst(lc, sect_lst, mask); else if (lc->cmd == LC_SYMTAB) if (add_symtab_lst((struct symtab_command *)lc, ptr, sym_lst, mask) == -1) return (EXIT_FAILURE); swap_load_command(lc = (void *)lc + lc->cmdsize, IS_BE(mask)); i++; } return (0); }
void dump_segment_commands(FILE *obj_file, int offset, int is_swap, uint32_t ncmds) { int actual_offset = offset; for (int i = 0; i < ncmds; i++) { struct load_command *cmd = load_bytes(obj_file, actual_offset, sizeof(struct load_command)); if (is_swap) { swap_load_command(cmd, 0); } if (cmd->cmd == LC_SEGMENT_64) { struct segment_command_64 *segment = load_bytes(obj_file, actual_offset, sizeof(struct segment_command_64)); if (is_swap) { swap_segment_command_64(segment, 0); } printf("segname: %s\n", segment->segname); free(segment); } else if (cmd->cmd == LC_SEGMENT) { struct segment_command *segment = load_bytes(obj_file, actual_offset, sizeof(struct segment_command)); if (is_swap) { swap_segment_command(segment, 0); } printf("segname: %s\n", segment->segname); free(segment); } actual_offset += cmd->cmdsize; free(cmd); } }
boolean_t macho_unswap_32( u_char * file) { boolean_t result = FALSE; enum NXByteOrder order = 0; struct mach_header *hdr = (struct mach_header *) file; struct load_command *lc = (struct load_command *) &hdr[1]; struct segment_command *seg = NULL; u_long offset = 0; u_int i = 0; if (NXHostByteOrder() == NX_LittleEndian) { order = NX_BigEndian; } else { order = NX_LittleEndian; } if (!hdr || hdr->magic != MH_MAGIC) goto finish; offset = sizeof(*hdr); for (i = 0; i < hdr->ncmds; ++i) { lc = (struct load_command *) (file + offset); offset += lc->cmdsize; if (lc->cmd == LC_SEGMENT) { seg = (struct segment_command *) lc; swap_segment_command(seg, order); } else { swap_load_command(lc, order); } } swap_mach_header(hdr, order); result = TRUE; finish: return result; }
boolean_t macho_swap_64( u_char * file) { boolean_t result = FALSE; struct mach_header_64 *hdr = (struct mach_header_64 *) file; struct load_command *lc = (struct load_command *) &hdr[1]; struct segment_command_64 *seg = NULL; u_long offset = 0; u_int cmd = 0; u_int cmdsize = 0; u_int i = 0; if (!hdr || hdr->magic != MH_CIGAM_64) goto finish; swap_mach_header_64(hdr, NXHostByteOrder()); offset = sizeof(*hdr); for (i = 0; i < hdr->ncmds; ++i) { lc = (struct load_command *) (file + offset); cmd = OSSwapInt32(lc->cmd); cmdsize = OSSwapInt32(lc->cmdsize); offset += cmdsize; if (cmd == LC_SEGMENT_64) { seg = (struct segment_command_64 *) lc; swap_segment_command_64(seg, NXHostByteOrder()); } else { swap_load_command(lc, NXHostByteOrder()); } } result = TRUE; finish: return result; }