模拟系统nbtstat 的代码实现

来源:互联网 发布:linux配置dns命令 编辑:程序博客网 时间:2024/04/27 20:48

#include <windows.h>

#include <stdio.h>

#include <conio.h>

#include <malloc.h>

 

 

typedef UINT NTSTATUS;

 

#define STATUS_SUCCESS                           ((NTSTATUS)0x00000000L)

#define STATUS_BUFFER_OVERFLOW           ((NTSTATUS)0x80000005L)

#define STATUS_INVALID_PARAMETER         ((NTSTATUS)0xC000000DL)

#define STATUS_BUFFER_TOO_SMALL          ((NTSTATUS)0xC0000023L)

#define STATUS_ALREADY_COMMITTED         ((NTSTATUS)0xC0000021L)

#define STATUS_INVALID_DEVICE_REQUEST    ((NTSTATUS)0xC0000010L)

#define STATUS_OBJECT_NAME_NOT_FOUND     ((NTSTATUS)0xC0000034L)

#define STATUS_OBJECT_NAME_INVALID       ((NTSTATUS)0xC0000033L)

#define STATUS_ACCESS_VIOLATION          ((NTSTATUS)0xC0000005L)    // winnt ntsubauth

#define STATUS_PENDING                   ((NTSTATUS)0x00000103L)    // winnt

 

 

typedef struct _UNICODE_STRING {

    USHORT Length;

    USHORT MaximumLength;

#ifdef MIDL_PASS

    [size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer;

#else // MIDL_PASS

    PWSTR  Buffer;

#endif // MIDL_PASS

} UNICODE_STRING;

typedef UNICODE_STRING *PUNICODE_STRING;

#define UNICODE_NULL ((WCHAR)0) // winnt

 

 

typedef struct _OBJECT_ATTRIBUTES {

    ULONG Length;

    HANDLE RootDirectory;

    PUNICODE_STRING ObjectName;

    ULONG Attributes;

    PVOID SecurityDescriptor;        // Points to type SECURITY_DESCRIPTOR

    PVOID SecurityQualityOfService;  // Points to type SECURITY_QUALITY_OF_SERVICE

} OBJECT_ATTRIBUTES;

typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;

 

 

typedef struct _IO_STATUS_BLOCK {

    NTSTATUS Status;

    ULONG Information;

} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

 

 

NTSTATUS (__stdcall *fNtCreateFile)(

                                        PHANDLE FileHandle,

                                        ACCESS_MASK DesiredAccess,

                                        POBJECT_ATTRIBUTES ObjectAttributes,

                                        PIO_STATUS_BLOCK IoStatusBlock,

                                        PLARGE_INTEGER AllocationSize, 

                                        ULONG FileAttributes,

                                        ULONG ShareAccess,

                                        ULONG CreateDisposition,

                                        ULONG CreateOptions,

                                        PVOID EaBuffer,

                                        ULONG EaLength

                        );

 

NTSTATUS (__stdcall *fNtDeviceIoControlFile)(

                                        HANDLE FileHandle,

                                        DWORD a,

                                        DWORD b,

                                        DWORD c,

                                        PVOID structA, 

                                        PVOID d,

                                        PVOID e,

                                        PVOID f,

                                        PVOID outBuf,

                                        DWORD size

                        );

 

 

 

//

// Macro definition for defining IOCTL and FSCTL function control codes.  Note

// that function codes 0-2047 are reserved for Microsoft Corporation, and

// 2048-4095 are reserved for customers.

//

 

#define CTL_CODE( DeviceType, Function, Method, Access ) (                 /

    ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) /

)

 

 

#define FILE_DEVICE_TRANSPORT           0x00000021

 

//

// Define the method codes for how buffers are passed for I/O and FS controls

//

 

#define METHOD_BUFFERED                 0

#define METHOD_IN_DIRECT                1

#define METHOD_OUT_DIRECT               2

#define METHOD_NEITHER                  3

 

//

// Define the access check value for any access

//

//

// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in

// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these

// constants *MUST* always be in sync.

//

 

 

#define FILE_ANY_ACCESS                 0

#define FILE_READ_ACCESS          ( 0x0001 )    // file & pipe

#define FILE_WRITE_ACCESS         ( 0x0002 )    // file & pipe

 

//

