在windbg中测试shadow ssdt , win32k!NtUserGetForegroundWindow , hook shadow ssdt

在windbg中测试shadow ssdt , win32k!NtUserGetForegroundWindow , hook shadow ssdt

在windbg中查看shadow ssdt:

0: kd> lm
start    end        module name
804d8000 806e3000   nt         (pdb symbols)          I:\Symbols\ntkrpamp.pdb\966DF78E558F483199141B029DF5A9D51\ntkrpamp.pdb

Unloaded modules:
f56ab000 f56d6000   kmixer.sys
f7b59000 f7b5a000   drmkaud.sys
f6fc8000 f6fd5000   DMusic.sys
f7018000 f7026000   swmidi.sys
f56d6000 f56f9000   aec.sys 
f7ad9000 f7adb000   splitter.sys
f70dd000 f70e0000   wmiacpi.sys
f79fb000 f79ff000   kbdhid.sys
f78cf000 f78d4000   Cdaudio.SYS
f79ef000 f79f2000   Sfloppy.SYS
0: kd> x win32k!*     win32k.sys的symbol文件没有被载入,此时无法查看win32k.sys的内容
               ^ Couldn't resolve 'x win32k'
0: kd> uf win32k!NtUserGetForegroundWindow
Couldn't resolve error at 'win32k!NtUserGetForegroundWindow '
0: kd> !process 0 0
**** NT ACTIVE PROCESS DUMP ****
PROCESS 861b5660 SessionId: none Cid: 0004    Peb: 00000000 ParentCid: 0000
    DirBase: 069c0020 ObjectTable: e1003e40 HandleCount: 255.
    Image: System

PROCESS 85c99298 SessionId: none Cid: 0220    Peb: 7ffde000 ParentCid: 0004
    DirBase: 069c0040 ObjectTable: e1366228 HandleCount: 21.
    Image: smss.exe

PROCESS 85f92ca8 SessionId: 0 Cid: 025c    Peb: 7ffde000 ParentCid: 0220
    DirBase: 069c0060 ObjectTable: e13bfd50 HandleCount: 368.
    Image: csrss.exe
......

PROCESS 85b61020 SessionId: 0 Cid: 0794    Peb: 7ffdd000 ParentCid: 02a0
    DirBase: 069c0280 ObjectTable: e184ce98 HandleCount: 63.
    Image: VMwareService.exe

PROCESS 85c9ab38 SessionId: 0 Cid: 06cc    Peb: 7ffd4000 ParentCid: 060c
    DirBase: 069c01c0 ObjectTable: e1043768 HandleCount: 49.
    Image: notepad.exe


0: kd> .process 85c9ab38 
Implicit process is now 85c9ab38
WARNING: .cache forcedecodeuser is not enabled
0: kd> .reload    重新载入符号
Connected to Windows XP 2600 x86 compatible target, ptr64 FALSE
Loading Kernel Symbols
........................................................................................................................
Loading User Symbols
............................
Loading unloaded module list
..........
0: kd> x win32k!*      现在可以查看shadow ssdt了
bf9346be win32k!EngQueryLocalTime = <no type information>
bf938572 win32k!NtGdiCreateEllipticRgn = <no type information>
bf9ab110 win32k!ghwndSwitch = <no type information>
bf9248f9 win32k!SearchAndSetKbdTbl = <no type information>
bf92602a win32k!xxxUnlatchStickyKeys = <no type information>
bf814d93 win32k!NtUserInvalidateRect = <no type information>
bf98c678 win32k!_imp__IoGetStackLimits = <no type information>
bf944f4a win32k!vTransparentCopyS32D8 = <no type information>
bf8778da win32k!xxxMoveThumb = <no type information>
bf85ef37 win32k!KillTooltipTimer = <no type information>
bf8d3308 win32k!fsg_CompositeInnerGridFit = <no type information>
bf98c49c win32k!_imp__RtlSetOwnerSecurityDescriptor = <no type information>
bf8687ef win32k!bCalcMeshExtent = <no type information>
bf842cf7 win32k!xxxClientLoadMenu = <no type information>
bf8a1307 win32k!ParkIcon = <no type information>
......


