前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >内核挂钩调试记录

内核挂钩调试记录

作者头像
战神伽罗
发布2019-07-24 15:36:46
5750
发布2019-07-24 15:36:46
举报

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 received\n");
			status = RtlCharToInteger(buffer, 10, &malware_pid);
			Dbg("malware_pid : %d\n", malware_pid);
			if(NT_SUCCESS(status) && malware_pid > 0)
				StartMonitoringProcess(malware_pid);				
			break;	

		case IOCTL_PROC_TO_HIDE:
			Dbg("pids to hide : %s\n", 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 large\n");
				return STATUS_BUFFER_TOO_SMALL;
			}
			Dbg("cuckoo path : %ws\n", 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 zer0m0n\n", 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 zer0m0n\n", pid);
            free(s_pid);
        

            fprintf(stderr, "[+] cuckoo path : %ls\n", 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 zer0m0n\n", cuckoo_path);
        }
        else
            fprintf(stderr, "[-] failed to access kernel driver\n");
        CloseHandle(hDevice);
    }

下面也是一种方法:

NtDebugActiveProcess( __in HANDLE ProcessHandle, __in HANDLE DebugHandle);

通过调用这个传入挂钩的handle,由于内核中hook了这个,因此宿主只要调用这个,就把自己传入进来了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档