宝峰科技

 找回密码
 注册

QQ登录

只需一步,快速开始

智能终端设备维修查询系统注册会员邮箱认证须知!
查看: 2235|回复: 0

[转载] Gloomy对Windows内核的分析2

[复制链接]
  • TA的每日心情
    开心
    2024-12-9 18:45
  • 签到天数: 124 天

    [LV.7]常住居民III

    admin 发表于 2009-12-12 23:27:44 | 显示全部楼层 |阅读模式

    欢迎您注册加入!这里有您将更精采!

    您需要 登录 才可以下载或查看,没有账号?注册

    x
    在Windows 95下,位于TIB中的偏移0x30的是指向拥有该线程的进程的基址数据指针。在Windows NT 4.0中,这个偏移保存的是指向结构体的指针,该结构体实现于kernel32.dll。遗憾的是,到现在为止,除了几个域之外我还不清楚这个结构体的格式。除此之外,类似的,在Win 2K中EB结构体也发生了变化。
    typedef struct _PROCESS_PARAMETERS {
    /*000*/     ULONG AllocationSize;
    /*004*/     ULONG ActualSize;
    /*008*/     ULONG Flags;//PPFLAG_xxx
    /*00c*/     ULONG Unknown1;
    /*010*/     ULONG Unknown2;
    /*014*/     ULONG Unknown3;
    /*018*/     HANDLE InputHandle;
    /*01c*/     HANDLE OutputHandle;
    /*020*/     HANDLE ErrorHandle;
    /*024*/     UNICODE_STRING CurrentDirectory;
    /*028*/     HANDLE CurrentDir;
    /*02c*/     UNICODE_STRING SearchPaths;
    /*030*/     UNICODE_STRING ApplicationName;
    /*034*/     UNICODE_STRING CommandLine;
    /*038*/     PVOID EnvironmentBlock;
    /*03c*/     ULONG Unknown[9];
           UNICODE_STRING Unknown4;
           UNICODE_STRING Unknown5;
           UNICODE_STRING Unknown6;
           UNICODE_STRING Unknown7;
    } PROCESS_PARAMETERS, *PPROCESS_PARAMETERS;

    typedef struct _PEB {                     // Size: 0x1D8
    /*000*/ UCHAR InheritedAddressSpace;
    /*001*/ UCHAR ReadImageFileExecOptions;
    /*002*/ UCHAR BeingDebugged;
    /*003*/ UCHAR SpareBool;                       // Allocation size
    /*004*/ HANDLE Mutant;
    /*008*/ HINSTANCE ImageBaseAddress;            // Instance
    /*00C*/ VOID *DllList;
    /*010*/ PPROCESS_PARAMETERS *ProcessParameters;
    /*014*/ ULONG SubSystemData;
    /*018*/ HANDLE DefaultHeap;
    /*01C*/ KSPIN_LOCK FastPebLock;
    /*020*/ ULONG FastPebLockRoutine;
    /*024*/ ULONG FastPebUnlockRoutine;
    /*028*/ ULONG EnvironmentUpdateCount;
    /*02C*/ ULONG KernelCallbackTable;
    /*030*/ LARGE_INTEGER SystemReserved;
    /*038*/ ULONG FreeList;
    /*03C*/ ULONG TlsExpansionCounter;
    /*040*/ ULONG TlsBitmap;
    /*044*/ LARGE_INTEGER TlsBitmapBits;
    /*04C*/ ULONG ReadOnlySharedMemoryBase;
    /*050*/ ULONG ReadOnlySharedMemoryHeap;
    /*054*/ ULONG ReadOnlyStaticServerData;
    /*058*/ ULONG AnsiCodePageData;
    /*05C*/ ULONG OemCodePageData;
    /*060*/ ULONG UnicodeCaseTableData;
    /*064*/ ULONG NumberOfProcessors;
    /*068*/ LARGE_INTEGER NtGlobalFlag;            // Address of a local copy
    /*070*/ LARGE_INTEGER CriticalSectionTimeout;
    /*078*/ ULONG HeapSegmentReserve;
    /*07C*/ ULONG HeapSegmentCommit;
    /*080*/ ULONG HeapDeCommitTotalFreeThreshold;
    /*084*/ ULONG HeapDeCommitFreeBlockThreshold;
    /*088*/ ULONG NumberOfHeaps;
    /*08C*/ ULONG MaximumNumberOfHeaps;
    /*090*/ ULONG ProcessHeaps;
    /*094*/ ULONG GdiSharedHandleTable;
    /*098*/ ULONG ProcessStarterHelper;
    /*09C*/ ULONG GdiDCAttributeList;
    /*0A0*/ KSPIN_LOCK LoaderLock;
    /*0A4*/ ULONG OSMajorVersion;
    /*0A8*/ ULONG OSMinorVersion;
    /*0AC*/ USHORT OSBuildNumber;
    /*0AE*/ USHORT OSCSDVersion;
    /*0B0*/ ULONG OSPlatformId;
    /*0B4*/ ULONG ImageSubsystem;
    /*0B8*/ ULONG ImageSubsystemMajorVersion;
    /*0BC*/ ULONG ImageSubsystemMinorVersion;
    /*0C0*/ ULONG ImageProcessAffinityMask;
    /*0C4*/ ULONG GdiHandleBuffer[0x22];
    /*14C*/ ULONG PostProcessInitRoutine;
    /*150*/ ULONG TlsExpansionBitmap;
    /*154*/ UCHAR TlsExpansionBitmapBits[0x80];
    /*1D4*/ ULONG SessionId;
    } PEB, *PPEB;

    在TEB的开头是NT_TIB结构体(TEB和TIB的结合)。这个结构体中的大部分名字都很易懂,最
    有意思的是指向异常处理链表的指针peExcept(Fs:[0])。这个域经常被引用。如果在随便
    某个Win32应用程序下看一下实际的情况,可以看到类似下面这样的代码:

    .01B45480: 64A100000000                   mov         eax,fs:[000000000]
    .01B45486: 55                             push        ebp
    .01B45487: 8BEC                           mov         ebp,esp
    .01B45489: 6AFF                           push        0FF
    .01B4548B: 68F868B401                     push        001B468F8
    .01B45490: 687256B401                     push        001B45672
    .01B45495: 50                             push        eax
    .01B45496: 64892500000000                 mov         fs:[000000000],esp
    .01B4549D: 83EC78                         sub         esp,078

    这段有代表性的代码是由编译器生成的,用于在堆栈中生成_EXCEPTION_REGISTRATION_RECO
    RD。这个堆栈中的结构体用于实现称作“structured exception handling”的机制,这就是
    结构化异常处理。接着,我们来看Windows NT下的结构化异常处理。这个机制可真是十分著
    名,而且实现在编译器的细节之中。在MSDN中可以找到Matt Petriek写得非常详细的文章,
    题为“A Crash Course    on    the    Depths    of Win32 Structured Exception Handling”,
    此文介绍的就是这项机制。

    FS:[0]中的指针是指向_EXCEPTION_REGISTRATION_RECORD首部的指针。对应地,每个结构体
    在pNext域中包含着指向下一个结构体的指针和指向回调函数pfnHandler的指针。不难猜到,
    这就是异常处理的处理程序。函数的原型如下:

    EXCEPTION_DISPOSITION      __cdecl _except_handler(
    struct _EXCEPTION_RECORD *ExceptionRecord,
    void * EstablisherFrame,
    struct _CONTEXT *ContextRecord,
    void * DispatcherContext
    );

    我们来分析函数的参数。第一个参数是指向下面结构体的指针。
    typedef struct _EXCEPTION_RECORD {
    DWORD ExceptionCode;
    DWORD ExceptionFlags;
    struct _EXCEPTION_RECORD *ExceptionRecord;
    PVOID ExceptionAddress;
    DWORD NumberParameters;
    DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
    } EXCEPTION_RECORD;


    ExceptionCode是Windows NT的异常代号。异常在NTSTATUS.H文件中被描述为STATUX_xxxxxx
    :    ExceptionAddres - 发生异常的地址。

    第三个参数是指向CONTEXT结构体的指针。
    typedef struct _CONTEXT
    {
    DWORD ContextFlags;
    DWORD Dr0;
    DWORD Dr1;
    DWORD Dr2;
    :.
    DWORD Esp;
    DWORD SegSs;
    } CONTEXT;

    这个结构体定义于WINNT.H文件。其意义是不言而喻的,这里就不全写了。函数返回下面枚举
    类型值中的一个:

    typedef enum _EXCEPTION_DISPOSITION {
          ExceptionContinueExecution,
          ExceptionContinueSearch,
          ExceptionNestedException,
          ExceptionCollidedUnwind
    } EXCEPTION_DISPOSITION;

    ExceptionFlags定义了下面的位标志:
    #define EH_NONCONTINUABLE     1
    #define EH_UNWINDING          2
    #define EH_EXIT_UNWIND        4
    #define EH_STACK_INVALID      8
    #define EH_NESTED_CALL     0x10

    在发生异常时,控制传递到ntoskrnl.exe中相应的处理程序。例如,如果试图下面这段代码

    mov eax,80100000h
    mov dword ptr [eax],0

    这会引发异常0e,控制传递向处理程序KiTrap0E,堆栈中错误号为07(试图在用户模式下向
    内核写入。该页位于内存中,因为线性地址80100000h是内核加载的起始地址)。之后,控制
    传递到ntdll.dll,在这里解析线程的TEB并顺次执行链表中所有的处理程序,直到某个函数
    的返回代号不是ExceptionContinueSearch。在此之后,再次调用链表中的所有处理函数,直
    到找到某个函数,但这次用的是另外一个代号ExceptionCode(STATUS_UNWIND)并在Except
    ionFlags设置位EH_UNWINDINGS。这个标志用于异常处理,进行堆栈的清除和其它必要的工作
    。如果没有一个处理程序能处理,则就来到链表中最后一个处理程序,由Win32子系统建立的
    处理程序。这个处理程序是如何被建立的以及建立在哪里在以后研究CreateProcessW函数时
    会讲到。关于异常处理的完整介绍可以从MSDN获得,因为在反汇编源代码中所得到的是扩大
    化了的异常处理机制(更高层次的机制)。


    04. 进程控制域(PROCESSOR CONTROL REGION)
    ===========================================================

    当线程在内核模式下执行时,在FS寄存器中加载的是选择子30,用于寻址PCR结构体(基址0
    xFFDFF000,界限0x00001FFF)。在NTDDK.H中远没有描述结构体所有的成员,只是其中不多
    的部分。为了说明PCR中的成分信息,这里列出用于i386的结构体(Windows NT 4.0)

    typedef struct _KPCR {               // Size: 0xB10
    /*000*/ NT_TIB NtTib;
    /*01C*/ struct _KPCR* SelfPcr;
    /*020*/ struct _KPRCB* Prcb;         // Current PCB
    /*024*/ KIRQL Irql;             // Current IRQL
    /*028*/ ULONG IRR;
    /*02C*/ ULONG IrrActive;
    /*030*/ ULONG IDR;
    /*034*/ ULONG Reserved2;
    /*038*/ struct _KIDTENTRY* ULONG IDT;
    /*03C*/ struct _KGDTENTRY* GDT;
    /*040*/ struct _KTSS* TSS;
    /*044*/ USHORT MajorVersion;         // 1
    /*046*/ USHORT MinorVersion;         // 1
    /*048*/ KAFFINITY SetMember;
    /*04C*/ ULONG StallScaleFactor;
    /*050*/ UCHAR DebugActive;
    /*051*/ UCHAR Number;

    // End of official portion of KPCR
    /*052*/ BOOLEAN VdmAlert;
    /*053*/ UCHAR Reserved;
    /*054*/ UCHAR KernelReserved[0x90-0x54];
    /*090*/ ULONG SecondLevelCacheSize;
    /*094*/ UCHAR HalReserved[0xD4-0x94];
    /*0D4*/ ULONG InterruptMode;
    /*0D8*/ ULONG Spare1;
    /*0DC*/ UCHAR KernelReserved2[0x120-0xDC];

    // Note that current thread is at offset 0x124 (pointer to KTHREAD)
    // This essentially means that the 1st PRCB must match the active CPU

    /*120*/ UCHAR PrcbData[0xB10-0x120];      // PCBs for all CPUs supported
    } KPCR, *PKPCR;

    PCR包含着指向PCRB(Processor Control Region)的指针,但实际上,PCRB位于PCR的偏移
    0x120处,并且所有的向PCRB域的转换都是相对于PCR的起点的。在WINNT.H中描述了PCRB结构
    体。这里给出整个结构体(Windows NT 4.0):

    // 0x120 from KPCR
    typedef struct _KPRCB {
    /*000*/      USHORT MinorVersion;
    /*002*/      USHORT MajorVersion;
    /*004*/      struct _KTHREAD *CurrentThread;
    /*008*/      struct _KTHREAD *NextThread;
    /*00c*/      struct _KTHREAD *IdleThread;
    /*010*/      CCHAR Number;
    /*011*/      CCHAR Reserved;
    /*012*/      USHORT BuildType;
    /*014*/      KAFFINITY SetMember;
    /*015*/      struct _RESTART_BLOCK *RestartBlock;
    /*018*/      CCHAR CpuType;
    /*019*/      CCHAR CpuID;
    /*01A*/      CCHAR CpuStep;
    /*01C*/      KPROCESSOR_STATE ProcessorState;
    /*13C*/      CCHAR KernelReserved[0x40];
    /*17C*/      CCHAR HalReserved[0x40];
    /*1BC*/      ULONG NpxThread;
    /*1C0*/      ULONG InterruptCount;
    /*1C4*/      ULONG KernelTime;
    /*1C8*/      ULONG UserTime;
    /*1CC*/      ULONG DpcTime;
    /*1D0*/      ULONG InterruptTime;
    /*1D4*/      ULONG ApcBypassCount;
    /*1D8*/      ULONG DpcBypassCount;
    /*1DC*/      ULONG AdjustDpcThreshold;
    /*1E0*/      UCHAR Spare2[0x14];
    /*1F4*/      ULONG64 ThreadStartCount;
    /*1FC*/      SINGLE_LIST_ENTRY FsRtlFreeSharedLockList;
    /*200*/      SINGLE_LIST_ENTRY FsRtlFreeExclusiveLockList;
    /*204*/      ULONG CcFastReadNoWait;
    /*208*/      ULONG CcFastReadWait;
    /*20C*/      ULONG CcFastReadNotPossible;
    /*210*/      ULONG CcCopyReadNoWait;
    /*214*/      ULONG CcCopyReadWait;
    /*218*/      ULONG CcCopyReadNoWaitMiss;
    /*21C*/      ULONG KeAlignmentFixupCount;
    /*220*/      ULONG KeContextSwitches;
    /*224*/      ULONG KeDcacheFlushCount;
    /*228*/      ULONG KeExceptionDispatchCount;
    /*22C*/      ULONG KeFirstLevelTbFills;
    /*230*/      ULONG KeFloatingEmulationCount;
    /*234*/      ULONG KeIcacheFlushCount;
    /*238*/      ULONG KeSecondLevelTbFills;
    /*23C*/      ULONG KeSystemCalls;
    /*240*/      SINGLE_LIST_ENTRY FsRtlFreeWaitingLockList;
    /*244*/      SINGLE_LIST_ENTRY FsRtlFreeLockTreeNodeList
    /*248*/      CCHAR ReservedCounter[0x18];
    /*260*/      PVOID SmallIrpFreeEntry;
    /*264*/      PVOID LargeIrpFreeEntry;
    /*268*/      PVOID MdlFreeEntry
    /*26C*/      PVOID    CreateInfoFreeEntry;
    /*270*/      PVOID NameBufferFreeEntry
    /*274*/      PVOID SharedCacheMapEntry
    /*278*/      CCHAR CachePad0[8];
    /*280*/      CCHAR ReservedPad[0x200];
    /*480*/      CCHAR    CurrentPacket[0xc];
    /*48C*/      ULONG TargetSet;
    /*490*/      PVOID WorkerRoutine;
    /*494*/      ULONG IpiFrozen;
    /*498*/      CCHAR    CachePad1[0x8];
    /*4A0*/      ULONG RequestSummary;
    /*4A4*/      ULONG SignalDone;
    /*4A8*/      ULONG ReverseStall;
    /*4AC*/      ULONG IpiFrame;
    /*4B0*/      CCHAR CachePad2[0x10];
    /*4C0*/      ULONG DpcInterruptRequested;
    /*4C4*/      CCHAR CachePad3 [0xc];
    /*4D0*/      ULONG MaximumDpcQueueDepth;
    /*4D4*/      ULONG MinimumDpcRate;
    /*4D8*/      CCHAR CachePad4[0x8];
    /*4E0*/      LIST_ENTRY DpcListHead;
    /*4E8*/      ULONG DpcQueueDepth;
    /*4EC*/      ULONG DpcRoutineActive;
    /*4F0*/      ULONG DpcCount;
    /*4F4*/      ULONG DpcLastCount;
    /*4F8*/      ULONG DpcRequestRate;
    /*4FC*/      CCHAR KernelReserved2[0x2c];
    /*528*/      ULONG DpcLock;
    /*52C*/      CCHAR SkipTick;
    /*52D*/      CCHAR VendorString[0xf];
    /*53C*/      ULONG MHz;
    /*540*/      ULONG64 FeatureBits;
    /*548*/      ULONG64 UpdateSignature;
    /*550*/      ULONG QuantumEnd;

    } KPRCB, *PKPRCB, *RESTRICTED_POINTER PRKPRCB;
    PCRB中最有用的就是指向当前线程的指针(KTHREAD结构体)。通常内核代码以以下代码取得
    此指针:
    《加密解密》中没有讲得很清楚,初学者可能有点疑问。这里写得教清楚:
    FS:[0]中的指针是指向_EXCEPTION_REGISTRATION_RECORD首部的指针。对应地,每个结
    构体在pNext域中包含着指向下一个结构体的指针和指向回调函数pfnHandler的指针。不
    难猜到,这就是异常处理的处理程序。函数的原型如下:

    EXCEPTION_DISPOSITION      __cdecl _except_handler(
    struct _EXCEPTION_RECORD *ExceptionRecord,
    void * EstablisherFrame,
    struct _CONTEXT *ContextRecord,
    void * DispatcherContext
    );
    我们来分析函数的参数。第一个参数是指向下面结构体的指针。
    typedef struct _EXCEPTION_RECORD {
    DWORD ExceptionCode;
    DWORD ExceptionFlags;
    struct _EXCEPTION_RECORD *ExceptionRecord;
    PVOID ExceptionAddress;
    DWORD NumberParameters;
    DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
    } EXCEPTION_RECORD;

    ExceptionCode是Windows NT的异常代号。异常在NTSTATUS.H文件中被描述为STATUX_xx
    xxxx

    :    ExceptionAddres - 发生异常的地址。
    第三个参数是指向CONTEXT结构体的指针。
    typedef struct _CONTEXT
    {
    DWORD ContextFlags;
    DWORD Dr0;
    DWORD Dr1;
    DWORD Dr2;
    :.
    DWORD Esp;
    DWORD SegSs;
    } CONTEXT;
    这个结构体定义于WINNT.H文件。其意义是不言而喻的,这里就不全写了。函数返回下面
    枚举类型值中的一个:

    typedef enum _EXCEPTION_DISPOSITION {
          ExceptionContinueExecution,
          ExceptionContinueSearch,
          ExceptionNestedException,
          ExceptionCollidedUnwind
    } EXCEPTION_DISPOSITION;
    ExceptionFlags定义了下面的位标志:
    #define EH_NONCONTINUABLE     1
    #define EH_UNWINDING          2
    #define EH_EXIT_UNWIND        4
    #define EH_STACK_INVALID      8
    #define EH_NESTED_CALL     0x10
    在发生异常时,控制传递到ntoskrnl.exe中相应的处理程序。例如,如果试图下面这段
    代码:

    mov eax,80100000h
    mov dword ptr [eax],0
    这会引发异常0e,控制传递向处理程序KiTrap0E,堆栈中错误号为07(试图在用户模式
    下向内核写入。该页位于内存中,因为线性地址80100000h是内核加载的起始地址)。之
    后,控制传递到ntdll.dll,在这里解析线程的TEB并顺次执行链表中所有的处理程序,
    直到某个函数的返回代号不是ExceptionContinueSearch。在此之后,再次调用链表中的
    所有处理函数,直到找到某个函数,但这次用的是另外一个代号ExceptionCode(STATU
    S_UNWIND)并在ExceptionFlags设置位EH_UNWINDINGS。这个标志用于异常处理,进行堆
    栈的清除和其它必要的工作。如果没有一个处理程序能处理,则就来到链表中最后一个
    处理程序,由Win32子系统建立的处理程序。这个处理程序是如何被建立的以及建立在哪
    里在以后研究CreateProcessW函数时会讲到。关于异常处理的完整介绍可以从MSDN获得
    ,因为在反汇编源代码中所得到的是扩大化了的异常处理机制(更高层次的机制)。

    这样初学者研究SHE反调试就有章可寻了
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    免责声明

    本站中所有被研究的素材与信息全部来源于互联网,版权争议与本站无关。本站所发布的任何软件编程开发或软件的逆向分析文章、逆向分析视频、补丁、注册机和注册信息,仅限用于学习和研究软件安全的目的。全体用户必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。学习编程开发技术或逆向分析技术是为了更好的完善软件可能存在的不安全因素,提升软件安全意识。所以您如果喜欢某程序,请购买注册正版软件,获得正版优质服务!不得将上述内容私自传播、销售或者用于商业用途!否则,一切后果请用户自负!

    QQ|Archiver|手机版|小黑屋|联系我们|宝峰科技 ( 滇公网安备 53050202000040号 | 滇ICP备09007156号-2 )

    Copyright © 2001-2023 Discuz! Team. GMT+8, 2025-5-8 13:56 , File On Powered by Discuz! X3.49

    快速回复 返回顶部 返回列表