📄 bpint.cpp
字号:
// BPINT Plugs for TRW2000 for Windows 9x
// Copyright (C) , 1999-2000 ,
//
// Author:
// Zhunanhao, reached at nhzhu@163.net
//
// History :
// 2000.2.23 Zhunanhao write origin code
//
// Note:
// This is only a DEMO ! And testing NOT completed, do NOT use BPINT 3, or it'll crash!
//
// Please, DO NOT develop any breakpoint plug-ins now! Because we are
// developing breakpoint-system now, all interface of breakpoint-system
// maybe changed!
//
#include <wdm.h>
#include "..\INCLUDE\PLUGS.H"
// prototypes
EXC NTSTATUS
DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
VOID
PLUGS_Unload(IN PDRIVER_OBJECT DriverObject);
NTSTATUS
DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
DriverObject->DriverUnload = PLUGS_Unload;
return ntStatus;
}
VOID
PLUGS_Unload(IN PDRIVER_OBJECT DriverObject)
{
}
/****************** WDM Rountine End ****************/
// prototype
BOOL cmd_BPINT( int argc,char** argv ) ;
// end
PLUGS_API* api = 0 ;
// Call TRW2000 API must like this:
// api->Add_Command ( ) ;
EXC EXPORT BOOL Plugs_Init ( PLUGS_API* plugsapi)
{
api=plugsapi;
api->Add_Command ( "BPINT" , "interrupt-number" ,
"Breakpoint on interrupt" ,
"BPINT 3\tBPINT 21",
cmd_BPINT ) ;
api->dprintf ( "BPINT Plugs Ver 0.01 Initialized..." ) ;
return TRUE ;
}
EXC EXPORT BOOL Plugs_Exit ( )
{
return TRUE ;
}
/***************** Command ***************/
// Command : NPINT
// NOTE:
// This is only a demo, it DO NOT call any breakpoint-system function of TRW2000,
// so you can not use BC to clear it. It's not a real breakpoint that recognized
// by TRW2000.
// It's too bad. But maybe it will be improved. We'll change the breakpoint-system
// of TRW2000. Export more functions.
//
// Now use -R to clear it.
//
WORD IntBPid=0x1000;
BOOL myIntBPhandle()
{
if( *(api->pActive_BP_ID)!=IntBPid )
return FALSE;
// Does the action "Enter Kernel" caused by breakpoint?
// Is yes, Active_BP_ID include the id of breakpoint,
// or Active_BP_ID is 0xFFFF.
api->unhook(api->hh_PreEnterKernel,myIntBPhandle);
api->DeleteBP((BYTE)IntBPid);
return FALSE;
// In the step "PreEnterKernel", you have a chance to prevent to enter kernel,
// if you return TRUE, TRW2000 will exit to kernel directly. Or return FALSE,
// TRW2000 will be actived.
}
DWORD HookIntNum=0xFFFFFFFF;
BOOL myinthandler(DWORD intnum)
{
if( HookIntNum!=intnum )
return FALSE;
// Return FALSE means that put this interrupt to the next handler.
// If there is no next handler, TRW2000 will pass this interrupt
// to Windows.
if( api->GetTraceFlag()==TRUE )
return FALSE;
// what is GetTraceFlag? If user use F8(T) to trace program, this flag will be set,
// When user press F8, we can NOT capture the interrupt.
if( *(api->pfSoft_1Step)==TRUE )
return FALSE;
// what is fSoft_1Step? It means that some part of TRW2000( maybe a plug-ins) need that
// the code debugged run one step then return to TRW2000. For example, breakpoint-system
// set this to set INT 3. In this state, we can NOT capture the interrupt too!
// The difference of fSoft1_Step and TraceFlag is TraceFlag is readable, fSoft_1Step is
// full-access. You can set it to do some special functions. But must be carefully, we
// recommend you e-mail us first to get advanced document, if you want to use fSoft_1Step.
// Add your check proc here.
// e.g:
// if( api->pUser->CRS.Client_EAX!=0x12345678 )
// return FALSE;
// This means that if EAX of code debugged is not 0x12345678, TRW2000 will not be active.
//
// And, you can add your "DO" code here.
// e.g:
api->dprintf("Break due on interrupt %02X",intnum);
// This means print a line to command window.
api->Set_Enter_Kernel();
// Active TRW2000!
ADDRE addr;
BYTE opcode;
BYTE opdata;
BOOL fFault=FALSE;
api->CurCSEIP(&addr);
addr._off--;
if( api->PeekB(&addr,&opdata)==FALSE ) // Can readable?
fFault=TRUE;
addr._off--;
if( api->PeekB(&addr,&opcode)==FALSE ) // Can readable?
fFault=TRUE;
if( intnum==3 && opdata==0xcc && fFault==FALSE) { // Is INT 3?
api->pUser->CRS.Client_EIP--;
return FALSE;
}
if( opcode==0xcd && opdata==intnum && fFault==FALSE ) { // Is INT xx?
api->pUser->CRS.Client_EIP-=2;
return FALSE;
}
// Now, we need to handle hardware interrupt and fault interrupt, because
// in these status we can not see any code like "INT xx"
DWORD intseg;
DWORD intoff;
BOOL gatesize;
api->Get_Origin_Interrupt_Vector(intnum,&intseg,&intoff,&gatesize);
addr._seg=(WORD)intseg;
addr._off=intoff;
IntBPid=api->addBPInt3(&addr,BP_IMMED);
api->hook(api->hh_PreEnterKernel,myIntBPhandle,0);
// Ok, we set a breakpoint on the entry point of Windows's ISRs,
// Now we can let's go!
return FALSE;
// Return TRUE means that prevent TRW2000 to pass the interrupt to next handler
// or Windows. It tell TRW2000 that the handling of interrupt has completed.
// When this function return, TRW2000 will check that whether need to active
// TRW2000. If yes, TRW2000 will pop-up. If no, there is nothing will be happened.
// Why we return FALSE here?
// Because we need to pass the interrupt to Windows! We can't handle INT21H AH=3FH!
}
BOOL cmd_BPINT( int argc,char**argv )
{
DWORD Intnum;
if( argc!=1 )
return FALSE;
if( api->strcmp(argv[0],"-R")==0 ) {
api->unhook(api->hh_IntObj+HookIntNum*4,myinthandler);
// Remove the interrupt handler. TRW2000 will modify IDT and restore
// the origin interrupt vector.
// Ues API api->UpdateIDT() to make the modification done immediately.
HookIntNum=0xFFFFFFFF;
return TRUE;
}
if( HookIntNum!=0xFFFFFFFF ) {
api->dprintf("BPINT only can be use once.");
return TRUE;
}
PSTR s=api->str2hex(argv[0],&Intnum);
if( *s!=0 )
return FALSE;
HookIntNum=Intnum;
api->hook(api->hh_IntObj+HookIntNum*4,myinthandler,0);
// Add a interrupt handler. TRW2000 will modify IDT
// and hook this interrupt.
// Ues API api->UpdateIDT() to make the modification done immediately.
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -