Windows NT 4.0 source code leak
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.

614 lines
14 KiB

4 years ago
  1. #include <precomp.h>
  2. #pragma hdrstop
  3. BOOL
  4. WINAPI
  5. ReadProcessMem(
  6. HANDLE hProcess,
  7. LPVOID lpBaseAddress,
  8. LPVOID lpBuffer,
  9. DWORD nSize,
  10. LPDWORD lpNumberOfBytesRead
  11. )
  12. {
  13. if ( fWinDbg ) {
  14. return (*ReadProcessMemWinDbg)( (DWORD)lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead );
  15. } else {
  16. return ReadProcessMemory( hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead );
  17. }
  18. }
  19. BOOL
  20. WINAPI
  21. WriteProcessMem(
  22. HANDLE hProcess,
  23. LPVOID lpBaseAddress,
  24. LPVOID lpBuffer,
  25. DWORD nSize,
  26. LPDWORD lpNumberOfBytesWritten
  27. )
  28. {
  29. if ( fWinDbg ) {
  30. return (*WriteProcessMemWinDbg)( (DWORD)lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten );
  31. } else {
  32. return WriteProcessMemory( hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten );
  33. }
  34. }
  35. #ifndef i386
  36. ULONG
  37. GetRegValue(
  38. NT_CPU_REG reg,
  39. BOOL bInNano,
  40. ULONG UMask
  41. )
  42. {
  43. if (bInNano) {
  44. return(ReadDword(reg.nano_reg));
  45. } else if (UMask & reg.universe_8bit_mask) {
  46. return (ReadDword(reg.saved_reg) & 0xFFFFFF00 |
  47. ReadDword(reg.reg) & 0xFF);
  48. } else if (UMask & reg.universe_16bit_mask) {
  49. return (ReadDword(reg.saved_reg) & 0xFFFF0000 |
  50. ReadDword(reg.reg) & 0xFFFF);
  51. } else {
  52. return (ReadDword(reg.reg));
  53. }
  54. }
  55. ULONG
  56. GetEspValue(
  57. NT_CPU_INFO nt_cpu_info,
  58. BOOL bInNano
  59. )
  60. {
  61. if (bInNano) {
  62. return (ReadDword(nt_cpu_info.nano_esp));
  63. } else {
  64. if (ReadDword(nt_cpu_info.stack_is_big)) {
  65. return (ReadDword(nt_cpu_info.host_sp) -
  66. ReadDword(nt_cpu_info.ss_base));
  67. } else {
  68. return (ReadDword(nt_cpu_info.esp_sanctuary) & 0xFFFF0000 |
  69. (ReadDword(nt_cpu_info.host_sp) -
  70. ReadDword(nt_cpu_info.ss_base) & 0xFFFF));
  71. }
  72. }
  73. }
  74. #endif
  75. int
  76. GetContext(
  77. VDMCONTEXT* lpContext
  78. ) {
  79. #ifndef i386 //
  80. int mode;
  81. ULONG pTmp;
  82. NT_CPU_INFO nt_cpu_info;
  83. BOOL b;
  84. BOOL bInNano;
  85. ULONG UMask;
  86. pTmp = (ULONG)EXPRESSION("ntvdm!nt_cpu_info");
  87. if ( pTmp ) {
  88. b = ReadProcessMem( hCurrentProcess,
  89. (LPVOID) pTmp,
  90. (LPVOID) &nt_cpu_info,
  91. sizeof(NT_CPU_INFO),
  92. NULL );
  93. if ( !b ) {
  94. PRINTF("Could not read IntelRegisters context out of process\n");
  95. return( -1 );
  96. }
  97. bInNano = ReadDword((ULONG) nt_cpu_info.in_nano_cpu);
  98. UMask = ReadDword((ULONG) nt_cpu_info.universe);
  99. lpContext->Eax = GetRegValue(nt_cpu_info.eax, bInNano, UMask);
  100. lpContext->Ecx = GetRegValue(nt_cpu_info.ecx, bInNano, UMask);
  101. lpContext->Edx = GetRegValue(nt_cpu_info.edx, bInNano, UMask);
  102. lpContext->Ebx = GetRegValue(nt_cpu_info.ebx, bInNano, UMask);
  103. lpContext->Ebp = GetRegValue(nt_cpu_info.ebp, bInNano, UMask);
  104. lpContext->Esi = GetRegValue(nt_cpu_info.esi, bInNano, UMask);
  105. lpContext->Edi = GetRegValue(nt_cpu_info.edi, bInNano, UMask);
  106. lpContext->Esp = GetEspValue(nt_cpu_info, bInNano);
  107. lpContext->EFlags = ReadDword(nt_cpu_info.flags);
  108. lpContext->Eip = ReadDword(nt_cpu_info.eip);
  109. lpContext->SegEs = ReadWord(nt_cpu_info.es);
  110. lpContext->SegCs = ReadWord(nt_cpu_info.cs);
  111. lpContext->SegSs = ReadWord(nt_cpu_info.ss);
  112. lpContext->SegDs = ReadWord(nt_cpu_info.ds);
  113. lpContext->SegFs = ReadWord(nt_cpu_info.fs);
  114. lpContext->SegGs = ReadWord(nt_cpu_info.gs);
  115. } else {
  116. PRINTF("Could not find the symbol 'ntvdm!nt_cpu_info'\n");
  117. return( -1 );
  118. }
  119. if ( !(ReadDword(nt_cpu_info.cr0) & 1) ) {
  120. mode = V86_MODE;
  121. } else {
  122. mode = PROT_MODE;
  123. }
  124. return( mode );
  125. #else //
  126. NTSTATUS rc;
  127. BOOL b;
  128. ULONG EFlags;
  129. WORD cs;
  130. int mode;
  131. ULONG lpVdmTib;
  132. lpContext->ContextFlags = CONTEXT_FULL;
  133. rc = NtGetContextThread( hCurrentThread,
  134. lpContext );
  135. if ( NT_ERROR(rc) ) {
  136. PRINTF( "bde.k: Could not get current threads context - status = %08lX\n", rc );
  137. return( -1 );
  138. }
  139. /*
  140. ** Get the 16-bit registers from the context
  141. */
  142. cs = (WORD)lpContext->SegCs;
  143. EFlags = lpContext->EFlags;
  144. if ( EFlags & V86_BITS ) {
  145. /*
  146. ** V86 Mode
  147. */
  148. mode = V86_MODE;
  149. } else {
  150. if ( (cs & RPL_MASK) != KGDT_R3_CODE ) {
  151. mode = PROT_MODE;
  152. } else {
  153. /*
  154. ** We are in flat 32-bit address space!
  155. */
  156. lpVdmTib = (ULONG)EXPRESSION("ntvdm!VdmTib");
  157. if ( !lpVdmTib ) {
  158. PRINTF("Could not find the symbol 'VdmTib'\n");
  159. return( -1 );
  160. }
  161. b = ReadProcessMem( hCurrentProcess,
  162. (LPVOID) (lpVdmTib +
  163. FIELD_OFFSET(VDM_TIB,VdmContext)),
  164. lpContext,
  165. sizeof(VDMCONTEXT),
  166. NULL );
  167. if ( !b ) {
  168. PRINTF("Could not read IntelRegisters context out of process\n");
  169. return( -1 );
  170. }
  171. EFlags = lpContext->EFlags;
  172. if ( EFlags & V86_BITS ) {
  173. mode = V86_MODE;
  174. } else {
  175. mode = PROT_MODE;
  176. }
  177. }
  178. }
  179. return( mode );
  180. #endif
  181. }
  182. ULONG
  183. GetIntelBase(
  184. VOID
  185. )
  186. {
  187. #ifndef i386
  188. ULONG IntelBase;
  189. BOOL b;
  190. IntelBase = (ULONG)EXPRESSION("ntvdm!Start_of_M_area");
  191. if ( IntelBase ) {
  192. b = ReadProcessMem( hCurrentProcess,
  193. (LPVOID) IntelBase, &IntelBase,
  194. sizeof(ULONG), NULL );
  195. if ( !b ) {
  196. PRINTF("Could not read symbol 'ntvdm!Start_of_M_area\n");
  197. return(0);
  198. }
  199. } else {
  200. PRINTF("Could not find the symbol 'ntvdm!Start_of_M_area'\n");
  201. }
  202. return(IntelBase);
  203. #else
  204. return(0);
  205. #endif
  206. }
  207. DWORD read_dword(
  208. ULONG lpAddress,
  209. BOOL bSafe
  210. ) {
  211. BOOL b;
  212. DWORD dword;
  213. b = ReadProcessMem(
  214. hCurrentProcess,
  215. (LPVOID)lpAddress,
  216. &dword,
  217. sizeof(dword),
  218. NULL
  219. );
  220. if ( !b ) {
  221. if ( !bSafe ) {
  222. PRINTF("Failure reading dword at memory location %08lX\n", lpAddress );
  223. }
  224. return( 0 );
  225. }
  226. return( dword );
  227. }
  228. WORD read_word(
  229. ULONG lpAddress,
  230. BOOL bSafe
  231. ) {
  232. BOOL b;
  233. WORD word;
  234. b = ReadProcessMem(
  235. hCurrentProcess,
  236. (LPVOID)lpAddress,
  237. &word,
  238. sizeof(word),
  239. NULL
  240. );
  241. if ( !b ) {
  242. if ( !bSafe ) {
  243. PRINTF("Failure reading word at memory location %08lX\n", lpAddress );
  244. }
  245. return( 0 );
  246. }
  247. return( word );
  248. }
  249. BYTE read_byte(
  250. ULONG lpAddress,
  251. BOOL bSafe
  252. ) {
  253. BOOL b;
  254. BYTE byte;
  255. b = ReadProcessMem(
  256. hCurrentProcess,
  257. (LPVOID)lpAddress,
  258. &byte,
  259. sizeof(byte),
  260. NULL
  261. );
  262. if ( !b ) {
  263. if ( !bSafe ) {
  264. PRINTF("Failure reading byte at memory location %08lX\n", lpAddress );
  265. }
  266. return( 0 );
  267. }
  268. return( byte );
  269. }
  270. BOOL read_gnode(
  271. ULONG lpAddress,
  272. PGNODE p,
  273. BOOL bSafe
  274. ) {
  275. BOOL b;
  276. b = ReadProcessMem(
  277. hCurrentProcess,
  278. (LPVOID)lpAddress,
  279. p,
  280. sizeof(*p),
  281. NULL
  282. );
  283. if ( !b ) {
  284. if ( !bSafe ) {
  285. PRINTF("Failure reading word at memory location %08lX\n", lpAddress );
  286. }
  287. return( 0 );
  288. }
  289. return( TRUE );
  290. }
  291. BOOL read_gnode32(
  292. ULONG lpAddress,
  293. PGNODE32 p,
  294. BOOL bSafe
  295. ) {
  296. BOOL b;
  297. b = ReadProcessMem(
  298. hCurrentProcess,
  299. (LPVOID)lpAddress,
  300. p,
  301. sizeof(*p),
  302. NULL
  303. );
  304. if ( !b ) {
  305. if ( !bSafe ) {
  306. PRINTF("Failure reading word at memory location %08lX\n", lpAddress );
  307. }
  308. return( 0 );
  309. }
  310. return( TRUE );
  311. }
  312. BOOL GetDescriptorData(
  313. WORD selector,
  314. LPVDMLDT_ENTRY pdte
  315. )
  316. {
  317. #ifdef i386
  318. NTSTATUS rc;
  319. DESCRIPTOR_TABLE_ENTRY dte;
  320. dte.Selector = selector;
  321. rc = NtQueryInformationThread( hCurrentThread,
  322. ThreadDescriptorTableEntry,
  323. &dte,
  324. sizeof(DESCRIPTOR_TABLE_ENTRY),
  325. NULL );
  326. if ( NT_ERROR(rc) ) {
  327. return( FALSE );
  328. }
  329. pdte->HighWord = dte.Descriptor.HighWord;
  330. pdte->BaseLow = dte.Descriptor.BaseLow;
  331. pdte->LimitLow = dte.Descriptor.LimitLow;
  332. return (TRUE);
  333. #else
  334. PVOID LdtAddress;
  335. NTSTATUS Status;
  336. ULONG BytesRead;
  337. selector &= ~(SELECTOR_LDT | SELECTOR_RPL);
  338. //
  339. // Get address of Ldt
  340. //
  341. LdtAddress = (PVOID)EXPRESSION("ntvdm!Ldt");
  342. Status = ReadProcessMem(
  343. hCurrentProcess,
  344. LdtAddress,
  345. &LdtAddress,
  346. sizeof(ULONG),
  347. &BytesRead
  348. );
  349. if ((!Status) || (BytesRead != sizeof(ULONG))) {
  350. return FALSE;
  351. }
  352. (PUCHAR)LdtAddress += selector;
  353. Status = ReadProcessMem(
  354. hCurrentProcess,
  355. LdtAddress,
  356. pdte,
  357. sizeof(VDMLDT_ENTRY),
  358. &BytesRead
  359. );
  360. return TRUE;
  361. #endif
  362. }
  363. ULONG GetInfoFromSelector(
  364. WORD selector,
  365. int mode,
  366. SELECTORINFO *si
  367. ) {
  368. ULONG base;
  369. ULONG type;
  370. #ifdef i386
  371. BYTE byte;
  372. BOOL b;
  373. #endif
  374. VDMLDT_ENTRY dte;
  375. switch( mode ) {
  376. case V86_MODE:
  377. base = (ULONG)selector << 4;
  378. if ( si ) {
  379. si->Limit = 0xFFFFL;
  380. si->bCode = FALSE;
  381. }
  382. break;
  383. case PROT_MODE:
  384. #ifdef i386
  385. if ( (selector & 0xFF78) < KGDT_LDT ) {
  386. return( (ULONG)-1 );
  387. }
  388. #endif
  389. if ( !GetDescriptorData(selector, &dte) ) {
  390. return( (ULONG)-1 );
  391. }
  392. base = ((ULONG)dte.HighWord.Bytes.BaseHi << 24)
  393. + ((ULONG)dte.HighWord.Bytes.BaseMid << 16)
  394. + ((ULONG)dte.BaseLow);
  395. if ( si ) {
  396. si->Limit = (ULONG)dte.LimitLow
  397. + ((ULONG)dte.HighWord.Bits.LimitHi << 16);
  398. if ( dte.HighWord.Bits.Granularity ) {
  399. si->Limit <<= 12;
  400. si->Limit += 0xFFF;
  401. }
  402. si->Base = base;
  403. type = dte.HighWord.Bits.Type;
  404. si->bSystem = !(BOOL) (type & 0x10);
  405. if (!si->bSystem) {
  406. si->bCode = (BOOL) (type & 8);
  407. }
  408. si->bAccessed = (BOOL) (type & 1);
  409. si->bWrite = (BOOL) (type & 2);
  410. if (si->bCode) {
  411. si->bWrite = !si->bWrite;
  412. }
  413. si->bPresent = (BOOL) dte.HighWord.Bits.Pres;
  414. si->bBig = (BOOL) dte.HighWord.Bits.Default_Big;
  415. }
  416. if ( base == 0 ) {
  417. return( (ULONG)-1 );
  418. }
  419. #ifdef i386
  420. b = ReadProcessMem(
  421. hCurrentProcess,
  422. (LPVOID)base,
  423. &byte,
  424. sizeof(byte),
  425. NULL
  426. );
  427. if ( !b ) {
  428. return( (ULONG)-1 );
  429. }
  430. #endif
  431. break;
  432. case FLAT_MODE:
  433. PRINTF("Unsupported determination of base address in flat mode\n");
  434. base = 0;
  435. break;
  436. }
  437. return( base );
  438. }
  439. //****************************************************************************
  440. //
  441. // Command line parsing routines
  442. //
  443. //****************************************************************************
  444. BOOL
  445. SkipToNextWhiteSpace(
  446. VOID
  447. )
  448. {
  449. char ch;
  450. while ( (ch = *lpArgumentString) != '\0' ) {
  451. if ( ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' ) {
  452. return TRUE;
  453. }
  454. lpArgumentString++;
  455. }
  456. return FALSE;
  457. }
  458. BOOL
  459. GetNextToken(
  460. VOID
  461. )
  462. {
  463. char ch;
  464. while ( (ch = *lpArgumentString) != '\0' ) {
  465. if ( ch != ' ' && ch != '\t' && ch != '\r' && ch != '\n' ) {
  466. return TRUE;
  467. }
  468. lpArgumentString++;
  469. }
  470. return FALSE;
  471. }
  472. BOOL
  473. ParseIntelAddress(
  474. int *pMode,
  475. WORD *pSelector,
  476. PULONG pOffset
  477. )
  478. {
  479. char sel_text[128], off_text[128];
  480. char *colon;
  481. char *mode_prefix;
  482. colon = strchr( lpArgumentString, ':' );
  483. if ( colon == NULL ) {
  484. PRINTF("Please specify an address in the form 'seg:offset'\n");
  485. return FALSE;
  486. }
  487. mode_prefix = strchr( lpArgumentString, '&' );
  488. if ( mode_prefix == NULL ) {
  489. mode_prefix = strchr( lpArgumentString, '#' );
  490. if ( mode_prefix != NULL ) {
  491. if ( mode_prefix != lpArgumentString ) {
  492. PRINTF("Address must have '&' symbol as the first character\n");
  493. return FALSE;
  494. }
  495. *pMode = PROT_MODE;
  496. lpArgumentString = mode_prefix+1;
  497. }
  498. } else {
  499. if ( mode_prefix != lpArgumentString ) {
  500. PRINTF("Address must have '#' symbol as the first character\n");
  501. return FALSE;
  502. }
  503. *pMode = V86_MODE;
  504. lpArgumentString = mode_prefix+1;
  505. }
  506. *colon = '\0';
  507. strcpy( sel_text, lpArgumentString );
  508. *colon = ':';
  509. strcpy( off_text, colon+1 );
  510. *pSelector = (WORD) EXPRESSION( sel_text );
  511. *pOffset = (ULONG) EXPRESSION( off_text );
  512. SkipToNextWhiteSpace();
  513. return TRUE;
  514. }