Kaspersky Flaw(5) -- 修改没有输出和不是系统服务的内核函数

修改没有输出和不是系统服务的内核函数

KAV的内核补丁还不仅局限于系统服务,其中最危险的就是挂钩一个既不是输出函数又不是系统服务的内核函数nt!SwapContext(因此并没有可靠的办法,只能从编码的特殊痕迹来获取它的地址)。nt!SwapContext在内核每一次上下文切换的时候都会被调用,以便进行内部数据的保存。

作者认为,通过不可靠的编码特殊痕迹来对未输出的重要核心函数进行补丁的方式并不可取。更不好的是,KAV所采用的补丁方法是对nt!SwapContext函数内部代码进行修改,而不是在函数开始处补丁。这将导致对该函数内部的寄存器和堆栈使用作出一些实现的假定。

kd> u nt!SwapContext
nt!SwapContext:
804db924 0ac9 or cl,cl
804db926 26c6462d02 mov byte ptr es:[esi+0x2d],0x2
804db92b 9c pushfd
804db92c 8b0b mov ecx,[ebx]
804db92e e9dd69d677 jmp klif!KavSwapContext (f8242310)

未修改的nt!SwapContext函数如下:

lkd> u nt!SwapContext
nt!SwapContext:
80540ab0 0ac9 or cl,cl
80540ab2 26c6462d02 mov byte ptr es:[esi+0x2d],0x2
80540ab7 9c pushfd
80540ab8 8b0b mov ecx,[ebx]
80540aba 83bb9409000000 cmp dword ptr [ebx+0x994],0x0
80540ac1 51 push ecx
80540ac2 0f8535010000 jne nt!SwapContext+0x14d (80540bfd)
80540ac8 833d0ca0558000 cmp dword ptr [nt!PPerfGlobalGroupMask (8055a00c)],0x0

以下列出几个这样补丁非常危险的原因:
1、nt!SwapContext是内核中使用非常频繁的函数,在每一次上下文切换都会被调用。因此对它进行动态补丁通常都会冒着使系统崩溃的风险,尤其是在多处理器的系统下。KAV试图通过在单处理器系统下彻底关闭中断来解决动态补丁带来的同步问题,但这种办法无法在多处理器系统上可靠的工作。所以KAV在多处理器系统下不对该问题做任何处理,结果就是在系统启动时KAV的动态补丁会导致系统随机崩溃。

2、定位nt!SwapContext函数的可靠性和对寄存器和堆栈使用的假设,必然造成无法在各版本Windows系统做到兼容,但KAV仍然固执的使用这种办法。KAV的用户必须要忍受Windows升级后无法启动系统的风险,因为KAV对进程上下文切换作出的假设很有可能是不正确的。

此外,为了能够便于进行内核代码补丁,KAV通过修改PTE属性来调整内核代码的页保护,而不是采用对内部内存管理结构进行了锁定保护的公开函数。

