首页
社区
课程
招聘
[转帖]网上找到的部分内核函数C原型
发表于: 2014-1-15 13:39 7358

[转帖]网上找到的部分内核函数C原型

2014-1-15 13:39
7358
由于部分代码打上了extern,部分代码完全是通过汇编实现的,很难用C语言描述,所以我们希望能够得到函数的原型。
以下代码是从网上看到的,希望有帮助。当然有部分wrk已经有了,我是原帖转过来的
1.IoCallDriver
NTSTATUS
IoCallDriver(
        IN PDEVICE_OBJECT  DeviceObject,
        IN OUT PIRP Irp
        )
{
        if (pIofCallDervier != NULL)
        {
                return pIofCallDervice(IoCallDriver);
        }
       
        //
        // 现在:push the stack
        // 包括:1) Irp->CurrentLocation 计数
        // 2) Irp->Tail.Overlay.CurrentStackLocation 当前 stack 位置 push
        //
        if (--Irp->CurrentLocation <= 0)
        {
                KeBugCheckEx(35, Irp,  0, 0, 0);
        }
       
        PIO_STACK_LOCATION Stack = --Irp->Tail.Overlay.CurrentStackLocation;
        Stack->DeviceObject = DeviceObject;
        PDRVIER_OBJECT Driver = DeviceObject->DriverObject;
       
        //
        //调用 driver's dispatch routine
        //
        return (*Drivert->MajorFunction[Stack->MajorFunction])(DeviceObject, Irp);
}
2. IoGetDeviceObjectPointer()

NTSTATUS
IoGetDeviceObjectPointer(
        IN PUNICODE_STRING  ObjectName,
        IN ACCESS_MASK  DesiredAccess,
        OUT PFILE_OBJECT  *FileObject,
        OUT PDEVICE_OBJECT  *DeviceObject
        )
{
        PIO_STATUS_BLOCK IoStatusBlock;       
        OBJECT_ATTRIBUTES ObjectAttributes;       
        HANDLE FileHandle;
        PVOID  Object;

        //
        // 初始化 OBJECT_ATTRIBUTE 结构
        //
        ObjectAttributes.Length = sizeof(ObjectAttributes);
        ObjectAttributes.RootDirectory = NULL;
        ObjectAttributes.Attributes = OBJ_KERNEL_HANDLE;
        ObjectAttributes.SecurityDescriptor = NULL;
        ObjectAttributes.SecurityQualityOfService = NULL;
        ObjectAttributes.ObjectName = ObjectName;

        NTSTATUS Status = ZwOpenFile(&FileHandle,
                                DesiredAccess,
                                &ObjectAttributes,
                                &IoStatusBlock,
                                0,
                                FILE_NON_DIRECTORY_FILE);

        if (!NT_SUCCESS(Status))
        {
                return Status;
        }

        Status = ObReferenceObjectByHandle(FileHandle,  0, IoFileObjectType, KerneMode, &Object, NULL);

        if (NT_SUCCESS(Status))
        {
                *FileObject = Object;
                *DeviceObject = IoGetRelatedDeviceObject(Object);
        }

        ZwClose(FileHandle);
        return Status;
}
3. IoGetAttachedDeviceReference()

PDEVICE_OBJECT
IoGetAttachedDeviceReference(
        IN PDEVICE_OBJECT  DeviceObject
        )
{
        PDEVICE_OBJECT devObj;
        KIRQL OldIrql = KeRaiseIrlToDpcLevel();

        devObj = IoGetAttachedDevice(DeviceObject);
        ObfReferenceObject(devObj);

        KfLowerIrql(OldIrql);
        return devObj;
}
4. ObfReferenceObject()

LONG ObfReferenceObject(PVOID Object)
{
        POBJECT_HEADER ObjectHeader = CONTAINING_RECORD(Object, OBJECT_HEADER, Body);

        if (ObpTraceEnabled == TRUE)
        {
                ObpPushStackInfo(ObjectHeader, 1);
        }

        return InterlockedIncrement(ObjectHeader->PointerCount);
}
5. ObReferenceObjectByHandle()

NTSTATUS
ObReferenceObjectByHandle(
        IN HANDLE Handle,
        IN ACCESS_MASK DesiredAccess,
        IN POBJECT_TYPE ObjectType,
        IN KPROCESSOR_MODE AccessMode,
        OUT PVOID *Object,
        OUT POBJECT_HANDLE_INFORMATION HandleInformation
        )

