int otool_segment_64(t_file_info *file_info, size_t cmd_offset) { struct segment_command_64 *seg; seg = file_info->data + cmd_offset; file_info->segment_command_64[file_info->nb_segment_cmd] = *seg; file_info->nb_segment_cmd++; process_sections(file_info, seg, cmd_offset); return (SUCCESS); }
//------------------------------------------------------------------------ // process all imports of a pe file // returns: -1:could not read an impdir; 0-ok; // other values can be returned by the visitor inline int pe_loader_t::process_imports(linput_t *li, pe_import_visitor_t &piv) { if ( pe.impdir.rva == 0 ) return 0; if ( transvec.empty() ) process_sections(li); int code = 0; bool is_memory_linput = get_linput_type(li) == LINPUT_PROCMEM; for ( int ni=0; ; ni++ ) { off_t off = pe.impdir.rva + ni*sizeof(peimpdir_t); peimpdir_t &id = piv.id; if ( !vmread(li, off, &id, sizeof(id)) ) { int code = piv.impdesc_error(off); if ( code != 0 ) break; // we continue if the import descriptor is within the page belonging // to the program if ( !is_memory_linput ) { uint32 fsize = pe.align_up_in_file(qlsize(li)); if ( map_ea(off)+sizeof(id) > fsize ) return -1; } } if ( id.dllname == 0 && id.table1 == 0 ) break; ea_t ltable = id.table1; //OriginalFirstThunk ea_t atable = id.looktab; //FirstThunk bool ok = true; char dll[MAXSTR]; asciiz(li, id.dllname, dll, sizeof(dll), &ok); if ( !ok || dll[0] == '\0' ) break; ansi2idb(dll); if ( !is_memory_linput && (map_ea(ltable) == BADADDR || ltable < pe.hdrsize) ) ltable = atable; atable += get_imagebase(); int code = piv.visit_module(dll, atable, ltable); if ( code != 0 ) break; code = process_import_table(li, pe, atable, ltable, piv); if ( code != 0 ) break; } return code; }
//------------------------------------------------------------------------ inline int pe_loader_t::process_delayed_imports(linput_t *li, pe_import_visitor_t &il) { if ( pe.didtab.rva == 0 ) return 0; if ( transvec.empty() ) process_sections(li); int code = 0; uint32 ni = 0; bool ok = true; while ( true ) { uint32 table = pe.didtab.rva + ni*uint32(sizeof(dimpdir_t)); if ( !vseek(li, table) ) break; dimpdir_t &id = il.did; lread(li, &id, sizeof(id)); if ( !id.dllname ) break; il.withbase = (id.attrs & DIMP_NOBASE) == 0; uval_t base = il.withbase ? 0 : uval_t(get_imagebase()); ea_t atable = id.diat + base; ea_t ltable = id.dint; char dll[MAXSTR]; uint32 off = uint32(il.withbase ? id.dllname - (ea_t)pe.imagebase() : id.dllname); asciiz(li, off, dll, sizeof(dll), &ok); if ( !ok ) break; ansi2idb(dll); code = il.visit_module(dll, atable, ltable); if ( code != 0 ) break; code = process_import_table(li, pe, atable, ltable, il); if ( code != 0 ) break; ni++; } return ok || code != 0 ? code : -1; }
//------------------------------------------------------------------------ // process all exports of a pe file // returns -2: could not read expdir, -1: other read errors, 0-ok, // other values can be returned by the visitor inline int pe_loader_t::process_exports(linput_t *li, pe_export_visitor_t &pev) { if ( pe.expdir.rva == 0 ) return 0; if ( transvec.empty() ) process_sections(li); if ( !vseek(li, pe.expdir.rva) ) return -2; // process export directory bool ok = true; char buf[MAXSTR]; peexpdir_t ed; lread(li, &ed, sizeof(ed)); asciiz(li, ed.dllname, buf, sizeof(buf), &ok); ansi2idb(buf); int code = pev.visit_expdir(ed, buf); if ( code != 0 ) return code; // gather name information typedef std::map<int, qstring> names_t; names_t names; for ( uint32 i=0; i < ed.nnames && ok; i++ ) { ushort ord = ushort(vashort(li, ed.ordtab + i*sizeof(ushort), &ok) + ed.ordbase); uint32 rva = valong(li, ed.namtab + i*sizeof(uint32), &ok); asciiz(li, rva, buf, sizeof(buf), &ok); if ( !win_utf2idb(buf) ) ansi2idb(buf); names[ord] = buf; } // visit all exports uint32 expdir_start_rva = pe.expdir.rva; uint32 expdir_end_rva = pe.expdir.rva+pe.expdir.size; for ( uint32 i=0; i < ed.naddrs && ok; i++ ) { uint32 rva = valong(li, ed.adrtab + i*sizeof(uint32), &ok); if ( rva != 0 && ok ) { uint32 ord = i + ed.ordbase; names_t::iterator p = names.find(ord); const char *name = p != names.end() ? p->second.c_str() : ""; const char *forwarder = NULL; if ( rva >= expdir_start_rva && rva < expdir_end_rva ) { asciiz(li, rva, buf, sizeof(buf), &ok); char* p = strrchr(buf, '.'); if ( p != NULL ) *p = '\0'; ansi2idb(buf); if ( p != NULL ) { *p++ = '.'; if ( !win_utf2idb(p) ) ansi2idb(p); } forwarder = buf; } int code = pev.visit_export(rva, ord, name, forwarder); if ( code != 0 ) return code; } } return ok ? 0 : -1; }
//------------------------------------------------------------------------ inline int pe_loader_t::process_sections(linput_t *li) { pe_section_visitor_t v; return process_sections(li, v); }
//------------------------------------------------------------------------ inline int pe_loader_t::process_sections(linput_t *li, pe_section_visitor_t &psv) { off_t first_sec_pos = pe.first_section_pos(peoff); return process_sections(li, first_sec_pos, pe.nobjs, psv); }