Kaspersky Flaw(6) -- 允许用户模式代码操作内核内存

允许用户模式代码操作内核内存

现代操作系统的一条重要原则是内核与用户模式的分离,不允许用户模式代码直接操作内核空间内存.这条原则对保证系统的稳定性非常必要,比如阻止有错误的用户模式程序破坏内核并导致系统崩溃。可是KAV程序员并不认为这种分离原则很重要。
KAV一个非常奇怪的不安全实现是让用户模式可以直接调用其内核驱动的部分函数,而不是采用加载用户模式DLL,或者加载用户模式代码到目标进程的方式。这个实现主要是用于检测DLL的加载,(最好的实现应该是通过PsSetLoadImageNotifyRoutine来完成)。
KAV在每个进程创建后对kernel32.dll进行补丁,比如修改kernel32.dll的输出函数LoadLibraryA,以便调用KAV驱动中的内核代码。此外,KAV还修改了它的驱动程序中代码段和数据段的段保护,以便用户模式代码能够调用。KAV通过设定PsLoadImageNotifyRoutine挂钩来检测kernel32.dll的加载,以便修改kernel32.dll的输出表。作者非常不理解KAV为什么不用PsSetLoadImageNotifyRoutine直接完成对DLL加载的功能,而非要采用一种允许用户模式代码直接操作内核内存的方式呢?

当一个新进程被加载的时候,CheckInjectCodeForNewProcess函数将被调用,用来检测kernel32的加载。如果被加载了,该函数将给新建进程发送一个进行补丁的APC。
.text:F82218B0 ; int __stdcall CheckInjectCodeForNewProcess(wchar_t *,PUCHAR ImageBase)
.text:F82218B0 CheckInjectCodeForNewProcess proc near ; CODE XREF: KavLoadImageNotifyRoutine+B5p
.text:F82218B0 ; KavDoKernel32Check+41p
.text:F82218B0
.text:F82218B0 arg_0 = dword ptr 4
.text:F82218B0 ImageBase = dword ptr 8
.text:F82218B0
.text:F82218B0 mov al, byte_F82282F9
.text:F82218B5 push esi
.text:F82218B6 test al, al
.text:F82218B8 push edi
.text:F82218B9 jz short loc_F8221936
.text:F82218BB mov eax, [esp+8+arg_0]
.text:F82218BF push offset aKernel32_dll ; "kernel32.dll"
.text:F82218C4 push eax ; wchar_t *
.text:F82218C5 call ds:_wcsicmp
.text:F82218CB add esp, 8
.text:F82218CE test eax, eax
.text:F82218D0 jnz short loc_F8221936
.text:F82218D2 mov al, g_FoundKernel32Exports
.text:F82218D7 mov edi, [esp+8+ImageBase]
.text:F82218DB test al, al
.text:F82218DD jnz short KavInitializePatchApcLabel
.text:F82218DF push edi
.text:F82218E0 call KavCheckFindKernel32Exports
.text:F82218E5 test al, al
.text:F82218E7 jz short loc_F8221936
.text:F82218E9
.text:F82218E9 KavInitializePatchApcLabel: ; CODE XREF: CheckInjectCodeForNewProcess+2Dj
.text:F82218E9 push ’3SeB’ ; Tag
.text:F82218EE push 30h ; NumberOfBytes
.text:F82218F0 push 0 ; PoolType
.text:F82218F2 call ds:ExAllocatePoolWithTag
.text:F82218F8 mov esi, eax
.text:F82218FA test esi, esi
.text:F82218FC jz short loc_F8221936
.text:F82218FE push edi
.text:F82218FF push 0
.text:F8221901 push offset KavPatchNewProcessApcRoutine
.text:F8221906 push offset loc_F82218A0
.text:F822190B push offset loc_F8221890
.text:F8221910 push 0
.text:F8221912 call KeGetCurrentThread
.text:F8221917 push eax
.text:F8221918 push esi
.text:F8221919 call KeInitializeApc
.text:F822191E push 0
.text:F8221920 push 0
.text:F8221922 push 0
.text:F8221924 push esi
.text:F8221925 call KeInsertQueueApc
.text:F822192B test al, al
.text:F822192D jnz short loc_F822193D
.text:F822192F push esi ; P
.text:F8221930 call ds:ExFreePool
.text:F8221936
.text:F8221936 loc_F8221936: ; CODE XREF: CheckInjectCodeForNewProcess+9j
.text:F8221936 ; CheckInjectCodeForNewProcess+20j ...
.text:F8221936 pop edi
.text:F8221937 xor al, al
.text:F8221939 pop esi
.text:F822193A retn 8
.text:F822193D ; ---------------------------------------------------------------------------
.text:F822193D
.text:F822193D loc_F822193D: ; CODE XREF: CheckInjectCodeForNewProcess+7Dj
.text:F822193D pop edi
.text:F822193E mov al, 1
.text:F8221940 pop esi
.text:F8221941 retn 8