uf一个函数试试:

0: kd> uf win32k!NtUserGetForegroundWindow   ( win32k!NtUserGetForegroundWindow是win32 api GetForegroundWindow()的内核实现)
win32k!NtUserGetForegroundWindow:
bf823d3d 8bff            mov     edi,edi
bf823d3f 56              push    esi
bf823d40 e8a4cefdff      call    win32k!EnterSharedCrit (bf800be9)
bf823d45 a160b59abf      mov     eax,dword ptr [win32k!gpqForeground (bf9ab560)]
bf823d4a 85c0            test    eax,eax
bf823d4c 7429            je      win32k!NtUserGetForegroundWindow+0x33 (bf823d77)

win32k!NtUserGetForegroundWindow+0x11:
bf823d4e 83782800        cmp     dword ptr [eax+28h],0
bf823d52 7423            je      win32k!NtUserGetForegroundWindow+0x33 (bf823d77)

win32k!NtUserGetForegroundWindow+0x17:
bf823d54 8b7028          mov     esi,dword ptr [eax+28h]
bf823d57 ff1560c298bf    call    dword ptr [win32k!_imp__PsGetCurrentThread (bf98c260)]
bf823d5d 50              push    eax
bf823d5e ff15f8c798bf    call    dword ptr [win32k!_imp__PsGetThreadWin32Thread (bf98c7f8)]
bf823d64 8b403c          mov     eax,dword ptr [eax+3Ch]
bf823d67 3b460c          cmp     eax,dword ptr [esi+0Ch]
bf823d6a 750b            jne     win32k!NtUserGetForegroundWindow+0x33 (bf823d77)
PVOID
PsGetThreadWin32Thread(
    __in PETHREAD Thread
     )
{
    return Thread->Tcb.Win32Thread;
}

PW32THREAD W32Thread;
PETHREAD PEThread = PsGetCurrentThread(); 
W32Thread = PsGetThreadWin32Thread(PEThread);
//不知道W32Thread和W32Thread->3Ch是什么结构
/*
0: kd> dt _W32THREAD
win32k!_W32THREAD
   +0x000 pEThread         : Ptr32 _ETHREAD
   +0x004 RefCount         : Uint4B
   +0x008 ptlW32           : Ptr32 _TL
   +0x00c pgdiDcattr       : Ptr32 Void
   +0x010 pgdiBrushAttr    : Ptr32 Void
   +0x014 pUMPDObjs        : Ptr32 Void
   +0x018 pUMPDHeap        : Ptr32 Void
   +0x01c dwEngAcquireCount : Uint4B
   +0x020 pSemTable        : Ptr32 Void
   +0x024 pUMPDObj         : Ptr32 Void
3Ch是什么?
*/
if( W32Thread->3Ch != [   [win32k!gpqForeground]+28h +0Ch ] ){
return 0; //hwnd=0
}
 
win32k!NtUserGetForegroundWindow+0x2f:
bf823d6c 8b36            mov     esi,dword ptr [esi]

win32k!NtUserGetForegroundWindow+0x35:
bf823d6e e8a3cdfdff      call    win32k!LeaveCrit (bf800b16)
bf823d73 8bc6            mov     eax,esi
bf823d75 5e              pop     esi
bf823d76 c3              ret

win32k!NtUserGetForegroundWindow+0x33:
bf823d77 33f6            xor     esi,esi
bf823d79 ebf3            jmp     win32k!NtUserGetForegroundWindow+0x35 (bf823d6e)



可以看到win32k!NtUserGetForegroundWindow()返回的值其实是 [   [win32k!gpqForeground]+28h ],我们在windbg就可以查看这个值:

