1.LoadImageNotifyRoutine
一个dll的加载过程是这样的
我们以LoadLibraryA("1.dll")为例
LoadLibraryA
--LoadLibraryExA
--LoadLibraryExW
--BasepLoadLibraryAsDataFile
--MapViewOfFileEx
--NtMapViewOfSection
--MmMapViewOfSection
--MiMapViewOfImageSection
PAGE:004A6869 mov esi, [esi]
PAGE:004A686B shl esi, 0Ch
PAGE:004A686E cmp ds:_PsImageNotifyEnabled, 0
PAGE:004A6875 mov [ebp+var_4], esi
PAGE:004A6878 jnz loc_51AD80
判断PsImageNotifyEnabled
PAGEDATA:005B7B38 _PsImageNotifyEnabled db 0
if ( PsImageNotifyEnabled )
{
PsCallImageNotifyRoutines(v49, v38, &v56);
}
PsCallImageNotifyRoutines将会依次执行PspLoadImageNotifyRoutine指向的
notifyroutine
清除方法
1: 将PsImageNotifyEnabled=0
优点,比较方便,但是PsImageNotifyEnabled是非导出变量
只能通过MiMapViewOfImageSection或者DbgkCreateThread定位
但是上面2个函数仍然是非导出函数,如果做安全工具的话可以使用PDB解析大法
不然的话嘛...
2:PsRemoveLoadImageNotifyRoutine
标准卸载函数,但是仍然存在缺点,需要知道notifyroutine函数地址,
以及存在2000系统不能解析PsRemoveLoadImageNotifyRoutine的问题
3.自己清除PspLoadImageNotifyRoutine指向的内存地址
.data:0048A480 _PspLoadImageNotifyRoutine db 0 ; DATA XREF: PsSetLoadImageNotifyRoutine(x)+20
.data:0048A480 ; PsRemoveLoadImageNotifyRoutine(x)+Ao ...
.data:0048A481 db 0
.data:0048A482 db 0
定位可以通过导出的函数PsSetLoadImageNotifyRoutine
lkd> u PsSetLoadImageNotifyRoutine
nt!PsSetLoadImageNotifyRoutine:
8062e97b 8bff mov edi,edi
8062e97d 55 push ebp
8062e97e 8bec mov ebp,esp
8062e980 53 push ebx
8062e981 57 push edi
8062e982 33ff xor edi,edi
8062e984 57 push edi
8062e985 ff7508 push dword ptr [ebp+8]
8062e988 e8437a0100 call nt!ExAllocateCallBack (806463d0)
8062e98d 8bd8 mov ebx,eax
8062e98f 3bdf cmp ebx,edi
8062e991 7507 jne nt!PsSetLoadImageNotifyRoutine+0x1f (8062e99a)
8062e993 b89a0000c0 mov eax,0C000009Ah
8062e998 eb2a jmp nt!PsSetLoadImageNotifyRoutine+0x49 (8062e9c4)
8062e99a 56 push esi
8062e99b be80245680 mov esi,offset nt!PspLoadImageNotifyRoutine (80562480)
8062e9a0 6a00 push 0
8062e9a2 53 push ebx
8062e9a3 56 push esi
另外也可以使用PsRemoveLoadImageNotifyRoutine定位
lkd> u PsRemoveLoadImageNotifyRoutine
nt!PsRemoveLoadImageNotifyRoutine:
8062e9ec 8bff mov edi,edi
8062e9ee 55 push ebp
8062e9ef 8bec mov ebp,esp
8062e9f1 53 push ebx
8062e9f2 56 push esi
8062e9f3 57 push edi
8062e9f4 33db xor ebx,ebx
8062e9f6 bf80245680 mov edi,offset nt!PspLoadImageNotifyRoutine (80562480)
8062e9fb 57 push edi
8062e9fc e8df7a0100 call nt!ExReferenceCallBackBlock (806464e0)
8062ea01 8bf0 mov esi,eax
8062ea03 85f6 test esi,esi
相对而言 PsRemoveLoadImageNotifyRoutine的距离更加接近
不过存在2000系统不能解析PsRemoveLoadImageNotifyRoutine的问题
4.patch MiMapViewOfImageSection
更好的办法是patch PsCallImageNotifyRoutines
缺点同样是函数不被导出,存在定位困难的问题
在偶的机器上面
lkd> dd PspLoadImageNotifyRoutine
80562480 e100c2cf e100e0c7 e15e28ff 00000000
80562490 00000000 00000000 00000000 00000000 2.CreateThreadNotifyRoutine
CreateThread
--NtCreateThread
--PspCreateThread
PAGE:00523434 mov [ebp+var_58], offset _PspCreateThreadNotifyRoutine
PAGE:0052343B mov [ebp+var_84], 8
PAGE:00523445
PAGE:00523445 loc_523445: ; CODE XREF: PspCreateThread(x,x,x,x,x,x,x,x,x,x,x)+6C379j
PAGE:00523445 push [ebp+var_58]
PAGE:00523448 call _ExReferenceCallBackBlock@4 ; ExReferenceCallBackBlock(x)
PAGE:0052344D mov [ebp+var_78], eax
PAGE:00523450 cmp eax, edi
PAGE:00523452 jz short loc_523475
PAGE:00523454 push eax
PAGE:00523455 call _ExGetCallBackBlockRoutine@4 ; ExGetCallBackBlockRoutine(x)
PAGE:0052345A push 1
PAGE:0052345C push dword ptr [esi+1F0h]
PAGE:00523462 push dword ptr [esi+1ECh]
PAGE:00523468 call eax 在PspCreateThread里面执行PspCreateThreadNotifyRoutine指向的notifyroutine
偶没找到CreateThread的enabled变量,
那么看起来只有3种方法使用了
lkd> dd PspCreateThreadNotifyRoutine
805624a0 e192e317 00000000 00000000 00000000
805624b0 00000000 00000000 00000000 00000000 3.CreateProcessNotifyRoutine几乎和CreateThreadNotifyRoutine完全一样
PAGE:00523372 mov [ebp+var_54], offset _PspCreateProcessNotifyRoutine
PAGE:00523379 mov [ebp+var_7C], 8
PAGE:00523380
PAGE:00523380 loc_523380: ; CODE XREF: PspCreateThread(x,x,x,x,x,x,x,x,x,x,x)+6C2AEj
PAGE:00523380 push [ebp+var_54]
PAGE:00523383 call _ExReferenceCallBackBlock@4 ; ExReferenceCallBackBlock(x)
PAGE:00523388 mov edi, eax
PAGE:0052338A test edi, edi
PAGE:0052338C jz short loc_5233AD
PAGE:0052338E push edi
PAGE:0052338F call _ExGetCallBackBlockRoutine@4 ; ExGetCallBackBlockRoutine(x)
PAGE:00523394 push 1
PAGE:00523396 push dword ptr [ebx+84h]
PAGE:0052339C push dword ptr [ebx+14Ch]
PAGE:005233A2 call eax
lkd> dd PspCreateProcessNotifyRoutine
805624e0 e15df187 e192e32f 00000000 00000000
805624f0 00000000 00000000 00000000 00000000
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课