// NtDeviceIoControlFile IoControlCode values for this device.

//

// Warning:  Remember that the low two bits of the code specify how the

//           buffers are passed to the driver!

//

 

#define _TDI_CONTROL_CODE(request,method) /

            CTL_CODE(FILE_DEVICE_TRANSPORT, request, method, FILE_ANY_ACCESS)

 

#define IOCTL_TDI_ACCEPT                _TDI_CONTROL_CODE( 0, METHOD_BUFFERED )

#define IOCTL_TDI_CONNECT               _TDI_CONTROL_CODE( 1, METHOD_BUFFERED )

#define IOCTL_TDI_DISCONNECT            _TDI_CONTROL_CODE( 2, METHOD_BUFFERED )

#define IOCTL_TDI_LISTEN                _TDI_CONTROL_CODE( 3, METHOD_BUFFERED )

#define IOCTL_TDI_QUERY_INFORMATION     _TDI_CONTROL_CODE( 4, METHOD_OUT_DIRECT )

#define IOCTL_TDI_RECEIVE               _TDI_CONTROL_CODE( 5, METHOD_OUT_DIRECT )

#define IOCTL_TDI_RECEIVE_DATAGRAM      _TDI_CONTROL_CODE( 6, METHOD_OUT_DIRECT )

#define IOCTL_TDI_SEND                  _TDI_CONTROL_CODE( 7, METHOD_IN_DIRECT )

#define IOCTL_TDI_SEND_DATAGRAM         _TDI_CONTROL_CODE( 8, METHOD_IN_DIRECT )

#define IOCTL_TDI_SET_EVENT_HANDLER     _TDI_CONTROL_CODE( 9, METHOD_BUFFERED )

#define IOCTL_TDI_SET_INFORMATION       _TDI_CONTROL_CODE( 10, METHOD_IN_DIRECT )

#define IOCTL_TDI_ASSOCIATE_ADDRESS     _TDI_CONTROL_CODE( 11, METHOD_BUFFERED )

#define IOCTL_TDI_DISASSOCIATE_ADDRESS  _TDI_CONTROL_CODE( 12, METHOD_BUFFERED )

#define IOCTL_TDI_ACTION                _TDI_CONTROL_CODE( 13, METHOD_OUT_DIRECT )

 

 

/* These *UNDOCUMENTED* IOCTL codes are used in NBTSTAT.EXE */

 

#define IOCTL_TDI_UNKNOWN1                _TDI_CONTROL_CODE( 41, METHOD_OUT_DIRECT ) //gets dword from ip?

#define IOCTL_TDI_UNKNOWN2                _TDI_CONTROL_CODE( 43, METHOD_OUT_DIRECT ) //gets netbios name

 

#define IOCTL_TDI_UNKNOWN3                _TDI_CONTROL_CODE( 30, METHOD_BUFFERED )

#define IOCTL_TDI_UNKNOWN4                _TDI_CONTROL_CODE( 31, METHOD_OUT_DIRECT )

#define IOCTL_TDI_UNKNOWN5                _TDI_CONTROL_CODE( 32, METHOD_OUT_DIRECT )

#define IOCTL_TDI_UNKNOWN6                _TDI_CONTROL_CODE( 33, METHOD_OUT_DIRECT )

 

 

typedef LONG TDI_STATUS;

typedef PVOID CONNECTION_CONTEXT;

 

 

/* This structure is passed with every TDI_REQUEST_ to TDI. It describes that

 * request and the parameters to it.

 */

typedef struct _TDI_REQUEST {

    union {

        HANDLE AddressHandle;

        CONNECTION_CONTEXT ConnectionContext;

        HANDLE ControlChannel;

    } Handle;

 

    PVOID RequestNotifyObject;

    PVOID RequestContext;

    TDI_STATUS TdiStatus;

} TDI_REQUEST, *PTDI_REQUEST;

 

 

/* EDIT the following structure as needed */

 

typedef struct _TDI_REQUEST_XXX {

    TDI_REQUEST Request;

    /* SOME ADDITIONAL DATA HERE */

} TDI_REQUEST_XXX, *PTDI_REQUEST_XXX;

 

/* test structure for TDI_UNKNOWN1 */

