void KImageModule::Unload(void) { SymUnloadModule(m_hProcess, m_symbolbase); SymCleanup(m_hProcess); if ( m_image.ModuleName ) UnMapAndLoad(& m_image); }
void DelImages (void) { PIMAGE_INFO pImage, pNextImage; pNextImage = pProcessHead->pImageHead; pProcessHead->pImageHead = NULL; while (pNextImage) { pImage = pNextImage; pNextImage=pImage->pImageNext; SymUnloadModule( pProcessCurrent->hProcess, (ULONG)pImage->lpBaseOfImage ); pProcessCurrent->pImageByIndex[ pImage->index ] = NULL; free(pImage); } }
void DelImage (PSZ pszName, PVOID BaseOfDll, ULONG ProcessId) { PIMAGE_INFO pImage, *pp; pp = &pProcessHead->pImageHead; while (pImage = *pp) { if (!_stricmp(pImage->szImagePath, pszName)){ *pp = pImage->pImageNext; SymUnloadModule( pProcessCurrent->hProcess, (ULONG)pImage->lpBaseOfImage ); pProcessCurrent->pImageByIndex[ pImage->index ] = NULL; free(pImage); } else { pp = &pImage->pImageNext; } } return; }
/* ================== Sym_Shutdown ================== */ void Sym_Shutdown( void ) { SymUnloadModule( GetCurrentProcess(), lastAllocationBase ); SymCleanup( GetCurrentProcess() ); lastAllocationBase = -1; }
static unsigned dbg_handle_debug_event(DEBUG_EVENT* de) { union { char bufferA[256]; WCHAR buffer[256]; } u; DWORD cont = DBG_CONTINUE; dbg_curr_pid = de->dwProcessId; dbg_curr_tid = de->dwThreadId; if ((dbg_curr_process = dbg_get_process(de->dwProcessId)) != NULL) dbg_curr_thread = dbg_get_thread(dbg_curr_process, de->dwThreadId); else dbg_curr_thread = NULL; switch (de->dwDebugEventCode) { case EXCEPTION_DEBUG_EVENT: if (!dbg_curr_thread) { WINE_ERR("%04x:%04x: not a registered process or thread (perhaps a 16 bit one ?)\n", de->dwProcessId, de->dwThreadId); break; } WINE_TRACE("%04x:%04x: exception code=%08x\n", de->dwProcessId, de->dwThreadId, de->u.Exception.ExceptionRecord.ExceptionCode); if (dbg_curr_process->continue_on_first_exception) { dbg_curr_process->continue_on_first_exception = FALSE; if (!DBG_IVAR(BreakOnAttach)) break; } if (dbg_fetch_context()) { cont = dbg_handle_exception(&de->u.Exception.ExceptionRecord, de->u.Exception.dwFirstChance); if (cont && dbg_curr_thread) { SetThreadContext(dbg_curr_thread->handle, &dbg_context); } } break; case CREATE_PROCESS_DEBUG_EVENT: dbg_curr_process = dbg_add_process(&be_process_active_io, de->dwProcessId, de->u.CreateProcessInfo.hProcess); if (dbg_curr_process == NULL) { WINE_ERR("Couldn't create process\n"); break; } fetch_module_name(de->u.CreateProcessInfo.lpImageName, de->u.CreateProcessInfo.fUnicode, de->u.CreateProcessInfo.lpBaseOfImage, u.buffer, sizeof(u.buffer) / sizeof(WCHAR), TRUE); WINE_TRACE("%04x:%04x: create process '%s'/%p @%p (%u<%u>)\n", de->dwProcessId, de->dwThreadId, wine_dbgstr_w(u.buffer), de->u.CreateProcessInfo.lpImageName, de->u.CreateProcessInfo.lpStartAddress, de->u.CreateProcessInfo.dwDebugInfoFileOffset, de->u.CreateProcessInfo.nDebugInfoSize); dbg_set_process_name(dbg_curr_process, u.buffer); if (!dbg_init(dbg_curr_process->handle, u.buffer, FALSE)) dbg_printf("Couldn't initiate DbgHelp\n"); if (!dbg_load_module(dbg_curr_process->handle, de->u.CreateProcessInfo.hFile, u.buffer, (DWORD_PTR)de->u.CreateProcessInfo.lpBaseOfImage, 0)) dbg_printf("couldn't load main module (%u)\n", GetLastError()); WINE_TRACE("%04x:%04x: create thread I @%p\n", de->dwProcessId, de->dwThreadId, de->u.CreateProcessInfo.lpStartAddress); dbg_curr_thread = dbg_add_thread(dbg_curr_process, de->dwThreadId, de->u.CreateProcessInfo.hThread, de->u.CreateProcessInfo.lpThreadLocalBase); if (!dbg_curr_thread) { WINE_ERR("Couldn't create thread\n"); break; } dbg_init_current_process(); dbg_init_current_thread(de->u.CreateProcessInfo.lpStartAddress); break; case EXIT_PROCESS_DEBUG_EVENT: WINE_TRACE("%04x:%04x: exit process (%d)\n", de->dwProcessId, de->dwThreadId, de->u.ExitProcess.dwExitCode); if (dbg_curr_process == NULL) { WINE_ERR("Unknown process\n"); break; } tgt_process_active_close_process(dbg_curr_process, FALSE); dbg_printf("Process of pid=%04x has terminated\n", de->dwProcessId); break; case CREATE_THREAD_DEBUG_EVENT: WINE_TRACE("%04x:%04x: create thread D @%p\n", de->dwProcessId, de->dwThreadId, de->u.CreateThread.lpStartAddress); if (dbg_curr_process == NULL) { WINE_ERR("Unknown process\n"); break; } if (dbg_get_thread(dbg_curr_process, de->dwThreadId) != NULL) { WINE_TRACE("Thread already listed, skipping\n"); break; } dbg_curr_thread = dbg_add_thread(dbg_curr_process, de->dwThreadId, de->u.CreateThread.hThread, de->u.CreateThread.lpThreadLocalBase); if (!dbg_curr_thread) { WINE_ERR("Couldn't create thread\n"); break; } dbg_init_current_thread(de->u.CreateThread.lpStartAddress); break; case EXIT_THREAD_DEBUG_EVENT: WINE_TRACE("%04x:%04x: exit thread (%d)\n", de->dwProcessId, de->dwThreadId, de->u.ExitThread.dwExitCode); if (dbg_curr_thread == NULL) { WINE_ERR("Unknown thread\n"); break; } /* FIXME: remove break point set on thread startup */ dbg_del_thread(dbg_curr_thread); break; case LOAD_DLL_DEBUG_EVENT: if (dbg_curr_thread == NULL) { WINE_ERR("Unknown thread\n"); break; } fetch_module_name(de->u.LoadDll.lpImageName, de->u.LoadDll.fUnicode, de->u.LoadDll.lpBaseOfDll, u.buffer, sizeof(u.buffer) / sizeof(WCHAR), FALSE); WINE_TRACE("%04x:%04x: loads DLL %s @%p (%u<%u>)\n", de->dwProcessId, de->dwThreadId, wine_dbgstr_w(u.buffer), de->u.LoadDll.lpBaseOfDll, de->u.LoadDll.dwDebugInfoFileOffset, de->u.LoadDll.nDebugInfoSize); dbg_load_module(dbg_curr_process->handle, de->u.LoadDll.hFile, u.buffer, (DWORD_PTR)de->u.LoadDll.lpBaseOfDll, 0); break_set_xpoints(FALSE); break_check_delayed_bp(); break_set_xpoints(TRUE); if (DBG_IVAR(BreakOnDllLoad)) { dbg_printf("Stopping on DLL %s loading at 0x%08lx\n", dbg_W2A(u.buffer, -1), (unsigned long)de->u.LoadDll.lpBaseOfDll); if (dbg_fetch_context()) cont = 0; } break; case UNLOAD_DLL_DEBUG_EVENT: WINE_TRACE("%04x:%04x: unload DLL @%p\n", de->dwProcessId, de->dwThreadId, de->u.UnloadDll.lpBaseOfDll); break_delete_xpoints_from_module((unsigned long)de->u.UnloadDll.lpBaseOfDll); SymUnloadModule(dbg_curr_process->handle, (unsigned long)de->u.UnloadDll.lpBaseOfDll); break; case OUTPUT_DEBUG_STRING_EVENT: if (dbg_curr_thread == NULL) { WINE_ERR("Unknown thread\n"); break; } memory_get_string(dbg_curr_process, de->u.DebugString.lpDebugStringData, TRUE, de->u.DebugString.fUnicode, u.bufferA, sizeof(u.bufferA)); WINE_TRACE("%04x:%04x: output debug string (%s)\n", de->dwProcessId, de->dwThreadId, u.bufferA); break; case RIP_EVENT: WINE_TRACE("%04x:%04x: rip error=%u type=%u\n", de->dwProcessId, de->dwThreadId, de->u.RipInfo.dwError, de->u.RipInfo.dwType); break; default: WINE_TRACE("%04x:%04x: unknown event (%x)\n", de->dwProcessId, de->dwThreadId, de->dwDebugEventCode); } if (!cont) return TRUE; /* stop execution */ ContinueDebugEvent(de->dwProcessId, de->dwThreadId, cont); return FALSE; /* continue execution */ }
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 ); } }
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; }
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; }