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.

525 lines
12 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: oledbg.cxx
  7. //
  8. // Contents: OLE debugger extention DLL
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 8-05-94 kevinro Created
  15. //
  16. //----------------------------------------------------------------------------
  17. extern "C" {
  18. #undef DBG
  19. #define DBG 1
  20. #include <nt.h>
  21. #include <ntrtl.h>
  22. #include <nturtl.h>
  23. }
  24. #include <windows.h>
  25. #include <rpc.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <ctype.h>
  30. #include <oledbg.h>
  31. #pragma hdrstop
  32. PNTSD_EXTENSION_APIS pExtApis;
  33. HANDLE hDbgThread;
  34. HANDLE hDbgProcess;
  35. //
  36. char achTokenBuf[1024];
  37. char *pszTokenNext = NULL;
  38. char *pszToken = NULL;
  39. void InitTokenStr(LPSTR lpszString)
  40. {
  41. if (lpszString)
  42. {
  43. strcpy(achTokenBuf,lpszString);
  44. }
  45. else
  46. {
  47. achTokenBuf[0]=0;
  48. }
  49. pszTokenNext = achTokenBuf;
  50. pszToken = NULL;
  51. }
  52. char *NextToken()
  53. {
  54. return(NULL);
  55. }
  56. //+---------------------------------------------------------------------------
  57. //
  58. // Function: ReadMemory
  59. //
  60. // Synopsis: Reads memory from the debuggee
  61. //
  62. // Effects:
  63. //
  64. // Arguments: [pvAddress] --
  65. // [cbMemory] --
  66. // [pvLocalMemory] --
  67. //
  68. // Requires:
  69. //
  70. // Returns:
  71. //
  72. // Signals:
  73. //
  74. // Modifies:
  75. //
  76. // Algorithm:
  77. //
  78. // History: 8-05-94 kevinro Created
  79. //
  80. // Notes:
  81. //
  82. //----------------------------------------------------------------------------
  83. DWORD
  84. ReadMemory( PVOID pvAddress,
  85. ULONG cbMemory,
  86. PVOID pvLocalMemory)
  87. {
  88. ULONG cbActual = cbMemory;
  89. if (ReadProcessMemory(hDbgProcess, pvAddress, pvLocalMemory, cbMemory, &cbActual))
  90. {
  91. if (cbActual != cbMemory)
  92. {
  93. return((DWORD)-1);
  94. }
  95. return(0);
  96. }
  97. return(GetLastError());
  98. }
  99. //+---------------------------------------------------------------------------
  100. //
  101. // Function: WriteMemory
  102. //
  103. // Synopsis: Writes memory to the debuggee
  104. //
  105. // Effects:
  106. //
  107. // Arguments: [pvLocalMemory] --
  108. // [cbMemory] --
  109. // [pvAddress] --
  110. //
  111. // Requires:
  112. //
  113. // Returns:
  114. //
  115. // Signals:
  116. //
  117. // Modifies:
  118. //
  119. // Algorithm:
  120. //
  121. // History: 8-05-94 kevinro Created
  122. //
  123. // Notes:
  124. //
  125. //----------------------------------------------------------------------------
  126. DWORD
  127. WriteMemory(PVOID pvLocalMemory,
  128. ULONG cbMemory,
  129. PVOID pvAddress)
  130. {
  131. ULONG cbActual = cbMemory;
  132. if (WriteProcessMemory(hDbgProcess, pvAddress, pvLocalMemory, cbMemory, &cbActual))
  133. {
  134. if (cbActual != cbMemory)
  135. {
  136. return((DWORD)-1);
  137. }
  138. return(0);
  139. }
  140. return(GetLastError());
  141. }
  142. #define AllocHeap(x) RtlAllocateHeap(RtlProcessHeap(), 0, x)
  143. #define FreeHeap(x) RtlFreeHeap(RtlProcessHeap(), 0, x)
  144. DWORD
  145. GetTlsEntry(ULONG TlsValue,
  146. PVOID * ppvValue)
  147. {
  148. NTSTATUS Status;
  149. THREAD_BASIC_INFORMATION ThreadInfo;
  150. ULONG cbReturned;
  151. PVOID *Slot;
  152. PTEB Teb;
  153. Status = NtQueryInformationThread( hDbgThread,
  154. ThreadBasicInformation,
  155. &ThreadInfo,
  156. sizeof(ThreadInfo),
  157. &cbReturned);
  158. if (!NT_SUCCESS(Status))
  159. {
  160. return(Status);
  161. }
  162. Teb = (PTEB) AllocHeap(sizeof(TEB));
  163. ReadMemory(ThreadInfo.TebBaseAddress, sizeof(TEB), Teb);
  164. Slot = &Teb->TlsSlots[TlsValue];
  165. *ppvValue = *Slot;
  166. FreeHeap(Teb);
  167. return(0);
  168. }
  169. void ShowBinaryData(PBYTE pData,
  170. DWORD cbData)
  171. {
  172. DWORD i;
  173. char line[20];
  174. PNTSD_EXTENSION_APIS lpExt = pExtApis;
  175. line[16] = '\0';
  176. if (cbData > 65536)
  177. {
  178. ntsdPrintf("ShowBinaryData: Data @%x is said to be %d bytes in length\n");
  179. ntsdPrintf(" Rejecting request. Corrupt data\n");
  180. return;
  181. }
  182. for (; cbData > 0 ; )
  183. {
  184. for (i = 0; i < 16 && cbData > 0 ; i++, cbData-- )
  185. {
  186. ntsdPrintf(" %02x", (unsigned) *pData);
  187. if (isprint(*pData))
  188. line[i] = *pData;
  189. else
  190. line[i] = '.';
  191. pData++;
  192. }
  193. if (i < 16)
  194. {
  195. for (;i < 16 ; i++ )
  196. {
  197. ntsdPrintf(" ");
  198. line[i] = ' ';
  199. }
  200. }
  201. ntsdPrintf("\t%s\n",line);
  202. if (lpExt->lpCheckControlCRoutine())
  203. {
  204. break;
  205. }
  206. }
  207. }
  208. BOOL
  209. IsDebug_olethk32()
  210. {
  211. ULONG addr;
  212. DWORD dwValue;
  213. addr = ntsdGetExpr("olethk32!oledbgCheck_olethk32");
  214. if (addr == 0)
  215. {
  216. ntsdPrintf("warning: olethk32 not debug version\n");
  217. return(0);
  218. }
  219. if (ReadMemory((LPVOID)addr,sizeof(dwValue),(PVOID)&dwValue))
  220. {
  221. ntsdPrintf("warning: could not read check value at %x\n",addr);
  222. return(0);
  223. }
  224. if (dwValue != 0x12345678)
  225. {
  226. ntsdPrintf("warning: olethk32!oledbgCheck_olethk32 value wrong\n");
  227. ntsdPrintf("warning: suspect wrong symbols for olethk32\n");
  228. return(0);
  229. }
  230. return(1);
  231. }
  232. BOOL
  233. IsDebug_ole32()
  234. {
  235. ULONG addr;
  236. DWORD dwValue;
  237. addr = ntsdGetExpr("ole32!oledbgCheck_ole32");
  238. if (addr == 0)
  239. {
  240. ntsdPrintf("warning: ole32 not debug version\n");
  241. return(0);
  242. }
  243. if (ReadMemory((LPVOID)addr,sizeof(dwValue),(PVOID)&dwValue))
  244. {
  245. ntsdPrintf("warning: could not read check value at %x\n",addr);
  246. return(0);
  247. }
  248. if (dwValue != 0x12345678)
  249. {
  250. ntsdPrintf("warning: olethk32!oledbgCheck_ole32 value wrong\n");
  251. ntsdPrintf("warning: suspect wrong symbols for ole32\n");
  252. return(0);
  253. }
  254. return(1);
  255. }
  256. //+---------------------------------------------------------------------------
  257. //
  258. // Function: DumpVtbl
  259. //
  260. // Synopsis: Dumps a vtbl to the debugger
  261. //
  262. // Effects: Given a pointer to a vtbl, output the name of the vtbl, and
  263. // its contents to the debugger.
  264. //
  265. // Arguments: [pvtbl] -- Address of vtbl
  266. // [pszCommand] -- Symbolic expression for pvtbl
  267. //
  268. // History: 8-07-94 kevinro Created
  269. //
  270. //----------------------------------------------------------------------------
  271. extern "C"
  272. void
  273. DumpVtbl(PVOID pvtbl, LPSTR pszCommand)
  274. {
  275. DWORD dwVtblOffset;
  276. char achNextSymbol[256];
  277. if (pvtbl == 0)
  278. {
  279. // Can't handle objects at zero
  280. ntsdPrintf("%s has a vtbl pointer of NULL\n",pszCommand);
  281. return;
  282. }
  283. if ((DWORD)pvtbl == 0xdededede)
  284. {
  285. // Can't handle objects at zero
  286. ntsdPrintf("%s may be deleted memory. pvtbl==0xdededede\n",pszCommand);
  287. return;
  288. }
  289. // This value points at the VTBL. Find a symbol for the VTBL
  290. ntsdGetSymbol((LPVOID)pvtbl,(UCHAR *)achNextSymbol,(LPDWORD)&dwVtblOffset);
  291. // If the dwVtblOffset is not zero, then we are pointing into the table.
  292. // This could mean multiple inheritance. We could be tricky, and try to
  293. // determine the vtbl by backing up here. Maybe later
  294. if (dwVtblOffset != 0)
  295. {
  296. ntsdPrintf("Closest Previous symbol is %s at 0x%x (offset -0x%x)\n",
  297. achNextSymbol,
  298. (DWORD)pvtbl - dwVtblOffset,
  299. dwVtblOffset);
  300. return;
  301. }
  302. ntsdPrintf("0x%08x -->\t %s\n",pvtbl,achNextSymbol);
  303. // vtbl entries should always point at functions. Therefore, we should
  304. // always have a displacement of zero. To check for the end of the table
  305. // we will reevaluate the vtbl pointer. If the offset isn't what we
  306. // expected, then we are done.
  307. DWORD dwIndex;
  308. for (dwIndex = 0 ; dwIndex < 4096 ; dwIndex += 4)
  309. {
  310. DWORD dwVtblEntry;
  311. ntsdGetSymbol((LPVOID)((DWORD)pvtbl+dwIndex),
  312. (UCHAR *)achNextSymbol,
  313. (LPDWORD)&dwVtblOffset);
  314. if (dwVtblOffset != dwIndex)
  315. {
  316. //
  317. // May have moved on to another vtable
  318. //
  319. #ifdef DBG_OLEDBG
  320. ntsdPrintf("?? %s + %x\n",achNextSymbol,dwVtblOffset);
  321. ntsdPrintf("Moved to another table?\n");
  322. #endif
  323. return;
  324. }
  325. if (ReadMemory((LPVOID)((DWORD)pvtbl+dwIndex),
  326. sizeof(dwVtblEntry),
  327. (PVOID)&dwVtblEntry))
  328. {
  329. //
  330. // Must be off the end of a page or something.
  331. //
  332. #ifdef DBG_OLEDBG
  333. ntsdPrintf("End of page?\n");
  334. #endif
  335. return;
  336. }
  337. // If the function is at zero, then must be at end of table
  338. if (dwVtblEntry == 0)
  339. {
  340. #ifdef DBG_OLEDBG
  341. ntsdPrintf("dwVtblEntry is zero. Must be end of table\n");
  342. return;
  343. #endif
  344. }
  345. // Now, determine the symbol for the entry in the vtbl
  346. ntsdGetSymbol((LPVOID)dwVtblEntry,
  347. (UCHAR *)achNextSymbol,
  348. (LPDWORD)&dwVtblOffset);
  349. // If it doesn't point to the start of a routine, then it
  350. // probably isn't part of the vtbl
  351. if (dwVtblOffset != 0)
  352. {
  353. #ifdef DBG_OLEDBG
  354. ntsdPrintf("?? %s + %x\n",achNextSymbol,dwVtblOffset);
  355. ntsdPrintf("Doesn't point to function?\n");
  356. #endif
  357. return;
  358. }
  359. ntsdPrintf(" 0x%08x\t %s\n",dwVtblEntry,achNextSymbol);
  360. }
  361. ntsdPrintf("Wow, there were at least 1024 entries in the table!\n");
  362. }
  363. extern "C"
  364. void
  365. punk( HANDLE hProcess,
  366. HANDLE hThread,
  367. DWORD dwCurrentPc,
  368. PNTSD_EXTENSION_APIS lpExt,
  369. LPSTR pszCommand)
  370. {
  371. PVOID punk;
  372. PVOID pvtbl;
  373. InitDebugHelp(hProcess, hThread, lpExt);
  374. // Evalute the first pointer. This is a pointer to the object
  375. punk = (PVOID) ntsdGetExpr(pszCommand);
  376. if (punk == NULL)
  377. {
  378. // Can't handle objects at zero
  379. ntsdPrintf("%s is not a valid pointer\n",pszCommand);
  380. return;
  381. }
  382. // Now, read the first DWORD of this memory location
  383. // This is a pointer to the table
  384. if (ReadMemory(punk,sizeof(pvtbl),(PVOID)&pvtbl))
  385. {
  386. ntsdPrintf("Couldn't read memory at %x\n",punk);
  387. return;
  388. }
  389. DumpVtbl(pvtbl,pszCommand);
  390. }
  391. extern "C"
  392. void
  393. vtbl( HANDLE hProcess,
  394. HANDLE hThread,
  395. DWORD dwCurrentPc,
  396. PNTSD_EXTENSION_APIS lpExt,
  397. LPSTR pszCommand)
  398. {
  399. PVOID pvtbl;
  400. InitDebugHelp(hProcess, hThread, lpExt);
  401. // Evalute the first pointer. This is a pointer to the table
  402. pvtbl = (PVOID) ntsdGetExpr(pszCommand);
  403. DumpVtbl(pvtbl,pszCommand);
  404. }
  405. extern "C"
  406. void
  407. expr( HANDLE hProcess,
  408. HANDLE hThread,
  409. DWORD dwCurrentPc,
  410. PNTSD_EXTENSION_APIS lpExt,
  411. LPSTR pszCommand)
  412. {
  413. InitDebugHelp(hProcess, hThread, lpExt);
  414. UCHAR symbol[256];
  415. DWORD expr;
  416. DWORD disp;
  417. expr = ntsdGetExpr(pszCommand);
  418. ntsdGetSymbol((LPVOID)expr,(UCHAR *)symbol,(LPDWORD)&disp);
  419. ntsdPrintf("expr: %s = %x (%d) %s + %d\n",pszCommand,expr,expr,symbol,disp);
  420. }
  421. extern "C"
  422. void
  423. isdbg( HANDLE hProcess,
  424. HANDLE hThread,
  425. DWORD dwCurrentPc,
  426. PNTSD_EXTENSION_APIS lpExt,
  427. LPSTR pszCommand)
  428. {
  429. InitDebugHelp(hProcess, hThread, lpExt);
  430. if (IsDebug_ole32())
  431. {
  432. ntsdPrintf("ole32.dll is debug\n");
  433. }
  434. if (IsDebug_olethk32())
  435. {
  436. ntsdPrintf("olethk32.dll is debug\n");
  437. }
  438. }
  439. extern "C"
  440. void
  441. help( HANDLE hProcess,
  442. HANDLE hThread,
  443. DWORD dwCurrentPc,
  444. PNTSD_EXTENSION_APIS lpExt,
  445. LPSTR pszCommand)
  446. {
  447. InitDebugHelp(hProcess, hThread, lpExt);
  448. ntsdPrintf(" help \tThis Message\n");
  449. ntsdPrintf(" isdbg \tDetermine if DLL's are debug\n");
  450. ntsdPrintf(" punk <expr> \tDump IUnknown vtbl\n");
  451. ntsdPrintf(" vtbl <expr> \tDump vtbl\n");
  452. }