我正在尝试从
NtQuerySystemInformation()
函数获取有关进程中句柄的信息。我有以下代码:
#include <iostream>
#include <Windows.h>
#include <winternl.h>
#include <process.h>
#define SystemHandleInformation 0x10
#define SystemHandleInformationSize 1024 * 1024 * 2
using fNtQuerySystemInformation = NTSTATUS(WINAPI*)(
ULONG SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
typedef struct _DEVICE_OBJECT* PDEVICE_OBJECT;
typedef struct _PVPB* PVPB;
typedef struct _KEVENT* PKEVENT;
typedef struct _IO_COMPLETION_CONTEXT* PIO_COMPLETION_CONTEXT;
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO
{
USHORT UniqueProcessId;
USHORT CreatorBackTraceIndex;
UCHAR ObjectTypeIndex;
UCHAR HandleAttributes;
USHORT HandleValue;
PVOID Object;
ULONG GrantedAccess;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, * PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
typedef struct _SYSTEM_HANDLE_INFORMATION
{
ULONG NumberOfHandles;
SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
} SYSTEM_HANDLE_INFORMATION, * PSYSTEM_HANDLE_INFORMATION;
typedef struct _SECTION_OBJECT_POINTERS
{
PVOID DataSectionObject;
PVOID SharedCacheMap;
PVOID ImageSectionObject;
} SECTION_OBJECT_POINTERS, * PSECTION_OBJECT_POINTERS;
typedef struct _FILE_OBJECT
{
SHORT Type;
SHORT Size;
PDEVICE_OBJECT DeviceObject;
PVPB Vpb;
PVOID FsContext;
PVOID FsContext2;
PSECTION_OBJECT_POINTERS SectionObjectPointer;
PVOID PrivateCacheMap;
LONG FinalStatus;
struct _FILE_OBJECT *RelatedFileObject;
UCHAR LockOperation;
UCHAR DeletePending;
UCHAR ReadAccess;
UCHAR WriteAccess;
UCHAR DeleteAccess;
UCHAR SharedRead;
UCHAR SharedWrite;
UCHAR SharedDelete;
ULONG Flags;
UNICODE_STRING FileName;
LARGE_INTEGER CurrentByteOffset;
ULONG Waiters;
ULONG Busy;
PVOID LastLock;
PKEVENT Lock;
PKEVENT Event;
PIO_COMPLETION_CONTEXT CompletionContext;
ULONG IrpListLock;
LIST_ENTRY IrpList;
PVOID FileObjectExtension;
} FILE_OBJECT, * PFILE_OBJECT;
int main() {
HANDLE hFile = CreateFileA("C:\\Users\\user\\Documents\\test.txt", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
ULONG returnLenght = 0;
fNtQuerySystemInformation NtQuerySystemInformation = (fNtQuerySystemInformation)GetProcAddress(GetModuleHandle(L"ntdll"), "NtQuerySystemInformation");
PSYSTEM_HANDLE_INFORMATION handleTableInformation = (PSYSTEM_HANDLE_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SystemHandleInformationSize);
NtQuerySystemInformation(SystemHandleInformation, handleTableInformation, SystemHandleInformationSize, &returnLenght);
int PID = _getpid();
for (int i = 0; i < handleTableInformation->NumberOfHandles; i++)
{
SYSTEM_HANDLE_TABLE_ENTRY_INFO handleInfo = (SYSTEM_HANDLE_TABLE_ENTRY_INFO)handleTableInformation->Handles[i];
if (handleInfo.UniqueProcessId == PID && handleInfo.ObjectTypeIndex == 37)
{
printf_s("Handle 0x%x at 0x%p, PID: %x\n", handleInfo.HandleValue, handleInfo.Object, handleInfo.UniqueProcessId);
PFILE_OBJECT fileObj = (PFILE_OBJECT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024 * 1024 * 2);
memcpy(&fileObj, &handleInfo.Object, sizeof(fileObj));
printf_s("%d\n", fileObj->Type);
}
}
return 0;
}
在
IF
条件下,我正在检查handleInfo
的PID以及对象类型是否为37,这意味着它是一个文件对象(这是Windows 10中的正确索引。在其他操作系统中可能有所不同) 。在这个 IF
块中,我需要通过存储在 PFILE_OBJECT
中的指针来获取 handleInfo.Object
。但是当我调用 memcpy()
函数将此结构分配给变量时,我收到了 Access violation of reading location
错误。
我做错了什么?如何访问这个结构?我需要获取它的 Type、ReadAccess、WriteAccess、FileName 等。
我运行了代码,
printf_s("%d\n", fileObj->Type);
行抛出了read access violation
异常。 fileObj
的地址是0xFFFF800D0F4C3940
。
根据虚拟地址空间:
进程可用的虚拟地址范围是已知的 作为进程的虚拟地址空间。每个用户模式进程都有其 自己的私有虚拟地址空间。
32 位进程的虚拟地址空间通常在 2 GB 范围内 0x00000000 到 0x7FFFFFFF。
64 位 Windows 上的 64 位进程具有 128 TB 范围内的虚拟地址空间 0x000'00000000 到 0x7FFF'FFFFFFFF。
和
在用户模式下运行的代码可以访问用户空间,但不能访问系统空间。 此限制可防止用户模式代码读取或更改 受保护的操作系统数据结构。
尝试访问大于
0x7FFF'FFFFFFFF
的地址将导致读访问冲突。