NtDeviceIoControlFile(查询IP地址条目)-STATUS_INVALID_DEVICE_REQUES
NtDeviceIoControlFile (Query IP Address Entries) - STATUS_INVALID_DEVICE_REQUEST
任务
我正在尝试使用NtDeviceIoControlFile
和IOCTL_TCP_QUERY_INFORMATION_EX
标志枚举当前的ip接口条目。
代码
NTSTATUS GetIPAddresses(HANDLE TcpFile, TDIEntityID InterfaceID, IPAddrEntry* Entries, ULONG NumEntries) {
TCP_REQUEST_QUERY_INFORMATION_EX_WOW ReqWow64;
IO_STATUS_BLOCK IOBlock = {0, 0};
NTSTATUS Status = -1;
ReqWow64.ID.toi_class = 0x200;
ReqWow64.ID.toi_type = 0x100;
ReqWow64.ID.toi_id = 0x102;
ReqWow64.ID.toi_entity = InterfaceID;
return NtDeviceIoControlFile(
TcpFile, NULL, NULL, NULL, &IOBlock, IOCTL_TCP_QUERY_INFORMATION_EX,
&ReqWow64, sizeof(ReqWow64), Entries, NumEntries * sizeof(IPAddrEntry));
}
在这个页面上,它说我可以
- 获取特定IP实体的地址信息
如果IPSNMPInfo结构的ipsi_numaddr成员返回如果特定IP实体为非零,则可以通过将ID.toi_entity成员设置为标识实体、将ID.toi_class设置为INFO_class_PROTOCOL、将ID_toi_type设置为INFO_type_PROVIDER以及将ID.toid_ID设置为IP_MIB_ADDRTABLE_ENTRY_ID来检索IPAddrEntry结构的数组。在这种情况下,应该分配输出缓冲区来容纳大小的数组
sizeof(IPAddrEntry)*pIpSnmpInfoReturned->ips_numaddr
我在这里完成了这项工作:
IPAddrEntry *AddrEntries = Crt::Allocate<IPAddrEntry *>(SnmpInfo.ipsi_numaddr * sizeof(IPAddrEntry));
if (!AddrEntries)
return STATUS_NO_MEMORY;
然而,当我调用函数时:
NTSTATUS Status = GetIPAddresses(TcpFile, Interfaces[n], AddrEntries, SnmpInfo.ipsi_numaddr);
我得到以下NTSTATUS-1073741808
,它在十六进制中等于0xC0000010
,其计算结果为STATUS_INVALID_DEVICE_REQUEST。
TCP_REQUEST_QUERY_INFORMATION_EX_WOW
结构的声明
struct TCP_REQUEST_QUERY_INFORMATION_EX_WOW {
TDIObjectID ID;
ULONG pad;
UCHAR Context[16];
};
问题
这个错误的原因是什么?我的代码中的问题在哪里?
#include <iptypes.h>
#include <tdiinfo.h>
#include <tcpioctl.h>
NTSTATUS QueryTcp()
{
NTSTATUS status;
#ifndef _WIN64
struct TCP_REQUEST_QUERY_INFORMATION_EX_WOW
{
TDIObjectID ID; // object ID to query.
ULONG pad; // ! for wow64 only - Context must be aligned on 8 byte in 64bit windows
uchar Context[CONTEXT_SIZE]; // multi-request context. Zeroed
};
PVOID Wow;
status = NtQueryInformationProcess(NtCurrentProcess(), ProcessWow64Information, &Wow, sizeof(Wow), 0);
if (0 > status)
{
return status;
}
#endif
static const UNICODE_STRING ObjectName = RTL_CONSTANT_STRING(L"\device\tcp");
static const OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, const_cast<PUNICODE_STRING>(&ObjectName), OBJ_CASE_INSENSITIVE };
HANDLE hFile;
IO_STATUS_BLOCK iosb;
status = NtOpenFile(&hFile, SYNCHRONIZE,
const_cast<POBJECT_ATTRIBUTES>(&oa), &iosb, FILE_SHARE_VALID_FLAGS, FILE_SYNCHRONOUS_IO_NONALERT);
if (0 <= status)
{
PVOID InputBuffer;
ULONG InputBufferLength;
TDIObjectID* pID;
PVOID Context;
#ifndef _WIN64
if (Wow)
{
TCP_REQUEST_QUERY_INFORMATION_EX_WOW req = {
{ { GENERIC_ENTITY }, INFO_CLASS_GENERIC, INFO_TYPE_PROVIDER, ENTITY_LIST_ID }
};
InputBuffer = &req, InputBufferLength = sizeof(req), pID = &req.ID, Context = req.Context;
}
else
#endif
{
TCP_REQUEST_QUERY_INFORMATION_EX req = {
{ { GENERIC_ENTITY }, INFO_CLASS_GENERIC, INFO_TYPE_PROVIDER, ENTITY_LIST_ID }
};
InputBuffer = &req, InputBufferLength = sizeof(req), pID = &req.ID, Context = req.Context;
}
union {
PVOID buf;
TDIEntityID* pEntity;
};
volatile static UCHAR guz;
PVOID stack = alloca(guz);
ULONG cbAllocated = 0, cbNeed = 8 * sizeof(TDIEntityID);
do
{
if (cbAllocated < cbNeed)
{
cbAllocated = RtlPointerToOffset(buf = alloca(cbNeed - cbAllocated), stack);
}
// 1. Enumerate TDI Entities (INFO_CLASS_GENERIC, INFO_TYPE_PROVIDER, ENTITY_LIST_ID)
if (0 <= (status = NtDeviceIoControlFile(hFile, 0, 0, 0, &iosb,
IOCTL_TCP_QUERY_INFORMATION_EX, InputBuffer, InputBufferLength, buf, cbAllocated)))
{
if (ULONG n = (ULONG)iosb.Information / sizeof(TDIEntityID))
{
NTSTATUS s;
union {
ULONG type;
IPSNMPInfo snmp;
IFEntry ife;
IPInterfaceInfo ii;
BYTE iii_addr[sizeof(IPInterfaceInfo) + MAX_PHYSADDR_SIZE];
BYTE if_descr[sizeof(IFEntry) + MAX_ADAPTER_DESCRIPTION_LENGTH];
};
cbAllocated = 0;
stack = buf;
PVOID pv = 0;
do
{
DbgPrint("***{ %08x, %08x }n", pEntity->tei_entity, pEntity->tei_instance);
// set Specific Entity.
pID->toi_entity = *pEntity;
switch (pEntity->tei_entity)
{
case IF_ENTITY:
//3. Obtain MIB-II Information about an Interface Entity.
pID->toi_id = IF_MIB_STATS_ID;
pID->toi_class = INFO_CLASS_PROTOCOL;
s = NtDeviceIoControlFile(hFile, 0, 0, 0, &iosb,
IOCTL_TCP_QUERY_INFORMATION_EX,
InputBuffer, InputBufferLength, if_descr, sizeof(if_descr));
DbgPrint("#%u type=%u mtu=%u %.*Sn", ife.if_index, ife.if_type, ife.if_mtu,
ife.if_descrlen / sizeof(WCHAR), ife.if_descr);
break;
case CO_NL_ENTITY:
case CL_NL_ENTITY:
//4. Obtain MIB-II Information about a Particular IP Entity.
pID->toi_id = IP_MIB_STATS_ID;
pID->toi_class = INFO_CLASS_PROTOCOL;
s = NtDeviceIoControlFile(hFile, 0, 0, 0, &iosb,
IOCTL_TCP_QUERY_INFORMATION_EX,
InputBuffer, InputBufferLength, &snmp, sizeof(snmp));
if (0 <= s)
{
if (snmp.ipsi_numaddr)
{
cbNeed = snmp.ipsi_numaddr * sizeof(IPAddrEntry);
if (cbAllocated < cbNeed)
{
cbAllocated = RtlPointerToOffset(pv = alloca(cbNeed - cbAllocated), stack);
}
// 5. Obtain Address Information about a Particular IP Entity
pID->toi_id = IP_MIB_ADDRTABLE_ENTRY_ID;
s = NtDeviceIoControlFile(hFile, 0, 0, 0, &iosb,
IOCTL_TCP_QUERY_INFORMATION_EX,
InputBuffer, InputBufferLength, pv, cbAllocated);
if (0 <= s)
{
IPAddrEntry* pAddr = (IPAddrEntry*)pv;
// 6. Obtain Interface Information about a Particular IP Address.
pID->toi_id = IP_INTFC_INFO_ID;
do
{
char sz[16], mask[16];
RtlIpv4AddressToStringA(&pAddr->iae_addr, sz);
RtlIpv4AddressToStringA(&pAddr->iae_mask, mask);
DbgPrint("[%s/%s]n", sz, mask);
// 6. Obtain Interface Information about a Particular IP Address.
memcpy(Context, &pAddr->iae_addr, sizeof(pAddr->iae_addr));
s = NtDeviceIoControlFile(hFile, 0, 0, 0, &iosb,
IOCTL_TCP_QUERY_INFORMATION_EX,
InputBuffer, InputBufferLength, &ii, sizeof(iii_addr));
if (0 <= s)
{
if (ii.iii_addrlength)
{
DbgPrint("addr=");
PBYTE pb = ii.iii_addr;
do
{
DbgPrint("%02x", *pb++);
} while (--ii.iii_addrlength);
DbgPrint("n");
}
}
} while (pAddr++, --snmp.ipsi_numaddr);
}
}
}
break;
case CO_TL_ENTITY:
case CL_TL_ENTITY:
//2. Obtain Type Information about a Specific TL Entity.
pID->toi_id = ENTITY_TYPE_ID;
pID->toi_class = INFO_CLASS_GENERIC;
s = NtDeviceIoControlFile(hFile, 0, 0, 0, &iosb,
IOCTL_TCP_QUERY_INFORMATION_EX,
InputBuffer, InputBufferLength, &type, sizeof(type));
if (0 <= s)
{
DbgPrint("type=%xn", type);
}
break;
default:continue;
}
if (0 > s)
{
DbgPrint("error=%x { %08x, %08x }n", s, pEntity->tei_entity, pEntity->tei_instance);
}
} while (pEntity++, --n);
}
}
cbNeed += 8 * sizeof(TDIEntityID);
} while (status == STATUS_BUFFER_OVERFLOW || status == STATUS_BUFFER_TOO_SMALL);
NtClose(hFile);
}
return status;
}
相关文章:
- 如何解决"invalid conversion from 'char' to 'const char*'"
- 如何处理 c++ 中类实现中的"invalid use of non-static data member"?
- C++ "error: invalid use of void expression"
- 收到错误"invalid use of non-static data member 'stu::n' "
- Poloniex API "Invalid command" c++ libcurl
- C++模板错误:"invalid explicitly-specified argument for template parameter"
- SDL_CreateTextureFromSurface() "Invalid texture"错误?
- C++ "Invalid use of 'this' in non-member function" ,
- 为什么gmp会在这里与"invalid next size"重新定位一起崩溃?
- 继承类时"invalid use of incomplete type ‘class tree_node_t’"
- 为什么我会"Invalid read of size 8"?(瓦尔格林德)
- "fast"或"normal"在"free(): invalid next size (fast)"中是什么意思?
- 如何在Arduino程序中解决"invalid operands of types"?
- 如何'Invalid conversion'和'no match for operator'更正这些 c++ 错误
- 访问函数变体时"Invalid conversion"错误
- 马洛克会在 C++17 年返回"invalid pointer value"吗?
- 出现这种错误的原因是什么"invalid use of non-static data member "
- 指向对象生存期之外的已分配内存的指针是"invalid pointer[s]"还是"pointer[s] to an object"?
- 模板类和'invalid use of incomplete type'错误
- "invalid use of incomplete type" .解决循环依赖关系