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.

559 lines
15 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. smbkd.c
  5. Abstract:
  6. Smb kd extension (To be finished)
  7. Author:
  8. Jiandong Ruan
  9. Notes:
  10. Revision History:
  11. 12-Mar-2001 jruan
  12. --*/
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #define KDEXTMODE
  16. #define KDEXT_64BIT
  17. #include <nturtl.h>
  18. #include <ntverp.h>
  19. #include <windef.h>
  20. #include <winbase.h>
  21. #include <wdbgexts.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <stdio.h>
  25. #include "winsock2.h"
  26. #include "winsock.h"
  27. #include <ws2tcpip.h>
  28. #include "../inc/ip6util.h"
  29. #include "../sys/drv/precomp.h"
  30. #define PRINTF dprintf
  31. EXT_API_VERSION ApiVersion = {
  32. (VER_PRODUCTVERSION_W >> 8), (VER_PRODUCTVERSION_W & 0xff),
  33. EXT_API_VERSION_NUMBER64, 0
  34. };
  35. WINDBG_EXTENSION_APIS ExtensionApis;
  36. USHORT SavedMajorVersion;
  37. USHORT SavedMinorVersion;
  38. BOOLEAN ChkTarget;
  39. DECLARE_API(dumpcfg)
  40. {
  41. ULONG64 SmbDeviceAddr, SmbServerAddr;
  42. ULONG64 ConfigPtr;
  43. ULONG TcpCfgOffset;
  44. SYM_DUMP_PARAM SymDump = { 0 };
  45. CHAR *cfg_sym = "smb!SmbCfg";
  46. CHAR *dns_sym = "smb!Dns";
  47. CHAR *smbdev_sym = "smb!_SMB_DEVICE";
  48. CHAR *smbsrv_sym = "smb!_SMB_CLIENT_ELEMENT";
  49. CHAR *tcp_sym = "smb!_SMB_TCP_INFO";
  50. PRINTF ("dt %s\n", cfg_sym);
  51. SymDump.size = sizeof(SYM_DUMP_PARAM);
  52. SymDump.sName = cfg_sym;
  53. Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
  54. PRINTF ("dt %s\n", dns_sym);
  55. SymDump.size = sizeof(SYM_DUMP_PARAM);
  56. SymDump.sName = dns_sym;
  57. Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
  58. ConfigPtr = GetExpression(cfg_sym);
  59. InitTypeRead(ConfigPtr, smb!SMBCONFIG);
  60. SmbDeviceAddr = ReadField(SmbDeviceObject);
  61. PRINTF ("dt %s %16.16I64x\n", smbdev_sym, SmbDeviceAddr);
  62. SymDump.size = sizeof(SYM_DUMP_PARAM);
  63. SymDump.sName = smbdev_sym;
  64. SymDump.addr = SmbDeviceAddr;
  65. Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
  66. PRINTF ("\n************ TCP Configuration ****************\n");
  67. if (GetFieldOffset("smb!_SMB_DEVICE", (LPSTR)"Tcp4", &TcpCfgOffset)) {
  68. PRINTF ("Cannot find the offset of smb!_SMB_CONNECT!TraceRcv\n");
  69. return;
  70. }
  71. PRINTF ("Dump IPv4 TCP configuration: dt %s %16.16I64x\n", tcp_sym, SmbDeviceAddr + TcpCfgOffset);
  72. SymDump.size = sizeof(SYM_DUMP_PARAM);
  73. SymDump.sName = tcp_sym;
  74. SymDump.addr = SmbDeviceAddr + TcpCfgOffset;
  75. Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
  76. if (GetFieldOffset("smb!_SMB_DEVICE", (LPSTR)"Tcp6", &TcpCfgOffset)) {
  77. PRINTF ("Cannot find the offset of smb!_SMB_CONNECT!TraceRcv\n");
  78. return;
  79. }
  80. PRINTF ("Dump IPv6 TCP configuration: dt %s %16.16I64x\n", tcp_sym, SmbDeviceAddr + TcpCfgOffset);
  81. SymDump.size = sizeof(SYM_DUMP_PARAM);
  82. SymDump.sName = tcp_sym;
  83. SymDump.addr = SmbDeviceAddr + TcpCfgOffset;
  84. Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
  85. InitTypeRead(SmbDeviceAddr, smb!_SMB_DEVICE);
  86. SmbServerAddr = ReadField(SmbServer);
  87. if (SmbServerAddr) {
  88. PRINTF ("\n************ Smb Server Client Element ****************\n");
  89. PRINTF ("dt %s %16.16I64x\n", smbsrv_sym, SmbServerAddr);
  90. SymDump.size = sizeof(SYM_DUMP_PARAM);
  91. SymDump.sName = smbsrv_sym;
  92. SymDump.addr = SmbServerAddr;
  93. Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
  94. }
  95. }
  96. __inline
  97. ULONG
  98. read_list_entry(
  99. ULONG64 addr,
  100. PLIST_ENTRY64 List
  101. )
  102. {
  103. if (InitTypeRead(addr, LIST_ENTRY)) {
  104. return 1;
  105. }
  106. List->Flink = ReadField(Flink);
  107. List->Blink = ReadField(Blink);
  108. return 0;
  109. }
  110. #define READLISTENTRY read_list_entry
  111. /*++
  112. Call callback for each entry in the list
  113. --*/
  114. typedef BOOL (*LIST_FOR_EACH_CALLBACK)(ULONG64 address, PVOID);
  115. int
  116. ListForEach(ULONG64 address, int maximum, PVOID pContext, LIST_FOR_EACH_CALLBACK callback)
  117. {
  118. LIST_ENTRY64 list;
  119. int i;
  120. if (READLISTENTRY(address, &list)) {
  121. PRINTF ("Failed to read memory 0x%I64lx\n", address);
  122. return (-1);
  123. }
  124. if (list.Flink == address) {
  125. return (-1);
  126. }
  127. if (maximum < 0) {
  128. maximum = 1000000;
  129. }
  130. for (i = 0; i < maximum && (list.Flink != address); i++) {
  131. /*
  132. * Allow user to break us.
  133. */
  134. if (CheckControlC()) {
  135. break;
  136. }
  137. callback(list.Flink, pContext);
  138. if (READLISTENTRY(list.Flink, &list)) {
  139. PRINTF ("Failed to read memory 0x%I64lx\n", list.Flink);
  140. return (-1);
  141. }
  142. }
  143. return i;
  144. }
  145. #define MAX_LIST_ELEMENTS 4096
  146. LPSTR Extensions[] = {
  147. "SMB6 debugger extensions",
  148. 0
  149. };
  150. LPSTR LibCommands[] = {
  151. "help -- print out these messages",
  152. "tracercv -- dump the trace log for TDI receive handler",
  153. "srvmap -- dump IPv6-NetBIOS name mapping (only for SRV)",
  154. "dumpcfg -- dump smb common global information",
  155. "clients -- dump the client list",
  156. "client -- dump a client",
  157. "interface -- dump a interface",
  158. 0
  159. };
  160. DECLARE_API(help)
  161. {
  162. int i;
  163. for( i=0; Extensions[i]; i++ )
  164. PRINTF( " %s\n", Extensions[i] );
  165. for( i=0; LibCommands[i]; i++ )
  166. PRINTF( " %s\n", LibCommands[i] );
  167. return;
  168. }
  169. DECLARE_API(version)
  170. {
  171. #if DBG
  172. PCHAR DebuggerType = "Checked";
  173. #else
  174. PCHAR DebuggerType = "Free";
  175. #endif
  176. PRINTF ( "NETBT: %s extension dll (build %d) debugging %s kernel (build %d)\n",
  177. DebuggerType,
  178. VER_PRODUCTBUILD,
  179. SavedMajorVersion == 0x0c ? "Checked" : "Free",
  180. SavedMinorVersion
  181. );
  182. }
  183. #define MIN(x,y) ((x) < (y) ? (x) : (y))
  184. DECLARE_API(interface)
  185. {
  186. CHAR *smbsrv_sym = "smb!SMB_TCP_DEVICE";
  187. SYM_DUMP_PARAM SymDump = { 0 };
  188. ULONG64 addr;
  189. addr = GetExpression(args);
  190. PRINTF ("****** dt %s %16.16I64x\n", smbsrv_sym, addr);
  191. SymDump.size = sizeof(SYM_DUMP_PARAM);
  192. SymDump.sName = smbsrv_sym;
  193. SymDump.addr = addr;
  194. Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
  195. PRINTF("\n");
  196. }
  197. DECLARE_API(tracercv)
  198. {
  199. ULONG64 addr;
  200. ULONG tag, head, i;
  201. ULONG traceoffset;
  202. SMB_TRACE_RCV traces;
  203. CHAR fn[512];
  204. if (*args == 0) {
  205. PRINTF ("tracercv connect_object\n");
  206. return;
  207. }
  208. addr = GetExpression(args);
  209. if (0 == addr) {
  210. PRINTF ("tracercv connect_object\n");
  211. return;
  212. }
  213. InitTypeRead(addr, smb!_SMB_CONNECT);
  214. tag = (ULONG)ReadField(Tag);
  215. if (tag != TAG_CONNECT_OBJECT) {
  216. PRINTF ("Incorrect tag: 0x%08lx\n", tag);
  217. return;
  218. }
  219. #if 0
  220. if (GetFieldOffset("smb!_SMB_CONNECT", (LPSTR)"TraceRcv", &traceoffset)) {
  221. PRINTF ("Cannot find the offset of smb!_SMB_CONNECT!TraceRcv\n");
  222. return;
  223. }
  224. #endif
  225. if (GetFieldData(addr, "smb!_SMB_CONNECT", "TraceRcv", sizeof(SMB_TRACE_RCV), &traces)) {
  226. PRINTF ("Cannot find the smb!_SMB_CONNECT!TraceRcv\n");
  227. return;
  228. }
  229. head = ((traces.Head + 1) % SMB_MAX_TRACE_SIZE);
  230. for (i = head; i < SMB_MAX_TRACE_SIZE; i++) {
  231. if (traces.Locations[i].id) {
  232. break;
  233. }
  234. }
  235. for (; i < SMB_MAX_TRACE_SIZE; i++) {
  236. if (traces.Locations[i].id == 0) {
  237. PRINTF ("Invalid trace Id: index=%3d, line=%d\n", i, traces.Locations[i].ln);
  238. continue;
  239. }
  240. PRINTF ("%3d: Id=0x%08lx at line %d\n",
  241. i - head + 1, traces.Locations[i].id, traces.Locations[i].ln);
  242. }
  243. for (i = 0; i < head; i++) {
  244. if (traces.Locations[i].id == 0) {
  245. PRINTF ("Invalid trace Id: index=%3d, line=%d\n", i, traces.Locations[i].ln);
  246. continue;
  247. }
  248. PRINTF ("%3d: Id=0x%08lx at line %d\n",
  249. SMB_MAX_TRACE_SIZE - head + i + 1, traces.Locations[i].id, traces.Locations[i].ln);
  250. }
  251. }
  252. BOOL
  253. clientlist_callback(ULONG64 addr, const int *bkt)
  254. {
  255. static ULONG addr_offset = (ULONG)(-1);
  256. CHAR *smbsrv_sym = "smb!_SMB_CLIENT_ELEMENT";
  257. SYM_DUMP_PARAM SymDump = { 0 };
  258. if (addr_offset == (ULONG)(-1)) {
  259. if (GetFieldOffset(smbsrv_sym, (LPSTR)"Linkage", &addr_offset)) {
  260. PRINTF ("Please fix your symbols\n");
  261. return FALSE;
  262. }
  263. }
  264. addr -= addr_offset;
  265. PRINTF ("****** dt %s %16.16I64x\n", smbsrv_sym, addr);
  266. SymDump.size = sizeof(SYM_DUMP_PARAM);
  267. SymDump.sName = smbsrv_sym;
  268. SymDump.addr = addr;
  269. Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
  270. PRINTF("\n");
  271. return TRUE;
  272. }
  273. DECLARE_API(clients)
  274. {
  275. ULONG64 ConfigPtr = 0, SmbDeviceAddr = 0;
  276. ULONG ClientListOffset;
  277. CHAR *cfg_sym = "smb!SmbCfg";
  278. ConfigPtr = GetExpression(cfg_sym);
  279. InitTypeRead(ConfigPtr, smb!SMBCONFIG);
  280. SmbDeviceAddr = ReadField(SmbDeviceObject);
  281. if (GetFieldOffset("smb!_SMB_DEVICE", (LPSTR)"ClientList", &ClientListOffset)) {
  282. PRINTF ("Cannot find the offset of smb!_SMB_CONNECT!TraceRcv\n");
  283. return;
  284. }
  285. PRINTF ("Dump client list\n");
  286. ListForEach(SmbDeviceAddr + ClientListOffset, -1, NULL, (LIST_FOR_EACH_CALLBACK)clientlist_callback);
  287. }
  288. BOOL
  289. connect_callback(ULONG64 addr, const int *bkt)
  290. {
  291. static ULONG addr_offset = (ULONG)(-1);
  292. CHAR *cnt_sym = "smb!_SMB_CONNECT";
  293. SYM_DUMP_PARAM SymDump = { 0 };
  294. if (addr_offset == (ULONG)(-1)) {
  295. if (GetFieldOffset(cnt_sym, (LPSTR)"Linkage", &addr_offset)) {
  296. PRINTF ("Please fix your symbols\n");
  297. return FALSE;
  298. }
  299. }
  300. addr -= addr_offset;
  301. PRINTF ("****** dt %s %16.16I64x\n", cnt_sym, addr);
  302. SymDump.size = sizeof(SYM_DUMP_PARAM);
  303. SymDump.sName = cnt_sym;
  304. SymDump.addr = addr;
  305. Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
  306. PRINTF("\n");
  307. return TRUE;
  308. }
  309. DECLARE_API(client)
  310. {
  311. ULONG64 addr;
  312. ULONG addr_offset, assoc_offset, active_offset;
  313. CHAR *smbsrv_sym = "smb!_SMB_CLIENT_ELEMENT";
  314. if (*args == 0) {
  315. PRINTF ("tracercv connect_object\n");
  316. return;
  317. }
  318. if (GetFieldOffset(smbsrv_sym, (LPSTR)"Linkage", &addr_offset)) {
  319. PRINTF ("Please fix your symbols\n");
  320. return;
  321. }
  322. if (GetFieldOffset(smbsrv_sym, (LPSTR)"AssociatedConnection", &assoc_offset)) {
  323. PRINTF ("Please fix your symbols\n");
  324. return;
  325. }
  326. if (GetFieldOffset(smbsrv_sym, (LPSTR)"ActiveConnection", &active_offset)) {
  327. PRINTF ("Please fix your symbols\n");
  328. return;
  329. }
  330. addr = GetExpression(args);
  331. clientlist_callback(addr + addr_offset, NULL);
  332. PRINTF ("Dump associated connections\n");
  333. ListForEach(addr + assoc_offset, -1, NULL, (LIST_FOR_EACH_CALLBACK)connect_callback);
  334. PRINTF ("Dump Active connections\n");
  335. ListForEach(addr + active_offset, -1, NULL, (LIST_FOR_EACH_CALLBACK)connect_callback);
  336. }
  337. BOOL
  338. srvmap_callback(ULONG64 addr, const int *bkt)
  339. {
  340. static ULONG addr_offset = (ULONG)(-1);
  341. struct sockaddr_in6 addr_in6 = { 0 };
  342. LONG RefCount;
  343. DWORD SerialNumber, dwError;
  344. CHAR host[64];
  345. if (addr_offset == (ULONG)(-1)) {
  346. if (GetFieldOffset("smb!SMB_IPV6_NETBIOS", (LPSTR)"Linkage", &addr_offset)) {
  347. PRINTF ("Please fix your symbols\n");
  348. return FALSE;
  349. }
  350. }
  351. addr -= addr_offset;
  352. if (InitTypeRead(addr, smb!SMB_IPV6_NETBIOS)) {
  353. PRINTF ("Please fix your symbols\n");
  354. return FALSE;
  355. }
  356. RefCount = (LONG)ReadField(RefCount);
  357. SerialNumber = (DWORD)ReadField(Serial);
  358. if (GetFieldData(addr, "smb!SMB_IPV6_NETBIOS", "IpAddress", 16, &addr_in6.sin6_addr)) {
  359. PRINTF ("Please fix your symbols\n");
  360. return FALSE;
  361. }
  362. addr_in6.sin6_family = AF_INET6;
  363. dwError = inet_ntoa6(host, sizeof(host), (PSMB_IP6_ADDRESS)&addr_in6.sin6_addr);
  364. if (dwError == 0) {
  365. return FALSE;
  366. }
  367. PRINTF ("%03d\t< %16.16I64x > *SMBSER%08x | %-40s | %02d\n",
  368. *bkt, addr, SerialNumber, host, RefCount);
  369. return TRUE;
  370. }
  371. DECLARE_API(srvmap)
  372. {
  373. ULONG64 addr = 0;
  374. ULONG64 hashtbl_addr = 0;
  375. ULONG64 buckets_addr = 0;
  376. ULONG64 sizeof_list = 0;
  377. int i, bucket_number = 0;
  378. SYM_DUMP_PARAM SymDump = { 0 };
  379. CHAR *mapping_sym = "smb!SmbIPv6Mapping";
  380. CHAR *hash_sym = "smb!SMB_HASH_TABLE";
  381. addr = GetExpression(mapping_sym);
  382. if (0 == addr) {
  383. PRINTF ("Please fix your symbols\n");
  384. return;
  385. }
  386. //
  387. // dump the mapping structure
  388. //
  389. PRINTF ("dt %s\n", mapping_sym);
  390. SymDump.size = sizeof(SYM_DUMP_PARAM);
  391. SymDump.sName = mapping_sym;
  392. Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
  393. //
  394. // dump the hash table
  395. //
  396. InitTypeRead(addr, smb!SMB_IPV6_NETBIOS_TABLE);
  397. hashtbl_addr = ReadField(HashTable);
  398. if (0 == hashtbl_addr) {
  399. PRINTF ("Please fix your symbols\n");
  400. return;
  401. }
  402. if (GetFieldOffset(hash_sym, (LPSTR)"Buckets", (LONG*)&buckets_addr)) {
  403. PRINTF ("Please fix your symbols\n");
  404. return;
  405. }
  406. buckets_addr += hashtbl_addr;
  407. PRINTF ("dt %s %16.16I64x\n", hash_sym, hashtbl_addr);
  408. SymDump.size = sizeof(SYM_DUMP_PARAM);
  409. SymDump.sName = hash_sym;
  410. SymDump.addr = hashtbl_addr;
  411. Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
  412. InitTypeRead(hashtbl_addr, smb!SMB_HASH_TABLE);
  413. bucket_number = (int)ReadField(NumberOfBuckets);
  414. if (0 >= bucket_number) {
  415. PRINTF ("Please fix your symbols\n");
  416. return;
  417. }
  418. //
  419. // dump each bucket
  420. //
  421. sizeof_list = GetTypeSize ("LIST_ENTRY");
  422. if (0 == sizeof_list) {
  423. PRINTF ("Please fix your symbols\n");
  424. return;
  425. }
  426. PRINTF ("[Bkt#]\t< Address > < Name > | IPv6 Address | RefC\n");
  427. PRINTF ("================================================================================================\n");
  428. for (i = 0; i < bucket_number; i++) {
  429. ListForEach(buckets_addr + i * sizeof_list, -1, &i, (LIST_FOR_EACH_CALLBACK)srvmap_callback);
  430. }
  431. }
  432. //
  433. // Standard Functions
  434. //
  435. DllInit(
  436. HANDLE hModule,
  437. DWORD dwReason,
  438. DWORD dwReserved
  439. )
  440. {
  441. WSADATA wsaData;
  442. switch (dwReason) {
  443. case DLL_THREAD_ATTACH:
  444. break;
  445. case DLL_THREAD_DETACH:
  446. break;
  447. case DLL_PROCESS_DETACH:
  448. WSAStartup(MAKEWORD(2, 0), &wsaData);
  449. break;
  450. case DLL_PROCESS_ATTACH:
  451. WSACleanup();
  452. break;
  453. }
  454. return TRUE;
  455. }
  456. VOID
  457. WinDbgExtensionDllInit(
  458. PWINDBG_EXTENSION_APIS lpExtensionApis,
  459. USHORT MajorVersion,
  460. USHORT MinorVersion
  461. )
  462. {
  463. ExtensionApis = *lpExtensionApis;
  464. SavedMajorVersion = MajorVersion;
  465. SavedMinorVersion = MinorVersion;
  466. ChkTarget = SavedMajorVersion == 0x0c ? TRUE : FALSE;
  467. return;
  468. }
  469. VOID
  470. CheckVersion(VOID)
  471. {
  472. return;
  473. }
  474. LPEXT_API_VERSION
  475. ExtensionApiVersion(
  476. VOID
  477. )
  478. {
  479. return &ApiVersion;
  480. }