高分请教关于 NtDeviceIoControlFile 的一个问题

krfstudio 2005-01-05 05:46:29
我正在写一个实现和 nbtstat 命令功能类似的程序,现在已经实现了使用 UDP 发送 NODE STATUS REQUEST(见RFC1002) 得到对方主机信息,但是在实际使用中发现,对于某些机器,使用 nbtstat 命令可以得到对方的 NetBIOS Name Table,但是用我的程序却得不到对方的回应。

通过调试跟踪 nbtstat,发现在这个命令中是使用 NtDeviceIoControlFile 来得到对方主机信息的,上网查阅了一下 MSDN,只有简单的函数原型介绍,对于其中关键的 IoControlCode 参数没有详细介绍,有谁知道怎样用这个函数实现 nbtstat 的功能吗?
...全文
889 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
oyljerry 2005-01-11
  • 打赏
  • 举报
回复
用Iphelper API,GetTcpTable,GetUdpTable
kingzai 2005-01-11
  • 打赏
  • 举报
回复
BOOL LoadPrivilege(const char * Privilege)
{
HANDLE hToken;
LUID SEDebugNameValue;
TOKEN_PRIVILEGES tkp;

if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
fprintf(stderr, "OpenProcessToken, Erreur: %s", get_error());
return FALSE;
}

if (!LookupPrivilegeValue(NULL, Privilege, &SEDebugNameValue))
{
fprintf(stderr, "LookupPrivilegeValue, Erreur: %s", get_error());
CloseHandle(hToken);
return FALSE;
}

tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = SEDebugNameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL))
{
fprintf(stderr, "LookupPrivilegeValue, Erreur: %s", get_error());
CloseHandle(hToken);
return FALSE;
}

CloseHandle(hToken);

return TRUE;
}

void main()
{
PMIB_TCPTABLE TcpTable=NULL;
PMIB_UDPTABLE UdpTable=NULL;

HANDLE Tcp=NULL;
HANDLE Udp=NULL;

DWORD i;

DWORD PortTcp=0;
DWORD PortUdp=0;

if(!LoadPrivilege(SE_DEBUG_NAME))
{
fprintf(stderr,"Load Privilege Error...\n");
return;
}


Tcp=OpenDeviceTcpUdp(TRUE);
Udp=OpenDeviceTcpUdp(FALSE);

if(Tcp != NULL)
TcpTable=GetTcpTable(Tcp);

if(Udp != NULL)
UdpTable=GetUdpTable(Udp);

if( (UdpTable != 0 && TcpTable != 0) )
{
for(i=0; i < TcpTable->dwNumEntries; i++)
{
fprintf(stdout,"TCP %-16s %i\t - ",
inet_ntoa(*(struct in_addr *)&TcpTable->table[i].dwLocalAddr),
ntohs((WORD)TcpTable->table[i].dwLocalPort));
fprintf(stdout,"%-16s %i\n",
inet_ntoa(*(struct in_addr *)&TcpTable->table[i].dwRemoteAddr),
TcpTable->table[i].dwRemoteAddr == 0? 0:ntohs((WORD)TcpTable->table[i].dwRemotePort));
}

for(i=0; i < UdpTable->dwNumEntries; i++)
fprintf(stdout,"UDP %-16s %i \t - *:* \n",
TcpTable->table[i].dwLocalAddr == 0? "0.0.0.0" :inet_ntoa(*(struct in_addr *)&UdpTable->table[i].dwLocalAddr),
UdpTable->table[i].dwLocalPort == 0? 0: ntohs((WORD)UdpTable->table[i].dwLocalPort)
);

}

if(TcpTable != NULL)
VirtualFree(TcpTable,0,MEM_RELEASE);
if(UdpTable != NULL)
VirtualFree(UdpTable,0,MEM_RELEASE);
if(Tcp != NULL)
CloseHandle(Tcp);
if(Udp != NULL)
CloseHandle(Udp);

return;
}
kingzai 2005-01-11
  • 打赏
  • 举报
