|
|
/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
ntsdexts.c
Abstract:
This function contains miscellaneous VDMEXTS functions
Author:
Bob Day (bobday) 29-Feb-1992 Grabbed standard header
Revision History:
Neil Sandlin (NeilSa) 15-Jan-1996 Merged with vdmexts
--*/
#include <precomp.h>
#pragma hdrstop
#include <ctype.h>
extern DWORD gOffset; // in disasm.c
VOID DumpMemory( UINT UnitSize, BOOL bAscii ) { VDMCONTEXT ThreadContext; int mode; int j, lines = 8, linelength; WORD selector; ULONG offset, endoffset, units; ULONG base; char ch;
if (!UnitSize) { return; }
mode = GetContext( &ThreadContext );
if (!GetNextToken()) { PRINTF("Please specify an address\n"); return; }
if (!ParseIntelAddress(&mode, &selector, &offset)) { return; }
if (GetNextToken()) { if ((*lpArgumentString == 'l') || (*lpArgumentString == 'L')) { lpArgumentString++; } units = EvaluateToken(); lines = (units*UnitSize+15)/16; } else { units = (lines*16)/UnitSize; }
endoffset = offset+units*UnitSize;
base = GetInfoFromSelector(selector, mode, NULL) + GetIntelBase();
while (lines--) { if (offset & 0xFFFF0000) { PRINTF("%04x:%08lx ", selector, offset); } else { PRINTF("%04x:%04x ", selector, LOWORD(offset)); }
linelength = endoffset - offset; if (linelength > 16) { linelength = 16; }
switch(UnitSize) {
case 1: for (j=0; j<linelength; j++) { if (j==8) { PRINTF("-"); } else { PRINTF(" "); } PRINTF("%02x", ReadByteSafe(base+offset+j)); }
break; case 2: for (j=0; j<linelength; j+=2) { PRINTF(" %04x", ReadWordSafe(base+offset+j)); } break; case 4: for (j=0; j<linelength; j+=4) { PRINTF(" %08lx", ReadDwordSafe(base+offset+j)); } break; }
if (bAscii) {
j = (16-linelength)*2 + (16-linelength)/UnitSize; while (j--) { PRINTF(" "); }
PRINTF(" ");
for (j=0; j<linelength; j++) { ch = ReadByteSafe(base+offset+j); if (isprint(ch)) { PRINTF("%c", ch); } else { PRINTF("."); } } } PRINTF("\n"); offset += 16;
}
}
VOID db( CMD_ARGLIST ) { CMD_INIT(); DumpMemory(1, TRUE);
}
VOID dw( CMD_ARGLIST ) { CMD_INIT(); DumpMemory(2, FALSE);
}
VOID dd( CMD_ARGLIST ) { CMD_INIT(); DumpMemory(4, FALSE);
}
VOID EditMemory( UINT UnitSize ) { ULONG value, base, offset; WORD selector; int mode;
if (!GetNextToken()) { PRINTF("Please specify an address\n"); return; }
if (!ParseIntelAddress(&mode, &selector, &offset)) { return; }
base = GetInfoFromSelector(selector, mode, NULL) + GetIntelBase();
while(GetNextToken()) { value = EvaluateToken();
PRINTF("%04x base=%08x offset=%08x value=%08x\n", selector, base, offset, value); // this is endian dependant code
WRITEMEM((LPVOID)(base+offset), &value, UnitSize); offset += UnitSize;
}
}
VOID eb( CMD_ARGLIST ) { CMD_INIT(); EditMemory(1); }
VOID ew( CMD_ARGLIST ) { CMD_INIT(); EditMemory(2); }
VOID ed( CMD_ARGLIST ) { CMD_INIT(); EditMemory(4); }
VOID r( CMD_ARGLIST ) { VDMCONTEXT ThreadContext; int mode; char sym_text[255]; char rgchOutput[128]; char rgchExtra[128]; BYTE rgbInstruction[64]; WORD selector; ULONG offset; ULONG dist; int cb, j; ULONG Base; SELECTORINFO si;
CMD_INIT();
mode = GetContext( &ThreadContext );
PRINTF("eax=%08lx ebx=%08lx ecx=%08lx edx=%08lx esi=%08lx edi=%08lx\n", ThreadContext.Eax, ThreadContext.Ebx, ThreadContext.Ecx, ThreadContext.Edx, ThreadContext.Esi, ThreadContext.Edi ); PRINTF("eip=%08lx esp=%08lx ebp=%08lx ", ThreadContext.Eip, ThreadContext.Esp, ThreadContext.Ebp );
if (ThreadContext.EFlags != 0xffffffff) { if ( ThreadContext.EFlags & FLAG_OVERFLOW ) { PRINTF("ov "); } else { PRINTF("nv "); } if ( ThreadContext.EFlags & FLAG_DIRECTION ) { PRINTF("dn "); } else { PRINTF("up "); } if ( ThreadContext.EFlags & FLAG_INTERRUPT ) { PRINTF("ei "); } else { PRINTF("di "); } if ( ThreadContext.EFlags & FLAG_SIGN ) { PRINTF("ng "); } else { PRINTF("pl "); } if ( ThreadContext.EFlags & FLAG_ZERO ) { PRINTF("zr "); } else { PRINTF("nz "); } if ( ThreadContext.EFlags & FLAG_AUXILLIARY ) { PRINTF("ac "); } else { PRINTF("na "); } if ( ThreadContext.EFlags & FLAG_PARITY ) { PRINTF("po "); } else { PRINTF("pe "); } if ( ThreadContext.EFlags & FLAG_CARRY ) { PRINTF("cy "); } else { PRINTF("nc "); } }
PRINTF("\n"); PRINTF("cs=%04x ss=%04x ds=%04x es=%04x fs=%04x gs=%04x ", ThreadContext.SegCs, ThreadContext.SegSs, ThreadContext.SegDs, ThreadContext.SegEs, ThreadContext.SegFs, ThreadContext.SegGs);
if (ThreadContext.EFlags == 0xffffffff) { //
// The contents of eflags are unreliable. This happens when you can't
// do a "getEFLAGS()" to obtain the value.
//
PRINTF("efl=????????\n");
} else { PRINTF("efl=%08lx\n",ThreadContext.EFlags ); }
//
// Do disassembly of current instruction
//
selector = (WORD) ThreadContext.SegCs; offset = ThreadContext.Eip;
Base = GetInfoFromSelector( selector, mode, &si ) + GetIntelBase();
if (FindSymbol(selector, offset, sym_text, &dist, BEFORE, mode )) { if ( dist == 0 ) { PRINTF("%s:\n", sym_text ); } else { PRINTF("%s+0x%lx:\n", sym_text, dist ); } }
cb = sizeof(rgbInstruction); if ((DWORD)(offset+cb) >= si.Limit) cb -= offset+cb-si.Limit; if (!READMEM((LPVOID)(Base+offset), rgbInstruction, cb)) { PRINTF("%04x:%08x: <Error Reading Memory>\n", selector, offset); return; }
cb = unassemble_one(rgbInstruction, si.bBig, selector, offset, rgchOutput, rgchExtra, &ThreadContext, mode);
if (offset > 0xffff) { PRINTF("%04x:%08x ", selector, offset); } else { PRINTF("%04x:%04x ", selector, offset); }
for (j=0; j<cb; ++j) PRINTF("%02x", rgbInstruction[j]); for (; j<8; ++j) PRINTF(" "); PRINTF("%s\t%s\n", rgchOutput, rgchExtra); }
VOID SearchModuleList( VOID ) { VDMCONTEXT ThreadContext; int mode; HEAPENTRY he = {0}; SELECTORINFO si; WORD selector = 0; SEGENTRY *se; char filename[9]; char szModuleArg[255]; BOOL bModuleNameGiven=FALSE; LPSTR pTemp;
mode = GetContext( &ThreadContext );
if (GetNextToken()) {
if (IsTokenHex()) { selector = (WORD) EvaluateToken(); } else { bModuleNameGiven = TRUE; pTemp = lpArgumentString; SkipToNextWhiteSpace(); *lpArgumentString = 0; strcpy(szModuleArg, pTemp); if (strlen(szModuleArg) > 8) { szModuleArg[8] = 0; } } }
PRINTF("Sel Base Limit Type Module Seg\n"); PRINTF("==== ======== ======== ==== ======== ===\n");
se = GetSegtablePointer(); while ( se ) { if ( selector == 0 || se->selector == selector || bModuleNameGiven) {
switch (se->type) {
case SEGTYPE_PROT: { HEAPENTRY he = {0}; he.Selector = se->selector; if (FindHeapEntry(&he, FHE_FIND_SEL_ONLY, FHE_FIND_QUIET)) { break; } } GetInfoFromSelector(se->selector, PROT_MODE, &si); ParseModuleName(filename, se->szExePath);
if (!bModuleNameGiven || !_stricmp(filename, szModuleArg)) {
PRINTF("%04X %08lX %08lX", se->selector, si.Base, si.Limit); PRINTF(" %s", si.bCode ? "code" : "data"); PRINTF(" %-8.8s %d\n", filename, se->segment+1 );
} break;
case SEGTYPE_V86: ParseModuleName(filename, se->szExePath);
if (!bModuleNameGiven || !_stricmp(filename, szModuleArg)) {
PRINTF("%04X %08lX %08lX %s %-8.8s %d\n", se->selector, se->selector << 4, se->length, "v86 ", filename, se->segment+1); } break; }
} se = se->Next; }
he.CurrentEntry = 0; // reset scan
if (bModuleNameGiven) { strcpy(he.ModuleArg, szModuleArg); } else { he.Selector = selector; }
while (FindHeapEntry(&he, bModuleNameGiven ? FHE_FIND_MOD_ONLY : FHE_FIND_SEL_ONLY, FHE_FIND_QUIET)) {
if (he.SegmentNumber != -1) { GetInfoFromSelector((WORD)(he.gnode.pga_handle | 1), PROT_MODE, &si); PRINTF("%04X %08lX %08lX", he.gnode.pga_handle | 1, he.gnode.pga_address, he.gnode.pga_size - 1);
PRINTF(" %s", si.bCode ? "Code" : "Data");
PRINTF(" %-8.8s %d\n", he.OwnerName, he.SegmentNumber+1); }
}
}
VOID lm( CMD_ARGLIST ) { CMD_INIT();
if (GetNextToken()) {
SearchModuleList();
} else {
WORD sel; BOOL b; NEHEADER owner; ULONG base; CHAR ModuleName[9]; UCHAR len;
if (!ReadMemExpression("ntvdmd!DbgWowhExeHead", &sel, sizeof(sel))) { return; }
PRINTF("NEHeader Module Name\n"); while(sel) {
base = GetInfoFromSelector(sel, PROT_MODE, NULL) + GetIntelBase();
b = READMEM((LPVOID)base, &owner, sizeof(owner));
if (!b || (owner.ne_magic != 0x454e)) { PRINTF("Invalid module list! (started with hExeHead)\n"); return; } len = ReadByteSafe(base+owner.ne_restab); if (len>8) { len=8; } READMEM((LPVOID)(base+owner.ne_restab+1), ModuleName, 8); ModuleName[len] = 0;
PRINTF(" %.04X %s\n", sel, ModuleName); // This is mapped to ne_pnextexe in kernel
sel = owner.ne_cbenttab; } } }
VOID dg( CMD_ARGLIST ) { ULONG selector; ULONG Base; SELECTORINFO si; int count = 16;
CMD_INIT();
if (!GetNextToken()) { PRINTF("Please enter a selector\n"); return; }
selector = EvaluateToken();
if (GetNextToken()) { if (tolower(*lpArgumentString) == 'l') { lpArgumentString++; } count = (WORD) EvaluateToken(); }
while (count--) {
Base = GetInfoFromSelector( (WORD) selector, PROT_MODE, &si );
PRINTF("%04X => Base: %08lX", selector, Base);
#ifndef i386
PRINTF(" (%08X)", Base+GetIntelBase()); #endif
PRINTF(" Limit: %08lX %s %s %s %s %s %s\n", si.Limit, si.bPresent ? " P" : "NP", si.bSystem ? "System" : si.bCode ? "Code " : "Data ", si.bSystem ? "" : si.bWrite ? "W" : "R", si.bSystem ? "" : si.bAccessed ? "A" : " ", si.bBig ? "Big" : "", si.bExpandDown ? "ED" : "" );
selector+=8; if (selector>0xffff) { break; } }
}
VOID ntsd( CMD_ARGLIST ) { #if 0
PVOID Address; static BOOL bTrue = TRUE; #endif
CMD_INIT();
PRINTF("vdmexts: obselete command 'ntsd', use '.<cmd>' from VDM> prompt\n"); #if 0
if (!InVdmPrompt()) { PRINTF("This command only works at the VDM> prompt\n"); }
Address = (PVOID)(*GetExpression)("ntvdmd!bWantsNtsdPrompt");
if (Address) { WRITEMEM((PVOID)Address, &bTrue, sizeof(BOOL)); PRINTF("Enter 'g' to return from the ntsd prompt\n"); } else { PRINTF("Can't find symbol 'ntvdmd!bWantsNtsdPrompt'\n"); } #endif
}
VOID q( CMD_ARGLIST ) { CMD_INIT();
PRINTF("!vdmexts.q quitting debugger..."); ExitProcess(0); }
//
// fs find string
// case-insensitive
// searches LDT selectors one by one, first 64k only.
//
VOID fs( CMD_ARGLIST ) { ULONG selector; ULONG Base; ULONG cbCopied; SELECTORINFO si; BYTE Buffer[65*1024]; LPSTR pszSearch; LPSTR pch;
CMD_INIT();
RtlZeroMemory(Buffer, sizeof(Buffer));
if (!GetNextToken()) { PRINTF("Please enter a string to find in 16:16 memory\n"); return; }
pszSearch = lpArgumentString;
PRINTF("Searching 16:16 memory for '%s'\n", pszSearch);
for (selector = 7; selector < 0x10000; selector += 8) {
Base = GetInfoFromSelector( (WORD) selector, PROT_MODE, &si );
//
// If the selector is valid and present read up to 64k
// into Buffer.
//
if (Base != (ULONG)-1 && si.bPresent) {
cbCopied = si.Limit + 1;
if (cbCopied > 0x10000) { cbCopied = 0x10000; }
if (!READMEM((LPVOID)(Base + GetIntelBase()), Buffer, cbCopied)) { PRINTF("Unable to read selector %04x contents at %x for %x bytes\n", selector, Base + GetIntelBase(), cbCopied); } else {
//
// search the block for the string, buffer is 1k too big and
// zero-inited so that strcmp is safe.
//
for (pch = Buffer; pch < (Buffer + cbCopied); pch++) {
if (!_memicmp(pch, pszSearch, strlen(pszSearch))) {
//
// Match!
//
PRINTF("%04x:%04x (%08x) '%s'\n", selector, pch - Buffer, #ifndef i386
GetIntelBase() + #endif
Base + (pch - Buffer), pch); } } } } }
}
|