0: kd> dd poi(poi(win32k!gpqForeground) +28h)
bc6542b0 00030100 00000009 e24102c8 85c4d480
bc6542c0 bc6542b0 40020049 80000300 00000910
bc6542d0 14cf0000 01000000 00000000 bc66d800
bc6542e0 bc66e010 bc6506e8 bc66e820 00000000
bc6542f0 00000041 00000045 00000299 000001d9
bc654300 00000045 00000077 00000295 000001d5
bc654310 01003429 bc654230 00000000 bc66e1c8
bc654320 00000000 00000000 bc654478 03040587

其中00030100 便是win32k!NtUserGetForegroundWindow()的返回值。
在驱动中可以这样实现:
 

ULONG ASM_GetForeground(){

    //win32k.sys不常驻内存,调用它的函数前一定要先载入gui进程
    KeAttachProcess(crsEProc);
    DbgPrint("==hwnd:%x \n",g_OriginalNtUserGetForegroundWindow());//
    __asm{
        ;call    win32k!EnterSharedCrit (bf800be9)
        ;mov        eax,0bf800be9h 
        ;call    eax
        
        mov     eax,0bf9ab560h        ;win32k!gpqForeground.我用的是硬编码
        mov     eax,dword ptr [eax]
        test    eax,eax
        je      _failed

        cmp     dword ptr [eax+28h],0
        je      _failed

        mov     esi,dword ptr [eax+28h]
        mov        esi,[esi]
        jmp        _end

_failed:
        mov        esi,0
_end:
        ;call    win32k!LeaveCrit (bf800b16)
        ;mov        eax,0bf800b16h
        ;call    eax

        call KeDetachProcess

        mov        eax,esi
    }
}



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

尝试一下下断点

0: kd> bu win32k!_imp__PsGetThreadWin32Thread

WARNING: Software breakpoints on session addresses can cause bugchecks.
Use hardware execution breakpoints (ba e) if possible.
0: kd> bc *
0: kd> ba e1 win32k!_imp__PsGetThreadWin32Thread 必须下硬件断点,否则会导致异常!
0: kd> bl
0 e bf98c7f8 e 1 0001 (0001) win32k!_imp__PsGetThreadWin32Thread

至此下断点成功

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

最后是测试hook shadow ssdt 。
《Hook Shadow SSDT》 里面有参考代码.我测试了一下添加对NtUserInternalGetWindowText()的hook:

if ( majorVersion == 5 && minorVersion == 1 )
    {
    DbgPrint("comint32: Running on Windows XP\n");
      NtUserFindWindowEx_callnumber = 0x17A;
    NtUserGetForegroundWindow_callnumber = 0x194;
    NtUserBuildHwndList_callnumber = 0x138;
    NtUserQueryWindow_callnumber = 0x1E3;
    NtUserWindowFromPoint_callnumber = 0x250;
    NtUserInternalGetWindowText_callnumber = 0x1c1;

    }

INT MyNtUserInternalGetWindowText(
                                IN HWND hwnd,
                                OUT LPWSTR lpString,
                                IN int nMaxCount){
    INT result;
    result=g_OriginalNtUserInternalGetWindowText(hwnd,lpString,nMaxCount);
    DbgPrint("MyNtUserInternalGetWindowText() hwnd:%x, lpString:%x-\"%S\", %d, %d\n",hwnd,lpString,lpString,nMaxCount,result);
    return result;
}






