Annotation of mstools/samples/sdktools/image/drwatson/i386/disasm.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1993  Microsoft Corporation
                      4: 
                      5: Module Name:
                      6: 
                      7:     disasm.c
                      8: 
                      9: Abstract:
                     10: 
                     11:     This file provides support disassembly ( x86 ).
                     12: 
                     13: Author:
                     14: 
                     15:     Gerd Immeyer       19-Oct-1989
                     16:     Wesley Witt (wesw) 1-May-1993    ( ported from ntsd to drwatson)
                     17: 
                     18: Environment:
                     19: 
                     20:     User Mode
                     21: 
                     22: --*/
                     23: 
                     24: #include <windows.h>
                     25: #include <stddef.h>
                     26: #include <string.h>
                     27: #include "regs.h"
                     28: #include "disasm.h"
                     29: #include "drwatson.h"
                     30: #include "proto.h"
                     31: 
                     32: /*****                     macros and defines                          *****/
                     33: 
                     34: #define BIT20(b) (b & 0x07)
                     35: #define BIT53(b) (b >> 3 & 0x07)
                     36: #define BIT76(b) (b >> 6 & 0x03)
                     37: #define MAXL     16
                     38: #define MAXOPLEN 10
                     39: 
                     40: #define OBOFFSET 26
                     41: #define OBOPERAND 34
                     42: #define OBLINEEND 77
                     43: 
                     44: /*****                     static tables and variables                 *****/
                     45: 
                     46: static char regtab[] = "alcldlblahchdhbhaxcxdxbxspbpsidi";  /* reg table */
                     47: static char *mrmtb16[] = { "bx+si",  /* modRM string table (16-bit) */
                     48:                            "bx+di",
                     49:                            "bp+si",
                     50:                            "bp+di",
                     51:                            "si",
                     52:                            "di",
                     53:                            "bp",
                     54:                            "bx"
                     55:                          };
                     56: 
                     57: static char *mrmtb32[] = { "eax",       /* modRM string table (32-bit) */
                     58:                            "ecx",
                     59:                            "edx",
                     60:                            "ebx",
                     61:                            "esp",
                     62:                            "ebp",
                     63:                            "esi",
                     64:                            "edi"
                     65:                          };
                     66: 
                     67: static char seg16[8]   = { REGDS,  REGDS,  REGSS,  REGSS,
                     68:                            REGDS,  REGDS,  REGSS,  REGDS };
                     69: static char reg16[8]   = { REGEBX, REGEBX, REGEBP, REGEBP,
                     70:                            REGESI, REGEDI, REGEBP, REGEBX };
                     71: static char reg16_2[4] = { REGESI, REGEDI, REGESI, REGEDI };
                     72: 
                     73: static char seg32[8]   = { REGDS,  REGDS,  REGDS,  REGDS,
                     74:                            REGSS,  REGSS,  REGDS,  REGDS };
                     75: static char reg32[8]   = { REGEAX, REGECX, REGEDX, REGEBX,
                     76:                            REGESP, REGEBP, REGESI, REGEDI };
                     77: 
                     78: static char sregtab[] = "ecsdfg";  // first letter of ES, CS, SS, DS, FS, GS
                     79: 
                     80: char    hexdigit[] = { '0', '1', '2', '3', '4', '5', '6', '7',
                     81:                        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
                     82: 
                     83: static int              mod;            /* mod of mod/rm byte */
                     84: static int              rm;             /* rm of mod/rm byte */
                     85: static int              ttt;            /* return reg value (of mod/rm) */
                     86: static unsigned char    *pMem;          /* current position in instruction */
                     87: static int              mode_32;        /* local addressing mode indicator */
                     88: static int              opsize_32;      /* operand size flag */
                     89: 
                     90: ULONG                   EAaddr[2];      //  offset of effective address
                     91: static int              EAsize[2];      //  size of effective address item
                     92: static char             *pchEAseg[2];   //  normal segment for operand
                     93: 
                     94: int                     G_mode_32 = 1;  /* global address mode indicator */
                     95: 
                     96: static BOOLEAN          fMovX;          // indicates a MOVSX or MOVZX
                     97: 
                     98: //      internal function definitions
                     99: 
                    100: BOOLEAN disasm(PDEBUGPACKET, PULONG, PUCHAR, BOOLEAN);
                    101: void DIdoModrm(PDEBUGPACKET dp,char **, int, BOOLEAN);
                    102: 
                    103: void OutputHexString(char **, char *, int);
                    104: void OutputHexValue(char **, char *, int, int);
                    105: void OutputHexCode(char **, char *, int);
                    106: void OutputString(char **, char *);
                    107: void OutputSymbol(PDEBUGPACKET, char **, char *, int, int);
                    108: 
                    109: void GetNextOffset(PDEBUGPACKET, PULONG, BOOLEAN);
                    110: void OutputHexAddr(PUCHAR *, ULONG);
                    111: USHORT GetSegRegValue(PDEBUGPACKET,int);
                    112: 
                    113: /**** disasm - disassemble an 80x86/80x87 instruction
                    114: *
                    115: *  Input:
                    116: *       pOffset = pointer to offset to start disassembly
                    117: *       fEAout = if set, include EA (effective address)
                    118: *
                    119: *  Output:
                    120: *       pOffset = pointer to offset of next instruction
                    121: *       pchDst = pointer to result string
                    122: *
                    123: ***************************************************************************/
                    124: 
                    125: BOOLEAN
                    126: disasm( PDEBUGPACKET dp, PULONG pOffset, PUCHAR pchDst, BOOLEAN fEAout )
                    127: {
                    128:     int     opcode;                     /* current opcode */
                    129:     int     olen = 2;                   /* operand length */
                    130:     int     alen = 2;                   /* address length */
                    131:     int     end = FALSE;                /* end of instruction flag */
                    132:     int     mrm = FALSE;                /* indicator that modrm is generated*/
                    133:     unsigned char *action;              /* action for operand interpretation*/
                    134:     long    tmp;                        /* temporary storage field */
                    135:     int     indx;                       /* temporary index */
                    136:     int     action2;                    /* secondary action */
                    137:     int     instlen;                    /* instruction length */
                    138:     int     cBytes;                     //  bytes read into instr buffer
                    139:     int     segOvr = 0;                 /* segment override opcode */
                    140:     char    membuf[MAXL];               /* current instruction buffer */
                    141:     char    *pEAlabel = "";             //  optional label for operand
                    142: 
                    143:     char    *pchResultBuf = pchDst;     //  working copy of pchDst pointer
                    144:     char    RepPrefixBuffer[32];        //  rep prefix buffer
                    145:     char    *pchRepPrefixBuf = RepPrefixBuffer; //  pointer to prefix buffer
                    146:     char    OpcodeBuffer[8];            //  opcode buffer
                    147:     char    *pchOpcodeBuf = OpcodeBuffer; //  pointer to opcode buffer
                    148:     char    OperandBuffer[80];          //  operand buffer
                    149:     char    *pchOperandBuf = OperandBuffer; //  pointer to operand buffer
                    150:     char    ModrmBuffer[80];            //  modRM buffer
                    151:     char    *pchModrmBuf = ModrmBuffer; //  pointer to modRM buffer
                    152:     char    EABuffer[42];               //  effective address buffer
                    153:     char    *pchEABuf = EABuffer;       //  pointer to EA buffer
                    154: 
                    155:     int     obOpcode = OBOFFSET;
                    156:     int     obOpcodeMin;
                    157:     int     obOpcodeMax;
                    158: 
                    159:     int     obOperand = OBOPERAND;
                    160:     int     obOperandMin;
                    161:     int     obOperandMax;
                    162: 
                    163:     int     cbOpcode;
                    164:     int     cbOperand;
                    165:     int     cbOffset;
                    166:     int     cbEAddr;
                    167: 
                    168:     int     fTwoLines = FALSE;
                    169: 
                    170:     fMovX = FALSE;
                    171:     EAsize[0] = EAsize[1] = 0;          //  no effective address
                    172:     pchEAseg[0] = dszDS_;
                    173:     pchEAseg[1] = dszES_;
                    174: 
                    175:     mode_32 = opsize_32 = (G_mode_32 == 1); /* local addressing mode */
                    176:     olen = alen = (1 + mode_32) << 1;   //  set operand/address lengths
                    177:                                         //  2 for 16-bit and 4 for 32-bit
                    178: 
                    179:     OutputHexAddr(&pchResultBuf, *pOffset);
                    180: 
                    181:     *pchResultBuf++ = ' ';
                    182: 
                    183:     ReadProcessMemory( dp->hProcess,
                    184:                        (LPVOID)*pOffset,
                    185:                        (LPVOID)membuf,
                    186:                        MAXL,
                    187:                        &cBytes
                    188:                      );
                    189: 
                    190:                                         /* move full inst to local buffer */
                    191:     pMem = membuf;                      /* point to begin of instruction */
                    192:     opcode = *pMem++;                   /* get opcode */
                    193:     OutputString(&pchOpcodeBuf, distbl[opcode].instruct);
                    194:     action = actiontbl + distbl[opcode].opr; /* get operand action */
                    195: 
                    196: /*****          loop through all operand actions               *****/
                    197: 
                    198:     do {
                    199:         action2 = (*action) & 0xc0;
                    200:         switch((*action++) & 0x3f) {
                    201:             case ALT:                   /* alter the opcode if 32-bit */
                    202:                 if (opsize_32) {
                    203:                     indx = *action++;
                    204:                     pchOpcodeBuf = &OpcodeBuffer[indx];
                    205:                     if (indx == 0)
                    206:                         OutputString(&pchOpcodeBuf, dszCWDE);
                    207:                     else {
                    208:                         *pchOpcodeBuf++ = 'd';
                    209:                         if (indx == 1)
                    210:                             *pchOpcodeBuf++ = 'q';
                    211:                         }
                    212:                     }
                    213:                 break;
                    214: 
                    215:             case STROP:
                    216:                 //  compute size of operands in indx
                    217:                 //  also if dword operands, change fifth
                    218:                 //  opcode letter from 'w' to 'd'.
                    219: 
                    220:                 if (opcode & 1) {
                    221:                     if (opsize_32) {
                    222:                         indx = 4;
                    223:                         OpcodeBuffer[4] = 'd';
                    224:                         }
                    225:                     else
                    226:                         indx = 2;
                    227:                     }
                    228:                 else
                    229:                     indx = 1;
                    230: 
                    231:                 if (*action & 1) {
                    232:                     if (fEAout) {
                    233:                         EAaddr[0] = GetRegValue(dp, REGESI);
                    234:                         EAsize[0] = indx;
                    235:                         }
                    236:                     }
                    237:                 if (*action++ & 2) {
                    238:                     if (fEAout) {
                    239:                         EAaddr[1] = GetRegValue(dp, REGEDI);
                    240:                         EAsize[1] = indx;
                    241:                         }
                    242:                     }
                    243:                 break;
                    244: 
                    245:             case CHR:                   /* insert a character */
                    246:                 *pchOperandBuf++ = *action++;
                    247:                 break;
                    248: 
                    249:             case CREG:                  /* set debug, test or control reg */
                    250:                 if ((opcode - 231) & 0x04)      //  remove bias from opcode
                    251:                     *pchOperandBuf++ = 't';
                    252:                 else if ((opcode - 231) & 0x01)
                    253:                     *pchOperandBuf++ = 'd';
                    254:                 else
                    255:                     *pchOperandBuf++ = 'c';
                    256:                 *pchOperandBuf++ = 'r';
                    257:                 *pchOperandBuf++ = (char)('0' + ttt);
                    258:                 break;
                    259: 
                    260:             case SREG2:                 /* segment register */
                    261:                 ttt = BIT53(opcode);    //  set value to fall through
                    262: 
                    263:             case SREG3:                 /* segment register */
                    264:                 *pchOperandBuf++ = sregtab[ttt];  // reg is part of modrm
                    265:                 *pchOperandBuf++ = 's';
                    266:                 break;
                    267: 
                    268:             case BRSTR:                 /* get index to register string */
                    269:                 ttt = *action++;        /*    from action table */
                    270:                 goto BREGlabel;
                    271: 
                    272:             case BOREG:                 /* byte register (in opcode) */
                    273:                 ttt = BIT20(opcode);    /* register is part of opcode */
                    274:                 goto BREGlabel;
                    275: 
                    276:             case ALSTR:
                    277:                 ttt = 0;                /* point to AL register */
                    278: BREGlabel:
                    279:             case BREG:                  /* general register */
                    280:                 *pchOperandBuf++ = regtab[ttt * 2];
                    281:                 *pchOperandBuf++ = regtab[ttt * 2 + 1];
                    282:                 break;
                    283: 
                    284:             case WRSTR:                 /* get index to register string */
                    285:                 ttt = *action++;        /*    from action table */
                    286:                 goto WREGlabel;
                    287: 
                    288:             case VOREG:                 /* register is part of opcode */
                    289:                 ttt = BIT20(opcode);
                    290:                 goto VREGlabel;
                    291: 
                    292:             case AXSTR:
                    293:                 ttt = 0;                /* point to eAX register */
                    294: VREGlabel:
                    295:             case VREG:                  /* general register */
                    296:                 if (opsize_32)          /* test for 32bit mode */
                    297:                     *pchOperandBuf++ = 'e';
                    298: WREGlabel:
                    299:             case WREG:                  /* register is word size */
                    300:                 *pchOperandBuf++ = regtab[ttt * 2 + 16];
                    301:                 *pchOperandBuf++ = regtab[ttt * 2 + 17];
                    302:                 break;
                    303: 
                    304:             case IST_ST:
                    305:                 OutputString(&pchOperandBuf, "st(0),st");
                    306:                 *(pchOperandBuf - 5) += rm;
                    307:                 break;
                    308: 
                    309:             case ST_IST:
                    310:                 OutputString(&pchOperandBuf, "st,");
                    311:             case IST:
                    312:                 OutputString(&pchOperandBuf, "st(0)");
                    313:                 *(pchOperandBuf - 2) += rm;
                    314:                 break;
                    315: 
                    316:             case xBYTE:                 /* set instruction to byte only */
                    317:                 EAsize[0] = 1;
                    318:                 pEAlabel = "byte ptr ";
                    319:                 break;
                    320: 
                    321:             case VAR:
                    322:                 if (opsize_32)
                    323:                     goto DWORDlabel;
                    324: 
                    325:             case xWORD:
                    326:                 EAsize[0] = 2;
                    327:                 pEAlabel = "word ptr ";
                    328:                 break;
                    329: 
                    330:             case EDWORD:
                    331:                 opsize_32 = 1;    //  for control reg move, use eRegs
                    332:             case xDWORD:
                    333: DWORDlabel:
                    334:                 EAsize[0] = 4;
                    335:                 pEAlabel = "dword ptr ";
                    336:                 break;
                    337: 
                    338:             case QWORD:
                    339:                 EAsize[0] = 8;
                    340:                 pEAlabel = "qword ptr ";
                    341:                 break;
                    342: 
                    343:             case TTBYTE:
                    344:                 EAsize[0] = 10;
                    345:                 pEAlabel = "tbyte ptr ";
                    346:                 break;
                    347: 
                    348:             case FARPTR:
                    349:                 if (opsize_32) {
                    350:                     EAsize[0] = 6;
                    351:                     pEAlabel = "fword ptr ";
                    352:                     }
                    353:                 else {
                    354:                     EAsize[0] = 4;
                    355:                     pEAlabel = "dword ptr ";
                    356:                     }
                    357:                 break;
                    358: 
                    359:             case LMODRM:                //  output modRM data type
                    360:                 if (mod != 3)
                    361:                     OutputString(&pchOperandBuf, pEAlabel);
                    362:                 else
                    363:                     EAsize[0] = 0;
                    364: 
                    365:             case MODRM:                 /* output modrm string */
                    366:                 if (segOvr)             /* in case of segment override */
                    367:                     OutputString(&pchOperandBuf, distbl[segOvr].instruct);
                    368:                 *pchModrmBuf = '\0';
                    369:                 OutputString(&pchOperandBuf, ModrmBuffer);
                    370:                 break;
                    371: 
                    372:             case ADDRP:                 /* address pointer */
                    373:                 OutputHexString(&pchOperandBuf, pMem + olen, 2); // segment
                    374:                 *pchOperandBuf++ = ':';
                    375:                 OutputSymbol(dp, &pchOperandBuf, pMem, olen, segOvr);
                    376:                 pMem += olen + 2;
                    377:                 break;
                    378: 
                    379:             case REL8:                  /* relative address 8-bit */
                    380:                 if (opcode == 0xe3 && mode_32) {
                    381:                     pchOpcodeBuf = OpcodeBuffer;
                    382:                     OutputString(&pchOpcodeBuf, dszJECXZ);
                    383:                     }
                    384:                 tmp = (long)*(char *)pMem++; /* get the 8-bit rel offset */
                    385:                 goto DoRelDispl;
                    386: 
                    387:             case REL16:                 /* relative address 16-/32-bit */
                    388:                 tmp = 0;
                    389:                 memmove(&tmp,pMem,sizeof(long));
                    390:                 pMem += alen;           /* skip over offset */
                    391: DoRelDispl:
                    392:                 tmp += *pOffset + (pMem - membuf); /* calculate address */
                    393:                 OutputSymbol(dp, &pchOperandBuf, (char *) &tmp, alen, segOvr);
                    394:                                                    // address
                    395:                 break;
                    396: 
                    397:             case UBYTE:                 //  unsigned byte for int/in/out
                    398:                 OutputHexString(&pchOperandBuf, pMem, 1);  //  ubyte
                    399:                 pMem++;
                    400:                 break;
                    401: 
                    402:             case IB:                    /* operand is immediate byte */
                    403:                 if ((opcode & ~1) == 0xd4) {  // postop for AAD/AAM is 0x0a
                    404:                     if (*pMem++ != 0x0a) // test post-opcode byte
                    405:                         OutputString(&pchOperandBuf, dszRESERVED);
                    406:                     break;
                    407:                     }
                    408:                 olen = 1;               /* set operand length */
                    409:                 goto DoImmed;
                    410: 
                    411:             case IW:                    /* operand is immediate word */
                    412:                 olen = 2;               /* set operand length */
                    413: 
                    414:             case IV:                    /* operand is word or dword */
                    415: DoImmed:
                    416:                 OutputHexValue(&pchOperandBuf, pMem, olen, FALSE);
                    417:                 pMem += olen;
                    418:                 break;
                    419: 
                    420:             case OFFS:                  /* operand is offset */
                    421:                 EAsize[0] = (opcode & 1) ? olen : 1;
                    422: 
                    423:                 if (segOvr)             /* in case of segment override */
                    424:                     OutputString(&pchOperandBuf, distbl[segOvr].instruct);
                    425: 
                    426:                 *pchOperandBuf++ = '[';
                    427:                 OutputSymbol(dp,&pchOperandBuf, pMem, alen, segOvr);  //  offset
                    428:                 pMem += alen;
                    429:                 *pchOperandBuf++ = ']';
                    430:                 break;
                    431: 
                    432:             case GROUP:                 /* operand is of group 1,2,4,6 or 8 */
                    433:                                         /* output opcode symbol */
                    434:                 OutputString(&pchOpcodeBuf, group[*action++][ttt]);
                    435:                 break;
                    436: 
                    437:             case GROUPT:                /* operand is of group 3,5 or 7 */
                    438:                 indx = *action;         /* get indx into group from action */
                    439:                 goto doGroupT;
                    440: 
                    441:             case EGROUPT:               /* x87 ESC (D8-DF) group index */
                    442:                 indx = BIT20(opcode) * 2; /* get group index from opcode */
                    443:                 if (mod == 3) {         /* some operand variations exists */
                    444:                                         /*   for x87 and mod == 3 */
                    445:                     ++indx;             /* take the next group table entry */
                    446:                     if (indx == 3) {    /* for x87 ESC==D9 and mod==3 */
                    447:                         if (ttt > 3) {  /* for those D9 instructions */
                    448:                             indx = 12 + ttt; /* offset index to table by 12 */
                    449:                             ttt = rm;   /* set secondary index to rm */
                    450:                             }
                    451:                         }
                    452:                     else if (indx == 7) { /* for x87 ESC==DB and mod==3 */
                    453:                         if (ttt == 4)   /* only valid if ttt==4 */
                    454:                             ttt = rm;   /* set secondary group table index */
                    455:                         else
                    456:                             ttt = 7;    /* no an x87 instruction */
                    457:                         }
                    458:                     }
                    459: doGroupT:
                    460:                 /* handle group with different types of operands */
                    461: 
                    462:                 OutputString(&pchOpcodeBuf, groupt[indx][ttt].instruct);
                    463:                 action = actiontbl + groupt[indx][ttt].opr;
                    464:                                                         /* get new action */
                    465:                 break;
                    466: 
                    467:             case OPC0F:                 /* secondary opcode table (opcode 0F) */
                    468:                 opcode = *pMem++;       /* get real opcode */
                    469:                 fMovX  = (BOOLEAN)(opcode == 0xBF || opcode == 0xB7);
                    470:                 if (opcode < 7) /* for the first 7 opcodes */
                    471:                     opcode += 256;      /* point begin of secondary opcode tab. */
                    472:                 else if (opcode > 0x1f && opcode < 0x27)
                    473:                     opcode += 231;      /* adjust for non-existing opcodes */
                    474:                 else if (opcode > 0x2f && opcode < 0x33)
                    475:                     opcode += 222;      /* adjust for non-existing opcodes */
                    476:                 else if (opcode > 0x7e && opcode < 0xd0)
                    477:                     opcode += 148;      /* adjust for non-existing opcodes */
                    478:                 else
                    479:                     opcode = 260;       /* all non-existing opcodes */
                    480:                 goto getNxtByte1;
                    481: 
                    482:             case ADR_OVR:               /* address override */
                    483:                 mode_32 = !G_mode_32;   /* override addressing mode */
                    484:                 alen = (mode_32 + 1) << 1; /* toggle address length */
                    485:                 goto getNxtByte;
                    486: 
                    487:             case OPR_OVR:               /* operand size override */
                    488:                 opsize_32 = !G_mode_32; /* override operand size */
                    489:                 olen = (opsize_32 + 1) << 1; /* toggle operand length */
                    490:                 goto getNxtByte;
                    491: 
                    492:             case SEG_OVR:               /* handle segment override */
                    493:                 segOvr = opcode;        /* save segment override opcode */
                    494:                 pchOpcodeBuf = OpcodeBuffer;  // restart the opcode string
                    495:                 goto getNxtByte;
                    496: 
                    497:             case REP:                   /* handle rep/lock prefixes */
                    498:                 *pchOpcodeBuf = '\0';
                    499:                 if (pchRepPrefixBuf != RepPrefixBuffer)
                    500:                     *pchRepPrefixBuf++ = ' ';
                    501:                 OutputString(&pchRepPrefixBuf, OpcodeBuffer);
                    502:                 pchOpcodeBuf = OpcodeBuffer;
                    503: getNxtByte:
                    504:                 opcode = *pMem++;        /* next byte is opcode */
                    505: getNxtByte1:
                    506:                 action = actiontbl + distbl[opcode].opr;
                    507:                 OutputString(&pchOpcodeBuf, distbl[opcode].instruct);
                    508: 
                    509:             default:                    /* opcode has no operand */
                    510:                 break;
                    511:             }
                    512:         switch (action2) {              /* secondary action */
                    513:             case MRM:                   /* generate modrm for later use */
                    514:                 if (!mrm) {             /* ignore if it has been generated */
                    515:                     DIdoModrm(dp, &pchModrmBuf, segOvr, fEAout);
                    516:                                         /* generate modrm */
                    517:                     mrm = TRUE;         /* remember its generation */
                    518:                     }
                    519:                 break;
                    520: 
                    521:             case COM:                   /* insert a comma after operand */
                    522:                 *pchOperandBuf++ = ',';
                    523:                 break;
                    524: 
                    525:             case END:                   /* end of instruction */
                    526:                 end = TRUE;
                    527:                 break;
                    528:             }
                    529:  } while (!end);                        /* loop til end of instruction */
                    530: 
                    531: /*****       prepare disassembled instruction for output              *****/
                    532: 
                    533:     instlen = pMem - membuf;
                    534: 
                    535:     if (instlen < cBytes)
                    536:         cBytes = instlen;
                    537: 
                    538:     OutputHexCode(&pchResultBuf, membuf, cBytes);
                    539: 
                    540:     if (instlen > cBytes) {
                    541:         *pchResultBuf++ = '?';
                    542:         *pchResultBuf++ = '?';
                    543:         (*pOffset)++;                   //  point past unread byte
                    544:         }
                    545: 
                    546:     *pOffset += instlen;                /* set instruction length */
                    547: 
                    548:     if (instlen > cBytes) {
                    549:         do
                    550:             *pchResultBuf++ = ' ';
                    551:         while (pchResultBuf < pchDst + OBOFFSET);
                    552:         OutputString(&pchResultBuf, "???");
                    553:         *pchResultBuf++ = '\0';
                    554:         return FALSE;
                    555:         }
                    556: 
                    557:     //  if fEAout is set, build each EA with trailing space in EABuf
                    558:     //  point back over final trailing space if buffer nonnull
                    559: 
                    560:     if (fEAout) {
                    561: 
                    562:         for (indx = 0; indx < 2; indx++)
                    563:             if (EAsize[indx]) {
                    564:                 OutputString(&pchEABuf, segOvr ? distbl[segOvr].instruct
                    565:                                                : pchEAseg[indx]);
                    566:                 OutputHexAddr(&pchEABuf, EAaddr[indx]);
                    567:                 *pchEABuf++ = '=';
                    568: 
                    569:                 ReadProcessMemory( dp->hProcess,
                    570:                                    (LPVOID)EAaddr[indx],
                    571:                                    (LPVOID)membuf,
                    572:                                    EAsize[indx],
                    573:                                    &tmp
                    574:                                  );
                    575: 
                    576:                 if (tmp == EAsize[indx])
                    577:                     OutputHexString(&pchEABuf, (char *)membuf,
                    578:                                                EAsize[indx]);
                    579:                 else
                    580:                     while (EAsize[indx]--) {
                    581:                         *pchEABuf++ = '?';
                    582:                         *pchEABuf++ = '?';
                    583:                         }
                    584:                 *pchEABuf++ = ' ';
                    585:                 }
                    586:         if (pchEABuf != EABuffer)
                    587:             pchEABuf--;
                    588:         }
                    589: 
                    590:     //  compute lengths of component strings.
                    591:     //  if the rep string is nonnull,
                    592:     //      add the opcode string length to the operand
                    593:     //      make the rep string the opcode string
                    594: 
                    595:     cbOffset = pchResultBuf - pchDst;
                    596:     cbOperand = pchOperandBuf - OperandBuffer;
                    597:     cbOpcode = pchOpcodeBuf - OpcodeBuffer;
                    598:     if (pchRepPrefixBuf != RepPrefixBuffer) {
                    599:         cbOperand += cbOpcode + (cbOperand != 0);
                    600:         cbOpcode = pchRepPrefixBuf - RepPrefixBuffer;
                    601:         }
                    602:     cbEAddr = pchEABuf - EABuffer;
                    603: 
                    604:     //  for really long strings, where the opcode and operand
                    605:     //      will not fit on a 77-character line, make two lines
                    606:     //      with the opcode on offset 0 on the second line with
                    607:     //      the operand following after one space
                    608: 
                    609:     if (cbOpcode + cbOperand > OBLINEEND - 1) {
                    610:         fTwoLines = TRUE;
                    611:         obOpcode = 0;
                    612:         obOperand = cbOpcode + 1;
                    613:         }
                    614:     else {
                    615: 
                    616:         //  compute the minimum and maximum offset values for
                    617:         //      opcode and operand strings.
                    618:         //  if strings are nonnull, add extra for separating space
                    619: 
                    620:         obOpcodeMin = cbOffset + 1;
                    621:         obOperandMin = obOpcodeMin + cbOpcode + 1;
                    622:         obOperandMax = OBLINEEND - cbEAddr - (cbEAddr != 0) - cbOperand;
                    623:         obOpcodeMax = obOperandMax - (cbOperand != 0) - cbOpcode;
                    624: 
                    625:         //  if minimum offset is more than the maximum, the strings
                    626:         //      will not fit on one line.  recompute the min/max
                    627:         //      values with no offset and EA strings.
                    628: 
                    629:         if (obOpcodeMin > obOpcodeMax) {
                    630:             fTwoLines = TRUE;
                    631:             obOpcodeMin = 0;
                    632:             obOperandMin = cbOpcode + 1;
                    633:             obOperandMax = OBLINEEND - cbOperand;
                    634:             obOpcodeMax = obOperandMax - (cbOperand != 0) - cbOpcode;
                    635:             }
                    636: 
                    637:         //  compute the opcode and operand offsets.  set offset as
                    638:         //      close to the default values as possible.
                    639: 
                    640:         if (obOpcodeMin > OBOFFSET)
                    641:             obOpcode = obOpcodeMin;
                    642:         else if (obOpcodeMax < OBOFFSET)
                    643:             obOpcode = obOpcodeMax;
                    644: 
                    645:         obOperandMin = obOpcode + cbOpcode + 1;
                    646: 
                    647:         if (obOperandMin > OBOPERAND)
                    648:             obOperand = obOperandMin;
                    649:         else if (obOperandMax < OBOPERAND)
                    650:             obOperand = obOperandMax;
                    651:         }
                    652: 
                    653:     //  build the resultant string with the offsets computed
                    654: 
                    655:     //  if two lines are to be output,
                    656:     //      append the EAddr string
                    657:     //      output a new line and reset the pointer
                    658: 
                    659:     if (fTwoLines) {
                    660:         if (pchEABuf != EABuffer) {
                    661:             do
                    662:                 *pchResultBuf++ = ' ';
                    663:             while (pchResultBuf < pchDst + OBLINEEND - cbEAddr);
                    664:             *pchEABuf = '\0';
                    665:             OutputString(&pchResultBuf, EABuffer);
                    666:             }
                    667:         pchDst = pchResultBuf;
                    668:         }
                    669: 
                    670:     //  output rep, opcode, and operand strings
                    671: 
                    672:     do
                    673:         *pchResultBuf++ = ' ';
                    674:     while (pchResultBuf < pchDst + obOpcode);
                    675: 
                    676:     if (pchRepPrefixBuf != RepPrefixBuffer) {
                    677:         *pchRepPrefixBuf = '\0';
                    678:         OutputString(&pchResultBuf, RepPrefixBuffer);
                    679:         do
                    680:             *pchResultBuf++ = ' ';
                    681:         while (pchResultBuf < pchDst + obOperand);
                    682:         }
                    683: 
                    684:     *pchOpcodeBuf = '\0';
                    685:     OutputString(&pchResultBuf, OpcodeBuffer);
                    686: 
                    687:     if (pchOperandBuf != OperandBuffer) {
                    688:         do
                    689:             *pchResultBuf++ = ' ';
                    690:         while (pchResultBuf < pchDst + obOperand);
                    691:         *pchOperandBuf = '\0';
                    692:         OutputString(&pchResultBuf, OperandBuffer);
                    693:         }
                    694: 
                    695:     //  if one line is to be output, append the EAddr string
                    696: 
                    697:     if (!fTwoLines && pchEABuf != EABuffer) {
                    698:         *pchEABuf = '\0';
                    699:         do
                    700:             *pchResultBuf++ = ' ';
                    701:         while (pchResultBuf < pchDst + OBLINEEND - cbEAddr);
                    702:         OutputString(&pchResultBuf, EABuffer);
                    703:         }
                    704: 
                    705:     *pchResultBuf = '\0';
                    706:     return TRUE;
                    707: }
                    708: 
                    709: /*...........................internal function..............................*/
                    710: /*                                                                          */
                    711: /*                       generate a mod/rm string                           */
                    712: /*                                                                          */
                    713: 
                    714: void
                    715: DIdoModrm (PDEBUGPACKET dp, char **ppchBuf, int segOvr, BOOLEAN fEAout)
                    716: {
                    717:     int     mrm;                        /* modrm byte */
                    718:     char    *src;                       /* source string */
                    719:     int     sib;
                    720:     int     ss;
                    721:     int     ind;
                    722:     int     oldrm;
                    723: 
                    724:     mrm = *pMem++;                      /* get the mrm byte from instruction */
                    725:     mod = BIT76(mrm);                   /* get mod */
                    726:     ttt = BIT53(mrm);                   /* get reg - used outside routine */
                    727:     rm  = BIT20(mrm);                   /* get rm */
                    728: 
                    729:     if (mod == 3) {                     /* register only mode */
                    730:         src = &regtab[rm * 2];          /* point to 16-bit register */
                    731:         if (EAsize[0] > 1) {
                    732:             src += 16;                  /* point to 16-bit register */
                    733:             if (opsize_32 && !fMovX)
                    734:                 *(*ppchBuf)++ = 'e';    /* make it a 32-bit register */
                    735:             }
                    736:         *(*ppchBuf)++ = *src++;         /* copy register name */
                    737:         *(*ppchBuf)++ = *src;
                    738:         EAsize[0] = 0;                  //  no EA value to output
                    739:         return;
                    740:         }
                    741: 
                    742:     if (mode_32) {                      /* 32-bit addressing mode */
                    743:         oldrm = rm;
                    744:         if (rm == 4) {                  /* rm == 4 implies sib byte */
                    745:             sib = *pMem++;              /* get s_i_b byte */
                    746:             rm = BIT20(sib);            /* return base */
                    747:             }
                    748: 
                    749:         *(*ppchBuf)++ = '[';
                    750:         if (mod == 0 && rm == 5) {
                    751:             OutputSymbol(dp,ppchBuf, pMem, 4, segOvr); // offset
                    752:             pMem += 4;
                    753:             }
                    754:         else {
                    755:             if (fEAout) {
                    756:                 if (segOvr) {
                    757:                     EAaddr[0] = GetRegValue(dp, reg32[rm]);
                    758:                     pchEAseg[0] = distbl[segOvr].instruct;
                    759:                     }
                    760:                 else if (reg32[rm] == REGEBP || reg32[rm] == REGESP) {
                    761:                     EAaddr[0] = GetRegValue(dp, reg32[rm]);
                    762:                     pchEAseg[0] = dszSS_;
                    763:                     }
                    764:                 else
                    765:                     EAaddr[0] = GetRegValue(dp, reg32[rm]);
                    766:                 }
                    767:             OutputString(ppchBuf, mrmtb32[rm]);
                    768:             }
                    769: 
                    770:         if (oldrm == 4) {               //  finish processing sib
                    771:             ind = BIT53(sib);
                    772:             if (ind != 4) {
                    773:                 *(*ppchBuf)++ = '+';
                    774:                 OutputString(ppchBuf, mrmtb32[ind]);
                    775:                 ss = 1 << BIT76(sib);
                    776:                 if (ss != 1) {
                    777:                     *(*ppchBuf)++ = '*';
                    778:                     *(*ppchBuf)++ = (char)(ss + '0');
                    779:                     }
                    780:                 if (fEAout)
                    781:                     EAaddr[0] = GetRegValue(dp, reg32[ind]);
                    782:                 }
                    783:             }
                    784:         }
                    785:     else {                              //  16-bit addressing mode
                    786:         *(*ppchBuf)++ = '[';
                    787:         if (mod == 0 && rm == 6) {
                    788:             OutputSymbol(dp,ppchBuf, pMem, 2, segOvr);   // 16-bit offset
                    789:             pMem += 2;
                    790:             }
                    791:         else {
                    792:             if (fEAout) {
                    793:                 if (segOvr) {
                    794:                     EAaddr[0] = GetRegValue(dp, reg16[rm]);
                    795:                     pchEAseg[0] = distbl[segOvr].instruct;
                    796:                     }
                    797:                 else if (reg16[rm] == REGEBP) {
                    798:                     EAaddr[0] = GetRegValue(dp, reg16[rm]);
                    799:                     pchEAseg[0] = dszSS_;
                    800:                     }
                    801:                 else
                    802:                     EAaddr[0] = GetRegValue(dp, reg16[rm]);
                    803:                 if (rm < 4)
                    804:                     EAaddr[0] += GetRegValue(dp, reg16_2[rm]);
                    805:             }
                    806:             OutputString(ppchBuf, mrmtb16[rm]);
                    807:             }
                    808:         }
                    809: 
                    810:     //  output any displacement
                    811: 
                    812:     if (mod == 1) {
                    813:         if (fEAout)
                    814:             EAaddr[0] += (ULONG)pMem;
                    815:         OutputHexValue(ppchBuf, pMem, 1, TRUE);
                    816:         pMem++;
                    817:         }
                    818:     else if (mod == 2) {
                    819:         long tmp = 0;
                    820:         if (mode_32) {
                    821:             memmove(&tmp,pMem,sizeof(long));
                    822:             if (fEAout)
                    823:                 EAaddr[0] += (ULONG)tmp;
                    824:             OutputHexValue(ppchBuf, pMem, 4, TRUE);
                    825:             pMem += 4;
                    826:             }
                    827:         else {
                    828:             memmove(&tmp,pMem,sizeof(short));
                    829:             if (fEAout)
                    830:                 EAaddr[0] += tmp;
                    831:             OutputHexValue(ppchBuf, pMem, 2, TRUE);
                    832:             pMem += 2;
                    833:             }
                    834:         }
                    835: 
                    836:     if (!mode_32 && fEAout) {
                    837:         EAaddr[0] &= 0xffff;
                    838:         EAaddr[1] &= 0xffff;
                    839:     }
                    840: 
                    841:     *(*ppchBuf)++ = ']';
                    842: }
                    843: 
                    844: /*** OutputHexValue - output hex value
                    845: *
                    846: *   Purpose:
                    847: *       Output the value pointed by *ppchBuf of the specified
                    848: *       length.  The value is treated as signed and leading
                    849: *       zeroes are not printed.  The string is prefaced by a
                    850: *       '+' or '-' sign as appropriate.
                    851: *
                    852: *   Input:
                    853: *       *ppchBuf - pointer to text buffer to fill
                    854: *       *pchMemBuf - pointer to memory buffer to extract value
                    855: *       length - length in bytes of value (1, 2, and 4 supported)
                    856: *       fDisp - set if displacement to output '+'
                    857: *
                    858: *   Output:
                    859: *       *ppchBuf - pointer updated to next text character
                    860: *
                    861: *************************************************************************/
                    862: 
                    863: void OutputHexValue (char **ppchBuf, char *pchMemBuf, int length, int fDisp)
                    864: {
                    865:     long    value;
                    866:     int     index;
                    867:     char    digit[8];
                    868: 
                    869:     value = 0;
                    870:     if (length == 1)
                    871:         value = (long)(*(char *)pchMemBuf);
                    872:     else if (length == 2)
                    873:         memmove(&value,pchMemBuf,2);
                    874:     else
                    875:         memmove(&value,pchMemBuf,sizeof(long));
                    876: 
                    877:     length <<= 1;               //  shift once to get hex length
                    878: 
                    879:     if (value != 0 || !fDisp) {
                    880:         if (fDisp)
                    881:             if (value < 0 && length == 2) {   //  use neg value for byte
                    882:                 value = -value;               //    displacement
                    883:                 *(*ppchBuf)++ = '-';
                    884:                 }
                    885:             else
                    886:                 *(*ppchBuf)++ = '+';
                    887: 
                    888:         *(*ppchBuf)++ = '0';
                    889:         *(*ppchBuf)++ = 'x';
                    890:         for (index = length - 1; index != -1; index--) {
                    891:             digit[index] = (char)(value & 0xf);
                    892:             value >>= 4;
                    893:             }
                    894:         index = 0;
                    895:         while (digit[index] == 0 && index < length - 1)
                    896:             index++;
                    897:         while (index < length)
                    898:             *(*ppchBuf)++ = hexdigit[digit[index++]];
                    899:         }
                    900: }
                    901: 
                    902: /*** OutputHexString - output hex string
                    903: *
                    904: *   Purpose:
                    905: *       Output the value pointed by *ppchMemBuf of the specified
                    906: *       length.  The value is treated as unsigned and leading
                    907: *       zeroes are printed.
                    908: *
                    909: *   Input:
                    910: *       *ppchBuf - pointer to text buffer to fill
                    911: *       *pchValue - pointer to memory buffer to extract value
                    912: *       length - length in bytes of value
                    913: *
                    914: *   Output:
                    915: *       *ppchBuf - pointer updated to next text character
                    916: *       *ppchMemBuf - pointer update to next memory byte
                    917: *
                    918: *************************************************************************/
                    919: 
                    920: void
                    921: OutputHexString (char **ppchBuf, char *pchValue, int length)
                    922: {
                    923:     unsigned char    chMem;
                    924: 
                    925:     pchValue += length;
                    926:     while (length--) {
                    927:         chMem = *--pchValue;
                    928:         *(*ppchBuf)++ = hexdigit[chMem >> 4];
                    929:         *(*ppchBuf)++ = hexdigit[chMem & 0x0f];
                    930:         }
                    931: }
                    932: 
                    933: /*** OutputHexCode - output hex code
                    934: *
                    935: *   Purpose:
                    936: *       Output the code pointed by pchMemBuf of the specified
                    937: *       length.  The value is treated as unsigned and leading
                    938: *       zeroes are printed.  This differs from OutputHexString
                    939: *       in that bytes are printed from low to high addresses.
                    940: *
                    941: *   Input:
                    942: *       *ppchBuf - pointer to text buffer to fill
                    943: *       pchMemBuf - pointer to memory buffer to extract value
                    944: *       length - length in bytes of value
                    945: *
                    946: *   Output:
                    947: *       *ppchBuf - pointer updated to next text character
                    948: *
                    949: *************************************************************************/
                    950: 
                    951: void
                    952: OutputHexCode (char **ppchBuf, char *pchMemBuf, int length)
                    953: {
                    954:     unsigned char    chMem;
                    955: 
                    956:     while (length--) {
                    957:         chMem = *pchMemBuf++;
                    958:         *(*ppchBuf)++ = hexdigit[chMem >> 4];
                    959:         *(*ppchBuf)++ = hexdigit[chMem & 0x0f];
                    960:         }
                    961: }
                    962: 
                    963: /*** OutputString - output string
                    964: *
                    965: *   Purpose:
                    966: *       Copy the string into the buffer pointed by *ppBuf.
                    967: *
                    968: *   Input:
                    969: *       *pStr - pointer to string
                    970: *
                    971: *   Output:
                    972: *       *ppBuf points to next character in buffer.
                    973: *
                    974: *************************************************************************/
                    975: 
                    976: void
                    977: OutputString (char **ppBuf, char *pStr)
                    978: {
                    979:     while (*pStr)
                    980:         *(*ppBuf)++ = *pStr++;
                    981: }
                    982: 
                    983: /*** OutputSymbol - output symbolic value
                    984: *
                    985: *   Purpose:
                    986: *       Output the value in outvalue into the buffer
                    987: *       pointed by *pBuf.  Express the value as a
                    988: *       symbol plus displacment, if possible.
                    989: *
                    990: *   Input:
                    991: *       *ppBuf - pointer to text buffer to fill
                    992: *       *pValue - pointer to memory buffer to extract value
                    993: *       length - length in bytes of value
                    994: *
                    995: *   Output:
                    996: *       *ppBuf - pointer updated to next text character
                    997: *
                    998: *************************************************************************/
                    999: 
                   1000: void
                   1001: OutputSymbol (PDEBUGPACKET dp, char **ppBuf, char *pValue, int length, int segOvr)
                   1002: {
                   1003:     ULONG   displacement;
                   1004:     ULONG   value;
                   1005:     PSYMBOL sym;
                   1006:     char    *szSymName;
                   1007: 
                   1008:     value = 0;
                   1009:     if (length == 1)
                   1010:         value = (long)(*(char *)pValue);
                   1011:     else if (length == 2)
                   1012:         memmove(&value,pValue,sizeof(short));
                   1013:     else
                   1014:         memmove(&value,pValue,sizeof(long));
                   1015: 
                   1016:     EAaddr[0] = value;
                   1017: 
                   1018:     sym = GetSymFromAddrAllContexts( value, &displacement, dp );
                   1019:     if (sym) {
                   1020:         szSymName = UnDName( &sym->szName[1] );
                   1021:         OutputString(ppBuf, szSymName);
                   1022:         OutputHexValue(ppBuf, (char *)&displacement, length, TRUE);
                   1023:         *(*ppBuf)++ = ' ';
                   1024:         *(*ppBuf)++ = '(';
                   1025:         OutputHexString(ppBuf, pValue, length);
                   1026:         *(*ppBuf)++ = ')';
                   1027:         }
                   1028:     else
                   1029:         OutputHexString(ppBuf, pValue, length);
                   1030: }
                   1031: 
                   1032: /*** X86GetNextOffset - compute offset for trace or step
                   1033: *
                   1034: *   Purpose:
                   1035: *       From a limited disassembly of the instruction pointed
                   1036: *       by the FIR register, compute the offset of the next
                   1037: *       instruction for either a trace or step operation.
                   1038: *
                   1039: *   Input:
                   1040: *       fStep - TRUE if step offset returned - FALSE for trace offset
                   1041: *
                   1042: *   Returns:
                   1043: *       step or trace offset if input is TRUE or FALSE, respectively
                   1044: *       -1 returned for trace flag to be used
                   1045: *
                   1046: *************************************************************************/
                   1047: 
                   1048: void
                   1049: GetNextOffset (PDEBUGPACKET dp, PULONG pcaddr, BOOLEAN fStep)
                   1050: {
                   1051:     int     mode_32;
                   1052:     int     opsize_32;
                   1053:     int     cBytes;
                   1054:     char    membuf[MAXL];               //  current instruction buffer
                   1055:     ULONG   addrReturn;
                   1056:     USHORT  retAddr[3];                 //  return address buffer
                   1057:     char    *pMem;
                   1058:     UCHAR   opcode;
                   1059:     int     fPrefix = TRUE;
                   1060:     int     fRepPrefix = FALSE;
                   1061:     int     ttt;
                   1062:     int     rm;
                   1063:     ULONG   instroffset;
                   1064: 
                   1065:     //  read instruction stream bytes into membuf and set mode and
                   1066:     //      opcode size flags
                   1067: 
                   1068:     *pcaddr = GetRegValue(dp,REGEIP);
                   1069:     instroffset = *pcaddr;
                   1070:     G_mode_32 = TRUE;
                   1071:     mode_32 = opsize_32 = (G_mode_32 == 1); /* local addressing mode */
                   1072:     ReadProcessMemory( dp->hProcess,
                   1073:                        (LPVOID)*pcaddr,
                   1074:                        (LPVOID)membuf,
                   1075:                        MAXL,
                   1076:                        &cBytes
                   1077:                      );
                   1078:                                         /* move full inst to local buffer */
                   1079:     pMem = membuf;                      /* point to begin of instruction */
                   1080: 
                   1081:     //  read and process any prefixes first
                   1082: 
                   1083:     do {
                   1084:         opcode = (UCHAR)*pMem++;        /* get opcode */
                   1085:         if (opcode == 0x66)
                   1086:             opsize_32 = !G_mode_32;
                   1087:         else if (opcode == 0x67)
                   1088:             mode_32 = !G_mode_32;
                   1089:         else if ((opcode & ~1) == 0xf2)
                   1090:             fRepPrefix = TRUE;
                   1091:         else if (opcode != 0xf0 && (opcode & ~0x18) != 0x26
                   1092:                                 && (opcode & ~1) != 0x64)
                   1093:             fPrefix = FALSE;
                   1094:         }
                   1095:     while (fPrefix);
                   1096: 
                   1097:     //  for instructions that alter the TF (trace flag), return the
                   1098:     //      offset of the next instruction despite the flag of fStep
                   1099: 
                   1100:     if (((opcode & ~0x3) == 0x9c))
                   1101:         //  9c-9f, pushf, popf, sahf, lahf
                   1102:         ;
                   1103: 
                   1104:     else if (opcode == 0xcf) {          //  cf - iret - get RA from stack
                   1105: 
                   1106:         addrReturn = GetRegValue(dp, REGESP);
                   1107:         ReadProcessMemory( dp->hProcess,
                   1108:                            (LPVOID)addrReturn,
                   1109:                            (LPVOID)retAddr,
                   1110:                            sizeof(retAddr),
                   1111:                            NULL
                   1112:                          );
                   1113: 
                   1114:         *pcaddr = retAddr[2];
                   1115:         return;
                   1116:         }
                   1117: 
                   1118:     //  repeated string/port instructions
                   1119: 
                   1120:     if (opcode == 0xe8)            //  near direct jump
                   1121:         pMem += (1 + opsize_32) * 2;
                   1122: 
                   1123:     else if (opcode == 0x9a)            //  far direct jump
                   1124:         pMem += (2 + opsize_32) * 2;
                   1125: 
                   1126:     else if (opcode == 0xcd ||
                   1127:              (opcode >= 0xe0 && opcode <= 0xe2)) //  loop / int nn instrs
                   1128:         pMem++;
                   1129: 
                   1130:     else if (opcode == 0xff) {          //  indirect call - compute length
                   1131:         opcode = *pMem++;               //  get modRM
                   1132:         ttt = BIT53(opcode);
                   1133:         if ((ttt & ~1) == 2) {
                   1134:             mod = BIT76(opcode);
                   1135:             if (mod != 3) {                     //  nonregister operand
                   1136:                 rm = BIT20(opcode);
                   1137:                 if (mode_32) {
                   1138:                     if (rm == 4)
                   1139:                         rm = BIT20(*pMem++);    //  get base from SIB
                   1140:                     if (mod == 0) {
                   1141:                         if (rm == 5)
                   1142:                             pMem += 4;          //  long direct address
                   1143:                         }                       //  else register
                   1144:                     else if (mod == 1)
                   1145:                         pMem++;                 //  register with byte offset
                   1146:                     else
                   1147:                         pMem += 4;              //  register with long offset
                   1148:                     }
                   1149:                 else {                          //  16-bit mode
                   1150:                     if (mod == 0) {
                   1151:                         if (rm == 6)
                   1152:                             pMem += 2;          //  short direct address
                   1153:                         }
                   1154:                     else
                   1155:                         pMem += mod;            //  reg, byte, word offset
                   1156:                     }
                   1157:                 }
                   1158:             }
                   1159:         else
                   1160:             instroffset = (ULONG)-1;            //  0xff, but not call
                   1161:         }
                   1162: 
                   1163:     else if (!((fRepPrefix && ((opcode & ~3) == 0x6c ||
                   1164:                                (opcode & ~3) == 0xa4 ||
                   1165:                                (opcode & ~1) == 0xaa ||
                   1166:                                (opcode & ~3) == 0xac)) ||
                   1167:                                opcode == 0xcc || opcode == 0xce))
                   1168:         instroffset = (ULONG)-1;                //  not repeated string op
                   1169:                                                 //  or int 3 / into
                   1170: 
                   1171:     //  if not enough bytes were read for instruction parse,
                   1172:     //      just give up and trace the instruction
                   1173: 
                   1174:     if (cBytes < pMem - membuf)
                   1175:         instroffset = (ULONG)-1;
                   1176: 
                   1177:     //  if not tracing, compute the new instruction offset
                   1178: 
                   1179:     if (instroffset != (ULONG)-1)
                   1180:         instroffset += pMem - membuf;
                   1181: 
                   1182:     *pcaddr = instroffset;
                   1183: }
                   1184: 
                   1185: void
                   1186: OutputHexAddr (PUCHAR *ppBuffer, ULONG offset)
                   1187: {
                   1188:     OutputHexString(ppBuffer, (char *)&offset, sizeof(ULONG));
                   1189: }
                   1190: 
                   1191: USHORT
                   1192: GetSegRegValue (PDEBUGPACKET dp, int segOpcode)
                   1193: {
                   1194:     ULONG    regnum;
                   1195: 
                   1196:     switch (segOpcode) {
                   1197:         case 0x26:
                   1198:             regnum = REGES;
                   1199:             break;
                   1200:         case 0x2e:
                   1201:             regnum = REGCS;
                   1202:             break;
                   1203:         case 0x36:
                   1204:             regnum = REGSS;
                   1205:             break;
                   1206:         case 0x64:
                   1207:             regnum = REGFS;
                   1208:             break;
                   1209:         case 0x65:
                   1210:             regnum = REGGS;
                   1211:             break;
                   1212:         case 0x3e:
                   1213:         default:
                   1214:             regnum = REGDS;
                   1215:         }
                   1216: 
                   1217:     return (USHORT)GetRegValue(dp,regnum);
                   1218: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.