Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2472 lines
50 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. disasm.c
  5. Abstract:
  6. This file contains the x86 disassmbler invoked by "!bde.u <16:16 address>"
  7. Author:
  8. Barry Bond (BarryBo)
  9. Revision History:
  10. 09-May-1995 Barry Bond (BarryBo) Created
  11. 15-Jan-1996 Neil Sandlin (NeilSa) Merged with vdmexts
  12. 32 bit segments fixes
  13. --*/
  14. #include <precomp.h>
  15. #pragma hdrstop
  16. WORD gSelector = 0;
  17. ULONG gOffset = 0;
  18. int gMode = 0;
  19. VOID
  20. u(
  21. CMD_ARGLIST
  22. ) {
  23. VDMCONTEXT ThreadContext;
  24. WORD selector;
  25. ULONG offset;
  26. int mode;
  27. char rgchOutput[128];
  28. char rgchExtra[128];
  29. BYTE rgbInstruction[64];
  30. CHAR sym_text[255];
  31. CHAR sym_prev[255] = "";
  32. DWORD dist;
  33. int cb;
  34. int i;
  35. int j;
  36. int count=10;
  37. ULONG Base;
  38. SELECTORINFO si;
  39. ULONG BPNum;
  40. UCHAR BPData;
  41. BOOL bIsBP;
  42. CMD_INIT();
  43. mode = GetContext( &ThreadContext );
  44. if (!GetNextToken()) {
  45. if (!gSelector && !gOffset) {
  46. selector = (WORD) ThreadContext.SegCs;
  47. offset = ThreadContext.Eip;
  48. } else {
  49. mode = gMode;
  50. selector = gSelector;
  51. offset = gOffset;
  52. }
  53. } else if (!ParseIntelAddress(&mode, &selector, &offset)) {
  54. return;
  55. }
  56. if (GetNextToken()) {
  57. count = (int) EXPRESSION(lpArgumentString);
  58. if (count > 1000) {
  59. PRINTF("Count too large - ignored\n");
  60. count=10;
  61. }
  62. }
  63. if ( mode != PROT_MODE && mode != V86_MODE) {
  64. PRINTF(" Disassembly of flat mode code not allowed.\n");
  65. return;
  66. }
  67. LoadBreakPointCache();
  68. Base = GetInfoFromSelector( selector, mode, &si ) + GetIntelBase();
  69. for (i=0; i<count; ++i) {
  70. if (FindSymbol(selector, offset, sym_text, &dist, BEFORE, mode )) {
  71. if (_stricmp(sym_text, sym_prev)) {
  72. if ( dist == 0 ) {
  73. PRINTF("%s:\n", sym_text );
  74. } else {
  75. PRINTF("%s+0x%lx:\n", sym_text, dist );
  76. }
  77. strcpy(sym_prev, sym_text);
  78. }
  79. }
  80. cb = sizeof(rgbInstruction);
  81. if ((DWORD)(offset+cb) >= si.Limit)
  82. cb -= offset+cb-si.Limit;
  83. if (!READMEM((LPVOID)(Base+offset), rgbInstruction, cb)) {
  84. PRINTF("%04x:%08x: <Error Reading Memory>\n", selector, offset);
  85. return;
  86. }
  87. if (bIsBP = IsVdmBreakPoint(selector,
  88. offset,
  89. mode==PROT_MODE,
  90. &BPNum,
  91. &BPData)) {
  92. rgbInstruction[0] = BPData;
  93. }
  94. cb = unassemble_one(rgbInstruction,
  95. si.bBig,
  96. selector, offset,
  97. rgchOutput,
  98. rgchExtra,
  99. &ThreadContext,
  100. mode);
  101. gOffset += cb;
  102. if (offset > 0xffff) {
  103. PRINTF("%04x:%08x ", selector, offset);
  104. } else {
  105. PRINTF("%04x:%04x ", selector, offset);
  106. }
  107. for (j=0; j<cb; ++j)
  108. PRINTF("%02x", rgbInstruction[j]);
  109. for (; j<8; ++j)
  110. PRINTF(" ");
  111. PRINTF("%s\t%s", rgchOutput, rgchExtra);
  112. if (bIsBP) {
  113. PRINTF("; BP%d",BPNum);
  114. }
  115. PRINTF("\n");
  116. offset+=cb;
  117. }
  118. }
  119. typedef struct _ADDR {
  120. ULONG sOff;
  121. USHORT sSeg;
  122. } ADDR;
  123. LPBYTE checkprefixes(LPBYTE);
  124. void AppendPrefixes(void);
  125. void DisplayAddress(int mod, int rm, int sOff, int size);
  126. int DisplayBOP(void);
  127. #define modrmB 1
  128. #define modrmW 2
  129. #define reg1B 3
  130. #define reg1W 4
  131. #define reg2B 5
  132. #define reg2W 6
  133. #define eeeControl 7
  134. #define eeeDebug 8
  135. #define eeeTest 9
  136. #define regSeg 10
  137. #define ALreg 11
  138. #define AHreg 12
  139. #define BLreg 13
  140. #define BHreg 14
  141. #define CLreg 15
  142. #define CHreg 16
  143. #define DLreg 17
  144. #define DHreg 18
  145. #define AXreg 19
  146. #define BXreg 20
  147. #define CXreg 21
  148. #define DXreg 22
  149. #define SIreg 23
  150. #define DIreg 24
  151. #define SPreg 25
  152. #define BPreg 26
  153. #define CSreg 27
  154. #define SSreg 28
  155. #define DSreg 29
  156. #define ESreg 30
  157. #define FSreg 31
  158. #define GSreg 32
  159. #define ImmB 33
  160. #define ImmBEnter 34
  161. #define ImmBS 35
  162. #define ImmW 36
  163. #define ImmW1 37
  164. #define jmpB 38
  165. #define jmpW 39
  166. #define memB 40
  167. #define memW 41
  168. #define memD 42
  169. #define indirmodrmW 43
  170. #define indirFARmodrmW 44
  171. #define memB1 45
  172. int DmodrmB(LPBYTE);
  173. int DmodrmW(LPBYTE);
  174. int Dreg1B(LPBYTE);
  175. int Dreg1W(LPBYTE);
  176. int Dreg2B(LPBYTE);
  177. int Dreg2W(LPBYTE);
  178. int DeeeControl(LPBYTE);
  179. int DeeeDebug(LPBYTE);
  180. int DeeeTest(LPBYTE);
  181. int DregSeg(LPBYTE);
  182. int DALreg(LPBYTE);
  183. int DAHreg(LPBYTE);
  184. int DBLreg(LPBYTE);
  185. int DBHreg(LPBYTE);
  186. int DCLreg(LPBYTE);
  187. int DCHreg(LPBYTE);
  188. int DDLreg(LPBYTE);
  189. int DDHreg(LPBYTE);
  190. int DAXreg(LPBYTE);
  191. int DBXreg(LPBYTE);
  192. int DCXreg(LPBYTE);
  193. int DDXreg(LPBYTE);
  194. int DSIreg(LPBYTE);
  195. int DDIreg(LPBYTE);
  196. int DSPreg(LPBYTE);
  197. int DBPreg(LPBYTE);
  198. int DCSreg(LPBYTE);
  199. int DSSreg(LPBYTE);
  200. int DDSreg(LPBYTE);
  201. int DESreg(LPBYTE);
  202. int DFSreg(LPBYTE);
  203. int DGSreg(LPBYTE);
  204. int DImmB(LPBYTE);
  205. int DImmBEnter(LPBYTE);
  206. int DImmBS(LPBYTE);
  207. int DImmW(LPBYTE);
  208. int DImmW1(LPBYTE); // immediate-16 for 1-byte instructions
  209. int DjmpB(LPBYTE);
  210. int DjmpW(LPBYTE);
  211. int DmemB(LPBYTE);
  212. int DmemB1(LPBYTE);
  213. int DmemW(LPBYTE);
  214. int DmemD(LPBYTE);
  215. int DindirmodrmW(LPBYTE);
  216. int DindirFARmodrmW(LPBYTE);
  217. struct {
  218. int (*pfn)(LPBYTE);
  219. } rgpfn[] = {
  220. 0, // 0th entry is reserved
  221. DmodrmB,
  222. DmodrmW,
  223. Dreg1B,
  224. Dreg1W,
  225. Dreg2B,
  226. Dreg2W,
  227. DeeeControl,
  228. DeeeDebug,
  229. DeeeTest,
  230. DregSeg,
  231. DALreg,
  232. DAHreg,
  233. DBLreg,
  234. DBHreg,
  235. DCLreg,
  236. DCHreg,
  237. DDLreg,
  238. DDHreg,
  239. DAXreg,
  240. DBXreg,
  241. DCXreg,
  242. DDXreg,
  243. DSIreg,
  244. DDIreg,
  245. DSPreg,
  246. DBPreg,
  247. DCSreg,
  248. DSSreg,
  249. DDSreg,
  250. DESreg,
  251. DFSreg,
  252. DGSreg,
  253. DImmB,
  254. DImmBEnter,
  255. DImmBS,
  256. DImmW,
  257. DImmW1, // immediate-16 for 1-byte instructions
  258. DjmpB,
  259. DjmpW,
  260. DmemB,
  261. DmemW,
  262. DmemD,
  263. DindirmodrmW,
  264. DindirFARmodrmW,
  265. DmemB1
  266. };
  267. VDMCONTEXT *g_pThreadContext;
  268. int g_mode;
  269. char *g_pchOutput; // the disassembled instruction
  270. char *g_pchExtra; // contents of memory (if any) modified by this instr.
  271. int prefixes;
  272. //NOTE: if first byte = 0x0f, then the instruction is two bytes long
  273. char *szRegsB[] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"};
  274. char *szRegsW[] = {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"};
  275. char *szRegsD[] = {"eax","ecx","edx","ebx","esp","ebp","esi","edi"};
  276. char *szRegsSeg[] = {"es", "cs", "ss", "ds", "fs", "gs", "(bad)", "(bad)"};
  277. char *szMod[] = {"[bx+si", "[bx+di", "[bp+si", "[bp+di", "[si", "[di", "[bp", "[bx"};
  278. #define PREFIX_REPZ 1
  279. #define PREFIX_REPNZ 2
  280. #define PREFIX_LOCK 4
  281. #define PREFIX_CS 8
  282. #define PREFIX_SS 0x10
  283. #define PREFIX_DS 0x20
  284. #define PREFIX_ES 0x40
  285. #define PREFIX_FS 0x80
  286. #define PREFIX_GS 0x100
  287. #define PREFIX_DATA 0x200
  288. #define PREFIX_ADR 0x400
  289. #define PREFIX_FWAIT 0x800
  290. #define GROUP_1B -1
  291. #define GROUP_1WS -2
  292. #define GROUP_1W -3
  293. #define GROUP_2B -4
  294. #define GROUP_2W -5
  295. #define GROUP_2B_1 -6
  296. #define GROUP_2W_1 -7
  297. #define GROUP_2B_CL -8
  298. #define GROUP_2W_CL -9
  299. #define GROUP_3B -10
  300. #define GROUP_3W -11
  301. #define GROUP_4 -12
  302. #define GROUP_5 -13
  303. #define GROUP_6 -14
  304. #define GROUP_7 -15
  305. #define GROUP_8 -16
  306. #define FLOATCODE -51
  307. #define FLOAT FLOATCODE
  308. // WARNING: This list must remain in sync with the szInstructions[] array
  309. #define szAdc 1
  310. #define szAdd 2
  311. #define szAnd 3
  312. #define szBad 4
  313. #define szCmp 5
  314. #define szDec 6
  315. #define szIn 7
  316. #define szInc 8
  317. #define szJmp 9
  318. #define szMov 10
  319. #define szOr 11
  320. #define szOut 12
  321. #define szRcl 13
  322. #define szRcr 14
  323. #define szRol 15
  324. #define szRor 16
  325. #define szSar 17
  326. #define szSbb 18
  327. #define szShl 19
  328. #define szShr 20
  329. #define szSub 21
  330. #define szTest 22
  331. #define szPop 23
  332. #define szPush 24
  333. #define szXchg 25
  334. #define szXor 26
  335. #define szDaa 27
  336. #define szDas 28
  337. #define szPusha 29
  338. #define szPopa 30
  339. #define szBound 31
  340. #define szArpl 32
  341. #define szAaa 33
  342. #define szAas 34
  343. #define szImul 35
  344. #define szIdiv 36
  345. #define szJo 37
  346. #define szJno 38
  347. #define szJb 39
  348. #define szJae 40
  349. #define szJe 41
  350. #define szJne 42
  351. #define szJbe 43
  352. #define szJa 44
  353. #define szJs 45
  354. #define szJns 46
  355. #define szJp 47
  356. #define szJnp 48
  357. #define szJl 49
  358. #define szJnl 50
  359. #define szJle 51
  360. #define szJg 52
  361. #define szNop 53
  362. #define szLea 54
  363. #define szCbw 55
  364. #define szCwd 56
  365. #define szCall 57
  366. #define szPushf 58
  367. #define szPopf 59
  368. #define szSahf 60
  369. #define szLahf 61
  370. #define szMovsb 62
  371. #define szMovsw 63
  372. #define szCmpsb 64
  373. #define szCmpsw 65
  374. #define szStosb 66
  375. #define szStosw 67
  376. #define szLodsb 68
  377. #define szLodsw 69
  378. #define szScasb 70
  379. #define szScasw 71
  380. #define szRetn 72
  381. #define szLes 73
  382. #define szLds 74
  383. #define szEnter 75
  384. #define szLeave 76
  385. #define szRetf 77
  386. #define szInt3 78
  387. #define szInt 79
  388. #define szInto 80
  389. #define szIret 81
  390. #define szAam 82
  391. #define szAad 83
  392. #define szXlat 84
  393. #define szLoopne 85
  394. #define szLoope 86
  395. #define szLoop 87
  396. #define szJcxz 88
  397. #define szHalt 89
  398. #define szCmc 90
  399. #define szClc 91
  400. #define szStc 92
  401. #define szCli 93
  402. #define szSti 94
  403. #define szCld 95
  404. #define szStd 96
  405. #define szLar 97
  406. #define szLsl 98
  407. #define szClts 99
  408. #define szSeto 100
  409. #define szSetno 101
  410. #define szSetb 102
  411. #define szSetae 103
  412. #define szSete 104
  413. #define szSetne 105
  414. #define szSetbe 106
  415. #define szSeta 107
  416. #define szSets 108
  417. #define szSetns 109
  418. #define szSetp 110
  419. #define szSetnp 111
  420. #define szSetl 112
  421. #define szSetge 113
  422. #define szSetle 114
  423. #define szSetg 115
  424. #define szBt 116
  425. #define szShld 117
  426. #define szBts 118
  427. #define szShrd 119
  428. #define szShdr 120
  429. #define szLss 121
  430. #define szBtr 122
  431. #define szLfs 123
  432. #define szLgs 124
  433. #define szMovzx 125
  434. #define szBtc 126
  435. #define szBsf 127
  436. #define szBsr 128
  437. #define szMovsx 129
  438. #define szNot 130
  439. #define szNeg 131
  440. #define szMul 132
  441. #define szDiv 133
  442. #define szSldt 134
  443. #define szStr 135
  444. #define szLldt 136
  445. #define szLtr 137
  446. #define szVerr 138
  447. #define szVerw 139
  448. #define szSgdt 140
  449. #define szSidt 141
  450. #define szLgdt 142
  451. #define szLidt 143
  452. #define szSmsw 144
  453. #define szLmsw 145
  454. // WARNING: This must stay in sync with the #define list above
  455. char *szInstructions[] = {
  456. "", //used to indicate groups
  457. "adc",
  458. "add",
  459. "and",
  460. "(bad)",
  461. "cmp",
  462. "dec",
  463. "in",
  464. "inc",
  465. "jmp",
  466. // 10
  467. "mov",
  468. "or",
  469. "out",
  470. "rcl",
  471. "rcr",
  472. "rol",
  473. "ror",
  474. "sar",
  475. "sbb",
  476. "shl",
  477. // 20
  478. "shr",
  479. "sub",
  480. "test",
  481. "pop",
  482. "push",
  483. "xchg",
  484. "xor",
  485. "daa",
  486. "das",
  487. "pusha",
  488. // 30
  489. "popa",
  490. "bound",
  491. "arpl",
  492. "aaa",
  493. "aas",
  494. "imul",
  495. "idiv",
  496. "jo",
  497. "jno",
  498. "jb",
  499. // 40
  500. "jae",
  501. "je",
  502. "jne",
  503. "jbe",
  504. "ja",
  505. "js",
  506. "jns",
  507. "jp",
  508. "jnp",
  509. "jl",
  510. // 50
  511. "jnl",
  512. "jle",
  513. "jg",
  514. "nop",
  515. "lea",
  516. "cbw",
  517. "cwd",
  518. "call",
  519. "pushf",
  520. "popf",
  521. // 60
  522. "sahf",
  523. "lahf",
  524. "movsb",
  525. "movsw",
  526. "cmpsb",
  527. "cmpsw",
  528. "stosb",
  529. "stosw",
  530. "lodsb",
  531. "lodsw",
  532. // 70
  533. "scasb",
  534. "scasw",
  535. "retn",
  536. "les",
  537. "lds",
  538. "enter",
  539. "leave",
  540. "retf",
  541. "int3",
  542. "int",
  543. // 80
  544. "into",
  545. "iret",
  546. "aam",
  547. "aad",
  548. "xlat",
  549. "loopne",
  550. "loope",
  551. "loop",
  552. "jcxz",
  553. "halt",
  554. // 90
  555. "cmc",
  556. "clc",
  557. "stc",
  558. "cli",
  559. "sti",
  560. "cld",
  561. "std",
  562. "lar",
  563. "lsl",
  564. "clts",
  565. // 100
  566. "seto",
  567. "setno",
  568. "setb",
  569. "setae",
  570. "sete",
  571. "setne",
  572. "setbe",
  573. "seta",
  574. "sets",
  575. "setns",
  576. // 110
  577. "setp",
  578. "setnp",
  579. "setl",
  580. "setge",
  581. "setle",
  582. "setg",
  583. "bt",
  584. "shld",
  585. "bts",
  586. "shrd",
  587. // 120
  588. "shdr",
  589. "lss",
  590. "btr",
  591. "lfs",
  592. "lgs",
  593. "movzx",
  594. "btc",
  595. "bsf",
  596. "bsr",
  597. "movsx",
  598. // 130
  599. "not",
  600. "neg",
  601. "mul",
  602. "div",
  603. "sldt",
  604. "str",
  605. "lldt",
  606. "ltr",
  607. "verr",
  608. "verw",
  609. // 140
  610. "sgdt",
  611. "sidt",
  612. "lgdt",
  613. "lidt",
  614. "smsw",
  615. "lmsw"
  616. };
  617. struct dis {
  618. int szName;
  619. char iPart1;
  620. char iPart2;
  621. char iPart3;
  622. };
  623. struct dis dis386[] = {
  624. // 0
  625. { szAdd, modrmB, reg1B },
  626. { szAdd, modrmW, reg1W },
  627. { szAdd, reg1B, modrmB },
  628. { szAdd, reg1W, modrmW },
  629. { szAdd, ALreg, ImmB },
  630. { szAdd, AXreg, ImmW },
  631. { szPush, ESreg },
  632. { szPop, ESreg},
  633. // 8
  634. { szOr, modrmB, reg1B },
  635. { szOr, modrmW, reg1W },
  636. { szOr, reg1B, modrmB },
  637. { szOr, reg1W, modrmW },
  638. { szOr, ALreg, ImmB },
  639. { szOr, AXreg, ImmW },
  640. { szPush, CSreg },
  641. { szBad }, // 0x0f is the 2-byte instr prefix
  642. // 10
  643. { szAdc, modrmB, reg1B },
  644. { szAdc, modrmW, reg1W },
  645. { szAdc, reg1B, modrmB },
  646. { szAdc, reg1W, modrmW },
  647. { szAdc, ALreg, ImmB },
  648. { szAdc, AXreg, ImmW },
  649. { szPush, SSreg },
  650. { szPop, SSreg },
  651. // 18
  652. { szSbb, modrmB, reg1B },
  653. { szSbb, modrmW, reg1W },
  654. { szSbb, reg1B, modrmB },
  655. { szSbb, reg1W, modrmW },
  656. { szSbb, ALreg, ImmB },
  657. { szSbb, AXreg, ImmW },
  658. { szPush, DSreg },
  659. { szPop, DSreg },
  660. // 20
  661. { szAnd, modrmB, reg1B },
  662. { szAnd, modrmW, reg1W },
  663. { szAnd, reg1B, modrmB },
  664. { szAnd, reg1W, modrmW },
  665. { szAnd, ALreg, ImmB },
  666. { szAnd, AXreg, ImmW },
  667. { szBad }, // ES override prefix
  668. { szDaa },
  669. // 28
  670. { szSub, modrmB, reg1B },
  671. { szSub, modrmW, reg1W },
  672. { szSub, reg1B, modrmB },
  673. { szSub, reg1W, modrmW },
  674. { szSub, ALreg, ImmB },
  675. { szSub, AXreg, ImmW },
  676. { szBad }, // CS override prefix
  677. { szDas },
  678. // 30
  679. { szXor, modrmB, reg1B },
  680. { szXor, modrmW, reg1W },
  681. { szXor, reg1B, modrmB },
  682. { szXor, reg1W, modrmW },
  683. { szXor, ALreg, ImmB },
  684. { szXor, AXreg, ImmW },
  685. { szBad}, // SS override prefix
  686. { szAaa },
  687. // 38
  688. { szCmp, modrmB, reg1B },
  689. { szCmp, modrmW, reg1W },
  690. { szCmp, reg1B, modrmB },
  691. { szCmp, reg1W, modrmW },
  692. { szCmp, ALreg, ImmB },
  693. { szCmp, AXreg, ImmW },
  694. { szBad },
  695. { szAas },
  696. // 40
  697. { szInc, AXreg },
  698. { szInc, CXreg },
  699. { szInc, DXreg },
  700. { szInc, BXreg },
  701. { szInc, SPreg },
  702. { szInc, BPreg },
  703. { szInc, SIreg },
  704. { szInc, DIreg },
  705. // 48
  706. { szDec, AXreg },
  707. { szDec, CXreg },
  708. { szDec, DXreg },
  709. { szDec, BXreg },
  710. { szDec, SPreg },
  711. { szDec, BPreg },
  712. { szDec, SIreg },
  713. { szDec, DIreg },
  714. // 50
  715. { szPush, AXreg },
  716. { szPush, CXreg },
  717. { szPush, DXreg },
  718. { szPush, BXreg },
  719. { szPush, SPreg },
  720. { szPush, BPreg },
  721. { szPush, SIreg },
  722. { szPush, DIreg },
  723. // 58
  724. { szPop, AXreg },
  725. { szPop, CXreg },
  726. { szPop, DXreg },
  727. { szPop, BXreg },
  728. { szPop, SPreg },
  729. { szPop, BPreg },
  730. { szPop, SIreg },
  731. { szPop, DIreg },
  732. // 60
  733. { szPusha },
  734. { szPopa },
  735. { szBound, reg1W, modrmW },
  736. { szArpl, reg1W, reg2W },
  737. { szBad }, // FS segment override
  738. { szBad }, // GS segment override
  739. { szBad }, // op size prefix
  740. { szBad }, // addr size prefix
  741. // 68
  742. { szPush, ImmW},
  743. { szImul, reg1W, modrmW },
  744. { szPush, ImmBS},
  745. { szImul, reg1B, modrmB },
  746. { szIn, ImmB, DXreg },
  747. { szIn, ImmW, DXreg },
  748. { szOut, ImmB, DXreg },
  749. { szOut, ImmW, DXreg },
  750. // 70
  751. { szJo, jmpB },
  752. { szJno, jmpB },
  753. { szJb, jmpB },
  754. { szJae, jmpB },
  755. { szJe, jmpB },
  756. { szJne, jmpB },
  757. { szJbe, jmpB },
  758. { szJa, jmpB },
  759. // 78
  760. { szJs, jmpB },
  761. { szJns, jmpB },
  762. { szJp, jmpB },
  763. { szJnp, jmpB },
  764. { szJl, jmpB },
  765. { szJnl, jmpB },
  766. { szJle, jmpB },
  767. { szJg, jmpB },
  768. // 80
  769. { GROUP_1B },
  770. { GROUP_1W },
  771. { szBad },
  772. { GROUP_1WS },
  773. { szTest, reg1B, modrmB },
  774. { szTest, reg1W, modrmW },
  775. { szXchg, reg1B, modrmB },
  776. { szXchg, reg1W, modrmW },
  777. // 88
  778. { szMov, modrmB, reg1B },
  779. { szMov, modrmW, reg1W },
  780. { szMov, reg1B, modrmB },
  781. { szMov, reg1W, modrmW },
  782. { szMov, modrmW, regSeg },
  783. { szLea, reg1W, modrmW },
  784. { szMov, regSeg, modrmW },
  785. { szPop, modrmW },
  786. // 90
  787. { szNop },
  788. { szXchg, AXreg, CXreg },
  789. { szXchg, AXreg, DXreg },
  790. { szXchg, AXreg, BXreg },
  791. { szXchg, AXreg, SPreg },
  792. { szXchg, AXreg, BPreg },
  793. { szXchg, AXreg, SIreg },
  794. { szXchg, AXreg, DIreg },
  795. // 98
  796. { szCbw },
  797. { szCwd },
  798. { szCall, memD },
  799. { szBad },
  800. { szPushf },
  801. { szPopf },
  802. { szSahf },
  803. { szLahf },
  804. // a0
  805. { szMov, ALreg, memB },
  806. { szMov, AXreg, memW },
  807. { szMov, memB, ALreg },
  808. { szMov, memW, AXreg },
  809. { szMovsb },
  810. { szMovsw },
  811. { szCmpsb },
  812. { szCmpsw },
  813. // a8
  814. { szTest, ALreg, ImmB },
  815. { szTest, AXreg, ImmW },
  816. { szStosb },
  817. { szStosw },
  818. { szLodsb },
  819. { szLodsw },
  820. { szScasb },
  821. { szScasw },
  822. // b0
  823. { szMov, ALreg, ImmB },
  824. { szMov, CLreg, ImmB },
  825. { szMov, DLreg, ImmB },
  826. { szMov, BLreg, ImmB },
  827. { szMov, AHreg, ImmB },
  828. { szMov, CHreg, ImmB },
  829. { szMov, DHreg, ImmB },
  830. { szMov, BHreg, ImmB },
  831. // b8
  832. { szMov, AXreg, ImmW },
  833. { szMov, CXreg, ImmW },
  834. { szMov, DXreg, ImmW },
  835. { szMov, BXreg, ImmW },
  836. { szMov, SPreg, ImmW },
  837. { szMov, BPreg, ImmW },
  838. { szMov, SIreg, ImmW },
  839. { szMov, DIreg, ImmW },
  840. // c0
  841. { GROUP_2B },
  842. { GROUP_2W },
  843. { szRetn, ImmW },
  844. { szRetn },
  845. { szLes, reg1W, modrmW },
  846. { szLds, reg1W, modrmW },
  847. { szMov, modrmB, ImmB },
  848. { szMov, modrmW, ImmW },
  849. // c8
  850. { szEnter, ImmW, ImmBEnter },
  851. { szLeave },
  852. { szRetf, ImmW1 },
  853. { szRetf },
  854. { szInt3 },
  855. { szInt, ImmB },
  856. { szInto },
  857. { szIret },
  858. // d0
  859. { GROUP_2B_1 },
  860. { GROUP_2W_1 },
  861. { GROUP_2B_CL },
  862. { GROUP_2W_CL },
  863. { szAam, ImmB },
  864. { szAad, ImmB },
  865. { szBad },
  866. { szXlat },
  867. // d8
  868. { FLOAT },
  869. { FLOAT },
  870. { FLOAT },
  871. { FLOAT },
  872. { FLOAT },
  873. { FLOAT },
  874. { FLOAT },
  875. { FLOAT },
  876. // e0
  877. { szLoopne, jmpB },
  878. { szLoope, jmpB },
  879. { szLoop, jmpB },
  880. { szJcxz, jmpB },
  881. { szIn, ALreg, memB1 },
  882. { szIn, AXreg, memB1 },
  883. { szOut, memB1, ALreg },
  884. { szOut, memB1, AXreg },
  885. // e8
  886. { szCall, jmpW },
  887. { szJmp, jmpW },
  888. { szJmp, memD },
  889. { szJmp, jmpB },
  890. { szIn, ALreg, DXreg },
  891. { szIn, AXreg, DXreg },
  892. { szOut, DXreg, ALreg },
  893. { szOut, DXreg, AXreg },
  894. // f0
  895. { szBad }, // lock prefix
  896. { szBad },
  897. { szBad }, // repne prefix
  898. { szBad }, // repz prefix
  899. { szHalt },
  900. { szCmc },
  901. { GROUP_3B },
  902. { GROUP_3W },
  903. // f8
  904. { szClc },
  905. { szStc },
  906. { szCli },
  907. { szSti },
  908. { szCld },
  909. { szStd },
  910. { GROUP_4 },
  911. { GROUP_5 },
  912. };
  913. struct dis dis386_2[] = {
  914. // 00
  915. { GROUP_6 },
  916. { GROUP_7 },
  917. { szLar, reg1W, modrmW },
  918. { szLsl, reg1W, modrmW },
  919. { szBad },
  920. { szBad },
  921. { szClts },
  922. { szBad },
  923. // 08
  924. { szBad },
  925. { szBad },
  926. { szBad },
  927. { szBad },
  928. { szBad },
  929. { szBad },
  930. { szBad },
  931. { szBad },
  932. // 10
  933. { szBad },
  934. { szBad },
  935. { szBad },
  936. { szBad },
  937. { szBad },
  938. { szBad },
  939. { szBad },
  940. { szBad },
  941. // 18
  942. { szBad },
  943. { szBad },
  944. { szBad },
  945. { szBad },
  946. { szBad },
  947. { szBad },
  948. { szBad },
  949. { szBad },
  950. // 20
  951. { szMov, reg2W, eeeControl },
  952. { szMov, reg2W, eeeDebug },
  953. { szMov, eeeControl, reg2W },
  954. { szMov, eeeDebug, reg2W },
  955. { szMov, reg2W, eeeTest },
  956. { szBad },
  957. { szMov, eeeTest, reg2W },
  958. { szBad },
  959. // 28
  960. { szBad },
  961. { szBad },
  962. { szBad },
  963. { szBad },
  964. { szBad },
  965. { szBad },
  966. { szBad },
  967. { szBad },
  968. // 30
  969. { szBad },
  970. { szBad },
  971. { szBad },
  972. { szBad },
  973. { szBad },
  974. { szBad },
  975. { szBad },
  976. { szBad },
  977. // 38
  978. { szBad },
  979. { szBad },
  980. { szBad },
  981. { szBad },
  982. { szBad },
  983. { szBad },
  984. { szBad },
  985. { szBad },
  986. // 40
  987. { szBad },
  988. { szBad },
  989. { szBad },
  990. { szBad },
  991. { szBad },
  992. { szBad },
  993. { szBad },
  994. { szBad },
  995. // 48
  996. { szBad },
  997. { szBad },
  998. { szBad },
  999. { szBad },
  1000. { szBad },
  1001. { szBad },
  1002. { szBad },
  1003. { szBad },
  1004. // 50
  1005. { szBad },
  1006. { szBad },
  1007. { szBad },
  1008. { szBad },
  1009. { szBad },
  1010. { szBad },
  1011. { szBad },
  1012. { szBad },
  1013. // 58
  1014. { szBad },
  1015. { szBad },
  1016. { szBad },
  1017. { szBad },
  1018. { szBad },
  1019. { szBad },
  1020. { szBad },
  1021. { szBad },
  1022. // 60
  1023. { szBad },
  1024. { szBad },
  1025. { szBad },
  1026. { szBad },
  1027. { szBad },
  1028. { szBad },
  1029. { szBad },
  1030. { szBad },
  1031. // 68
  1032. { szBad },
  1033. { szBad },
  1034. { szBad },
  1035. { szBad },
  1036. { szBad },
  1037. { szBad },
  1038. { szBad },
  1039. { szBad },
  1040. // 70
  1041. { szBad },
  1042. { szBad },
  1043. { szBad },
  1044. { szBad },
  1045. { szBad },
  1046. { szBad },
  1047. { szBad },
  1048. { szBad },
  1049. // 78
  1050. { szBad },
  1051. { szBad },
  1052. { szBad },
  1053. { szBad },
  1054. { szBad },
  1055. { szBad },
  1056. { szBad },
  1057. { szBad },
  1058. // 80
  1059. { szJo, jmpW },
  1060. { szJno, jmpW },
  1061. { szJb, jmpW },
  1062. { szJae, jmpW },
  1063. { szJe, jmpW },
  1064. { szJne, jmpW },
  1065. { szJbe, jmpW },
  1066. { szJa, jmpW },
  1067. // 88
  1068. { szJs, jmpW },
  1069. { szJns, jmpW },
  1070. { szJp, jmpW },
  1071. { szJnp, jmpW },
  1072. { szJl, jmpW },
  1073. { szJnl, jmpW },
  1074. { szJle, jmpW },
  1075. { szJg, jmpW },
  1076. // 90
  1077. { szSeto, modrmB },
  1078. { szSetno, modrmB },
  1079. { szSetb, modrmB },
  1080. { szSetae, modrmB },
  1081. { szSete, modrmB },
  1082. { szSetne, modrmB },
  1083. { szSetbe, modrmB },
  1084. { szSeta, modrmB },
  1085. // 98
  1086. { szSets, modrmB },
  1087. { szSetns, modrmB },
  1088. { szSetp, modrmB },
  1089. { szSetnp, modrmB },
  1090. { szSetl, modrmB },
  1091. { szSetge, modrmB },
  1092. { szSetle, modrmB },
  1093. { szSetg, modrmB },
  1094. // a0
  1095. { szPush, FSreg },
  1096. { szPop, FSreg },
  1097. { szBad },
  1098. { szBt, modrmW, reg1W },
  1099. { szShld, reg1W, modrmW, ImmB },
  1100. { szShld, reg1W, modrmW, CLreg },
  1101. { szBad },
  1102. { szBad },
  1103. // a8
  1104. { szPush, GSreg },
  1105. { szPop, GSreg },
  1106. { szBad },
  1107. { szBts, modrmW, reg1W },
  1108. { szShrd, reg1W, modrmW, ImmB },
  1109. { szShdr, reg1W, modrmW, CLreg },
  1110. { szBad },
  1111. { szImul, reg1W, modrmW },
  1112. // b0
  1113. { szBad },
  1114. { szBad },
  1115. { szLss, reg1W, modrmW },
  1116. { szBtr, modrmW, reg1W },
  1117. { szLfs, reg1W, modrmW },
  1118. { szLgs, reg1W, modrmW },
  1119. { szMovzx, reg1B, modrmB },
  1120. { szMovzx, reg1W, modrmW },
  1121. // b8
  1122. { szBad },
  1123. { szBad },
  1124. { GROUP_8 },
  1125. { szBtc, modrmW, reg1W },
  1126. { szBsf, reg1W, modrmW },
  1127. { szBsr, reg1W, modrmW },
  1128. { szMovsx, reg1B, modrmB },
  1129. { szMovsx, reg1W, modrmW },
  1130. // c0
  1131. { szBad },
  1132. { szBad },
  1133. { szBad },
  1134. { szBad },
  1135. { szBad },
  1136. { szBad },
  1137. { szBad },
  1138. { szBad },
  1139. // c8
  1140. { szBad },
  1141. { szBad },
  1142. { szBad },
  1143. { szBad },
  1144. { szBad },
  1145. { szBad },
  1146. { szBad },
  1147. { szBad },
  1148. // d0
  1149. { szBad },
  1150. { szBad },
  1151. { szBad },
  1152. { szBad },
  1153. { szBad },
  1154. { szBad },
  1155. { szBad },
  1156. { szBad },
  1157. // d8
  1158. { szBad },
  1159. { szBad },
  1160. { szBad },
  1161. { szBad },
  1162. { szBad },
  1163. { szBad },
  1164. { szBad },
  1165. { szBad },
  1166. // e0
  1167. { szBad },
  1168. { szBad },
  1169. { szBad },
  1170. { szBad },
  1171. { szBad },
  1172. { szBad },
  1173. { szBad },
  1174. { szBad },
  1175. // e8
  1176. { szBad },
  1177. { szBad },
  1178. { szBad },
  1179. { szBad },
  1180. { szBad },
  1181. { szBad },
  1182. { szBad },
  1183. { szBad },
  1184. // f0
  1185. { szBad },
  1186. { szBad },
  1187. { szBad },
  1188. { szBad },
  1189. { szBad },
  1190. { szBad },
  1191. { szBad },
  1192. { szBad },
  1193. // f8
  1194. { szBad },
  1195. { szBad },
  1196. { szBad },
  1197. { szBad },
  1198. { szBad },
  1199. { szBad },
  1200. { szBad },
  1201. { szBad },
  1202. };
  1203. struct dis dis386_groups[][8] = {
  1204. // GROUP_1B
  1205. {
  1206. { szAdd, modrmB, ImmB },
  1207. { szOr, modrmB, ImmB },
  1208. { szAdc, modrmB, ImmB },
  1209. { szSbb, modrmB, ImmB },
  1210. { szAnd, modrmB, ImmB },
  1211. { szSub, modrmB, ImmB },
  1212. { szXor, modrmB, ImmB },
  1213. { szCmp, modrmB, ImmB }
  1214. },
  1215. // GROUP_1WS
  1216. {
  1217. { szAdd, modrmW, ImmBS },
  1218. { szOr, modrmW, ImmBS },
  1219. { szAdc, modrmW, ImmBS },
  1220. { szSbb, modrmW, ImmBS },
  1221. { szAnd, modrmW, ImmBS },
  1222. { szSub, modrmW, ImmBS },
  1223. { szXor, modrmW, ImmBS },
  1224. { szCmp, modrmW, ImmBS }
  1225. },
  1226. // GROUP_1W
  1227. {
  1228. { szAdd, modrmW, ImmW },
  1229. { szOr, modrmW, ImmW },
  1230. { szAdc, modrmW, ImmW },
  1231. { szSbb, modrmW, ImmW },
  1232. { szAnd, modrmW, ImmW },
  1233. { szSub, modrmW, ImmW },
  1234. { szXor, modrmW, ImmW },
  1235. { szCmp, modrmW, ImmW }
  1236. },
  1237. // GROUP_2B
  1238. {
  1239. { szRol, modrmB, ImmB },
  1240. { szRor, modrmB, ImmB },
  1241. { szRcl, modrmB, ImmB },
  1242. { szRcr, modrmB, ImmB },
  1243. { szShl, modrmB, ImmB },
  1244. { szShr, modrmB, ImmB },
  1245. { szBad },
  1246. { szSar, modrmB, ImmB }
  1247. },
  1248. // GROUP_2W
  1249. {
  1250. { szRol, modrmW, ImmB },
  1251. { szRor, modrmW, ImmB },
  1252. { szRcl, modrmW, ImmB },
  1253. { szRcr, modrmW, ImmB },
  1254. { szShl, modrmW, ImmB },
  1255. { szShr, modrmW, ImmB },
  1256. { szBad },
  1257. { szSar, modrmW, ImmB }
  1258. },
  1259. // GROUP_2B_1
  1260. {
  1261. { szRol, modrmB },
  1262. { szRor, modrmB },
  1263. { szRcl, modrmB },
  1264. { szRcr, modrmB },
  1265. { szShl, modrmB },
  1266. { szShr, modrmB },
  1267. { szBad },
  1268. { szSar, modrmB }
  1269. },
  1270. // GROUP_2W_1
  1271. {
  1272. { szRol, modrmW },
  1273. { szRor, modrmW },
  1274. { szRcl, modrmW },
  1275. { szRcr, modrmW },
  1276. { szShl, modrmW },
  1277. { szShr, modrmW },
  1278. { szBad },
  1279. { szSar, modrmW }
  1280. },
  1281. // GROUP_2B_CL
  1282. {
  1283. { szRol, modrmB, CLreg },
  1284. { szRor, modrmB, CLreg },
  1285. { szRcl, modrmB, CLreg },
  1286. { szRcr, modrmB, CLreg },
  1287. { szShl, modrmB, CLreg },
  1288. { szShr, modrmB, CLreg },
  1289. { szBad },
  1290. { szSar, modrmB, CLreg }
  1291. },
  1292. // GROUP_2W_CL
  1293. {
  1294. { szRol, modrmW, CLreg },
  1295. { szRor, modrmW, CLreg },
  1296. { szRcl, modrmW, CLreg },
  1297. { szRcr, modrmW, CLreg },
  1298. { szShl, modrmW, CLreg },
  1299. { szShr, modrmW, CLreg },
  1300. { szBad },
  1301. { szSar, modrmW, CLreg }
  1302. },
  1303. // GROUP_3B
  1304. {
  1305. { szTest, modrmB, ImmB },
  1306. { szBad },
  1307. { szNot, modrmB },
  1308. { szNeg, modrmB },
  1309. { szMul, ALreg, modrmB },
  1310. { szImul, ALreg, modrmB },
  1311. { szDiv, ALreg, modrmB },
  1312. { szIdiv, ALreg, modrmB }
  1313. },
  1314. // GROUP_3W
  1315. {
  1316. { szTest, modrmW, ImmW },
  1317. { szBad },
  1318. { szNot, modrmW },
  1319. { szNeg, modrmW },
  1320. { szMul, AXreg, modrmW },
  1321. { szImul, AXreg, modrmW },
  1322. { szDiv, AXreg, modrmW },
  1323. { szIdiv, AXreg, modrmW }
  1324. },
  1325. // GROUP_4
  1326. {
  1327. { szInc, modrmB },
  1328. { szDec, modrmB },
  1329. { szBad },
  1330. { szBad },
  1331. { szBad },
  1332. { szBad },
  1333. { szBad },
  1334. { szBad }
  1335. },
  1336. // GROUP_5
  1337. {
  1338. { szInc, modrmW },
  1339. { szDec, modrmW },
  1340. { szCall, indirmodrmW },
  1341. { szCall, indirFARmodrmW },
  1342. { szJmp, indirmodrmW },
  1343. { szJmp, indirFARmodrmW },
  1344. { szPush, modrmW },
  1345. { szBad }
  1346. },
  1347. // GROUP_6
  1348. {
  1349. { szSldt, modrmW },
  1350. { szStr, modrmW },
  1351. { szLldt, modrmW },
  1352. { szLtr, modrmW },
  1353. { szVerr, modrmW },
  1354. { szVerw, modrmW },
  1355. { szBad },
  1356. { szBad }
  1357. },
  1358. // GROUP_7
  1359. {
  1360. { szSgdt, modrmW },
  1361. { szSidt, modrmW },
  1362. { szLgdt, modrmW },
  1363. { szLidt, modrmW },
  1364. { szSmsw, modrmW },
  1365. { szBad },
  1366. { szLmsw, modrmW },
  1367. { szBad }
  1368. },
  1369. // GROUP_8
  1370. {
  1371. { szBad },
  1372. { szBad },
  1373. { szBad },
  1374. { szBad },
  1375. { szBt, modrmW, ImmB },
  1376. { szBts, modrmW, ImmB },
  1377. { szBtr, modrmW, ImmB },
  1378. { szBtc, modrmW, ImmB }
  1379. }
  1380. };
  1381. UCHAR OpcodeSize;
  1382. BYTE *pData;
  1383. ADDR g_InstrAddr;
  1384. BOOL bBig;
  1385. void AppendString(char *str)
  1386. {
  1387. strcpy(g_pchOutput, (str));
  1388. g_pchOutput+=strlen(g_pchOutput);
  1389. }
  1390. void ExtraString(char *str)
  1391. {
  1392. strcpy(g_pchExtra, (str));
  1393. g_pchExtra+=strlen(g_pchExtra);
  1394. }
  1395. #define AppendChar(c) {*g_pchOutput++ = (c);}
  1396. #define AppendNumber(d) {_ultoa((ULONG)d,g_pchOutput, 16); g_pchOutput+=strlen(g_pchOutput);}
  1397. #define ExtraChar(c) {*g_pchExtra++ = (c);}
  1398. #define ExtraNumber(d) {_ultoa((ULONG)d,g_pchExtra, 16); g_pchExtra+=strlen(g_pchExtra);}
  1399. #define OPERAND_32 ((prefixes & PREFIX_DATA) ^ bBig)
  1400. #define ADDR_32 ((prefixes & PREFIX_ADR) ^ bBig)
  1401. int unassemble_one(
  1402. BYTE *pInstrStart, // instruction to decode (can be local buffer)
  1403. BOOL bDefaultBig,
  1404. WORD wInstrSeg, // selector of instruction
  1405. DWORD dwInstrOff, // offset of instruction
  1406. char *pchOutput, // [out] disassembled instruction
  1407. char *pchExtra, // [out] extra info (ie. "es:[53]=1234")
  1408. // (can be NULL)
  1409. VDMCONTEXT *pThreadContext,
  1410. int mode
  1411. ) {
  1412. int i;
  1413. int cb;
  1414. BYTE *pInstr = pInstrStart;
  1415. struct dis *pszDecode;
  1416. g_pThreadContext = pThreadContext;
  1417. g_mode = mode;
  1418. g_pchOutput = pchOutput;
  1419. g_InstrAddr.sSeg = wInstrSeg;
  1420. g_InstrAddr.sOff = dwInstrOff;
  1421. bBig = bDefaultBig;
  1422. gMode = mode;
  1423. gSelector = wInstrSeg;
  1424. gOffset = dwInstrOff;
  1425. if (pchExtra)
  1426. *pchExtra = '\0';
  1427. g_pchExtra = pchExtra;
  1428. if (*(UNALIGNED USHORT*)pInstr == 0xc4c4) {
  1429. pData = pInstr;
  1430. pData+=2;
  1431. return DisplayBOP();
  1432. }
  1433. pInstr = checkprefixes(pInstr);
  1434. OpcodeSize = 1;
  1435. if (*pInstr == 0x0f) {
  1436. OpcodeSize++;
  1437. pInstr++;
  1438. pszDecode = &dis386_2[*pInstr];
  1439. } else {
  1440. pszDecode = &dis386[*pInstr];
  1441. }
  1442. if (prefixes & PREFIX_REPZ)
  1443. AppendString("repz ");
  1444. if (prefixes & PREFIX_REPNZ)
  1445. AppendString("repnz ");
  1446. if (prefixes & PREFIX_LOCK)
  1447. AppendString("lock ");
  1448. if ((prefixes & PREFIX_FWAIT) && ((*pInstr < 0xd8) || (*pInstr > 0xdf))) {
  1449. /* fwait not followed by floating point instruction */
  1450. AppendString("fwait");
  1451. return (1);
  1452. }
  1453. pInstr++;
  1454. pData = pInstr;
  1455. if (pszDecode->szName < 0) { // found a GROUP_ or FLOAT entry...
  1456. i = (-pszDecode->szName)-1;
  1457. if (pszDecode->szName == FLOATCODE) {
  1458. AppendString("*float* ");
  1459. //Later: mputs("Floating point instructions NYI\n");
  1460. return 1;
  1461. } else {
  1462. pszDecode = &dis386_groups[i][(*pInstr>>3)&7];
  1463. }
  1464. }
  1465. AppendString(szInstructions[pszDecode->szName]);
  1466. if (pszDecode->iPart1) {
  1467. AppendChar('\t');
  1468. i = (*(rgpfn[pszDecode->iPart1].pfn))(pInstr);
  1469. if (pszDecode->iPart2) {
  1470. AppendString(", ");
  1471. i+=(*(rgpfn[pszDecode->iPart2].pfn))(pInstr);
  1472. if (pszDecode->iPart3) {
  1473. AppendString(", ");
  1474. i+=(*(rgpfn[pszDecode->iPart3].pfn))(pInstr);
  1475. }
  1476. }
  1477. pInstr+=i;
  1478. }
  1479. AppendChar('\0');
  1480. cb = pInstr - pInstrStart; // return length of instruction
  1481. return cb;
  1482. }
  1483. BOOL safe_read_byte(
  1484. ADDR addr,
  1485. BYTE *pb
  1486. ) {
  1487. ULONG Base;
  1488. *pb = 0xbb;
  1489. Base = GetInfoFromSelector( addr.sSeg, g_mode, NULL );
  1490. if (Base == (ULONG)-1 || Base == 0) {
  1491. return FALSE;
  1492. }
  1493. Base += GetIntelBase();
  1494. return READMEM((LPVOID)(Base+(ULONG)addr.sOff), pb, 1);
  1495. }
  1496. BOOL safe_read_short(
  1497. ADDR addr,
  1498. SHORT *ps
  1499. ) {
  1500. ULONG Base;
  1501. Base = GetInfoFromSelector( addr.sSeg, g_mode, NULL );
  1502. if (Base == (ULONG)-1 || Base == 0) {
  1503. return FALSE;
  1504. }
  1505. Base += GetIntelBase();
  1506. return READMEM((LPVOID)(Base+(ULONG)addr.sOff), ps, 2);
  1507. }
  1508. BOOL safe_read_long(
  1509. ADDR addr,
  1510. LONG *pl
  1511. ) {
  1512. ULONG Base;
  1513. Base = GetInfoFromSelector( addr.sSeg, g_mode, NULL );
  1514. if (Base == (ULONG)-1 || Base == 0) {
  1515. return FALSE;
  1516. }
  1517. Base += GetIntelBase();
  1518. return READMEM((LPVOID)(Base+(ULONG)addr.sOff), pl, 4);
  1519. }
  1520. int Dreg1B(LPBYTE lpB)
  1521. {
  1522. BYTE b = (*lpB >> 3) & 7;
  1523. AppendString(szRegsB[b]);
  1524. return 0;
  1525. }
  1526. int Dreg1W(LPBYTE lpB)
  1527. {
  1528. BYTE b = (*lpB >> 3) & 7;
  1529. if (OPERAND_32)
  1530. AppendString(szRegsD[b]);
  1531. else
  1532. AppendString(szRegsW[b]);
  1533. return 0;
  1534. }
  1535. int Dreg2B(LPBYTE lpB)
  1536. {
  1537. BYTE b = *lpB & 7;
  1538. AppendString(szRegsB[b]);
  1539. return 0;
  1540. }
  1541. int Dreg2W(LPBYTE lpB)
  1542. {
  1543. BYTE b = *lpB & 7;
  1544. if (OPERAND_32)
  1545. AppendString(szRegsD[b]);
  1546. else
  1547. AppendString(szRegsW[b]);
  1548. return 0;
  1549. }
  1550. int DmodrmB(LPBYTE lpB)
  1551. {
  1552. BYTE rm = *lpB & 0x07;
  1553. BYTE mod = *lpB >> 6;
  1554. unsigned short num;
  1555. int iRet;
  1556. pData++; // skip past mod r/m
  1557. if (mod == 3) {
  1558. AppendPrefixes();
  1559. AppendString(szRegsB[rm]);
  1560. return 1;
  1561. }
  1562. iRet = 0;
  1563. AppendString("byte ptr ");
  1564. AppendPrefixes();
  1565. AppendString(szMod[rm]);
  1566. AppendChar('+');
  1567. switch (mod) {
  1568. case 0:
  1569. if (rm == 6) {
  1570. g_pchOutput-=3; // back up over the 'BP+'
  1571. num = *((UNALIGNED USHORT*)pData);
  1572. AppendNumber(num);
  1573. pData+=2;
  1574. iRet = 3;
  1575. } else {
  1576. num = 0;
  1577. g_pchOutput--;
  1578. iRet = 1;
  1579. }
  1580. break;
  1581. case 1:
  1582. num = *pData;
  1583. AppendNumber(num);
  1584. pData++;
  1585. iRet = 2;
  1586. break;
  1587. case 2:
  1588. num = *((UNALIGNED USHORT*)pData);
  1589. AppendNumber(num);
  1590. pData += 2;
  1591. iRet = 3;
  1592. break;
  1593. }
  1594. AppendChar(']');
  1595. DisplayAddress(mod, rm, num, 1);
  1596. return iRet;
  1597. }
  1598. int DmodrmW(LPBYTE lpB)
  1599. {
  1600. BYTE rm = *lpB & 0x07;
  1601. BYTE mod = *lpB >> 6;
  1602. ULONG num;
  1603. int iRet;
  1604. pData++; // skip past mod r/m
  1605. AppendPrefixes();
  1606. if (mod == 3) {
  1607. if (OPERAND_32)
  1608. AppendString(szRegsD[rm]);
  1609. else
  1610. AppendString(szRegsW[rm]);
  1611. return 1;
  1612. }
  1613. if (ADDR_32) {
  1614. AppendChar('[');
  1615. AppendString(szRegsD[rm]);
  1616. } else {
  1617. AppendString(szMod[rm]);
  1618. }
  1619. AppendChar('+');
  1620. switch (mod) {
  1621. case 0:
  1622. //
  1623. // Handle special cases of ModRM
  1624. //
  1625. if ((rm == 6) && !ADDR_32) {
  1626. g_pchOutput-=3; // back up over 'BP+'
  1627. num = *((UNALIGNED USHORT*)pData);
  1628. AppendNumber(num);
  1629. pData+=2;
  1630. iRet = 3;
  1631. } else if ((rm == 5) && ADDR_32) {
  1632. g_pchOutput-=4; // back up over 'EBP+'
  1633. num = *((UNALIGNED ULONG*)pData);
  1634. AppendNumber(num);
  1635. pData+=4;
  1636. iRet = 5;
  1637. } else {
  1638. g_pchOutput--; // else back up over '+' alone
  1639. num=0;
  1640. iRet = 1;
  1641. }
  1642. break;
  1643. case 1:
  1644. num = *pData;
  1645. AppendNumber(num);
  1646. pData++;
  1647. iRet = 2;
  1648. break;
  1649. case 2:
  1650. num = *((UNALIGNED USHORT *)pData);
  1651. AppendNumber(num);
  1652. pData+=2;
  1653. iRet = 3;
  1654. break;
  1655. }
  1656. AppendChar(']');
  1657. DisplayAddress(mod, rm, num, ADDR_32 ? 4 : 2);
  1658. return iRet;
  1659. }
  1660. void DisplayAddress(int mod, int rm, int sOff, int size)
  1661. {
  1662. ADDR addr;
  1663. // if caller of unassemble_one() didn't want extra info, return now
  1664. if (g_pchExtra == NULL)
  1665. return;
  1666. // no memory reference
  1667. if (mod == 3)
  1668. return;
  1669. // display prefix
  1670. if (prefixes & PREFIX_DS) {
  1671. ExtraChar('D');
  1672. addr.sSeg = (USHORT)g_pThreadContext->SegDs;
  1673. } else if (prefixes & PREFIX_ES) {
  1674. ExtraChar('E');
  1675. addr.sSeg = (USHORT)g_pThreadContext->SegEs;
  1676. } else if (prefixes & PREFIX_FS) {
  1677. ExtraChar('F');
  1678. addr.sSeg = (USHORT)g_pThreadContext->SegFs;
  1679. } else if (prefixes & PREFIX_GS) {
  1680. ExtraChar('G');
  1681. addr.sSeg = (USHORT)g_pThreadContext->SegGs;
  1682. } else if (prefixes & PREFIX_CS) {
  1683. ExtraChar('C');
  1684. addr.sSeg = (USHORT)g_pThreadContext->SegCs;
  1685. } else if ( (prefixes & PREFIX_SS) || rm==2 || rm == 3) {
  1686. ExtraChar('S');
  1687. addr.sSeg = (USHORT)g_pThreadContext->SegSs;
  1688. } else if (rm == 6 && mod != 0) {
  1689. ExtraChar('S');
  1690. addr.sSeg = (USHORT)g_pThreadContext->SegSs;
  1691. } else {
  1692. ExtraChar('D');
  1693. addr.sSeg = (USHORT)g_pThreadContext->SegDs;
  1694. }
  1695. ExtraString("S:[");
  1696. switch (rm) {
  1697. case 0:
  1698. addr.sOff = (USHORT)(g_pThreadContext->Ebx + g_pThreadContext->Esi);
  1699. break;
  1700. case 1:
  1701. addr.sOff = (USHORT)(g_pThreadContext->Ebx + g_pThreadContext->Edi);
  1702. break;
  1703. case 2:
  1704. addr.sOff = (USHORT)(g_pThreadContext->Ebp + g_pThreadContext->Esi);
  1705. break;
  1706. case 3:
  1707. addr.sOff = (USHORT)(g_pThreadContext->Ebp + g_pThreadContext->Edi);
  1708. break;
  1709. case 4:
  1710. addr.sOff = (USHORT)g_pThreadContext->Esi;
  1711. break;
  1712. case 5:
  1713. addr.sOff = (USHORT)g_pThreadContext->Edi;
  1714. break;
  1715. case 6:
  1716. if (mod == 0)
  1717. addr.sOff = 0;
  1718. else
  1719. addr.sOff = (USHORT)g_pThreadContext->Ebp;
  1720. break;
  1721. default:
  1722. addr.sOff = (USHORT)g_pThreadContext->Ebx;
  1723. }
  1724. addr.sOff += sOff;
  1725. ExtraNumber(addr.sOff);
  1726. ExtraString("]=");
  1727. if (size == 2) {
  1728. SHORT s;
  1729. if (safe_read_short(addr, &s)) {
  1730. ExtraNumber( s );
  1731. } else {
  1732. ExtraString("????");
  1733. }
  1734. } else if (size == 1) {
  1735. BYTE b;
  1736. if (safe_read_byte(addr, &b)) {
  1737. ExtraNumber( b );
  1738. } else {
  1739. ExtraString("??");
  1740. }
  1741. } else if (size == 4) {
  1742. LONG l;
  1743. if (safe_read_long(addr, &l)) {
  1744. ExtraNumber( l );
  1745. } else {
  1746. ExtraString("????????");
  1747. }
  1748. } else {
  1749. ExtraString("Unknown size!");
  1750. }
  1751. }
  1752. int DisplayBOP(void)
  1753. {
  1754. UCHAR mjcode;
  1755. int InstSize = 3;
  1756. AppendString("BOP ");
  1757. mjcode = *((UCHAR *)pData);
  1758. pData++;
  1759. AppendNumber(mjcode);
  1760. switch (mjcode) {
  1761. case 0x50:
  1762. case 0x52:
  1763. case 0x53:
  1764. case 0x54:
  1765. case 0x58:
  1766. //
  1767. // This BOP has a minor function code
  1768. //
  1769. InstSize++;
  1770. AppendString(", ");
  1771. AppendNumber(*((UCHAR *)pData));
  1772. }
  1773. return InstSize;
  1774. }
  1775. int DALreg(LPBYTE lpB)
  1776. {
  1777. AppendString("al");
  1778. return 0;
  1779. }
  1780. int DAHreg(LPBYTE lpB)
  1781. {
  1782. AppendString("ah");
  1783. return 0;
  1784. }
  1785. int DBLreg(LPBYTE lpB)
  1786. {
  1787. AppendString("bl");
  1788. return 0;
  1789. }
  1790. int DBHreg(LPBYTE lpB)
  1791. {
  1792. AppendString("bh");
  1793. return 0;
  1794. }
  1795. int DCLreg(LPBYTE lpB)
  1796. {
  1797. AppendString("cl");
  1798. return 0;
  1799. }
  1800. int DCHreg(LPBYTE lpB)
  1801. {
  1802. AppendString("ch");
  1803. return 0;
  1804. }
  1805. int DDLreg(LPBYTE lpB)
  1806. {
  1807. AppendString("dl");
  1808. return 0;
  1809. }
  1810. int DDHreg(LPBYTE lpB)
  1811. {
  1812. AppendString("dh");
  1813. return 0;
  1814. }
  1815. int DAXreg(LPBYTE lpB)
  1816. {
  1817. if (OPERAND_32)
  1818. AppendChar('e');
  1819. AppendString("ax");
  1820. return 0;
  1821. }
  1822. int DBXreg(LPBYTE lpB)
  1823. {
  1824. if (OPERAND_32)
  1825. AppendChar('e');
  1826. AppendString("bx");
  1827. return 0;
  1828. }
  1829. int DCXreg(LPBYTE lpB)
  1830. {
  1831. if (OPERAND_32)
  1832. AppendChar('e');
  1833. AppendString("cx");
  1834. return 0;
  1835. }
  1836. int DDXreg(LPBYTE lpB)
  1837. {
  1838. if (OPERAND_32)
  1839. AppendChar('e');
  1840. AppendString("dx");
  1841. return 0;
  1842. }
  1843. int DBPreg(LPBYTE lpB)
  1844. {
  1845. if (OPERAND_32)
  1846. AppendChar('e');
  1847. AppendString("bp");
  1848. return 0;
  1849. }
  1850. int DSPreg(LPBYTE lpB)
  1851. {
  1852. if (OPERAND_32)
  1853. AppendChar('e');
  1854. AppendString("sp");
  1855. return 0;
  1856. }
  1857. int DSIreg(LPBYTE lpB)
  1858. {
  1859. if (OPERAND_32)
  1860. AppendChar('e');
  1861. AppendString("si");
  1862. return 0;
  1863. }
  1864. int DDIreg(LPBYTE lpB)
  1865. {
  1866. if (OPERAND_32)
  1867. AppendChar('e');
  1868. AppendString("di");
  1869. return 0;
  1870. }
  1871. int DCSreg(LPBYTE lpB)
  1872. {
  1873. AppendString("cs");
  1874. return 0;
  1875. }
  1876. int DDSreg(LPBYTE lpB)
  1877. {
  1878. AppendString("ds");
  1879. return 0;
  1880. }
  1881. int DSSreg(LPBYTE lpB)
  1882. {
  1883. AppendString("es");
  1884. return 0;
  1885. }
  1886. int DESreg(LPBYTE lpB)
  1887. {
  1888. AppendString("es");
  1889. return 0;
  1890. }
  1891. int DFSreg(LPBYTE lpB)
  1892. {
  1893. AppendString("fs");
  1894. return 0;
  1895. }
  1896. int DGSreg(LPBYTE lpB)
  1897. {
  1898. AppendString("gs");
  1899. return 0;
  1900. }
  1901. int DImmB(LPBYTE lpB)
  1902. {
  1903. AppendNumber(*((UCHAR *)pData));
  1904. pData++;
  1905. return 1;
  1906. }
  1907. int DImmBEnter(LPBYTE lpB)
  1908. {
  1909. AppendNumber(*((UCHAR *)pData));
  1910. pData++;
  1911. return 1;
  1912. }
  1913. int DImmBS(LPBYTE lpB) // sign-extend 8-bit value to 16 bits
  1914. {
  1915. int i = (signed char)*(pData);
  1916. AppendNumber((USHORT)i);
  1917. pData++;
  1918. return 1;
  1919. }
  1920. int DImmW(LPBYTE lpB)
  1921. {
  1922. if (OPERAND_32) {
  1923. AppendNumber( *((UNALIGNED ULONG*)pData) );
  1924. pData+=4;
  1925. return 4;
  1926. } else {
  1927. AppendNumber( *((UNALIGNED USHORT*)pData) );
  1928. pData+=2;
  1929. return 2;
  1930. }
  1931. }
  1932. int DImmW1(LPBYTE lpB)
  1933. {
  1934. AppendNumber( *((UNALIGNED SHORT*)(pData)) );
  1935. pData++;
  1936. return 2;
  1937. }
  1938. int DjmpB(LPBYTE lpB)
  1939. {
  1940. ULONG Dest = g_InstrAddr.sOff + (LONG)*((UNALIGNED CHAR *)lpB) + OpcodeSize + 1;
  1941. if (OPERAND_32) {
  1942. AppendNumber(Dest);
  1943. } else {
  1944. AppendNumber((USHORT)Dest);
  1945. }
  1946. return 1;
  1947. }
  1948. int DjmpW(LPBYTE lpB)
  1949. {
  1950. if (OPERAND_32) {
  1951. AppendNumber(g_InstrAddr.sOff + *((UNALIGNED ULONG *)lpB) + OpcodeSize + 4);
  1952. return 4;
  1953. } else {
  1954. AppendNumber(LOWORD(g_InstrAddr.sOff + (ULONG)*((UNALIGNED USHORT *)lpB) + OpcodeSize + 2));
  1955. return 2;
  1956. }
  1957. }
  1958. int DregSeg(LPBYTE lpB)
  1959. {
  1960. BYTE b = (*lpB >> 3) & 7;
  1961. AppendString(szRegsSeg[b]);
  1962. return 0;
  1963. }
  1964. int DmemB(LPBYTE lpB)
  1965. {
  1966. ADDR addr;
  1967. addr.sOff = *(lpB+1);
  1968. AppendChar('[');
  1969. AppendNumber( addr.sOff );
  1970. AppendChar(']');
  1971. if (g_pchExtra) {
  1972. BYTE b;
  1973. if (prefixes & PREFIX_DS) {
  1974. ExtraChar('D');
  1975. addr.sSeg = (USHORT)g_pThreadContext->SegDs;
  1976. } else if (prefixes & PREFIX_ES) {
  1977. ExtraChar('E');
  1978. addr.sSeg = (USHORT)g_pThreadContext->SegEs;
  1979. } else if (prefixes & PREFIX_FS) {
  1980. ExtraChar('F');
  1981. addr.sSeg = (USHORT)g_pThreadContext->SegFs;
  1982. } else if (prefixes & PREFIX_GS) {
  1983. ExtraChar('G');
  1984. addr.sSeg = (USHORT)g_pThreadContext->SegGs;
  1985. } else if (prefixes & PREFIX_CS) {
  1986. ExtraChar('C');
  1987. addr.sSeg = (USHORT)g_pThreadContext->SegCs;
  1988. } else if (prefixes & PREFIX_SS) {
  1989. ExtraChar('S');
  1990. addr.sSeg = (USHORT)g_pThreadContext->SegSs;
  1991. } else {
  1992. ExtraChar('D');
  1993. addr.sSeg = (USHORT)g_pThreadContext->SegDs;
  1994. }
  1995. ExtraString("S:[");
  1996. ExtraNumber( addr.sOff );
  1997. ExtraString("]=");
  1998. if (safe_read_byte(addr, &b)) {
  1999. ExtraNumber( b );
  2000. } else {
  2001. ExtraString("??");
  2002. }
  2003. }
  2004. return 1;
  2005. }
  2006. int DmemB1(LPBYTE lpB)
  2007. {
  2008. AppendNumber( *lpB );
  2009. return 1;
  2010. }
  2011. int DmemW(LPBYTE lpB)
  2012. {
  2013. int i;
  2014. ADDR addr;
  2015. addr.sOff = *(lpB+1);
  2016. AppendChar('[');
  2017. if (ADDR_32) {
  2018. AppendNumber( *((UNALIGNED long*)lpB) );
  2019. i=4;
  2020. } else {
  2021. addr.sOff = *((UNALIGNED short *)lpB);
  2022. AppendNumber( addr.sOff );
  2023. i=2;
  2024. }
  2025. AppendChar(']');
  2026. if (g_pchExtra) {
  2027. if (prefixes & PREFIX_DS) {
  2028. ExtraChar('D');
  2029. addr.sSeg = (USHORT)g_pThreadContext->SegDs;
  2030. } else if (prefixes & PREFIX_ES) {
  2031. ExtraChar('E');
  2032. addr.sSeg = (USHORT)g_pThreadContext->SegEs;
  2033. } else if (prefixes & PREFIX_FS) {
  2034. ExtraChar('F');
  2035. addr.sSeg = (USHORT)g_pThreadContext->SegFs;
  2036. } else if (prefixes & PREFIX_GS) {
  2037. ExtraChar('G');
  2038. addr.sSeg = (USHORT)g_pThreadContext->SegGs;
  2039. } else if (prefixes & PREFIX_CS) {
  2040. ExtraChar('C');
  2041. addr.sSeg = (USHORT)g_pThreadContext->SegCs;
  2042. } else if (prefixes & PREFIX_SS) {
  2043. ExtraChar('S');
  2044. addr.sSeg = (USHORT)g_pThreadContext->SegSs;
  2045. } else {
  2046. ExtraChar('D');
  2047. addr.sSeg = (USHORT)g_pThreadContext->SegDs;
  2048. }
  2049. ExtraString("S:[");
  2050. ExtraNumber( addr.sOff );
  2051. ExtraString("]=");
  2052. if (i == 2) {
  2053. SHORT s;
  2054. if (safe_read_short(addr, &s)) {
  2055. ExtraNumber( s );
  2056. } else {
  2057. ExtraString( "????" );
  2058. }
  2059. } else {
  2060. LONG l;
  2061. if (safe_read_long(addr, &l)) {
  2062. ExtraNumber( l );
  2063. } else {
  2064. ExtraString( "????????" );
  2065. }
  2066. }
  2067. }
  2068. return i;
  2069. }
  2070. int DmemD(LPBYTE lpB)
  2071. {
  2072. int i;
  2073. if (OPERAND_32) {
  2074. AppendNumber( *(((UNALIGNED SHORT*)lpB)+2) );
  2075. AppendChar(':');
  2076. AppendNumber( *((UNALIGNED long*)lpB) );
  2077. i=6;
  2078. } else {
  2079. USHORT sel, off;
  2080. sel = *(((UNALIGNED SHORT*)lpB)+1);
  2081. off = *((UNALIGNED SHORT*)lpB);
  2082. AppendNumber( sel );
  2083. AppendChar(':');
  2084. AppendNumber( off );
  2085. i=4;
  2086. if (g_pchExtra) {
  2087. char sym_text[1000];
  2088. LONG dist;
  2089. // if the exact symbol name was found, print it
  2090. if (FindSymbol( sel,
  2091. off,
  2092. sym_text,
  2093. &dist,
  2094. BEFORE,
  2095. g_mode)) {
  2096. ExtraString("= ");
  2097. ExtraString(sym_text);
  2098. if (dist) {
  2099. ExtraString(" + ");
  2100. ExtraNumber( dist );
  2101. }
  2102. }
  2103. }
  2104. }
  2105. return i;
  2106. }
  2107. int DindirmodrmW(LPBYTE lpB)
  2108. {
  2109. int i;
  2110. AppendString("FAR PTR ");
  2111. i = DmodrmW(lpB);
  2112. AppendChar(']');
  2113. return i;
  2114. }
  2115. int DindirFARmodrmW(LPBYTE lpB)
  2116. {
  2117. int i;
  2118. AppendString("FAR PTR ");
  2119. i = DmodrmW(lpB);
  2120. AppendChar(']');
  2121. return i;
  2122. }
  2123. int DeeeControl(LPBYTE lpB)
  2124. {
  2125. AppendChar('c');
  2126. AppendChar('r');
  2127. AppendChar('0'+ ((*lpB >> 3) & 7) );
  2128. return 1;
  2129. }
  2130. int DeeeDebug(LPBYTE lpB)
  2131. {
  2132. AppendChar('d');
  2133. AppendChar('r');
  2134. AppendChar('0'+ ((*lpB >> 3) & 7) );
  2135. return 1;
  2136. }
  2137. int DeeeTest(LPBYTE lpB)
  2138. {
  2139. AppendChar('t');
  2140. AppendChar('r');
  2141. AppendChar('0'+ ((*lpB >> 3) & 7) );
  2142. return 1;
  2143. }
  2144. LPBYTE checkprefixes(LPBYTE lpB)
  2145. {
  2146. prefixes = 0;
  2147. for (;;) {
  2148. switch (*lpB) {
  2149. case 0xf3:
  2150. prefixes |= PREFIX_REPZ;
  2151. break;
  2152. case 0xf2:
  2153. prefixes |= PREFIX_REPNZ;
  2154. break;
  2155. case 0xf0:
  2156. prefixes |= PREFIX_LOCK;
  2157. break;
  2158. case 0x2e:
  2159. prefixes |= PREFIX_CS;
  2160. break;
  2161. case 0x36:
  2162. prefixes |= PREFIX_SS;
  2163. break;
  2164. case 0x3e:
  2165. prefixes |= PREFIX_DS;
  2166. break;
  2167. case 0x26:
  2168. prefixes |= PREFIX_ES;
  2169. break;
  2170. case 0x64:
  2171. prefixes |= PREFIX_FS;
  2172. break;
  2173. case 0x65:
  2174. prefixes |= PREFIX_GS;
  2175. break;
  2176. case 0x66:
  2177. prefixes |= PREFIX_DATA;
  2178. break;
  2179. case 0x67:
  2180. prefixes |= PREFIX_ADR;
  2181. break;
  2182. case 0x9b:
  2183. prefixes |= PREFIX_FWAIT;
  2184. break;
  2185. default:
  2186. return lpB;
  2187. }
  2188. lpB++;
  2189. }
  2190. }
  2191. void AppendPrefixes(void)
  2192. {
  2193. if (prefixes & PREFIX_CS)
  2194. AppendString("cs:");
  2195. if (prefixes & PREFIX_DS)
  2196. AppendString("ds:");
  2197. if (prefixes & PREFIX_SS)
  2198. AppendString("ss:");
  2199. if (prefixes & PREFIX_ES)
  2200. AppendString("es:");
  2201. if (prefixes & PREFIX_FS)
  2202. AppendString("fs:");
  2203. if (prefixes & PREFIX_GS)
  2204. AppendString("gs:");
  2205. }