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

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那样把各个分发例程分两层处理的,不但看起来美观,而且方便管理

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

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

你可能感兴趣的:(工作)