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
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
没有评论:
发表评论