/*********************************************************************** * SymLoadModuleEx (DBGHELP.@) */ DWORD64 WINAPI SymLoadModuleEx(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD DllSize, PMODLOAD_DATA Data, DWORD Flags) { TRACE("(%p %p %s %s %s %08lx %p %08lx)\n", hProcess, hFile, debugstr_a(ImageName), debugstr_a(ModuleName), wine_dbgstr_longlong(BaseOfDll), DllSize, Data, Flags); if (Data) FIXME("Unsupported load data parameter %p for %s\n", Data, ImageName); if (!validate_addr64(BaseOfDll)) return FALSE; if (Flags & SLMFLAG_VIRTUAL) { struct process* pcs = process_find_by_handle(hProcess); struct module* module; if (!pcs) return FALSE; module = module_new(pcs, ImageName, module_get_type_by_name(ImageName), TRUE, (DWORD)BaseOfDll, DllSize, 0, 0); if (!module) return FALSE; if (ModuleName) lstrcpynA(module->module.ModuleName, ModuleName, sizeof(module->module.ModuleName)); module->module.SymType = SymVirtual; return TRUE; } if (Flags & ~(SLMFLAG_VIRTUAL)) FIXME("Unsupported Flags %08lx for %s\n", Flags, ImageName); return SymLoadModule(hProcess, hFile, (char*)ImageName, (char*)ModuleName, (DWORD)BaseOfDll, DllSize); }
t_module *mode_module_add(t_mode *mode,char *name,void *data) { int is_free=1; t_link *link; if(mode->modules->first) { for(link=mode->modules->first;link;link=link->next) { t_module *module=link->data; if(is(module->name,"name")) { printf("module %s exists\n",name); is_free=0; } } } if(is_free) { t_module *module=module_new(name,data); lst_add(mode->modules,module,module->name); return module; } else { return NULL; } }
/** * @since 2016-11-20 */ Object tm_load_module(Object file, Object code, Object name) { Object mod = module_new(file, name, code); Object fnc = func_new(mod, NONE_OBJECT, NULL); GET_FUNCTION(fnc)->code = (unsigned char*) GET_STR(code); GET_FUNCTION(fnc)->name = string_new("#main"); call_function(fnc); return GET_MODULE(mod)->globals; }
/****************************************************************** * 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_t *module_load_file(const char *File, const char *Type) { struct stat Stat[1]; if (stat(File, Stat)) return 0; module_t *Module = module_new(File); if (Type) { module_loader_t *Loader = module_get_loader(Type); if (Loader == 0) { log_errorf("Error: loader %s not found.\n", Type); } else { if (Loader->Load(Module->Providers, File)) return Module; }; } else { for (module_loader_t *Loader = ModuleLoaders; Loader; Loader = Loader->Next) { if (Loader->Load(Module->Providers, File)) return Module; }; }; return 0; };
/****************************************************************** * pe_load_builtin_module * */ struct module* pe_load_builtin_module(struct process* pcs, const WCHAR* name, DWORD64 base, DWORD64 size) { struct module* module = NULL; if (base && pcs->dbg_hdr_addr) { IMAGE_NT_HEADERS nth; if (pe_load_nt_header(pcs->handle, base, &nth)) { if (!size) size = nth.OptionalHeader.SizeOfImage; module = module_new(pcs, name, DMT_PE, FALSE, base, size, nth.FileHeader.TimeDateStamp, nth.OptionalHeader.CheckSum); } } return module; }
bool module_load(const char *path) { Module *module; ModuleInfo *moduleInfo; module = module_new(); module->Path = StrDup(path); if(uv_dlopen(path, &module->handle) < 0) { module_free(module); return false; } if(uv_dlsym(&module->handle, "ModuleInfoPtr", (void **)&moduleInfo) < 0) { module_free(module); return false; } if(moduleInfo == NULL) { module_free(module); return false; } if(moduleInfo->Load != NULL) { moduleInfo->Load(); } vector_push_back(ModuleList, module); return true; }
void module_init(void) { module_t *Module = module_new("Riva/Module"); module_add_alias(Module, "library:/Riva/Module"); module_export(Module, "_load", 0, module_load); module_export(Module, "_refresh", 0, module_refresh); module_export(Module, "_load_file", 0, module_load_file); module_export(Module, "_get_path", 0, module_get_path); module_export(Module, "_get_name", 0, module_get_name); module_export(Module, "_import", 0, module_import); module_export(Module, "_lookup", 0, module_lookup); module_export(Module, "_suggest", 0, module_suggest); module_export(Module, "_new", 0, module_new); module_export(Module, "_add_alias", 0, module_add_alias); module_export(Module, "_set_path", 0, module_set_path); module_export(Module, "_export", 0, module_export); module_export(Module, "_add_directory", 0, module_add_directory); module_export(Module, "_add_loader", 0, module_add_loader); module_export(Module, "_set_import_func", 0, module_importer_set); module_export(Module, "_set_suggest_func", 0, module_suggest_set); module_export(Module, "_get_default_provider", 0, module_get_default_provider); module_export(Module, "_set_version", 0, module_set_version); module_export(Module, "_get_version", 0, module_get_version); module_export(Module, "_load_symbol", 0, module_load_symbol); };
int blue_main(int argc, char **argv){ int arg_index; int mode=0; char * filename = NULL; char * output_filename = NULL; /* Not enough arguments */ if (argc < 2 ) usage(); Global = malloc(sizeof(struct Global)); if ( ! Global){ printf("Out of Memory\n"); exit(1); } Global->dbg_status = 0; /* handle arguments to blue */ for (arg_index=1; arg_index<argc ; arg_index++){ if (argv[arg_index][0] == '-'){ /* disassemble and quit*/ if ( strcmp(argv[arg_index], "-d")==0 ) mode = 1; else if ( strcmp(argv[arg_index], "-c")==0 ) mode = 2; else if ( strcmp(argv[arg_index], "-g")==0 ) Global->dbg_status = 1; else if ( strcmp(argv[arg_index], "-o")==0 ){ arg_index++; output_filename = argv[arg_index]; } else if ( strcmp(argv[arg_index], "-s")==0 ){ mode = 3 ; } else if ( strcmp(argv[arg_index], "-a")==0 ){ mode = 4 ; } if (argc <3) return 0; }else{ filename = argv[arg_index]; break; } } /* Initialization routines */ global_init(); link_setThreadState(0); // turn multi-threading off until needed if (mode==1){ /* DISASSEMBLE */ Link module = create_module_filename(filename); string_t code = disassemble(module->value.module->bytecode); string_fprint(code , stdout); exit(0); } else if (mode == 2){ /* COMPILE */ Link module = create_module_filename(filename); module_save( module, output_filename ? output_filename : "blue.blx"); exit(0); }else if (mode == 3){ /* COMPILE TO ASSEMBLY CODE */ char * acode = compile_file( filename); if ( memcmp( acode, "ERR:",4) ==0 ){ printf( acode+4); exit(0); } if (output_filename){ FILE * fp = fopen( output_filename,"wb"); fprintf(fp,acode); fclose(fp); }else{ printf(acode); } free(acode); exit(0); }else if (mode == 4){ /* ASSEMBLE THS ASSEMBLY CODE TO BYTECODE */ char * acode = file_load(filename); if ( memcmp( acode, "ERR:",4) ==0 ){ printf( acode+4); exit(0); } Bytes bytes = assemble( acode ); if (output_filename){ bytes_save(bytes, output_filename); }else{ bytes_save(bytes, "out.blx"); } free(acode); exit(0); } /* Add arguments from call to this application */ Link Arg = array_new(argc-arg_index); Link * Argv = array_getArray(Arg); Link a = NULL; int c = 0; for(c=0; c <argc-arg_index; c++){ a = create_string_str( string_new((argv+arg_index)[c]) ); Argv[c] =a; } /* creates and runs the module */ Link main_ret = module_new(filename, Arg); link_free(Arg); if (main_ret){ showBacktrace(main_ret); link_free(main_ret); } fflush(stdout); fflush(stderr); exit(0); return 0; }
/****************************************************************** * macho_load_file * * Loads the information for Mach-O module stored in 'filename'. * The module has been loaded at 'load_addr' address. * returns * FALSE if the file cannot be found/opened or if the file doesn't * contain symbolic info (or this info cannot be read or parsed) * TRUE on success */ static BOOL macho_load_file(struct process* pcs, const WCHAR* filename, unsigned long load_addr, struct macho_info* macho_info) { BOOL ret = TRUE; struct macho_file_map fmap; TRACE("(%p/%p, %s, 0x%08lx, %p/0x%08x)\n", pcs, pcs->handle, debugstr_w(filename), load_addr, macho_info, macho_info->flags); if (!macho_map_file(filename, &fmap)) return FALSE; /* Find the dynamic loader's table of images loaded into the process. */ if (macho_info->flags & MACHO_INFO_DEBUG_HEADER) { static void* dyld_all_image_infos_addr; /* This symbol should be in the same place in all processes. */ if (!dyld_all_image_infos_addr) { struct nlist nl[2]; memset(nl, 0, sizeof(nl)); nl[0].n_un.n_name = (char*)"_dyld_all_image_infos"; if (!nlist("/usr/lib/dyld", nl)) dyld_all_image_infos_addr = (void*)nl[0].n_value; } if (dyld_all_image_infos_addr) macho_info->dbg_hdr_addr = (unsigned long)dyld_all_image_infos_addr; else ret = FALSE; TRACE("dbg_hdr_addr = 0x%08lx\n", macho_info->dbg_hdr_addr); } if (macho_info->flags & MACHO_INFO_MODULE) { struct macho_module_info *macho_module_info; struct module_format* modfmt = HeapAlloc(GetProcessHeap(), 0, sizeof(struct module_format) + sizeof(struct macho_module_info)); if (!modfmt) goto leave; macho_info->module = module_new(pcs, filename, DMT_MACHO, FALSE, load_addr, fmap.segs_size, 0, calc_crc32(fmap.fd)); if (!macho_info->module) { HeapFree(GetProcessHeap(), 0, modfmt); goto leave; } macho_module_info = (void*)(modfmt + 1); macho_info->module->format_info[DFI_MACHO] = modfmt; modfmt->module = macho_info->module; modfmt->remove = NULL; modfmt->loc_compute = NULL; modfmt->u.macho_info = macho_module_info; macho_module_info->load_addr = load_addr; if (dbghelp_options & SYMOPT_DEFERRED_LOADS) macho_info->module->module.SymType = SymDeferred; else if (!macho_load_debug_info(macho_info->module, &fmap)) ret = FALSE; macho_info->module->format_info[DFI_MACHO]->u.macho_info->in_use = 1; macho_info->module->format_info[DFI_MACHO]->u.macho_info->is_loader = 0; TRACE("module = %p\n", macho_info->module); } if (macho_info->flags & MACHO_INFO_NAME) { WCHAR* ptr; ptr = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1) * sizeof(WCHAR)); if (ptr) { strcpyW(ptr, filename); macho_info->module_name = ptr; } else ret = FALSE; TRACE("module_name = %p %s\n", macho_info->module_name, debugstr_w(macho_info->module_name)); } leave: macho_unmap_file(&fmap); TRACE(" => %d\n", ret); return ret; }
/*********************************************************************** * SymLoadModuleExW (DBGHELP.@) */ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageName, PCWSTR wModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll, PMODLOAD_DATA Data, DWORD Flags) { struct process* pcs; struct module* module = NULL; TRACE("(%p %p %s %s %s %08x %p %08x)\n", hProcess, hFile, debugstr_w(wImageName), debugstr_w(wModuleName), wine_dbgstr_longlong(BaseOfDll), SizeOfDll, Data, Flags); if (Data) FIXME("Unsupported load data parameter %p for %s\n", Data, debugstr_w(wImageName)); if (!validate_addr64(BaseOfDll)) return FALSE; if (!(pcs = process_find_by_handle(hProcess))) return FALSE; if (Flags & SLMFLAG_VIRTUAL) { if (!wImageName) return FALSE; module = module_new(pcs, wImageName, module_get_type_by_name(wImageName), TRUE, BaseOfDll, SizeOfDll, 0, 0); if (!module) return FALSE; if (wModuleName) module_set_module(module, wModuleName); module->module.SymType = SymVirtual; return TRUE; } if (Flags & ~(SLMFLAG_VIRTUAL)) FIXME("Unsupported Flags %08x for %s\n", Flags, debugstr_w(wImageName)); refresh_module_list(pcs); /* this is a Wine extension to the API just to redo the synchronisation */ if (!wImageName && !hFile) return 0; /* check if the module is already loaded, or if it's a builtin PE module with * an containing ELF module */ if (wImageName) { module = module_is_already_loaded(pcs, wImageName); if (!module && module_is_container_loaded(pcs, wImageName, BaseOfDll)) { /* force the loading of DLL as builtin */ module = pe_load_builtin_module(pcs, wImageName, BaseOfDll, SizeOfDll); } } if (!module) { /* otherwise, try a regular PE module */ if (!(module = pe_load_native_module(pcs, wImageName, hFile, BaseOfDll, SizeOfDll)) && wImageName) { /* and finally an ELF or Mach-O module */ switch (module_get_type_by_name(wImageName)) { case DMT_ELF: module = elf_load_module(pcs, wImageName, BaseOfDll); break; case DMT_MACHO: module = macho_load_module(pcs, wImageName, BaseOfDll); break; default: /* Ignored */ break; } } } if (!module) { WARN("Couldn't locate %s\n", debugstr_w(wImageName)); return 0; } module->module.NumSyms = module->ht_symbols.num_elts; /* by default module_new fills module.ModuleName from a derivation * of LoadedImageName. Overwrite it, if we have better information */ if (wModuleName) module_set_module(module, wModuleName); if (wImageName) lstrcpynW(module->module.ImageName, wImageName, sizeof(module->module.ImageName) / sizeof(WCHAR)); return module->module.BaseOfImage; }
/* machLoadModule(): attempts to find and load the debug information for the module <imageName>. The filename in <imageName> is assumed to be a windows DLL name (and optional path). The <moduleBase> and <moduleSize> parameters are stored in the module information that is returned. On success, a module object is created, added to the module list in the process desription <pcs>, and is returned. Failing to load the debug information from a module is not considered failure, and the module object will still be returned. Returns NULL if the module does not represent a dylib, the file could not be opened or read, or the memory could not be allocated. */ struct module *machLoadModule(struct process *pcs, const WCHAR *imageName, DWORD64 moduleBase, ULONG moduleSize){ struct module * module; WCHAR * actualName; MachMap map; TRACE("adding mach-o module {pcs = %p, imageName = %s, moduleBase = 0x%08llx, moduleSize = %d bytes}\n", pcs, debugstr_w(imageName), moduleBase, moduleSize); /* make sure it's not a 64-bit address */ if (!validate_addr64(moduleBase)){ FIXME("module base is actually 64-bit!\n"); return NULL; } moduleBase = normalize_addr64(moduleBase); /* verify that this image represents a dylib file */ if (!machIsMachFile(imageName, &actualName, NULL) || actualName == NULL){ TRACE("the module %s was not loaded from a dylib file\n", debugstr_w(imageName)); SAFEFREEBUF(actualName); return NULL; } /* need to load the module file to get the header information */ if (machMapFile(actualName, &map, FALSE)){ /* correct the module base and size if they were passed in as 0 */ if (moduleBase == 0){ if (map.modStart == 0) FIXME("no module base specified and couldn't guess at it\n"); moduleBase = map.modStart; } if (moduleSize == 0) moduleSize = map.modSize; } else{ ERR("could not open the dylib %s to gather module header information\n", debugstr_w(actualName)); SAFEFREEBUF(actualName); return NULL; } /* create a container for the module information */ module = module_new(pcs, imageName, DMT_DYLIB, FALSE, /* <-- not a virtual module */ moduleBase, moduleSize, map.timestamp, map.checksum); if (module == NULL){ ERR("could not create a new module container\n"); SAFEFREEBUF(actualName); machUnmapFile(&map); return NULL; } /* deferred module debug loads is set in the options => mark it and allow the module to be loaded when first needed */ if (dbghelp_options & SYMOPT_DEFERRED_LOADS) module->module.SymType = SymDeferred; /* attempt to load the module's debug information */ else{ BOOL ret; TRACE("loading the debug information for module %p\n", module); ret = machLoadDebugInfo(pcs, module, &map); TRACE("loading debug information %s\n", ret ? "SUCCEEDED" : "FAILED"); } machUnmapFile(&map); SAFEFREEBUF(actualName); return module; }