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.
430 lines
9.0 KiB
430 lines
9.0 KiB
/*++
|
|
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
Cmdexec0.c
|
|
|
|
Abstract:
|
|
|
|
This file contains the front end code for parsing the various commands
|
|
for the command window, and the code for the debugger control commands.
|
|
|
|
Author:
|
|
|
|
David J. Gilman (davegi) 21-Apr-92
|
|
|
|
Environment:
|
|
|
|
Win32, User Mode
|
|
|
|
--*/
|
|
|
|
#define NOEXTAPI
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <ntdbg.h>
|
|
#include <ntos.h>
|
|
#include <windows.h>
|
|
#include <imagehlp.h>
|
|
#include <crash.h>
|
|
#include <wdbgexts.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <disasm.h>
|
|
#include "dumpexam.h"
|
|
|
|
//
|
|
// prototypes
|
|
//
|
|
DWORD ExtGetExpression(LPSTR lpsz);
|
|
VOID ExtGetSymbol(LPVOID offset, PUCHAR pchBuffer, LPDWORD lpDisplacement);
|
|
DWORD ExtDisasm(LPDWORD lpOffset, LPSTR lpBuffer, ULONG fShowEffectiveAddress);
|
|
BOOL ExtReadProcessMemory(DWORD offset, LPVOID lpBuffer, DWORD cb, LPDWORD lpcbBytesRead);
|
|
BOOL ExtWriteProcessMemory(DWORD offset, LPVOID lpBuffer, DWORD cb, LPDWORD lpcbBytesWritten);
|
|
BOOL ExtGetThreadContext(DWORD Processor, LPCONTEXT lpContext, DWORD cbSizeOfContext);
|
|
BOOL ExtSetThreadContext(DWORD Processor, LPCONTEXT lpContext, DWORD cbSizeOfContext);
|
|
BOOL ExtIoctl(USHORT IoctlType, LPVOID lpvData, DWORD cbSize);
|
|
DWORD ExtCallStack(DWORD FramePointer, DWORD StackPointer, DWORD ProgramCounter, PEXTSTACKTRACE StackFrames, DWORD Frames);
|
|
VOID ExtOutput(PSTR,...);
|
|
ULONG ExtCheckCtrlCTrap(VOID);
|
|
|
|
extern FILE *FileOut;
|
|
extern struct DIS *pdis;
|
|
|
|
DWORD OsVersion;
|
|
|
|
|
|
static WINDBG_EXTENSION_APIS WindbgExtensions =
|
|
{
|
|
sizeof(WindbgExtensions),
|
|
(PWINDBG_OUTPUT_ROUTINE) ExtOutput,
|
|
(PWINDBG_GET_EXPRESSION) ExtGetExpression,
|
|
(PWINDBG_GET_SYMBOL) ExtGetSymbol,
|
|
(PWINDBG_DISASM) ExtDisasm,
|
|
(PWINDBG_CHECK_CONTROL_C) ExtCheckCtrlCTrap,
|
|
(PWINDBG_READ_PROCESS_MEMORY_ROUTINE) ExtReadProcessMemory,
|
|
(PWINDBG_WRITE_PROCESS_MEMORY_ROUTINE) ExtWriteProcessMemory,
|
|
(PWINDBG_GET_THREAD_CONTEXT_ROUTINE) ExtGetThreadContext,
|
|
(PWINDBG_SET_THREAD_CONTEXT_ROUTINE) ExtSetThreadContext,
|
|
(PWINDBG_IOCTL_ROUTINE) ExtIoctl,
|
|
(PWINDBG_STACKTRACE_ROUTINE) ExtCallStack
|
|
};
|
|
|
|
|
|
|
|
|
|
BOOL fDoVersionCheck = TRUE;
|
|
HINSTANCE hModKd;
|
|
|
|
#define BUILD_MAJOR_VERSION 3
|
|
#define BUILD_MINOR_VERSION 5
|
|
#define BUILD_REVISION API_VERSION_NUMBER
|
|
API_VERSION ApiVersion = { BUILD_MAJOR_VERSION, BUILD_MINOR_VERSION, API_VERSION_NUMBER, 0 };
|
|
|
|
|
|
|
|
LPSTR
|
|
CPSkipWhitespace(
|
|
LPSTR lpszIn
|
|
)
|
|
{
|
|
while (*lpszIn == ' ' || *lpszIn == '\t') lpszIn++;
|
|
return( lpszIn );
|
|
}
|
|
|
|
|
|
VOID
|
|
ExtOutput(
|
|
PSTR format,
|
|
...
|
|
)
|
|
{
|
|
char vbuf[1024];
|
|
va_list arg_ptr;
|
|
|
|
|
|
va_start(arg_ptr, format);
|
|
_vsnprintf(vbuf, sizeof(vbuf), format, arg_ptr);
|
|
fprintf( FileOut, "%s", vbuf );
|
|
}
|
|
|
|
|
|
ULONG
|
|
ExtCheckCtrlCTrap(
|
|
VOID
|
|
)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
DWORD
|
|
ExtGetExpression(
|
|
LPSTR lpsz
|
|
)
|
|
{
|
|
PIMAGEHLP_SYMBOL Symbol;
|
|
|
|
|
|
lpsz = CPSkipWhitespace(lpsz);
|
|
if (*lpsz == '&') {
|
|
lpsz += 1;
|
|
}
|
|
|
|
if (SymGetSymFromName( DmpHeader, lpsz, sym )) {
|
|
return sym->Address;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
VOID
|
|
ExtGetSymbol(
|
|
LPVOID offset,
|
|
PUCHAR pchBuffer,
|
|
LPDWORD lpDisplacement
|
|
)
|
|
{
|
|
if (SymGetSymFromAddr( DmpHeader, (ULONG)offset, lpDisplacement, sym )) {
|
|
strcpy( pchBuffer, sym->Name );
|
|
} else {
|
|
pchBuffer[0] = 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
DWORD
|
|
ExtDisasm(
|
|
LPDWORD lpOffset,
|
|
LPSTR lpBuffer,
|
|
ULONG fShowEffectiveAddress
|
|
)
|
|
{
|
|
#define CODE_BUFFER_SIZE 256
|
|
BYTE CodeBuffer[CODE_BUFFER_SIZE];
|
|
|
|
|
|
DmpReadMemory( (LPVOID)*lpOffset, CodeBuffer, CODE_BUFFER_SIZE );
|
|
|
|
*lpOffset += Disassemble(
|
|
pdis,
|
|
(ULONG)*lpOffset,
|
|
CodeBuffer,
|
|
CODE_BUFFER_SIZE,
|
|
" ",
|
|
lpBuffer,
|
|
256
|
|
);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ExtReadProcessMemory(
|
|
DWORD offset,
|
|
LPVOID lpBuffer,
|
|
DWORD nSize,
|
|
LPDWORD lpcbBytesRead
|
|
)
|
|
{
|
|
DWORD cb = DmpReadMemory( (PVOID)offset, lpBuffer, nSize );
|
|
if (lpcbBytesRead) {
|
|
*lpcbBytesRead = cb;
|
|
}
|
|
return cb == nSize;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ExtWriteProcessMemory(
|
|
DWORD offset,
|
|
LPVOID lpBuffer,
|
|
DWORD cb,
|
|
LPDWORD lpcbBytesWritten
|
|
)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ExtGetThreadContext(
|
|
DWORD Processor,
|
|
LPCONTEXT lpContext,
|
|
DWORD cbSizeOfContext
|
|
)
|
|
{
|
|
GetContext( Processor, lpContext );
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ExtSetThreadContext(
|
|
DWORD Processor,
|
|
LPCONTEXT lpContext,
|
|
DWORD cbSizeOfContext
|
|
)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ExtIoctl(
|
|
USHORT IoctlType,
|
|
LPVOID lpvData,
|
|
DWORD cbSize
|
|
)
|
|
{
|
|
PREADCONTROLSPACE prc;
|
|
ULONG cb;
|
|
|
|
|
|
if (IoctlType == IG_READ_CONTROL_SPACE) {
|
|
prc = lpvData;
|
|
return DmpReadControlSpace(
|
|
(USHORT)prc->Processor,
|
|
(PVOID)prc->Address,
|
|
prc->Buf,
|
|
prc->BufLen,
|
|
&cb
|
|
);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
DWORD
|
|
ExtGetModuleBase(
|
|
PDUMP_HEADER DmpHeader,
|
|
ULONG Address
|
|
)
|
|
{
|
|
IMAGEHLP_MODULE ModuleInfo;
|
|
|
|
if (SymGetModuleInfo( DmpHeader, Address, &ModuleInfo )) {
|
|
return ModuleInfo.BaseOfImage;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
DWORD
|
|
ExtCallStack(
|
|
DWORD FramePointer,
|
|
DWORD StackPointer,
|
|
DWORD ProgramCounter,
|
|
PEXTSTACKTRACE StackFrames,
|
|
DWORD Frames
|
|
)
|
|
{
|
|
extern PVOID ExtContext;
|
|
DWORD i;
|
|
STACKFRAME StackFrame;
|
|
PVOID Context;
|
|
|
|
|
|
|
|
ZeroMemory( &StackFrame, sizeof(STACKFRAME) );
|
|
|
|
//
|
|
// setup the program counter
|
|
//
|
|
StackFrame.AddrPC.Offset = ProgramCounter;
|
|
StackFrame.AddrPC.Mode = AddrModeFlat;
|
|
|
|
//
|
|
// setup the frame pointer
|
|
//
|
|
StackFrame.AddrFrame.Offset = FramePointer;
|
|
StackFrame.AddrFrame.Mode = AddrModeFlat;
|
|
|
|
//
|
|
// setup the stack pointer
|
|
//
|
|
StackFrame.AddrStack.Offset = StackPointer;
|
|
StackFrame.AddrStack.Mode = AddrModeFlat;
|
|
|
|
i = 0;
|
|
Context = LocalAlloc( LPTR, MAX_CONTEXT_SIZE );
|
|
CopyMemory( Context, ExtContext, MAX_CONTEXT_SIZE );
|
|
while( TRUE ) {
|
|
if (!StackWalk(
|
|
DmpHeader->MachineImageType,
|
|
DmpHeader,
|
|
NULL,
|
|
&StackFrame,
|
|
Context,
|
|
SwReadMemory,
|
|
SymFunctionTableAccess,
|
|
ExtGetModuleBase,
|
|
NULL
|
|
)) {
|
|
//
|
|
// end of the stack
|
|
//
|
|
break;
|
|
}
|
|
|
|
StackFrames[i].FramePointer = StackFrame.AddrFrame.Offset;
|
|
StackFrames[i].ProgramCounter = StackFrame.AddrPC.Offset;
|
|
StackFrames[i].ReturnAddress = StackFrame.AddrReturn.Offset;
|
|
StackFrames[i].Args[0] = StackFrame.Params[0];
|
|
StackFrames[i].Args[1] = StackFrame.Params[1];
|
|
StackFrames[i].Args[2] = StackFrame.Params[2];
|
|
StackFrames[i].Args[3] = StackFrame.Params[3];
|
|
i += 1;
|
|
}
|
|
|
|
LocalFree( Context );
|
|
|
|
return i;
|
|
}
|
|
|
|
|
|
LONG
|
|
ExtensionExceptionFilterFunction(
|
|
LPSTR msg,
|
|
LPEXCEPTION_POINTERS lpep
|
|
)
|
|
{
|
|
fprintf( FileOut, "\n%s addr=0x%08x, ec=0x%08x\n\n",
|
|
msg,
|
|
lpep->ExceptionRecord->ExceptionAddress,
|
|
lpep->ExceptionRecord->ExceptionCode );
|
|
|
|
return EXCEPTION_EXECUTE_HANDLER;
|
|
}
|
|
|
|
|
|
BOOL
|
|
LoadKd(
|
|
LPSTR KdName
|
|
)
|
|
{
|
|
PWINDBG_EXTENSION_DLL_INIT pDllInit;
|
|
|
|
|
|
|
|
hModKd = LoadLibrary( KdName );
|
|
if (!hModKd) {
|
|
return FALSE;
|
|
}
|
|
|
|
pDllInit = (PWINDBG_EXTENSION_DLL_INIT)GetProcAddress( hModKd, "WinDbgExtensionDllInit" );
|
|
if (!pDllInit) {
|
|
return FALSE;
|
|
}
|
|
|
|
(pDllInit)( &WindbgExtensions, 0, 0 );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
DoExtension(
|
|
LPSTR FuncName,
|
|
LPSTR FuncArgs,
|
|
DWORD Processor,
|
|
DWORD Ip
|
|
)
|
|
{
|
|
PWINDBG_EXTENSION_ROUTINE WindbgExtRoutine;
|
|
extern PVOID ExtContext;
|
|
PVOID Context;
|
|
|
|
|
|
|
|
WindbgExtRoutine = (PWINDBG_EXTENSION_ROUTINE)GetProcAddress( hModKd, FuncName );
|
|
|
|
Context = LocalAlloc( LPTR, MAX_CONTEXT_SIZE );
|
|
ExtContext = Context;
|
|
|
|
PrintHeading( "!%s %s", FuncName, FuncArgs );
|
|
|
|
if (!WindbgExtRoutine) {
|
|
fprintf( FileOut, "**** could not call [ %s ]\n", FuncName );
|
|
return FALSE;
|
|
}
|
|
|
|
try {
|
|
(WindbgExtRoutine)( 0, 0, Ip, Processor, FuncArgs );
|
|
} except (ExtensionExceptionFilterFunction(
|
|
"Extension function faulted", GetExceptionInformation())) {
|
|
}
|
|
|
|
LocalFree( Context );
|
|
|
|
return TRUE;
|
|
}
|