繞過殺毒軟件之一(實時監控篇)
殺毒軟件的實時監控分爲兩個部分
一:Notify部分
二:Attach到文件系統部分
一:Notify對與殺毒軟件致關重要(有些流氓軟件也用的),主要用到的是
PsSetLoadImageNotifyRoutine和
PsSetCreateProcessNotifyRoutine這兩個函數
1 PsSetLoadImageNotifyRoutine(
IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine
);
通過字面意思大家也知道,就是文件被加載的時侯會調用這個NotifyRoutine;最簡單的是一個Exe在Run的過程中,PE加載器檢查它所depend的dll,然後由PE加載器LoadLibaray這些dll,此時NotifyRoutine就被調用起來了。
(PS:這個NotifyRoutine就是一個callback)
part1: 2k下的分析
kd> u PsSetLoadImageNotifyRoutine L10
nt!PsSetLoadImageNotifyRoutine:
804e31d4 b89a0000c0 mov eax,0xc000009a
804e31d9 33c9 xor ecx,ecx
804e31db ba20324880 mov edx,0x80483220
804e31e0 833a00 cmp dword ptr [edx],0x0
804e31e3 740e jz nt!PsSetLoadImageNotifyRoutine+0x1f (804e31f3)
804e31e5 83c204 add edx,0x4
804e31e8 41 inc ecx
804e31e9 81fa40324880 cmp edx,0x80483240
804e31ef 72ef jb nt!PsSetLoadImageNotifyRoutine+0xc (804e31e0)
804e31f1 eb1a jmp nt!PsSetLoadImageNotifyRoutine+0x39 (804e320d)
804e31f3 8b442404 mov eax,[esp+0x4]
804e31f7 ff0504324880 inc dword ptr [nt!PspLoadImageNotifyRoutineCount (80483204
)]
804e31fd 89048d20324880 mov [nt!PspLoadImageNotifyRoutine (80483220)+ecx*4],eax
804e3204 33c0 xor eax,eax
804e3206 c6051031488001 mov byte ptr [nt!PsImageNotifyEnabled (80483110)],0x1
804e320d c20400 ret 0x4
對應c代碼:
ULONG i;
NTSTATUS Status;
Status = STATUS_INSUFFICIENT_RESOURCES;
for (i=0; i < PSP_MAX_LOAD_IMAGE_NOTIFY; i++)
{
if (PspLoadImageNotifyRoutine[i] == NULL)
{
PspLoadImageNotifyRoutine[i] = NotifyRoutine;
PspLoadImageNotifyRoutineCount+= 1;
Status = STATUS_SUCCESS;
PsImageNotifyEnable= TRUE;
break;
}
}
我們如果不想讓某個NotifyRoutine監控,就把它在PspLoadImageNotifyRoutine數組中對應項清空,可是PspLoadImageNotifyRoutine並沒有導出,我們不能直接調用,有什麼方法呢?
1) 我們自己寫個MyNotifyRoutine.
VOID MyNotifyRoutine(
IN PUNICODE_STRING FullImageName,
IN HANDLE ProcessId,
IN PIMAGE_INFO ImageInfo)
{
return;
}
2) PsSetLoadImageNotifyRoutine(MyNotifyRoutine);
3) 直接在PsSetLoadImageNotifyRoutine函數裏找有效地址,然後訪問這個地址,看有沒有MyNotifyRoutine的地址,沒有的話再找下一個;
4) 直到找到爲止,那麼此時這個有效地址就是PspLoadImageNotifyRoutine的地址了
5) 遍歷PspLoadImageNotifyRoutine數組中的地址,檢查這些地址是否落在某個驅動程序的地址範圍,如果是的話,清了這一項,現在再LoadLibrary這個驅動程序就不會收到任何通知了。
如果你閒麻煩就直接把PspLoadImageNotifyRoutine所有項都清理掉。
part2: xp/2003下的分析
lkd> u PsSetLoadImageNotifyRoutine L25
nt!PsSetLoadImageNotifyRoutine:
8062d4f7 8bff mov edi,edi
8062d4f9 55 push ebp
8062d4fa 8bec mov ebp,esp
8062d4fc 53 push ebx
8062d4fd 57 push edi
8062d4fe 33ff xor edi,edi
8062d500 57 push edi
8062d501 ff7508 push dword ptr [ebp+0x8]
8062d504 e833790100 call nt!ExAllocateCallBack (80644e3c)
8062d509 8bd8 mov ebx,eax
8062d50b 3bdf cmp ebx,edi
8062d50d 7507 jnz nt!PsSetLoadImageNotifyRoutine+0x1f (8062d516)
8062d50f b89a0000c0 mov eax,0xc000009a
8062d514 eb2a jmp nt!PsSetLoadImageNotifyRoutine+0x49 (8062d540)
8062d516 56 push esi
8062d517 be001d5680 mov esi,0x80561d00
8062d51c 6a00 push 0x0
8062d51e 53 push ebx
8062d51f 56 push esi
8062d520 e84e790100 call nt!ExCompareExchangeCallBack (80644e73)
8062d525 84c0 test al,al
8062d527 751d jnz nt!PsSetLoadImageNotifyRoutine+0x4f (8062d546)
8062d529 83c704 add edi,0x4
8062d52c 83c604 add esi,0x4
8062d52f 83ff20 cmp edi,0x20
8062d532 72e8 jb nt!PsSetLoadImageNotifyRoutine+0x25 (8062d51c)
8062d534 53 push ebx
8062d535 e89134f4ff call nt!RtlpSysVolFree (805709cb)
8062d53a b89a0000c0 mov eax,0xc000009a
8062d53f 5e pop esi
8062d540 5f pop edi
8062d541 5b pop ebx
8062d542 5d pop ebp
8062d543 c20400 ret 0x4
對應c代碼:
ULONG i;
PEX_CALLBACK_ROUTINE_BLOCK CallBack;
CallBack = ExAllocateCallBack((PEX_CALLBACK_FUNCTION) NotifyRoutine, NULL);
if (CallBack == NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
}
for (i = 0; i < PSP_MAX_LOAD_IMAGE_NOTIFY; i++) {
if (ExCompareExchangeCallBack(&PspLoadImageNotifyRoutine[i],
CallBack,
NULL)) {
InterlockedIncrement ((PLONG)&PspLoadImageNotifyRoutineCount);
PsImageNotifyEnable = TRUE;
return STATUS_SUCCESS;
}
}
ExFreeCallBack(CallBack);
return STATUS_INSUFFICIENT_RESOURCES;
2 PsSetCreateProcessNotifyRoutine
二 Attach到文件系統部分
一:Notify部分
二:Attach到文件系統部分
一:Notify對與殺毒軟件致關重要(有些流氓軟件也用的),主要用到的是
PsSetLoadImageNotifyRoutine和
PsSetCreateProcessNotifyRoutine這兩個函數
1 PsSetLoadImageNotifyRoutine(
IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine
);
通過字面意思大家也知道,就是文件被加載的時侯會調用這個NotifyRoutine;最簡單的是一個Exe在Run的過程中,PE加載器檢查它所depend的dll,然後由PE加載器LoadLibaray這些dll,此時NotifyRoutine就被調用起來了。
(PS:這個NotifyRoutine就是一個callback)
part1: 2k下的分析
kd> u PsSetLoadImageNotifyRoutine L10
nt!PsSetLoadImageNotifyRoutine:
804e31d4 b89a0000c0 mov eax,0xc000009a
804e31d9 33c9 xor ecx,ecx
804e31db ba20324880 mov edx,0x80483220
804e31e0 833a00 cmp dword ptr [edx],0x0
804e31e3 740e jz nt!PsSetLoadImageNotifyRoutine+0x1f (804e31f3)
804e31e5 83c204 add edx,0x4
804e31e8 41 inc ecx
804e31e9 81fa40324880 cmp edx,0x80483240
804e31ef 72ef jb nt!PsSetLoadImageNotifyRoutine+0xc (804e31e0)
804e31f1 eb1a jmp nt!PsSetLoadImageNotifyRoutine+0x39 (804e320d)
804e31f3 8b442404 mov eax,[esp+0x4]
804e31f7 ff0504324880 inc dword ptr [nt!PspLoadImageNotifyRoutineCount (80483204
)]
804e31fd 89048d20324880 mov [nt!PspLoadImageNotifyRoutine (80483220)+ecx*4],eax
804e3204 33c0 xor eax,eax
804e3206 c6051031488001 mov byte ptr [nt!PsImageNotifyEnabled (80483110)],0x1
804e320d c20400 ret 0x4
對應c代碼:
ULONG i;
NTSTATUS Status;
Status = STATUS_INSUFFICIENT_RESOURCES;
for (i=0; i < PSP_MAX_LOAD_IMAGE_NOTIFY; i++)
{
if (PspLoadImageNotifyRoutine[i] == NULL)
{
PspLoadImageNotifyRoutine[i] = NotifyRoutine;
PspLoadImageNotifyRoutineCount+= 1;
Status = STATUS_SUCCESS;
PsImageNotifyEnable= TRUE;
break;
}
}
我們如果不想讓某個NotifyRoutine監控,就把它在PspLoadImageNotifyRoutine數組中對應項清空,可是PspLoadImageNotifyRoutine並沒有導出,我們不能直接調用,有什麼方法呢?
1) 我們自己寫個MyNotifyRoutine.
VOID MyNotifyRoutine(
IN PUNICODE_STRING FullImageName,
IN HANDLE ProcessId,
IN PIMAGE_INFO ImageInfo)
{
return;
}
2) PsSetLoadImageNotifyRoutine(MyNotifyRoutine);
3) 直接在PsSetLoadImageNotifyRoutine函數裏找有效地址,然後訪問這個地址,看有沒有MyNotifyRoutine的地址,沒有的話再找下一個;
4) 直到找到爲止,那麼此時這個有效地址就是PspLoadImageNotifyRoutine的地址了
5) 遍歷PspLoadImageNotifyRoutine數組中的地址,檢查這些地址是否落在某個驅動程序的地址範圍,如果是的話,清了這一項,現在再LoadLibrary這個驅動程序就不會收到任何通知了。
如果你閒麻煩就直接把PspLoadImageNotifyRoutine所有項都清理掉。
part2: xp/2003下的分析
lkd> u PsSetLoadImageNotifyRoutine L25
nt!PsSetLoadImageNotifyRoutine:
8062d4f7 8bff mov edi,edi
8062d4f9 55 push ebp
8062d4fa 8bec mov ebp,esp
8062d4fc 53 push ebx
8062d4fd 57 push edi
8062d4fe 33ff xor edi,edi
8062d500 57 push edi
8062d501 ff7508 push dword ptr [ebp+0x8]
8062d504 e833790100 call nt!ExAllocateCallBack (80644e3c)
8062d509 8bd8 mov ebx,eax
8062d50b 3bdf cmp ebx,edi
8062d50d 7507 jnz nt!PsSetLoadImageNotifyRoutine+0x1f (8062d516)
8062d50f b89a0000c0 mov eax,0xc000009a
8062d514 eb2a jmp nt!PsSetLoadImageNotifyRoutine+0x49 (8062d540)
8062d516 56 push esi
8062d517 be001d5680 mov esi,0x80561d00
8062d51c 6a00 push 0x0
8062d51e 53 push ebx
8062d51f 56 push esi
8062d520 e84e790100 call nt!ExCompareExchangeCallBack (80644e73)
8062d525 84c0 test al,al
8062d527 751d jnz nt!PsSetLoadImageNotifyRoutine+0x4f (8062d546)
8062d529 83c704 add edi,0x4
8062d52c 83c604 add esi,0x4
8062d52f 83ff20 cmp edi,0x20
8062d532 72e8 jb nt!PsSetLoadImageNotifyRoutine+0x25 (8062d51c)
8062d534 53 push ebx
8062d535 e89134f4ff call nt!RtlpSysVolFree (805709cb)
8062d53a b89a0000c0 mov eax,0xc000009a
8062d53f 5e pop esi
8062d540 5f pop edi
8062d541 5b pop ebx
8062d542 5d pop ebp
8062d543 c20400 ret 0x4
對應c代碼:
ULONG i;
PEX_CALLBACK_ROUTINE_BLOCK CallBack;
CallBack = ExAllocateCallBack((PEX_CALLBACK_FUNCTION) NotifyRoutine, NULL);
if (CallBack == NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
}
for (i = 0; i < PSP_MAX_LOAD_IMAGE_NOTIFY; i++) {
if (ExCompareExchangeCallBack(&PspLoadImageNotifyRoutine[i],
CallBack,
NULL)) {
InterlockedIncrement ((PLONG)&PspLoadImageNotifyRoutineCount);
PsImageNotifyEnable = TRUE;
return STATUS_SUCCESS;
}
}
ExFreeCallBack(CallBack);
return STATUS_INSUFFICIENT_RESOURCES;
2 PsSetCreateProcessNotifyRoutine
二 Attach到文件系統部分
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.