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

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
smbkd.c
Abstract:
Smb kd extension (To be finished)
Author:
Jiandong Ruan
Notes:
Revision History:
12-Mar-2001 jruan
--*/
#include <nt.h>
#include <ntrtl.h>
#define KDEXTMODE
#define KDEXT_64BIT
#include <nturtl.h>
#include <ntverp.h>
#include <windef.h>
#include <winbase.h>
#include <wdbgexts.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "winsock2.h"
#include "winsock.h"
#include <ws2tcpip.h>
#include "../inc/ip6util.h"
#include "../sys/drv/precomp.h"
#define PRINTF dprintf
EXT_API_VERSION ApiVersion = {
(VER_PRODUCTVERSION_W >> 8), (VER_PRODUCTVERSION_W & 0xff),
EXT_API_VERSION_NUMBER64, 0
};
WINDBG_EXTENSION_APIS ExtensionApis;
USHORT SavedMajorVersion;
USHORT SavedMinorVersion;
BOOLEAN ChkTarget;
DECLARE_API(dumpcfg)
{
ULONG64 SmbDeviceAddr, SmbServerAddr;
ULONG64 ConfigPtr;
ULONG TcpCfgOffset;
SYM_DUMP_PARAM SymDump = { 0 };
CHAR *cfg_sym = "smb!SmbCfg";
CHAR *dns_sym = "smb!Dns";
CHAR *smbdev_sym = "smb!_SMB_DEVICE";
CHAR *smbsrv_sym = "smb!_SMB_CLIENT_ELEMENT";
CHAR *tcp_sym = "smb!_SMB_TCP_INFO";
PRINTF ("dt %s\n", cfg_sym);
SymDump.size = sizeof(SYM_DUMP_PARAM);
SymDump.sName = cfg_sym;
Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
PRINTF ("dt %s\n", dns_sym);
SymDump.size = sizeof(SYM_DUMP_PARAM);
SymDump.sName = dns_sym;
Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
ConfigPtr = GetExpression(cfg_sym);
InitTypeRead(ConfigPtr, smb!SMBCONFIG);
SmbDeviceAddr = ReadField(SmbDeviceObject);
PRINTF ("dt %s %16.16I64x\n", smbdev_sym, SmbDeviceAddr);
SymDump.size = sizeof(SYM_DUMP_PARAM);
SymDump.sName = smbdev_sym;
SymDump.addr = SmbDeviceAddr;
Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
PRINTF ("\n************ TCP Configuration ****************\n");
if (GetFieldOffset("smb!_SMB_DEVICE", (LPSTR)"Tcp4", &TcpCfgOffset)) {
PRINTF ("Cannot find the offset of smb!_SMB_CONNECT!TraceRcv\n");
return;
}
PRINTF ("Dump IPv4 TCP configuration: dt %s %16.16I64x\n", tcp_sym, SmbDeviceAddr + TcpCfgOffset);
SymDump.size = sizeof(SYM_DUMP_PARAM);
SymDump.sName = tcp_sym;
SymDump.addr = SmbDeviceAddr + TcpCfgOffset;
Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
if (GetFieldOffset("smb!_SMB_DEVICE", (LPSTR)"Tcp6", &TcpCfgOffset)) {
PRINTF ("Cannot find the offset of smb!_SMB_CONNECT!TraceRcv\n");
return;
}
PRINTF ("Dump IPv6 TCP configuration: dt %s %16.16I64x\n", tcp_sym, SmbDeviceAddr + TcpCfgOffset);
SymDump.size = sizeof(SYM_DUMP_PARAM);
SymDump.sName = tcp_sym;
SymDump.addr = SmbDeviceAddr + TcpCfgOffset;
Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
InitTypeRead(SmbDeviceAddr, smb!_SMB_DEVICE);
SmbServerAddr = ReadField(SmbServer);
if (SmbServerAddr) {
PRINTF ("\n************ Smb Server Client Element ****************\n");
PRINTF ("dt %s %16.16I64x\n", smbsrv_sym, SmbServerAddr);
SymDump.size = sizeof(SYM_DUMP_PARAM);
SymDump.sName = smbsrv_sym;
SymDump.addr = SmbServerAddr;
Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
}
}
__inline
ULONG
read_list_entry(
ULONG64 addr,
PLIST_ENTRY64 List
)
{
if (InitTypeRead(addr, LIST_ENTRY)) {
return 1;
}
List->Flink = ReadField(Flink);
List->Blink = ReadField(Blink);
return 0;
}
#define READLISTENTRY read_list_entry
/*++
Call callback for each entry in the list
--*/
typedef BOOL (*LIST_FOR_EACH_CALLBACK)(ULONG64 address, PVOID);
int
ListForEach(ULONG64 address, int maximum, PVOID pContext, LIST_FOR_EACH_CALLBACK callback)
{
LIST_ENTRY64 list;
int i;
if (READLISTENTRY(address, &list)) {
PRINTF ("Failed to read memory 0x%I64lx\n", address);
return (-1);
}
if (list.Flink == address) {
return (-1);
}
if (maximum < 0) {
maximum = 1000000;
}
for (i = 0; i < maximum && (list.Flink != address); i++) {
/*
* Allow user to break us.
*/
if (CheckControlC()) {
break;
}
callback(list.Flink, pContext);
if (READLISTENTRY(list.Flink, &list)) {
PRINTF ("Failed to read memory 0x%I64lx\n", list.Flink);
return (-1);
}
}
return i;
}
#define MAX_LIST_ELEMENTS 4096
LPSTR Extensions[] = {
"SMB6 debugger extensions",
0
};
LPSTR LibCommands[] = {
"help -- print out these messages",
"tracercv -- dump the trace log for TDI receive handler",
"srvmap -- dump IPv6-NetBIOS name mapping (only for SRV)",
"dumpcfg -- dump smb common global information",
"clients -- dump the client list",
"client -- dump a client",
"interface -- dump a interface",
0
};
DECLARE_API(help)
{
int i;
for( i=0; Extensions[i]; i++ )
PRINTF( " %s\n", Extensions[i] );
for( i=0; LibCommands[i]; i++ )
PRINTF( " %s\n", LibCommands[i] );
return;
}
DECLARE_API(version)
{
#if DBG
PCHAR DebuggerType = "Checked";
#else
PCHAR DebuggerType = "Free";
#endif
PRINTF ( "NETBT: %s extension dll (build %d) debugging %s kernel (build %d)\n",
DebuggerType,
VER_PRODUCTBUILD,
SavedMajorVersion == 0x0c ? "Checked" : "Free",
SavedMinorVersion
);
}
#define MIN(x,y) ((x) < (y) ? (x) : (y))
DECLARE_API(interface)
{
CHAR *smbsrv_sym = "smb!SMB_TCP_DEVICE";
SYM_DUMP_PARAM SymDump = { 0 };
ULONG64 addr;
addr = GetExpression(args);
PRINTF ("****** dt %s %16.16I64x\n", smbsrv_sym, addr);
SymDump.size = sizeof(SYM_DUMP_PARAM);
SymDump.sName = smbsrv_sym;
SymDump.addr = addr;
Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
PRINTF("\n");
}
DECLARE_API(tracercv)
{
ULONG64 addr;
ULONG tag, head, i;
ULONG traceoffset;
SMB_TRACE_RCV traces;
CHAR fn[512];
if (*args == 0) {
PRINTF ("tracercv connect_object\n");
return;
}
addr = GetExpression(args);
if (0 == addr) {
PRINTF ("tracercv connect_object\n");
return;
}
InitTypeRead(addr, smb!_SMB_CONNECT);
tag = (ULONG)ReadField(Tag);
if (tag != TAG_CONNECT_OBJECT) {
PRINTF ("Incorrect tag: 0x%08lx\n", tag);
return;
}
#if 0
if (GetFieldOffset("smb!_SMB_CONNECT", (LPSTR)"TraceRcv", &traceoffset)) {
PRINTF ("Cannot find the offset of smb!_SMB_CONNECT!TraceRcv\n");
return;
}
#endif
if (GetFieldData(addr, "smb!_SMB_CONNECT", "TraceRcv", sizeof(SMB_TRACE_RCV), &traces)) {
PRINTF ("Cannot find the smb!_SMB_CONNECT!TraceRcv\n");
return;
}
head = ((traces.Head + 1) % SMB_MAX_TRACE_SIZE);
for (i = head; i < SMB_MAX_TRACE_SIZE; i++) {
if (traces.Locations[i].id) {
break;
}
}
for (; i < SMB_MAX_TRACE_SIZE; i++) {
if (traces.Locations[i].id == 0) {
PRINTF ("Invalid trace Id: index=%3d, line=%d\n", i, traces.Locations[i].ln);
continue;
}
PRINTF ("%3d: Id=0x%08lx at line %d\n",
i - head + 1, traces.Locations[i].id, traces.Locations[i].ln);
}
for (i = 0; i < head; i++) {
if (traces.Locations[i].id == 0) {
PRINTF ("Invalid trace Id: index=%3d, line=%d\n", i, traces.Locations[i].ln);
continue;
}
PRINTF ("%3d: Id=0x%08lx at line %d\n",
SMB_MAX_TRACE_SIZE - head + i + 1, traces.Locations[i].id, traces.Locations[i].ln);
}
}
BOOL
clientlist_callback(ULONG64 addr, const int *bkt)
{
static ULONG addr_offset = (ULONG)(-1);
CHAR *smbsrv_sym = "smb!_SMB_CLIENT_ELEMENT";
SYM_DUMP_PARAM SymDump = { 0 };
if (addr_offset == (ULONG)(-1)) {
if (GetFieldOffset(smbsrv_sym, (LPSTR)"Linkage", &addr_offset)) {
PRINTF ("Please fix your symbols\n");
return FALSE;
}
}
addr -= addr_offset;
PRINTF ("****** dt %s %16.16I64x\n", smbsrv_sym, addr);
SymDump.size = sizeof(SYM_DUMP_PARAM);
SymDump.sName = smbsrv_sym;
SymDump.addr = addr;
Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
PRINTF("\n");
return TRUE;
}
DECLARE_API(clients)
{
ULONG64 ConfigPtr = 0, SmbDeviceAddr = 0;
ULONG ClientListOffset;
CHAR *cfg_sym = "smb!SmbCfg";
ConfigPtr = GetExpression(cfg_sym);
InitTypeRead(ConfigPtr, smb!SMBCONFIG);
SmbDeviceAddr = ReadField(SmbDeviceObject);
if (GetFieldOffset("smb!_SMB_DEVICE", (LPSTR)"ClientList", &ClientListOffset)) {
PRINTF ("Cannot find the offset of smb!_SMB_CONNECT!TraceRcv\n");
return;
}
PRINTF ("Dump client list\n");
ListForEach(SmbDeviceAddr + ClientListOffset, -1, NULL, (LIST_FOR_EACH_CALLBACK)clientlist_callback);
}
BOOL
connect_callback(ULONG64 addr, const int *bkt)
{
static ULONG addr_offset = (ULONG)(-1);
CHAR *cnt_sym = "smb!_SMB_CONNECT";
SYM_DUMP_PARAM SymDump = { 0 };
if (addr_offset == (ULONG)(-1)) {
if (GetFieldOffset(cnt_sym, (LPSTR)"Linkage", &addr_offset)) {
PRINTF ("Please fix your symbols\n");
return FALSE;
}
}
addr -= addr_offset;
PRINTF ("****** dt %s %16.16I64x\n", cnt_sym, addr);
SymDump.size = sizeof(SYM_DUMP_PARAM);
SymDump.sName = cnt_sym;
SymDump.addr = addr;
Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
PRINTF("\n");
return TRUE;
}
DECLARE_API(client)
{
ULONG64 addr;
ULONG addr_offset, assoc_offset, active_offset;
CHAR *smbsrv_sym = "smb!_SMB_CLIENT_ELEMENT";
if (*args == 0) {
PRINTF ("tracercv connect_object\n");
return;
}
if (GetFieldOffset(smbsrv_sym, (LPSTR)"Linkage", &addr_offset)) {
PRINTF ("Please fix your symbols\n");
return;
}
if (GetFieldOffset(smbsrv_sym, (LPSTR)"AssociatedConnection", &assoc_offset)) {
PRINTF ("Please fix your symbols\n");
return;
}
if (GetFieldOffset(smbsrv_sym, (LPSTR)"ActiveConnection", &active_offset)) {
PRINTF ("Please fix your symbols\n");
return;
}
addr = GetExpression(args);
clientlist_callback(addr + addr_offset, NULL);
PRINTF ("Dump associated connections\n");
ListForEach(addr + assoc_offset, -1, NULL, (LIST_FOR_EACH_CALLBACK)connect_callback);
PRINTF ("Dump Active connections\n");
ListForEach(addr + active_offset, -1, NULL, (LIST_FOR_EACH_CALLBACK)connect_callback);
}
BOOL
srvmap_callback(ULONG64 addr, const int *bkt)
{
static ULONG addr_offset = (ULONG)(-1);
struct sockaddr_in6 addr_in6 = { 0 };
LONG RefCount;
DWORD SerialNumber, dwError;
CHAR host[64];
if (addr_offset == (ULONG)(-1)) {
if (GetFieldOffset("smb!SMB_IPV6_NETBIOS", (LPSTR)"Linkage", &addr_offset)) {
PRINTF ("Please fix your symbols\n");
return FALSE;
}
}
addr -= addr_offset;
if (InitTypeRead(addr, smb!SMB_IPV6_NETBIOS)) {
PRINTF ("Please fix your symbols\n");
return FALSE;
}
RefCount = (LONG)ReadField(RefCount);
SerialNumber = (DWORD)ReadField(Serial);
if (GetFieldData(addr, "smb!SMB_IPV6_NETBIOS", "IpAddress", 16, &addr_in6.sin6_addr)) {
PRINTF ("Please fix your symbols\n");
return FALSE;
}
addr_in6.sin6_family = AF_INET6;
dwError = inet_ntoa6(host, sizeof(host), (PSMB_IP6_ADDRESS)&addr_in6.sin6_addr);
if (dwError == 0) {
return FALSE;
}
PRINTF ("%03d\t< %16.16I64x > *SMBSER%08x | %-40s | %02d\n",
*bkt, addr, SerialNumber, host, RefCount);
return TRUE;
}
DECLARE_API(srvmap)
{
ULONG64 addr = 0;
ULONG64 hashtbl_addr = 0;
ULONG64 buckets_addr = 0;
ULONG64 sizeof_list = 0;
int i, bucket_number = 0;
SYM_DUMP_PARAM SymDump = { 0 };
CHAR *mapping_sym = "smb!SmbIPv6Mapping";
CHAR *hash_sym = "smb!SMB_HASH_TABLE";
addr = GetExpression(mapping_sym);
if (0 == addr) {
PRINTF ("Please fix your symbols\n");
return;
}
//
// dump the mapping structure
//
PRINTF ("dt %s\n", mapping_sym);
SymDump.size = sizeof(SYM_DUMP_PARAM);
SymDump.sName = mapping_sym;
Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
//
// dump the hash table
//
InitTypeRead(addr, smb!SMB_IPV6_NETBIOS_TABLE);
hashtbl_addr = ReadField(HashTable);
if (0 == hashtbl_addr) {
PRINTF ("Please fix your symbols\n");
return;
}
if (GetFieldOffset(hash_sym, (LPSTR)"Buckets", (LONG*)&buckets_addr)) {
PRINTF ("Please fix your symbols\n");
return;
}
buckets_addr += hashtbl_addr;
PRINTF ("dt %s %16.16I64x\n", hash_sym, hashtbl_addr);
SymDump.size = sizeof(SYM_DUMP_PARAM);
SymDump.sName = hash_sym;
SymDump.addr = hashtbl_addr;
Ioctl(IG_DUMP_SYMBOL_INFO, &SymDump, SymDump.size);
InitTypeRead(hashtbl_addr, smb!SMB_HASH_TABLE);
bucket_number = (int)ReadField(NumberOfBuckets);
if (0 >= bucket_number) {
PRINTF ("Please fix your symbols\n");
return;
}
//
// dump each bucket
//
sizeof_list = GetTypeSize ("LIST_ENTRY");
if (0 == sizeof_list) {
PRINTF ("Please fix your symbols\n");
return;
}
PRINTF ("[Bkt#]\t< Address > < Name > | IPv6 Address | RefC\n");
PRINTF ("================================================================================================\n");
for (i = 0; i < bucket_number; i++) {
ListForEach(buckets_addr + i * sizeof_list, -1, &i, (LIST_FOR_EACH_CALLBACK)srvmap_callback);
}
}
//
// Standard Functions
//
DllInit(
HANDLE hModule,
DWORD dwReason,
DWORD dwReserved
)
{
WSADATA wsaData;
switch (dwReason) {
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
WSAStartup(MAKEWORD(2, 0), &wsaData);
break;
case DLL_PROCESS_ATTACH:
WSACleanup();
break;
}
return TRUE;
}
VOID
WinDbgExtensionDllInit(
PWINDBG_EXTENSION_APIS lpExtensionApis,
USHORT MajorVersion,
USHORT MinorVersion
)
{
ExtensionApis = *lpExtensionApis;
SavedMajorVersion = MajorVersion;
SavedMinorVersion = MinorVersion;
ChkTarget = SavedMajorVersion == 0x0c ? TRUE : FALSE;
return;
}
VOID
CheckVersion(VOID)
{
return;
}
LPEXT_API_VERSION
ExtensionApiVersion(
VOID
)
{
return &ApiVersion;
}