|
|
1.1 root 1: // ************************************************************************ 1.1.1.2 ! root 2: // ! 3: // Microsoft Developer Support ! 4: // Copyright (c) 1992 Microsoft Corporation ! 5: // ! 6: // ************************************************************************ ! 7: // MODULE : DEBDebug.C 1.1 root 8: // PURPOSE : Debug support functions for the Debug Event Browser 9: // FUNCTIONS : 10: // DbgEventThread() - debug event processing thread 11: // GetModuleFileNameFromHeader() - get the module name 1.1.1.2 ! root 12: // SkipBreakPoint() - skips over the break point in the ! 13: // debugee (R4000 only) 1.1 root 14: // COMMENTS : 1.1.1.2 ! root 15: // 1.1 root 16: // ************************************************************************ 1.1.1.2 ! root 17: #define STRICT 1.1 root 18: #include <Windows.H> 19: 20: #include "LinkList.H" 21: #include "DEBMain.H" 22: #include "DEBMisc.H" 23: #include "DEBDebug.H" 24: 1.1.1.2 ! root 25: //-- internal fucntion prototypes ! 26: DWORD WINAPI GetModuleFileNameFromHeader( HANDLE, HANDLE, LPTSTR, DWORD ); ! 27: #if( MIPS == 1 ) ! 28: BOOL SkipBreakPoint( DWORD ); ! 29: #endif 1.1 root 30: 31: // ************************************************************************ 32: // FUNCTION : DebugEventThread( LPCTSTR ) 33: // PURPOSE : Main debug event processing loop 1.1.1.2 ! root 34: // COMMENTS : ! 35: // A new debug event thread is created for each debugee process. ! 36: // DebugeeFileName may be the process ID of an active process or the ! 37: // name of a process to create. 1.1 root 38: // ************************************************************************ 1.1.1.2 ! root 39: DWORD WINAPI 1.1 root 40: DebugEventThread( LPCTSTR DebugeeFileName ) 41: { 1.1.1.2 ! root 42: #define STRING_BUFSIZ 256 ! 43: 1.1 root 44: static BOOL fFirstTime = TRUE; 1.1.1.2 ! root 45: static TCHAR szDebugeeTitle[128]; 1.1 root 46: static PNODE ThreadNode; // used for inserting new thread nodes 47: 48: PNODE TempNode; // used for queries on thread linked list 49: DEBUG_EVENT DebugEvent; 1.1.1.2 ! root 50: TCHAR szDebugEventBuffer[STRING_BUFSIZ]; ! 51: TCHAR szTempBuf[STRING_BUFSIZ]; 1.1 root 52: DWORD NumberOfBytesRead; 53: 54: //-- temporary thread info node used for queries 55: CreateNode( &ProcessList, &TempNode ); 56: 57: //-- determine if 'attach to' or 'open' debugee 58: // DebugeeFileName may be dwProcessId and an actual filename 59: if( !DebugActiveProcess( (DWORD) DebugeeFileName ) ) { 60: 1.1.1.2 ! root 61: STARTUPINFO StartInfo; ! 62: LPSTARTUPINFO lpStartInfo = &StartInfo; ! 63: ! 64: PROCESS_INFORMATION ProcessInfo; ! 65: LPPROCESS_INFORMATION lpProcessInfo = &ProcessInfo; ! 66: ! 67: if( fFirstTime ) { ! 68: LoadString( hInstance, IDS_OFN_DEBUGEE_TITLE, szDebugeeTitle, ! 69: sizeof(szDebugeeTitle)/sizeof(TCHAR) ); ! 70: } ! 71: ! 72: lpStartInfo->cb = sizeof( STARTUPINFO ); ! 73: lpStartInfo->lpDesktop = NULL; ! 74: lpStartInfo->lpTitle = szDebugeeTitle; ! 75: lpStartInfo->dwX = 0; ! 76: lpStartInfo->dwY = 0; ! 77: lpStartInfo->dwXSize = 0; ! 78: lpStartInfo->dwYSize = 0; ! 79: lpStartInfo->dwFlags = NULL; ! 80: lpStartInfo->wShowWindow = SW_SHOWDEFAULT; ! 81: ! 82: lpProcessInfo->hProcess = NULL; ! 83: 1.1 root 84: //-- create the debugee process instead 85: if( !CreateProcess( 86: NULL, 87: DebugeeFileName, 88: (LPSECURITY_ATTRIBUTES) NULL, 89: (LPSECURITY_ATTRIBUTES) NULL, 90: TRUE, 91: DebugMode | DebugeePriority | CREATE_NEW_CONSOLE, 92: (LPVOID) NULL, 93: (LPTSTR) NULL, 1.1.1.2 ! root 94: &StartInfo, &ProcessInfo ) ) { 1.1 root 95: 1.1.1.2 ! root 96: ErrorBox( "Failed", "CreateProcess()", __FILE__, __LINE__ ); ! 97: ExitThread( FALSE ); 1.1 root 98: 99: } 100: else { 101: 1.1.1.2 ! root 102: hProcess = ProcessInfo.hProcess; ! 103: CloseHandle( ProcessInfo.hProcess ); ! 104: CloseHandle( ProcessInfo.hThread ); 1.1 root 105: 106: } 107: } 108: 109: for(;;) { 110: if( !WaitForDebugEvent( &DebugEvent, (DWORD) -1L ) ) { 111: ListBoxPrintF( "%s", "Waiting..." ); 112: continue; 113: } 114: 115: switch( DebugEvent.dwDebugEventCode ) { 116: 117: case EXCEPTION_DEBUG_EVENT: 118: MakeDebugEventString( szDebugEventBuffer, "Exception:", 119: &DebugEvent); 120: 121: switch( DebugEvent.u.Exception.ExceptionRecord.ExceptionCode ) { 122: 123: case EXCEPTION_ACCESS_VIOLATION: 1.1.1.2 ! root 124: lstrcat(szDebugEventBuffer, "ACCESS_VIOLATION"); 1.1 root 125: break; 126: 127: case EXCEPTION_BREAKPOINT: 1.1.1.2 ! root 128: lstrcat(szDebugEventBuffer, "BREAKPOINT"); 1.1 root 129: break; 130: 131: case EXCEPTION_DATATYPE_MISALIGNMENT: 1.1.1.2 ! root 132: lstrcat(szDebugEventBuffer, "DATATYPE_MISALIGNMENT"); 1.1 root 133: break; 134: 135: case EXCEPTION_SINGLE_STEP: 1.1.1.2 ! root 136: lstrcat(szDebugEventBuffer, "SINGLE_STEP"); 1.1 root 137: break; 138: 139: case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: 1.1.1.2 ! root 140: lstrcat(szDebugEventBuffer, "ARRAY_BOUNDS_EXCEEDED"); 1.1 root 141: break; 142: 143: case EXCEPTION_FLT_DIVIDE_BY_ZERO: 1.1.1.2 ! root 144: lstrcat(szDebugEventBuffer, "FLT_DIVIDE_BY_ZERO"); 1.1 root 145: break; 146: 147: case EXCEPTION_FLT_INVALID_OPERATION: 1.1.1.2 ! root 148: lstrcat(szDebugEventBuffer, "FLT_INVALID_OPERATION"); 1.1 root 149: break; 150: 151: case EXCEPTION_FLT_OVERFLOW: 1.1.1.2 ! root 152: lstrcat(szDebugEventBuffer, "FLT_OVERFLOW"); 1.1 root 153: break; 154: 155: case EXCEPTION_FLT_STACK_CHECK: 1.1.1.2 ! root 156: lstrcat(szDebugEventBuffer, "FLT_STACK_CHECK"); 1.1 root 157: break; 158: 159: case EXCEPTION_FLT_UNDERFLOW: 1.1.1.2 ! root 160: lstrcat(szDebugEventBuffer, "FLT_UNDERFLOW"); 1.1 root 161: break; 162: 163: case EXCEPTION_INT_DIVIDE_BY_ZERO: 1.1.1.2 ! root 164: lstrcat(szDebugEventBuffer, "INT_DIVIDE_BY_ZERO"); 1.1 root 165: break; 166: 167: case EXCEPTION_INT_OVERFLOW: 1.1.1.2 ! root 168: lstrcat(szDebugEventBuffer, "INT_OVERFLOW"); 1.1 root 169: break; 170: 171: case EXCEPTION_PRIV_INSTRUCTION: 1.1.1.2 ! root 172: lstrcat(szDebugEventBuffer, "PRIV_INSTRUCTION"); 1.1 root 173: break; 174: 175: default: 1.1.1.2 ! root 176: lstrcat(szDebugEventBuffer, "Unknown [0x"); ! 177: lstrcat(szDebugEventBuffer, 1.1 root 178: LongToCharUpper( (LONG) DebugEvent.u.Exception.ExceptionRecord.ExceptionCode, szTempBuf, 16) ); 1.1.1.2 ! root 179: lstrcat(szDebugEventBuffer, "]"); 1.1 root 180: break; 181: } 182: if( fVerbose ) { 1.1.1.2 ! root 183: lstrcat(szDebugEventBuffer, " - dwFirstChance:"); ! 184: lstrcat(szDebugEventBuffer, 1.1 root 185: LongToCharUpper( (LONG) DebugEvent.u.Exception.dwFirstChance, szTempBuf, 10) ); 186: } 187: else { 188: if(DebugEvent.u.Exception.dwFirstChance != 0) 1.1.1.2 ! root 189: lstrcat(szDebugEventBuffer, " - First Chance"); 1.1 root 190: else 1.1.1.2 ! root 191: lstrcat(szDebugEventBuffer, " - Second Chance"); 1.1 root 192: } 193: break; 194: 195: case CREATE_THREAD_DEBUG_EVENT: 196: MakeDebugEventString(szDebugEventBuffer, "Create Thread", 197: &DebugEvent); 198: if( fVerbose ) { 1.1.1.2 ! root 199: lstrcat(szDebugEventBuffer, " - hThread:0x"); ! 200: lstrcat(szDebugEventBuffer, 1.1 root 201: LongToCharUpper( (LONG) DebugEvent.u.CreateThread.hThread, szTempBuf, 16) ); 1.1.1.2 ! root 202: lstrcat(szDebugEventBuffer, " - lpStartAddress:0x"); ! 203: lstrcat(szDebugEventBuffer, 1.1 root 204: LongToCharUpper( (LONG) DebugEvent.u.CreateThread.lpStartAddress, szTempBuf, 16) ); 205: } 206: break; 207: 208: case CREATE_PROCESS_DEBUG_EVENT: 209: MakeDebugEventString(szDebugEventBuffer, "Create Process", 210: &DebugEvent); 211: if( fVerbose ) { 1.1.1.2 ! root 212: lstrcat(szDebugEventBuffer, " - hFile:0x"); ! 213: lstrcat(szDebugEventBuffer, 1.1 root 214: LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.hFile, szTempBuf, 16) ); 1.1.1.2 ! root 215: lstrcat(szDebugEventBuffer, " - hProcess:0x"); ! 216: lstrcat(szDebugEventBuffer, 1.1 root 217: LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.hProcess, szTempBuf, 16) ); 1.1.1.2 ! root 218: lstrcat(szDebugEventBuffer, " - hThread:0x"); ! 219: lstrcat(szDebugEventBuffer, 1.1 root 220: LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.hThread, szTempBuf, 16) ); 1.1.1.2 ! root 221: lstrcat(szDebugEventBuffer, " - lpBaseOfImage:0x"); ! 222: lstrcat(szDebugEventBuffer, 1.1 root 223: LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.lpBaseOfImage, szTempBuf, 16) ); 1.1.1.2 ! root 224: lstrcat(szDebugEventBuffer, " - dwDebugInfoFileOffset:"); ! 225: lstrcat(szDebugEventBuffer, 1.1 root 226: LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.dwDebugInfoFileOffset, szTempBuf, 10) ); 1.1.1.2 ! root 227: lstrcat(szDebugEventBuffer, " - nDebugInfoSize:"); ! 228: lstrcat(szDebugEventBuffer, 1.1 root 229: LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.nDebugInfoSize, szTempBuf, 10) ); 1.1.1.2 ! root 230: lstrcat(szDebugEventBuffer, " - lpStartAddress:0x"); ! 231: lstrcat(szDebugEventBuffer, 1.1 root 232: LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.lpStartAddress, szTempBuf, 16) ); 233: } 234: break; 235: 236: case EXIT_THREAD_DEBUG_EVENT: 237: MakeDebugEventString(szDebugEventBuffer, "Exit Thread", 238: &DebugEvent); 239: 240: if( fVerbose ) { 1.1.1.2 ! root 241: lstrcat(szDebugEventBuffer, " - dwExitCode:"); 1.1 root 242: } 243: else { 1.1.1.2 ! root 244: lstrcat(szDebugEventBuffer, " - Returned:"); 1.1 root 245: } 1.1.1.2 ! root 246: lstrcat(szDebugEventBuffer, 1.1 root 247: LongToCharUpper( (LONG) DebugEvent.u.ExitThread.dwExitCode, szTempBuf, 10) ); 248: break; 249: 250: case EXIT_PROCESS_DEBUG_EVENT: 251: MakeDebugEventString(szDebugEventBuffer, "Exit Process", 252: &DebugEvent); 253: if( fVerbose ) { 1.1.1.2 ! root 254: lstrcat(szDebugEventBuffer, " - dwExitCode:"); 1.1 root 255: } 256: else { 1.1.1.2 ! root 257: lstrcat(szDebugEventBuffer, " - Returned:"); 1.1 root 258: } 1.1.1.2 ! root 259: lstrcat(szDebugEventBuffer, 1.1 root 260: LongToCharUpper( (LONG) DebugEvent.u.ExitProcess.dwExitCode, szTempBuf, 10) ); 261: break; 262: 263: case LOAD_DLL_DEBUG_EVENT: 264: MakeDebugEventString(szDebugEventBuffer, "Load DLL:", 265: &DebugEvent); 266: 267: GetModuleFileNameFromHeader( 268: hProcess, DebugEvent.u.LoadDll.hFile, 1.1.1.2 ! root 269: szTempBuf, STRING_BUFSIZ ); ! 270: lstrcat( szDebugEventBuffer, szTempBuf ); 1.1 root 271: if( fVerbose ) { 1.1.1.2 ! root 272: lstrcat(szDebugEventBuffer, " - hFile:0x"); ! 273: lstrcat(szDebugEventBuffer, 1.1 root 274: LongToCharUpper( (LONG) DebugEvent.u.LoadDll.hFile, szTempBuf, 16) ); 1.1.1.2 ! root 275: lstrcat(szDebugEventBuffer, " - lpBaseOfDll:0x"); ! 276: lstrcat(szDebugEventBuffer, 1.1 root 277: LongToCharUpper( (LONG) DebugEvent.u.LoadDll.lpBaseOfDll, szTempBuf, 16) ); 1.1.1.2 ! root 278: lstrcat(szDebugEventBuffer, " - dwDebugInfoFileOffset:"); ! 279: lstrcat(szDebugEventBuffer, 1.1 root 280: LongToCharUpper( (LONG) DebugEvent.u.LoadDll.dwDebugInfoFileOffset, szTempBuf, 10) ); 1.1.1.2 ! root 281: lstrcat(szDebugEventBuffer, " - nDebugInfoSize:"); ! 282: lstrcat(szDebugEventBuffer, 1.1 root 283: LongToCharUpper( (LONG) DebugEvent.u.LoadDll.nDebugInfoSize, szTempBuf, 10) ); 284: } 285: break; 286: 287: case UNLOAD_DLL_DEBUG_EVENT: 288: MakeDebugEventString(szDebugEventBuffer, "Unload DLL", 289: &DebugEvent); 290: if( fVerbose ) { 1.1.1.2 ! root 291: lstrcat(szDebugEventBuffer, " - lpBaseOfDLL:0x"); ! 292: lstrcat(szDebugEventBuffer, 1.1 root 293: LongToCharUpper( (LONG) DebugEvent.u.UnloadDll.lpBaseOfDll, szTempBuf, 16) ); 294: } 295: break; 296: 297: case OUTPUT_DEBUG_STRING_EVENT: 298: MakeDebugEventString(szDebugEventBuffer, "Output Debug String", 299: &DebugEvent); 1.1.1.2 ! root 300: lstrcat(szDebugEventBuffer, ":\""); 1.1 root 301: 302: //-- According to Win32 Specs Rev3, I need to use ReadVirtualMemory 303: // however this incorrect. ReadProcessMemory is the correct API 304: ReadProcessMemory( hProcess, 305: DebugEvent.u.DebugString.lpDebugStringData, 306: szTempBuf, DebugEvent.u.DebugString.nDebugStringLength, 307: &NumberOfBytesRead ); 1.1.1.2 ! root 308: lstrcat(szDebugEventBuffer, szTempBuf ); ! 309: lstrcat(szDebugEventBuffer, "\"" ); 1.1 root 310: if( fVerbose ) { 1.1.1.2 ! root 311: lstrcat(szDebugEventBuffer, " - fUnicode:"); ! 312: lstrcat(szDebugEventBuffer, 1.1 root 313: LongToCharUpper( (LONG) DebugEvent.u.DebugString.fUnicode, szTempBuf, 10) ); 1.1.1.2 ! root 314: lstrcat(szDebugEventBuffer, " - nDebugStringLength:"); ! 315: lstrcat(szDebugEventBuffer, 1.1 root 316: LongToCharUpper( (LONG) DebugEvent.u.DebugString.nDebugStringLength, szTempBuf, 10) ); 317: } 318: break; 319: 320: default: 321: MakeDebugEventString(szDebugEventBuffer, "Debug Event:", 322: &DebugEvent); 1.1.1.2 ! root 323: lstrcat(szDebugEventBuffer, "Unknown [0x"); ! 324: lstrcat(szDebugEventBuffer, 1.1 root 325: LongToCharUpper( (LONG) DebugEvent.dwDebugEventCode, szTempBuf, 16) ); 1.1.1.2 ! root 326: lstrcat(szDebugEventBuffer, "]"); 1.1 root 327: break; 328: } 329: 330: //-- insert the debug event string into the listbox 331: ListBoxPrintF( "%s", szDebugEventBuffer ); 332: 333: //-- handle minimal exception handling needs for particular events 334: switch( DebugEvent.dwDebugEventCode ) { 335: 336: case EXCEPTION_DEBUG_EVENT: 337: switch( DebugEvent.u.Exception.ExceptionRecord.ExceptionCode ) { 338: 339: #if( MIPS == 1 ) 340: case STATUS_BREAKPOINT: 341: //-- increment instruction pointer past the break point 342: // only needed for the MIPS R4000 343: if( !SkipBreakPoint( DebugEvent.dwThreadId ) ) 344: ListBoxInsert( hWndDebugList, &MaxStrLen, 345: "--> Failed To skip over the Break Point" ); 346: break; 347: #endif 348: 349: case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: 350: case EXCEPTION_FLT_DIVIDE_BY_ZERO: 351: case EXCEPTION_FLT_INVALID_OPERATION: 352: case EXCEPTION_FLT_OVERFLOW: 353: case EXCEPTION_FLT_STACK_CHECK: 354: case EXCEPTION_FLT_UNDERFLOW: 355: case EXCEPTION_INT_DIVIDE_BY_ZERO: 356: case EXCEPTION_INT_OVERFLOW: 357: case EXCEPTION_PRIV_INSTRUCTION: 358: case STATUS_ACCESS_VIOLATION: 359: ContinueDebugEvent( DebugEvent.dwProcessId, DebugEvent.dwThreadId, 360: DBG_EXCEPTION_NOT_HANDLED ); 361: } 362: break; 363: 364: case CREATE_PROCESS_DEBUG_EVENT: 365: CreateNode( &ProcessList, &ThreadNode ); 366: (ThreadNode->NodeData).dwThreadId = DebugEvent.dwThreadId; 367: (ThreadNode->NodeData).hThread = DebugEvent.u.CreateProcessInfo.hThread; 368: InsertNode( &ProcessList, ThreadNode ); 369: if( ++ActiveProcesses == 1 ) { 370: //-- store the current process handle in the temp global handle 371: hProcess = DebugEvent.u.CreateProcessInfo.hProcess; 372: } 373: break; 374: 375: case CREATE_THREAD_DEBUG_EVENT: 376: CreateNode( &ProcessList, &ThreadNode ); 377: (ThreadNode->NodeData).dwThreadId = DebugEvent.dwThreadId; 378: (ThreadNode->NodeData).hThread = DebugEvent.u.CreateThread.hThread; 379: InsertNode( &ProcessList, ThreadNode ); 380: break; 381: 382: case EXIT_THREAD_DEBUG_EVENT: 383: (ThreadNode->NodeData).dwThreadId = DebugEvent.dwThreadId; 384: GetNode( &ProcessList, &ThreadNode, OrderFunc, 1 ); 385: DeleteCurrentNode( &ProcessList ); 386: break; 387: 388: case EXIT_PROCESS_DEBUG_EVENT: 389: //-- if the event was EXIT_PROCESS_DEBUG_EVENT and it was the 390: // original process opened/attached to then exit the 391: // debug event processing thread. Also do some cleanup first. 392: (ThreadNode->NodeData).dwThreadId = DebugEvent.dwThreadId; 393: GetNode( &ProcessList, &ThreadNode, OrderFunc, 1 ); 394: DeleteCurrentNode( &ProcessList ); 395: DestroyNode( TempNode ); 396: if( --ActiveProcesses == 0 ) { 1.1.1.2 ! root 397: // return( TRUE ); 1.1 root 398: ExitThread( TRUE ); 399: } 400: break; 401: } 402: 403: //-- default action - just continue 404: ContinueDebugEvent( DebugEvent.dwProcessId, DebugEvent.dwThreadId, 405: DBG_CONTINUE ); 406: } 407: 1.1.1.2 ! root 408: ExitThread( FALSE ); ! 409: ! 410: return( FALSE ); // avoid the "no return value" warning 1.1 root 411: } 412: 413: 414: // ************************************************************************ 415: // FUNCTION : GetModuleFileNameFromHeader( HANDLE, HANDLE, LPTSTR, DWORD ) 416: // PURPOSE : Retrieves the DLL module name for a given file handle of a 417: // the module. Reads the module name from the EXE header. 1.1.1.2 ! root 418: // COMMENTS : ! 419: // Retrieves only the module name and not the pathname. 1.1 root 420: // ************************************************************************ 1.1.1.2 ! root 421: DWORD WINAPI 1.1 root 422: GetModuleFileNameFromHeader( HANDLE hProcess, HANDLE hFile, LPTSTR lpszPath, 423: DWORD cbPath ) 424: { 425: #define IMAGE_DOS_SIGNATURE 0x5A4D // MZ 426: #define IMAGE_OS2_SIGNATURE 0x454E // NE 427: #define IMAGE_NT_SIGNATURE 0x00004550 // PE00 428: 429: #define IMAGE_SECOND_HEADER_OFFSET (15 * sizeof(ULONG)) // relative to file beginning 430: #define IMAGE_BASE_OFFSET (13 * sizeof(DWORD)) // relative to PE header base 431: #define IMAGE_EXPORT_TABLE_RVA_OFFSET (30 * sizeof(DWORD)) // relative to PE header base 432: #define IMAGE_NAME_RVA_OFFSET (3 * sizeof(DWORD)) // relative to Exports/Imports table base 433: 434: WORD DosSignature; 435: DWORD NtSignature; 436: DWORD NumberOfBytesRead; 437: 438: DWORD PeHeader, ImageBase, ExportTableRVA, NameRVA; 439: 440: //-- verify that the handle is not NULL 441: if( !hFile ) { 1.1.1.2 ! root 442: lstrcpy( lpszPath, "hFile is NULL!" ); 1.1 root 443: return( 0 ); 444: } 445: 446: //-- verify that the handle is for a disk file 447: if( GetFileType(hFile) != FILE_TYPE_DISK ) { 1.1.1.2 ! root 448: lstrcpy( lpszPath, "Incorrect hFile Type!" ); 1.1 root 449: return( 0 ); 450: } 451: 452: //-- Extract the filename from the EXE header 453: ReadFile( hFile, &DosSignature, sizeof(DosSignature), &NumberOfBytesRead, 454: (LPOVERLAPPED) NULL); 455: 456: if( DosSignature == IMAGE_DOS_SIGNATURE ) { 457: 458: SetFilePointer( hFile, IMAGE_SECOND_HEADER_OFFSET, (LPLONG) NULL, 459: FILE_BEGIN ); 460: ReadFile( hFile, &PeHeader, sizeof(PeHeader), 461: &NumberOfBytesRead, (LPOVERLAPPED) NULL ); 462: 463: SetFilePointer( hFile, PeHeader, (LPLONG) NULL, 464: FILE_BEGIN ); 465: ReadFile( hFile, &NtSignature, sizeof(NtSignature), 466: &NumberOfBytesRead, (LPOVERLAPPED) NULL); 467: 468: if( NtSignature == IMAGE_NT_SIGNATURE ) { 469: 470: SetFilePointer( hFile, PeHeader+IMAGE_BASE_OFFSET, 471: (LPLONG) NULL, FILE_BEGIN ); 472: ReadFile( hFile, &ImageBase, sizeof(ImageBase), 473: &NumberOfBytesRead, (LPOVERLAPPED) NULL); 474: 475: SetFilePointer( hFile, PeHeader + IMAGE_EXPORT_TABLE_RVA_OFFSET, 476: (LPLONG) NULL, FILE_BEGIN ); 477: ReadFile( hFile, &ExportTableRVA, sizeof(ExportTableRVA), 478: &NumberOfBytesRead, (LPOVERLAPPED) NULL); 479: 480: //-- now read from the virtual address space in the process 481: ReadProcessMemory( hProcess, 482: (LPVOID) (ImageBase + ExportTableRVA + IMAGE_NAME_RVA_OFFSET), 483: &NameRVA, sizeof(NameRVA), &NumberOfBytesRead ); 484: 485: ReadProcessMemory( hProcess, 486: (LPVOID) (ImageBase+NameRVA), 487: lpszPath, cbPath, &NumberOfBytesRead ); 488: 489: return( NumberOfBytesRead ); 490: } 491: else 1.1.1.2 ! root 492: wsprintf( lpszPath, "NtSignature is 0x%x!", NtSignature ); 1.1 root 493: 494: } 495: else 1.1.1.2 ! root 496: wsprintf( lpszPath, "DosSignature is 0x%x!", DosSignature ); 1.1 root 497: 498: return( 0 ); 499: } 500: 501: 502: #if( MIPS == 1 ) 503: // ************************************************************************ 504: // FUNCTION : SkipThreadBreakPoint( DWORD ); 505: // PURPOSE : Skip over the break point instruction belonging to 1.1.1.2 ! root 506: // dwThreadId. ! 507: // COMMENTS : ! 508: // Only the MIPS R4000 requires this. 1.1 root 509: // ************************************************************************ 510: BOOL 511: SkipBreakPoint( DWORD dwThreadId ) 512: { 513: CONTEXT Context; 514: PNODE ThreadNode; 515: PNODE InputNode; 516: 517: CreateNode( &ProcessList, &InputNode ); 518: ThreadNode = InputNode; 519: (InputNode->NodeData).dwThreadId = dwThreadId; 520: 521: if( GetNode( &ProcessList, &ThreadNode, OrderFunc, 1 ) == NO_MATCH_ERROR ) { 522: ListBoxInsert( hWndDebugList, &MaxStrLen, "--> Error: Node not found" ); 523: return( FALSE ); 524: } 525: 526: Context.ContextFlags = CONTEXT_CONTROL; 527: 528: if( !GetThreadContext( (ThreadNode->NodeData).hThread, &Context ) ) { 529: char szTempBuf[64]; 530: 1.1.1.2 ! root 531: wsprintf(szTempBuf, "--> Error: dwThreadId = 0x%8.8lx", dwThreadId ); 1.1 root 532: ListBoxInsert( hWndDebugList, &MaxStrLen, szTempBuf ); 1.1.1.2 ! root 533: wsprintf(szTempBuf, "--> Error: GetThreadContext( %lx ) failed, error 0x%8.8lx", 1.1 root 534: (DWORD) (ThreadNode->NodeData).hThread, 535: (DWORD) GetLastError() ); 536: ListBoxInsert( hWndDebugList, &MaxStrLen, szTempBuf); 537: 538: return( FALSE ); 539: } 540: 541: Context.Fir += 4L; // Fir is the PC (program counter) 542: // BREAK (breakpoint instruction) occupies 4 bytes 543: 544: // ----------------------------------------------------------------------- 545: // Below would be equvalent for the Intel 80x86 if it were necessary 546: // Context.Eip += 2L; // Eip is the PC (program counter) 547: // // int 3 (breakpoint instruction) occupies 2 bytes 548: // ----------------------------------------------------------------------- 549: 550: SetThreadContext( (ThreadNode->NodeData).hThread, &Context ); 551: DestroyNode( InputNode ); 552: 553: return( TRUE ); 554: } 555: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.