سؤال

I am trying to convert PVOID to ULONG but it always fails and gives me wrong data and it is also adviced that not to type cast pointer variables to int, ulong or such other data types in msdn like ULONG client = (ULONG) pvoidVar but i tried different techniques and pre defined functions like:

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

What is happening is that i am trying to send client id from a usermode app to kernel driver but the recieving part in kernel driver makes it as PVOID Irp->UserBuffer also it sends process id which i want to use as a HANDLE now now handles are same as PVOID and i thought of using it directly but it still doesn't work like:

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

I have read everywhere and all have adviced to use PtrToUlong and HANDLE is same as PVOID am i wrong? please advice me how to convert PVOID to ULONG or how can i use PVOID as a HANDLE

EDIT---

here is the code for my main driver it doesn't crash but gives me wrong output

#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;

}

here is my user mode app

#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);
    }

}

Now all this doesn't crash or break or give me blue screen but it gives me the wrong output in the driver how ever if i do not cast it and use it as PVOID only then it gives me the correct output

هل كانت مفيدة؟

المحلول

You have missed a pointer dereference:

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

Also pay attention that sizeof(HANDLE) depends on a process bitness, so it is better to use fixed size types. For PID/TID values 32-bit is enough.

Update:

Also you are passing a string representation of the PID. Use a binary form:

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

نصائح أخرى

You say you're trying to send a "client id" from user to kernel space. What is this entity "client id"? I am not familiar with this term.

  • If it is a pointer, then it is meaningful in (at maximum) one of either user space or kernel space, so it makes no sense to pass it from one to the other; these are separate address spaces.
  • If it is a ULONG, then you don't need to do type conversions, so your question is wrong.
  • If you think it is both a pointer and a ulong, then you are probably confused, as these are different types.

What do process IDs have to do with this problem? They are a fourth type of entity, neither your 'client id's nor pointers nor ulongs.

I'm sorry I can't help more; I can't understand what you are trying to do.

I have to say, it scares me greatly that you are attempting to write Win32 kernel-mode code, but seem very confused. Perhaps you should explain why you think you need to write kernel-mode code. You should probably start at the very beginning: "I am trying to make a software system that achieves..."

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top