typedef struct _TDI_REQUEST_UNKNOWN1 {

    TDI_REQUEST Request;

    /* SOME ADDITIONAL DATA HERE */

} TDI_REQUEST_UNKNOWN1, *PTDI_REQUEST_UNKNOWN1;

 

 

/* test structure for TDI_UNKNOWN2 */

typedef struct _TDI_REQUEST_UNKNOWN2 {

    TDI_REQUEST Request;

    /* SOME ADDITIONAL DATA HERE */

        DWORD a, b, c, d;

} TDI_REQUEST_UNKNOWN2, *PTDI_REQUEST_UNKNOWN2;

 

 

struct netbiosName {

        char name[15];

        char type;

        char index;

        char registered;

};

 

LPWSTR WINAPI Ascii2WideHelper(LPWSTR lpw, LPCSTR lpa, int nChars);

LPSTR WINAPI Wide2AsciiHelper(LPSTR lpa, LPCWSTR lpw, int nChars);

 

#ifndef A2WHELPER

#define A2WHELPER Ascii2WideHelper

#define W2AHELPER Wide2AsciiHelper

#endif

 

#ifndef _DEBUG

#define USES_UNICODE_CONVERSION int _Uconvert; _Uconvert

#else

#define USES_UNICODE_CONVERSION int _Uconvert = 0

#endif

 

#define ASCII2WIDE(lpa) (/

        ((LPCSTR)lpa == NULL) ? NULL : (/

                _Uconvert = (lstrlenA(lpa)+1),/

                A2WHELPER((LPWSTR) alloca(_Uconvert*2), lpa, _Uconvert)))

 

 

#define WIDE2ASCII(lpw) (/

        ((LPCWSTR)lpw == NULL) ? NULL : (/

                _Uconvert = (lstrlenW(lpw)+1)*2,/

                W2AHELPER((LPSTR) alloca(_Uconvert), lpw, _Uconvert)))

 

#define ASCII2CWIDE(lpa) ((LPCWSTR)ASCII2WIDE(lpa))

#define WIDE2CASCII(lpw) ((LPCSTR)WIDE2ASCII(lpw))

 

void dumpNames(char *outbuf);

char * getLinkage(char *theKey);

 

 

int main( int argc, char *argv[])

{

        USES_UNICODE_CONVERSION;

 

        if(argc != 2){

                fprintf(stdout, "Usage: %s <ip address>/n", argv[0]);

                exit(0);

        }

 

        if(!(fNtCreateFile =

                        (void *) GetProcAddress(GetModuleHandle("ntdll.dll"),

                                                                        "NtCreateFile"))){

                fputs("Could not find entry point in NTDLL.DLL/n", stderr);

                exit(1);

        }

 

        if(!(fNtDeviceIoControlFile =

                        (void *) GetProcAddress(GetModuleHandle("ntdll.dll"),

                                                                        "NtDeviceIoControlFile"))){

                fputs("Could not find entry point in NTDLL.DLL/n", stderr);

                exit(1);

        }

 

        if(fNtCreateFile){

                HANDLE h;

                OBJECT_ATTRIBUTES anObjAttrib;

                IO_STATUS_BLOCK aReturnCode;

                NTSTATUS ret;

                char *aCs = 0;

                WCHAR *aUs = 0;

                UNICODE_STRING aSS;

 

                aCs = getLinkage("system//currentcontrolset//services//netbt//linkage");

                if(!aCs){

                        fputs("Could not get linkage for NetBT/n", stderr);

                        exit(1);

                }

                

                aUs = ASCII2WIDE(aCs);

                aSS.Length = strlen(aCs) * sizeof(WCHAR);

                aSS.MaximumLength = aSS.Length + sizeof(WCHAR);

                aSS.Buffer = aUs;

 

                /* InitializeObjectAttributes */

                memset((void *)&anObjAttrib, 0, sizeof(OBJECT_ATTRIBUTES));

                anObjAttrib.ObjectName = &aSS;

                anObjAttrib.Length = sizeof(OBJECT_ATTRIBUTES);

                anObjAttrib.Attributes = 0x40; /* sniffed this value */

 

                ret = fNtCreateFile(    &h,

                                                                0x00100003, /* snooped this too */

                                                                &anObjAttrib,

                                                                &aReturnCode,

                                                                0,      /* optional */

                                                                0x80, /* file attrib, snooped this */

                                                                0x3,

                                                                0x3,

                                                                0,

                                                                NULL,

                                                                0

                                                                );

 

                if(ret != STATUS_SUCCESS){

                        fprintf(stderr, "NtCreateFile error %d/n", GetLastError());

                        exit(1);

                }

 

                if(h){

                        if(fNtDeviceIoControlFile){

                                char outbuf2[600];

                                TDI_REQUEST_UNKNOWN2 aTdi2;

                               

                                /* this is hax0red sushi */

                                aTdi2.Request.Handle.AddressHandle = (void *) htonl(inet_addr(argv[1]));

                                aTdi2.Request.RequestNotifyObject = (void *) 1;

                                aTdi2.Request.RequestContext = (void *) 0x110012;

                                aTdi2.Request.TdiStatus = 0x2a0000;

                                aTdi2.a = 0;

                                aTdi2.b = 0;

                                aTdi2.c = 0;

                                aTdi2.d = 0;

 

                                /* outbuf2 should be filled with the nbtstat data */

                                ret = fNtDeviceIoControlFile(   h,

                                                                                                0,

                                                                                                0,

                                                                                                0,

                                                                                                &aTdi2, // ???

                                                                                                IOCTL_TDI_UNKNOWN2, //0x2100A6, // code

                                                                                                &aTdi2,

                                                                                                0x20,

                                                                                                outbuf2,

                                                                                                0x258

                                                                                                );

                                if(ret == STATUS_PENDING){

                                        if(WaitForSingleObject(h, 5000) == WAIT_TIMEOUT){

                                                fputs("Timed out waiting for response.../n", stderr);

                                                exit(1);

                                        }

                                }

       

                                dumpNames(outbuf2);

                        }

                        CloseHandle(h);

                }

        }

              return 0;

}

 

 