这个APC函数将补丁kernel32的输出表(生成调用内核模式代码的Thunk)和调整PTE属性以便允许用户模式能操作KAV驱动函数。
.text:F8221810 KavPatchNewProcessApcRoutine proc near ; DATA XREF: heckInjectCodeForNewProcess+51o
.text:F8221810
.text:F8221810 var_8 = dword ptr -8
.text:F8221810 var_4 = dword ptr -4
.text:F8221810 ImageBase = dword ptr 8
.text:F8221810
.text:F8221810 push ebp
.text:F8221811 mov ebp, esp
.text:F8221813 sub esp, 8
.text:F8221816 mov eax, [ebp+ImageBase]
.text:F8221819 push esi
.text:F822181A push eax ; ImageBase
.text:F822181B call KavPatchImageForNewProcess
.text:F8221820 mov esi, dword_F8230518
.text:F8221826 mov eax, dword_F823051C
.text:F822182B and esi, 0FFFFF000h
.text:F8221831 cmp esi, eax
.text:F8221833 mov [ebp+ImageBase], esi
.text:F8221836 jnb short loc_F8221883
.text:F8221838
.text:F8221838 loc_F8221838: ; CODE XREF: KavPatchNewProcessApcRoutine+71j
.text:F8221838 push esi
.text:F8221839 call KavPageTranslation0
.text:F822183F push esi
.text:F8221840 mov [ebp+var_8], eax
.text:F8221843 call KavPageTranslation1
.text:F8221849 mov [ebp+var_4], eax
.text:F822184C mov eax, [ebp+var_8]
.text:F822184F lock or dword ptr [eax], 4
.text:F8221853 lock and dword ptr [eax], 0FFFFFEFFh
.text:F822185A mov eax, [ebp+var_4]
.text:F822185D invlpg byte ptr [eax]
.text:F8221860 lock or dword ptr [eax], 4
.text:F8221864 lock and dword ptr [eax], 0FFFFFEFDh
.text:F822186B mov eax, [ebp+ImageBase]
.text:F822186E invlpg byte ptr [eax]
.text:F8221871 mov eax, dword_F823051C
.text:F8221876 add esi, 1000h
.text:F822187C cmp esi, eax
.text:F822187E mov [ebp+ImageBase], esi
.text:F8221881 jb short loc_F8221838
.text:F8221883
.text:F8221883 loc_F8221883: ; CODE XREF: KavPatchNewProcessApcRoutine+26j
.text:F8221883 pop esi
.text:F8221884 mov esp, ebp
.text:F8221886 pop ebp
.text:F8221887 retn 0Ch
.text:F8221887 KavPatchNewProcessApcRoutine endp