KAV的nt!SwapContext补丁函数如下:
.text:F82264EA mov eax, 90909090h ; 构造挂钩nt!SwapContext函数的代码
.text:F82264EF mov [ebp+var_38], eax
.text:F82264F2 mov [ebp+var_34], eax
.text:F82264F5 mov [ebp+var_30], ax
.text:F82264F9 mov byte ptr [ebp+var_38], 0E9h
.text:F82264FD mov ecx, offset KavSwapContext
.text:F8226502 sub ecx, ebx ; (译注:ebx保存的是原nt!SwapContext要被修改的起始地址)
.text:F8226504 sub ecx, 5
.text:F8226507 mov [ebp+var_38+1], ecx
.text:F822650A mov ecx, [ebp+var_1C] ; (译注:[ebp+var_1C]保存的是要修改代码的长度)
.text:F822650D lea edx, [ecx+ebx]
.text:F8226510 mov dword_F8228338, edx
.text:F8226516 mov esi, ebx
.text:F8226518 mov edi, offset unk_F8227DBC
.text:F822651D mov eax, ecx
.text:F822651F shr ecx, 2
.text:F8226522 rep movsd
.text:F8226524 mov ecx, eax
.text:F8226526 and ecx, 3
.text:F8226529 rep movsb
.text:F822652B lea ecx, [ebp+var_48] ; 通过直接修改PTE属性让nt!SwapContent函数可写
.text:F822652E push ecx
.text:F822652F push 1
.text:F8226531 push ebx
.text:F8226532 call ModifyPteAttributes
.text:F8226537 test al, al
.text:F8226539 jz short loc_F8226588
.text:F822653B mov ecx, offset KavInternalSpinLock
.text:F8226540 call KavSpinLockAcquire ; 关闭中断
.text:F8226545 mov ecx, [ebp+var_1C] ; 更改内核代码
.text:F8226548 lea esi, [ebp+var_38]
.text:F822654B mov edi, ebx
.text:F822654D mov edx, ecx
.text:F822654F shr ecx, 2
.text:F8226552 rep movsd
.text:F8226554 mov ecx, edx
.text:F8226556 and ecx, 3
.text:F8226559 rep movsb
.text:F822655B mov edx, eax
.text:F822655D mov ecx, offset KavInternalSpinLock
.text:F8226562 call KavSpinLockRelease ; 打开中断
.text:F8226567 lea eax, [ebp+var_48] ; 恢复原来的PTE属性
.text:F822656A push eax
.text:F822656B mov ecx, [ebp+var_48]
.text:F822656E push ecx
.text:F822656F push ebx
.text:F8226570 call ModifyPteAttributes
.text:F8226575 mov al, 1
.text:F8226577 mov ecx, [ebp+var_10]
.text:F822657A mov large fs:0, ecx
.text:F8226581 pop edi
.text:F8226582 pop esi
.text:F8226583 pop ebx
.text:F8226584 mov esp, ebp
.text:F8226586 pop ebp
.text:F8226587 retn

KavSpinLockAcquire子函数(关闭中断):
.text:F8221240 KavSpinLockAcquire proc near ; CODE XREF:

sub_F8225690+D7p
.text:F8221240 ; sub_F8225D50+8Cp ...
.text:F8221240 pushf
.text:F8221241 pop eax
.text:F8221242
.text:F8221242 loc_F8221242: ; CODE XREF: KavSpinLockAcquire+13j
.text:F8221242 cli
.text:F8221243 lock bts dword ptr [ecx], 0
.text:F8221248 jb short loc_F822124B
.text:F822124A retn
.text:F822124B ; ---------------------------------------------------------------------------
.text:F822124B
.text:F822124B loc_F822124B: ; CODE XREF: KavSpinLockAcquire+8j
.text:F822124B push eax
.text:F822124C popf
.text:F822124D
.text:F822124D loc_F822124D: ; CODE XREF: KavSpinLockAcquire+17j
.text:F822124D test dword ptr [ecx], 1
.text:F8221253 jz short loc_F8221242
.text:F8221255 pause
.text:F8221257 jmp short loc_F822124D
.text:F8221257 KavSpinLockAcquire endp

KavSpinLockRelease子函数(打开中断):
.text:F8221260 KavSpinLockRelease proc near ; CODE XREF:

sub_F8225690+F2p
.text:F8221260 ; sub_F8225D50+BAp ...
.text:F8221260 mov dword ptr [ecx], 0
.text:F8221266 push edx
.text:F8221267 popf
.text:F8221268 retn
.text:F8221268 KavSpinLockRelease endp

ModifyPteAttributes子函数:
.text:F82203C0 ModifyPteAttributes proc near ; CODE XREF:

sub_F821A9D0+91p
.text:F82203C0 ; sub_F8220950+43p ...
.text:F82203C0
.text:F82203C0 var_24 = dword ptr -24h
.text:F82203C0 var_20 = byte ptr -20h
.text:F82203C0 var_1C = dword ptr -1Ch
.text:F82203C0 var_18 = dword ptr -18h
.text:F82203C0 var_10 = dword ptr -10h
.text:F82203C0 var_4 = dword ptr -4
.text:F82203C0 arg_0 = dword ptr 8
.text:F82203C0 arg_4 = byte ptr 0Ch
.text:F82203C0 arg_8 = dword ptr 10h
.text:F82203C0
.text:F82203C0 push ebp
.text:F82203C1 mov ebp, esp
.text:F82203C3 push 0FFFFFFFFh
.text:F82203C5 push offset dword_F8212180
.text:F82203CA push offset _except_handler3
.text:F82203CF mov eax, large fs:0
.text:F82203D5 push eax
.text:F82203D6 mov large fs:0, esp
.text:F82203DD sub esp, 14h
.text:F82203E0 push ebx
.text:F82203E1 push esi
.text:F82203E2 push edi
.text:F82203E3 mov [ebp+var_18], esp
.text:F82203E6 xor ebx, ebx
.text:F82203E8 mov [ebp+var_20], bl
.text:F82203EB mov esi, [ebp+arg_0]
.text:F82203EE mov ecx, esi
.text:F82203F0 call KavGetEflags
.text:F82203F5 push esi
.text:F82203F6 call KavGetPte ; KavGetPte是一个动态设定的函数指针,根据系统设定PAE选项变化
.text:F82203FC mov edi, eax
.text:F82203FE mov [ebp+var_1C], edi
.text:F8220401 cmp edi, 0FFFFFFFFh
.text:F8220404 jz short loc_F8220458
.text:F8220406 mov [ebp+var_4], ebx
.text:F8220409 mov ecx, esi
.text:F822040B call KavGetEflags
.text:F8220410 mov eax, [edi]
.text:F8220412 test al, 1
.text:F8220414 jz short loc_F8220451
.text:F8220416 mov ecx, eax
.text:F8220418 mov [ebp+var_24], ecx
.text:F822041B cmp [ebp+arg_4], bl
.text:F822041E jz short loc_F8220429
.text:F8220420 mov eax, [ebp+var_1C]
.text:F8220423 lock or dword ptr [eax], 2
.text:F8220427 jmp short loc_F8220430
.text:F8220429 ; ---------------------------------------------------------------------------
.text:F8220429
.text:F8220429 loc_F8220429: ; CODE XREF: ModifyPteAttributes+5Ej
.text:F8220429 mov eax, [ebp+var_1C]
.text:F822042C lock and dword ptr [eax], 0FFFFFFFDh
.text:F8220430
.text:F8220430 loc_F8220430: ; CODE XREF: ModifyPteAttributes+67j
.text:F8220430 mov eax, [ebp+arg_8]
.text:F8220433 cmp eax, ebx
.text:F8220435 jz short loc_F822043C
.text:F8220437 and ecx, 2
.text:F822043A mov [eax], cl
.text:F822043C
.text:F822043C loc_F822043C: ; CODE XREF: ModifyPteAttributes+75j
.text:F822043C mov [ebp+var_20], 1
.text:F8220440 mov eax, [ebp+arg_0]
.text:F8220443 invlpg byte ptr [eax]
.text:F8220446 jmp short loc_F8220451
.text:F8220448 ; ---------------------------------------------------------------------------
.text:F8220448
.text:F8220448 loc_F8220448: ; DATA XREF: .text:F8212184o
.text:F8220448 mov eax, 1
.text:F822044D retn
.text:F822044E ; ---------------------------------------------------------------------------
.text:F822044E
.text:F822044E loc_F822044E: ; DATA XREF: .text:F8212188o
.text:F822044E mov esp, [ebp-18h]
.text:F8220451
.text:F8220451 loc_F8220451: ; CODE XREF: ModifyPteAttributes+54j
.text:F8220451 ; ModifyPteAttributes+86j
.text:F8220451 mov [ebp+var_4], 0FFFFFFFFh
.text:F8220458
.text:F8220458 loc_F8220458: ; CODE XREF: ModifyPteAttributes+44j
.text:F8220458 mov al, [ebp+var_20]
.text:F822045B mov ecx, [ebp+var_10]
.text:F822045E mov large fs:0, ecx
.text:F8220465 pop edi
.text:F8220466 pop esi
.text:F8220467 pop ebx
.text:F8220468 mov esp, ebp
.text:F822046A pop ebp
.text:F822046B retn 0Ch
.text:F822046B ModifyPteAttributes endp 

Kaspersky Flaw的都是翻译自Skywing的"What Were They Thinking? Anti-Virus Software Gone Wrong",只对其中关于Kaspersky的部分进行翻译。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值