国外高手谈卡巴斯基存隐患(1)

http://tech.ddvip.com   2007年06月22日    社区交流 收藏本文

内容摘要:我们这篇文章的核心就是要谈谈卡巴斯基的杀毒软件。跟很多其他的杀毒软件一样,卡巴斯基的杀毒软件也是既能手动操作扫描病毒也可以实时扫描病毒。我们这篇文章的核心就是要谈谈卡巴斯基的杀毒软件。跟很多其他的杀毒软件一样,卡巴斯基的杀毒软件也是既能手动操作扫描病毒也可以实时扫描病毒。

  这是非常危险的一种打包操作,原因有如下几点:

  nt!SwapContext是非常热门的代码路径,每次环境变更时都会调用它。这样一来,很难做到实时给它打补丁,并且不冒使系统崩溃的风险。KAV在单核系统上解决此类与给此函数打补丁相关的同步问题的方法是:完全关闭中断,但是,在多核系统上,这个方法并不总是有效。KAV在多核系统上并没有去努力解决这个问题,它使这些系统面临在KAV打补丁的时候会随机地出现启动失败的风险。

  准确地找到该函数的位置,并找到所有已发布的和将来出现的系统版本的注册机和堆栈用法(以及指令布局),这些都是不可能操作完成的,而KAV却恰恰试图做这样的事情。这使得KAV用户不得不担心新的系统更新,由于KAV的钩子代码所做的假设与环境变更的进程不相容,那些更新就有可能使他们的系统启动失败。

  另外,为了在内核上执行代码补丁,KAV调整了内核代码的页保护设置,使其可以通过直接修改PTE属性而不是使用文档函数(该函数可以锁住访问内部内存管理结构的语义逻辑)变得可以写入。

KAV nt!SwapContext patching:
KAV nt!SwapContext补丁:
.text:F82264EA  mov   eax, 90909090h ; Build the code to be written to 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
.text:F8226504  sub   ecx, 5
.text:F8226507  mov   [ebp+var_38+1], ecx
.text:F822650A  mov   ecx, [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] ; 使nt!SwapContext可通过直接访问而写入
.text:F822652B        ; the PTEs.
.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 ; Disable interrupts
.text:F8226545  mov   ecx, [ebp+var_1C] ; Write to kernel code
.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 ; Reenable interrupts
.text:F8226567  lea   eax, [ebp+var_48] ; Restore the original PTE attributes.
.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 subroutine (disables interrupts):
.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 subroutine (reenables interrupts):
.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 subroutine:
.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    ; 在这里的功能指针将被实时填充
.text:F82203F6        ; 因系统是否有PAE而不同
.text:F82203F6        ; 使能或者使不能。
.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

  允许用户层代码访问内核内存

  当前操作系统所使用的划分内核/用户的主要原则是:不允许用户层直接访问内核层的内存。这对维持系统稳定十分重要,比如它可以阻止有bug的用户层程序造成内核崩溃,甚至使整个系统崩溃。不幸的是,KAV的程序员们似乎认为这个原则根本不重要。

  KAV所执行的不安全操作里最奇怪的地方就在于:它允许用户层直接调用他们内核驱动的一部分(在内核地址空间内!),而不是只加载用户层DLL(或者在目标进程中加载用户层代码)。

来源:赛迪网    作者:杜莉    责编:豆豆技术应用

正在加载评论...