回复
MIB_TCPTABLE *GetTcpTable(HANDLE hTcpPort)
{
PMIB_TCPTABLE RTcpTable=NULL;

TCP_REQUEST_QUERY_INFORMATION_EX req={0};
MIB_TCPROW *TcpTable=NULL;
MIB_TCPSTATS TcpStats={0};

IO_STATUS_BLOCK IoStatusBlockStats={0};
IO_STATUS_BLOCK IoStatusBlockTable={0};

NTSTATUS Status=0;

DWORD arrayLen=0;
DWORD numconn=0;

HANDLE hEven2=NULL;

hEven2=CreateEventW(0,1,0,0);

//netstat
//http://msdn.microsoft.com/library/en-us/devnotes/winprog/ioctl_tcp_query_information_ex.asp

req.ID.toi_entity.tei_entity = 0x400; //CO_TL_ENTITY; tcp
req.ID.toi_entity.tei_instance = 0;
req.ID.toi_class = 0x200; //INFO_CLASS_PROTOCOL;
req.ID.toi_type = 0x100; //INFO_TYPE_PROVIDER;
req.ID.toi_id = 0x1; //TCP_STATS_ID;

Status = NtDeviceIoControlFile(
hTcpPort,
hEven2,
NULL,
NULL,
&IoStatusBlockStats,
0x00120003,
&req,
sizeof(req),
&TcpStats,
sizeof(TcpStats));

if(!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
fprintf(stderr, "GetTcpStats, Erreur: %s", get_error());
return 0;
}

RtlZeroMemory(&req,sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));
CloseHandle(hEven2);

arrayLen = TcpStats.dwNumConns * sizeof(MIB_TCPROW); //TCPAddrEntry
TcpTable = VirtualAlloc(NULL,arrayLen,MEM_COMMIT,PAGE_READWRITE);
hEven2=CreateEventW(0,1,0,0);

req.ID.toi_entity.tei_entity = 0x400; //CO_TL_ENTITY; tcp
req.ID.toi_entity.tei_instance = 0;
req.ID.toi_class = 0x200; //INFO_CLASS_PROTOCOL;
req.ID.toi_type = 0x100; //INFO_TYPE_PROVIDER;
req.ID.toi_id = 0x101; //TCP_MIB_ADDRTABLE_ENTRY_ID;

Status = NtDeviceIoControlFile(
hTcpPort,
hEven2,
NULL,
NULL,
&IoStatusBlockTable,
0x00120003,
&req,
sizeof(req),
TcpTable,
arrayLen);

CloseHandle(hEven2);


if(!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
fprintf(stderr, "GetTcpTable, Erreur: %s", get_error());
return 0;
}

numconn = IoStatusBlockTable.Information/sizeof(MIB_TCPROW);

RTcpTable=VirtualAlloc(NULL,numconn*sizeof(MIB_TCPTABLE),MEM_COMMIT,PAGE_READWRITE);
RTcpTable->dwNumEntries=numconn;

memcpy(RTcpTable->table,TcpTable,arrayLen);

VirtualFree(TcpTable,0,MEM_RELEASE);

return RTcpTable;

}

MIB_UDPTABLE *GetUdpTable(HANDLE hUdpPort)
{
PMIB_UDPTABLE RUdpTable=NULL;

TCP_REQUEST_QUERY_INFORMATION_EX req={0};

MIB_UDPROW *UdpTable=NULL;
MIB_UDPSTATS UdpStats={0};

IO_STATUS_BLOCK IoStatusBlockStats={0};
IO_STATUS_BLOCK IoStatusBlockTable={0};

NTSTATUS Status=0;
//DWORD i;

DWORD arrayLen=0;
DWORD numconn=0;

HANDLE hEven2=NULL;

hEven2=CreateEventW(0,1,0,0);

//netstat
//http://msdn.microsoft.com/library/en-us/devnotes/winprog/ioctl_tcp_query_information_ex.asp

req.ID.toi_entity.tei_entity = 0x401; //CO_TL_ENTITY; udp
req.ID.toi_entity.tei_instance = 0;
req.ID.toi_class = 0x200; //INFO_CLASS_PROTOCOL;
req.ID.toi_type = 0x100; //INFO_TYPE_PROVIDER;
req.ID.toi_id = 0x1; //TCP_STATS_ID;

Status = NtDeviceIoControlFile(
hUdpPort,
hEven2,
NULL,
NULL,
&IoStatusBlockStats,
0x00120003,
&req,
sizeof(req),
&UdpStats,
sizeof(UdpStats));

CloseHandle(hEven2);

if(!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
fprintf(stderr, "GetUdpStat, Erreur: %s", get_error());
return NULL;
}

RtlZeroMemory(&req,sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));

arrayLen = UdpStats.dwNumAddrs * sizeof(MIB_UDPROW); //TCPAddrEntry
UdpTable = VirtualAlloc(NULL,arrayLen,MEM_COMMIT,PAGE_READWRITE);

hEven2=CreateEventW(0,1,0,0);

req.ID.toi_entity.tei_entity = 0x401; //CO_TL_ENTITY; udp
req.ID.toi_entity.tei_instance = 0;
req.ID.toi_class = 0x200; //INFO_CLASS_PROTOCOL;
req.ID.toi_type = 0x100; //INFO_TYPE_PROVIDER;
req.ID.toi_id = 0x101; //TCP_MIB_ADDRTABLE_ENTRY_ID;

Status = NtDeviceIoControlFile(
hUdpPort,
hEven2,
NULL,
NULL,
&IoStatusBlockTable,
0x00120003,
&req,
sizeof(req),
UdpTable,
arrayLen);

CloseHandle(hEven2);

if(!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
fprintf(stderr, "GetUdpTable, Erreur: %s", get_error());
return NULL;
}


numconn = IoStatusBlockTable.Information/sizeof(MIB_UDPROW);

RUdpTable=VirtualAlloc(NULL,numconn*sizeof(MIB_UDPTABLE),MEM_COMMIT,PAGE_READWRITE);
RUdpTable->dwNumEntries=numconn;
memcpy(RUdpTable->table,UdpTable,arrayLen);

VirtualFree(UdpTable,0,MEM_RELEASE);
return RUdpTable;
}

HANDLE OpenDeviceTcpUdp(BOOL PROTO)
{
NTSTATUS Status;
UNICODE_STRING physmemString;
OBJECT_ATTRIBUTES attributes;
IO_STATUS_BLOCK iosb;
HANDLE pDeviceHandle;

if(PROTO)
RtlInitUnicodeString(&physmemString, L"\\Device\\TCP");
else
RtlInitUnicodeString(&physmemString, L"\\Device\\UDP");

attributes.Length = sizeof(OBJECT_ATTRIBUTES);
attributes.RootDirectory = NULL;
attributes.ObjectName = &physmemString;
attributes.Attributes = 0x40; //OBJ_CASE_INSENSITIVE
attributes.SecurityDescriptor = NULL;
attributes.SecurityQualityOfService = NULL;

Status = ZwOpenFile ( &pDeviceHandle,0x100000, &attributes, &iosb, 3,0);

if(!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
fprintf(stderr, "ZwOpenFile, Erreur: %s", get_error());
return NULL;
}

return pDeviceHandle;
}
kingzai 2005-01-11
  • 打赏
  • 举报
回复
#include<windows.h>
#include <stdio.h>

#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L)
#pragma comment (lib,"ws2_32.lib")
#pragma comment (lib,"advapi32.lib")
#pragma comment (lib,"ntdll.lib")


//tiny
#pragma optimize("gsy",on)
#pragma comment(linker,"/RELEASE")
#pragma comment(linker,"/merge:.rdata=.data")
#pragma comment(linker,"/merge:.text=.data")
#pragma comment(linker,"/merge:.reloc=.data")
#pragma comment(linker,"/SECTION:.data,EWR")
#pragma comment(linker,"/FILEALIGN:0x200")
#pragma comment(linker,"/IGNORE:4078")
#pragma comment(linker,"/OPT:NOWIN98")


typedef long NTSTATUS;

