NTSTATUS Ioctl_DeviceControl(__in PDEVICE_OBJECT pDeviceObject, __in PIRP pIrp)
项目地址:https://github.com/angelkillah/zer0m0n
传入要监控的pid,具体代码例子:
代码语言:javascript复制NTSTATUS Ioctl_DeviceControl(__in PDEVICE_OBJECT pDeviceObject,
__in PIRP pIrp)
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION pIoStackIrp = NULL;
PCHAR buffer;
ULONG ioControlCode;
ULONG inputLength;
ULONG malware_pid = 0;
if(pIrp == NULL || pDeviceObject == NULL)
return STATUS_INVALID_PARAMETER;
pIoStackIrp = IoGetCurrentIrpStackLocation(pIrp);
ioControlCode = pIoStackIrp->Parameters.DeviceIoControl.IoControlCode;
inputLength = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;
buffer = pIrp->AssociatedIrp.SystemBuffer;
switch(ioControlCode)
{
case IOCTL_PROC_MALWARE:
Dbg("IOCTL_PROC_MALWARE receivedn");
status = RtlCharToInteger(buffer, 10, &malware_pid);
Dbg("malware_pid : %dn", malware_pid);
if(NT_SUCCESS(status) && malware_pid > 0)
StartMonitoringProcess(malware_pid);
break;
case IOCTL_PROC_TO_HIDE:
Dbg("pids to hide : %sn", buffer);
status = ParsePids(buffer);
RtlZeroMemory(buffer, inputLength);
break;
case IOCTL_CUCKOO_PATH:
cuckooPath = PoolAlloc(MAX_SIZE);
if(inputLength && inputLength < MAX_SIZE)
RtlStringCchPrintfW(cuckooPath, MAX_SIZE, L"\??\%ws", buffer);
else
{
Dbg("IOCTL_CUCKOO_PATH : Buffer too largen");
return STATUS_BUFFER_TOO_SMALL;
}
Dbg("cuckoo path : %wsn", cuckooPath);
break;
default:
break;
}
pIrp->IoStatus.Status = status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
注册接口:
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Ioctl_DeviceControl;
ring3调用方式,代码如下:
代码语言:javascript复制 if(kernel_analysis)
{
Sleep(5000);
// get handle to device driver and send IOCTLs
hDevice = CreateFile(PATH_KERNEL_DRIVER, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hDevice != INVALID_HANDLE_VALUE)
{
// send processes pid to hide
processes_to_hide = malloc(MAX_PATH);
sprintf(processes_to_hide, "%d,%d,%d", GetCurrentProcessId(), pid_from_process_name(L"VBoxService.exe"), pid_from_process_name(L"VBoxTray.exe"));
if(DeviceIoControl(hDevice, IOCTL_PROC_TO_HIDE, processes_to_hide, strlen(processes_to_hide), NULL, 0, &dwBytesReturned, NULL))
fprintf(stderr, "[ ] processes to hide [%s] sent to zer0m0nn", processes_to_hide);
free(processes_to_hide);
// send malware's pid
s_pid = malloc(MAX_PATH);
sprintf(s_pid, "%d", pid);
if(DeviceIoControl(hDevice, IOCTL_PROC_MALWARE, s_pid, strlen(s_pid), NULL, 0, &dwBytesReturned, NULL))
fprintf(stderr, "[ ] malware pid : %s sent to zer0m0nn", pid);
free(s_pid);
fprintf(stderr, "[ ] cuckoo path : %lsn", cuckoo_path);
// send current directory
if(DeviceIoControl(hDevice, IOCTL_CUCKOO_PATH, cuckoo_path, 200, NULL, 0, &dwBytesReturned, NULL))
fprintf(stderr, "[ ] cuckoo path %ws sent to zer0m0nn", cuckoo_path);
}
else
fprintf(stderr, "[-] failed to access kernel drivern");
CloseHandle(hDevice);
}
下面也是一种方法:
NtDebugActiveProcess( __in HANDLE ProcessHandle, __in HANDLE DebugHandle);
通过调用这个传入挂钩的handle,由于内核中hook了这个,因此宿主只要调用这个,就把自己传入进来了。