/****************************************************************** * pe_load_native_module * */ struct module* pe_load_native_module(struct process* pcs, const WCHAR* name, HANDLE hFile, DWORD64 base, DWORD size) { struct module* module = NULL; BOOL opened = FALSE; struct module_format* modfmt; WCHAR loaded_name[MAX_PATH]; loaded_name[0] = '\0'; if (!hFile) { assert(name); if ((hFile = FindExecutableImageExW(name, pcs->search_path, loaded_name, NULL, NULL)) == NULL) return NULL; opened = TRUE; } else if (name) strcpyW(loaded_name, name); else if (dbghelp_options & SYMOPT_DEFERRED_LOADS) FIXME("Trouble ahead (no module name passed in deferred mode)\n"); if (!(modfmt = HeapAlloc(GetProcessHeap(), 0, sizeof(struct module_format) + sizeof(struct pe_module_info)))) return NULL; modfmt->u.pe_info = (struct pe_module_info*)(modfmt + 1); if (pe_map_file(hFile, &modfmt->u.pe_info->fmap, DMT_PE)) { if (!base) base = modfmt->u.pe_info->fmap.u.pe.ntheader.OptionalHeader.ImageBase; if (!size) size = modfmt->u.pe_info->fmap.u.pe.ntheader.OptionalHeader.SizeOfImage; module = module_new(pcs, loaded_name, DMT_PE, FALSE, base, size, modfmt->u.pe_info->fmap.u.pe.ntheader.FileHeader.TimeDateStamp, modfmt->u.pe_info->fmap.u.pe.ntheader.OptionalHeader.CheckSum); if (module) { modfmt->module = module; modfmt->remove = pe_module_remove; modfmt->loc_compute = NULL; module->format_info[DFI_PE] = modfmt; if (dbghelp_options & SYMOPT_DEFERRED_LOADS) module->module.SymType = SymDeferred; else pe_load_debug_info(pcs, module); module->reloc_delta = base - modfmt->u.pe_info->fmap.u.pe.ntheader.OptionalHeader.ImageBase; } else { ERR("could not load the module '%s'\n", debugstr_w(loaded_name)); pe_unmap_file(&modfmt->u.pe_info->fmap); } } if (!module) HeapFree(GetProcessHeap(), 0, modfmt); if (opened) CloseHandle(hFile); return module; }
/****************************************************************** * pe_load_native_module * */ struct module* pe_load_native_module(struct process* pcs, const WCHAR* name, HANDLE hFile, DWORD base, DWORD size) { struct module* module = NULL; BOOL opened = FALSE; HANDLE hMap; WCHAR loaded_name[MAX_PATH]; loaded_name[0] = '\0'; if (!hFile) { assert(name); if ((hFile = FindExecutableImageExW(name, pcs->search_path, loaded_name, NULL, NULL)) == NULL) return NULL; opened = TRUE; } else if (name) strcpyW(loaded_name, name); else if (dbghelp_options & SYMOPT_DEFERRED_LOADS) FIXME("Trouble ahead (no module name passed in deferred mode)\n"); if ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL) { void* mapping; if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL) { IMAGE_NT_HEADERS* nth = RtlImageNtHeader(mapping); if (nth) { if (!base) base = nth->OptionalHeader.ImageBase; if (!size) size = nth->OptionalHeader.SizeOfImage; module = module_new(pcs, loaded_name, DMT_PE, FALSE, base, size, nth->FileHeader.TimeDateStamp, nth->OptionalHeader.CheckSum); if (module) { if (dbghelp_options & SYMOPT_DEFERRED_LOADS) module->module.SymType = SymDeferred; else pe_load_debug_info(pcs, module); } else ERR("could not load the module '%s'\n", debugstr_w(loaded_name)); } UnmapViewOfFile(mapping); } CloseHandle(hMap); } if (opened) CloseHandle(hFile); return module; }
/****************************************************************** * module_get_debug * * get the debug information from a module: * - if the module's type is deferred, then force loading of debug info (and return * the module itself) * - if the module has no debug info and has an ELF container, then return the ELF * container (and also force the ELF container's debug info loading if deferred) * - otherwise return the module itself if it has some debug info */ BOOL module_get_debug(struct module_pair* pair) { IMAGEHLP_DEFERRED_SYMBOL_LOADW64 idslW64; if (!pair->requested) return FALSE; /* for a PE builtin, always get info from container */ if (!(pair->effective = module_get_container(pair->pcs, pair->requested))) pair->effective = pair->requested; /* if deferred, force loading */ if (pair->effective->module.SymType == SymDeferred) { BOOL ret; if (pair->effective->is_virtual) ret = FALSE; else switch (pair->effective->type) { #ifndef DBGHELP_STATIC_LIB case DMT_ELF: ret = elf_load_debug_info(pair->effective); break; #endif case DMT_PE: idslW64.SizeOfStruct = sizeof(idslW64); idslW64.BaseOfImage = pair->effective->module.BaseOfImage; idslW64.CheckSum = pair->effective->module.CheckSum; idslW64.TimeDateStamp = pair->effective->module.TimeDateStamp; memcpy(idslW64.FileName, pair->effective->module.ImageName, sizeof(pair->effective->module.ImageName)); idslW64.Reparse = FALSE; idslW64.hFile = INVALID_HANDLE_VALUE; pcs_callback(pair->pcs, CBA_DEFERRED_SYMBOL_LOAD_START, &idslW64); ret = pe_load_debug_info(pair->pcs, pair->effective); pcs_callback(pair->pcs, ret ? CBA_DEFERRED_SYMBOL_LOAD_COMPLETE : CBA_DEFERRED_SYMBOL_LOAD_FAILURE, &idslW64); break; #ifndef DBGHELP_STATIC_LIB case DMT_MACHO: ret = macho_load_debug_info(pair->effective); break; #endif default: ret = FALSE; break; } if (!ret) pair->effective->module.SymType = SymNone; assert(pair->effective->module.SymType != SymDeferred); pair->effective->module.NumSyms = pair->effective->ht_symbols.num_elts; } return pair->effective->module.SymType != SymNone; }
/****************************************************************** * module_get_debug * * get the debug information from a module: * - if the module's type is deferred, then force loading of debug info (and return * the module itself) * - if the module has no debug info and has an ELF container, then return the ELF * container (and also force the ELF container's debug info loading if deferred) * - otherwise return the module itself if it has some debug info */ BOOL module_get_debug(const struct process* pcs, struct module_pair* pair) { IMAGEHLP_DEFERRED_SYMBOL_LOAD64 idsl64; if (!pair->requested) return FALSE; /* for a PE builtin, always get info from container */ if (!(pair->effective = module_get_container(pcs, pair->requested))) pair->effective = pair->requested; /* if deferred, force loading */ if (pair->effective->module.SymType == SymDeferred) { BOOL ret; if (pair->effective->is_virtual) ret = FALSE; else switch (pair->effective->type) { case DMT_ELF: ret = elf_load_debug_info(pair->effective, NULL); break; case DMT_PE: idsl64.SizeOfStruct = sizeof(idsl64); idsl64.BaseOfImage = pair->effective->module.BaseOfImage; idsl64.CheckSum = pair->effective->module.CheckSum; idsl64.TimeDateStamp = pair->effective->module.TimeDateStamp; strcpy(idsl64.FileName, pair->effective->module.ImageName); idsl64.Reparse = FALSE; idsl64.hFile = INVALID_HANDLE_VALUE; pcs_callback(pcs, CBA_DEFERRED_SYMBOL_LOAD_START, &idsl64); ret = pe_load_debug_info(pcs, pair->effective); pcs_callback(pcs, ret ? CBA_DEFERRED_SYMBOL_LOAD_COMPLETE : CBA_DEFERRED_SYMBOL_LOAD_FAILURE, &idsl64); break; default: ret = FALSE; break; } if (!ret) pair->effective->module.SymType = SymNone; assert(pair->effective->module.SymType != SymDeferred); module_compute_num_syms(pair->effective); } return pair->effective->module.SymType != SymNone; }