【发布时间】:2013-11-28 12:16:06
【问题描述】:
我正在尝试将 PVOID 转换为 ULONG,但它总是失败并给我错误的数据,还建议不要将指针变量类型转换为 int、ulong 或 msdn 中的其他数据类型,如 ULONG client = (ULONG) pvoidVar,但我试过了不同的技术和预定义的功能,例如:
ULONG client = PtrToUlong(pvoidVar);
ULONG client = (ULONG) PtrToUlong(pvoidVar);
发生的事情是我试图将客户端 ID 从用户模式应用程序发送到内核驱动程序,但内核驱动程序中的接收部分使其成为 PVOID Irp->UserBuffer 并且它发送我想用作 HANDLE 的进程 ID现在句柄与PVOID 相同,我想直接使用它,但它仍然不能像这样工作:
HANDLE processID = (HANDLE) Irp->UserBuffer;
HANDLE processID = Irp->UserBUffer;
我到处阅读,都建议使用PtrToUlong 和HANDLE 与PVOID 相同,我错了吗?请告诉我如何将PVOID 转换为ULONG 或如何将PVOID 用作HANDLE
编辑---
这是我的主驱动程序的代码,它不会崩溃,但输出错误
#include <ntddk.h>
#include <wdm.h>
#define DEVICE L"\\Device\\TEST"
#define DOSDEVICE L"\\DosDevices\\TEST"
VOID Unload(PDRIVER_OBJECT DriverObject) {
UNICODE_STRING DosDeviceName;
DbgPrint("Driver Unloaded");
RtlInitUnicodeString(&DosDeviceName, DOSDEVICE);
IoDeleteSymbolicLink(&DosDeviceName);
IoDeleteDevice(DriverObject->DeviceObject);
}
NTSTATUS IODispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS IOManager(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp);
ULONG IRPcode = StackLocation->Parameters.DeviceIoControl.IoControlCode;
// Here i cannot convert pvoid as ULONG if i try to do that it gives me some other value
DbgPrint("%lu", (ULONG)Irp->AssociatedIrp.SystemBuffer);
NTSTATUS ntStatus = STATUS_SUCCESS;
HANDLE hProcess;
OBJECT_ATTRIBUTES ObjectAttributes;
CLIENT_ID ClientId;
// Here i cannot use pvoid directly as a handle nor cast it as a handle as it fails
ClientId.UniqueProcess = (HANDLE)Irp->AssociatedIrp.SystemBuffer;
ClientId.UniqueThread = NULL;
InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_INHERIT, NULL, NULL);
ntStatus = ZwOpenProcess(&hProcess, PROCESS_ALL_ACCESS, &ObjectAttributes, &ClientId);
if(NT_SUCCESS(ntStatus)) {
ZwClose(hProcess);
}
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath) {
NTSTATUS status = STATUS_SUCCESS;
int uiIndex = 0;
PDEVICE_OBJECT pDeviceObject = NULL;
UNICODE_STRING DriverName, DosDeviceName;
DbgPrint("Driver Loaded");
RtlInitUnicodeString(&DriverName, DEVICE);
RtlInitUnicodeString(&DosDeviceName, DOSDEVICE);
pDriverObject->DriverUnload = Unload;
status = IoCreateDevice(pDriverObject, 0, &DriverName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDeviceObject);
if (!NT_SUCCESS(status)) {
DbgPrint("IoCreateDevice failed: %x", status);
return status;
}
status = IoCreateSymbolicLink(&DosDeviceName, &DriverName);
if (!NT_SUCCESS(status)) {
IoDeleteDevice(pDeviceObject);
DbgPrint("IoCreateSymbolicLink failed");
return status;
}
pDriverObject->MajorFunction[IRP_MJ_CREATE] = IODispatch;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = IODispatch;
pDriverObject->MajorFunction[IRP_MJ_READ] = IODispatch;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = IODispatch;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IOManager;
return status;
}
这是我的用户模式应用程序
#define SYSFILE L"C:\\TEST.sys"
#define SERVICENAME L"TEST"
BOOL GetProcessList();
VOID startServ(DWORD processID);
int _cdecl main(void) {
GetProcessList();
return 0;
}
BOOL GetProcessList() {
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) {
printf("CreateTool");
getchar();
return(FALSE);
}
pe32.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(hProcessSnap, &pe32)) {
CloseHandle(hProcessSnap);
printf("Process32");
getchar();
return(FALSE);
}
do {
if (wcscmp(L"test.exe", pe32.szExeFile) == 0) {
startServ(pe32.th32ProcessID);
}
} while(Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return(TRUE);
}
VOID startServ(DWORD processID) {
SC_HANDLE hSCManager;
SC_HANDLE hService;
SERVICE_STATUS ss;
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
printf("Load Driver\n");
if(hSCManager)
{
printf("Create Service\n");
hService = CreateService(hSCManager, SERVICENAME,
SERVICENAME,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_IGNORE,
SYS_FILE,
NULL, NULL, NULL, NULL, NULL);
printf("CreateService: %d\r\n", GetLastError());
if(!hService) {
hService = OpenService(hSCManager, SERVICENAME, SERVICE_ALL_ACCESS);
}
printf("OpenService: %d\r\n", GetLastError());
if(hService) {
printf("Start Service\n");
StartService(hService, 0, NULL);
printf("StartService: %d\r\n", GetLastError());
HANDLE hFile;
hFile = CreateFile(L"\\\\.\\Global\\TEST\0", GENERIC_READ|GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, NULL);
printf("CreateFile: %d\r\n", GetLastError());
wchar_t pid[1024];
wsprintf(pid, L"%d", processID);
if(hFile) {
char ret[1024];
DWORD bytes;
DeviceIoControl(hFile, 4092, pid, (wcslen(pid)+1)*2, &ret, sizeof(ret), &bytes, NULL);
CloseHandle(hFile);
}
printf("Press Enter to close service\r\n");
getchar();
ControlService(hService, SERVICE_CONTROL_STOP, &ss);
DeleteService(hService);
CloseServiceHandle(hService);
}
CloseServiceHandle(hSCManager);
}
}
现在所有这一切都不会崩溃或损坏或给我蓝屏,但它给我驱动程序中的错误输出,但是如果我不强制转换并将它用作PVOID,那么它会给我正确的输出
【问题讨论】:
-
这是 32 位还是 64 位?
-
@RogerRowland: 32 位,但我也会做 64 位
-
你的意思“不起作用”是什么意思?不编译?崩溃?把电脑变成会飞的白菜? “我想用作句柄的进程 ID”是什么意思,有什么意义?
-
我已经添加了完整的源代码,请查看它
标签: windows winapi kernel driver msdn