2015年2月17日星期二

查看进程回调的函数的地址

0: kd> x nt!*PspCreateProcessNotifyRoutine*
80564a60          nt!PspCreateProcessNotifyRoutineCount = <no type information>
80564a40          nt!PspCreateProcessNotifyRoutine = <no type information>
0: kd> dd 80564a60 L1
80564a60  00000001
0: kd> dd 80564a40 L1
80564a40  e22ecc07
0: kd> dd e22ecc04 L1 上面的数的二进制的低四位清零然后加4(64位可能是加八).也就是16进制的末尾清零加4(64位可能是加八).
e22ecc04  b1abeeb0
0: kd> u b1abeeb0
ahsh!ProcessCreateMon [e:\ahsh\sandbox\filter\process.c @ 179]:
b1abeeb0 8bff            mov     edi,edi


上面的是XP的32位的分析。
--------------------------------------------------------------------------------------------------
下面分析win10 X64的。

首先,先用IDA分析下ntoskrnl.exe,得出:
PsSetCreateProcessNotifyRoutine
PsSetCreateProcessNotifyRoutineEx
PsSetCreateProcessNotifyRoutineEx2
都用到了nt!PspCreateProcessNotifyRoutine。
不过,计数有两个PspCreateProcessNotifyRoutineCount和PspCreateProcessNotifyRoutineExCount。