.text:F8221750 ; int __stdcall KavPatchImageForNewProcess(PUCHAR ImageBase)
.text:F8221750 KavPatchImageForNewProcess proc near ; CODE XREF:KavPatchNewProcessApcRoutine+Bp
.text:F8221750
.text:F8221750 ImageBase = dword ptr 8
.text:F8221750
.text:F8221750 push ebx
.text:F8221751 call ds:KeEnterCriticalRegion
.text:F8221757 mov eax, dword_F82282F4
.text:F822175C push 1 ; Wait
.text:F822175E push eax ; Resource
.text:F822175F call ds:ExAcquireResourceExclusiveLite
.text:F8221765 push 1
.text:F8221767 call KavSetPageAttributes1
.text:F822176C mov ecx, [esp+ImageBase]
.text:F8221770 push ecx ; ImageBase
.text:F8221771 call KavPatchImage
.text:F8221776 push 0
.text:F8221778 mov bl, al
.text:F822177A call KavSetPageAttributes1
.text:F822177F mov ecx, dword_F82282F4 ; Resource
.text:F8221785 call ds:ExReleaseResourceLite
.text:F822178B call ds:KeLeaveCriticalRegion
.text:F8221791 mov al, bl
.text:F8221793 pop ebx
.text:F8221794 retn 4
.text:F8221794 KavPatchImageForNewProcess endp

KavPatchImage函数补丁kernel32中的一组LoadLibrary函数的输出函数表,让它指向位于KAV内核空间的Thunk代码:
.text:F8221680 ; int __stdcall KavPatchImage(PUCHAR ImageBase)
.text:F8221680 KavPatchImage proc near ; CODE XREF: KavPatchImageForNewProcess+21p
.text:F8221680
.text:F8221680 var_C = dword ptr -0Ch
.text:F8221680 FunctionVa = dword ptr -8
.text:F8221680 var_4 = dword ptr -4
.text:F8221680 ImageBase = dword ptr 4
.text:F8221680
.text:F8221680 mov eax, [esp+ImageBase]
.text:F8221684 sub esp, 0Ch
.text:F8221687 push ebp
.text:F8221688 push 3Ch
.text:F822168A push eax
.text:F822168B call KavReprotectExportTable
.text:F8221690 mov ebp, eax
.text:F8221692 test ebp, ebp
.text:F8221694 jnz short loc_F822169F
.text:F8221696 xor al, al
.text:F8221698 pop ebp
.text:F8221699 add esp, 0Ch
.text:F822169C retn 4
.text:F822169F ; ---------------------------------------------------------------------------
.text:F822169F
.text:F822169F loc_F822169F: ; CODE XREF: KavPatchImage+14j
.text:F822169F push ebx
.text:F82216A0 push esi
.text:F82216A1 push edi
.text:F82216A2 xor ebx, ebx
.text:F82216A4 mov edi, ebp
.text:F82216A6 mov esi, offset ExportedFunctionsToCheckTable
.text:F82216AB
.text:F82216AB CheckNextFunctionInTable: ; CODE XREF: KavPatchImage+B4j
.text:F82216AB mov edx, [esi+0Ch]
.text:F82216AE mov eax, [esp+1Ch+ImageBase]
.text:F82216B2 lea ecx, [esp+1Ch+var_C]
.text:F82216B6 push ecx
.text:F82216B7 push edx
.text:F82216B8 push eax
.text:F82216B9 call LookupExportedFunction
.text:F82216BE test eax, eax
.text:F82216C0 mov [esp+1Ch+FunctionVa], eax
.text:F82216C4 jz short loc_F8221725
.text:F82216C6 mov edx, [esp+1Ch+var_C]
.text:F82216CA lea ecx, [esp+1Ch+var_4]
.text:F82216CE push ecx
.text:F82216CF push 40h
.text:F82216D1 push 4
.text:F82216D3 push edx
.text:F82216D4 call KavExecuteNtProtectVirtualMemoryInt2E
.text:F82216D9 test al, al
.text:F82216DB jz short loc_F8221725
.text:F82216DD cmp dword ptr [esi], 0
.text:F82216E0 jnz short loc_F82216EF
.text:F82216E2 mov eax, [esp+1Ch+FunctionVa]
.text:F82216E6 mov ecx, [esp+1Ch+var_C]
.text:F82216EA mov [esi], eax
.text:F82216EC mov [esi+8], ecx
.text:F82216EF
.text:F82216EF loc_F82216EF: ; CODE XREF: KavPatchImage+60j
.text:F82216EF mov eax, edi
.text:F82216F1 mov edx, 90909090h
.text:F82216F6 mov [eax], edx
.text:F82216F8 mov [eax+4], edx
.text:F82216FB mov [eax+8], edx
.text:F82216FE mov [eax+0Ch], dx
.text:F8221702 mov [eax+0Eh], dl
.text:F8221705 mov byte ptr [edi], 0E9h
.text:F8221708 mov ecx, [esi+4]
.text:F822170B mov edx, ebx
.text:F822170D sub ecx, ebx
.text:F822170F sub ecx, ebp
.text:F8221711 sub ecx, 5
.text:F8221714 mov [edi+1], ecx
.text:F8221717 mov ecx, [esp+1Ch+ImageBase]
.text:F822171B mov eax, [esp+1Ch+var_C]
.text:F822171F sub edx, ecx
.text:F8221721 add edx, ebp
.text:F8221723 mov [eax], edx ;
.text:F8221723 ; Patching Export Table here
.text:F8221723 ; e.g. write to 7c802f58
.text:F8221723 ; (kernel32 EAT entry for LoadLibraryA)
.text:F8221723 ;
.text:F8221723 ; 578 241 00001D77 LoadLibraryA = _LoadLibraryA@4
.text:F8221723 ; 579 242 00001D4F LoadLibraryExA = _LoadLibraryExA@12
.text:F8221723 ; 580 243 00001AF1 LoadLibraryExW = _LoadLibraryExW@12
.text:F8221723 ; 581 244 0000ACD3 LoadLibraryW = _LoadLibraryW@4
.text:F8221723 ;
.text:F8221723 ; KAV writes a new RVA pointing to its hook code here.
.text:F8221725
.text:F8221725 loc_F8221725: ; CODE XREF: KavPatchImage+44j.text:F8221725 ; KavPatchImage+5Bj
.text:F8221725 add esi, 10h
.text:F8221728 add ebx, 0Fh
.text:F822172B add edi, 0Fh
.text:F822172E cmp esi, offset byte_F82357E0
.text:F8221734 jb CheckNextFunctionInTable
.text:F822173A pop edi
.text:F822173B pop esi
.text:F822173C pop ebx
.text:F822173D mov al, 1
.text:F822173F pop ebp
.text:F8221740 add esp, 0Ch
.text:F8221743 retn 4
.text:F8221743 KavPatchImage endp

