将PVOID转换为ULONG或在Windows内核驱动程序中将PVOID用作HANDLE

时间:2013-11-28 12:16:07

标签: windows winapi kernel driver msdn

我正在尝试将PVOID转换为ULONG,但它总是失败并且给我错误的数据,并且还建议不要将转换指针变量键入int,ulong或msdn中的其他数据类型,如ULONG client = (ULONG) pvoidVar但是我尝试了不同的技术和预定义的功能,如:

ULONG client = PtrToUlong(pvoidVar);
ULONG client = (ULONG) PtrToUlong(pvoidVar);

发生的事情是我正在尝试将客户端ID从用户模式应用程序发送到内核驱动程序,但内核驱动程序中的接收部分使其成为PVOID Irp->UserBuffer,它还发送了我想用作{的进程ID {1}}现在现在句柄与HANDLE相同,我想直接使用它,但它仍然不起作用:

PVOID

我到处都读过,所有人都建议使用HANDLE processID = (HANDLE) Irp->UserBuffer; HANDLE processID = Irp->UserBUffer; PtrToUlongHANDLE相同,我错了吗?请告诉我如何将PVOID转换为PVOID或如何将ULONG用作PVOID

EDIT ---

这是我的主驱动程序的代码,它没有崩溃,但是给了我错误的输出

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); } } 只有它然后它给了我正确的输出

2 个答案:

答案 0 :(得分:1)

您错过了指针取消引用:

HANDLE processID = *(HANDLE*)Irp->UserBuffer;

还要注意sizeof(HANDLE)取决于进程位数,因此最好使用固定大小类型。对于PID / TID值,32位就足够了。

<强>更新

此外,您正在传递PID的字符串表示形式。使用二进制形式:

DeviceIoControl(hFile, 4092, &processID, sizeof(processID)

答案 1 :(得分:0)

您说您正在尝试从用户向内核空间发送“客户端ID”。这个实体“客户端ID”是什么?我不熟悉这个词。

  • 如果它是一个指针,那么它在(最多)用户空间或内核空间之一是有意义的,所以将它从一个传递到另一个是没有意义的;这些是单独的地址空间。
  • 如果是ULONG,那么您不需要进行类型转换,因此您的问题是错误的。
  • 如果您认为它既是指针又是ulong,那么您可能会感到困惑,因为它们是不同的类型。

进程ID与此问题有什么关系?它们是第四种类型的实体,既不是你的客户身份,也不是指针,也不是指针。

对不起,我忍不住多了;我无法理解你想要做什么。

我不得不说,你试图编写Win32内核模式代码让我很害怕,但看起来很困惑。也许您应该解释为什么您认为需要编写内核模式代码。你应该从一开始就开始:“我正在努力建立一个能够实现......的软件系统。”