0: kd> ||
.  0 64-bit Full kernel dump: C:\WINDOWS\livekd.dmp
0: kd> vertarget
Windows 8 Kernel Version 9200 MP (4 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 16299.15.amd64fre.rs3_release.170928-1534
Machine Name:
Kernel base = 0xfffff800`c648d000 PsLoadedModuleList = 0xfffff800`c67f3fd0
Debug session time: Thu Jan  4 14:08:28.974 2018 (UTC + 8:00)
System Uptime: 0 days 1:02:35.071
0: kd> dq nt!PspCreateProcessNotifyRoutine
fffff800`c682ad40  ffffae00`5d44ab1f ffffae00`5d87496f
fffff800`c682ad50  ffffae00`5f005fef ffffae00`5f0581df
fffff800`c682ad60  ffffae00`5f09709f ffffae00`5f20589f
fffff800`c682ad70  ffffae00`5f182b5f ffffae00`5f18083f
fffff800`c682ad80  ffffae00`611d2bbf 00000000`00000000
fffff800`c682ad90  00000000`00000000 00000000`00000000
fffff800`c682ada0  00000000`00000000 00000000`00000000
fffff800`c682adb0  00000000`00000000 00000000`00000000
0: kd> dd nt!PspCreateProcessNotifyRoutineCount L1
fffff800`c6c7ae80  00000005
0: kd> dd nt!PspCreateProcessNotifyRoutineExCount L1
fffff800`c6c7ae84  00000004

听说X64上的SSDT都做了手脚,小加密移位等运算,这个进程回掉也不会简单吧!
不信你看:
0: kd> dq ffffae00`5d44ab1f
ffffae00`5d44ab1f  00000000`000000ff 00000000`00000000
ffffae00`5d44ab2f  31695602`07000300 c78a14c6`d1c37830
ffffae00`5d44ab3f  00000000`00000071 00000000`00000000
ffffae00`5d44ab4f  00000001`00000400 00000000`00000000
ffffae00`5d44ab5f  00000100`00000000 0000a832`31695600
ffffae00`5d44ab6f  fff800c6`5a74a000 fff800c6`49ec90ff
ffffae00`5d44ab7f  ffae005d`4d7d30ff ffae0061`206630ff
ffffae00`5d44ab8f  00000000`000000ff 00000000`7d003600
这是什么东西呢?乍看都找不到自己想要的。

经过了思索,看WRK的代码,IDA分析,走了不少的弯路。
IDA分析出ExCompareExchangeCallBack函数是要点。
经查WRK这个函数的第二个参数是PEX_CALLBACK_ROUTINE_BLOCK,可见插入的是一个结构的指针,这是ExAllocateCallBack函数申请的。
这个函数的重点是ExFastRefCompareSwapObject函数。
ExFastRefCompareSwapObject函数又调用了InterlockedCompareExchangePointerRelease。

ExFastRefCompareSwapObject函数里看到了MAX_FAST_REFS的位与的操作。
#if defined (_WIN64)
#define MAX_FAST_REFS 15
#else
#define MAX_FAST_REFS 7
#endif

可是这和上面的也不照啊!看来微软又修改了。

这时确实无招了,那就看看这个内存的TAG吧!
听说一个地址的前面几个字节是TAG,于是:
0: kd> dq ffffae00`5d44ab1f - 8 L1
ffffae00`5d44ab17  fff800c6`5ac5c000

说明下,如果自己编写驱动,并添加了进程回调的代码,此时你会发现此地址是很特殊的,和吸引人的。

其实,这是个有符号的数,然后右移8位就是注册的回调函数,代码演示如下:

    SSIZE_T x = 0xfff800c65ac5c000;
    SSIZE_T y = x >> 8;

0: kd> ln fffff800c65ac5c0
Browse module
Set bu breakpoint

(fffff800`c65ac5c0)   nt!ViCreateProcessCallback   |  (fffff800`c65ac5e0)   nt!IopCancelIrpsInCurrentThreadListSpecialApc
Exact matches:
    nt!ViCreateProcessCallback (void)
0: kd> u fffff800c65ac5c0
nt!ViCreateProcessCallback:
fffff800`c65ac5c0 4883ec28        sub     rsp,28h
fffff800`c65ac5c4 833dd5f9230000  cmp     dword ptr [nt!ViVerifierEnabled (fffff800`c67ebfa0)],0
fffff800`c65ac5cb 488bc2          mov     rax,rdx
fffff800`c65ac5ce 0f857acf0a00    jne     nt!ViCreateProcessCallback+0xacf8e (fffff800`c665954e)
fffff800`c65ac5d4 4883c428        add     rsp,28h
fffff800`c65ac5d8 c3              ret
fffff800`c65ac5d9 cc              int     3
fffff800`c65ac5da cc              int     3
0: kd> lmDva 0xfffff800`c65ac5c0
Browse full module list
start             end                 module name
fffff800`c648d000 fffff800`c6d62000   nt         (pdb symbols)          c:\symbols\ntkrnlmp.pdb\9378084E8DBD4AB1A155099BCE693E341\ntkrnlmp.pdb
    Loaded symbol image file: ntkrnlmp.exe
    Image path: ntkrnlmp.exe
    Image name: ntkrnlmp.exe
    Browse all global symbols  functions  data
    Timestamp:        Mon Jan  1 19:07:05 2018 (5A4A1659)
    CheckSum:         00842CC4
    ImageSize:        008D5000
    Translations:     0000.04b0 0000.04e4 0409.04b0 0409.04e4

顺便说下:
IDA分析中有个按位操作(_interlockedbittestandset)PspNotifyEnableMask,估计这就是那个最多64个限制的原因。
应该是32,因为定义是int不是64位的。
看样子还有开关。
0: kd> dd nt!PspNotifyEnableMask L1
fffff800`c6c7aaf4  0000000f
0: kd> .formats f
Evaluate expression:
  Hex:     00000000`0000000f
  Decimal: 15
  Octal:   0000000000000000000017
  Binary:  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00001111
  Chars:   ........
  Time:    Thu Jan  1 08:00:15 1970
  Float:   low 2.10195e-044 high 0
  Double:  7.41098e-323


至此分析完毕,其他的,如:thread,image等应该与此类似。

最后奉送一个查看进程回调函数的命令/脚本:
0: kd> r @$t0=(poi(nt!PspCreateProcessNotifyRoutineCount) + poi(nt!PspCreateProcessNotifyRoutineExCount));r @$t1=nt!PspCreateProcessNotifyRoutine;.for(r @$t2=0; @$t2<@$t0; r @$t2=@$t2+1){.printf /D "ProcessNotifyRoutine(%d):%y\n", (@$t2 + 1), ((poi(((poi(@$t1+@$t2*8))-@@(sizeof(void *))))>>8) | ff00000000000000)}
ProcessNotifyRoutine(1):nt!ViCreateProcessCallback (fffff800`955252f0)
ProcessNotifyRoutine(2):cng!CngCreateProcessNotifyRoutine (fffff801`82693d10)
ProcessNotifyRoutine(3):ksecdd!KsecCreateProcessNotifyRoutine (fffff801`8332be10)
ProcessNotifyRoutine(4):tcpip!CreateProcessNotifyRoutineEx (fffff801`8345a0e0)
ProcessNotifyRoutine(5):iorate!IoRateProcessCreateNotify (fffff801`8394c010)
ProcessNotifyRoutine(6):CI!I_PEProcessNotify (fffff801`82620c00)
ProcessNotifyRoutine(7):dxgkrnl!DxgkProcessNotify (fffff801`852a3020)
ProcessNotifyRoutine(8):nvlddmkm+0xe6bf4 (fffff801`871f6bf4)
ProcessNotifyRoutine(9):peauth+0x2bbd0 (fffff800`9989bbd0) 这个没有符号文件,所以出现下面的错误。
ProcessNotifyRoutine(10):Memory access error at ')>>8) | ff00000000000000)'


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

made by correy
made at 15:21 2018/1/4
http://correy.webs.com

没有评论:

发表评论