KAV输出表的补丁代码必须假定用户模式文件的PE文件头是正确的,且不包含任何指向内核空间的偏移量(译注:这些都是在系统一切正常的情况下才会有的,不过系统本来已经被污染的话,这样的补丁就可能造成系统崩溃。):
.text:F8221360 KavReprotectExportTable proc near ; CODE XREF: KavPatchImage+Bp
.text:F8221360
.text:F8221360 var_10 = dword ptr -10h
.text:F8221360 var_C = dword ptr -0Ch
.text:F8221360 var_8 = dword ptr -8
.text:F8221360 var_4 = dword ptr -4
.text:F8221360 arg_0 = dword ptr 4
.text:F8221360 arg_4 = dword ptr 8
.text:F8221360
.text:F8221360 mov eax, [esp+arg_0]
.text:F8221364 sub esp, 10h
.text:F8221367 cmp word ptr [eax], ’ZM’
.text:F822136C push ebx
.text:F822136D push ebp
.text:F822136E push esi
.text:F822136F push edi
.text:F8221370 jnz loc_F8221442
.text:F8221376 mov esi, [eax+3Ch]
.text:F8221379 add esi, eax
.text:F822137B mov [esp+20h+var_C], esi
.text:F822137F cmp dword ptr [esi], ’EP’
.text:F8221385 jnz loc_F8221442
.text:F822138B lea eax, [esp+20h+var_8]
.text:F822138F xor edx, edx
.text:F8221391 mov dx, [esi+14h]
.text:F8221395 push eax
.text:F8221396 xor eax, eax
.text:F8221398 push 40h
.text:F822139A mov ax, [esi+6]
.text:F822139E lea ecx, [eax+eax*4]
.text:F82213A1 lea eax, [edx+ecx*8+18h]
.text:F82213A5 push eax
.text:F82213A6 push esi
.text:F82213A7 call KavExecuteNtProtectVirtualMemoryInt2E ; NtProtectVirtualMemory
.text:F82213AC test al, al
.text:F82213AE jz loc_F8221442
.text:F82213B4 mov ecx, [esi+8]
.text:F82213B7 mov [esp+20h+var_10], 0
.text:F82213BF inc ecx
.text:F82213C0 mov [esi+8], ecx
.text:F82213C3 xor ecx, ecx
.text:F82213C5 mov cx, [esi+14h]
.text:F82213C9 cmp word ptr [esi+6], 0
.text:F82213CE lea edi, [ecx+esi+18h]
.text:F82213D2 jbe short loc_F8221442
.text:F82213D4 mov ebp, [esp+20h+arg_4]
.text:F82213D8
.text:F82213D8 loc_F82213D8: ; CODE XREF: KavReprotectExportTable+E0j
.text:F82213D8 mov ebx, [edi+10h]
.text:F82213DB test ebx, 0FFFh
.text:F82213E1 jz short loc_F82213EA
.text:F82213E3 or ebx, 0FFFh
.text:F82213E9 inc ebx
.text:F82213EA
.text:F82213EA loc_F82213EA: ; CODE XREF: KavReprotectExportTable+81j
.text:F82213EA mov ecx, [edi+8]
.text:F82213ED mov edx, ebx
.text:F82213EF sub edx, ecx
.text:F82213F1 cmp edx, ebp
.text:F82213F3 jle short loc_F822142C
.text:F82213F5 mov esi, [edi+0Ch]
.text:F82213F8 mov ecx, [esp+20h+arg_0]
.text:F82213FC sub esi, ebp
.text:F82213FE push ebp
.text:F82213FF add esi, ebx
.text:F8221401 add esi, ecx
.text:F8221403 push esi
.text:F8221404 call KavFindSectionName
.text:F8221409 test al, al
.text:F822140B jz short loc_F8221428
.text:F822140D cmp dword ptr [edi+1], ’TINI’
.text:F8221414 jz short loc_F8221428
.text:F8221416 lea eax, [esp+20h+var_4]
.text:F822141A push eax
.text:F822141B push 40h
.text:F822141D push ebp
.text:F822141E push esi
.text:F822141F call KavExecuteNtProtectVirtualMemoryInt2E ; NtProtectVirtualMemory
.text:F8221424 test al, al
.text:F8221426 jnz short loc_F822144E
.text:F8221428
.text:F8221428 loc_F8221428: ; CODE XREF:

