static enum dbg_start minidump_do_reload(struct tgt_process_minidump_data* data) { ULONG size; MINIDUMP_DIRECTORY* dir; void* stream; DWORD pid = 1; /* by default */ HANDLE hProc = (HANDLE)0x900DBAAD; int i; MINIDUMP_MODULE_LIST* mml; MINIDUMP_MODULE* mm; MINIDUMP_STRING* mds; char exec_name[1024]; char name[1024]; unsigned len; /* fetch PID */ if (MiniDumpReadDumpStream(data->mapping, MiscInfoStream, &dir, &stream, &size)) { MINIDUMP_MISC_INFO* mmi = (MINIDUMP_MISC_INFO*)stream; if (mmi->Flags1 & MINIDUMP_MISC1_PROCESS_ID) pid = mmi->ProcessId; } /* fetch executable name (it's normally the first one in module list) */ strcpy(exec_name, "<minidump-exec>"); /* default */ if (MiniDumpReadDumpStream(data->mapping, ModuleListStream, &dir, &stream, &size)) { mml = (MINIDUMP_MODULE_LIST*)stream; if (mml->NumberOfModules) { char* ptr; mm = &mml->Modules[0]; mds = (MINIDUMP_STRING*)((char*)data->mapping + mm->ModuleNameRva); len = WideCharToMultiByte(CP_ACP, 0, mds->Buffer, mds->Length / sizeof(WCHAR), name, sizeof(name) - 1, NULL, NULL); name[len] = 0; for (ptr = name + len - 1; ptr >= name; ptr--) { if (*ptr == '/' || *ptr == '\\') { strcpy(exec_name, ptr + 1); break; } } if (ptr < name) strcpy(exec_name, name); } } if (MiniDumpReadDumpStream(data->mapping, SystemInfoStream, &dir, &stream, &size)) { MINIDUMP_SYSTEM_INFO* msi = (MINIDUMP_SYSTEM_INFO*)stream; const char *str; char tmp[128]; dbg_printf("WineDbg starting on minidump on pid %lu\n", pid); switch (msi->ProcessorArchitecture) { case PROCESSOR_ARCHITECTURE_UNKNOWN: str = "Unknown"; break; case PROCESSOR_ARCHITECTURE_INTEL: strcpy(tmp, "Intel "); switch (msi->ProcessorLevel) { case 3: str = "80386"; break; case 4: str = "80486"; break; case 5: str = "Pentium"; break; case 6: str = "Pentium Pro/II"; break; default: str = "???"; break; } strcat(tmp, str); if (msi->ProcessorLevel == 3 || msi->ProcessorLevel == 4) { if (HIWORD(msi->ProcessorRevision) == 0xFF) sprintf(tmp + strlen(tmp), "-%c%d", 'A' + HIBYTE(LOWORD(msi->ProcessorRevision)), LOBYTE(LOWORD(msi->ProcessorRevision))); else sprintf(tmp + strlen(tmp), "-%c%d", 'A' + HIWORD(msi->ProcessorRevision), LOWORD(msi->ProcessorRevision)); } else sprintf(tmp + strlen(tmp), "-%d.%d", HIWORD(msi->ProcessorRevision), LOWORD(msi->ProcessorRevision)); str = tmp; break; case PROCESSOR_ARCHITECTURE_MIPS: str = "Mips"; break; case PROCESSOR_ARCHITECTURE_ALPHA: str = "Alpha"; break; case PROCESSOR_ARCHITECTURE_PPC: str = "PowerPC"; break; default: str = "???"; break; } dbg_printf(" %s was running on #%d %s CPU%s", exec_name, msi->u.s.NumberOfProcessors, str, msi->u.s.NumberOfProcessors < 2 ? "" : "s"); switch (msi->MajorVersion) { case 3: switch (msi->MinorVersion) { case 51: str = "NT 3.51"; break; default: str = "3-????"; break; } break; case 4: switch (msi->MinorVersion) { case 0: str = (msi->PlatformId == VER_PLATFORM_WIN32_NT) ? "NT 4.0" : "95"; break; case 10: str = "98"; break; case 90: str = "ME"; break; default: str = "5-????"; break; } break; case 5: switch (msi->MinorVersion) { case 0: str = "2000"; break; case 1: str = "XP"; break; case 2: str = "Server 2003"; break; default: str = "5-????"; break; } break; default: str = "???"; break; } dbg_printf(" on Windows %s (%lu)\n", str, msi->BuildNumber); /* FIXME CSD: msi->CSDVersionRva */ } dbg_curr_process = dbg_add_process(&be_process_minidump_io, pid, hProc); dbg_curr_pid = pid; dbg_curr_process->pio_data = data; dbg_set_process_name(dbg_curr_process, exec_name); SymInitialize(hProc, NULL, FALSE); if (MiniDumpReadDumpStream(data->mapping, ThreadListStream, &dir, &stream, &size)) { MINIDUMP_THREAD_LIST* mtl = (MINIDUMP_THREAD_LIST*)stream; MINIDUMP_THREAD* mt = &mtl->Threads[0]; dbg_add_thread(dbg_curr_process, mt->ThreadId, NULL, (void*)(DWORD_PTR)mt->Teb); } /* first load ELF modules, then do the PE ones */ if (MiniDumpReadDumpStream(data->mapping, Wine_ElfModuleListStream, &dir, &stream, &size)) { char buffer[MAX_PATH]; mml = (MINIDUMP_MODULE_LIST*)stream; for (i = 0, mm = &mml->Modules[0]; i < mml->NumberOfModules; i++, mm++) { mds = (MINIDUMP_STRING*)((char*)data->mapping + mm->ModuleNameRva); len = WideCharToMultiByte(CP_ACP, 0, mds->Buffer, mds->Length / sizeof(WCHAR), name, sizeof(name) - 1, NULL, NULL); name[len] = 0; if (SymFindFileInPath(hProc, NULL, name, (void*)(DWORD_PTR)mm->CheckSum, 0, 0, SSRVOPT_DWORD, buffer, validate_file, NULL)) SymLoadModule(hProc, NULL, buffer, NULL, mm->BaseOfImage, mm->SizeOfImage); else SymLoadModuleEx(hProc, NULL, name, NULL, mm->BaseOfImage, mm->SizeOfImage, NULL, SLMFLAG_VIRTUAL); } } if (MiniDumpReadDumpStream(data->mapping, ModuleListStream, &dir, &stream, &size)) { mml = (MINIDUMP_MODULE_LIST*)stream; for (i = 0, mm = &mml->Modules[0]; i < mml->NumberOfModules; i++, mm++) { mds = (MINIDUMP_STRING*)((char*)data->mapping + mm->ModuleNameRva); len = WideCharToMultiByte(CP_ACP, 0, mds->Buffer, mds->Length / sizeof(WCHAR), name, sizeof(name) - 1, NULL, NULL); name[len] = 0; SymLoadModule(hProc, NULL, name, NULL, mm->BaseOfImage, mm->SizeOfImage); } } if (MiniDumpReadDumpStream(data->mapping, ExceptionStream, &dir, &stream, &size)) { MINIDUMP_EXCEPTION_STREAM* mes = (MINIDUMP_EXCEPTION_STREAM*)stream; if ((dbg_curr_thread = dbg_get_thread(dbg_curr_process, mes->ThreadId))) { ADDRESS64 addr; dbg_curr_tid = mes->ThreadId; dbg_curr_thread->in_exception = TRUE; dbg_curr_thread->excpt_record.ExceptionCode = mes->ExceptionRecord.ExceptionCode; dbg_curr_thread->excpt_record.ExceptionFlags = mes->ExceptionRecord.ExceptionFlags; dbg_curr_thread->excpt_record.ExceptionRecord = (void*)(DWORD_PTR)mes->ExceptionRecord.ExceptionRecord; dbg_curr_thread->excpt_record.ExceptionAddress = (void*)(DWORD_PTR)mes->ExceptionRecord.ExceptionAddress; dbg_curr_thread->excpt_record.NumberParameters = mes->ExceptionRecord.NumberParameters; for (i = 0; i < dbg_curr_thread->excpt_record.NumberParameters; i++) { dbg_curr_thread->excpt_record.ExceptionInformation[i] = mes->ExceptionRecord.ExceptionInformation[i]; } memcpy(&dbg_context, (char*)data->mapping + mes->ThreadContext.Rva, min(sizeof(dbg_context), mes->ThreadContext.DataSize)); memory_get_current_pc(&addr); stack_fetch_frames(); be_cpu->print_context(dbg_curr_thread->handle, &dbg_context, 0); stack_info(); be_cpu->print_segment_info(dbg_curr_thread->handle, &dbg_context); stack_backtrace(mes->ThreadId); source_list_from_addr(&addr, 0); } } return start_ok; }
/* ================== Sym_Init ================== */ void Sym_Init( long addr ) { TCHAR moduleName[MAX_STRING_CHARS]; TCHAR modShortNameBuf[MAX_STRING_CHARS]; MEMORY_BASIC_INFORMATION mbi; if ( lastAllocationBase != -1 ) { Sym_Shutdown(); } VirtualQuery( (void*)addr, &mbi, sizeof(mbi) ); GetModuleFileName( (HMODULE)mbi.AllocationBase, moduleName, sizeof( moduleName ) ); _splitpath( moduleName, NULL, NULL, modShortNameBuf, NULL ); lastModule = modShortNameBuf; processHandle = GetCurrentProcess(); if ( !SymInitialize( processHandle, NULL, FALSE ) ) { return; } if ( !SymLoadModule( processHandle, NULL, moduleName, NULL, (DWORD)mbi.AllocationBase, 0 ) ) { SymCleanup( processHandle ); return; } SymSetOptions( SymGetOptions() & ~SYMOPT_UNDNAME ); lastAllocationBase = (DWORD) mbi.AllocationBase; }
//************************************************************************* // Method: enumAndLoadModuleSymbols // Description: Enumerates and loads the module symbols in a given process // // Parameters: // hProcess - the handle to the process // pid - the ID of the process // // Return Value: (none) //************************************************************************* void StackWalker::enumAndLoadModuleSymbols( HANDLE hProcess, DWORD pid ) { ModuleList modules; ModuleListIter it; char *img, *mod; // fill in module list fillModuleList( modules, pid, hProcess ); for ( it = modules.begin(); it != modules.end(); ++ it ) { // unfortunately, SymLoadModule() wants writeable strings img = new char[(*it).imageName.size() + 1]; strcpy( img, (*it).imageName.c_str() ); mod = new char[(*it).moduleName.size() + 1]; strcpy( mod, (*it).moduleName.c_str() ); SymLoadModule( hProcess, 0, img, mod, (*it).baseAddress, (*it).size ); /*if ( SymLoadModule( hProcess, 0, img, mod, (*it).baseAddress, (*it).size ) == 0 ) printf( "Error %lu loading symbols for \"%s\"\n", GetLastError(), (*it).moduleName.c_str() ); else printf( "Symbols loaded: \"%s\"\n", (*it).moduleName.c_str() );*/ delete [] img; delete [] mod; } }
/*********************************************************************** * 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); }
bool CallStack::loadAllModules() { #ifdef WIN32 DWORD dwNeeded = 0; if (!EnumProcessModules(hProcess, hModule, sizeof(hModule), &dwNeeded)) return false; const int iCount = dwNeeded / sizeof(HMODULE); for (int i = 0; i < iCount; ++i) { MODULEINFO info; GetModuleInformation(hProcess, hModule[i], &info, sizeof(info)); GetModuleFileNameEx(hProcess, hModule[i], szImageName, iMax); GetModuleBaseName(hProcess, hModule[i], szModuleName, iMax); #ifdef X64 SymLoadModule64(hProcess, hModule[i], szImageName, szModuleName, (DWORD64)info.lpBaseOfDll, info.SizeOfImage); #else SymLoadModule(hProcess, hModule[i], szImageName, szModuleName, (DWORD)info.lpBaseOfDll, info.SizeOfImage); #endif } #endif return true; }
static ULONG_ADDR CALLBACK GetModuleBase(HANDLE hProcess, ULONG_ADDR dwAddress) { MEMORY_BASIC_INFORMATION memoryInfo; ULONG_ADDR dwAddrBase = SymGetModuleBase(hProcess, dwAddress); if (dwAddrBase) { return dwAddrBase; } if (VirtualQueryEx(hProcess, (void*)(GC_ULONG_PTR)dwAddress, &memoryInfo, sizeof(memoryInfo))) { char filePath[_MAX_PATH]; char curDir[_MAX_PATH]; char exePath[_MAX_PATH]; DWORD size = GetModuleFileNameA((HINSTANCE)memoryInfo.AllocationBase, filePath, sizeof(filePath)); /* Save and restore current directory around SymLoadModule, see KB */ /* article Q189780. */ GetCurrentDirectoryA(sizeof(curDir), curDir); GetModuleFileNameA(NULL, exePath, sizeof(exePath)); #if defined(_MSC_VER) && _MSC_VER == 1200 /* use strcat for VC6 */ strcat(exePath, "\\.."); #else strcat_s(exePath, sizeof(exePath), "\\.."); #endif /* _MSC_VER >= 1200 */ SetCurrentDirectoryA(exePath); #ifdef _DEBUG GetCurrentDirectoryA(sizeof(exePath), exePath); #endif SymLoadModule(hProcess, NULL, size ? filePath : NULL, NULL, (ULONG_ADDR)(GC_ULONG_PTR)memoryInfo.AllocationBase, 0); SetCurrentDirectoryA(curDir); } return (ULONG_ADDR)(GC_ULONG_PTR)memoryInfo.AllocationBase; }
bool KImageModule::Load(char * filename, char *sympath) { _tcscpy(m_modulename, filename); memset(& m_image, 0, sizeof(m_image)); m_imagebase_loaded = (DWORD) GetModuleHandle(filename); if ( m_imagebase_loaded ) // module is already loaded, for example GDI32.DLL { m_imagebase_default = m_imagebase_loaded; m_bLoaded = false; PIMAGE_NT_HEADERS pNTHeader = ImageNtHeader((void *)m_imagebase_loaded); Output("%s already loaded at 0x%x %s\n", filename, m_imagebase_loaded, ctime( (time_t *) & pNTHeader->FileHeader.TimeDateStamp)); } else { if ( MapAndLoad(filename, NULL, & m_image, FALSE, TRUE) ) Output("%s loaded at 0x%x %s\n", m_image.ModuleName, m_image.MappedAddress, ctime( (time_t *) & m_image.FileHeader->FileHeader.TimeDateStamp)); else { Output("Unable to load %s\n", filename); return false; } m_imagebase_loaded = (DWORD) m_image.MappedAddress; m_imagebase_default = m_image.FileHeader->OptionalHeader.ImageBase; m_bLoaded = true; } if ( !SymInitialize(m_hProcess, sympath, FALSE) ) { Output("SymInitialize failed\n\n"); return false; } m_symbolbase = SymLoadModule(m_hProcess, NULL, filename, 0, m_imagebase_loaded, 0 ); if ( m_symbolbase==0 ) { Output("SymLoadModule failed\n\n"); return false; } IMAGEHLP_MODULE im; im.SizeOfStruct = sizeof(im); SymGetModuleInfo( m_hProcess, m_symbolbase, &im ); Output("""%s"" loaded. %s\n", im.LoadedImageName, ctime((time_t *) & im.TimeDateStamp)); return true; }
static DWORD __stdcall GetModuleBase(HANDLE hProcess, DWORD dwReturnAddress) { IMAGEHLP_MODULE moduleInfo; if (SymGetModuleInfo(hProcess, dwReturnAddress, &moduleInfo)) return moduleInfo.BaseOfImage; else { MEMORY_BASIC_INFORMATION memoryBasicInfo; if (::VirtualQueryEx(hProcess, (LPVOID) dwReturnAddress, &memoryBasicInfo, sizeof(memoryBasicInfo))) { DWORD cch = 0; char szFile[MAX_PATH] = { 0 }; cch = GetModuleFileNameA((HINSTANCE)memoryBasicInfo.AllocationBase, szFile, MAX_PATH); // Ignore the return code since we can't do anything with it. if (!SymLoadModule(hProcess, NULL, ((cch) ? szFile : NULL), NULL, (DWORD) memoryBasicInfo.AllocationBase, 0)) { DWORD dwError = GetLastError(); TRACE1("Error: %d\n", dwError); } return (DWORD) memoryBasicInfo.AllocationBase; } else TRACE1("Error is %d\n", GetLastError()); } return 0; }
BOOL ProcessModuleLoad ( PDEBUGPACKET dp, LPDEBUG_EVENT de ) /*++ Routine Description: Process all module load debug events, create process & dll load. The purpose is to allocate a MODULEINFO structure, fill in the necessary values, and load the symbol table. Arguments: dp - pointer to a debug packet de - pointer to a debug event structure Return Value: TRUE - everything worked FALSE - we're hosed --*/ { HANDLE hFile; DWORD dwBaseOfImage; LPSTR SymbolPath; if (de->dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT) { hFile = de->u.CreateProcessInfo.hFile; dwBaseOfImage = (DWORD)de->u.CreateProcessInfo.lpBaseOfImage; dp->hProcess = de->u.CreateProcessInfo.hProcess; dp->dwProcessId = de->dwProcessId; SymInitialize( dp->hProcess, NULL, FALSE ); SymbolPath = GetSymbolSearchPath(); SymSetSearchPath( dp->hProcess, SymbolPath ); free( SymbolPath ); } else if (de->dwDebugEventCode == LOAD_DLL_DEBUG_EVENT) { hFile = de->u.LoadDll.hFile; dwBaseOfImage = (DWORD)de->u.LoadDll.lpBaseOfDll; } if ((hFile == NULL) || (hFile == INVALID_HANDLE_VALUE)) { return FALSE; } if (!SymLoadModule( dp->hProcess, hFile, NULL, NULL, dwBaseOfImage, 0 )) { return FALSE; } else { if (de->dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT) { IMAGEHLP_MODULE mi; if (SymGetModuleInfo( dp->hProcess, dwBaseOfImage, &mi )) { strcpy( szApp, mi.ImageName ); } } } return TRUE; }
DWORD __stdcall CCallStackTrace::GetModuleBase(HANDLE hProcess, DWORD address) { IMAGEHLP_MODULE imagehlp_module; MEMORY_BASIC_INFORMATION memory_basic_information; char module_file_name[260]; DWORD module_file_name_length; HANDLE file_handle; char * image_name; imagehlp_module.SizeOfStruct = sizeof(imagehlp_module); if ( SymGetModuleInfo(hProcess, address, &imagehlp_module) == TRUE ) { return imagehlp_module.BaseOfImage; } if ( VirtualQueryEx(hProcess, (LPCVOID)address, &memory_basic_information, sizeof(memory_basic_information)) == FALSE ) { return 0; } module_file_name_length = GetModuleFileName((HMODULE)memory_basic_information.AllocationBase, module_file_name, sizeof(module_file_name)); if ( module_file_name_length ) { file_handle = CreateFile(module_file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); } else { file_handle = NULL; } image_name = NULL; if ( module_file_name_length > 0 ) { image_name = module_file_name; } else { image_name = NULL; } SymLoadModule(hProcess, file_handle, image_name, 0, (DWORD)memory_basic_information.AllocationBase, 0); return (DWORD)memory_basic_information.AllocationBase; }
BOOL dbg_get_debuggee_info(HANDLE hProcess, IMAGEHLP_MODULE64* imh_mod) { struct mod_loader_info mli; DWORD opt; /* this will resynchronize builtin dbghelp's internal ELF module list */ SymLoadModule(hProcess, 0, 0, 0, 0, 0); mli.handle = hProcess; mli.imh_mod = imh_mod; imh_mod->SizeOfStruct = sizeof(*imh_mod); imh_mod->BaseOfImage = 0; /* this is a wine specific options to return also ELF modules in the * enumeration */ SymSetOptions((opt = SymGetOptions()) | 0x40000000); SymEnumerateModules64(hProcess, mod_loader_cb, (void*)&mli); SymSetOptions(opt); return imh_mod->BaseOfImage != 0; }
bool dbgsymengine::guard::load_module(HANDLE hProcess, HMODULE hMod) { char filename[MAX_PATH]; if (!GetModuleFileNameA(hMod, filename, MAX_PATH)) return false; HANDLE hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); if (hFile == INVALID_HANDLE_VALUE) return false; // "Debugging Applications" John Robbins // For whatever reason, SymLoadModule can return zero, but it still loads the modules. Sheez. SetLastError(ERROR_SUCCESS); if (!SymLoadModule(hProcess, hFile, filename, 0, (DWORD)hMod, 0) && ERROR_SUCCESS != GetLastError()) { return false; } return true; }
static DWORD __stdcall GetModBase( HANDLE hProcess, DWORD dwAddr ) #endif { // Check in the symbol engine first. IMAGEHLP_MODULE stIHM; // This is what the MFC stack trace routines forgot to do so their // code will not get the info out of the symbol engine. stIHM.SizeOfStruct = sizeof( IMAGEHLP_MODULE ); if( SymGetModuleInfo( hProcess, dwAddr, &stIHM ) ) { return ( stIHM.BaseOfImage ); } else { // Let's go fishing. MEMORY_BASIC_INFORMATION stMBI; if( 0 != VirtualQueryEx( hProcess, (LPCVOID) dwAddr, &stMBI, sizeof( stMBI ) ) ) { // Try and load it. DWORD dwNameLen = 0; TCHAR szFile[MAX_PATH]; memset( szFile, 0, sizeof( szFile ) ); HANDLE hFile = NULL; dwNameLen = GetModuleFileName( (HINSTANCE) stMBI.AllocationBase, szFile, MAX_PATH ); if( 0 != dwNameLen ) { hFile = CreateFile( szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 ); SymLoadModule( hProcess, hFile, (PSTR) ( dwNameLen ? szFile : NULL ), NULL, (ULONG_PTR) stMBI.AllocationBase, 0 ); CloseHandle( hFile ); } return ( (ULONG_PTR) stMBI.AllocationBase ); } } return ( 0 ); }
void enumAndLoadModuleSymbols( HANDLE hProcess, DWORD pid ) { ModuleList modules; ModuleListIter it; char *img, *mod; // fill in module list fillModuleList( modules, pid, hProcess ); for ( it = modules.begin(); it != modules.end(); ++ it ) { // unfortunately, SymLoadModule() wants writeable strings img = new char[(*it).imageName.size() + 1]; strcpy( img, (*it).imageName.c_str() ); mod = new char[(*it).moduleName.size() + 1]; strcpy( mod, (*it).moduleName.c_str() ); SymLoadModule( hProcess, 0, img, mod, (*it).baseAddress, (*it).size ); delete [] img; delete [] mod; } }
BOOL CShadowSSDTMgr::GetShadowSSDTNativeAddrBySymbol() { BOOL boRetn; PDWORD pW32pServiceTable = 0; DWORD dwload = 0; PLOADED_IMAGE ploadImage = {0}; char imgPath[MAX_PATH]; // 初始化 if ( !InitSymbolsHandler() ) { return FALSE; } // 获取系统目录"C:\WINDOWS\system32" GetSystemDirectory( imgPath, MAX_PATH ); // 加载模块 ploadImage = ImageLoad( "win32k.sys", imgPath ); // 加载符号"C:\WINDOWS\system32\win32k.sys" strcat( imgPath, "\\win32k.sys" ); dwload=SymLoadModule ( g_ixerhProc, ploadImage->hFile, imgPath, "win32k.pdb", 0, ploadImage->SizeOfImage ); boRetn=SymEnumSymbols( g_ixerhProc, dwload, NULL, (PSYM_ENUMERATESYMBOLS_CALLBACK)EnumSymRoutine, NULL ); if (g_W32pServiceTable) { pW32pServiceTable = (PDWORD)( g_W32pServiceTable - dwload + (DWORD)ploadImage->MappedAddress ); boRetn=SymEnumSymbols( g_ixerhProc, dwload, NULL, (PSYM_ENUMERATESYMBOLS_CALLBACK)EnumSymRoutine, pW32pServiceTable ); } ImageUnload(ploadImage); SymCleanup(g_ixerhProc); return boRetn; }
/*********************************************************************** * SymLoadModule64 (DBGHELP.@) */ DWORD64 WINAPI SymLoadModule64(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll) { if (!validate_addr64(BaseOfDll)) return FALSE; return SymLoadModule(hProcess, hFile, ImageName, ModuleName, (DWORD)BaseOfDll, SizeOfDll); }
DWORD __stdcall BSUSymInitialize ( DWORD dwPID , HANDLE hProcess , PSTR UserSearchPath , BOOL fInvadeProcess ) { // If this is any flavor of NT or fInvadeProcess is FALSE, just call // SymInitialize itself if ( ( TRUE == IsNT ( ) ) || ( FALSE == fInvadeProcess ) ) { return ( ::SymInitialize ( hProcess , UserSearchPath , fInvadeProcess ) ) ; } else { // This is Win9x and the user wants to invade! // The first step is to initialize the symbol engine. If it // fails, there is not much I can do. BOOL bSymInit = ::SymInitialize ( hProcess , UserSearchPath , fInvadeProcess ) ; ASSERT ( FALSE != bSymInit ) ; if ( FALSE == bSymInit ) { return ( FALSE ) ; } DWORD dwCount ; // Find out how many modules there are. This is a BSU function. if ( FALSE == GetLoadedModules ( dwPID , 0 , NULL , &dwCount ) ) { ASSERT ( !"GetLoadedModules failed" ) ; // Clean up the symbol engine and leave. VERIFY ( ::SymCleanup ( hProcess ) ) ; return ( FALSE ) ; } // Allocate something big enough to hold the list. HMODULE * paMods = new HMODULE[ dwCount ] ; // Get the list for real. if ( FALSE == GetLoadedModules ( dwPID , dwCount , paMods , &dwCount ) ) { ASSERT ( !"GetLoadedModules failed" ) ; // Clean up the symbol engine and leave. VERIFY ( ::SymCleanup ( hProcess ) ) ; // Free the memory that I allocated earlier. delete [] paMods ; return ( FALSE ) ; } // The module filename. TCHAR szModName [ MAX_PATH ] ; for ( UINT uiCurr = 0 ; uiCurr < dwCount ; uiCurr++ ) { // Get the module's filename. if ( FALSE == GetModuleFileName ( paMods[ uiCurr ] , szModName , sizeof ( szModName ) ) ) { ASSERT ( !"GetModuleFileName failed!" ) ; // Clean up the symbol engine and leave. VERIFY ( ::SymCleanup ( hProcess ) ) ; // Free the memory that I allocated earlier. delete [] paMods ; return ( FALSE ) ; } // In order to get the symbol engine to work outside a // debugger, it needs a handle to the image. Yes, this // will leak but the OS will close it down when the process // ends. HANDLE hFile = CreateFile ( szModName , GENERIC_READ , FILE_SHARE_READ , NULL , OPEN_EXISTING , 0 , 0 ) ; // For whatever reason, SymLoadModule can return zero, but // it still loads the modules. Sheez. if ( FALSE == SymLoadModule ( hProcess , hFile , szModName , NULL , (DWORD)paMods[ uiCurr ] , 0 ) ) { // Check the last error value. If it is zero, then all // I can assume is that it worked. DWORD dwLastErr = GetLastError ( ) ; ASSERT ( ERROR_SUCCESS == dwLastErr ) ; if ( ERROR_SUCCESS != dwLastErr ) { // Clean up the symbol engine and leave. VERIFY ( ::SymCleanup ( hProcess ) ) ; // Free the memory that I allocated earlier. delete [] paMods ; return ( FALSE ) ; } } } delete [] paMods ; } return ( TRUE ) ; }
void AddImage( PSZ pszName, PVOID BaseOfDll, ULONG SizeOfImage, ULONG CheckSum, ULONG ProcessId, PSZ pszModuleName, BOOL ForceSymbolLoad ) { PIMAGE_INFO pImageNew; PIMAGE_INFO *pp; UCHAR index = 0; PSZ pszBaseName; PCHAR KernelBaseFileName; HANDLE KernelBaseFileHandle; DWORD BytesWritten; IMAGEHLP_MODULE mi; CHAR buf[256]; ULONG LoadAddress; if (pszName == NULL) { return; } if ((_stricmp( pszName, KERNEL_IMAGE_NAME ) == 0) || (_stricmp( pszName, KERNEL_IMAGE_NAME_MP ) == 0)) { // // rename the image if necessary // if (GetModnameFromImage( (ULONG)BaseOfDll, NULL, buf )) { strcpy( pszName, buf ); } pszModuleName = "NT"; } if (_stricmp( pszName, HAL_IMAGE_FILE_NAME ) == 0) { // // rename the image if necessary // if (GetModnameFromImage( (ULONG)BaseOfDll, NULL, buf )) { strcpy( pszName, buf ); } pszModuleName = "HAL"; } pszBaseName = strchr(pszName,'\0'); while (pszBaseName > pszName) { if (pszBaseName[-1] == '\\' || pszBaseName[-1] == '/' || pszBaseName[-1] == ':') { pszName = pszBaseName; break; } else { pszBaseName -= 1; } } // // search for existing image with same checksum at same base address // if found, remove symbols, but leave image structure intact // pp = &pProcessCurrent->pImageHead; while (pImageNew = *pp) { if (pImageNew->lpBaseOfImage == BaseOfDll) { if (fVerboseOutput) { dprintf("%s: force unload of %s\n", DebuggerName, pImageNew->szImagePath); } SymUnloadModule( pProcessCurrent->hProcess, (ULONG)pImageNew->lpBaseOfImage ); break; } else if (pImageNew->lpBaseOfImage > BaseOfDll) { pImageNew = NULL; break; } pp = &pImageNew->pImageNext; } // if not found, allocate and fill new image structure if (!pImageNew) { for (index=0; index<pProcessCurrent->MaxIndex; index++) { if (pProcessCurrent->pImageByIndex[ index ] == NULL) { pImageNew = calloc(sizeof(IMAGE_INFO),1); break; } } if (!pImageNew) { DWORD NewMaxIndex; PIMAGE_INFO *NewImageByIndex; NewMaxIndex = pProcessCurrent->MaxIndex + 32; if (NewMaxIndex < 0x100) { NewImageByIndex = calloc( NewMaxIndex, sizeof( *NewImageByIndex ) ); } else { NewImageByIndex = NULL; } if (NewImageByIndex == NULL) { dprintf("%s: No room for %s image record.\n", DebuggerName, pszName ); return; } if (pProcessCurrent->pImageByIndex) { memcpy( NewImageByIndex, pProcessCurrent->pImageByIndex, pProcessCurrent->MaxIndex * sizeof( *NewImageByIndex ) ); free( pProcessCurrent->pImageByIndex ); } pProcessCurrent->pImageByIndex = NewImageByIndex; index = (UCHAR) pProcessCurrent->MaxIndex; pProcessCurrent->MaxIndex = NewMaxIndex; pImageNew = calloc(sizeof(IMAGE_INFO),1); if (!pImageNew) { dprintf("%s: Unable to allocate memory for %s symbols.\n", DebuggerName, pszName); return; } } pImageNew->pImageNext = *pp; *pp = pImageNew; pImageNew->index = index; pProcessCurrent->pImageByIndex[ index ] = pImageNew; } // // pImageNew has either the unloaded structure or the newly created one // pImageNew->lpBaseOfImage = BaseOfDll; pImageNew->dwCheckSum = CheckSum; pImageNew->dwSizeOfImage = SizeOfImage; pImageNew->GoodCheckSum = TRUE; strcpy( pImageNew->szImagePath, pszName ); LoadAddress = SymLoadModule( pProcessCurrent->hProcess, NULL, pImageNew->szImagePath, pszModuleName, (ULONG)pImageNew->lpBaseOfImage, pImageNew->dwSizeOfImage ); if (!LoadAddress) { DelImage( pszName, 0, 0 ); return; } if (!pImageNew->lpBaseOfImage) { pImageNew->lpBaseOfImage = (PVOID)LoadAddress; } if (ForceSymbolLoad) { SymLoadModule( pProcessCurrent->hProcess, NULL, NULL, NULL, (ULONG)pImageNew->lpBaseOfImage, 0 ); } if (SymGetModuleInfo( pProcessCurrent->hProcess, (ULONG)pImageNew->lpBaseOfImage, &mi )) { pImageNew->dwSizeOfImage = mi.ImageSize; strcpy( pImageNew->szImagePath, mi.ImageName ); strcpy( pImageNew->szDebugPath, mi.LoadedImageName ); } else { DelImage( pszName, 0, 0 ); return; } if (pszModuleName) { strcpy( pImageNew->szModuleName, pszModuleName ); } else { CreateModuleNameFromPath( pImageNew->szImagePath, pImageNew->szModuleName ); } if (fVerboseOutput) { dprintf( "%s ModLoad: %08lx %08lx %-8s\n", DebuggerName, pImageNew->lpBaseOfImage, (ULONG)(pImageNew->lpBaseOfImage) + pImageNew->dwSizeOfImage, pImageNew->szImagePath ); } }
/// /// \brief Get stack trace /// /// \return Stack trace /// LIBALT_API altStr altRuntime::GetStackTrace() { #ifdef ALT_WIN HANDLE hProcess = ::GetCurrentProcess(); HANDLE hThread = ::GetCurrentThread(); #if 0 DWORD dwOpts = ::SymGetOptions(); ::SymSetOptions (dwOpts | SYMOPT_LOAD_LINES); #endif if (! ::SymInitialize (hProcess, NULL, TRUE)) { return (""); } CONTEXT ctx; ctx.ContextFlags = CONTEXT_FULL; ctx.ContextFlags = CONTEXT_ALL; std::vector<DWORD> vAddrs; if (::GetThreadContext (hThread, & ctx)) { STACKFRAME frame; DWORD dwMachine; memset (& frame, 0x00, sizeof (frame)); frame.AddrPC.Mode = AddrModeFlat; dwMachine = IMAGE_FILE_MACHINE_I386; frame.AddrPC.Offset = ctx.Eip; frame.AddrStack.Offset = ctx.Esp; frame.AddrFrame.Offset = ctx.Ebp; frame.AddrPC.Mode = AddrModeFlat; frame.AddrStack.Mode = AddrModeFlat; frame.AddrFrame.Mode = AddrModeFlat; #if 0 BOOL bRet = SymLoadModule (hProcess, NULL, (PSTR)sImageName.GetCStr(), NULL, 0, 0); #endif for (DWORD dw = 0; dw < 512; dw++) { if (! ::StackWalk (dwMachine, hProcess, hThread, & frame, & ctx, NULL, SymFunctionTableAccess, SymGetModuleBase, NULL)) { break; } if (frame.AddrPC.Offset != 0) { vAddrs.push_back (frame.AddrPC.Offset); } } } altStr sStackTrace; altStr sSym; for (altUInt i = 0; i < vAddrs.size(); i++) { ConvertAddress (hProcess, vAddrs[i], sSym); sStackTrace += sSym; } SymCleanup (hProcess); return (sStackTrace); #endif #ifdef ALT_LINUX void * ar[100]; altInt nSize = 0; altChar ** ppStrings; altStr sStackTrace; nSize = backtrace (ar,100); ppStrings = backtrace_symbols (ar, nSize); for (altInt i = 1; i < nSize; i++) { sStackTrace += "\t"; sStackTrace += ppStrings[i]; sStackTrace += "\n"; } free (ppStrings); return (sStackTrace); #endif }
PPROFBLK SetupProfiling(LPCTSTR ptchFileName) { PVOID ImageBase; PPROFBLK pProfBlk; PPROFBLK pPrevProfBlk; ULONG ulBlkOff; LPCSTR ptchImageName; TCHAR atchImageName [256]; PIMAGE_NT_HEADERS pImageNtHeader; IMAGEHLP_MODULE ModuleInfo; // Skip directory name if ( (ptchImageName = strrchr(ptchFileName, '\\')) ) ptchImageName++; else ptchImageName = (PTCHAR)ptchFileName; // Make uppercase copy _strupr (strcpy (atchImageName, ptchImageName)); // Don't profile CAP if ( !strcmp (atchImageName, CAPDLL) ) return NULL; // Search prof blk list for matching image name pPrevProfBlk = NULL; ulBlkOff = ulLocProfBlkOff; while (ulBlkOff != 0) { pPrevProfBlk = MKPPROFBLK(ulBlkOff); // If found image, no need to set up new block if (!strcmp((PCHAR)pPrevProfBlk->atchImageName, atchImageName)) return FALSE; ulBlkOff = pPrevProfBlk->ulNxtBlk; } try // Accessing new block can cause an access fault // which will extend the allocation { // Place block at next available offset pProfBlk = MKPPROFBLK(*pulProfBlkBase); // Fill in initial values pProfBlk->ImageBase =0; pProfBlk->CodeStart = 0; pProfBlk->CodeLength = 0; pProfBlk->iSymCnt = 0; pProfBlk->State = BLKSTATE_ASSIGNED; pProfBlk->ulNxtBlk = 0; strcpy ((TCHAR *) pProfBlk->atchImageName, atchImageName); // Link to previous block or initial block offset if (pPrevProfBlk) pPrevProfBlk->ulNxtBlk = *pulProfBlkBase; else ulLocProfBlkOff = *pulProfBlkBase; // Load module symbols ImageBase = GetModuleHandle(ptchImageName); SymLoadModule(hThisProcess, NULL, (LPSTR)ptchFileName, (LPSTR)ptchImageName, (DWORD)ImageBase, 0); if (ImageBase != NULL) { pProfBlk->ImageBase = ImageBase; // Get code start address if ((pImageNtHeader = ImageNtHeader(ImageBase)) != NULL) { pProfBlk->CodeStart = (PULONG)((TCHAR *)ImageBase + pImageNtHeader->OptionalHeader.BaseOfCode); } else { // If can't get code start, use imagebase as next best guess pProfBlk->CodeStart = ImageBase; } #if defined(MIPS) && !defined(MIPS_VC40_INTERFACE) // Enumerate symbols to find adress of _penter fPenterFound = FALSE; SymEnumerateSymbols(hThisProcess, (DWORD)ImageBase, FindPenterCallback, (PVOID)pProfBlk); #endif // MIPS && !MIPS_VC40_INTERFACE // Get module info for symbols count SymGetModuleInfo(hThisProcess, (DWORD)ImageBase, &ModuleInfo); pProfBlk->iSymCnt = ModuleInfo.NumSyms; // Determine location for symbols and symbol names pProfSymb = (PSYMINFO)(&pProfBlk->atchImageName[strlen(atchImageName) + 1]); pProfBlk->ulSym = (PTCHAR)pProfSymb - (PTCHAR)pulProfBlkBase; pcProfSymbName = (PTCHAR)&pProfSymb[ModuleInfo.NumSyms]; // Now enumerate symbols to build up symbol table ulMaxSymbAddr = (ULONG)pProfBlk->CodeStart; SymEnumerateSymbols(hThisProcess, (DWORD)ImageBase, SymbolEnumCallback, (PVOID)pProfBlk); // Set symbol range based on max symbol address encountered if (ulMaxSymbAddr > (ULONG)pProfBlk->CodeStart) pProfBlk->CodeLength = ulMaxSymbAddr - (ULONG)pProfBlk->CodeStart; // Update pointer to available space *pulProfBlkBase = (ULONG)(pcProfSymbName - (PTCHAR)pulProfBlkBase); // Unload the module SymUnloadModule(hThisProcess, (DWORD)ImageBase); // Do any requested import/export patching PatchDll (ptchPatchImports, ptchPatchCallers, bCallersToPatch, atchImageName, ImageBase); } else { // No symbols - Update offset to next free space *pulProfBlkBase = (ULONG)&pProfBlk->atchImageName[strlen(atchImageName) + 1] -(ULONG)pulProfBlkBase; } // ImageBase != NULL } // // + : transfer control to the handler (EXCEPTION_EXECUTE_HANDLER) // 0 : continue search (EXCEPTION_CONTINUE_SEARCH) // - : dismiss exception & continue (EXCEPTION_CONTINUE_EXECUTION) // except ( AccessXcptFilter (GetExceptionCode(), GetExceptionInformation(), COMMIT_SIZE)) { // Should never get here since filter never returns // EXCEPTION_EXECUTE_HANDLER. CapDbgPrint ("CAP: DoDllInitializations() - *LOGIC ERROR* - " "Inside the EXCEPT: (xcpt=0x%lx)\n", GetExceptionCode()); } // end of TRY/EXCEPT return pProfBlk; }
/*********************************************************************** * dbg_exception_prolog * * Examine exception and decide if interactive mode is entered(return TRUE) * or exception is silently continued(return FALSE) * is_debug means the exception is a breakpoint or single step exception */ static unsigned dbg_exception_prolog(BOOL is_debug, BOOL first_chance, const EXCEPTION_RECORD* rec) { ADDRESS64 addr; BOOL is_break; char hexbuf[MAX_OFFSET_TO_STR_LEN]; memory_get_current_pc(&addr); break_suspend_execution(); dbg_curr_thread->excpt_record = *rec; dbg_curr_thread->in_exception = TRUE; if (!is_debug) { switch (addr.Mode) { case AddrModeFlat: dbg_printf(" in 32-bit code (%s)", memory_offset_to_string(hexbuf, addr.Offset, 0)); break; case AddrModeReal: dbg_printf(" in vm86 code (%04x:%04x)", addr.Segment, (unsigned) addr.Offset); break; case AddrMode1616: dbg_printf(" in 16-bit code (%04x:%04x)", addr.Segment, (unsigned) addr.Offset); break; case AddrMode1632: dbg_printf(" in 32-bit code (%04x:%08lx)", addr.Segment, (unsigned long) addr.Offset); break; default: dbg_printf(" bad address"); } dbg_printf(".\n"); } /* this will resynchronize builtin dbghelp's internal ELF module list */ SymLoadModule(dbg_curr_process->handle, 0, 0, 0, 0, 0); if (is_debug) break_adjust_pc(&addr, rec->ExceptionCode, first_chance, &is_break); /* * Do a quiet backtrace so that we have an idea of what the situation * is WRT the source files. */ stack_fetch_frames(); if (is_debug && !is_break && break_should_continue(&addr, rec->ExceptionCode)) return FALSE; if (addr.Mode != dbg_curr_thread->addr_mode) { const char* name = NULL; switch (addr.Mode) { case AddrMode1616: name = "16 bit"; break; case AddrMode1632: name = "32 bit"; break; case AddrModeReal: name = "vm86"; break; case AddrModeFlat: name = "32 bit"; break; } dbg_printf("In %s mode.\n", name); dbg_curr_thread->addr_mode = addr.Mode; } display_print(); if (!is_debug) { /* This is a real crash, dump some info */ be_cpu->print_context(dbg_curr_thread->handle, &dbg_context, 0); stack_info(); be_cpu->print_segment_info(dbg_curr_thread->handle, &dbg_context); stack_backtrace(dbg_curr_tid); } else { static char* last_name; static char* last_file; char buffer[sizeof(SYMBOL_INFO) + 256]; SYMBOL_INFO* si = (SYMBOL_INFO*)buffer; void* lin = memory_to_linear_addr(&addr); DWORD64 disp64; IMAGEHLP_LINE il; DWORD disp; si->SizeOfStruct = sizeof(*si); si->MaxNameLen = 256; il.SizeOfStruct = sizeof(il); if (SymFromAddr(dbg_curr_process->handle, (DWORD_PTR)lin, &disp64, si) && SymGetLineFromAddr(dbg_curr_process->handle, (DWORD_PTR)lin, &disp, &il)) { if ((!last_name || strcmp(last_name, si->Name)) || (!last_file || strcmp(last_file, il.FileName))) { HeapFree(GetProcessHeap(), 0, last_name); HeapFree(GetProcessHeap(), 0, last_file); last_name = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(si->Name) + 1), si->Name); last_file = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(il.FileName) + 1), il.FileName); dbg_printf("%s () at %s:%u\n", last_name, last_file, il.LineNumber); } } } if (!is_debug || is_break || dbg_curr_thread->exec_mode == dbg_exec_step_over_insn || dbg_curr_thread->exec_mode == dbg_exec_step_into_insn) { ADDRESS64 tmp = addr; /* Show where we crashed */ memory_disasm_one_insn(&tmp); } source_list_from_addr(&addr, 0); return TRUE; }
int getDebugInfo(char* fname) { HANDLE Self; DWORD moduleAddr; IMAGEHLP_MODULE moduleInfo; namesSize = 1; maxDebug = CodeSize + 10000; hasDebug = calloc(maxDebug, sizeof(int)); names = calloc(MAX_NAMES_SIZE,1); nonCode = calloc(MAX_NONCODE_SIZE,sizeof(Sym)); nonCodeCount = 0; Self = GetCurrentProcess(); SymSetOptions(SYMOPT_LOAD_LINES); if(!SymInitialize(Self,NULL,FALSE)) { printf("Failed to initialize Sym \n"); return -1; } printf("Trying to load with base = %08X\n",imageBase); // moduleAddr = SymLoadModule(Self,NULL,fname,NULL,imageBase+BASE_SHIFT,0); moduleAddr = SymLoadModule(Self,NULL,fname,NULL,0,0); if(!moduleAddr) { printf("Error: %n",GetLastError()); return -1; } moduleInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE); if(SymGetModuleInfo(Self,moduleAddr,&moduleInfo)) { printf("ImageSize : %d \n",moduleInfo.ImageSize); printf("NumSyms : %d \n",moduleInfo.NumSyms); printf("SymType : "); switch (moduleInfo.SymType) { case SymNone : printf("No symbols are loaded \n"); break; case SymCoff : printf("COFF symbols \n"); break; case SymCv : printf("CodeView symbols \n"); break; case SymPdb : printf("pdb file \n"); break; case SymExport : printf("Symbols generated from a DLL's export table\n"); break; case SymDeferred : printf("The library has not yet attempted to load symbols.\n"); break; case SymSym : printf(".SYM file \n"); break; default: printf("Unknown value for SymType : %d\n",moduleInfo.SymType); } printf("ModuleName : %s\n",moduleInfo.ModuleName); printf("ImageName : %s\n",moduleInfo.ImageName); printf("LoadedImageName : %s\n",moduleInfo.LoadedImageName); printf("LoadedImageBase : %08X\n",moduleInfo.BaseOfImage); } SymEnumerateSymbols(Self,moduleAddr,SymbolEnumumeration,NULL); SymUnloadModule(Self,moduleAddr); SymCleanup(Self); return 0; }