//-------------------------------------------------------------------------- ea_t win32_debmod_t::get_process_base(size_t size) { ea_t ea = kd.aInfo[KINX_PROCARRAY]; for ( int i=0; i < MAX_PROCESSES; i++, ea+=size ) { if ( is_ce500() ) { win500_process_t &p = *(win500_process_t*)ea; if ( p.dwVMBase == slot ) { process_objcnt = p.e32.objcnt; process_o32_ptr = p.o32_ptr; process_vbase = p.e32.vbase; return p.e32.vbase; // we always use slot 0 } } else { win420_process_t &p = *(win420_process_t*)ea; if ( p.dwVMBase == slot ) { process_objcnt = p.e32.objcnt; process_o32_ptr = p.o32_ptr; process_vbase = p.e32.vbase; return p.e32.vbase; // we always use slot 0 } } } warning("WinCE: could not find process base for slot 0x%08X", slot); return 0; }
//-------------------------------------------------------------------------- static int match_module_baseptr(wince_module_t *wm, void *ud) { ea_t base = *(ea_t *)ud; if ( is_ce500() ) { win500_module_t *w = (win500_module_t *)wm; return (ea_t)w->BasePtr == base; } else { win420_module_t *w = (win420_module_t *)wm; return (ea_t)w->BasePtr == base; } }
//-------------------------------------------------------------------------- ea_t get_process_slot(HANDLE phandle) { size_t size = is_ce500() ? sizeof(win500_process_t) : sizeof(win420_process_t); __try { ea_t ea = kd.aInfo[KINX_PROCARRAY]; for ( int i=0; i < MAX_PROCESSES; i++, ea+=size ) { win420_process_t &p = *(win420_process_t*)ea; if ( p.hProc == phandle ) return p.dwVMBase; } } __except ( EXCEPTION_EXECUTE_HANDLER ) { } warning("WinCE: could not find process slot for 0x%08X", phandle); return 0; }
//-------------------------------------------------------------------------- LPVOID win32_debmod_t::correct_exe_image_base(LPVOID base) { // we have to correct the image base for Windows CE since // the kernel returns only the slot number, not the image base if ( is_ce600() ) return base; slot = (ea_t)base; ea_t ea; __try { size_t size = is_ce500() ? sizeof(win500_process_t) : sizeof(win420_process_t); ea = get_process_base(size); } __except ( EXCEPTION_EXECUTE_HANDLER ) { } base = (LPVOID)ea; return base; }
//-------------------------------------------------------------------------- static int enumerate_modules(int (*func)(wince_module_t *wm, void *), void *ud, wince_module_t *result) { int code = 0; size_t size = is_ce500() ? sizeof(win500_module_t) : sizeof(win420_module_t); __try { KDataStruct kd; if ( !myread(KDataStructAddr, &kd, sizeof(kd)) ) return 0; ea_t ea = kd.aInfo[KINX_MODULES]; while ( ea != 0 ) { wince_module_t wm; if ( !myread(ea, &wm, size) ) return 0; code = func(&wm, ud); if ( code != 0 ) { if ( result != NULL ) memcpy(result, &wm, size); break; } win420_module_t *ptr = (win420_module_t*)&wm; ea = (ea_t)ptr->pMod; } } __except ( EXCEPTION_EXECUTE_HANDLER ) { msg("failed to obtain module list\n"); } return code; }
//-------------------------------------------------------------------------- bool win32_debmod_t::get_dll_exports( const images_t &dlls, ea_t imagebase, name_info_t &ni, const char *exported_name) { int i; wince_module_t wm; if ( !find_module(imagebase, &wm) ) return false; common_e32_lite &e32 = get_e32(&wm); petab_t *pexpdir; if ( is_ce500() ) { win500_e32_lite *e32_500 = (win500_e32_lite *)&e32; pexpdir = &e32_500->unit[E32_LITE_EXP]; } else { win420_e32_lite *e32_420 = (win420_e32_lite *)&e32; pexpdir = &e32_420->unit[E32_LITE_EXP]; } petab_t &expdir = *pexpdir; if ( expdir.size <= 0 ) return false; // calculate the export directory address ea_t o32_ptr = (ea_t)get_o32_ptr(&wm); ea_t exp_ea = BADADDR; // no memory or bad object count o32_lite *ao32 = new o32_lite[e32.objcnt]; if ( ao32 == NULL ) return false; if ( myread(o32_ptr, ao32, e32.objcnt * sizeof(o32_lite)) ) { for ( i=0; i < e32.objcnt; i++ ) { o32_lite &o32 = ao32[i]; if ( expdir.rva >= o32.rva && expdir.rva+expdir.size <= o32.rva+o32.vsize ) exp_ea = o32.realaddr + (expdir.rva - o32.rva); } } delete [] ao32; if ( exp_ea == BADADDR ) return false; // read export section uchar *data = new uchar[expdir.size]; if ( data == NULL ) return false; bool ok = false; const uint32 *end = (const uint32 *)(data + expdir.size); if ( myread(exp_ea, data, expdir.size) ) { peexpdir_t &ed = *(peexpdir_t *)data; char *dllname = (char *)data + ed.dllname - expdir.rva; if ( dllname < (char *)data || dllname >= (char*)end ) dllname = ""; char *dot = strrchr(dllname, '.'); if ( dot != NULL ) *dot = '\0'; const uint32 *names = (const uint32 *)(data + ed.namtab - expdir.rva); const uint16 *ords = (const uint16 *)(data + ed.ordtab - expdir.rva); const uint32 *addrs = (const uint32 *)(data + ed.adrtab - expdir.rva); if ( names < end && (uint32*)ords < end && addrs < end ) { // ordinals -> names typedef std::map<int, qstring> expfunc_t; expfunc_t funcs; for ( i=0; i < ed.nnames; i++ ) { const char *name = (char*)data + names[i] - expdir.rva; if ( name >= (char*)data && name < (char*)end ) funcs.insert(make_pair(ed.ordbase + ords[i], qstring(name))); } for ( i=0; i < ed.naddrs; i++ ) { char buf[MAXSTR]; uint32 adr = addrs[i]; if ( adr == 0 ) continue; int ord = ed.ordbase + i; ea_t fulladdr = imagebase + adr; expfunc_t::iterator p = funcs.find(ord); if ( p != funcs.end() ) qsnprintf(buf, sizeof(buf), "%s_%s", dllname, p->second.c_str()); else qsnprintf(buf, sizeof(buf), "%s_%d", dllname, ord); ni.addrs.push_back(fulladdr); ni.names.push_back(qstrdup(buf)); ok = true; } } } delete [] data; return ok; }