{
        PKTHREAD Thread = GetCurrentThread();                // fs:[124h]
        PHANDLE_TABLE HandleTable;
        ACCESS_MASK GrantedAccess;
        PKPROCESS Process;
        PEPROCESS EProcess;
        PETHREAD EThread;

        PHANDLE_TABLE_ENTRY TableEntry;
        PHANDLE_TABLE_ENTRY_INFO EntryInfo;
        POBJECT_HEADER ObjectHeader;
        ULONG ObAttributes;

        PLIST_ENTRY ListEntry;
        NTSTATUS Status;
       
        *Object = NULL;

        //
        // BodyPointer 的值用来计算出 OBJECT_HEADER 结构地址:
        // 1. 当 Handle = -1(KPROCESS handle)时,BodyPointer 为 Process值(由 Thread->ApcState.Process 得到)
        // 2. 当 Handle = -2(KTHREAD handle)时,BodyPointer 为 Thread 值
        //
        PVOID BodyPointer;

        if ((LONG)Handle < 0)
        {
                //
                // 如果 Handle 是当前 KPROCESS  handle 的话
                // 当前 process 的 handle 为 -1
                //
                if (Handle == 0xFFFFFFFF)
                {
                        if ((ObjectType != PsProcessType) && (ObjectType != NULL))
                        {
                                return STATUS_ACCESS_DENIED;                                        // 值为 0C0000024h
                        }

                        //
                        // 从 KTHREAD 结构(ApcState.Process 域)里得到 KPROCESS 结构指针
                        // 这个 KPROCESS 指针指向一个 EPROCESS 结构的 Pcb 域(KPROCESS 变量)
                        // 根据这个得到 EPROCESS 结构地址!
                        //
                        Process = Thread->ApcState.Process;                                        // KPROCESS 结构
                        EProcess = CONTAINING_RECORD(Process, EPROCESS, Pcb);                        // EPROCESS 结构
                        GrantedAccess = EProcess->GrantedAccess;

                        //
                        // 当前的 Process 指向 OBJECT_HEADER 结构的 Body 域
                        // 用 Process 值求出 OBJECT_HEADER 结构地址!
                        //
                        BodyPointer = Process;
                }
                else if (Handle == 0xFFFFFFFE)
                {
                        //
                        // 如果 Handle 是当前 KTHREAD handle 的话
                        // 当前 thread 的 handle 为 -2 (0FFFFFFFEh)
                        //

                        if ((ObjectType != PsThreadType) && (ObectType != NULL))
                        {
                                return STATUS_ACCESS_DENIED;
                        }

                        //
                        // 此时:Thread 指向 ETHREAD 结构的 Tcb 成员!
                        // 根据 Tcb 得到宿主 ETHREAD  结构地址
                        //
                        EThread = CONTAINING_RECORD(Thread, ETHREAD, Tcb);                        // ETHREAD 结构
                        GrantedAccess = EThread->GrantedAccess;

                        //
                        // 当前的 Thread 指向 OBJECT_HEADER 结构的 Body 域
                        // 用 Thread 值求出 OBJECT_HEADER 结构地址!
                        //
                        BodyPointer = Thread;
                }
                else
                {
                        //
                        // 测试 AccessMode 是否为 KernelMode(值为 0)
                        //
                        if (AccessMode  == KernelMode)
                        {
                                Handle ^= 0x80000000;                                                // 调整 Handle 值
                                HandleTable = ObpKernelHandleTable;                                // 使用全局变量 ObpKernelHandleTable 值
                        }
                        else
                        {
                                return STATUS_INVALID_HANDLE;
                        }
                       
                }

                //
                // 下面代码,在 handle 属于当前 process 或 thread 时,进行操作
                //

                if ((Handle == 0xFFFFFFFF || Handle == 0xFFFFFFFE)
                {
               
                        if (((~GrantedAccess & DesiredAccess) != 0) && (AccessMode != KernelMode))
                        {
                                return STATUS_ACCESS_DENIED;
                        }

                        //
                        // 设置 Handlle information 返回结构
                        //
                        if (HandleInformation != NULL)       
                        {
                                HandleInformation->GrantedAccess = GrantedAccess;
                                HandleInformation->HandleAttributes = 0;
                        }

                       
                        //
                        // 根据 BodyPointer(指向 OBJECT_HEADER 结构的 Body 域)来得到 OBJECT_HEADER 结构地址
                        // 在 Handle = -1 时,BodyPointer = Process
                        // 在 Handle = -2 时,BodyPointer = Thread
                        //
                        ObjectHeader = CONTAINING_RECORD(BodyPointer, OBJECT_HEADER, Body);

                        if (ObpTraceEnabled == TRUE)
                        {
                                ObpPushStackInfo(ObjectHeader, 1);
                        }

                        //
                        // 增加 Object 计数
                        //
                        InterlockedIncrement(ObjectHeader->PointerCount);

                        //
                        // 成功:返回 Object 值
                        //
                        *Object = Thread;

                        return STATUS_SUCCESS;
                }

        }
        else
        {
                //
                // 当前 handle >= 0 时:得到当前 EPROCESS 结构地址和 HANDLE_TABLE 结构
                //
                Process = Thread->>ApcState.Process;
                EProcess = CONTAINING_RECORD(Process, EPROCESS, Pcb);
                HandleTable = &EProcess->ObjectTable;
        }

        //
        // KeEnterCriticalRegionThread() 实现:对 KernelApcDisable -- 操作
        //

        Thread->KernelApcDisable--;
        TableEntry = ExMapHandleToPointerEx(HandleTable, Handle, AccessMode);

        if (TableEntry != NULL)
        {
                //
                // 找到 宿主的 OBJECT_HEADER 结构地址
                //
                ObjectHeader = (POBJECT_HEADER )((ULONG)TableEntry->Object & 0xFFFFFFF8);

                //
                // 测试 object 类型,不区配时返回类型不符状态(STATUS_OBJECT_TYPE_MISMATCH)
                //
                if ((ObjectHeader->Type == ObjectType) || (ObjectType == NULL))
                {
                        if (NtGlobalFlag & ***_KERNEL_STACK_TRACE_DB)
                        {
                                GrantedAccess = ObpTranslateGrantedAccessIndex(TableEntry->GrantedAccessIndex);
                        }
                        else
                        {
                                GrantedAccess = TableEntry->GrantedAccess & ~ObpAccessProtectCloseBit;
                        }
                               
                        //
                        // 下面测试访问权限和模式,符合时成功处理
                        // 否则:返回 STATUS_ACCESS_DENIED 状态值
                        //
                        if (((DesiredAccess & ~GrantedAccess) == 0) || (AccessMode == KernelMode))
                        {
                                if (HandleTable->ExtraInfoPages != 0)
                                {
                                        EntryInfo = ExpGetHandleInfo(HandleTable, Handle, TRUE);
                                }
                                else
                                {
                                        EntryInfo = NULL;
                                }

                                //
                                // 设置 HandleInformation 返回信息
                                //
                                if (HandleInformation != NULL)
                                {
                                        HandleInformation->GrantedAccesse = GrantedAccess ;
                                        ObAttributes = TableEntry->ObAttributes;
                               
                                        ObAttributes = ObAttributes & 6;
                                        if (TableEntry->GrantedAccess & ObpAccessProtectCloseBit)
                                        {
                                                ObAttributes = ObAttributes  | 1;
                                        }

                                        HandleInformation->HandleAttributes = ObAttributes;
                                }

                                if ((TableEntry->ObAttributes & 4)
                                        && (EntryInfo != NULL)
                                        && (EntryInfo->AuditMask != 0)
                                        && (DesiredAccess != 0)
                                        && (AccessMode != 0))
                                {
                                        ObpAuditObjectAccess(Handle, EntryInfo, &ObjectHeader->Type->Name, DesiredAccess);
                                }

                                if (ObpTraceEnabled == TRUE)
                                {
                                        ObpPushStackInfo(ObjectHeader, 1);
                                }

                                InterlockedIncrement(ObjectHeader->PointerCount);                // 增加 object 计数
                                ExUnlockHandleTableEntry(HandleTable, ObjectHandler);

                                *Object = &ObjectHeader->Body;                                        // ObjectHeadler 的 Body 域作为 Object 参数值返回
                                Status = STATUS_SUCCESS;
                        }
                        else
                        {
                                //
                                // 返回权限不足
                                //
                                Status = STATUS_ACCESS_DENIED;
                                ExUnlockHandleTableEntry(HandleTable, TableEntry);
                        }
                }
                else
                {
                        //
                        // 返回 object 类型不区配
                        //
                        Status =  STATUS_OBJECT_TYPE_MISMATCH;
                        ExUnlockHandleTableEntry(HandleTable, TableEntry);
                }
        }
        else
        {
                Status = STATUS_INVALID_HANDLE;
        }

        //
        // KeLeaveCriticalRegionThread() 实现:对 KernelApcDisable ++ 操作后:
        // 测试 KernelApcDisable 值是否为 0,并且 ListEntry 是否指向自己
        //

        Thread->KernelApcDisable++;
        ListEntry = &Thread->ApcState.ApcListHead;

        if ((Thread->KernelApcDisable == 0)
                && (Thread->ApcState.ApcListHead.Flink != ListEntry)
                && (Thread->SpecialApcDisable == 0)
        {
                KiCheckForKernelApcDelivery();
        }

        return Status;
}
6. ExpLookupHandleTableEntry()

PHANDLE_TABLE_ENTRY
ExpLookupHandleTableEntry (
        IN PHANDLE_TABLE HandleTable,
        IN EXHANDLE tHandle
        )

{
        PHANDLE_TABLE_ENTRY TableEntry;
        ULONG MaxHandle = HandleTable->NextHandleNeedingPool;
       
        tHandle.TagBits = 0;
       
        if (tHandle.Value >= MaxHandle)
        {
                return NULL;
        }

        //
        // HandleTable->TableCode 结构:
        // (1) bit 0 到 bit 1 得出 TableEntry 的层数(类似分页机制的页表结构层数)
        // (2) bit 2 到 bit 31 是 TableEntry 结构的基址(类似分页机制的 CR3 基址)
        //

        ULONG Level = HandleTable->TableCode & 3;
        ULONG Base =  HandleTable->TableCode & 0xFFFFFFFC;

        ULONG Table;                                        // Table 表基址
        ULONG Scale;                                        // Scale 值用于得出 TableEntry

        switch (Level)
        {
        case 0:
                //
                // 当层数只有一层时:Base 就是最终的 Table 基址,tHandle.Value 就是 Scale 值
                //
                Table = Base;
                Scale = tHandle.Value;
                break;
        case 1:
                //
                // 当层数有两层时:需要求出 Table 基址(放在 Base + TableOffset 地址的内存里)
                // tHandle.Value 的 bit 2 到 bit 10 是 Scale  值
                //
                ULONG TableOffset = (tHandle.Value & 0xFFFFF800) >> 9;                        // 求出 Table Offset 值
                Table = *((PULONG)(Base + TableOffset));                                // 得到 Table 基址
                Scale = tHandle.Value & 0x7FF;
                break;
        default:
                //
                // 否则(层数为三层):
                // (1) 求出 Driectory 基址( 放在 Base + DriectoryOffset 地址的内存里)
                // (2) 求出 Table 基址(放在 Directory + TableOffset 地址内存里)
                // (3) tHandle.Value 的 bit 2 到 bit 10 是 Scale  值
                //

                ULONG TableOffset = ((tHandle.Value & 0xFFFFFF800) >> 9) & 0xFFF;
                ULONG DirectoryOffset = ((tHandle.Value & 0xFFFFFF800) >> 9) & 0xFFFFF000) >> 10;

                ULONG Directory = *((PULONG)(Base + DirectoryOffset));                        // 得到 Diectory 基址
                Table = *((PULONG)(Directory + TableOffset));                                // 得到 Table 基址
                Scale = tHandle.Value & 0x7FF;
                break;
        }

        //
        // 得到最后 TableEntry 结构地址
        //
        TableEntry = (PHANDLE_TABLE_ENTRY)(Table + Sacle * 2);
       
        return TableEntry;
}
7. IoGetRelatedDeviceObject()

PDEVICE_OBJECT
IoGetRelatedDeviceObject(
        IN PFILE_OBJECT  FileObject
        )
{
        PDEVICE_OBJECT DeviceObject;
        PVPB Vpb = FileObject->Vpb;

        //
        // 根据 FileObject 找到当前的 DeviceObject:
        // 1. 如果 Vpb != NULL 并且 Vpb->DeviceObject != NULL,则:DeviceObject = Vpb->DeviceObject
        // 2. 如果 FileObject->DeviceObject->Vpb->DeviceObject != NULL,则:DeviceObject = FileObject->DeviceObject->Vpb->DeviceObject
        // 3. 否则 DeviceObject = FileObject->DeviceObject
        //

        if ((Vpb == NULL) || (Vpb->DeviceObject == NULL))
        {
                if (((FileObject->Flag & FO_DIRECT_DEVICE_OPEN) != 0)
                        || (FileObject->DeviceObject->Vpb == NULL)
                        || (FileObject->DeviceObject->Vpb->DeviceObject == NULL))
                {
                        DeviceObject = FileObject->DeviceObject;
                }
                else
                {
                        DeviceObject =  FileObject->DeviceObject->Vpb->DeviceObject;
                }
        }
        else
        {
                DeviceObject = Vpb->DeviceObject;
        }

        //
        // 假如这个 DeviceObject 没有附加的 DeviceObject,就直接返回当前的 DeviceObject
        // 在 DeviceObject->AttachedDevice 不为 NULL 时:
        // 1. 当有 FileObject 有扩展结构时,并且扩展结构的TopDeviceObjectHint 不为 NULL
        //     且 IopVerifyDeviceObjectOnStack() 返回值为 TURE 时,返回的 DeviceObject 为 FileObjectExtension->TopDeviceObjectHint;
        // 2. 否则调用IoGetAttachedDevice() 函数找到最顶层的 附加的 DeviceObject
        //

        if (DeviceObject->AttachedDevice)
        {
                PIOP_FILE_OBJECT_EXTENSION FileObjectExtension =
                                (PIOP_FILE_OBJECT_EXTENSION)(FileObject + 1);

                if ((FileObject->Flag & FO_FILE_OBJECT_HAS_EXTENSION == 0)
                        || (FileObjectExtension->TopDeviceObjectHint == NULL)
                        || (IopVerifyDeviceObjectOnStack(
                                        DeviceObject,
                                        fileObjectExtension->TopDeviceObjectHint,
                                        0) == FALSE)
                        )
                {
                        DeviceObject = IoGetAttachedDevice(DeviceObject);
                }
                else
                {
                        DeviceObject = FileObjectExtension->TopDeviceObjectHint;
                }

        }

        return DeviceObject;
}
8. IopfCompleteRequest()

VOID
IopfCompleteRequest(
        IN PIRP  Irp,
        IN CCHAR  PriorityBoost
        )
{
        CHAR StackCount = Irp->StackCount + 1;
        CHAR CurrentLocation = Irp->CurrentLocation
        PCHAR AuxiliaryBuffer = NULL;
        NTSTATUS Status;
        PDEVICE_OBJECT DeviceObject;
        PFILE_OBJECT OriginalFileObject;
        PIO_STACK_LOCATION  CurrentStackLocation;

        //
        // 假如 Stack location 超出 stack 数量(StackCount + 1)
        // 或者 IRP 的类型不为 IO_TYPE_IRP(值为 6)时,进入蓝屏
        //
        if ((Irp->CurrentLocation > Irp->StackCount + 1)
                || (Irp->Type != IO_TYPE_IRP))
        {
                KeBugCheckEx(MULTIPLE_IRP_COMPLETE_REQUESTS, (ULONG_PTR)Irp, __LINE__, 0, 0);               
        }

        //
        // 得到最底层的 Stack location 结构
        //
        PIO_STACK_LOCATION Bottom = (PIO_STACK_LOCATION)((ULONG)Irp + sizeof(IRP));

        //
        // 假如发生错误返回,则:Parameters.Others.Argument4 是错误状态值
        //
        if (Bottom->Control & SL_ERROR_RETURNED)
        {
                Status = (NTSTATUS)(Bottom->Parameters.Others.Argument4);
        }
        else
        {
                Status = STATUS_SUCCESS;
        }

        //
        // 得到当前 stack location,并从当前开始向后遍历
        // 直到最后完成
        //
        CurrentStackLocation = Irp->Tail.Overlay.CurrentStackLocation;

        Irp->CurrentLocation++;
        Irp->Tail.Overlay.CurrentStackLocation = CurrentStackLocation + 1;

        while (Irp->CurrentLocation <= Irp->StackCount + 1)
        {
                Irp->PendingReturned = CurrentStackLocation->Control & SL_PENDING_RETURNED;

                //
                // 当返回错误时:
                //
                if (!NT_SUCCESS(Irp->IoStatus.Status) &&  (Irp->IoStatus.Status != Status))
                {
                        CurrentStackLocation->Control |= SL_ERROR_RETURNED;
                        Bottom->Control |= SL_ERROR_RETURNED;
                        Status = Irp->IoStatus.Staus;
                        Bottom->Parameters.Others.Argument4 = Status;
                }

               
                //
                // 两个条件之一:
                // 1. 在 NT_SUCCESS(Irp->IoStatus.Status) == TRUE 的情况下:
                //         (CurrentStackLocation->Control & SL_INVOKE_ON_SUCCESS) != 0 或者
                //                        (Irp->Cacel == TURE) 并且 (CurrentStackLocation->Control & SL_INVOKE_ON_CANCEL) != 0
                //
                // 2. 在 NT_SUCESSS(Irp->IoStatus.Status) == FALSE 的情况下:
                //        (CurrentStackLocation->Control & SL_INVOKE_ON_ERROR) != 0 或者
                //                        (Irp->Cancel == TURE) 并且 (CurrentStackLocation->Control & SL_INVOKE_ON_CANCEL) != 0
                //

                if ((NT_SUCCESS(Irp->IoStatus.Status) &&
                                ((CurrentStackLocation->Control & SL_INVOKE_ON_SUCCESS)
                                || (Irp->Cancel && (CurrentStackLocation->Control & SL_INVOKE_ON_CANCEL)))
                        || (!NT_SUCCESS(Irp->IoStatus.Status) &&
                                ((CurrentStackLocation->Control & SL_INVOKE_ON_ERROR)
                                || (Irp->Cancel && (CurrentStackLocation->Control & SL_INVOKE_ON_CANCEL))))
                {
                        CurrentStackLocation->Control &= SL_ERROR_RETURNED;
                        CurrentStackLocation->MinorFunction = 0;
                        CurrentStackLocation->Flags = 0;
                        CurrentStackLocation->Parameters.Others.Argument1 = NULL;
                        CurrentStackLocation->Parameters.Others.Argument2 = NULL;
                        CurrentStackLocation->Parameters.Others.Argument3 = NULL;
                        CurrentStackLocation->FileObject = NULL;

                        if ( Irp->CurrentLocation != Irp->StackCount + 1)
                        {
                                DeviceObject = Irp->Tail.Overlay.CurrentStackLocation->DeviceObject;
                        }
                        else
                        {
                                DeviceObject = NULL;
                        }

                        Status = (*(IO_COMPLETION_ROUTINE)CurrentStackLocation->CompletionRoutine)(
                                                                DeviceObject,
                                                                Irp,
                                                                CurrentStackLocation->Context);

                        if (Status == STATUS_MORE_PROCESSING_REQUIRED)
                        {
                                return;
                        }
                }
                else
                {
                        if ((Irp->PendingReturned) && (Irp->CurrentLocation <= Irp->StackCount)
                        {
                                Irp->Tail.Overlay.CurrentStackLocation->Control |= SL_PENDING_RETURNED;
                        }
               
                        CurrentStackLocation->Control &= SL_ERROR_RETURNED;
                        CurrentStackLocation->MinorFunction = 0;
                        CurrentStackLocation->Flags = 0;
                        CurrentStackLocation->Parameters.Others.Argument1 = NULL;
                        CurrentStackLocation->Parameters.Others.Argument2 = NULL;
                        CurrentStackLocation->Parameters.Others.Argument3 = NULL;
                        CurrentStackLocation->FileObject = NULL;
                }

               
                //
                // 指向下一个 stack location
                //
                Irp->Tail.Overlay.CurrentStackLocation++;
                CurrentStackLocation++;
                Irp->CurrentLocation++;
        }

        if (Irp->Flags & IRP_ASSOCIATED_IRP)
        {
                PIRP MasterIrp = Irp->AssociatedIrp.MasterIrp;
                ULONG IrpCount = IopInterlocakedDecrementUlong(LockQueueIoDatabaseLock,
                                        &MasterIrp->AssociatedIrp.IrpCount);
                IopFreeIrpAndMdls(Irp);
                if (IrpCount == 1)
                {
                        IopfCompleteRequest(MasterIrp, PriorityBoost);
                }

                return;

        }

        if (Irp->IoStatus.Status == STATUS_REPARSE)
        {
                if (Irp->IoStatus.Information > IO_REPARSE_TAG_RESERVED_RANGE)
                {
                        if (Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT)
                        {
                                AuxiliaryBuffer = Irp->Tail.Overlay.AuxiliaryBuffer;
                                Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
                        }
                        else
                        {
                                Irp->IoStatus.Status = STATUS_IO_REPARSE_TAG_NOT_HANDLED;
                        }
               
                }
        }
       
        if (Irp->Tail.Overlay.AuxiliaryBuffer != NULL)
        {
                ExFreePoolWithTag(Irp->Tail.Overlay.AuxiliaryBuffer, 0);
                Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
        }

        if ((Irp->Flags & (IRP_CLOSE_OPERATION | IRP_PAGING_IO))
        {

                if (Irp->Flags & (IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_PAGING_IO)))
                {
                        Irp->UserIosb->Status = Irp->IoStatus.Status;
                        Irp->UserIosb->Information = Irp->IoStatus.Information;
                        KeSetEvent(Irp->UserEvent, PriorityBoost, 0);

                        if (Irp->Flags & (IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO))
                        {
                                if (IopReserveIrpAllocator == Irp)
                                {
                                        IopFreeReserveIrp(PriorityBoost);
                                }
                                else
                                {
                                        IoFreeIrp(Irp);
                                }
                        }
                }
                else
                (
                        KeInitializeApc(&Irp->Tail.Apc,
                                &Irp->Tail.Overlay.Thread->Tcb,
                                Irp->ApcEnvironment,
                                IopCompletePageWrite,
                                0,
                                0,
                                0,
                                0);       

                        KeInsertQueueApc(&Irp->Tail.Apc,
                                NULL,
                                NULL,
                                PriorityBoost);
                }

                return;
        }

        PMDL Mdl = = Irp->MdlAddress;

        for (; Mdl; Mdl = Mdl->Next)
        {
                MmUnlockPages(Irp->MdlAddress);
        }

        if (Irp->Flags & IRP_DEFER_IO_COMPLETION)
                && (Irp->PendingReturned == FALSE))
        {
                if (Irp->IoStatus.Status == STATUS_REPARSE) &&
                        (Irp->Information == IO_REPARSE_TAG_MOUNT_POINT))
                {
                        Irp->Tail.Overlay.AuxiliaryBuffer = AuxiliaryBuffer;
                }

                return;
        }

        OriginalFileObject =  Irp->Tail.Overlay.OriginalFileObject;

        if (Irp->Cancel == FALSE)
        {
                KeInitializeApc(&Irp->Tail.Apc,
                        &Irp->Tail.Overlay.Thread->Tcb,
                        Irp->ApcEnvironment,
                        IopCompleteRequest,
                        IopAbortRequest,
                        NULL,
                        KernelMode,
                        NULL);
               
                KeInsertQueueApc(&Irp->Tail.Apc,
                        OriginalFileObject,
                        AuxiliaryBuffer,
                        PriorityBoost);

                return;
        }

        KIRQL OldIrql = KeRaiseIrqlToDpcLevel();

        if (Irp->Tail.Overlay.Thread != NULL)
        {
                KeInitializeApc(&Irp->Tail.Apc,
                        &Irp->Tail.Overlay.Thread->Tcb,
                        Irp->ApcEnvironment,
                        IopCompleteRequest,
                        IopAbortRequest,
                        NULL,
                        KernelMode,
                        NULL);

                KeInsertQueueApc(&Irp->Tail.Apc,
                        OriginalFileObject,
                        AuxiliaryBuffer,
                        PriorityBoost);

                KfLowerIrql(OldIrql);
        }
        else
        {
                KfLowerIrql(OldIrql);
                IopDropIrp(Irp, OriginalFileObject);
        }       
       
        return;
}
9. IopCompleteUnloadOrDelete()

VOID
IopCompleteUnloadOrDelete(
        IN PDEVICE_OBJECT DeviceObject,
        IN BOOLEAN OnCleanStack,
        IN KIRQL Irql
        )
{
        PDRIVER_OBJECT DriverObject = DeviceObject->DriverObject;
        BOOLEAN Unload = TRUE;

        //
        // 需要做 REMOVE 操作时:
        //
        if (DeviceObject->DeviceObjectExtension->ExtensionFlags & DOE_REMOVE_PENDING)
        {
                //
                // 找到栈 bottom 的 device object
                //
                PDEVICE_OBJECT Bottom = IopGetDeviceAttachmentBase(DeviceObject);
                PDEVICE_OBJECT Base = Bottom;

                //
                // 检测整个 stack 中的所有 device object 的 ReferenceCount 值是否为 0
                // 不是则退出:
                //  
                while (Bottom)
                {
                        if (Bottom->ReferenceCount != 0)
                        {
                                KfLowerIrql(Irql);
                                return;
                        }
                        Bottom = Bottom->AttachedDevice;
                }

                //
                // 如果所有的 device object 的 ReferenceCount = 0 时
                // ExtensionFlags 标志值去掉 DOE_REMOVE_PENDING
                // 指示:已处理移除
                //
                Bottom = Base;
                while (Bottom)
                {
                        Bottom->DeviceObjectExtension->ExtensionFlags &= ~DOE_REMOVE_PENDING;
                        Bottom->DeviceObjectExtension->ExtensionFlags |= DOE_REMOVE_PROCESSED;
                        Bottom = Bottom->AttachedDevice;
                }

                KfLowerIrql(Irql);
                IopChainDereferenceComplete(Base, OnCleanStack);
                return;
        }

        //
        // 如果需要做 DELETE 操作时:
        //
        if (DeviceObject->DeviceObjectExtension->ExtensionFlags & DOE_DELETE_PENDING)
        {
                //
                // 检测是否需要做 Unload 操作:
                //
                if (((DeviceObject->DeviceObjectExtension->ExtensionFlags & DOE_UNLOAD_PENDING) == 0)
                        || (DriverObject->Flags & DRVO_UNLOAD_INVOKED))
                {
                        Unload = FALSE;
                }

                if (DeviceObject->AttachedDevice != NULL)
                {

                        PDRIVER_OBJECT AttachedDriverObject = DeviceObject->AttachedDevice->DriverObject;

                        DeviceObject->ReferenceCount++;
                        KfLowerIrql(Irql);

                        if ((AttachedDriverObject->FastIoDispatch)
                                        && (AttachedDriverObject->FastIoDispatch->SizeOfFastIoDispatch > 0x34)
                                        && (AttachedDriverObject->FastIoDispatch->FastIoDetachDevice))
                        {
                                AttachedDriverObject->FastIoDispatch->FastIoDetachDevice(
                                                                DeviceObject->AttachedDevice,
                                                                DeviceObject);
                        }

                        KIRQL OldIrql = KeRaiseIrqlToDpcLevel();
                        DeviceObject->ReferenceCount--;

                        if ((DeviceObject->AttachedDevice != NULL) || (DeviceObject->ReferenceCount != 0))
                        {
                                KfLowerIrql(OldIrql);       
                                return;       
                        }
                }

                KfLowerIrql(OldIrql);

                if (DeviceObject->SecurityDescriptor != NULL)
                {
                        ObDereferenceSecurityDescriptor(DeviceObject->SecurityDescriptor, 1);
                }
                IopInsertRemoveDevice(DeviceObject->DriverObject, DeviceObject, FALSE);
                ObfDereferenceObject(DeviceObject);

                if (Unload == FALSE)
                {
                        return;
                }

                OldIrql = KeRaiseIrqlToDpcLevel();       

                if (DriverObject->Flags & DRVO_UNLOAD_INVOKED)
                {
                        KfLowerIrql(OldIrql);
                        return;
                }
        }

        PDEVICE_OBJECT devObj = DriverObject->DeviceObject;

        while (devObj)
        {
                if ((devObj->ReferenceCount != 0)
                        || (devObj->AttachedDevice != NULL)
                        || ((devObj->DeviceObjectExtension->ExtensionFlags & 6))
                {
                        Unload = FALSE;
                        break;
                }
                devObj = devObj->NextDevice;
        }

        if ((DriverObject->Flags & 0x80) && (DriverObject->DeviceObject != NULL))
        {
                Unload = FALSE;
        }

        if (Unload = FALSE)
        {
                KfLowerIrql(OldIrql);
                return;
        }

        DriverObject->Flags |= 1;
        KfLowerIrql(OldIrql);

        LOAD_PACKET LoadPacket;
       
        LoadPacket.Event.WaitListHead.Flink = &LoadPacket.Event.WaitListHead;
        LoadPacket.Event.WaitListHead.Blink = &LoadPacket.Event.WaitListHead;
        LoadPacket.Event.Type = 0;
        LoadPacket.Event.Size = 4;
        LoadPacket.Event.SignalState = 0;
        LoadPacket.DriverObject = DriverObject;

        if (OnCleanStack == FALSE)
        {
                LoadPacket.WorkQueueItem.Parameter = &LoadPacket;
                LoadPacket.WorkQueueItem.List.Flink = NULL;
                LoadPacket.WorkQueueItem.WorkerRoutine = IopLoadUnloadDrive;

                ExQueueWorkItem(&LoadPacket.WorkQueueItem, DelayedWorkQueue);
                KeWaitForSingleObject(&LoadPacket.Event,
                                Executive,
                                KernelMode,
                                FALSE,
                                NULL);
        }
        else
        {
                IopLoadUnloadDriver(&LoadPacket);
        }
       
        ObMakeTemporaryObject(DriverObject);
        ObfDereferenceObject(DriverObject);
}
10. KiFastCallEntry()

注意:这个 KiFastCallEntry() 还不是完整的代码(逆了大部分代码):

//
// 说明:
// 下面的 KiFastCallEntry() 代码是根据 windows 2003 的反汇编出来
// 然后转化为 C 的伪代码形式。
// 主要分析了  sysenter 指令进入 0 级 kernel 内的系统服务例程分发的流程
// 只分析了部分流程(属于正常进入时,不包含不正确时的情形
//

//
// KiFastCallEntry() 看起来像下面:由 EAX 寄存器传递系统服务功能号
//
VOID
KiFastCallEntry(ULONG ServiceNumber)
{
        //
        // 设 fs 寄存器的 base 为 kernel 的 PCR 结构地址
        //
        fs = 0x30;

        //
        // 用户代码 data selector
        //
        ds = 0x23;
        es = 0x23;

        //
        // 得到当前 TSS 块,并读取 0 级的 esp 值
        // 注意:这个 Esp0 指向一个 KTRAP_FRAME 结构的 V86Es 成员!
        // Esp0 值减去 0x7c 就等于 KTRAP_FRAME 结构地址,trap 用于 context 信息
        // esp 被赋予 KTRAP_FRAME 结构地址:esp = KtrapFrame,它以 push  的方式保存 context 信息
        //
        PKTSS Tss = GetCurrentTss();                        
        PKTRAP_FRAME KtrapFrame = (PKTRAP_FRAME)(Tss->Esp0 - 0x7c);

        //
        // 注意:下面保存 context 的操作是以 push 方式压入 TrapFrame  为 esp  的栈中
        //
        KtrapFrame->HardwareSegSs = 0x23;                                // 保存原 R3 的 SS 值
        KtrapFrame->HardwareEsp = edx;                                  // edx 是原 R3 的 ESP 值
        KtrapFrame->EFlags = eflags;                                    // 保存原 eflags 值

        KtrapFrame->EFlags.IF = 1;                                      // context 中的 eflags.IF 置位
        eflags = 0;                                                     // 当前的 eflags 清为 0
               
        //
        // 当前 edx 保存着 sysenter 进入前的 esp 值
        // 加上 8 后:edx 指向 native API 调用中的第 1 个参数
        //
        PVOID ArgumentPointer = edx + 8;
        
        KtrapFrame->SegCs = 0x1b;                                          // 保存原 R3 的 CS 值
        KtrapFrame->Eip = UserSharedData->SystemCallReturn;                // 保存返回函数
        KtrapFrame->ErrCode = 0;                                          // 错误码为 0
        KtrapFrame->Ebp = ebp;
        KtrapFrame->Ebx = ebx;
        KtrapFrame->Esi = esi;
        KtrapFrame->Edi = edi;
        KtrapFrame->SegFs = 0x3b;                                          // 原 R3 的 FS 值

        PKPCR Kpcr = (PKPCR)0xffdff000;                                    // 也就是 fs.base

        KtrapFrame->ExceptionList = Kpcr->NtTib.ExceptionList;            // 保存原 SEH 链底
        Kpcr->->NtTib.ExceptionList = -1;                                 // 设置为空 SEH 链

        PKTHREAD Thread = Kpcr->PrcbData.CurrentThread;                 // 得到当前线程结构
        PVOID InitialStack = Thread->InitialStack;                       // 得到初始的 stack 地址

        KtrapFrame->PreviousPreviousMode = UserMode;                           // 1 值是原 MODE_MASK 值

        KtrapFrame = (PKTRAP_FRAME)((ULONG)KtrapFrame - 0x48);         // 计算出 Ktrap_frame 基地址

        //
        // 计算初始 stack 的 ktrap_frame 基址:
        // 这个 0x29c 值等于:NPX_FRAME_LENGTH + KTRAP_FRAME_LENGTH
        // NPX_FRAME_LEGNTH = 0x210
        // KTRAP_FRAME_LENGTH = 0x8c
        //
        InitialStack = (PVOID)((ULONG)InitialStack - 0x29c);

        Thread->PreviousMode = UserMode;

        //
        // 假如这两个 stack 基址值不同
        //
        if (KtrapFrame != InitialStack)
        {
                goto 3869;
        }

        //
        // 此时 InitialStack 指向 KtrapFrame 基址,也就是:InitialStack == KtrapFrame
        //
        InitialStack->Dr7 = 0;                                                 // 清 Dr7 值

        Thread->TrapFrame = InitialStack;

        //
        // 检测是否需要保存 debug context 信息(debug 寄存器)
        //
        if (Thread->Header.DebugActive != 0xff)
        {
                goto 372c;
        }

        ebx = KtrapFrame->Ebp;                                               // 读取原 ebp  值
        edi = KtrapFrame->Eip;                                              // 读取  UserSharedData->SystemCallReturn
        KtrapFrame->DbgArgPointer = ArgumentPointer;                        // native API 调用的第 1 个参数
        KtrapFrame->DbgArgMark = 0xbadb0d00;

        //
        // 实际上:当前 KtrapFrame 值等价于当前 esp
        // 因此,下面两行代码是构建一个标准的 call 返回流程
        // 1. push  UserSharedData->SystemCallReturn(返回地址)
        // 2. push ebp(原 stack frame base )
        //
        // 当前:
        //  1. ebp == esp
        //  2. ebp 指向 KtrapFrame->DbgEbp 值(stack top)
        //
        KtrapFrame->DbgEbp = ebx;                                       
        KtrapFrame->DbgEip = edi;

        //
        // ServiceNumber 的 bit 12 是 index 值,由这个 index 值得到 SeviceTable entry 结构
        // ServiceTable entry 为 16 bytes,其中 entry 的第  3 个值是 MaxServerNumber
        //
        // 在 windows 2003 中:
        // ServiceTable[0].MaxServiceNumber = 0x128
        // ServiceTable[1].MaxServiceNumber = 0x299
        //
        ULONG ServiceNumber = eax & 0xFFF;
        ULONG Index = (eax >> 12) & 0x01

        PSERVER_TABLE_ENTRY ServiceTableEntry = Thread->ServiceTable[Index];

        //
        // ServiceNumber 的低 12 位是真正的 ServiceNumber 值
        //
        //
        if (ServiceNumber >= ServceTableEntry->MaxServiceNumber)
        {
                goto nt!KiBBTUnexpectedRange (80883662)
        }

        //
        // 测试是否进入 GUI 服务例程
        //
        if (Index == 1)
        {
                //
                // 从 fs:[18h] 得到 R3 的 TEB 块
                //
                PTEB Teb = GetCurrentUserTeb()

                if (Teb->GdiBatchCount != 0)
                {
                        //
                        // 调用 win32k 的 NtGdiFlushUserBatch() 函数
                        //
                        KeGdiFlushUserBatch(ServiceNumber, edx);                             // edx 是参数地址
                }
        }

        Kpcr->PrcbData.KeSystemCalls++;

        //
        // 从 ServiceTable 里得到参数表地址
        //
        PVOID ArgumentTable = ServiceTableEntry->ArgumentTable;

        //
        // 得到 native API 调用时的参数 size
        //
         CCHAR ArgumentSize = ArgumentTable[ServiceNumber];

        //
        // 从 ServiceTable 里得到 service table address
        //
        PVOID ServiceTableBase = ServiceTableEntry->ServiceTableBase;

        //
        // 下面检测 API 参数地址是否属于 User-space
        // MmUserProbeAddress 的值为 0x7FFF0000
        //
        if (ArgumentPointer >= MmUserProbeAddress)
        {
                goto 3b54;
        }

        
        //
        // 在当前 stack  上开辟足够容参数的空间
        // 将 API 调用时的参数复制到当前 stack 上
        //
        esp = esp - ArgumentSize;
        RtlMoveMemory(esp, ArgumentPointer, ArgumentSize);
        
        //
        // 最后调用服务例程:这里真正调用系统服务例程!
        //
        *(PFUN)ServiceTableBase[ServiceNumber]();

        //
        // 假如调用者是 ring 3 并且需要检查 APC
        //
        if ((KiEnableApcCheck & 0x01) && (KtrapFrame->SegCs.RPL == 3))
        {
                KIRQL Irql = KeGetCurrentIrql();

                //
                // 如果当前 Irql 不是 PASSIVE_LEVEL 级别:抛出 BugCheck 错误!
                //
                if (Irql != PASSIVE_LEVEL)
                {
                        Kpcr->Irql = PASSIVE_LEVEL;

                        KeBugCheck2(0x4A,
                                NtWriteFile,
                                Irql,
                                0,
                                0,
                                InitialStack);
                }

                Thread = Kpcr->CurrentThread;

                //
                // 检查 process 是否 attached ?
                // 或者 APCs 是否被  disable ?
                // 如果是的话:抛出 BugCheck 错误!
                //
                if ((Thread->ApcStateIndex & 0xff) || (Thread->CombinedApcDisable != 0))
                {
                        KeBugCheck2(1,
                                NtWriteFile,
                                Thread->ApcStateIndex,
                                Thread->CombinedApcDisable,
                                0,
                                InitialStack);
                }
        }

        //
        // 恢复  stack frame
        //
        esp = ebp;

        PKTRAP_FRAME OldTrapFrame = KtrapFrame->Edx;                                // 找到原 esp 值(进入 sysenter 之前)
        Thread->TrapFrame = OldTrapFrame;                                          // 保存在 Thread 的 TrapFrame 域里
               
        cli();

        if ((KtrapFrame->EFlags.VM == 1) || (KtrapFrame->SegCs.RPL == 3))
        {
                Thread->Alerted = 0;
               
                while (Thread->ApcStateFill.AsUserApcPending != 0)
                {
                        KtrapFrame->Eax = eax;                                            // 保存返回值
                        KtrapFrame->SegFs = 0x3b;
                        KtrapFrame->SegDs = 0x23;
                        KtrapFrame->SegEs = 0x23;
                        KtrapFrame->SegGs = 0;

                        //
                        // 下面代码将  IRQL 提升到 APC_LEVEL 级别
                        // 然后提交 APC 排队处理(需要开中断)
                        // 完成后恢复原 IRQL 级别并关闭中断许可
                        //

                        OldIrql = KfRaiseIrql(APC_LEVEL);
                        sti();
                        KiDeliverApc(1, 0, KtrapFrame);                                  // 提交 APC 处理
                        KfLowerIrql(OldIrql);
                        cli();

                        Thread->Alerted = 0;
                }
        }

        Kpcr->NtTib.ExceptionList = KtrapFrame->ExceptionList;
        Thread->PreviousMode = KtrapFrame->PreviousPreviousMode;
               
        if (KtrapFrame->Dr7 & 0xffff23ff)
        {
                //
                // 如果开启了 DR7 调试功能
                //
                if ((KtrapFrame->EFlags.VM == 1) || (KtrapFrame->SegCs.RPL == 3))
                {
                        dr7 = 0;                                                        // 先关闭调试功能

                        dr0 = KtrapFrame->Dr0;
                        dr1 = KtrapFrame->Dr1;
                        dr2 = KtrapFrame->Dr2;
                        dr3 = KtrapFrame->Dr3;
                        dr6 = KtrapFrame->Dr6;
                        dr7 = KtrapFrame->Dr7;
                }
        }

        //
        // 下面进行一些检测处理
        //

        if (KtrapFrame->EFlags.VM == 1)
        {
                //
                // 如果开启了 V8086 模式
                //
                edx = KtrapFrame->Edx;
                ecx = KtrapFrame->Ecx;
                eax = KtrapFrame->Eax;
        }
        else if (KtrapFrame->SegCs & 0xFFF9 == 0)
        {
                //
                // 如果 CS selector 为 0 值(0级下的 NULL selector)
                //
               
                KtrapFrame->SegCs = KtrapFrame->TempSegCs;      

                //
                // ErrCode 指向构造的 TempStack 结构
                //
                PVOID TempStack = KtrapFrame->TempEsp - 0x0c;
                KtrapFrame->ErrCode = TempStack;

                //
                // 下面构造一个 stack 结构(TempStack)以便使用 iretd 指令返回:
                //
                //                      Eflags
                //                      SegCs
                //          esp ------> Eip
                //
                TempStack->Eflags = KtrapFrame->EFlags;
                TempStack->SegCs = KtrapFrame->SegCs;
                TempStack->Eip = KtrapFrame->Eip;
        
                edi = KtrapFrame->Edi;
                esi = KtrapFrame->Esi;
                ebx = KtrapFrame->Ebx;
                ebp = KtrapFrame->Ebp;

                //
                // 基于构造的 TempStack 来中断返回
                //
                esp = &TempStack;
                iretd;
        }
        else if (KtrapFrame->SegCs.RPL == 3)
        {
              //
                // 恢复 ring 3 的寄存器值
                //
                eax = KtrapFrame->Eax;
                edx = KtrapFrame->Edx;
                ecx = KtrapFrame->Ecx;
                gs = KtrapFrame->SegGs;
                es = KtrapFrame->SegEs;
                ds = KtrapFrame->SegDs;
                fs = KtrapFrame->SegFs;
        }
        else if (KtrapFrame->SegCs != 8)
        {
                fs = KtrapFrame->SegFs;
        }

        //
        // 现在:esp 指向 KtrapFrame->Edi 域
        // 下一步工作是:pop 出相关的值
        //
        esp = &KtrapFrame->Edi;
        
        //
        // 下面恢复原部分寄存器 context 信息
        // 也就是执行:
        //        pop edi        ----> 此时 esp 指向 edi 保存的地址
        //        pop esi
        //        pop ebx
        //        pop ebp
        //
        edi = KtrapFrame->Edi;
        esi = KtrapFrame->Esi;
        ebx = KtrapFrame->Ebx;
        ebp = KtrapFrame->Ebp;

        //
        // 此时 stack frame 内的值为:
        //
        //     esp ---->  KtrapFrame->ErrCode
        //                KtrapFrame->Eip
        //                KtrapFrame->SegCs
        //                KtrapFrame->EFlags
        //                ktrapFrame->HardwareEsp
        //                KtrapFrame->HardwareSegSs
        //
        // 这是一个标准的调用中断 handler 入栈的情形,esp 指向 ErrorCode
        //

        //
        // 当 CS 值大于 0x80 时,代表是 16 位代码?(返回到 16 位代码 ?)
        //
        if (KtrapFrame->SegCs > 0x80)
        {
                //
                // 此时 KtrapFrame->ErrCode 被构造为一个 32 位宽的 far pointer(16:16)
                // 这个 far pointer 是 stack pointer 值,被用来加载到 SS:SP 寄存器
                //

                PFarPointer far = &KtrapFrame->ErrCode;

                if ((far->SegSs == 0) || far->Sp != 0)
                {
                        esp = esp + 4;                                          // 跳过 ErrCode, 执行中断返回
                        iretd;
                }

                //
                // 执行 shr dword ptr [esp], 10h 操作
                //
                far->Sp = far->SegSs;
                far->SegSs = 0xf8;                                              // SS selector 为 0xf8

                //
                // 下面将 far pointer 装入 SS:SP
                //
                Ss = far->SegSs;
                Sp = far->Sp;
        
                iretd;                                                          // 执行中断返回
        }

        //
        // 下面进行判断两种情形:
        // 1. 当调用者属于 Ring 0 时,直接使用 jmp 指令返回到目标返回地址
        // 2. 当调用者属于 Ring 3 时,使用 sysexit 指令返回
        //

        esp = esp + 4;                                  // 跳过 ErrCode
        
        if (KtrapFrame->SegCs.RPL == 0)
        {
                //
                // 属于 ring0 的调用,下面操作是:手动销栈,读出 Eip 值到 edx 寄存器
                // 等价于下面的操作:
                // pop edx
                // pop ecx
                // popfd
                // jmp edx
                //

                edx = KtrapFrame->Eip;                                  // 得到返回地址
                ecx = KtrapFrame->SegCs;                                // SegCs 值
                eflags = KtrapFrame->Eflags;                            // pop 出 eflags 寄存器

                //
                // 跳转到 edx 地址上,也就是跳到:ntdll!KiFastSystemCallRet() 例程
                // 这个 ntdll!KiFastSystemCallRet() 例程只有一条 ret 指令
                // 通过这种方式返回到 API 的调用者(而非执行 sysexit 指令)
                //
                jmp edx                                                
        }
        else
        {
                //
                // 当调用者是用户代码时,返回的地址属于 3 级的用户层代码
                //

                if (KtrapFrame->EFlags.TF == 1)
                {
                        //
                        // 如果开启单步调试,则使用 iretd 指令返回
                        //
                        iretd;                                
                }
                else
                {
                        //
                        // 下面的处理,目的是:
                        // 1. 销掉部分 stack
                        // 2. 找到返回地址到 EDX 寄存器
                        // 3. 找到返回的 esp 值到 ECX 寄存器
                        // 4. 使用 sysexit 指令返回
                        //
                        edx = KtrapFrame->Eip;                                         // pop 出 EIP 值
                        KtrapFrame->EFlags.IF = 0;                                      // 清掉 stack 的中 IF 标志位
                        eflags = KtrapFrame->EFlags;                                    // pop 出 eflags 值
                        ecx = ktrapFrame->HardwareEsp;                                  // pop 出 Esp 值到

                        sti();                                                        // 返回前打开中断
                        sysexit;                                                      // 执行 sysexit 指令返回
                }
        }
        
        ... ...
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
不错,有原型C调用会方便点
2014-1-15 18:52
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
wrk似乎都有吧…………
2014-1-15 20:03
0
雪    币: 478
活跃值: (50)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
收藏,谢谢啊啊啊
2014-1-16 00:41
0
雪    币: 49
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
这个看WRK 效果更好
网络找的比微软发布的源码更准确么?
2014-1-16 10:14
0
雪    币: 55
活跃值: (519)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
6
照这样说ReactOs岂不是毫无用处了
2014-1-16 14:16
0
雪    币: 49
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
你说的网络找来的 不如标明来自 reactos

另外如果reactos和wrk  都有同样的函数的话 wrk的确会更准确
但是不代表我认为reactos毫无用处
不太清楚你是如何从我觉得WRK比网络上的代码更准确这观点推测出 REACTOS毫无用处的结果

这个代码出处应该是
http://www.mouseos.com/windows/kernel/%E4%B8%80%E4%BA%9B%E9%80%86%E5%90%91%E5%87%BA%E6%9D%A5%E7%9A%84%E5%87%BD%E6%95%B0%E5%AE%9E%E7%8E%B0.html

http://www.mouseos.com
也就是
《x86/x64体系探索及编程》的作者邓志的页面

作者自己也说了“在学习 windows 驱动的时候顺便逆了下面一些函数的实现,下面这些代码从来自 windows 2003:(将会不定期地持续更新...)

有些函数逆出来意义不大,并且有些函数我也并不明白是什么意图。但是却可训练逆向能力和代码组织能力!



这样的函数比WRK更有说服力 更准确么?
2014-1-17 15:56
0
雪    币: 67
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
收了1 谢谢
2014-1-17 16:21
0
游客
登录 | 注册 方可回帖
返回
//