参考:
《shadow ssdt学习笔记(一)(二)》http://bbs.pediy.com/showthread.php?t=56955
《Hook Shadow SSDT》 http://bbs.pediy.com/showthread.php?t=65931
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一:SSDT表的hook检测和恢复 ~!~~~ 二:IDT表的hook检测和恢复 ~~~~~~(idt多处理器的恢复没处理,自己机器是单核的,没得搞,不过多核的列举可以) 三:系统加载驱动模块的检测 通过使用一个全局hash表(以DRIVEROBJECT为对象)来使用以下的方法来存储得到的结果,最终显示出来 1.常规的ZwQuerySystemInformation来列举 2通过打开驱动对象目录来列举 3搜索内核空间匹配驱动的特征来列举(这个功能里面我自己的主机一运行就死机,别的机器都没事,手动设置热键来蓝屏都不行,没dump没法分析,哎,郁闷) 4从本驱动的Modulelist开始遍历来列举驱动 四:进程的列举和进程所加载的dll检测 采用以下方法来列举进程: 1ZwQuerySystemInformation参数SystemProcessesAndThreadsInformation来枚举 2进程EPROCESS 结构的Activelist遍历来枚举 3通过解析句柄表来枚举进程 4通过Handletablelisthead枚举进程 5进程创建时都会向csrss来注册,从这个进程里面句柄表来枚举进程 6通过自身进程的HANDLETABLE来枚举进程 7通过EPROCESS的SessionProcessLinks来枚举进程 8通过EPROCESS ---VM---WorkingSetExpansionLinks获取进程 9暴力搜索内存MmSystemRangeStart以上查找PROCESS对象 进程操作: 进程的唤醒和暂停通过获取PsSuspendProcess和PsResumeProcess来操作的 进程结束通过进程空间清0和插入apc。 采用以下方法查找DLL: 1遍历VAD来查找dll 2挂靠到对应的进程查找InLoadOrderLinks来枚举dll 3暴力搜索对应进程空间查找pe特征来枚举dll DLL的操作: Dll的卸载是通过MmUnmapViewOfSection和MmmapViewOfSection(从sdt表相应函数搜索到的)来实现的(本来想直接清0 dll空间,有时行有时不行)(只要将这个进程的ntdll卸载了,进程就结束了,一个好的杀进程的办法撒,绿色环保无污染),注入dll使用的是插入apc实现的。(注入的dll必须是realse版的。Debug版会出现***错误,全局dll注入貌似也是)插入apc效果不是很好,要有线程有告警状态才执行。 五:线程信息的检测 遍历ThreadList来枚举线程 线程的暂停和唤醒都是通过反汇编获取PsResumeThread和PsSuspendThread直接从r3传来ETHREAD来操作的,通过插入APC来结束线程 六:shadow sdt表的hook检测与恢复 没有采用pdb来解决函数名问题,直接写入xp和03的shandow表函数名(主要是自己的网不稳定,连windbg有时都连不上微软) 七:系统所有的过滤驱动的检测 查看各device下是否挂接有驱动之类的,可直接卸载 八:系统常用回调历程的检测和清除 只检查了PsSetLoadImageNotifyRoutine PsSetCreateThreadNotifyRoutine PsSetCreateProcessNotifyRoutine CmRegisterCallback这几个,至于那个什么shutdown回调不知道是啥玩意,就没搞了,有知道的顺便告诉我下撒,谢谢 九:文件系统fat和ntfs的分发函数检测 直接反汇编fat和ntfs的DriverEntry得到对应的填充分发的偏移,然后和当前已经运行的文件系统的分发相比是否被hook,并附带恢复 十:文件查看功能 自己解析ntfs和fat的结构,来实现列举文件和直接写磁盘删除。附带有普通的删除和发生IRP来删除。不过这里面有点问题,ntfs删除有时把目录给搞坏了,大家凑合着吧, Ntfs网上删除这些操作的代码不多,就是sudami大大的利用ntfs-3g来实现的,看了下,太多了,充满了结构。然后自己对照着系统删除文件时目录的变化来自己实现的。只处理了$BITMAP对应的位清除,父目录的对应文件的索引项的覆盖,删除文件对应的filerecord清0. 另外偷懒时间都没处理,呵呵,y的,一个破时间都都搞好几个字节移来移去的。 十一:常用内核模块钩子的检测和恢复 这里只检测了主要的内核模块nkrnlpa**.exe的.win32k.sys,hal.dll,比对它们的原始文件从而查找eat inline hook,iat hook ,和inline hook。Inline是从TEXT段开始一段位置开始比较的。(有点慢貌似,等待显示扫描完成就好了) 十二:应用层进程所加载dll的钩子 应用层钩子检测和内核模块钩子检测原理一样,不过为了能读写别的进程的空间,并没有使用openprocess去打开进程,而是通过KiattachProcess挂靠到当前进程,然后通过在r0直接读写进程空间的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值