char * getLinkage(char *theKey)

{

        HKEY aKey;

        if(RegOpenKey(HKEY_LOCAL_MACHINE, theKey, &aKey) == ERROR_SUCCESS){

                char dt[255];

                int dsz = 255;

                int i = 0;

                char *aDest;

                if(RegQueryValueEx(     aKey,

                                                        "Export",

                                                        NULL,

                                                        NULL,

                                                        dt,

                                                        &dsz ) == ERROR_SUCCESS){

                        aDest = malloc(dsz);

                        memcpy(aDest, dt, dsz);

                        return(aDest);

                }

        }

        return(0);

}

 

 

void dumpNames(char *outbuf)

{

        struct netbiosName *aNameP;

        char numEntries;

 

        outbuf += 0x3a;  /* interesting data starts 58 bytes in */

        numEntries = *outbuf;

        outbuf += 2;

        while(numEntries--){

                char temp[16];

               

                aNameP = (struct netbiosName *)outbuf;

                strncpy(temp, aNameP->name, 15);

                temp[15] = '/0';

                if(aNameP->registered < 0)

                        fprintf(stdout, "%16s<%2x> %10s/n", temp, aNameP->type, "GROUP");

                else

                        fprintf(stdout, "%16s<%2x> %10s/n", temp, aNameP->type, "UNIQUE");

 

                outbuf += sizeof(struct netbiosName);

        }

}

 

/* Global UNICODE<>ANSI translation helpers */

LPWSTR WINAPI Ascii2WideHelper(LPWSTR lpw, LPCSTR lpa, int nChars)

{

        if(lpa == NULL){

                __asm int 3

        }

        if(lpw == NULL){

                __asm int 3

        }

        // verify that no illegal character present

        // since lpw was allocated based on the size of lpa

        // don't worry about the number of chars

        lpw[0] = '/0';

        MultiByteToWideChar(CP_ACP, 0, lpa, -1, lpw, nChars);

        return lpw;

}

 

LPSTR WINAPI Wide2AsciiHelper(LPSTR lpa, LPCWSTR lpw, int nChars)

{

        if(lpw == NULL){

                __asm int 3

        }

        if(lpa == NULL){

                __asm int 3

        }

        // verify that no illegal character present

        // since lpa was allocated based on the size of lpw

        // don't worry about the number of chars

        lpa[0] = '/0';

        WideCharToMultiByte(CP_ACP, 0, lpw, -1, lpa, nChars, NULL, NULL);

        return lpa;

}

 

原创粉丝点击