Windows NT 4.0 source code leak
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

#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 );
}