NODE *lsetlibloc(NODE *args) { NODE *arg; arg = cnv_node_to_strnode(car(args)); if (arg == UNBOUND) err_logo(BAD_DATA_UNREC, arg); else logolib = asciiz(arg); return UNBOUND; }
//------------------------------------------------------------------------ // 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; }
NODE *lseteditor(NODE *args) { NODE *arg; arg = cnv_node_to_strnode(car(args)); if (arg == UNBOUND) err_logo(BAD_DATA_UNREC, arg); else { editor = asciiz(arg); editorname = strrchr(editor, (int)'/'); if (editorname == NULL) editorname = strrchr(editor, (int)'\\'); if (editorname == NULL) editorname = strrchr(editor, (int)':'); editorname = (editorname ? editorname+1 : editor); } return UNBOUND; }
//------------------------------------------------------------------------ // process import table for one dll inline int pe_loader_t::process_import_table( linput_t *li, const peheader_t &pe, ea_t atable, ea_t ltable, pe_import_visitor_t &piv) { bool is_pe_plus = pe.is_pe_plus(); int elsize = piv.elsize = is_pe_plus ? 8 : 4; const uint64 mask = is_pe_plus ? IMP_BY_ORD64 : IMP_BY_ORD32; bool ok = true; int i; for ( i=0; ok; i++, atable += elsize ) { char buf[MAXSTR]; ea_t rva = ltable + i * elsize; if ( piv.withbase ) rva -= (uval_t)pe.imagebase(); uint32 fof = uint32(rva); uint64 entry = is_pe_plus ? vaint64(li, fof, &ok) : valong(li, fof, &ok); if ( entry == 0 ) break; showAddr(atable); int code; if( (entry & mask) == 0 ) // by name { ea_t nrva = (uval_t)entry + sizeof(short); if ( piv.withbase ) nrva -= (uval_t)pe.imagebase(); uint32 fof = uint32(nrva); asciiz(li, fof, buf, sizeof(buf), &ok); if ( !win_utf2idb(buf) ) ansi2idb(buf); code = piv.visit_import(atable, entry, buf); } else { code = piv.visit_import(atable, entry & ~mask, NULL); } if ( code != 0 ) return code; } return piv.leave_module(i); }
//------------------------------------------------------------------------ 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; }