KavReprotectExportTable+ABj
.text:F8221428 ; KavReprotectExportTable+B4j
.text:F8221428 mov esi, [esp+20h+var_C]
.text:F822142C
.text:F822142C loc_F822142C: ; CODE XREF: KavReprotectExportTable+93j
.text:F822142C mov eax, [esp+20h+var_10]
.text:F8221430 xor ecx, ecx
.text:F8221432 mov cx, [esi+6]
.text:F8221436 add edi, 28h
.text:F8221439 inc eax
.text:F822143A cmp eax, ecx
.text:F822143C mov [esp+20h+var_10], eax
.text:F8221440 jb short loc_F82213D8
.text:F8221442
.text:F8221442 loc_F8221442: ; CODE XREF:

KavReprotectExportTable+10j
.text:F8221442 ; KavReprotectExportTable+25j ...
.text:F8221442 pop edi
.text:F8221443 pop esi
.text:F8221444 pop ebp
.text:F8221445 xor eax, eax
.text:F8221447 pop ebx
.text:F8221448 add esp, 10h
.text:F822144B retn 8
.text:F822144E ; ---------------------------------------------------------------------------
.text:F822144E
.text:F822144E loc_F822144E: ; CODE XREF:

KavReprotectExportTable+C6j
.text:F822144E mov eax, [edi+8]
.text:F8221451 mov [edi+10h], ebx
.text:F8221454 add eax, ebp
.text:F8221456 mov [edi+8], eax
.text:F8221459 mov eax, esi
.text:F822145B pop edi
.text:F822145C pop esi
.text:F822145D pop ebp
.text:F822145E pop ebx
.text:F822145F add esp, 10h
.text:F8221462 retn 8
.text:F8221462 KavReprotectExportTable endp

