Guest User

Virogen source

a guest
Sep 5th, 2016
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;
  2. ;**WARNING: Encryption and Decryption code closed to public for security (as if there
  3. ; were any<g>). Everything else is here tho.
  4. ;
  5. ;
  6. ;VGCrypt PE Encryptor v0.75 Beta
  7. ;(c)1998 Virogen
  8. ;www: http://virogen.cjb.net
  9. ;----------------------------------------------------------------
  10. ;
  11. ; This is a fairly simple PE encryptor I wrote up. I commented everything
  12. ; that is relavent to PE appendation or insertion, more so than I needed to
  13. ; even. The most interesting feature of this encryptor is that it attempts to
  14. ; find a location to insert itself between object virtual size and the next
  15. ; file alignment boundary, thus not changing the physical file size.
  16. ;
  17. ; Note that this code is still under development.
  18. ;
  19. ; Features:
  20. ;   -three types of PE parasticality<g>:
  21. ;       1) install in cave - no physical size increase
  22. ;       2) append to last object
  23. ;       3) create new object
  24. ;   -full win95/98/NT compliant
  25. ;   -does not add new object unless you want to
  26. ;   -stores correct new checksum of PE executable
  27. ;   -preserves original file data/time and attributes
  28. ;   -prompts u to encrypt again if file already encrypted, you can encrypt
  29. ;    a file as many times as you want. Of course, eventually you will run out
  30. ;    of available caves and the filesize will start increasing.
  31. ;
  32. ; Usage:
  33. ;   -VGCRYPT filename
  34. ;
  35. ;
  36. ; known bugs:
  37. ;   -might be problems with some encrypted DLLs.
  38. ;
  39. ;
  40. ; Note to coders:
  41. ;   If you need to retrieve API RVAs in the decryptor, the best way is to
  42. ;   manually import from the kernel32 export table in memory. The base of
  43. ;   kernel32.dll can be obtained by using [esp] at entry and scanning down
  44. ;   to the base. For more information, see my viral code at
  45. ;   http://virogen.cjb.net.
  46. ;
  47. ;
  48. ; Updates:
  49. ;   11/26/98 v0.40: Initial release
  50. ;   11/27/98 v0.45: Added simple SEH anti-debugging code
  51. ;                   Fixed command line problem when running under winnt
  52. ;                    dos box
  53. ;                   Other minor changes in decryptor
  54. ;   11/28/98 v0.50: Fixed winNT image problems
  55. ;                   Added better anti-debugging code, but still needs improvements,
  56. ;                    optimization, etc.              
  57. ;                   Closed decryptor and encryption source. Sorry, but all the other
  58. ;                    code is still open
  59. ;   11/28/98 v0.51: Reformatted decryptor a little, anti-debugging code still needs to
  60. ;                    be improved alot.
  61. ;   11/28/98 v0.54: Fixed exception when object with no physical offset/size encountered.
  62. ;                   Temporarily disabled portion of anti-debugging code.
  63. ;   11/29/98 v0.56: Source code beautification by Ghiribizzo<g>.
  64. ;                   EBP now preserved correctly
  65. ;                   Minor winNT command line problem fixed
  66. ;                   Encrypted DLLs now load, but some have unusual problems
  67. ;                   Executables which are loaded at an image base other than the one
  68. ;                   specifid in the PE header (unusual) will now work properly.
  69. ;                   No longer flagged by AVP if appended to last object
  70. ;                   Note that when we reach v0.60 I will re-release the source
  71. ;                   code, with the noted exceptions of the encryption and decryption
  72. ;                   code.
  73. ;   11/30/98 v0.57: If no "caves" found, gives you choice of appending to last object or
  74. ;                   creating a new object.
  75. ;   11/30/98 v0.58: Minor bug fix in creating new object.
  76. ;           Was missing last object while traversing thru object table, oops.
  77. ;   11/31/98 v0.60: Checks to make sure there is room to add another object to
  78. ;           object table before allowing user to select this option.
  79. ;           Other minor changes here and there.
  80. ;   12/05/98 v0.61: Now accounts correctly for PEs loaded at a differing image base.
  81. ;               I had forgotten to recalculate encrypted object addresses. This
  82. ;           was a minor bug because it is rare to have a PE loaded a base other
  83. ;           than the one specified in the header.
  84. ;   12/09/98 v0.65: Now avoids encrypting import & export table no matter where it is at.
  85. ;               Oops, should done this in the first place.
  86. ;   12/19/98 v0.75: Improved security a little bit, still not secure at all.. someday
  87. ;           I will remedy this.
  88. ;                  
  89. ;
  90. ;
  91. ; ====================================================================================
  92. ; Special thanks to Ghiribizzo who has provided more anti-debugging ideas than I can
  93. ;  even hope to have time to implement<g>. http://Ghiribizzo.home.ml.org
  94. ; Greetz lapse,jp,vecna,darkman,Iczelion, and everyone else.
  95. ; ====================================================================================
  96. ;
  97. ;
  98. ;
  99. include mywin.inc      
  100.  
  101. ID_OFF          equ     0ch    ; offset of our marker in PE
  102. DECRYPTOR_SIZE  equ     (offset decryptor_code_end-offset decryptor_code)  ;
  103. VIRTUAL_SIZE    equ     DECRYPTOR_SIZE
  104. MAX_OBJS        equ     6               ; maximum objects we can handle
  105.                                         ; by increasing this you are increasing the size
  106.                                         ; of the table in decryptor by MAX_OBJS*8.
  107.  
  108. .586p
  109. locals
  110. jumps
  111. .model flat,STDCALL
  112.  
  113. extrn   ExitProcess:PROC        
  114. extrn   CreateFileA:PROC        
  115. extrn   CloseHandle:PROC        
  116. extrn   ReadFile:PROC            
  117. extrn   WriteFile:PROC          
  118. extrn   SetFilePointer:PROC      
  119. extrn   MapViewOfFile:PROC      
  120. extrn   CreateFileMappingA:PROC  
  121. extrn   UnmapViewOfFile:PROC    
  122. extrn   SetEndOfFile:PROC        
  123. extrn   SetFilePointer:PROC      
  124. extrn   GetFileAttributesA:PROC  
  125. extrn   SetFileAttributesA:PROC  
  126. extrn   GetFileSize:PROC        
  127. extrn   GetTickCount:PROC        
  128. extrn   GetFileSize:PROC        
  129. extrn   GetFileTime:PROC        
  130. extrn   SetFileTime:PROC        
  131. extrn   CheckSumMappedFile:PROC  
  132. extrn   MessageBoxA:PROC        
  133. extrn   GetCommandLineA:PROC    
  134. extrn   lstrcat:PROC            
  135. extrn   IsBadReadPtr:PROC        
  136. extrn   WriteConsoleA:PROC
  137. extrn   GetStdHandle:PROC
  138. extrn   ReadConsoleA:PROC
  139.  
  140.  
  141.  
  142. org 0  
  143. .data                                   ; data object
  144.  
  145. ; conditional compile
  146. ;console_app equ 1
  147.  
  148.  
  149. ;
  150. cr      equ 0dh
  151. lf      equ 0ah
  152. tab     equ 9
  153. hline   equ 196
  154. marker  equ 90909090h
  155.  
  156. cr_lf_tab       db cr,lf,tab,tab,0
  157. init_txt        db 50 dup(hline),cr,lf
  158. caption         db 'Virogen''s PE Encryptor v0.75, (c)1998 Virogen[NOP]'
  159. ifndef console_app
  160.                 db 0
  161. endif          
  162. ifdef console_app
  163.                 db cr,lf,'http://virogen.cjb.net email:[email protected]',cr,lf
  164.                 db 50 dup(hline),cr,lf,0        
  165. endif          
  166. badcmd_txt      db 'Invalid command line!',cr,lf,'Usage: VGCRYPT filename',cr,lf,0
  167. success_txt:
  168. ifdef console_app
  169.                 db cr,lf
  170. endif          
  171.                 db 'Successfully encrypted!'
  172. ifdef console_app
  173.                 db 0
  174. endif                          
  175. file_txt        db cr,lf,' Installed on file: ',tab,0
  176.                 db 400 dup (0)          ; plenty of space
  177. obj_txt         db cr,lf,' Installed in object: ',tab,0
  178.                 db 9 dup(0)
  179. eobj_txt        db cr,lf,' Encrypted objects: ',0
  180.                 db (MAX_OBJS*8)+1 dup(0)        
  181. hole_txt        db cr,lf,'VGCrypt installed in alignment hole, with no phsyical size increase!',0
  182. already_txt:
  183. ifdef console_app
  184.                 db cr,lf,'File appears to already be encrypted. Encrypting again.',0
  185. endif
  186.                 db 'File appears to already be encrypted. Do you wish to encrypt again?',0
  187. append_question db 'Could not locate any "caves" to install into!',cr,lf,'Click YES'
  188.                 db ' to create new object',cr,lf,'Click NO to append to last object.',0
  189. error_txt:
  190. ifdef console_app
  191.                 db cr,lf,' '
  192. endif          
  193.                 db 'There was an error encrypting the file!',cr,lf
  194. ifdef console_app
  195.                 db 0
  196. endif          
  197. fname_txt       db 'Specified file: ',0
  198.                 db 260 dup(0)
  199. nohole_txt      db cr,lf,'No available "caves" to install into, forced to increase physical size.',0
  200. doing_obj_txt   db cr,lf,'Encrypting object: ',tab,0
  201. skip_obj_txt    db cr,lf,'Skipping object: ',tab,0
  202. found_hole_obj  db cr,lf,'Found hole in object: ',tab,0
  203. done_txt        db '..Done',0
  204. creation        dd 0,0                     ; our file time structures
  205. lastaccess      dd 0,0
  206. lastwrite       dd 0,0
  207. oldchksum       dd 0
  208. fsize           dd 0
  209. map_ptr         dd 0
  210. oldattrib       dd 0                        ; stored file attribs
  211. fnameptr        dd 0                        ; ptr to file name we're inf
  212. ptrpeheader     dd 0
  213. objPsize        dd 0
  214. maphandle       dd 0
  215. handle          dd 0
  216. objtblVA        dd 0
  217. objptr          dd 0
  218. lastobjimageoff dd 0
  219. originalpsize   dd 0
  220. originalvsize   dd 0
  221. error           db -1                       ;
  222. importtbl   dd 0
  223. exporttbl       dd 0
  224. byteswrote      dd 0
  225. hstdo           dd 0
  226. hstdi           dd 0
  227. ynbuf           db 0
  228. use_hole        db 0
  229. holeptr     dd 0
  230.  
  231.  
  232. bad_otbl:                       ; this is the list of bad objs - did I miss any?
  233.    dd 'rsr.'                            ; rsrc
  234.    dd 'ler.'                            ; relo
  235.    dd 'ade.'                            ; edata
  236.    dd 'ete.'                            ; etext
  237.    dd 'adi.'                            ; idata
  238.    dd 'adr.'                            ; rdata
  239.    dd 'slt.'                            ; tls
  240.    dd 0                                
  241.  
  242. ;---- decryptor code installed into file ----
  243. ;
  244. ;
  245. ;
  246. ;*** CLOSED SOURCE, for security
  247. ;
  248. ;
  249. ;
  250. ; --- end of decryptor code ---
  251.  
  252.  
  253. ; --- start of VGCrypt ---
  254. .code                                   ; code object - change flags to rwx
  255. start:
  256. ifdef console_app      
  257.         call    GetSHandle
  258.         lea     ebx,init_txt
  259.         call    WriteString
  260. endif  
  261.         call    GetCommandLineA                 ; retrieve command line
  262.         or      eax,eax                        
  263.         jz      _exit_bad_cmd_line              ; if none then abort /w msg
  264.         xchg    esi,eax
  265. sl:
  266.         cmp     byte ptr [esi],0                ; if first byte is NULL then something way wrong
  267.         jz      _exit_bad_cmd_line    
  268.         shl     eax,8                           ; rotate 1 byte in eax, for loop.. eax running load
  269.         lodsb                           ; get next byte in al
  270.         cmp     eax,'rypt'                      ; end of our proggie name?
  271.         jnz     not_eoc
  272.         cmp     byte ptr [esi],'.'
  273.         jnz     esl
  274. not_eoc:    
  275.         cmp     eax,'.exe'                      ; .exe end of our proggie name?
  276.         jz      esl
  277.         cmp     eax,'.EXE'                      ; .EXE end of our proggie name?
  278.         jnz     sl
  279. esl:
  280.         lodsb
  281.         cmp     al,' '
  282.         jz      esl            
  283.         cmp     al,'"'
  284.         jz      esl
  285.         dec     esi
  286. esl2:    
  287.         cmp     byte ptr [esi],0                ; if first char in parameter 1 is NULL then we fuq
  288.         jz      _exit_bad_cmd_line    
  289.        
  290. ifndef console_app      
  291.         push    esi                            
  292.         push    offset success_txt              
  293.         call    lstrcat                 ; append filename to success message
  294. endif  
  295. ifdef console_app      
  296.         push    esi
  297.         push    offset fname_txt
  298.         call    lstrcat
  299.         lea     ebx,fname_txt
  300.         call    WriteString
  301. endif  
  302.         mov     fnameptr,esi                    ; set fnameptr->filename
  303.         call    EncryptFile                     ; go encrypt        
  304.         ;cmp     error,-4
  305.         ;jz      _exit
  306.         cmp     error,-1                        ; error?
  307.         jz      _exit_error                     ; if so go display error message
  308.        
  309. ifndef console_app      
  310.         push    offset obj_txt
  311.         push    offset success_txt
  312.         call    lstrcat                 ; append object name we inserted or appending to
  313.        
  314.         push    offset eobj_txt
  315.         push    offset success_txt
  316.         call    lstrcat                 ; append objects we encrypted  
  317.        
  318.         cmp     use_hole,1
  319.         jnz     no_hole_msg    
  320.         push    offset hole_txt
  321.         jmp     app_success
  322. no_hole_msg:    
  323.         push    offset nohole_txt    
  324. app_success:
  325.         push    offset success_txt
  326.         call    lstrcat
  327.  
  328.         push    0                
  329.         push    offset caption    
  330.         push    offset success_txt
  331.         push    0                
  332.         call    MessageBoxA      
  333. endif
  334. ifdef console_app
  335.         lea     ebx,success_txt
  336.         call    WriteString    
  337. endif  
  338.                                  
  339.         xor     eax,eax          
  340.         jmp     _exit            
  341.  
  342. _exit_error:
  343. ifndef console_app
  344.         push    fnameptr          
  345.         push    offset error_txt  
  346.         call    lstrcat            
  347.  
  348.         push    MB_ICONEXCLAMATION
  349.         push    offset caption    
  350.         push    offset error_txt  
  351.         push    0                  
  352.         call    MessageBoxA        
  353. endif
  354. ifdef console_app
  355.         lea     ebx,error_txt
  356.         call    WriteString    
  357. endif  
  358.         mov     eax,2              
  359.         jmp     _exit              
  360.  
  361. _exit_bad_cmd_line:
  362. ifndef console_app      
  363.         push    MB_ICONEXCLAMATION
  364.         push    offset caption    
  365.         push    offset badcmd_txt
  366.         push    0                
  367.         call    MessageBoxA      
  368. endif  
  369. ifdef console_app
  370.         lea     ebx,badcmd_txt
  371.         call    WriteString
  372. endif  
  373.         xor     eax,eax          
  374.         inc     eax              
  375.  
  376. _exit:    
  377.         call    ExitProcess,eax
  378.  
  379. ;-----------------------------------------------
  380. ; encrypt file - call with fnameptr set
  381. ;
  382. EncryptFile proc
  383.  
  384.         mov     eax,fnameptr
  385.         push    eax                                                              
  386.         call    GetFileAttributesA                  ; get file attributes        
  387.         mov     oldattrib,eax                                                      
  388.                                                                                    
  389.         cmp     eax,-1                               ; if error then maybe shared  
  390.         jnz     not_shared                                                        
  391.         ret                                          ; can't encrypt it            
  392.  
  393. not_shared:
  394.         push    20h                                 ; +A
  395.         mov     eax,fnameptr
  396.         push    eax
  397.         call    SetFileAttributesA                  ; clear 'da attribs
  398.        
  399.         mov     esi,fnameptr
  400.         call    OpenFile
  401.         call    test_error
  402.         jnc     open_ok
  403.         ret        
  404. open_ok:
  405.         mov     handle,eax                                                          
  406.                                                                                    
  407.         push    offset creation                                                    
  408.         push    offset lastaccess                                                  
  409.         push    offset lastwrite                                                    
  410.         push    eax                                                                
  411.         call    GetFileTime                           ; grab the file time          
  412.                                                                                    
  413.         xor     ecx,ecx                                ; only map size of file      
  414.         call    create_mapping                        ; create file mapping        
  415.         jc      abort_encrypt                                                      
  416.                                                ; eax->mapped file                
  417.         cmp     word ptr [eax],'ZM'                    ; is EXE?                    
  418.         jnz     abort_encrypt                                                      
  419.                                                                                    
  420.         call    GetPEHeader                           ; load esi->PE Header        
  421.                                                                                    
  422.         push    2                                                                  
  423.         push    esi                                    ; test ptr for read acces
  424.         call    IsBadReadPtr                           ; was ptr any good?      
  425.         or      eax,eax                                                            
  426.         jnz     abort_encrypt                                                      
  427.                                                                                    
  428.         cmp     word ptr [esi],'EP'                    ; PE?                        
  429.         jnz     abort_encrypt                                                      
  430.         cmp     dword ptr [esi+ID_OFF],marker          ; marker?                    
  431.         jnz     not_encrypted                          ; if yes, already processed  
  432. ifndef console_app
  433.         push    MB_ICONHAND or MB_YESNO                                            
  434.         push    offset caption                                                      
  435.         push    offset already_txt                                                  
  436.         push    0                                                                  
  437.         call    MessageBoxA                                                        
  438.         cmp     eax,IDYES                                                          
  439.         jnz     abort_encrypt                                                      
  440. endif
  441. ifdef console_app      
  442.         lea     ebx,already_txt
  443.         call    WriteString
  444. endif  
  445. not_encrypted:
  446.         call    unmap                                 ; unmap file                                  
  447.                                                                                                      
  448.         mov     ecx,1000h                              ; give us room to add to the file, if needed      
  449.         call    create_mapping                        ; map file again                              
  450.         jc      abort_encrypt                                                                        
  451.                                                                                                      
  452.         call    GetPEHeader                           ; load esi -> pe header                        
  453.                                                                                                      
  454.         call    GetTickCount                          ; get tick count                              
  455.         mov     key,eax                                ; save for encryption key                    
  456.                                                                                                      
  457.         mov     dword ptr [esi+ID_OFF],marker          ; save marker                                
  458.                                                                                                      
  459.         ;mov     eax,[esi+imagebase]                                                                  
  460.         ;mov     svd_imagebase,eax                      ; save the image base                            
  461.                                                                                                      
  462.         mov     eax,[esi+datadir]          
  463.         mov     importtbl,eax
  464.         mov     eax,[esi+edatadir]
  465.         mov     exporttbl,eax
  466.        
  467.         xor     eax,eax                                                                              
  468.         mov     ax, word ptr [esi+NtHeaderSize]        ; get header size                            
  469.         add     eax,18h                                ; object table is here                        
  470.         add     eax,esi                                                                              
  471.         mov     objptr,eax                                                                          
  472.        
  473.         ; Let's check for existance of cave after object table in PE header
  474.        
  475.        
  476.         ;mov     edi,[eax+objpoff]
  477.         ;add     edi,map_ptr
  478.         ;push    esi
  479.         ;int 3
  480.         ;push    eax
  481.         ;xor     eax,eax
  482.         ;mov     ax,[esi+numObj]        
  483.         ;inc     eax
  484.         ;mov     ecx,40
  485.         ;xor     edx,edx        
  486.         ;mul     ecx
  487.         ;pop     esi
  488.         ;add     esi,eax        
  489.         ;cmp     esi,edi
  490.         ;jge     no_room_in_hdr
  491.         ;xchg    edi,esi
  492.         ;mov     cx,DECRYPTOR_SIZE
  493.         ;xor     eax,eax
  494.         ;push    edi
  495.         ;repz    scasb
  496.         ;pop     edi
  497.         ;or      cx,cx
  498.         ;jnz    no_room_in_hdr                
  499.         ;pop     esi
  500.         ;push    esi
  501.         ;mov     eax,objptr
  502.          ;mov     ecx,[esi+filealign]
  503.         ;mov     ebx,[eax+objpoff]
  504.         ;sub     ebx,edi
  505.         ;sub     ebx,map_ptr
  506.         ;mov     [eax+objpoff],ebx
  507.                                
  508.         ;mov     holeptr,edi                
  509.         ;mov     use_hole,1
  510. no_room_in_hdr:        
  511.                      
  512.         ; Here we will traverse through the object table, encrypting objects
  513.         ; which can be encrypted and also searching for a 'cave' big enough
  514.         ; to hold us.        
  515.         ;pop    esi
  516.     push    esi                
  517.         mov     eax,objptr
  518.         lea     edi,otable                                                        
  519.         xor     ecx,ecx                                                            
  520.         mov     cx,[esi+numObj]                          ; get number of objects  
  521. ;        dec     cx                                                                
  522. otbl_loop:
  523.         cmp     edi,offset otable_end-8                  ; filled up table?
  524.         jz      next_obj    
  525.         call    test_obj                                 ; see if good obj name
  526.         jc      next_obj
  527.         pushad                              
  528.         cmp     use_hole,1                               ; already found hole?
  529.         jz      no_hole_here
  530.         mov     edx,[eax+objpsize]                       ; get obj psize
  531.         mov     ecx,[eax+objvsize]                       ; get obj vsize        
  532.         cmp     ecx,edx                                  ; any hole here?
  533.         jge     no_hole_here
  534.         sub     edx,ecx                                  ; get size of hole
  535.         cmp     edx,DECRYPTOR_SIZE                       ; big enough for us?
  536.         jl      no_hole_here    
  537.         mov     objptr,eax                               ; save ptr obj rec
  538.         mov     use_hole,1                               ; set flag                                              
  539.         mov     ecx,[eax+objvsize]                       ; encrypt vsize
  540.         mov     [edi+4],ecx                              ; if vsize<psize
  541. ifdef console_app
  542.         lea     ebx,found_hole_obj
  543.         call    WriteString
  544.         mov     ebx,eax
  545.         call    WriteString
  546. endif  
  547. no_hole_here:                
  548.         push    offset cr_lf_tab
  549.         push    offset eobj_txt
  550.         call    lstrcat
  551.         popad
  552.         pushad
  553.         push    eax
  554.         push    offset eobj_txt
  555.         call    lstrcat
  556.         popad
  557.                
  558.         push    eax ecx
  559.         mov     ebx,eax[objflags]                        ; get obj flags
  560.         or      ebx,oflag_write                           ; OR in writable flag
  561.         mov     eax[objflags],ebx                        ; save new object flags
  562.         mov     ebx,eax[objrva]                          ; get the object's rva        
  563.         mov     [edi],ebx                                ; save it
  564.         mov     ecx,[edi+4]                              ; see if we set above
  565.         or      ecx,ecx                                  ; if so then we are
  566.         jnz     already_vsize                            ; gonna use vsize
  567.         mov     ecx,eax[objpsize]                        ; get the object's physical size  
  568.         mov     [edi+4],ecx              
  569. already_vsize:                                                                          
  570. ifdef console_app      
  571.         lea     ebx,doing_obj_txt
  572.         call    WriteString    
  573.         mov     ebx,eax
  574.         call    WriteString
  575. endif  
  576.         add     edi,8                                    ; increment to next table member      
  577.         push    edi                                                                            
  578.         mov     esi,eax[objpoff]                         ; esi->object physical offset          
  579.         add     esi,map_ptr                                                                    
  580.         mov     edi,esi                                                                        
  581.         call    encrypt_object                           ; encrypt the object                  
  582.         pop     edi ecx eax                                                                            
  583. ifdef console_app      
  584.         lea     ebx,done_txt
  585.         call    WriteString    
  586. endif  
  587. ifdef console_app      
  588.         jmp     next_did
  589. endif  
  590. next_obj:    
  591. ifdef console_app
  592.         lea     ebx,skip_obj_txt
  593.         call    WriteString    
  594.         mov     ebx,eax
  595.         call    WriteString
  596. endif  
  597. next_did:
  598.         add     eax,40                                   ; increment to next object record    
  599.         loop    otbl_loop
  600. done_otbl:    
  601.         pop     esi                                       ; restore ptr pe hdr  
  602.                                                                              
  603.         cmp     use_hole,1                                                  
  604.         jz      found_hole                                                      
  605.        
  606.         sub     eax,40
  607.        
  608. ; make sure nuff room to add another object before we ask if
  609. ; the user wants to. dunno if this is best way to do it, but I
  610. ; just scan to make sure the next 40 bytes (1 object record) are
  611. ; all 0.
  612.        
  613.         pushad        
  614.         mov     edi,eax
  615.         add     edi,40
  616.         mov     ecx,40
  617.         xor eax,eax
  618.     repz    scasb
  619.     or      ecx,ecx
  620.     jnz     go_append  
  621.        
  622.         push    MB_ICONQUESTION or MB_YESNO
  623.         push    offset caption
  624.         push    offset append_question
  625.         push    0
  626.         call    MessageBoxA            
  627.         cmp     eax,IDNO
  628.         jz      go_append      
  629.         ;cmp     eax,IDCANCEL
  630.         ;jnz     go_create
  631.         ;popad
  632.         ;mov     error,-4
  633.         ;jmp     abort_encrypt
  634. go_create:        
  635. ; user selected to create new object
  636.         popad                              
  637.         mov     ecx,[eax+objrva]            ; get last object rva
  638.         add     ecx,[eax+objvsize]      ; +=last object virtual size
  639.         push    eax             ; save obj record ptr
  640.         xchg    ecx,eax             ; eax=last object virtual end
  641.         mov     ecx,[esi+objalign]      ; ecx=object alignment
  642.         call    align_fix           ; go align da shiznit
  643.         xchg    ecx,eax                     ; ecx=next object's rva
  644.         pop     eax                     ; restore obj record ptr
  645.         mov     edx,[eax+objpoff]       ; edx=last object physical offset
  646.         add     edx,[eax+objpsize]          ; edx+=last object psize=obj pend
  647.         add     eax,40              ; goto next object in table (new)
  648.         mov     dword ptr [eax],'cgv.'      ; set object name to .vgc
  649.         mov     dword ptr [eax+objpsize],0  ; set psize to 0, updated later
  650.         mov     dword ptr [eax+objvsize],0  ; set vsize to 0, update later
  651.         mov     [eax+objrva],ecx        ; set rva of object
  652.         mov     [eax+objpoff],edx           ; set physical offset of obj
  653.         inc     word ptr [esi+numObj]       ; increment number of objects
  654.         jmp     after_apop
  655.        
  656. go_append:
  657.         popad
  658. after_apop:    
  659.         mov     objptr,eax                              ; objptr->last obj      
  660. found_hole:
  661.         mov     edi,objptr                              ; objptr->obj /w hole
  662.  
  663.     cmp     holeptr,0
  664.     jnz     go_pe_hdr_hole
  665.    
  666.         push    edi                                                                  
  667.         push    offset obj_txt                          ; strcat object name
  668.         call    lstrcat                         ; for display                
  669.                                                                                  
  670.         mov     eax,[edi+objpoff]                       ; get object physical off
  671.         mov     lastobjimageoff,eax                     ; save it                
  672.         mov     ecx,[edi+objpsize]                      ; get object physical size  
  673.         mov     originalpsize,ecx                       ; save it 4 later        
  674.                                                                                  
  675.         mov     eax,[edi+objvsize]                      ; get object virtual size
  676.         mov     originalvsize,eax                       ; save it                    
  677.         cmp     use_hole,1                                                      
  678.         jz      psize_less_vsize                                                
  679.         cmp     eax,ecx                                                          
  680.         jge     psize_less_vsize                        ; padded space for alignment?
  681.         mov     eax,ecx                                 ; set vsize to psize    
  682. psize_less_vsize:
  683.         add     eax,VIRTUAL_SIZE                        ; add our virtual size
  684.         mov     dword ptr [edi+objvsize],eax            ; save new virtual size
  685.        
  686.         cmp     use_hole,1                              ; if using hole then add virtual size
  687.         jz      in_hole_no_psize                                                        
  688.         mov     eax,originalpsize                       ; get physical size of object                                              
  689.         add     eax,DECRYPTOR_SIZE                      ; adjust physical size of object
  690.         mov     ecx,[esi+filealign]                                                      
  691.         call    align_fix                               ; on file alignment              
  692.         mov     [edi+objpsize],eax                                                              
  693.         ; now we must CORRECTLY calculate the new image size. This was the
  694.         ; bug under winNT appendation.    
  695.         mov     ecx,dword ptr [esi+objalign]            ; get object alignment
  696.         mov     eax,dword ptr [edi+objvsize]            ; add virtual size
  697.         add     eax,dword ptr [edi+objrva]              ; +last object rva
  698.         call    align_fix                              ; set on obj alignment
  699.         mov     dword ptr [esi+imagesize],eax           ; save new imagesize  
  700.            
  701.        
  702.         mov     eax,originalpsize
  703.         jmp     not_in_hole_psize_entry
  704. in_hole_no_psize:    
  705.    
  706.         mov     eax,originalvsize
  707. not_in_hole_psize_entry:
  708.  
  709.         mov     [edi+objflags],0E0000060h               ; set object flags r/w/x/init data
  710.         add     eax,[edi+objrva]                        ; add last object's RVA    
  711.                                                     ; eax now RVA of decryptor code
  712.     jmp     new_entry
  713. go_pe_hdr_hole:
  714.     mov     eax,holeptr
  715.     sub     eax,map_ptr
  716. new_entry:    
  717.         mov     ebx,[esi+entrypointRVA]                  ; get original entry        
  718.         mov     [esi+entrypointRVA],eax                  ; put our RVA as entry      
  719.         mov     newep,eax                                ; save it for decryptor too
  720.                                                                                              
  721.         mov     [host_eip],ebx                           ; save it                    
  722.        
  723.         push    esi
  724.        
  725.         ; CLOSED SOURCE
  726.                
  727.         mov     edi,map_ptr
  728.         cmp     holeptr,0
  729.         jz      not_hdr_hole
  730.         mov     edi,holeptr
  731.         jmp     copy_to_hdr
  732. not_hdr_hole:        
  733.         cmp     use_hole,1                               ; if in hole then install at end of vsize
  734.         jz      endvsize
  735.         add     edi,originalpsize                        ; add original physical size
  736.         jmp     go_copy
  737. endvsize:        
  738.         add     edi,originalvsize                        ; add original virtual size
  739. go_copy:    
  740.         add     edi,lastobjimageoff                      ; add object physical offset  
  741. copy_to_hdr:        
  742.         lea     esi,decryptor_code                       ; esi->decryptor code        
  743.         mov     ecx,DECRYPTOR_SIZE                                                    
  744.         rep     movsb                                                                  
  745.                                                                                        
  746.         pop     esi                                     ; restore ptr pe hdr              
  747.                                                                                        
  748.         cmp     use_hole,1                               ; did we find hole to install in?
  749.         jnz     go_pad_fixup_size                        ; if no then we better pad
  750.         mov     ecx,fsize                                ; else new filesize=old filesize  
  751.         jmp     go_fixup_size                                                          
  752.        
  753. go_pad_fixup_size:            
  754.         mov     ecx,[esi+filealign]                     ; calculate amt                        
  755.         sub     ecx,DECRYPTOR_SIZE                       ; of padding needed                    
  756.         xor     eax,eax                                                                    
  757.         rep     stosb                                    ; pad up object to alignment      
  758.                                                                                        
  759.         mov     eax,map_ptr                              ; eax->beginning of mapped file        
  760.         sub     edi,eax                                  ; get difference from current ptr      
  761.         mov     ecx,edi                                  ; save file size              
  762. go_fixup_size:    
  763.         push    ecx                                     ; ecx=real file size            
  764.                                                                                          
  765.         call    unmap                                   ; unmap file                    
  766.                                                                                          
  767.         pop     ecx                                                                      
  768.         push    FILE_BEGIN                              ; from file begin                
  769.         push    0                                       ; distance high                  
  770.         push    ecx                                     ; distance low                  
  771.         push    handle                                                                  
  772.         call    SetFilePointer                           ; move file pointer to      
  773.                                                  ; real EOF                          
  774.         push    handle                                                                  
  775.         call    SetEndOfFile                             ; set end of file            
  776. go_checksum:
  777. ;
  778. ; now we need to calculate checksum. We need to remap the file to get it
  779. ; right after file size change. I might be wrong about this, there could
  780. ; have been a bug in my code, but it seems resonable.<g>
  781. ;
  782.         xor     ecx,ecx
  783.         call    create_mapping
  784.         jc      unmapped
  785.         call    GetPEHeader
  786.         lea     eax,[esi+checksum]
  787.         push    eax                                   ; destination of checksum in hdr
  788.         push    offset oldchksum
  789.         push    fsize                                 ; new file size
  790.         mov     eax,map_ptr
  791.         push    eax
  792.         call    CheckSumMappedFile
  793.         call    unmap
  794.        
  795.         mov     error,0                                ; if we made it here then no error
  796.         jmp     unmapped                                
  797. abort_encrypt:
  798.         call    unmap                                  ;unmap if aborted infection
  799. unmapped:
  800.  
  801.         push    offset creation                                              
  802.         push    offset lastaccess                                            
  803.         push    offset lastwrite                                            
  804.         push    handle                                                      
  805.         call    SetFileTime                    ; restore orginal file time
  806.                                                                              
  807.         push    handle                                                      
  808.         call    CloseHandle                                                  
  809.        
  810.         mov     eax,oldattrib                          ; get original attribs
  811.         push    eax
  812.         mov     eax,fnameptr
  813.         push    eax                    
  814.         call    SetFileAttributesA                    ; restore the original attributes
  815.        
  816.         ret                                
  817. EncryptFile endp
  818. ;
  819. ; CLOSED SOURCE
  820. ;
  821. test_obj proc    
  822.         cmp     dword ptr [eax+objpoff],0       ; make sure physical offset isn't 0
  823.         jz      ret_stc
  824.         cmp     dword ptr [eax+objpsize],0      ; make sure physical size isn't 0
  825.         jz      ret_stc
  826.     call    test_rvas
  827.     jc      ret_stc
  828.         lea     esi,bad_otbl                     ; scan thru bad obj    
  829. bobj_loop:                                       ; table
  830.         xchg    eax,ebx
  831.         lodsd
  832.         xchg    eax,ebx
  833.         cmp     ebx,[eax]
  834.         jz      ret_stc                                                        
  835.         or      ebx,ebx
  836.         jnz     bobj_loop
  837.         clc
  838.         ret
  839. ret_stc:
  840.         stc    
  841.         ret
  842. test_obj endp    
  843.  
  844. test_rvas proc
  845.         pushad
  846.         mov     ecx,2        
  847.         lea     esi,importtbl        
  848. rva_loop:        
  849.     mov     edx,dword ptr [esi]        
  850.         mov     ebx,dword ptr [eax+objrva]        
  851.         cmp     ebx,edx
  852.         jg      not_bad
  853.         jz      ret_stc2
  854.         mov     ebx,dword ptr [eax+40+objrva]
  855.         or      ebx,ebx
  856.         jz  ret_stc
  857.         cmp     ebx,edx
  858.         jg      ret_stc2
  859. not_bad:        
  860.         add     esi,4
  861.     loop    rva_loop
  862.     popad
  863.         clc
  864.         ret
  865. ret_stc2:
  866.     popad
  867.     stc
  868.     ret                
  869. endp
  870.  
  871.  
  872. GetPEHeader proc
  873.         mov     esi,[eax+3Ch]                        ; where PE hdr pointer is
  874.         add     esi,eax                                                        
  875.         mov     ptrpeheader,esi                      ; esi->PE Hdr            
  876.         ret
  877. GetPEHeader endp
  878.  
  879. ; create_mapping - create file mapping of [handle]
  880. ; entry: ecx=+adjust mapping size
  881. ;
  882. create_mapping proc
  883.         push    ecx                                ; save additional mapping size  
  884.         push    0                                  ; high fsize storage, not needed
  885.         push    handle                             ; file handle                  
  886.         call    GetFileSize                                                          
  887.         call    test_error                                                            
  888.         jc      create_abort                                                          
  889.         mov     fsize,eax                                                            
  890.        
  891.         pop     ecx                     ; restore map size
  892.        
  893.         push    0              ; no map name
  894.         add     eax,ecx
  895.         push    eax            ; low size+vs  
  896.         push    0              ; high size  
  897.         push    PAGE_READWRITE ; read&write  
  898.         push    0                            
  899.         push    handle                      
  900.         call    CreateFileMappingA          
  901.         call    test_error                  
  902.         jc      create_abort
  903.         mov     maphandle,eax
  904.        
  905.         push    0               ; # of bytes, 0= map entire file
  906.         push    0               ; file offset low
  907.         push    0               ; file offset high            
  908.         push    FILE_MAP_WRITE  ; access flags - read&write      
  909.         push    eax             ; handle                          
  910.         call    MapViewOfFile                                    
  911.         call    test_error                                        
  912.         jc      create_abort
  913.         mov     map_ptr,eax
  914.  
  915. create_abort:
  916.         ret
  917. create_mapping endp
  918.  
  919.  
  920. ; test_error - test API for an error return
  921. ;  entry: eax=API return
  922. ;  returns: carry if error
  923. ;
  924. test_error proc
  925.         cmp     eax,-1
  926.         jz      api_err
  927.         or      eax,eax
  928.         jz      api_err
  929.         clc
  930.         ret
  931. api_err:
  932.         stc
  933.         ret
  934. test_error endp
  935.  
  936. ; unmap file - Unmap view of file
  937. ;
  938. unmap proc
  939.  
  940.         push    map_ptr          
  941.         call    UnmapViewOfFile  
  942.         push    maphandle        
  943.         call    CloseHandle      
  944.         ret
  945.  
  946. unmap endp
  947.  
  948. ; sets eax on alignment of ecx
  949. ;
  950. align_fix proc  
  951.         xor     edx,edx                                                                    
  952.         div     ecx                               ; /alignment                                  
  953.         or      edx,edx               ; if no remainder then no next
  954.         jz      no_adjust
  955.         inc     eax                               ; next alignment                                
  956. no_adjust:        
  957.         mul     ecx                               ; *alignment                            
  958.         ret
  959. align_fix endp    
  960.  
  961. OpenFile proc
  962.         push    0                                                
  963.         push    20h                          ; attribute normal  
  964.         push    3                          ; 3=open existing file
  965.         push    0                                                
  966.         push    0                                                
  967.         push    0c0000000h                 ; permissions        
  968.         push    esi                                              
  969.         call    CreateFileA                                      
  970.         ret
  971. OpenFile endp
  972.  
  973. ifdef console_app
  974. GetSHandle proc
  975.         push    -11
  976.         call    GetStdHandle
  977.         mov     [hstdo],eax            
  978.         push    -10
  979.         call    GetStdHandle
  980.         mov     [hstdi],eax
  981.         ret
  982. GetSHandle endp
  983.  
  984. WriteString proc
  985.         pushad
  986.         mov     edi,ebx
  987.         xor     eax,eax
  988.         mov     ecx,0fffh
  989.         cld
  990. sc_loop:        
  991.         scasb                                ; find end of string
  992.         jz      fnd
  993.         loop sc_loop
  994. fnd:    
  995.         mov     ecx,edi              
  996.         sub     ecx,ebx
  997.         push    0
  998.         push    offset byteswrote
  999.         push    ecx    
  1000.         push    ebx
  1001.         push    [hstdo]
  1002.         call    WriteConsoleA
  1003.         popad
  1004.         ret
  1005. WriteString endp
  1006.  
  1007.  
  1008. GetYN proc      
  1009.         pushad
  1010.         lea edi,ynbuf
  1011.         xor eax,eax
  1012.         stosb
  1013.         dec edi
  1014.         push 0
  1015.         push offset byteswrote
  1016.         push 1
  1017.         push edi
  1018.         push [hstdi]
  1019.         call ReadConsoleA
  1020.         popad
  1021.         cmp ynbuf,'y'
  1022.         jz exit_y
  1023.         cmp ynbuf,'Y'
  1024.         jz exit_y
  1025.         stc
  1026.         ret
  1027. exit_y:
  1028.         clc
  1029.         ret            
  1030. GetYN endp
  1031. endif
  1032.  
  1033.  
  1034.  
  1035. end start
  1036. ends
Advertisement
Add Comment
Please, Sign In to add comment