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)