Source code of Windows XP (NT5)
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.

721 lines
16 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. ntsdexts.c
  5. Abstract:
  6. This function contains miscellaneous VDMEXTS functions
  7. Author:
  8. Bob Day (bobday) 29-Feb-1992 Grabbed standard header
  9. Revision History:
  10. Neil Sandlin (NeilSa) 15-Jan-1996 Merged with vdmexts
  11. --*/
  12. #include <precomp.h>
  13. #pragma hdrstop
  14. #include <ctype.h>
  15. extern DWORD gOffset; // in disasm.c
  16. VOID
  17. DumpMemory(
  18. UINT UnitSize,
  19. BOOL bAscii
  20. )
  21. {
  22. VDMCONTEXT ThreadContext;
  23. int mode;
  24. int j, lines = 8, linelength;
  25. WORD selector;
  26. ULONG offset, endoffset, units;
  27. ULONG base;
  28. char ch;
  29. if (!UnitSize) {
  30. return;
  31. }
  32. mode = GetContext( &ThreadContext );
  33. if (!GetNextToken()) {
  34. PRINTF("Please specify an address\n");
  35. return;
  36. }
  37. if (!ParseIntelAddress(&mode, &selector, &offset)) {
  38. return;
  39. }
  40. if (GetNextToken()) {
  41. if ((*lpArgumentString == 'l') || (*lpArgumentString == 'L')) {
  42. lpArgumentString++;
  43. }
  44. units = EvaluateToken();
  45. lines = (units*UnitSize+15)/16;
  46. } else {
  47. units = (lines*16)/UnitSize;
  48. }
  49. endoffset = offset+units*UnitSize;
  50. base = GetInfoFromSelector(selector, mode, NULL) + GetIntelBase();
  51. while (lines--) {
  52. if (offset & 0xFFFF0000) {
  53. PRINTF("%04x:%08lx ", selector, offset);
  54. } else {
  55. PRINTF("%04x:%04x ", selector, LOWORD(offset));
  56. }
  57. linelength = endoffset - offset;
  58. if (linelength > 16) {
  59. linelength = 16;
  60. }
  61. switch(UnitSize) {
  62. case 1:
  63. for (j=0; j<linelength; j++) {
  64. if (j==8) {
  65. PRINTF("-");
  66. } else {
  67. PRINTF(" ");
  68. }
  69. PRINTF("%02x", ReadByteSafe(base+offset+j));
  70. }
  71. break;
  72. case 2:
  73. for (j=0; j<linelength; j+=2) {
  74. PRINTF(" %04x", ReadWordSafe(base+offset+j));
  75. }
  76. break;
  77. case 4:
  78. for (j=0; j<linelength; j+=4) {
  79. PRINTF(" %08lx", ReadDwordSafe(base+offset+j));
  80. }
  81. break;
  82. }
  83. if (bAscii) {
  84. j = (16-linelength)*2 + (16-linelength)/UnitSize;
  85. while (j--) {
  86. PRINTF(" ");
  87. }
  88. PRINTF(" ");
  89. for (j=0; j<linelength; j++) {
  90. ch = ReadByteSafe(base+offset+j);
  91. if (isprint(ch)) {
  92. PRINTF("%c", ch);
  93. } else {
  94. PRINTF(".");
  95. }
  96. }
  97. }
  98. PRINTF("\n");
  99. offset += 16;
  100. }
  101. }
  102. VOID
  103. db(
  104. CMD_ARGLIST
  105. )
  106. {
  107. CMD_INIT();
  108. DumpMemory(1, TRUE);
  109. }
  110. VOID
  111. dw(
  112. CMD_ARGLIST
  113. )
  114. {
  115. CMD_INIT();
  116. DumpMemory(2, FALSE);
  117. }
  118. VOID
  119. dd(
  120. CMD_ARGLIST
  121. )
  122. {
  123. CMD_INIT();
  124. DumpMemory(4, FALSE);
  125. }
  126. VOID
  127. EditMemory(
  128. UINT UnitSize
  129. )
  130. {
  131. ULONG value, base, offset;
  132. WORD selector;
  133. int mode;
  134. if (!GetNextToken()) {
  135. PRINTF("Please specify an address\n");
  136. return;
  137. }
  138. if (!ParseIntelAddress(&mode, &selector, &offset)) {
  139. return;
  140. }
  141. base = GetInfoFromSelector(selector, mode, NULL) + GetIntelBase();
  142. while(GetNextToken()) {
  143. value = EvaluateToken();
  144. PRINTF("%04x base=%08x offset=%08x value=%08x\n", selector, base, offset, value);
  145. // this is endian dependant code
  146. WRITEMEM((LPVOID)(base+offset), &value, UnitSize);
  147. offset += UnitSize;
  148. }
  149. }
  150. VOID
  151. eb(
  152. CMD_ARGLIST
  153. )
  154. {
  155. CMD_INIT();
  156. EditMemory(1);
  157. }
  158. VOID
  159. ew(
  160. CMD_ARGLIST
  161. )
  162. {
  163. CMD_INIT();
  164. EditMemory(2);
  165. }
  166. VOID
  167. ed(
  168. CMD_ARGLIST
  169. )
  170. {
  171. CMD_INIT();
  172. EditMemory(4);
  173. }
  174. VOID
  175. r(
  176. CMD_ARGLIST
  177. ) {
  178. VDMCONTEXT ThreadContext;
  179. int mode;
  180. char sym_text[255];
  181. char rgchOutput[128];
  182. char rgchExtra[128];
  183. BYTE rgbInstruction[64];
  184. WORD selector;
  185. ULONG offset;
  186. ULONG dist;
  187. int cb, j;
  188. ULONG Base;
  189. SELECTORINFO si;
  190. CMD_INIT();
  191. mode = GetContext( &ThreadContext );
  192. PRINTF("eax=%08lx ebx=%08lx ecx=%08lx edx=%08lx esi=%08lx edi=%08lx\n",
  193. ThreadContext.Eax,
  194. ThreadContext.Ebx,
  195. ThreadContext.Ecx,
  196. ThreadContext.Edx,
  197. ThreadContext.Esi,
  198. ThreadContext.Edi );
  199. PRINTF("eip=%08lx esp=%08lx ebp=%08lx ",
  200. ThreadContext.Eip,
  201. ThreadContext.Esp,
  202. ThreadContext.Ebp );
  203. if (ThreadContext.EFlags != 0xffffffff) {
  204. if ( ThreadContext.EFlags & FLAG_OVERFLOW ) {
  205. PRINTF("ov ");
  206. } else {
  207. PRINTF("nv ");
  208. }
  209. if ( ThreadContext.EFlags & FLAG_DIRECTION ) {
  210. PRINTF("dn ");
  211. } else {
  212. PRINTF("up ");
  213. }
  214. if ( ThreadContext.EFlags & FLAG_INTERRUPT ) {
  215. PRINTF("ei ");
  216. } else {
  217. PRINTF("di ");
  218. }
  219. if ( ThreadContext.EFlags & FLAG_SIGN ) {
  220. PRINTF("ng ");
  221. } else {
  222. PRINTF("pl ");
  223. }
  224. if ( ThreadContext.EFlags & FLAG_ZERO ) {
  225. PRINTF("zr ");
  226. } else {
  227. PRINTF("nz ");
  228. }
  229. if ( ThreadContext.EFlags & FLAG_AUXILLIARY ) {
  230. PRINTF("ac ");
  231. } else {
  232. PRINTF("na ");
  233. }
  234. if ( ThreadContext.EFlags & FLAG_PARITY ) {
  235. PRINTF("po ");
  236. } else {
  237. PRINTF("pe ");
  238. }
  239. if ( ThreadContext.EFlags & FLAG_CARRY ) {
  240. PRINTF("cy ");
  241. } else {
  242. PRINTF("nc ");
  243. }
  244. }
  245. PRINTF("\n");
  246. PRINTF("cs=%04x ss=%04x ds=%04x es=%04x fs=%04x gs=%04x ",
  247. ThreadContext.SegCs,
  248. ThreadContext.SegSs,
  249. ThreadContext.SegDs,
  250. ThreadContext.SegEs,
  251. ThreadContext.SegFs,
  252. ThreadContext.SegGs);
  253. if (ThreadContext.EFlags == 0xffffffff) {
  254. //
  255. // The contents of eflags are unreliable. This happens when you can't
  256. // do a "getEFLAGS()" to obtain the value.
  257. //
  258. PRINTF("efl=????????\n");
  259. } else {
  260. PRINTF("efl=%08lx\n",ThreadContext.EFlags );
  261. }
  262. //
  263. // Do disassembly of current instruction
  264. //
  265. selector = (WORD) ThreadContext.SegCs;
  266. offset = ThreadContext.Eip;
  267. Base = GetInfoFromSelector( selector, mode, &si ) + GetIntelBase();
  268. if (FindSymbol(selector, offset, sym_text, &dist, BEFORE, mode )) {
  269. if ( dist == 0 ) {
  270. PRINTF("%s:\n", sym_text );
  271. } else {
  272. PRINTF("%s+0x%lx:\n", sym_text, dist );
  273. }
  274. }
  275. cb = sizeof(rgbInstruction);
  276. if ((DWORD)(offset+cb) >= si.Limit)
  277. cb -= offset+cb-si.Limit;
  278. if (!READMEM((LPVOID)(Base+offset), rgbInstruction, cb)) {
  279. PRINTF("%04x:%08x: <Error Reading Memory>\n", selector, offset);
  280. return;
  281. }
  282. cb = unassemble_one(rgbInstruction,
  283. si.bBig,
  284. selector, offset,
  285. rgchOutput,
  286. rgchExtra,
  287. &ThreadContext,
  288. mode);
  289. if (offset > 0xffff) {
  290. PRINTF("%04x:%08x ", selector, offset);
  291. } else {
  292. PRINTF("%04x:%04x ", selector, offset);
  293. }
  294. for (j=0; j<cb; ++j)
  295. PRINTF("%02x", rgbInstruction[j]);
  296. for (; j<8; ++j)
  297. PRINTF(" ");
  298. PRINTF("%s\t%s\n", rgchOutput, rgchExtra);
  299. }
  300. VOID
  301. SearchModuleList(
  302. VOID
  303. )
  304. {
  305. VDMCONTEXT ThreadContext;
  306. int mode;
  307. HEAPENTRY he = {0};
  308. SELECTORINFO si;
  309. WORD selector = 0;
  310. SEGENTRY *se;
  311. char filename[9];
  312. char szModuleArg[255];
  313. BOOL bModuleNameGiven=FALSE;
  314. LPSTR pTemp;
  315. mode = GetContext( &ThreadContext );
  316. if (GetNextToken()) {
  317. if (IsTokenHex()) {
  318. selector = (WORD) EvaluateToken();
  319. } else {
  320. bModuleNameGiven = TRUE;
  321. pTemp = lpArgumentString;
  322. SkipToNextWhiteSpace();
  323. *lpArgumentString = 0;
  324. strcpy(szModuleArg, pTemp);
  325. if (strlen(szModuleArg) > 8) {
  326. szModuleArg[8] = 0;
  327. }
  328. }
  329. }
  330. PRINTF("Sel Base Limit Type Module Seg\n");
  331. PRINTF("==== ======== ======== ==== ======== ===\n");
  332. se = GetSegtablePointer();
  333. while ( se ) {
  334. if ( selector == 0 ||
  335. se->selector == selector ||
  336. bModuleNameGiven) {
  337. switch (se->type) {
  338. case SEGTYPE_PROT:
  339. {
  340. HEAPENTRY he = {0};
  341. he.Selector = se->selector;
  342. if (FindHeapEntry(&he, FHE_FIND_SEL_ONLY, FHE_FIND_QUIET)) {
  343. break;
  344. }
  345. }
  346. GetInfoFromSelector(se->selector, PROT_MODE, &si);
  347. ParseModuleName(filename, se->szExePath);
  348. if (!bModuleNameGiven || !_stricmp(filename, szModuleArg)) {
  349. PRINTF("%04X %08lX %08lX",
  350. se->selector,
  351. si.Base,
  352. si.Limit);
  353. PRINTF(" %s", si.bCode ? "code" : "data");
  354. PRINTF(" %-8.8s %d\n",
  355. filename,
  356. se->segment+1 );
  357. }
  358. break;
  359. case SEGTYPE_V86:
  360. ParseModuleName(filename, se->szExePath);
  361. if (!bModuleNameGiven || !_stricmp(filename, szModuleArg)) {
  362. PRINTF("%04X %08lX %08lX %s %-8.8s %d\n",
  363. se->selector,
  364. se->selector << 4,
  365. se->length,
  366. "v86 ",
  367. filename,
  368. se->segment+1);
  369. }
  370. break;
  371. }
  372. }
  373. se = se->Next;
  374. }
  375. he.CurrentEntry = 0; // reset scan
  376. if (bModuleNameGiven) {
  377. strcpy(he.ModuleArg, szModuleArg);
  378. } else {
  379. he.Selector = selector;
  380. }
  381. while (FindHeapEntry(&he, bModuleNameGiven ? FHE_FIND_MOD_ONLY :
  382. FHE_FIND_SEL_ONLY,
  383. FHE_FIND_QUIET)) {
  384. if (he.SegmentNumber != -1) {
  385. GetInfoFromSelector((WORD)(he.gnode.pga_handle | 1), PROT_MODE, &si);
  386. PRINTF("%04X %08lX %08lX",
  387. he.gnode.pga_handle | 1,
  388. he.gnode.pga_address,
  389. he.gnode.pga_size - 1);
  390. PRINTF(" %s", si.bCode ? "Code" : "Data");
  391. PRINTF(" %-8.8s %d\n",
  392. he.OwnerName,
  393. he.SegmentNumber+1);
  394. }
  395. }
  396. }
  397. VOID
  398. lm(
  399. CMD_ARGLIST
  400. )
  401. {
  402. CMD_INIT();
  403. if (GetNextToken()) {
  404. SearchModuleList();
  405. } else {
  406. WORD sel;
  407. BOOL b;
  408. NEHEADER owner;
  409. ULONG base;
  410. CHAR ModuleName[9];
  411. UCHAR len;
  412. if (!ReadMemExpression("ntvdmd!DbgWowhExeHead", &sel, sizeof(sel))) {
  413. return;
  414. }
  415. PRINTF("NEHeader Module Name\n");
  416. while(sel) {
  417. base = GetInfoFromSelector(sel, PROT_MODE, NULL) + GetIntelBase();
  418. b = READMEM((LPVOID)base, &owner, sizeof(owner));
  419. if (!b || (owner.ne_magic != 0x454e)) {
  420. PRINTF("Invalid module list! (started with hExeHead)\n");
  421. return;
  422. }
  423. len = ReadByteSafe(base+owner.ne_restab);
  424. if (len>8) {
  425. len=8;
  426. }
  427. READMEM((LPVOID)(base+owner.ne_restab+1), ModuleName, 8);
  428. ModuleName[len] = 0;
  429. PRINTF(" %.04X %s\n", sel, ModuleName);
  430. // This is mapped to ne_pnextexe in kernel
  431. sel = owner.ne_cbenttab;
  432. }
  433. }
  434. }
  435. VOID
  436. dg(
  437. CMD_ARGLIST
  438. ) {
  439. ULONG selector;
  440. ULONG Base;
  441. SELECTORINFO si;
  442. int count = 16;
  443. CMD_INIT();
  444. if (!GetNextToken()) {
  445. PRINTF("Please enter a selector\n");
  446. return;
  447. }
  448. selector = EvaluateToken();
  449. if (GetNextToken()) {
  450. if (tolower(*lpArgumentString) == 'l') {
  451. lpArgumentString++;
  452. }
  453. count = (WORD) EvaluateToken();
  454. }
  455. while (count--) {
  456. Base = GetInfoFromSelector( (WORD) selector, PROT_MODE, &si );
  457. PRINTF("%04X => Base: %08lX", selector, Base);
  458. #ifndef i386
  459. PRINTF(" (%08X)", Base+GetIntelBase());
  460. #endif
  461. PRINTF(" Limit: %08lX %s %s %s %s %s %s\n",
  462. si.Limit,
  463. si.bPresent ? " P" : "NP",
  464. si.bSystem ? "System" : si.bCode ? "Code " : "Data ",
  465. si.bSystem ? "" : si.bWrite ? "W" : "R",
  466. si.bSystem ? "" : si.bAccessed ? "A" : " ",
  467. si.bBig ? "Big" : "",
  468. si.bExpandDown ? "ED" : ""
  469. );
  470. selector+=8;
  471. if (selector>0xffff) {
  472. break;
  473. }
  474. }
  475. }
  476. VOID
  477. ntsd(
  478. CMD_ARGLIST
  479. )
  480. {
  481. #if 0
  482. PVOID Address;
  483. static BOOL bTrue = TRUE;
  484. #endif
  485. CMD_INIT();
  486. PRINTF("vdmexts: obselete command 'ntsd', use '.<cmd>' from VDM> prompt\n");
  487. #if 0
  488. if (!InVdmPrompt()) {
  489. PRINTF("This command only works at the VDM> prompt\n");
  490. }
  491. Address = (PVOID)(*GetExpression)("ntvdmd!bWantsNtsdPrompt");
  492. if (Address) {
  493. WRITEMEM((PVOID)Address, &bTrue, sizeof(BOOL));
  494. PRINTF("Enter 'g' to return from the ntsd prompt\n");
  495. } else {
  496. PRINTF("Can't find symbol 'ntvdmd!bWantsNtsdPrompt'\n");
  497. }
  498. #endif
  499. }
  500. VOID
  501. q(
  502. CMD_ARGLIST
  503. )
  504. {
  505. CMD_INIT();
  506. PRINTF("!vdmexts.q quitting debugger...");
  507. ExitProcess(0);
  508. }
  509. //
  510. // fs find string
  511. // case-insensitive
  512. // searches LDT selectors one by one, first 64k only.
  513. //
  514. VOID
  515. fs(
  516. CMD_ARGLIST
  517. ) {
  518. ULONG selector;
  519. ULONG Base;
  520. ULONG cbCopied;
  521. SELECTORINFO si;
  522. BYTE Buffer[65*1024];
  523. LPSTR pszSearch;
  524. LPSTR pch;
  525. CMD_INIT();
  526. RtlZeroMemory(Buffer, sizeof(Buffer));
  527. if (!GetNextToken()) {
  528. PRINTF("Please enter a string to find in 16:16 memory\n");
  529. return;
  530. }
  531. pszSearch = lpArgumentString;
  532. PRINTF("Searching 16:16 memory for '%s'\n", pszSearch);
  533. for (selector = 7;
  534. selector < 0x10000;
  535. selector += 8) {
  536. Base = GetInfoFromSelector( (WORD) selector, PROT_MODE, &si );
  537. //
  538. // If the selector is valid and present read up to 64k
  539. // into Buffer.
  540. //
  541. if (Base != (ULONG)-1 && si.bPresent) {
  542. cbCopied = si.Limit + 1;
  543. if (cbCopied > 0x10000) {
  544. cbCopied = 0x10000;
  545. }
  546. if (!READMEM((LPVOID)(Base + GetIntelBase()), Buffer, cbCopied)) {
  547. PRINTF("Unable to read selector %04x contents at %x for %x bytes\n",
  548. selector, Base + GetIntelBase(), cbCopied);
  549. } else {
  550. //
  551. // search the block for the string, buffer is 1k too big and
  552. // zero-inited so that strcmp is safe.
  553. //
  554. for (pch = Buffer;
  555. pch < (Buffer + cbCopied);
  556. pch++) {
  557. if (!_memicmp(pch, pszSearch, strlen(pszSearch))) {
  558. //
  559. // Match!
  560. //
  561. PRINTF("%04x:%04x (%08x) '%s'\n",
  562. selector,
  563. pch - Buffer,
  564. #ifndef i386
  565. GetIntelBase() +
  566. #endif
  567. Base + (pch - Buffer),
  568. pch);
  569. }
  570. }
  571. }
  572. }
  573. }
  574. }