📄 debdebug.c
字号:
//-- verify DOS signature found
if( DosSignature != IMAGE_DOS_SIGNATURE ) {
wsprintf( lpszPath, TEXT( "Bad MZ Signature: 0x%x" ), DosSignature );
return( 0 );
}
SetFilePointer( hFile, IMAGE_SECOND_HEADER_OFFSET, (LPLONG) NULL,
FILE_BEGIN );
ReadFile( hFile, &PeHeader, sizeof(PeHeader), &dwNumberOfBytesRead,
(LPOVERLAPPED) NULL );
SetFilePointer( hFile, PeHeader, (LPLONG) NULL, FILE_BEGIN );
ReadFile( hFile, &NtSignature, sizeof(NtSignature), &dwNumberOfBytesRead,
(LPOVERLAPPED) NULL);
//-- verify Windows NT (PE) signature found
if( NtSignature != IMAGE_NT_SIGNATURE ) {
wsprintf( lpszPath, TEXT( "Bad PE Signature: 0x%x" ), DosSignature );
return( 0 );
}
SetFilePointer( hFile, PeHeader + IMAGE_BASE_OFFSET, (LPLONG) NULL,
FILE_BEGIN );
ReadFile( hFile, &ImageBase, sizeof(ImageBase), &dwNumberOfBytesRead,
(LPOVERLAPPED) NULL);
SetFilePointer( hFile, PeHeader + IMAGE_EXPORT_TABLE_RVA_OFFSET,
(LPLONG) NULL, FILE_BEGIN );
ReadFile( hFile, &ExportTableRVA, sizeof(ExportTableRVA),
&dwNumberOfBytesRead, (LPOVERLAPPED) NULL);
//-- now read from the virtual address space in the process
ReadProcessMemory( hProcess,
(LPVOID) (BaseOfDll + ExportTableRVA + IMAGE_NAME_RVA_OFFSET),
&NameRVA, sizeof(NameRVA), &dwNumberOfBytesRead );
lstrcpy( lpszPath, TEXT("Empty!") );
if( !ReadProcessMemory( hProcess,
(LPVOID) (BaseOfDll + NameRVA),
lpszPath, cchPath, &dwNumberOfBytesRead ) )
lstrcpy( lpszPath, TEXT("Access Denied!") );
return( dwNumberOfBytesRead );
}
#if defined(_MIPS_) || defined(_ALPHA_) || defined(_PPC_)
// ************************************************************************
// FUNCTION : SkipThreadBreakPoint( HANDLE );
// PURPOSE : Skip over the break point instruction belonging to
// hThread.
// COMMENTS :
// Only the MIPS R4x00 and DEC Alpha AXP require this.
// ************************************************************************
BOOL
SkipBreakPoint( HANDLE hThread )
{
static CONTEXT Context;
Context.ContextFlags = CONTEXT_CONTROL;
if( !GetThreadContext( hThread, &Context ) )
return( FALSE );
#if defined(_PPC_)
Context.Iar += 4L; // Iar is the PC (program counter)
#else
Context.Fir += 4L; // Fir is the PC (program counter)
// BREAK (breakpoint instruction) occupies 4 bytes
#endif
// -----------------------------------------------------------------------
// Below would be equivalent for the Intel 80x86 (if it were necessary)
// however the Intel x86 automatically increments ip past the 'int 3':
// Context.Eip += 1L; // Eip is the PC (program counter)
// // int 3 (breakpoint instruction) occupies 1 byte
// -----------------------------------------------------------------------
if( !SetThreadContext( hThread, &Context ) )
return( FALSE );
return( TRUE );
}
#endif
// ========================================================================
// wrapper functions to the linked list services
// ========================================================================
// ========================================================================
// Debug Event Browser Data Structure Overview
// -------------------------------------------
//
// The Debug Event Browser (DEB) maintains a rather involved data structure
// to store various debug event and debuggee process information. It
// attempts to encapsulate the intricacies of what makes a process based on
// the occuring events. Much of this stored information is never utilized
// by the Debug Event Browser but it is included to demonstrate what types
// of debug event may be useful to a full blown debugger application.
//
// This data structure uses the generalized, sorted, double-linked list
// package provided with the sample. Each list can store list-specific
// instance data, list-specific node data, and maintain various pointers
// to these nodes. The list is sorted via the insertion sort method where
// the programmer defines the list-specific sort function whose purpose is
// to compare two given nodes and return their relative sort location. The
// list package in generalized in the sense that the list and node-specific
// data type is not known to this package at compile time or at runtime.
// The application programmer is merely responsible for defining the list
// and node-specific data structures and the sorting and optional searching
// functions and the list package keeps track of these nodes and provides
// easy access to them.
//
// DEB uses this list package to create three unique list types: process,
// thread and DLL lists.
//
// The backbone of the data structure is the process list. The nodes of
// the process list are the individual debuggee processes. DEB allows
// debugging (or should I say debug event browsing) of other processes that
// are spawned by the initial debuggee. Thus each debug session may have
// multiple debuggees and thus the process becomes the logical node unit.
//
// A visual diagram of the process list is as follows:
//
// (ProcessList)
// |
// |
// v
// +-----------------+ +----------------------+
// | -ProcessList- | | -ListData- |
// | | | |
// | ListData--------+---------->| ActiveProcessCount=N |
// +-----+-FirstNode | +----------------------+
// | +-+ CurrentNode |
// | | | LastNode--------+-----------------------+
// | | | OrderFunction=& | |
// | | | ListError=0 | |
// | | +-----------------+ |
// | | |
// | +-------------------+ |
// | | |
// v v v
// +------------+ +------------+ +------------+
// NULL <- |ProcessNode1| <=> |ProcessNode2| <=> ... <=> |ProcessNodeN| -> NULL
// +------------+ +------------+ +------------+
//
// Each process node also contains two lists: the thread list and the DLL list.
// This node also stores some of the relevent debug event information
// particular to the create process event. Visually it is as follows:
//
// +------------------+ +--------------+
// | -ProcessNode- | +------>| -ThreadList- |
// | | | +--------------+
// | ProcessID=0 | |
// | ThreadID=0 | | +-----------+
// | FileName="" | | +-->| -DllList- |
// | PathName="" | | | +-----------+
// | ThreadList-------+-+ |
// | DllList----------+-----+ +-------------------+
// | ProcessDebugInfo-+-------->|-ProcessDebugInfo- |
// +------------------+ +-------------------+
//
// Much like the process list, the visual diagram of the thread list is as
// follows:
//
// +-----------------+ +---------------------+
// | -ThreadList- | | -ListData- |
// | | | |
// | ListData--------+---------->| ActiveThreadCount=N |
// +-----+-FirstNode | +---------------------+
// | +-+ CurrentNode |
// | | | LastNode--------+-----------------------+
// | | | OrderFunction=& | |
// | | | ListError=0 | |
// | | +-----------------+ |
// | | |
// | +-------------------+ |
// | | |
// v v v
// +-----------+ +-----------+ +-----------+
// NULL <- |ThreadNode1| <=> |ThreadNode2| <=> ... <=> |ThreadNodeN| -> NULL
// +-----------+ +-----------+ +-----------+
//
// The thread nodes store some of the relevent debug event information
// particular to the create thread event. Visually it is as follows:
//
// +--------------------+
// | -ThreadNode- |
// | |
// | ProcessID=0 |
// | ThreadID=0 |
// | ThreadDebugInfo={} |
// +--------------------+
//
// Much like the process and thread lists, the visual diagram of the Dll list
// is as follows:
//
// +-----------------+ +------------------+
// | -DllList- | | -ListData- |
// | | | |
// | ListData--------+---------->| ActiveDllCount=N |
// +-----+-FirstNode | +------------------+
// | +-+ CurrentNode |
// | | | LastNode--------+-----------------+
// | | | OrderFunction=& | |
// | | | ListError=0 | |
// | | +-----------------+ |
// | | |
// | +-------------+ |
// | | |
// v v v
// +--------+ +--------+ +--------+
// NULL <- |DllNode1| <=> |DllNode2| <=> ... <=> |DllNodeN| -> NULL
// +--------+ +--------+ +--------+
//
// The Dll nodes store some of the relevent debug event information particular
// to the Dll load event. Visually it is as follows:
//
// +----------------+
// | -DllNode- |
// | |
// | FileName="" |
// | PathName="" |
// | DllDebugInfo={}|
// +----------------+
//
// ========================================================================
// ------------------------------------------------------------------------
// Process list and node specific linked list wrapper functions
// ------------------------------------------------------------------------
// ************************************************************************
// FUNCTION : ProcessOrderFunction( PNODE, PNODE );
// PURPOSE : Provides the sorting/search logic for the double linked
// list package.
// COMMENTS :
// Sorted by process ID value
// ************************************************************************
int
ProcessOrderFunction( PNODE pNode1, PNODE pNode2 )
{
PDEB_PROCESS_NODE_INFO pProcessNodeInfo1 = pNode1->pNodeData;
PDEB_PROCESS_NODE_INFO pProcessNodeInfo2 = pNode2->pNodeData;
if( pProcessNodeInfo1->dwProcessId < pProcessNodeInfo2->dwProcessId )
return( LIST_LEFT_OF );
if( pProcessNodeInfo1->dwProcessId > pProcessNodeInfo2->dwProcessId )
return( LIST_RIGHT_OF );
return( LIST_MATCH );
}
// ************************************************************************
// FUNCTION : CreateProcessList( PLIST* )
// PURPOSE :
// COMMENTS :
//
// ************************************************************************
BOOL
CreateProcessList( PLIST* ppProcessList )
{
PDEB_PROCESS_LIST_INFO pProcessListInfo;
//-- create list
CreateList( ppProcessList, ProcessOrderFunction );
//-- alloc info data
pProcessListInfo = (PDEB_PROCESS_LIST_INFO) HeapAlloc( hHeap, (DWORD) NULL,
sizeof( DEB_PROCESS_LIST_INFO ) );
(*ppProcessList)->pListData = pProcessListInfo;
//-- init info data
pProcessListInfo->dwActiveProcesses = 0;
return( TRUE );
}
// ************************************************************************
// FUNCTION : DestroyProcessList( PLIST )
// PURPOSE :
// COMMENTS :
//
// ************************************************************************
BOOL
DestroyProcessList( PLIST pProcessList )
{
PDEB_PROCESS_LIST_INFO pProcessListInfo = pProcessList->pListData;
PNODE pDeleteNode;
//-- make sure all nodes are removed first
while( pProcessListInfo->dwActiveProcesses ) {
GetCurrentNode( pProcessList, &pDeleteNode );
DeleteCurrentProcessNode( pProcessList );
}
//-- free info data
HeapFree( hHeap, (DWORD) NULL, (PVOID) pProcessListInfo );
//-- destroy list
DestroyList( pProcessList );
return( TRUE );
}
// ************************************************************************
// FUNCTION : AllocProcessNode( PNODE*, PDEB_PROCESS_NODE_INFO* )
// PURPOSE :
// COMMENTS :
//
// ************************************************************************
BOOL
AllocProcessNode( PNODE* ppProcessNode, PDEB_PROCESS_NODE_INFO* ppProcessNodeInfo )
{
//-- create node
CreateNode( ppProcessNode );
//-- alloc info data
*ppProcessNodeInfo = (PDEB_PROCESS_NODE_INFO) HeapAlloc( hHeap, (DWORD) NULL,
sizeof( DEB_PROCESS_NODE_INFO ) );
(*ppProcessNode)->pNodeData = *(ppProcessNodeInfo);
(*ppProcessNodeInfo)->lpstrFileName = (LPTSTR) HeapAlloc( hHeap, (DWORD) NULL,
(DWORD) MAX_PATH );
(*ppProcessNodeInfo)->lpstrPathName = (LPTSTR) HeapAlloc( hHeap, (DWORD) NULL,
(DWORD) MAX_PATH );
CreateThreadList( &((*ppProcessNodeInfo)->pThreadList) );
CreateDllList( &((*ppProcessNodeInfo)->pDllList) );
return( TRUE );
}
// ************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -