mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
265 lines
6.5 KiB
265 lines
6.5 KiB
#include "master.hxx"
|
|
#pragma hdrstop
|
|
|
|
BYTE BUFFER_BREAKPOINT_OPCODE[SIZEOF_BREAKPOINT_OPCODE]={BREAKPOINT_OPCODE};
|
|
|
|
|
|
BOOL
|
|
RemoveRemoteBreakpoint
|
|
(
|
|
IN PBREAKPOINT_RECORD pBreakpointRecord
|
|
)
|
|
{
|
|
PLIST_ENTRY pEntry;
|
|
|
|
if ( !DisableRemoteBreakpoint( pBreakpointRecord ) )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
pBreakpointRecord->References --;
|
|
|
|
if ( pBreakpointRecord->References == 0 )
|
|
{
|
|
pEntry = (PLIST_ENTRY)pBreakpointRecord;
|
|
pEntry--;
|
|
|
|
ASSERT( SanityCheckListEntry( pEntry ) );
|
|
|
|
RemoveEntryList( pEntry );
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
BOOL
|
|
DisableRemoteBreakpoint
|
|
(
|
|
IN PBREAKPOINT_RECORD pBreakpointRecord
|
|
)
|
|
{
|
|
BYTE OldOpCode[SIZEOF_BREAKPOINT_OPCODE];
|
|
|
|
if( !ReadProcessMemory( pBreakpointRecord->hProcess,
|
|
pBreakpointRecord->pvAddress,
|
|
&OldOpCode,
|
|
SIZEOF_BREAKPOINT_OPCODE,
|
|
NULL ) )
|
|
{
|
|
DebugPrintf( "DisableRemoteBreakpoint: cannot read instruction, error %lu\n", GetLastError() );
|
|
return( FALSE );
|
|
}
|
|
|
|
if ( RtlCompareMemory( OldOpCode, BUFFER_BREAKPOINT_OPCODE, SIZEOF_BREAKPOINT_OPCODE ) !=
|
|
SIZEOF_BREAKPOINT_OPCODE )
|
|
{
|
|
DebugPrintf( "DisableRemoteBreakpoint: Old code not breakpoint.\n" );
|
|
return( FALSE );
|
|
}
|
|
|
|
if( !WriteProcessMemory( pBreakpointRecord->hProcess,
|
|
pBreakpointRecord->pvAddress,
|
|
pBreakpointRecord->OldOpCode,
|
|
SIZEOF_BREAKPOINT_OPCODE,
|
|
NULL ) )
|
|
{
|
|
DebugPrintf( "DisableRemoteBreakpoint: cannot write old opcode, error %lu\n", GetLastError() );
|
|
return( FALSE );
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
BOOL
|
|
EnableRemoteBreakpoint
|
|
(
|
|
IN PBREAKPOINT_RECORD pBreakpointRecord
|
|
)
|
|
{
|
|
if( !WriteProcessMemory( pBreakpointRecord->hProcess,
|
|
pBreakpointRecord->pvAddress,
|
|
BUFFER_BREAKPOINT_OPCODE,
|
|
SIZEOF_BREAKPOINT_OPCODE,
|
|
NULL ) )
|
|
{
|
|
DebugPrintf( "EnableRemoteBreakpoint: cannot write breakpoint opcode, error %lu\n", GetLastError() );
|
|
return( FALSE );
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
BOOL
|
|
SetRemoteBreakpointOnFunctionReturn
|
|
(
|
|
IN HANDLE hProcess,
|
|
IN HANDLE hThread,
|
|
IN OUT PLIST_ENTRY pList,
|
|
IN PBREAKPOINT_RECORD pAssociatedBreakpoint
|
|
)
|
|
{
|
|
PVOID pvReturnAddress;
|
|
CONTEXT Context;
|
|
|
|
Context.ContextFlags = CONTEXT_FULL;
|
|
|
|
if ( !GetThreadContext( hThread, &Context ) )
|
|
{
|
|
DebugPrintf( "FixupRemoteReturnAddress: cannot get context, error %lu\n", GetLastError() );
|
|
return( FALSE );
|
|
}
|
|
|
|
if( !ReadProcessMemory( hProcess,
|
|
(PVOID)Context.Esp,
|
|
&pvReturnAddress,
|
|
sizeof( pvReturnAddress ),
|
|
NULL ) )
|
|
{
|
|
DebugPrintf( "SetRemoteBreakpointOnFunctionReturn: cannot read return address, error %lu\n", GetLastError() );
|
|
return( FALSE );
|
|
}
|
|
|
|
return( SetRemoteBreakpointAssociated( hProcess,
|
|
pvReturnAddress,
|
|
pList,
|
|
pAssociatedBreakpoint ) );
|
|
}
|
|
|
|
BOOL
|
|
SetRemoteBreakpoint
|
|
(
|
|
IN HANDLE hProcess,
|
|
IN PVOID pvRemoteAddr,
|
|
IN OUT PLIST_ENTRY pList
|
|
)
|
|
{
|
|
return( SetRemoteBreakpointAssociated( hProcess, pvRemoteAddr, pList, NULL ) );
|
|
}
|
|
|
|
|
|
BOOL
|
|
SetRemoteBreakpointAssociated
|
|
(
|
|
IN HANDLE hProcess,
|
|
IN PVOID pvRemoteAddr,
|
|
IN OUT PLIST_ENTRY pList,
|
|
IN PBREAKPOINT_RECORD pAssociatedBreakpoint
|
|
)
|
|
{
|
|
PLIST_ENTRY pEntry;
|
|
PBREAKPOINT_RECORD pBreakpointRecord;
|
|
|
|
pBreakpointRecord = GetBreakpointRecord( hProcess, pvRemoteAddr, pList );
|
|
|
|
if ( pBreakpointRecord != NULL )
|
|
{
|
|
ASSERT( pAssociatedBreakpoint == pBreakpointRecord->pAssociatedBreakpoint );
|
|
pBreakpointRecord->References ++;
|
|
}
|
|
|
|
ASSERT( SanityCheckListEntry( pList ) );
|
|
|
|
pEntry = ( PLIST_ENTRY )LocalAlloc( LPTR, sizeof( LIST_ENTRY ) + sizeof( BREAKPOINT_RECORD ) );
|
|
|
|
if ( pEntry == NULL )
|
|
{
|
|
DebugPrintf( "ERROR: Heaper out of memory creating breakpoint.\n" );
|
|
return( FALSE );
|
|
}
|
|
|
|
pBreakpointRecord = (PBREAKPOINT_RECORD)( pEntry + 1 );
|
|
|
|
if( !ReadProcessMemory( hProcess,
|
|
pvRemoteAddr,
|
|
&pBreakpointRecord->OldOpCode,
|
|
SIZEOF_BREAKPOINT_OPCODE,
|
|
NULL ) )
|
|
{
|
|
DebugPrintf( "SetRemoteBreakpoint: cannot read instruction, error %lu\n", GetLastError() );
|
|
LocalFree( pEntry );
|
|
return( FALSE );
|
|
}
|
|
|
|
if( !WriteProcessMemory( hProcess,
|
|
pvRemoteAddr,
|
|
BUFFER_BREAKPOINT_OPCODE,
|
|
SIZEOF_BREAKPOINT_OPCODE,
|
|
NULL ) )
|
|
{
|
|
DebugPrintf( "SetRemoteBreakpoint: cannot write bp opcode, error %lu\n", GetLastError() );
|
|
LocalFree( pEntry );
|
|
return( FALSE );
|
|
}
|
|
|
|
pBreakpointRecord->hProcess = hProcess;
|
|
pBreakpointRecord->pvAddress = pvRemoteAddr;
|
|
pBreakpointRecord->pAssociatedBreakpoint = pAssociatedBreakpoint;
|
|
pBreakpointRecord->References = 1;
|
|
|
|
InsertTailList( pList, pEntry );
|
|
|
|
if ( Debug>0 )
|
|
{
|
|
ASSERT( SanityCheckListEntry( pList ) );
|
|
ASSERT( SanityCheckListEntry( pEntry ) );
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
PBREAKPOINT_RECORD
|
|
GetBreakpointRecord
|
|
(
|
|
HANDLE hProcess,
|
|
LPVOID pvAddress,
|
|
PLIST_ENTRY pList
|
|
)
|
|
{
|
|
PLIST_ENTRY pEntry;
|
|
PBREAKPOINT_RECORD pBreakpointRecord;
|
|
|
|
for ( pEntry = pList->Flink;
|
|
pEntry != pList;
|
|
pEntry = pEntry->Flink )
|
|
{
|
|
pBreakpointRecord = (PBREAKPOINT_RECORD)(pEntry+1);
|
|
|
|
if ( pBreakpointRecord->hProcess == hProcess &&
|
|
pBreakpointRecord->pvAddress == pvAddress )
|
|
{
|
|
return( pBreakpointRecord );
|
|
}
|
|
}
|
|
|
|
return( NULL );
|
|
}
|
|
|
|
BOOL
|
|
ContinuePastBreakpoint
|
|
(
|
|
IN HANDLE hThread
|
|
)
|
|
{
|
|
CONTEXT Context;
|
|
|
|
Context.ContextFlags = CONTEXT_FULL;
|
|
|
|
if ( !GetThreadContext( hThread, &Context ) )
|
|
{
|
|
DebugPrintf( "FixupRemoteReturnAddress: cannot get context, error %lu\n", GetLastError() );
|
|
return( FALSE );
|
|
}
|
|
|
|
Context.Eip -= SIZEOF_BREAKPOINT_OPCODE;
|
|
|
|
if ( !SetThreadContext( hThread, &Context ) )
|
|
{
|
|
DebugPrintf( "FixupRemoteReturnAddress: cannot set context, error %lu\n", GetLastError() );
|
|
return( FALSE );
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|