typedef struct _IO_STATUS_BLOCK
{
NTSTATUS Status;
ULONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;


typedef struct _ANSI_STRING {
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
}ANSI_STRING,*PANSI_STRING;

typedef struct _OBJECT_ATTRIBUTES
{
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;

typedef struct _MIB_TCPROW
{
DWORD dwState;
DWORD dwLocalAddr;
DWORD dwLocalPort;
DWORD dwRemoteAddr;
DWORD dwRemotePort;
} MIB_TCPROW, *PMIB_TCPROW;

typedef struct _MIB_UDPROW
{
DWORD dwLocalAddr;
DWORD dwLocalPort;
} MIB_UDPROW, *PMIB_UDPROW;

typedef struct _MIB_UDPTABLE {
DWORD dwNumEntries;
MIB_UDPROW table[1];
} MIB_UDPTABLE, *PMIB_UDPTABLE;

typedef struct _MIB_TCPTABLE {
DWORD dwNumEntries;
MIB_TCPROW table[1];
} MIB_TCPTABLE, *PMIB_TCPTABLE;

//* Structure of an entity ID.
typedef struct TDIEntityID {
ULONG tei_entity;
ULONG tei_instance;
} TDIEntityID;

//* Structure of an object ID.
typedef struct TDIObjectID {
TDIEntityID toi_entity;
ULONG toi_class;
ULONG toi_type;
ULONG toi_id;
} TDIObjectID;

typedef struct _MIB_TCPSTATS
{
DWORD dwRtoAlgorithm;
DWORD dwRtoMin;
DWORD dwRtoMax;
DWORD dwMaxConn;
DWORD dwActiveOpens;
DWORD dwPassiveOpens;
DWORD dwAttemptFails;
DWORD dwEstabResets;
DWORD dwCurrEstab;
DWORD dwInSegs;
DWORD dwOutSegs;
DWORD dwRetransSegs;
DWORD dwInErrs;
DWORD dwOutRsts;
DWORD dwNumConns;
} MIB_TCPSTATS, *PMIB_TCPSTATS;

typedef struct _MIB_UDPSTATS
{
DWORD dwInDatagrams;
DWORD dwNoPorts;
DWORD dwInErrors;
DWORD dwOutDatagrams;
DWORD dwNumAddrs;
} MIB_UDPSTATS,*PMIB_UDPSTATS;

#define MIB_TCP_STATE_CLOSED 1
#define MIB_TCP_STATE_LISTEN 2
#define MIB_TCP_STATE_SYN_SENT 3
#define MIB_TCP_STATE_SYN_RCVD 4
#define MIB_TCP_STATE_ESTAB 5
#define MIB_TCP_STATE_FIN_WAIT1 6
#define MIB_TCP_STATE_FIN_WAIT2 7
#define MIB_TCP_STATE_CLOSE_WAIT 8
#define MIB_TCP_STATE_CLOSING 9
#define MIB_TCP_STATE_LAST_ACK 10
#define MIB_TCP_STATE_TIME_WAIT 11
#define MIB_TCP_STATE_DELETE_TCB 12

//
// Possible TCP endpoint states
//
static char TcpState[][32] = {
"???",
"CLOSED",
"LISTENING",
"SYN_SENT",
"SEN_RECEIVED",
"ESTABLISHED",
"FIN_WAIT",
"FIN_WAIT2",
"CLOSE_WAIT",
"CLOSING",
"LAST_ACK",
"TIME_WAIT"
};


#define CONTEXT_SIZE 16

//#define CO_TL_ENTITY 0x400
//#define INFO_CLASS_PROTOCOL 0x200
//#define INFO_TYPE_PROVIDER 0x100

//#define TCP_MIB_ADDRTABLE_ENTRY_ID 0x101
//#define INFO_TYPE_CONNECTION 0x300
//#define CO_TL_TCP 0x404
// QueryInformationEx IOCTL. The return buffer is passed as the OutputBuffer
// in the DeviceIoControl request. This structure is passed as the
// InputBuffer.
//
struct tcp_request_query_information_ex {
TDIObjectID ID; // object ID to query.
ULONG * Context[CONTEXT_SIZE/sizeof(ULONG *)]; // multi-request context. Zeroed
// for the first request.
};

typedef struct tcp_request_query_information_ex
TCP_REQUEST_QUERY_INFORMATION_EX,
*PTCP_REQUEST_QUERY_INFORMATION_EX;

typedef
void
(NTAPI *PIO_APC_ROUTINE) (
IN PVOID ApcContext,
IN PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG Reserved
);

NTSYSAPI
NTSTATUS
NTAPI ZwOpenFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG ShareAccess,
IN ULONG OpenOptions
);

NTSYSAPI
NTSTATUS
NTAPI
NtDeviceIoControlFile(

IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG IoControlCode,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferLength );

NTSYSAPI
ULONG
NTAPI
RtlNtStatusToDosError(
IN NTSTATUS Status
);

NTSYSAPI
void
NTAPI
RtlInitUnicodeString(
PUNICODE_STRING DestinationString,
PCWSTR SourceString
);


extern char *get_error(void)
{
LPVOID lpMsgBuf;

FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL);

return (lpMsgBuf);
}
kingzai 2005-01-11
  • 打赏
  • 举报
回复
http://www.packetstormsecurity.org/new-exploits/nstat.c
krfstudio 2005-01-11
  • 打赏
  • 举报
