📄 stack.cpp
字号:
// Stack Plugs for TRW2000
// Copyright (C) , 1999 ,
//
// Author:
// Zhunanhao , reached at nhzhu@163.net
//
// History :
// 2000.2.24 Zhunanhao write origin code
//
// Note:
// This is only a DEMO! Please modify it to improve!
//
#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_STACK( 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 ( "STACK", 0,
"Display call stack", 0,
cmd_STACK );
api->dprintf ( "STACK Plugs Ver 0.01 Initialized..." ) ;
return TRUE ;
}
EXC EXPORT BOOL Plugs_Exit ( )
{
return TRUE ;
}
/***************** Command ***************/
//#define DEBUG
// Command : STACK
BOOL cmd_STACK( int argc,char**argv )
{
DWORD EBP;
DWORD r;
PSTR s;
char buf[20];
ADDRE addr,addr2;
if( argc!=0 )
return FALSE ;
#ifdef DEBUG
api->Begin_Nest_VMM_Exec();
#endif
api->CurCSEIP(&addr2);
if( api->ifLinear(&addr2)==FALSE ) {
api->dprintf ( "Sorry, now STACK only support Win32&VxD linear address." ) ;
return TRUE;
}
addr._off=api->pUser->CRS.Client_EBP;
addr._seg=api->pUser->CRS.Client_SS;
addr._mod=0;
EBP=addr._off;
api->dprintf("Address\t\tSymbol/Owner");
while(1) {
addr._off=EBP+4;
if( api->PeekD(&addr,&r)==FALSE )
break;
addr._off=EBP;
if( api->PeekD(&addr,&EBP)==FALSE )
break;
if( EBP<=addr._off )
break;
addr2._off=r;
s=api->GetSymbol(&addr2,0x400);
if( s==0 )
s=api->GetSymbolArea(&addr2);
if( s==0 ) {
api->sprintf(buf,"%08X",r);
s=buf;
}
api->dprintf("%08X %s",r,s);
}
#ifdef DEBUG
api->End_Nest_VMM_Exec();
#endif
return TRUE ;
}
/*
This document is from DDK 2000 document.
Anatomy of a Stack Trace
The following is a register dump from the kernel debugger. It contains information
about what is stored in the stack:
kd> r [This command dumps the information from a register.]
eax=c0000018 ebx=80621828 ecx=00000000 edx=807da761 esi=e12e0e28 edi=e12df868
eip=f28343b3 esp=f2c132cc ebp=f2c132f0 iopl=0 nv up ei pl zr na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246
VIDEOPRT!pVideoPortReportResourceList+0x263:
f28343b3 8db340010000 lea esi,[ebx+0x140] ds:0023:80621968=00000000
The registers are used as follows:
esp = stack pointer
ebp = base pointer
eip = instruction pointer
eax, ebx, ecx, edx = general purpose registers for storing intermediate results
edi, esi = often used as general registers
A stack trace could be diagramed in the following manner:
Arguments
Return Address
Caller's EBP
Local Variables
The stack trace displayed on a kernel debugger is written in assembly code. A simple
set of instructions in assembly code could look like this:
push ebp ;Places the caller's base pointer (ebp) on to the stack
mov ebp,esp ;Sets the base pointer (ebp) equal to the stack pointer (esp)
mov eax, [ebp+8] ;Grab the value of the first argument off the stack and store
;it in eax
add eax, [ebp+c] ;Add the second argument's value to the value in eax
pop ebp ;Restore the caller's base pointer
ret 8 ;Return to the calling function and remove 8 bytes from the stack
The compiler can optimize this code, simplifying it so that it is shorter and more
direct. An optimized routine might look like this: (Note how the code omits references
to the base pointer.)
mov eax, [esp+4]
add eax, [esp+8]
ret 8
Finally here's how it would look in C:
ULONG Add(ULONG a, ULONG b)
{
return a + b;
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -