From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/mvdm/vdmexts/disasm.c | 2407 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2407 insertions(+) create mode 100644 private/mvdm/vdmexts/disasm.c (limited to 'private/mvdm/vdmexts/disasm.c') diff --git a/private/mvdm/vdmexts/disasm.c b/private/mvdm/vdmexts/disasm.c new file mode 100644 index 000000000..04fa0c4c2 --- /dev/null +++ b/private/mvdm/vdmexts/disasm.c @@ -0,0 +1,2407 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + disasm.c + +Abstract: + + This file contains the x86 disassmbler invoked by "!bde.u <16:16 address>" + +Author: + + Barry Bond (BarryBo) + +Revision History: + + 09-May-1995 Barry Bond (BarryBo) Created + 15-Jan-1996 Neil Sandlin (NeilSa) Merged with vdmexts + 32 bit segments fixes + +--*/ + +#include +#pragma hdrstop + +WORD gSelector = 0; +ULONG gOffset = 0; + +VOID +u( + CMD_ARGLIST +) { + VDMCONTEXT ThreadContext; + WORD selector; + ULONG offset; + int mode; + char rgchOutput[128]; + char rgchExtra[128]; + BYTE rgbInstruction[64]; + CHAR sym_text[255]; + CHAR sym_prev[255] = ""; + DWORD dist; + int cb; + int i; + int j; + int count=10; + ULONG Base; + SELECTORINFO si; + + CMD_INIT(); + + mode = GetContext( &ThreadContext ); + + if (!GetNextToken()) { + if (!gSelector && !gOffset) { + selector = (WORD) ThreadContext.SegCs; + offset = ThreadContext.Eip; + } else { + selector = gSelector; + offset = gOffset; + } + } else if (!ParseIntelAddress(&mode, &selector, &offset)) { + return; + } + + if (GetNextToken()) { + count = (int) EXPRESSION(lpArgumentString); + } + + if ( mode != PROT_MODE && mode != V86_MODE) { + PRINTF(" Disassembly of flat mode code not allowed.\n"); + return; + } + + Base = GetInfoFromSelector( selector, mode, &si ) + GetIntelBase(); + + for (i=0; i= si.Limit) + cb -= offset+cb-si.Limit; + if (!READMEM((LPVOID)(Base+offset), rgbInstruction, cb)) { + PRINTF("%04x:%08x: \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 0xdf))) { + /* fwait not followed by floating point instruction */ + AppendString("fwait"); + return (1); + } + + pInstr++; + pData = pInstr; + if (pszDecode->szName < 0) { // found a GROUP_ or FLOAT entry... + i = (-pszDecode->szName)-1; + if (i == FLOATCODE) { + //Later: mputs("Floating point instructions NYI\n"); + return 1; + } else { + pszDecode = &dis386_groups[i][(*pInstr>>3)&7]; + } + } + + AppendString(szInstructions[pszDecode->szName]); + + if (pszDecode->iPart1) { + + AppendChar('\t'); + + i = (*(rgpfn[pszDecode->iPart1].pfn))(pInstr); + + if (pszDecode->iPart2) { + + AppendString(", "); + i+=(*(rgpfn[pszDecode->iPart2].pfn))(pInstr); + + if (pszDecode->iPart3) { + + AppendString(", "); + i+=(*(rgpfn[pszDecode->iPart3].pfn))(pInstr); + + } + } + + pInstr+=i; + } + + AppendChar('\0'); + cb = pInstr - pInstrStart; // return length of instruction + + gSelector = wInstrSeg; + gOffset = dwInstrOff + cb; + return cb; +} + +BOOL safe_read_byte( + ADDR addr, + BYTE *pb +) { + ULONG Base; + + *pb = 0xbb; + Base = GetInfoFromSelector( addr.sSeg, g_mode, NULL ); + if (Base == (ULONG)-1 || Base == 0) { + return FALSE; + } + + Base += GetIntelBase(); + + return READMEM((LPVOID)(Base+(ULONG)addr.sOff), pb, 1); +} + +BOOL safe_read_short( + ADDR addr, + SHORT *ps +) { + ULONG Base; + + Base = GetInfoFromSelector( addr.sSeg, g_mode, NULL ); + if (Base == (ULONG)-1 || Base == 0) { + return FALSE; + } + + Base += GetIntelBase(); + + return READMEM((LPVOID)(Base+(ULONG)addr.sOff), ps, 2); +} + +BOOL safe_read_long( + ADDR addr, + LONG *pl +) { + ULONG Base; + + Base = GetInfoFromSelector( addr.sSeg, g_mode, NULL ); + if (Base == (ULONG)-1 || Base == 0) { + return FALSE; + } + + Base += GetIntelBase(); + + return READMEM((LPVOID)(Base+(ULONG)addr.sOff), pl, 4); +} + + +int Dreg1B(LPBYTE lpB) +{ + BYTE b = (*lpB >> 3) & 7; + + AppendString(szRegsB[b]); + + return 0; +} + +int Dreg1W(LPBYTE lpB) +{ + BYTE b = (*lpB >> 3) & 7; + + if (OPERAND_32) + AppendString(szRegsD[b]); + else + AppendString(szRegsW[b]); + + return 0; +} + +int Dreg2B(LPBYTE lpB) +{ + BYTE b = *lpB & 7; + + AppendString(szRegsB[b]); + + return 0; +} + +int Dreg2W(LPBYTE lpB) +{ + BYTE b = *lpB & 7; + + if (OPERAND_32) + AppendString(szRegsD[b]); + else + AppendString(szRegsW[b]); + + return 0; +} + +int DmodrmB(LPBYTE lpB) +{ + BYTE rm = *lpB & 0x07; + BYTE mod = *lpB >> 6; + unsigned short num; + int iRet; + + pData++; // skip past mod r/m + if (mod == 3) { + AppendPrefixes(); + AppendString(szRegsB[rm]); + return 1; + } + + iRet = 0; + AppendString("byte ptr "); + AppendPrefixes(); + AppendString(szMod[rm]); + AppendChar('+'); + + switch (mod) { + case 0: + if (rm == 6) { + g_pchOutput-=3; // back up over the 'BP+' + num = *((UNALIGNED USHORT*)pData); + AppendNumber(num); + pData+=2; + iRet = 3; + } else { + num = 0; + g_pchOutput--; + iRet = 1; + } + break; + + case 1: + num = *pData; + AppendNumber(num); + pData++; + iRet = 2; + break; + + case 2: + num = *((UNALIGNED USHORT*)pData); + AppendNumber(num); + pData += 2; + iRet = 3; + break; + } + + AppendChar(']'); + + DisplayAddress(mod, rm, num, 1); + + return iRet; +} + +int DmodrmW(LPBYTE lpB) +{ + BYTE rm = *lpB & 0x07; + BYTE mod = *lpB >> 6; + unsigned short num; + int iRet; + + pData++; // skip past mod r/m + if (mod == 3) { + AppendPrefixes(); + if (OPERAND_32) + AppendString(szRegsD[rm]); + else + AppendString(szRegsW[rm]); + return 1; + } + + if (OPERAND_32) { + AppendString("dword ptr "); + AppendPrefixes(); + AppendChar('['); + AppendString(szRegsD[rm]); + } else { + AppendString("word ptr "); + AppendPrefixes(); + AppendString(szMod[rm]); + } + AppendChar('+'); + + switch (mod) { + case 0: + if (rm == 6) { + g_pchOutput-=3; // back up over 'BP+' + num = *((UNALIGNED USHORT*)pData); + AppendNumber(num); + pData+=2; + iRet = 3; + } else { + g_pchOutput--; // else back up over '+' alone + num=0; + iRet = 1; + } + break; + + case 1: + num = *pData; + AppendNumber(num); + pData++; + iRet = 2; + break; + + case 2: + num = *((UNALIGNED USHORT *)pData); + AppendNumber(num); + pData+=2; + iRet = 3; + break; + } + + AppendChar(']'); + + if (OPERAND_32) + DisplayAddress(mod, rm, num, 4); + else + DisplayAddress(mod, rm, num, 2); + + return iRet; +} + + +void DisplayAddress(int mod, int rm, int sOff, int size) +{ + ADDR addr; + + // if caller of unassemble_one() didn't want extra info, return now + if (g_pchExtra == NULL) + return; + + // no memory reference + if (mod == 3) + return; + + // display prefix + + if (prefixes & PREFIX_DS) { + ExtraChar('D'); + addr.sSeg = (USHORT)g_pThreadContext->SegDs; + } else if (prefixes & PREFIX_ES) { + ExtraChar('E'); + addr.sSeg = (USHORT)g_pThreadContext->SegEs; + } else if (prefixes & PREFIX_FS) { + ExtraChar('F'); + addr.sSeg = (USHORT)g_pThreadContext->SegFs; + } else if (prefixes & PREFIX_GS) { + ExtraChar('G'); + addr.sSeg = (USHORT)g_pThreadContext->SegGs; + } else if (prefixes & PREFIX_CS) { + ExtraChar('C'); + addr.sSeg = (USHORT)g_pThreadContext->SegCs; + } else if ( (prefixes & PREFIX_SS) || rm==2 || rm == 3) { + ExtraChar('S'); + addr.sSeg = (USHORT)g_pThreadContext->SegSs; + } else if (rm == 6 && mod != 0) { + ExtraChar('S'); + addr.sSeg = (USHORT)g_pThreadContext->SegSs; + } else { + ExtraChar('D'); + addr.sSeg = (USHORT)g_pThreadContext->SegDs; + } + + ExtraString("S:["); + + switch (rm) { + case 0: + addr.sOff = (USHORT)(g_pThreadContext->Ebx + g_pThreadContext->Esi); + break; + + case 1: + addr.sOff = (USHORT)(g_pThreadContext->Ebx + g_pThreadContext->Edi); + break; + + case 2: + addr.sOff = (USHORT)(g_pThreadContext->Ebp + g_pThreadContext->Esi); + break; + + case 3: + addr.sOff = (USHORT)(g_pThreadContext->Ebp + g_pThreadContext->Edi); + break; + + case 4: + addr.sOff = (USHORT)g_pThreadContext->Esi; + break; + + case 5: + addr.sOff = (USHORT)g_pThreadContext->Edi; + break; + + case 6: + if (mod == 0) + addr.sOff = 0; + else + addr.sOff = (USHORT)g_pThreadContext->Ebp; + break; + + default: + addr.sOff = (USHORT)g_pThreadContext->Ebx; + + } + + addr.sOff += sOff; + ExtraNumber(addr.sOff); + ExtraString("]="); + if (size == 2) { + SHORT s; + if (safe_read_short(addr, &s)) { + ExtraNumber( s ); + } else { + ExtraString("????"); + } + } else if (size == 1) { + BYTE b; + if (safe_read_byte(addr, &b)) { + ExtraNumber( b ); + } else { + ExtraString("??"); + } + } else if (size == 4) { + LONG l; + if (safe_read_long(addr, &l)) { + ExtraNumber( l ); + } else { + ExtraString("????????"); + } + } else { + ExtraString("Unknown size!"); + } +} + + +int DALreg(LPBYTE lpB) +{ + AppendString("al"); + + return 0; +} + +int DAHreg(LPBYTE lpB) +{ + AppendString("ah"); + + return 0; +} + +int DBLreg(LPBYTE lpB) +{ + AppendString("bl"); + + return 0; +} + +int DBHreg(LPBYTE lpB) +{ + AppendString("bh"); + + return 0; +} + +int DCLreg(LPBYTE lpB) +{ + AppendString("cl"); + + return 0; +} + +int DCHreg(LPBYTE lpB) +{ + AppendString("ch"); + + return 0; +} + +int DDLreg(LPBYTE lpB) +{ + AppendString("dl"); + + return 0; +} + +int DDHreg(LPBYTE lpB) +{ + AppendString("dh"); + + return 0; +} + +int DAXreg(LPBYTE lpB) +{ + if (OPERAND_32) + AppendChar('e'); + + AppendString("ax"); + + return 0; +} + +int DBXreg(LPBYTE lpB) +{ + if (OPERAND_32) + AppendChar('e'); + + AppendString("bx"); + + return 0; +} + +int DCXreg(LPBYTE lpB) +{ + if (OPERAND_32) + AppendChar('e'); + + AppendString("cx"); + + return 0; +} + +int DDXreg(LPBYTE lpB) +{ + if (OPERAND_32) + AppendChar('e'); + + AppendString("dx"); + + return 0; +} + +int DBPreg(LPBYTE lpB) +{ + if (OPERAND_32) + AppendChar('e'); + + AppendString("bp"); + + return 0; +} + +int DSPreg(LPBYTE lpB) +{ + if (OPERAND_32) + AppendChar('e'); + + AppendString("sp"); + + return 0; +} + +int DSIreg(LPBYTE lpB) +{ + if (OPERAND_32) + AppendChar('e'); + + AppendString("si"); + + return 0; +} + +int DDIreg(LPBYTE lpB) +{ + if (OPERAND_32) + AppendChar('e'); + + AppendString("di"); + + return 0; +} + +int DCSreg(LPBYTE lpB) +{ + AppendString("cs"); + + return 0; +} + +int DDSreg(LPBYTE lpB) +{ + AppendString("ds"); + + return 0; +} + +int DSSreg(LPBYTE lpB) +{ + AppendString("es"); + + return 0; +} + +int DESreg(LPBYTE lpB) +{ + AppendString("es"); + + return 0; +} + +int DFSreg(LPBYTE lpB) +{ + AppendString("fs"); + + return 0; +} + +int DGSreg(LPBYTE lpB) +{ + AppendString("gs"); + + return 0; +} + +int DImmB(LPBYTE lpB) +{ + AppendNumber(*((UCHAR *)pData)); + pData++; + + return 1; +} + +int DImmBEnter(LPBYTE lpB) +{ + AppendNumber(*((UCHAR *)pData)); + pData++; + + return 1; +} + +int DImmBS(LPBYTE lpB) // sign-extend 8-bit value to 16 bits +{ + int i = (signed char)*(pData); + + AppendNumber((USHORT)i); + pData++; + + return 1; +} + +int DImmW(LPBYTE lpB) +{ + if (OPERAND_32) { + + AppendNumber( *((UNALIGNED ULONG*)pData) ); + pData+=4; + return 4; + + } else { + + AppendNumber( *((UNALIGNED USHORT*)pData) ); + pData+=2; + return 2; + + } +} + +int DImmW1(LPBYTE lpB) +{ + AppendNumber( *((UNALIGNED SHORT*)(pData)) ); + pData++; + + return 2; +} + +int DjmpB(LPBYTE lpB) +{ + ULONG Dest = g_InstrAddr.sOff + (LONG)*((UNALIGNED CHAR *)lpB) + OpcodeSize + 1; + + if (OPERAND_32) { + AppendNumber(Dest); + } else { + AppendNumber((USHORT)Dest); + } + + return 1; +} + +int DjmpW(LPBYTE lpB) +{ + ULONG Dest = g_InstrAddr.sOff + (ULONG)*((UNALIGNED USHORT *)lpB) + OpcodeSize + 2; + + if (OPERAND_32) { + AppendNumber(Dest); + } else { + AppendNumber((USHORT)Dest); + } + + return 2; +} + +int DregSeg(LPBYTE lpB) +{ + BYTE b = (*lpB >> 3) & 7; + + AppendString(szRegsSeg[b]); + + return 0; +} + + +int DmemB(LPBYTE lpB) +{ + ADDR addr; + + addr.sOff = *(lpB+1); + + AppendChar('['); + AppendNumber( addr.sOff ); + AppendChar(']'); + + if (g_pchExtra) { + BYTE b; + + if (prefixes & PREFIX_DS) { + ExtraChar('D'); + addr.sSeg = (USHORT)g_pThreadContext->SegDs; + } else if (prefixes & PREFIX_ES) { + ExtraChar('E'); + addr.sSeg = (USHORT)g_pThreadContext->SegEs; + } else if (prefixes & PREFIX_FS) { + ExtraChar('F'); + addr.sSeg = (USHORT)g_pThreadContext->SegFs; + } else if (prefixes & PREFIX_GS) { + ExtraChar('G'); + addr.sSeg = (USHORT)g_pThreadContext->SegGs; + } else if (prefixes & PREFIX_CS) { + ExtraChar('C'); + addr.sSeg = (USHORT)g_pThreadContext->SegCs; + } else if (prefixes & PREFIX_SS) { + ExtraChar('S'); + addr.sSeg = (USHORT)g_pThreadContext->SegSs; + } else { + ExtraChar('D'); + addr.sSeg = (USHORT)g_pThreadContext->SegDs; + } + + ExtraString("S:["); + ExtraNumber( addr.sOff ); + ExtraString("]="); + if (safe_read_byte(addr, &b)) { + ExtraNumber( b ); + } else { + ExtraString("??"); + } + + } + + return 1; +} + +int DmemB1(LPBYTE lpB) +{ + AppendNumber( *lpB ); + + return 1; +} + +int DmemW(LPBYTE lpB) +{ + int i; + ADDR addr; + + addr.sOff = *(lpB+1); + + AppendChar('['); + if (OPERAND_32) { + AppendNumber( *((UNALIGNED long*)lpB) ); + i=4; + } else { + addr.sOff = *((UNALIGNED short *)lpB); + AppendNumber( addr.sOff ); + i=2; + } + AppendChar(']'); + + if (g_pchExtra) { + + if (prefixes & PREFIX_DS) { + ExtraChar('D'); + addr.sSeg = (USHORT)g_pThreadContext->SegDs; + } else if (prefixes & PREFIX_ES) { + ExtraChar('E'); + addr.sSeg = (USHORT)g_pThreadContext->SegEs; + } else if (prefixes & PREFIX_FS) { + ExtraChar('F'); + addr.sSeg = (USHORT)g_pThreadContext->SegFs; + } else if (prefixes & PREFIX_GS) { + ExtraChar('G'); + addr.sSeg = (USHORT)g_pThreadContext->SegGs; + } else if (prefixes & PREFIX_CS) { + ExtraChar('C'); + addr.sSeg = (USHORT)g_pThreadContext->SegCs; + } else if (prefixes & PREFIX_SS) { + ExtraChar('S'); + addr.sSeg = (USHORT)g_pThreadContext->SegSs; + } else { + ExtraChar('D'); + addr.sSeg = (USHORT)g_pThreadContext->SegDs; + } + + ExtraString("S:["); + ExtraNumber( addr.sOff ); + ExtraString("]="); + if (i == 2) { + SHORT s; + if (safe_read_short(addr, &s)) { + ExtraNumber( s ); + } else { + ExtraString( "????" ); + } + } else { + LONG l; + + if (safe_read_long(addr, &l)) { + ExtraNumber( l ); + } else { + ExtraString( "????????" ); + } + } + } + + return i; +} + + +int DmemD(LPBYTE lpB) +{ + int i; + + if (OPERAND_32) { + AppendNumber( *(((UNALIGNED SHORT*)lpB)+2) ); + AppendChar(':'); + AppendNumber( *((UNALIGNED long*)lpB) ); + i=6; + } else { + USHORT sel, off; + + sel = *(((UNALIGNED SHORT*)lpB)+1); + off = *((UNALIGNED SHORT*)lpB); + AppendNumber( sel ); + AppendChar(':'); + AppendNumber( off ); + i=4; + + if (g_pchExtra) { + char sym_text[1000]; + LONG dist; + + // if the exact symbol name was found, print it + if (FindSymbol( sel, + off, + sym_text, + &dist, + BEFORE, + g_mode)) { + ExtraString("= "); + ExtraString(sym_text); + if (dist) { + ExtraString(" + "); + ExtraNumber( dist ); + } + } + } + + } + + return i; +} + +int DindirmodrmW(LPBYTE lpB) +{ + int i; + + AppendString("FAR PTR "); + i = DmodrmW(lpB); + AppendChar(']'); + + return i; +} + + +int DindirFARmodrmW(LPBYTE lpB) +{ + int i; + + AppendString("FAR PTR "); + i = DmodrmW(lpB); + AppendChar(']'); + + return i; +} + + +int DeeeControl(LPBYTE lpB) +{ + AppendChar('c'); + AppendChar('r'); + AppendChar('0'+ ((*lpB >> 3) & 7) ); + + return 1; +} + +int DeeeDebug(LPBYTE lpB) +{ + AppendChar('d'); + AppendChar('r'); + AppendChar('0'+ ((*lpB >> 3) & 7) ); + + return 1; +} + +int DeeeTest(LPBYTE lpB) +{ + AppendChar('t'); + AppendChar('r'); + AppendChar('0'+ ((*lpB >> 3) & 7) ); + + return 1; +} + + +LPBYTE checkprefixes(LPBYTE lpB) +{ + prefixes = 0; + + for (;;) { + + switch (*lpB) { + case 0xf3: + prefixes |= PREFIX_REPZ; + break; + case 0xf2: + prefixes |= PREFIX_REPNZ; + break; + case 0xf0: + prefixes |= PREFIX_LOCK; + break; + case 0x2e: + prefixes |= PREFIX_CS; + break; + case 0x36: + prefixes |= PREFIX_SS; + break; + case 0x3e: + prefixes |= PREFIX_DS; + break; + case 0x26: + prefixes |= PREFIX_ES; + break; + case 0x64: + prefixes |= PREFIX_FS; + break; + case 0x65: + prefixes |= PREFIX_GS; + break; + case 0x66: + prefixes |= PREFIX_DATA; + break; + case 0x67: + prefixes |= PREFIX_ADR; + break; + case 0x9b: + prefixes |= PREFIX_FWAIT; + break; + default: + return lpB; + } + lpB++; + } +} + + +void AppendPrefixes(void) +{ + if (prefixes & PREFIX_CS) + AppendString("cs:"); + if (prefixes & PREFIX_DS) + AppendString("ds:"); + if (prefixes & PREFIX_SS) + AppendString("ss:"); + if (prefixes & PREFIX_ES) + AppendString("es:"); + if (prefixes & PREFIX_FS) + AppendString("fs:"); + if (prefixes & PREFIX_GS) + AppendString("gs:"); +} -- cgit v1.2.3