回复
还有,才发现这段代码实现的是 netstat,我需要的是 nbtstat
kingzai 2005-01-11
  • 打赏
  • 举报
回复
NTDDK
ntdll.lib 库文件
krfstudio 2005-01-11
  • 打赏
  • 举报
回复
To kingzai(stevenzhu):

找不到 ntdll.lib 啊。(注:我用的是 VC7.0 )
krfstudio 2005-01-06
  • 打赏
  • 举报
回复
自己再顶一下。
krfstudio 2005-01-06
  • 打赏
  • 举报
回复
那个代码我试过了,就是用的我上面所说的使用 UDP 发送 NODE STATUS REQUEST 数据包,只是有一些机器不知道是开了防火墙还是什么原因,这种方法不能用,但是 nbtstat 却可以用,所以才引出了上面我所说的问题。
krfstudio 2005-01-06
  • 打赏
  • 举报
回复
CSDN 的各位大虾,帮帮忙啦,要是分不够可以开贴加分。
kingzai 2005-01-05
  • 打赏
  • 举报
回复
网络命令nbtstat的VC版源代码 详细信息 < 局域网 >

实现nbtstat -a的功能。得到某一网段内所有机器的IP,机器名,工作组,用户名,MAC地址,
http://www.vckbase.com/code/downcode.asp?id=1572
krfstudio 2005-01-05
  • 打赏
  • 举报
回复
自己顶一下。
内容概要:本文围绕不确定环境下的多式联运路径优化问题展开研究,提出并实现了基于AFO算法、遗传算法(GA)和粒子群优化算法(PSO)的三种智能优化方法,并借助Matlab平台完成算法编程与仿真。研究构建了考虑时间、成本、转运风险等多重不确定因素的路径优化模型,系统比较了AFO、GA、PSO三种算法在收敛速度、全局寻优能力和稳定性方面的表现,同时引入Matlab自带的全局优化搜索器作为基准对照,深入分析各算法在复杂物流网络中的适用边界与性能差异。研究表明,AFO算法在解决此类组合优化问题时展现出更快的收敛效率和更强的局部规避能力。; 适合人群:具备一定Matlab编程基础与运筹优化知识,从事物流工程、交通运输规划、智能算法开发等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于多式联运、综合货运网络中的路径决策支持系统构建;②为不确定性条件下复杂路径规划问题提供智能算法选型依据与技术实现方案;③支持科研人员复现主流优化算法并开展横向性能对比实验,推动算法改进与实际落地。; 阅读建议:建议读者结合提供的Matlab代码逐模块分析算法实现流程,重点理解目标函数设计、约束条件处理及参数敏感性分析部分,可通过调整问题规模与算法参数进行对比实验,进一步拓展至动态路径规划或大规模网络优化等延伸场景。
内容概要:本文研究了基于QLearning自适应强化学习的PID控制器在自主水下航行器(AUV)运动控制中的应用,通过Matlab代码实现了控制算法的仿真验证。该方法融合强化学习的在线自适应能力与传统PID控制的稳定性优势,利用QLearning算法动态优化PID控制器的比例、积分、微分参数,以应对水下复杂流体环境、模型不确定性及外部干扰等挑战,从而提升AUV轨迹跟踪的精度、鲁棒性与动态响应性能。文中系统阐述了AUV的六自由度非线性动力学建模过程、QLearning算法的状态空间与动作空间设计、奖励函数构造及训练机制,并详细说明了PID参数自整定的闭环控制架构。仿真结果表明,相较于传统固定参数PID控制器,该智能控制策略在多种工况下均展现出更优的控制效果,有效抑制了超调,加快了响应速度,并增强了抗干扰能力。; 适合人群:具备自动控制理论、强化学习基础及Matlab/Simulink仿真能力,从事水下机器人、智能控制、海洋工程、自动化等领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于AUV、UUV等无人水下平台的高精度自主导航与运动控制;②为解决非线性、强耦合、时变系统的控制器参数自适应整定问题提供智能化解决方案;③作为强化学习与经典控制理论深度融合的技术范例,推动智能控制算法在海洋装备中的工程化应用。; 阅读建议:建议读者结合提供的Matlab代码深入理解算法实现细节,重点剖析QLearning的状态-动作-奖励机制设计、PID参数更新逻辑及仿真对比实验结果,有条件者可在更复杂的动力学模型或实际硬件平台上进一步验证与优化算法性能。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