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.

472 lines
15 KiB

  1. #include <windows.h>
  2. #include <malloc.h>
  3. #include <stddef.h>
  4. #include <process.h>
  5. #define _DBDBG32_
  6. #include "dbwin32.h"
  7. ProcessList::ProcessList() : GrowableList(sizeof(ProcessInfo))
  8. {
  9. }
  10. ProcessList::~ProcessList()
  11. {
  12. }
  13. BOOL ProcessList::IsEqual(void *pv1, void *pv2)
  14. {
  15. return(!memcmp(pv1, pv2, sizeof(DWORD)));
  16. }
  17. ThreadList::ThreadList() : GrowableList(sizeof(ThreadInfo))
  18. {
  19. }
  20. ThreadList::~ThreadList()
  21. {
  22. }
  23. BOOL ThreadList::IsEqual(void *pv1, void *pv2)
  24. {
  25. return(!memcmp(pv1, pv2, sizeof(ThreadInfo)));
  26. }
  27. DllList::DllList() : GrowableList(sizeof(DllInfo))
  28. {
  29. }
  30. DllList::~DllList()
  31. {
  32. }
  33. BOOL DllList::IsEqual(void *pv1, void *pv2)
  34. {
  35. return(!memcmp(pv1, pv2, (sizeof(DWORD) + sizeof(LPVOID))));
  36. }
  37. void __cdecl AttachThread(void *pv)
  38. {
  39. AttachInfo *pai = (AttachInfo *)pv;
  40. if (DebugActiveProcess(pai->dwProcess))
  41. DebugThread(pai->hwndFrame, pai->dwProcess);
  42. else
  43. {
  44. MessageBeep(MB_ICONEXCLAMATION);
  45. MessageBox(pai->hwndFrame, "Unable to attach to process.", "DbWin32",
  46. MB_ICONEXCLAMATION | MB_OK);
  47. }
  48. delete pai;
  49. }
  50. void __cdecl ExecThread(void *pv)
  51. {
  52. ExecInfo *pei = (ExecInfo *)pv;
  53. STARTUPINFO si;
  54. PROCESS_INFORMATION pi;
  55. memset(&si, 0, sizeof(STARTUPINFO));
  56. si.cb = sizeof(STARTUPINFO);
  57. si.wShowWindow = SW_SHOWDEFAULT;
  58. pi.hProcess = NULL;
  59. if (CreateProcess(NULL, pei->lpszCommandLine, NULL, NULL, TRUE,
  60. DEBUG_PROCESS | CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
  61. {
  62. CloseHandle(pi.hProcess);
  63. CloseHandle(pi.hThread);
  64. DebugThread(pei->hwndFrame, pi.dwProcessId);
  65. }
  66. else
  67. {
  68. MessageBeep(MB_ICONEXCLAMATION);
  69. MessageBox(pei->hwndFrame, "Unable to execute process.", "DbWin32",
  70. MB_ICONEXCLAMATION | MB_OK);
  71. }
  72. free((void *)(pei->lpszCommandLine));
  73. delete pei;
  74. }
  75. void __cdecl SystemThread(void *pv)
  76. {
  77. BOOL fFailed = TRUE;
  78. DWORD dwRet;
  79. HANDLE hevtBuffer = NULL, hevtData = NULL;
  80. HANDLE hfileShared = NULL;
  81. HWND hwndFrame = (HWND)pv;
  82. LPVOID lpvBuffer = NULL;
  83. LPSTR lpszText = NULL;
  84. DEBUG_EVENT DebugEvent;
  85. hevtBuffer = CreateEvent(NULL, FALSE, FALSE, "DBWIN_BUFFER_READY");
  86. if (hevtBuffer)
  87. hevtData = CreateEvent(NULL, FALSE, FALSE, "DBWIN_DATA_READY");
  88. if (hevtBuffer && hevtData)
  89. hfileShared = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE, 0,
  90. 4096, "DBWIN_BUFFER");
  91. if (hevtBuffer && hevtData && hfileShared)
  92. lpvBuffer = MapViewOfFile(hfileShared, FILE_MAP_READ, 0, 0, 512);
  93. if (hevtBuffer && hevtData && hfileShared && lpvBuffer)
  94. {
  95. fFailed = FALSE;
  96. lpszText = (LPSTR)lpvBuffer + sizeof(DWORD);
  97. DebugEvent.dwDebugEventCode = OUTPUT_DEBUG_STRING_EVENT;
  98. DebugEvent.dwProcessId = DebugEvent.dwThreadId = 0;
  99. SetEvent(hevtBuffer);
  100. }
  101. else
  102. {
  103. MessageBeep(MB_ICONEXCLAMATION);
  104. MessageBox(hwndFrame, "Unable to open System Window.", "DbWin32",
  105. MB_ICONEXCLAMATION | MB_OK);
  106. }
  107. while (!fFailed)
  108. {
  109. dwRet = WaitForSingleObject(hevtData, INFINITE);
  110. if (dwRet != WAIT_OBJECT_0)
  111. {
  112. SendText(hwndFrame, &DebugEvent, 0,
  113. "-------- DbWin32 ERROR! --------\r\n",
  114. DBO_OUTPUTDEBUGSTRING);
  115. SendText(hwndFrame, &DebugEvent, 0,
  116. "-------- Shutting down System Window --------\r\n",
  117. DBO_OUTPUTDEBUGSTRING);
  118. fFailed = TRUE;
  119. }
  120. else
  121. {
  122. SendText(hwndFrame, &DebugEvent, 0, lpszText,
  123. DBO_OUTPUTDEBUGSTRING);
  124. SetEvent(hevtBuffer);
  125. }
  126. }
  127. if (hfileShared)
  128. CloseHandle(hfileShared);
  129. if (hevtData)
  130. CloseHandle(hevtData);
  131. if (hevtBuffer)
  132. CloseHandle(hevtBuffer);
  133. }
  134. void __cdecl DebugThread(HWND hwndFrame, DWORD dwProcess)
  135. {
  136. char DisplayBuffer[BUF_SIZE];
  137. WORD wEvent;
  138. DWORD dwContinue;
  139. SIZE_T dwRead;
  140. ProcessList pl;
  141. ProcessInfo pi;
  142. ThreadList tl;
  143. ThreadInfo ti;
  144. DllList dl;
  145. DllInfo di;
  146. int iItem;
  147. BOOL fDone = FALSE;
  148. DEBUG_EVENT DebugEvent;
  149. EXCEPTION_DEBUG_INFO *pException = &DebugEvent.u.Exception;
  150. CREATE_THREAD_DEBUG_INFO *pCreateThread = &DebugEvent.u.CreateThread;
  151. CREATE_PROCESS_DEBUG_INFO *pCreateProcessInfo = &DebugEvent.u.CreateProcessInfo;
  152. EXIT_THREAD_DEBUG_INFO *pExitThread = &DebugEvent.u.ExitThread;
  153. EXIT_PROCESS_DEBUG_INFO *pExitProcess = &DebugEvent.u.ExitProcess;
  154. LOAD_DLL_DEBUG_INFO *pLoadDll = &DebugEvent.u.LoadDll;
  155. UNLOAD_DLL_DEBUG_INFO *pUnloadDll = &DebugEvent.u.UnloadDll;
  156. OUTPUT_DEBUG_STRING_INFO *pDebugString = &DebugEvent.u.DebugString;
  157. RIP_INFO *pRipInfo = &DebugEvent.u.RipInfo;
  158. while (!fDone && WaitForDebugEvent(&DebugEvent, INFINITE))
  159. {
  160. *DisplayBuffer = '\0';
  161. dwContinue = DBG_CONTINUE;
  162. switch (DebugEvent.dwDebugEventCode)
  163. {
  164. case EXCEPTION_DEBUG_EVENT:
  165. ProcessExceptionEvent(pException, DisplayBuffer);
  166. if (pException->ExceptionRecord.ExceptionCode !=
  167. EXCEPTION_BREAKPOINT)
  168. {
  169. dwContinue = DBG_EXCEPTION_NOT_HANDLED;
  170. }
  171. wEvent = DBO_EXCEPTIONS;
  172. break;
  173. case CREATE_THREAD_DEBUG_EVENT:
  174. ti.dwProcess = DebugEvent.dwProcessId;
  175. ti.dwThread = DebugEvent.dwThreadId;
  176. tl.InsertItem(&ti);
  177. wsprintf(DisplayBuffer, "Create Thread: PID 0x%X - TID 0x%X\r\n",
  178. ti.dwProcess, ti.dwThread);
  179. wEvent = DBO_THREADCREATE;
  180. break;
  181. case CREATE_PROCESS_DEBUG_EVENT:
  182. ti.dwProcess = pi.dwProcess = DebugEvent.dwProcessId;
  183. ti.dwThread = DebugEvent.dwThreadId;
  184. tl.InsertItem(&ti);
  185. pi.hProcess = pCreateProcessInfo->hProcess;
  186. GetModuleName(pCreateProcessInfo->hFile, pi.hProcess,
  187. (DWORD_PTR)pCreateProcessInfo->lpBaseOfImage, pi.rgchModule);
  188. pl.InsertItem(&pi);
  189. wsprintf(DisplayBuffer, "Create Process: PID 0x%X - %s\r\n",
  190. pi.dwProcess, pi.rgchModule);
  191. wEvent = DBO_PROCESSCREATE;
  192. break;
  193. case EXIT_THREAD_DEBUG_EVENT:
  194. ti.dwProcess = DebugEvent.dwProcessId;
  195. ti.dwThread = DebugEvent.dwThreadId;
  196. tl.RemoveItem(&ti);
  197. wsprintf(DisplayBuffer, "Exit Thread: PID 0x%X - TID 0x%X - dwReturnCode %d\r\n",
  198. ti.dwProcess, ti.dwThread, pExitThread->dwExitCode);
  199. wEvent = DBO_THREADEXIT;
  200. break;
  201. case EXIT_PROCESS_DEBUG_EVENT:
  202. pi.dwProcess = DebugEvent.dwProcessId;
  203. if (pl.FindItem(&pi, &iItem))
  204. {
  205. pl.RemoveItem(iItem);
  206. }
  207. wsprintf(DisplayBuffer, "Exit Process: PID 0x%X - %s - dwReturnCode %d\r\n",
  208. pi.dwProcess, pi.rgchModule, pExitProcess->dwExitCode);
  209. if (pi.dwProcess == dwProcess)
  210. {
  211. fDone = TRUE;
  212. }
  213. wEvent = DBO_PROCESSEXIT;
  214. break;
  215. case LOAD_DLL_DEBUG_EVENT:
  216. di.dwProcess = pi.dwProcess = DebugEvent.dwProcessId;
  217. if (pl.FindItem(&pi))
  218. {
  219. di.lpBaseOfDll = pLoadDll->lpBaseOfDll;
  220. GetModuleName(pLoadDll->hFile, pi.hProcess, (DWORD_PTR)di.lpBaseOfDll,
  221. di.rgchModule);
  222. dl.InsertItem(&di);
  223. wsprintf(DisplayBuffer, "DLL Load: %s\r\n", di.rgchModule);
  224. wEvent = DBO_DLLLOAD;
  225. }
  226. break;
  227. case UNLOAD_DLL_DEBUG_EVENT:
  228. di.dwProcess = DebugEvent.dwProcessId;
  229. di.lpBaseOfDll = pUnloadDll->lpBaseOfDll;
  230. if (dl.FindItem(&di, &iItem))
  231. {
  232. dl.RemoveItem(iItem);
  233. }
  234. wsprintf(DisplayBuffer, "Dll Unload: %s\r\n", di.rgchModule);
  235. wEvent = DBO_DLLUNLOAD;
  236. break;
  237. case OUTPUT_DEBUG_STRING_EVENT:
  238. pi.dwProcess = DebugEvent.dwProcessId;
  239. if (!pl.FindItem(&pi) ||
  240. (!ReadProcessMemory(pi.hProcess,
  241. pDebugString->lpDebugStringData, DisplayBuffer,
  242. pDebugString->nDebugStringLength, &dwRead)))
  243. {
  244. dwRead = 0;
  245. }
  246. DisplayBuffer[dwRead] = '\0';
  247. wEvent = DBO_OUTPUTDEBUGSTRING;
  248. break;
  249. case RIP_EVENT:
  250. wsprintf(DisplayBuffer, "RIP: dwError %d - dwType %d\r\n",
  251. pRipInfo->dwError, pRipInfo->dwType);
  252. wEvent = DBO_RIP;
  253. break;
  254. // No events should reach here.
  255. default:
  256. wsprintf(DisplayBuffer, "Unknown Event: 0x%X\r\n",
  257. DebugEvent.dwDebugEventCode);
  258. wEvent = DBO_ALL;
  259. break;
  260. }
  261. if (*DisplayBuffer)
  262. SendText(hwndFrame, &DebugEvent, dwProcess, DisplayBuffer, wEvent);
  263. if (DebugEvent.dwDebugEventCode == EXIT_THREAD_DEBUG_EVENT)
  264. PostMessage(hwndFrame, WM_ENDTHREAD, (WPARAM)ti.dwThread,
  265. ti.dwProcess);
  266. if (DebugEvent.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
  267. {
  268. if (fDone)
  269. {
  270. for (iItem = tl.Count(); iItem > 0; iItem--)
  271. {
  272. tl.GetItem(iItem - 1, &ti);
  273. PostMessage(hwndFrame, WM_ENDTHREAD, (WPARAM)ti.dwThread, ti.dwProcess);
  274. }
  275. for (iItem = pl.Count(); iItem > 0; iItem--)
  276. {
  277. pl.GetItem(iItem - 1, &pi);
  278. PostMessage(hwndFrame, WM_ENDTHREAD, 0, pi.dwProcess);
  279. }
  280. }
  281. PostMessage(hwndFrame, WM_ENDTHREAD, 0, DebugEvent.dwProcessId);
  282. }
  283. ContinueDebugEvent(DebugEvent.dwProcessId, DebugEvent.dwThreadId, dwContinue);
  284. }
  285. }
  286. void SendText(HWND hwndFrame, DEBUG_EVENT *pDebugEvent, DWORD dwParentProcess,
  287. LPCSTR lpszText, WORD wEvent)
  288. {
  289. char rgchText[BUF_SIZE], *pch = rgchText;
  290. StringInfo *psi;
  291. psi = new StringInfo;
  292. // Niceify the text
  293. if (pDebugEvent->dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT)
  294. {
  295. psi->cLines = 0;
  296. while (*lpszText != '\0')
  297. {
  298. if ((*lpszText == 0x0d) || (*lpszText == 0x0a))
  299. {
  300. *pch++ = 0x0d;
  301. *pch++ = 0x0a;
  302. while ((*lpszText == 0x0d) || (*lpszText == 0x0a))
  303. lpszText++;
  304. psi->cLines++;
  305. }
  306. else
  307. {
  308. *pch++ = *lpszText++;
  309. }
  310. }
  311. *pch = '\0';
  312. psi->lpszText = _strdup(rgchText);
  313. }
  314. else
  315. {
  316. psi->cLines = 1;
  317. psi->lpszText = _strdup(lpszText);
  318. }
  319. psi->dwProcess = pDebugEvent->dwProcessId;
  320. psi->dwThread = pDebugEvent->dwThreadId;
  321. psi->dwParentProcess = dwParentProcess;
  322. PostMessage(hwndFrame, WM_SENDTEXT, wEvent, (LPARAM)psi);
  323. }
  324. void ProcessExceptionEvent(EXCEPTION_DEBUG_INFO *pException, LPSTR lpszBuf)
  325. {
  326. if (pException->dwFirstChance)
  327. strcpy(lpszBuf, "First");
  328. else
  329. strcpy(lpszBuf, "Second");
  330. strcat(lpszBuf, " chance exception: ");
  331. switch (pException->ExceptionRecord.ExceptionCode)
  332. {
  333. //--standard exceptions
  334. case EXCEPTION_ACCESS_VIOLATION:
  335. strcat(lpszBuf, "Access Violation");
  336. break;
  337. case EXCEPTION_DATATYPE_MISALIGNMENT:
  338. strcat(lpszBuf, "Datatype Misalignment");
  339. break;
  340. case EXCEPTION_BREAKPOINT:
  341. strcat(lpszBuf, "Breakpoint");
  342. break;
  343. case EXCEPTION_SINGLE_STEP:
  344. strcat(lpszBuf, "Single Step");
  345. break;
  346. case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
  347. strcat(lpszBuf, "Array Bound Exceeded");
  348. break;
  349. case EXCEPTION_FLT_DENORMAL_OPERAND:
  350. strcat(lpszBuf, "FP-Denormal Operand");
  351. break;
  352. case EXCEPTION_FLT_DIVIDE_BY_ZERO:
  353. strcat(lpszBuf, "FP-Divide By Zero");
  354. break;
  355. case EXCEPTION_FLT_INEXACT_RESULT:
  356. strcat(lpszBuf, "FP-Inexact Result");
  357. break;
  358. case EXCEPTION_FLT_INVALID_OPERATION:
  359. strcat(lpszBuf, "FP-Invalid Operation");
  360. break;
  361. case EXCEPTION_FLT_OVERFLOW:
  362. strcat(lpszBuf, "FP-Overflow");
  363. break;
  364. case EXCEPTION_FLT_STACK_CHECK:
  365. strcat(lpszBuf, "FP-Stack Check");
  366. break;
  367. case EXCEPTION_FLT_UNDERFLOW:
  368. strcat(lpszBuf, "FP-Underflow");
  369. break;
  370. case EXCEPTION_INT_DIVIDE_BY_ZERO:
  371. strcat(lpszBuf, "INT-Divide By Zero");
  372. break;
  373. case EXCEPTION_INT_OVERFLOW:
  374. strcat(lpszBuf, "INT-Overflow");
  375. break;
  376. case EXCEPTION_PRIV_INSTRUCTION:
  377. strcat(lpszBuf, "Privileged Instruction");
  378. break;
  379. case EXCEPTION_IN_PAGE_ERROR:
  380. strcat(lpszBuf, "In Page Error");
  381. break;
  382. //-- Debug exceptions
  383. case DBG_TERMINATE_THREAD:
  384. strcat(lpszBuf, "DBG-Terminate Thread");
  385. break;
  386. case DBG_TERMINATE_PROCESS:
  387. strcat(lpszBuf, "DBG-Terminate Process");
  388. break;
  389. case DBG_CONTROL_C:
  390. strcat(lpszBuf, "DBG-Control+C");
  391. break;
  392. case DBG_CONTROL_BREAK:
  393. strcat(lpszBuf, "DBG-Control+Break");
  394. break;
  395. //-- RPC exceptions (some)
  396. case RPC_S_UNKNOWN_IF:
  397. strcat(lpszBuf, "RPC-Unknown Interface");
  398. break;
  399. case RPC_S_SERVER_UNAVAILABLE:
  400. strcat(lpszBuf, "RPC-Server Unavailable");
  401. break;
  402. //-- VDM exceptions (minimal information)
  403. case EXCEPTION_VDM_EVENT: // see dbwin32.h for definition
  404. strcat(lpszBuf, "VDM");
  405. break;
  406. default:
  407. char rgchTmp[25];
  408. wsprintf(rgchTmp, "Unknown-[0x%X]", pException->ExceptionRecord.ExceptionCode);
  409. strcat(lpszBuf, rgchTmp);
  410. break;
  411. }
  412. strcat(lpszBuf, "\r\n");
  413. }
  414. #define IMAGE_SECOND_HEADER_OFFSET (15 * sizeof(ULONG))
  415. #define IMAGE_EXPORT_TABLE_RVA_OFFSET (30 * sizeof(DWORD))
  416. #define IMAGE_NAME_RVA_OFFSET offsetof(IMAGE_EXPORT_DIRECTORY, Name)
  417. void GetModuleName(HANDLE hFile, HANDLE hProcess, DWORD_PTR BaseOfImage, LPSTR lpszBuf)
  418. {
  419. DWORD dwRead = 0;
  420. WORD DosSignature;
  421. DWORD NtSignature, PeHeader, ExportTableRVA, NameRVA;
  422. strcpy(lpszBuf, "<unknown>");
  423. if (!hFile)
  424. return;
  425. if (GetFileType(hFile) != FILE_TYPE_DISK)
  426. return;
  427. SetFilePointer(hFile, 0L, NULL, FILE_BEGIN);
  428. if (!ReadFile(hFile, &DosSignature, sizeof(DosSignature), &dwRead, NULL))
  429. return;
  430. if (DosSignature != IMAGE_DOS_SIGNATURE)
  431. return;
  432. SetFilePointer(hFile, IMAGE_SECOND_HEADER_OFFSET, NULL, FILE_BEGIN);
  433. if (!ReadFile(hFile, &PeHeader, sizeof(PeHeader), &dwRead, NULL))
  434. return;
  435. SetFilePointer(hFile, PeHeader, NULL, FILE_BEGIN);
  436. if (!ReadFile(hFile, &NtSignature, sizeof(NtSignature), &dwRead, NULL))
  437. return;
  438. if (NtSignature != IMAGE_NT_SIGNATURE)
  439. return;
  440. SetFilePointer(hFile, PeHeader + IMAGE_EXPORT_TABLE_RVA_OFFSET, NULL, FILE_BEGIN);
  441. if (!ReadFile(hFile, &ExportTableRVA, sizeof(ExportTableRVA), &dwRead, NULL))
  442. return;
  443. if (!ExportTableRVA)
  444. return;
  445. ReadProcessMemory(hProcess, (LPVOID)(BaseOfImage + ExportTableRVA +
  446. IMAGE_NAME_RVA_OFFSET), &NameRVA, sizeof(NameRVA), NULL);
  447. ReadProcessMemory(hProcess, (LPVOID)(BaseOfImage + NameRVA), lpszBuf, MODULE_SIZE, NULL);
  448. }