上述KAV所采用的技术更像是一种黑客技术。此外,KAV动态获取NtProtectVirtualMemory的系统服务编号,以便利用它的int2E Thunk函数进行调用。
.text:F8221320 KavExecuteNtProtectVirtualMemoryInt2E proc near
.text:F8221320 ; CODE XREF: KavReprotectExportTable+47p
.text:F8221320 ; KavReprotectExportTable+BFp ...
.text:F8221320
.text:F8221320 arg_0 = dword ptr 4
.text:F8221320 arg_4 = dword ptr 8
.text:F8221320 arg_8 = dword ptr 0Ch
.text:F8221320 arg_C = dword ptr 10h
.text:F8221320
.text:F8221320 mov eax, [esp+arg_0]
.text:F8221324 mov ecx, [esp+arg_C]
.text:F8221328 mov edx, [esp+arg_8]
.text:F822132C push ebx
.text:F822132D mov [esp+4+arg_0], eax
.text:F8221331 push ecx
.text:F8221332 lea eax, [esp+8+arg_4]
.text:F8221336 push edx
.text:F8221337 mov edx, NtProtectVirtualMemoryOrdinal
.text:F822133D lea ecx, [esp+0Ch+arg_0]
.text:F8221341 push eax
.text:F8221342 push ecx
.text:F8221343 push 0FFFFFFFFh
.text:F8221345 push edx
.text:F8221346 xor bl, bl
.text:F8221348 call KavInt2E
.text:F822134D test eax, eax
.text:F822134F mov al, 1
.text:F8221351 jge short loc_F8221355
.text:F8221353 mov al, bl
.text:F8221355
.text:F8221355 loc_F8221355: ; CODE XREF: KavExecuteNtProtectVirtualMemoryInt2E+31j
.text:F8221355 pop ebx
.text:F8221356 retn 10h
.text:F8221356 KavExecuteNtProtectVirtualMemoryInt2E endp

.user:F8231090 KavInt2E proc near ; CODE XREF: KavExecuteNtProtectVirtualMemoryInt2E+28p
.user:F8231090
.user:F8231090 arg_0 = dword ptr 8
.user:F8231090 arg_4 = dword ptr 0Ch
.user:F8231090
.user:F8231090 push ebp
.user:F8231091 mov ebp, esp
.user:F8231093 mov eax, [ebp+arg_0]
.user:F8231096 lea edx, [ebp+arg_4]
.user:F823109C int 2Eh
.user:F823109C
.user:F823109E pop ebp
.user:F823109F retn 18h
.user:F823109F KavInt2E endp
.user:F823109F

KAV的输出函数查找代码对没有使用的PE文件头偏移量,并不能验证其正确性:
.text:F8220CA0 LookupExportedFunction proc near ; CODE XREF: sub_F8217A60+C9p
.text:F8220CA0 ; sub_F82181D0+Dp ...
.text:F8220CA0
.text:F8220CA0 var_20 = dword ptr -20h
.text:F8220CA0 var_1C = dword ptr -1Ch
.text:F8220CA0 var_18 = dword ptr -18h
.text:F8220CA0 var_14 = dword ptr -14h
.text:F8220CA0 var_10 = dword ptr -10h
.text:F8220CA0 var_C = dword ptr -0Ch
.text:F8220CA0 var_8 = dword ptr -8
.text:F8220CA0 var_4 = dword ptr -4
.text:F8220CA0 arg_0 = dword ptr 4
.text:F8220CA0 arg_4 = dword ptr 8
.text:F8220CA0 arg_8 = dword ptr 0Ch
.text:F8220CA0
.text:F8220CA0 mov edx, [esp+arg_0]
.text:F8220CA4 sub esp, 20h
.text:F8220CA7 cmp word ptr [edx], ’ZM’
.text:F8220CAC push ebx
.text:F8220CAD push ebp
.text:F8220CAE push esi
.text:F8220CAF push edi
.text:F8220CB0 jnz loc_F8220DE1
.text:F8220CB6 mov eax, [edx+3Ch]
.text:F8220CB9 add eax, edx
.text:F8220CBB cmp dword ptr [eax], ’EP’
.text:F8220CC1 jnz loc_F8220DE1
.text:F8220CC7 mov eax, [eax+78h]
.text:F8220CCA mov edi, [esp+30h+arg_4]
.text:F8220CCE add eax, edx
.text:F8220CD0 mov [esp+30h+var_14], eax
.text:F8220CD4 mov esi, [eax+1Ch]
.text:F8220CD7 mov ebx, [eax+24h]
.text:F8220CDA mov ecx, [eax+20h]
.text:F8220CDD add esi, edx
.text:F8220CDF add ebx, edx
.text:F8220CE1 add ecx, edx
.text:F8220CE3 cmp edi, 1000h
.text:F8220CE9 mov [esp+30h+var_4], esi
.text:F8220CED mov [esp+30h+var_C], ebx
.text:F8220CF1 mov [esp+30h+var_18], ecx
.text:F8220CF5 jnb short loc_F8220D27
.text:F8220CF7 mov ecx, [eax+10h]
.text:F8220CFA mov eax, edi
.text:F8220CFC sub eax, ecx
.text:F8220CFE mov eax, [esi+eax*4]
.text:F8220D01 add eax, edx
.text:F8220D03 mov edx, [esp+30h+arg_8]
.text:F8220D07 test edx, edx
.text:F8220D09 jz loc_F8220DE3
.text:F8220D0F mov ebx, ecx
.text:F8220D11 shl ebx, 1Eh
.text:F8220D14 sub ebx, ecx
.text:F8220D16 add ebx, edi
.text:F8220D18 pop edi
.text:F8220D19 lea ecx, [esi+ebx*4]
.text:F8220D1C pop esi
.text:F8220D1D pop ebp
.text:F8220D1E mov [edx], ecx
.text:F8220D20 pop ebx
.text:F8220D21 add esp, 20h
.text:F8220D24 retn 0Ch
.text:F8220D27 ; ---------------------------------------------------------------------------
.text:F8220D27
.text:F8220D27 loc_F8220D27: ; CODE XREF: LookupExportedFunction+55j
.text:F8220D27 mov edi, [eax+14h]
.text:F8220D2A mov [esp+30h+arg_0], 0
.text:F8220D32 test edi, edi
.text:F8220D34 mov [esp+30h+var_8], edi
.text:F8220D38 jbe loc_F8220DE1
.text:F8220D3E mov [esp+30h+var_1C], esi
.text:F8220D42
.text:F8220D42 loc_F8220D42: ; CODE XREF: LookupExportedFunction+13Bj
.text:F8220D42 cmp dword ptr [esi], 0
.text:F8220D45 jz short loc_F8220DC5
.text:F8220D47 mov ecx, [eax+18h]
.text:F8220D4A xor ebp, ebp
.text:F8220D4C test ecx, ecx
.text:F8220D4E mov [esp+30h+var_10], ecx
.text:F8220D52 jbe short loc_F8220DC5
.text:F8220D54 mov edi, [esp+30h+var_18]
.text:F8220D58 mov [esp+30h+var_20], ebx
.text:F8220D5C
.text:F8220D5C loc_F8220D5C: ; CODE XREF:

LookupExportedFunction+11Bj
.text:F8220D5C mov ebx, [esp+30h+var_20]
.text:F8220D60 xor esi, esi
.text:F8220D62 mov si, [ebx]
.text:F8220D65 mov ebx, [esp+30h+arg_0]
.text:F8220D69 cmp esi, ebx
.text:F8220D6B jnz short loc_F8220DAA
.text:F8220D6D mov eax, [edi]
.text:F8220D6F mov esi, [esp+30h+arg_4]
.text:F8220D73 add eax, edx
.text:F8220D75
.text:F8220D75 loc_F8220D75: ; CODE XREF: LookupExportedFunction+F3j
.text:F8220D75 mov bl, [eax]
.text:F8220D77 mov cl, bl
.text:F8220D79 cmp bl, [esi]
.text:F8220D7B jnz short loc_F8220D99
.text:F8220D7D test cl, cl
.text:F8220D7F jz short loc_F8220D95
.text:F8220D81 mov bl, [eax+1]
.text:F8220D84 mov cl, bl
.text:F8220D86 cmp bl, [esi+1]
.text:F8220D89 jnz short loc_F8220D99
.text:F8220D8B add eax, 2
.text:F8220D8E add esi, 2
.text:F8220D91 test cl, cl
.text:F8220D93 jnz short loc_F8220D75
.text:F8220D95
.text:F8220D95 loc_F8220D95: ; CODE XREF: LookupExportedFunction+DFj
.text:F8220D95 xor eax, eax
.text:F8220D97 jmp short loc_F8220D9E
.text:F8220D99 ; ---------------------------------------------------------------------------
.text:F8220D99
.text:F8220D99 loc_F8220D99: ; CODE XREF: LookupExportedFunction+DBj
.text:F8220D99 ; LookupExportedFunction+E9j
.text:F8220D99 sbb eax, eax
.text:F8220D9B sbb eax, 0FFFFFFFFh
.text:F8220D9E
.text:F8220D9E loc_F8220D9E: ; CODE XREF: LookupExportedFunction+F7j
.text:F8220D9E test eax, eax
.text:F8220DA0 jz short loc_F8220DED
.text:F8220DA2 mov eax, [esp+30h+var_14]
.text:F8220DA6 mov ecx, [esp+30h+var_10]
.text:F8220DAA
.text:F8220DAA loc_F8220DAA: ; CODE XREF: LookupExportedFunction+CBj
.text:F8220DAA mov esi, [esp+30h+var_20]
.text:F8220DAE inc ebp
.text:F8220DAF add esi, 2
.text:F8220DB2 add edi, 4
.text:F8220DB5 cmp ebp, ecx
.text:F8220DB7 mov [esp+30h+var_20], esi
.text:F8220DBB jb short loc_F8220D5C
.text:F8220DBD mov ebx, [esp+30h+var_C]
.text:F8220DC1 mov edi, [esp+30h+var_8]
.text:F8220DC5
.text:F8220DC5 loc_F8220DC5: ; CODE XREF: LookupExportedFunction+A5j
.text:F8220DC5 ; LookupExportedFunction+B2j
.text:F8220DC5 mov ecx, [esp+30h+arg_0]
.text:F8220DC9 mov esi, [esp+30h+var_1C]
.text:F8220DCD inc ecx
.text:F8220DCE add esi, 4
.text:F8220DD1 cmp ecx, edi
.text:F8220DD3 mov [esp+30h+arg_0], ecx
.text:F8220DD7 mov [esp+30h+var_1C], esi
.text:F8220DDB jb loc_F8220D42
.text:F8220DE1
.text:F8220DE1 loc_F8220DE1: ; CODE XREF: LookupExportedFunction+10j
.text:F8220DE1 ; LookupExportedFunction+21j ...
.text:F8220DE1 xor eax, eax
.text:F8220DE3
.text:F8220DE3 loc_F8220DE3: ; CODE XREF: LookupExportedFunction+69j

.text:F8220DE3 ; LookupExportedFunction+162j
.text:F8220DE3 pop edi
.text:F8220DE4 pop esi
.text:F8220DE5 pop ebp
.text:F8220DE6 pop ebx
.text:F8220DE7 add esp, 20h
.text:F8220DEA retn 0Ch
.text:F8220DED ; ---------------------------------------------------------------------------
.text:F8220DED
.text:F8220DED loc_F8220DED: ; CODE XREF:

LookupExportedFunction+100j
.text:F8220DED mov eax, [esp+30h+var_4]
.text:F8220DF1 mov ecx, [esp+30h+arg_0]
.text:F8220DF5 lea ecx, [eax+ecx*4]
.text:F8220DF8 mov eax, [ecx]
.text:F8220DFA add eax, edx
.text:F8220DFC mov edx, [esp+30h+arg_8]
.text:F8220E00 test edx, edx
.text:F8220E02 jz short loc_F8220DE3
.text:F8220E04 pop edi
.text:F8220E05 pop esi
.text:F8220E06 pop ebp
.text:F8220E07 mov [edx], ecx
.text:F8220E09 pop ebx
.text:F8220E0A add esp, 20h
.text:F8220E0D retn 0Ch
.text:F8220E0D LookupExportedFunction endp 

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值