windows-nt/Source/XPSP1/NT/base/mvdm/vdmexts/misc.c
2020-09-26 16:20:57 +08:00

722 lines
16 KiB
C

/*++
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);
}
}
}
}
}
}