• 代码这样写奇丑无比...编码前期要做好规划工作啊


    NTSTATUS ScDetective_DispatchDeviceControl(
        IN PDEVICE_OBJECT        DeviceObject,
        IN PIRP                    Irp
        )
    {
        NTSTATUS    ntStatus = STATUS_SUCCESS;
        PVOID       InputBuffer     = NULL;
        PVOID       OutputBuffer    = NULL;
        ULONG       cbInputBuffer   = 0;
        ULONG       cbOutputBuffer  = 0;
        PIO_STACK_LOCATION irpSp    = NULL;
        
        __try {
            irpSp = IoGetCurrentIrpStackLocation(Irp);
    
            InputBuffer     = Irp->AssociatedIrp.SystemBuffer;
            cbInputBuffer   = irpSp->Parameters.DeviceIoControl.InputBufferLength;
            OutputBuffer    = Irp->AssociatedIrp.SystemBuffer;
            cbOutputBuffer  = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
    
            switch(irpSp->Parameters.DeviceIoControl.IoControlCode)
            {
            case IOCTL_DUMP_KERNEL_MEMORY: 
                {
                    PVOID DumpAddress;
                    PMDL MdlCreate;
    
                    if (cbInputBuffer == sizeof(ULONG)) {
                        DumpAddress = (PVOID)((PULONG)InputBuffer)[0];
                        if (!MmIsAddressValid(DumpAddress)) {
                            ntStatus = STATUS_INVALID_ADDRESS;
                            break;
                        } else {
                            ScmMapVirtualAddress(DumpAddress, cbOutputBuffer, &MdlCreate);
                            RtlCopyMemory(OutputBuffer, DumpAddress, cbOutputBuffer);
                            ScmUnmapVirtualAddress(MdlCreate);
                            Irp->IoStatus.Information = cbOutputBuffer;  break; 
                        }
                    } else {
                        ntStatus = STATUS_BUFFER_TOO_SMALL;  break;
                    }
                }
            //////////////////////////////////////////////////////////////////////////
            case IOCTL_GET_SSDT:    // 获取 ssdt
                {         
                    ULONG NeedLen = 0;
                    ULONG Number = GetSsdtServiceNumber();
    
                    NeedLen = Number * sizeof(SSDT_ADDRESS);
                    if (cbOutputBuffer < NeedLen) {
                        if (cbOutputBuffer == sizeof(ULONG)) {
                            ((PULONG)OutputBuffer)[0] = NeedLen;
                            Irp->IoStatus.Information = sizeof(ULONG);
                            break;
                        }
                        ntStatus = STATUS_BUFFER_TOO_SMALL;  break;
                    }
                    Number = GetSsdtCurrentAddresses((PSSDT_ADDRESS)OutputBuffer, &NeedLen);
                    if (Number == 0)  ntStatus = STATUS_UNSUCCESSFUL;
                    Irp->IoStatus.Information = Number * sizeof(SSDT_ADDRESS);
                    break;
                } 
            //////////////////////////////////////////////////////////////////////////
            case IOCTL_UNHOOK_SSDT:          // 恢复 ssdt
                {
                    PSSDT_ADDRESS SsdtOrig = (PSSDT_ADDRESS)InputBuffer;
    
                    if (cbInputBuffer < sizeof(SSDT_ADDRESS) || 
                        InputBuffer == NULL) {
                        KdPrint(("输入缓冲区或输入缓冲区长度无效"));
                        ntStatus = STATUS_UNSUCCESSFUL;
                        break;
                    }
                    KdPrint(("要恢复的服务号:%d 原始地址:0x%X", 
                        SsdtOrig->nIndex, SsdtOrig->FunAddress));
    
                    if (!UnHookSsdtItem(SsdtOrig)) {
                        KdPrint(("恢复失败"));
                        ntStatus = STATUS_UNSUCCESSFUL;
                    }
                    break;
                } 
            //////////////////////////////////////////////////////////////////////////
            case IOCTL_GET_SSDTSHADOW:
                {
                    ULONG Number = GetShadowSsdtServiceNumber();
                    ULONG NeedLen = 0;
                    
                    NeedLen = Number * sizeof(SSDT_ADDRESS);
                    if (cbOutputBuffer < NeedLen) {
                        if (cbOutputBuffer == sizeof(ULONG)) {
                            ((PULONG)OutputBuffer)[0] = NeedLen;
                            Irp->IoStatus.Information = sizeof(ULONG);
                            break;
                        }
                        ntStatus = STATUS_BUFFER_TOO_SMALL;  break;
                    }
                    Number = GetShadowSsdtCurrentAddresses((PSSDT_ADDRESS)OutputBuffer, &NeedLen);
    
                    if (Number == 0)  ntStatus = STATUS_UNSUCCESSFUL;
                    Irp->IoStatus.Information = Number * sizeof(SSDT_ADDRESS);
                    break;
                }
            //////////////////////////////////////////////////////////////////////////
            case IOCTL_UNHOOK_SSDTSHADOW:
                {
                    PSSDT_ADDRESS ShadowSsdtOrig = (PSSDT_ADDRESS)InputBuffer;
    
                    if (cbInputBuffer < sizeof(SSDT_ADDRESS) || 
                        InputBuffer == NULL) {
                        KdPrint(("输入缓冲区或输入缓冲区长度无效"));
                        ntStatus = STATUS_UNSUCCESSFUL;  break;
                    }
                    KdPrint(("要恢复的服务号:%d 原始地址:0x%X", 
                        ShadowSsdtOrig->nIndex, ShadowSsdtOrig->FunAddress));
    
                    if (!UnHookShadowSsdtItem(ShadowSsdtOrig, g_CsrssProcess)) {
                        ntStatus = STATUS_UNSUCCESSFUL;
                    }
                    break;
                }
            //////////////////////////////////////////////////////////////////////////
            case IOCTL_GET_PROCESSES:  
                {
                    PPROCESS_LIST_HEAD ProcessHead;
                    ULONG NeedLen;
                    ULONG ReturnLength;
    
                    ProcessHead = ScPsQuerySystemProcessList();
                    NeedLen = ProcessHead->NumberOfProcesses * sizeof(PROCESS_INFO);
    
                    if (cbOutputBuffer < NeedLen) {
                        if (cbOutputBuffer == sizeof(ULONG)) {
                            ((PULONG)OutputBuffer)[0] = NeedLen;
                            Irp->IoStatus.Information = sizeof(ULONG);
                            break;
                        }
                        ntStatus = STATUS_BUFFER_TOO_SMALL; break;
                    }
                    ReturnLength = ExCopyProcessList2Buffer((PPROCESS_INFO)OutputBuffer);
                    if (ReturnLength == 0)  ntStatus = STATUS_UNSUCCESSFUL;
                    Irp->IoStatus.Information = ReturnLength;
                    break;
                }
            //////////////////////////////////////////////////////////////////////////
            case IOCTL_GET_PROCESS_IMAGE_PATH:
                {
                    PEPROCESS Process = NULL;
                    PUNICODE_STRING NameString;
                    ULONG BufferSize;
    
                    if (cbInputBuffer == sizeof(ULONG)) {
                        Process = ((PEPROCESS*)InputBuffer)[0];
                        if (Process == NULL) {
                            ntStatus = STATUS_ACCESS_DENIED; break;
                        }
                    } else {
                        ntStatus = STATUS_BUFFER_TOO_SMALL;
                        break;
                    }
                    if (Process == g_SystemProcess) {
                        if (cbOutputBuffer > sizeof(L"System")) {
                            RtlCopyMemory(OutputBuffer, L"System", sizeof(L"System"));
                            Irp->IoStatus.Information = sizeof(L"System");
                            break; 
                        }
                    } else if (Process == g_IdleProcess) {
                        if (cbOutputBuffer > sizeof(L"Idle")) {
                            RtlCopyMemory(OutputBuffer, L"Idle", sizeof(L"Idle"));
                            Irp->IoStatus.Information = sizeof(L"Idle");
                            break; 
                        }
                    }
                    if (cbOutputBuffer < 520) {
                        ntStatus = STATUS_BUFFER_TOO_SMALL;
                        break;
                    }
                    BufferSize = cbOutputBuffer + sizeof(UNICODE_STRING);
                    NameString = ExAllocatePoolWithTag(NonPagedPool, BufferSize, MEM_TAG);
                    NameString->Buffer = (PWCH)((ULONG)NameString + 8);
                    NameString->Length = 0;
                    NameString->MaximumLength = (USHORT)cbOutputBuffer;
    
                    ntStatus = ScPsGetProcessImagePath(Process, NameString);
                    if (NT_SUCCESS(ntStatus)) {
                        RtlCopyMemory(OutputBuffer, NameString->Buffer, NameString->Length);
                    }
                    Irp->IoStatus.Information = NameString->Length;
                    ExFreePoolWithTag(NameString, MEM_TAG);
                    break;
                }
            //////////////////////////////////////////////////////////////////////////
            case IOCTL_GET_PROCESS_THREADS:
                {            
                    PTHREAD_LIST_HEAD ThreadHead = NULL;
                    PEPROCESS EProcess = NULL;
                    ULONG NeedLen = 0;
                    ULONG ReturnLength = 0;
                    
                    if (cbInputBuffer == sizeof(ULONG)) {
                        EProcess = ((PEPROCESS*)InputBuffer)[0];
                    } else {
                        ntStatus = STATUS_BUFFER_TOO_SMALL;
                        break;
                    }
                    if (EProcess == g_IdleProcess) {
                        if (cbOutputBuffer == sizeof(ULONG)) {
                            ((PULONG)OutputBuffer)[0] = NeedLen;  
                            Irp->IoStatus.Information = sizeof(ULONG);
                            break; 
                        }
                    }
                    ThreadHead = ScPsQueryProcessThreadList(EProcess);
                    if (ThreadHead == NULL) {
                        ntStatus = STATUS_UNSUCCESSFUL;
                        break;
                    }
                    NeedLen = ThreadHead->NumberOfThread * sizeof(THREAD_INFO);
     
                    if (cbOutputBuffer < NeedLen) {
                        if (cbOutputBuffer == sizeof(ULONG)) {
                            ((PULONG)OutputBuffer)[0] = NeedLen;
                            Irp->IoStatus.Information = sizeof(ULONG);
                            break;
                        }
                        ntStatus = STATUS_BUFFER_TOO_SMALL;  break;
                    }
                    ReturnLength = ExCopyThreadList2Buffer((PTHREAD_INFO)OutputBuffer);
                    if (ReturnLength == 0)  ntStatus = STATUS_UNSUCCESSFUL;
                    Irp->IoStatus.Information = ReturnLength;
                    break;
                }
            //////////////////////////////////////////////////////////////////////////
            case IOCTL_GET_PROCESS_MODULES:
                {
                    PMODULE_LIST_HEAD ModuleHead = NULL;
                    PEPROCESS EProcess = NULL;
                    ULONG NeedLen = 0;
                    ULONG ReturnLength = 0;
    
                    if (cbInputBuffer == sizeof(ULONG)) {
                        EProcess = ((PEPROCESS*)InputBuffer)[0];
                    } else {
                        ntStatus = STATUS_BUFFER_TOO_SMALL;  break;
                    }
    
                    if (EProcess == g_IdleProcess) {
                        if (cbOutputBuffer = sizeof(ULONG)) {
                            ((PULONG)OutputBuffer)[0] = NeedLen;
                            Irp->IoStatus.Information = sizeof(ULONG);
                            break; 
                        }
                    }
                    ModuleHead = ScPsQueryProcessModuleList(EProcess);
                    if (ModuleHead == NULL) {
                        ntStatus = STATUS_UNSUCCESSFUL;  break;
                    }
                    NeedLen = ModuleHead->NumberOfModules * sizeof(MODULE_INFO);
    
                    if (cbOutputBuffer < NeedLen) {
                        if (cbOutputBuffer == sizeof(ULONG)) {
                            ((PULONG)OutputBuffer)[0] = NeedLen;
                            Irp->IoStatus.Information = sizeof(ULONG);
                            break;
                        }
                        ntStatus = STATUS_BUFFER_TOO_SMALL;  break;
                    }
                    ReturnLength = ExCopyModuleList2Buffer((PMODULE_INFO)OutputBuffer);
                    if (ReturnLength == 0)  ntStatus = STATUS_UNSUCCESSFUL;
                    Irp->IoStatus.Information = ReturnLength;
                    break;
                }
            //////////////////////////////////////////////////////////////////////////
            case IOCTL_GET_DRIVER_OBJECT:
                {
                    PDRIVER_LIST_HEAD DriverHead = NULL;
                    PEPROCESS EProcess = NULL;
                    HANDLE UserEvent;
                    PKEVENT kEvent;
                    ULONG NeedLen = 0;
                    ULONG ReturnLength = 0;
    
                    if (cbInputBuffer == sizeof(HANDLE) * 2) {
                        UserEvent = *(PHANDLE)InputBuffer;
                        ntStatus = ObReferenceObjectByHandle(UserEvent, 0, 
                                    *ExEventObjectType, UserMode, &kEvent, NULL);
                        if (NT_SUCCESS(ntStatus)) {
                            ScObQueryDriverObject(pdoGlobalDrvObj, kEvent);
                            ObDereferenceObject(kEvent);
                        }
                        Irp->IoStatus.Information = 0;  break;
                    }
    
                    DriverHead = ScObQueryDriverObject(NULL, NULL);
                    if (DriverHead == NULL) {
                        ntStatus = STATUS_UNSUCCESSFUL;  break;
                    }
                    NeedLen = DriverHead->NumberOfDrivers * sizeof(DRIVER_INFO);
    
                    if (cbOutputBuffer < NeedLen) {
                        if (cbOutputBuffer == sizeof(ULONG)) {
                            ((PULONG)OutputBuffer)[0] = NeedLen;
                            Irp->IoStatus.Information = sizeof(ULONG);
                            break;
                        }
                        ntStatus = STATUS_BUFFER_TOO_SMALL;  break;
                    }
                    ReturnLength = ExCopyDriverList2Buffer((PDRIVER_INFO)OutputBuffer);
                    if (ReturnLength == 0)  ntStatus = STATUS_UNSUCCESSFUL;
                    Irp->IoStatus.Information = ReturnLength;
                    break;
                }
            //////////////////////////////////////////////////////////////////////////
            case IOCTL_LIST_DIRECTORY:
                {
                    PWCHAR pszDirectory;
                    ULONG NeedLength;
                    ULONG ReturnLength;
                    PFILE_LIST_HEAD FileHead;
    
                    pszDirectory = ExAllocatePoolWithTag(PagedPool, 260 * 2, MEM_TAG);
                    RtlZeroMemory(pszDirectory, 260 * 2);
    
                    if (cbInputBuffer == 260 * 2) {
                        RtlCopyMemory(pszDirectory, InputBuffer, 260 * 2);
                    } else {
                        ntStatus = STATUS_BUFFER_TOO_SMALL;  break;
                    }
    
                    FileHead = ScfsQueryDirectoryInformation(pszDirectory);
                    if (FileHead == NULL) {
                        ((PULONG)OutputBuffer)[0] = 0;
                        Irp->IoStatus.Information = sizeof(ULONG);
                        ntStatus = STATUS_SUCCESS;  break;
                    }
                    NeedLength = FileHead->NumberOfItems * sizeof(FILE_INFO);
    
                    if (cbOutputBuffer < NeedLength) {
                        if (cbOutputBuffer == sizeof(ULONG)) {
                            ((PULONG)OutputBuffer)[0] = NeedLength;
                            Irp->IoStatus.Information = sizeof(ULONG);
                            break;
                        }
                        ntStatus = STATUS_BUFFER_TOO_SMALL; break;
                    }
                    ReturnLength = ExCopyFileList2Buffer((PFILE_INFO)OutputBuffer);
                    if (ReturnLength == 0)  ntStatus = STATUS_UNSUCCESSFUL;
                    Irp->IoStatus.Information = ReturnLength;
                    ExFreePoolWithTag(pszDirectory, MEM_TAG);
                    break;
                }
            //////////////////////////////////////////////////////////////////////////
            case IOCTL_PROTECT_MYSELF:
                {
                    HANDLE ProcessId;
                    if (cbInputBuffer == sizeof(ULONG)) {
                        ProcessId = ((PHANDLE)InputBuffer)[0];
                        if (ProcessId) {
                            ntStatus = ScPtHideProcessById(ProcessId);
                        }
                    }
                    Irp->IoStatus.Information = 0;
                    break;
                }
            //////////////////////////////////////////////////////////////////////////
            case IOCTL_EXIT_PROCESS:
                ScPtUnloadRoutine();
                break;
            //////////////////////////////////////////////////////////////////////////
            default:
                Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
                Irp->IoStatus.Information = 0;
                break;
            }
        } __except (EXCEPTION_EXECUTE_HANDLER) {
            ntStatus = GetExceptionCode();
            Irp->IoStatus.Information = 0;
        }
      
        Irp->IoStatus.Status = ntStatus;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return ntStatus;
    }

    应该像psnull那样把各个分发例程分两层处理的,不但看起来美观,而且方便管理

    一旦内核和用户层交互多了,这该怎么管理啊,真后悔开始没有多参考优秀的工程啊

    以后又有很多体力活要做了。。。

    -------------------------------------------------------

    kedebug

    Department of Computer Science and Engineering,

    Shanghai Jiao Tong University

    E-mail: kedebug0@gmail.com

    GitHub: http://github.com/kedebug

    -------------------------------------------------------

  • 相关阅读:
    左划删除
    UILabel 添加图片
    Swift-11-委托模式
    Swift-11-协议(Protocols)
    Swift-10--错误处理
    Swift-09-可空链式调用(Optional Chaining)
    Swift-08-闭包引起的循环强引用
    Swift-07-析构器deinit
    Swift-06-闭包
    【转】HTML5标签使用的常见误区
  • 原文地址:https://www.cnblogs.com/kedebug/p/2791749.html
Copyright © 2020-2023  润新知