📄 bp.c
字号:
/*++
Copyright (c) 1998-2001 Klaus P. Gerlicher
Module Name:
bp.c
Abstract:
setting, listing and removing breakpoints
Environment:
LINUX 2.2.X
Kernel mode only
Author:
Klaus P. Gerlicher
Revision History:
13-Nov-1999: created
15-Nov-2000: general cleanup of source files
Copyright notice:
This file may be distributed under the terms of the GNU Public License.
--*/
////////////////////////////////////////////////////
// INCLUDES
////
#include "remods.h"
#include "precomp.h"
////////////////////////////////////////////////////
// GLOBALS
////
char tempBp[1024];
ULONG OldInt3Handler=0;
SW_BP aSwBreakpoints[64]={{0,0,0,0},};
//*************************************************************************
// FindSwBp()
//
//*************************************************************************
PSW_BP FindSwBp(ULONG ulAddress)
{
ULONG i;
for(i=0;i<DIM(aSwBreakpoints);i++)
{
if(aSwBreakpoints[i].ulAddress == ulAddress && aSwBreakpoints[i].bUsed==TRUE && aSwBreakpoints[i].bVirtual==FALSE)
return &aSwBreakpoints[i];
}
return NULL;
}
//*************************************************************************
// FindEmptySwBpSlot()
//
//*************************************************************************
PSW_BP FindEmptySwBpSlot(void)
{
ULONG i;
for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
{
if(aSwBreakpoints[i].bUsed == FALSE)
{
return &aSwBreakpoints[i];
}
}
return NULL;
}
//*************************************************************************
// FindVirtualSwBp()
//
//*************************************************************************
PSW_BP FindVirtualSwBp(LPSTR ModName,LPSTR szFunctionName)
{
ULONG i;
PSW_BP p;
for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
{
p = &aSwBreakpoints[i];
if(p->bUsed == TRUE &&
p->bVirtual == TRUE &&
PICE_strcmpi(p->szModName,ModName)==0 &&
PICE_strcmpi(p->szFunctionName,szFunctionName)==0)
{
return p;
}
}
return NULL;
}
//*************************************************************************
// IsSwBpAtAddressInstalled()
//
//*************************************************************************
BOOLEAN IsSwBpAtAddressInstalled(ULONG ulAddress)
{
ULONG i;
for(i=0;i<DIM(aSwBreakpoints);i++)
{
if(aSwBreakpoints[i].ulAddress == ulAddress &&
aSwBreakpoints[i].bUsed == TRUE &&
aSwBreakpoints[i].bInstalled &&
aSwBreakpoints[i].bVirtual == FALSE)
return TRUE;
}
return FALSE;
}
//*************************************************************************
// IsSwBpAtAddress()
//
//*************************************************************************
BOOLEAN IsSwBpAtAddress(ULONG ulAddress)
{
ULONG i;
for(i=0;i<DIM(aSwBreakpoints);i++)
{
if(aSwBreakpoints[i].ulAddress == ulAddress && aSwBreakpoints[i].bUsed==TRUE && aSwBreakpoints[i].bVirtual==FALSE)
return TRUE;
}
return FALSE;
}
//*************************************************************************
// NeedToReInstallSWBreakpoints()
//
//*************************************************************************
BOOLEAN NeedToReInstallSWBreakpoints(ULONG ulAddress,BOOLEAN bUseAddress)
{
PSW_BP p;
BOOLEAN bResult = FALSE;
ULONG i;
ENTER_FUNC();
DPRINT((0,"NeedToReInstallSWBreakpoint() for %x (bUseAddress = %s)\n",ulAddress,bUseAddress?"TRUE":"FALSE"));
for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
{
p = &aSwBreakpoints[i];
if(bUseAddress)
{
if(p->bUsed == TRUE && p->bInstalled == FALSE && p->ulAddress==ulAddress && p->bVirtual==FALSE)
{
if(IsAddressValid(p->ulAddress))
{
DPRINT((0,"NeedToReInstallSWBreakpoint(): [1] found BP\n"));
bResult = TRUE;
break;
}
}
}
else
{
if(p->bUsed == TRUE && p->bInstalled == FALSE && p->bVirtual == FALSE)
{
if(IsAddressValid(p->ulAddress))
{
DPRINT((0,"NeedToReInstallSWBreakpoint(): [2] found BP\n"));
bResult = TRUE;
break;
}
}
}
}
LEAVE_FUNC();
return bResult;
}
//*************************************************************************
// ReInstallSWBreakpoint()
//
//*************************************************************************
BOOLEAN ReInstallSWBreakpoint(ULONG ulAddress)
{
PSW_BP p;
BOOLEAN bResult = FALSE;
ULONG i;
ENTER_FUNC();
DPRINT((0,"ReInstallSWBreakpoint()\n"));
for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
{
p = &aSwBreakpoints[i];
if(p->bUsed == TRUE && p->bInstalled == FALSE && p->ulAddress == ulAddress && p->bVirtual == FALSE)
{
if(IsAddressValid(p->ulAddress))
{
BOOLEAN isWriteable;
if( !( isWriteable = IsAddressWriteable(p->ulAddress) ) )
SetAddressWriteable(p->ulAddress,TRUE);
*(PUCHAR)(p->ulAddress) = 0xCC;
if( !isWriteable )
SetAddressWriteable(p->ulAddress,FALSE);
p->bInstalled = TRUE;
bResult = TRUE;
}
}
}
LEAVE_FUNC();
return bResult;
}
//*************************************************************************
// InstallSWBreakpoint()
//
//*************************************************************************
BOOLEAN InstallSWBreakpoint(ULONG ulAddress,BOOLEAN bPermanent,void (*SWBreakpointCallback)(void))
{
PSW_BP p;
BOOLEAN bResult = FALSE;
ENTER_FUNC();
DPRINT((0,"InstallSWBreakpoint()\n"));
// check if page is present
// TODO: must also check if it's a writable page
if(IsAddressValid(ulAddress) )
{
DPRINT((0,"InstallSWBreakpoint(): %.8X is valid, writable? %d\n",ulAddress,IsAddressWriteable(ulAddress)));
DPRINT((0,"pde: %x, pte: %x\n", *(ADDR_TO_PDE(ulAddress)), *(ADDR_TO_PTE(ulAddress))));
if((p = FindSwBp(ulAddress))==NULL)
{
DPRINT((0,"InstallSWBreakpoint(): %.8X is free\n",ulAddress));
if( (p=FindEmptySwBpSlot()) )
{
BOOLEAN isWriteable;
DPRINT((0,"InstallSWBreakpoint(): found empty slot\n"));
DPRINT((0,"InstallSWBreakpoint(): %x value: %x", ulAddress, *(PUCHAR)ulAddress));
p->ucOriginalOpcode = *(PUCHAR)ulAddress;
//allow writing to page
if( !( isWriteable = IsAddressWriteable(ulAddress) ) )
SetAddressWriteable(ulAddress,TRUE);
DPRINT((0,"writing breakpoint\n"));
*(PUCHAR)ulAddress = 0xCC;
DPRINT((0,"restoring page access\n"));
if( !isWriteable )
SetAddressWriteable(ulAddress,FALSE);
p->bUsed = TRUE;
p->bInstalled = TRUE;
// find next address
p->ulAddress = ulAddress;
Disasm(&ulAddress,(PUCHAR)&tempBp);
p->ulNextInstr = ulAddress;
p->bPermanent = bPermanent;
if(bPermanent)
p->Callback = SWBreakpointCallback;
else
p->Callback = NULL;
bResult = TRUE;
}
}
else
{
DPRINT((0,"InstallSWBreakpoint(): %.8X is already used\n",ulAddress));
if(p->bPermanent)
{
DPRINT((0,"InstallSWBreakpoint(): %.8X is a permanent breakpoint\n",ulAddress));
}
}
}
LEAVE_FUNC();
return bResult;
}
//*************************************************************************
// InstallVirtualSWBreakpoint()
//
//*************************************************************************
BOOLEAN InstallVirtualSWBreakpoint(LPSTR ModName,LPSTR FunctionName)
{
PSW_BP p;
BOOLEAN bResult = FALSE;
ENTER_FUNC();
DPRINT((0,"InstallVirtualSWBreakpoint(%s!%s)\n",ModName,FunctionName));
if( (p=FindEmptySwBpSlot()) )
{
DPRINT((0,"InstallVirtualSWBreakpoint(): found empty slot\n"));
p->bUsed = TRUE;
p->bInstalled = TRUE;
p->bVirtual = TRUE;
p->Callback = NULL;
PICE_strcpy(p->szModName,ModName);
PICE_strcpy(p->szFunctionName,FunctionName);
bResult = TRUE;
}
LEAVE_FUNC();
return bResult;
}
//*************************************************************************
// TryToInstallVirtualSWBreakpoints()
//
//*************************************************************************
void TryToInstallVirtualSWBreakpoints(void)
{
ULONG i,ulAddress;
PDEBUG_MODULE pMod;
PSW_BP p;
DPRINT((0,"TryToInstallVirtualSWBreakpoints()\n"));
for(i=0;i<(sizeof(aSwBreakpoints)/sizeof(SW_BP));i++)
{
p = &aSwBreakpoints[i];
if(p->bUsed == TRUE && p->bVirtual)
{
if((pMod = IsModuleLoaded(p->szModName)))
{
if((ulAddress = FindFunctionInModuleByName(p->szFunctionName,pMod)))
{
if((p = FindVirtualSwBp(p->szModName,p->szFunctionName)))
{
ULONG ulAddressWithOffset = ulAddress+p->ulAddress;
DPRINT((0,"TryToInstallVirtualSWBreakpoints(): ulAddressWithOffset = %x (offset = %x)\n",ulAddressWithOffset,p->ulAddress));
if(IsAddressValid(ulAddressWithOffset))
{
BOOLEAN isWriteable;
DPRINT((0,"TryToInstallVirtualSWBreakpoints(): installing...\n"));
p->ucOriginalOpcode = *(PUCHAR)ulAddressWithOffset;
//allow writing to page
if( !( isWriteable = IsAddressWriteable(ulAddressWithOffset) ) )
SetAddressWriteable(ulAddressWithOffset,TRUE);
*(PUCHAR)ulAddressWithOffset = 0xCC;
if( !isWriteable )
SetAddressWriteable(ulAddressWithOffset,FALSE);
p->bUsed = TRUE;
p->bInstalled = TRUE;
p->bVirtual = FALSE;
// find next address
p->ulAddress = ulAddressWithOffset;
Disasm(&ulAddressWithOffset,(PUCHAR)&tempBp);
p->ulNextInstr = ulAddressWithOffset;
p->bPermanent = FALSE;
p->Callback = NULL;
}
else
{
DPRINT((0,"TryToInstallVirtualSWBreakpoints(): not valid address\n"));
PICE_memset(p,0,sizeof(*p));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -