BPE32 多态引擎剖析.docx
- 文档编号:15957851
- 上传时间:2023-07-09
- 格式:DOCX
- 页数:30
- 大小:26.05KB
BPE32 多态引擎剖析.docx
《BPE32 多态引擎剖析.docx》由会员分享,可在线阅读,更多相关《BPE32 多态引擎剖析.docx(30页珍藏版)》请在冰点文库上搜索。
BPE32多态引擎剖析
BPE32多态引擎剖析
创建时间:
2008-11-11
文章属性:
原创
文章提交:
nEINEI(neineit_at_)
BPE32多态引擎剖析
autor:
nEINEI
e-mail:
neineit@
date:
2008-11-10
一BPE32简介
二技术细节分析
2.0--整体流程设计
2.1--随机数设计
2.2--代码加密方案
2.3--对抗VM的SEH设计
2.4--随机数生成与寄存器选择
2.5--垃圾指令生成方式
2.6--解密器设计
2.7--重建指令流程
三代码解析
四检测方案
一BPE32简介:
BPE32(Benny'sPolymorphicEngineforWin32)多态引擎是由Benny's/29A在#4期发布的一个病毒多态引擎,之后在病毒编写如(如Win32.Vulcano)及壳的编写(如ASProtect)当中都得到了应用,BPE32是一个很不错的多态引擎,这里将从设计的角度分析该引擎。
按照Benny's的描述,BPE32引擎有如下特点:
1可以通过创建SHE来干扰一些AV
2随机使用寄存器做代码的混淆
3同一功能代码,由不同的指令动态生成
4功能代码具有空间随机分布
5具有仿真CALL及jmp指令
6在代码之间插入垃圾指令(也包括使用未公开的SALC指令)
我们先看一下BPE32的调用时的输入参数,
ESI --指向待加密的virus数据。
EDI --指向一块内存数据,用来存放由BPE32生成的解密器及加密数据。
ECX --加解密数据的计数,加解密时按照4byte的方式操作,数据由公式(_end-start+3)/4获得。
EBP --做重定位时使用。
输出参数,
EAX --解码器加上加密数据后的大小,不对齐,精确到1byte而不是一个DWORD
调用很方式简单,例如:
movesi,vir_body;病毒体
movedi,pmem ;内存空间
movecx,6c0h ;解密计数
callBPE32
这样调用后pmem里面就是一个重建的病毒代码了。
下面将对具体技术细节做分析。
二技术细节分析
2.0流程设计:
调用BPE32后,将在内存中产生如下方式的3部分功能代码,结构如下:
/------- +--------------------+
| | call decryptor| --------->@1
| +--------------------+
| | |
| |encryptvirusbody | --------->@2
| | |
\------>|--------------------+
| |
| decryptor |
| | --------->@3
+--------------------+
@1是经过计算构造好的一个call调用,因为调用的具体位置要有@2部分决定。
@2是一个经过加密后的病毒体。
@3是一个解密器,用于对@2部分进行解密,该部分是经过代码混淆变换的。
这样每次感染其它文件后,重新生成的代码将不再有固定的特征部分,这将使得特征扫描机制失效。
2.1随机数设计:
BPE32的随机数部分设计的很简单,利用了RDTCS指令来产生一个随机数字,通过栈中参数X,产生一个0~X-1之间的数字,当参数是0时,则直接返回产生的该数字。
random proc
pushedx
RDTCS
xoredx,edx ;nulifyEDX,weneedonlyEAX
cmp[esp+8],edx ;isparameter==0?
jer_out ;yeah,donottruncateresult
divdwordptr[esp+8] ;divideit
xchgeax,edx ;remainderasresult
r_out:
popedx ;restoreEDX
retPshd ;quitprocedureanddestroypushedparameter
random endp
2.2代码加密方案:
BPE32采用的加密方案是,先产生两个随机数,一个作为密钥B_key(不变的数字),一个作为增量密钥I_key(每次运算后相加),每次使得B_key+I_key,然后xor待加密数据一个DWORD,实现如下:
push0 ;产生一个无索引范围的随机数
callrandom
xchgedx,eax
mov[ebp+xor_key-mgdelta],edx ;存储基密钥
push0 ;产生一个无索引范围的随机数
callrandom
xchgebx,eax
mov[ebp+key_inc-mgdelta],ebx ;存储增量密钥
x_loop:
lodsd ;加密virusbody
xoreax,edx
stosd
addedx,ebx
loopx_loop
2.3对抗VM的SEH设计:
对于上面小节中提到的@3部分,其实是由如下部分组成的,decryptor如下图:
+------------------+<--------\
| sehhandler | |
+------------------+ |
| deletageter | |
+------------------+ |
| decryption | |
+------------------+ |
| loopdecryptor |---------/
+------------------+
sehhandler --安装一个seh处理过程。
deletageter --因为@3部分是由垃圾指令随机填充的,所以每循环一次后需要进行一次重定位。
decryption --解密部分,同样由垃圾指令所包围。
loopdecryptor--跳向sehhandler。
对于SEHBPE32会产生如下形式的代码:
start:
callend_seh_fn
/---->movesp,[esp+8] ;-->相当于push seh->handler
| jmpseh_rs
| end_seh_fn:
| subedx,edx
| pushdwordptrfs:
[edx];-->相当于push seh->prev
| movfs:
[edx],esp
\-----incbyteptr[edx] ;-->该处引发异常,跳向上面语句
jmpstart
seh_rs:
xoredi,edi
popdwordptrfs:
[edi]
popedi
这样对于使用vm技术的aver,如果没有做好seh仿真,将导致仿真失败,无法完成检测,而jmpstart这条语句也很重要,有些aver会实现指令预取的功能(具体可参考《对抗启发式代码仿真检测技术分析》一文),这样会另aver陷入无休止的仿真循环当中。
2.4随机数生成与寄存器选择
BPE32通过get_reg函数产生一个随机的寄存器索引,即产生0~7之间的整数,不使用EAX(0),ESP(100b),在调用的外部也会判断是否使用了的EBP(101b),实现如下:
get_regproc
push8 ;产生一个随机的0~7之间的整数
callrandom
testeax,eax
jeget_reg ;不能使用eax
cmpal,100b;不能使用esp
jeget_reg
ret
get_regendp
2.5垃圾指令生成方式:
BPE32通过调用rjunk函数来产生垃圾指令,这部分可以产生1byte,2byte,3byte,5byte垃圾指令,及jmpcall类的仿真指令(无疑这类指令的加入使得junk看起来更像真实的指令),同时为了使junk的产生更加随机化,BPE32做了一个简单映射关系。
0=5,1=1+2,2=2+1,3=1,4=2,5=3,6=none,7=dummyjumpandcall
左侧索引(eax,随机数)=右侧(垃圾指令字节数),也就是rjunk先产生一个0~7的随机数,根据这个索引映射的列表,进行垃圾指令的生成,例如:
eax是0时,产生5bytejunk
eax是1时,产生1bytejunk和2bytejunk
eax是2时,则先产生2bytejunk,再产生1bytejunk
eax是7时,产生jmp或call
按照以上的映射关系,依次类推的产生垃圾指令,下面以1bytejunk的代码来说如何产生垃圾代码。
1bytejunk示例:
esi-->待加密数据
edi-->内存buff
产生1bytejunk指令到内存buff
j1:
calljunx1 ;onebytejunkinstruction
nop
deceax
SALC
inceax
clc
cwde
stc
cld
junx1:
popesi ;1bytejunk指令首地址,即指向nop指令
push8
callrandom
addesi,eax ;随机定位一条
movsb ;加入edi指向的内存当中
ret
其它的junk产生方式仅比1bytejunk复杂一些而已,故不再赘述,BPE32还有一个重要的功能指令产生函数,make_xor,make_xor2,make_xor主要是将指定的寄存器(由bl寄存器中的内容指定)清0,make_xor可以产生随机的,xor,Rx,Rx/subRx,Rx/movRx,0这样的等效指令,make_xor2则产生一个指定寄存器xor某一数值的指令,例如:
movbh,2
callmake_xor2
moveax,01234567h
stosd
以上则产生一条xoredx,01234567h这样的指令,以上两个函数功能简单,故不再做过多说明。
2.6解密器设计
因为BPE32可以随机的使用寄存器,故这里用Rx来表示任意一个可用的寄存器,每条语句的Rx并不一定代表同一个寄存器。
解密器的设计是BPE32多态的重点,我这里先将主要的功能代码表示出来。
mov Rx,src -------- I1 获得待解密的地址,放入Rx中
mov Rx,cnt -------- I2 获得要解密的此时,放入Rx中
/--->xor Rx,Rx -------- I3 解密
| add Rx,4 -------- I4 待解密的地址加4
| add Rx,1 -------- I5 计数器加1
| add Rx,Rx -------- I6 基密钥+增量密钥
| jcxzxxx -------- I7 测试解密是否完成,完成后跳出循环
\---jmp xxx -------- I8 继续解密
BPE32围绕I1~I8,通过随机寄存器、插入垃圾指令、变换指令顺序、同等指令替换等手段产生来产生数据不同但功能相同的解密代码,下面我将列举一个去除垃圾指令的BPE32产生的解密代码。
0040202B E800000000 CALLT-BPE32.00402030 ;构造的一个call
00402030 8B3C24 MOVEDI,DWORDPTRSS:
[ESP]
00402033 58 POPEAX
00402034 81EF30204000 SUBEDI,T-BPE32.00402030 ;构造一个重定位
;I1的一种生成方式,F7973BCB为随机产生的一个密钥,xor后,ecx指向了最初call调用后地址,即待解密数据首地址
0040203A 68CB3B97F7 PUSHF7973BCB;构造一个随机加密的密钥使得ecx指向最初的一个call调用
0040203F 59 POPECX ;这里ecx寄存器随机生成
00402040 81F1CE1BD7F7 XORECX,F7D71BCE
00402046 03CF ADDECX,EDI ;加重定位,获得真正数据的指向
;I2的一种生成方式,方案类似于I1
00402048 33D2 XOREDX,EDX ;获得解密的次数,同样采用随机密钥来混淆
0040204A 81C268D4F805 ADDEDX,5F8D468
00402050 81F26AD4F805 XOREDX,5F8D46A
;I3
00402056 2BDB SUBEBX,EBX ;获得密钥,该处密钥均为0
00402058 81C300000000 ADDEBX,0
0040205E 3119 XORDWORDPTRDS:
[ECX],EBX ;解密
;I4使计数增加的一种方式
00402060 41 INCECX ;源数据增加4
00402061 41 INCECX
00402062 41 INCECX
00402063 41 INCECX
;I5
00402064 B8CC54578A MOVEAX,8A5754CC ;循环计数减1
00402069 2BD0 SUBEDX,EAX
0040206B 81C2CB54578A ADDEDX,8A5754CB
;I6
00402071 B800000000 MOVEAX,0 ;基址密钥+增量密钥加(目前增量是0)
00402076 03D8 ADDEBX,EAX
;I7
00402078 51 PUSHECX
00402079 8BCA MOVECX,EDX
/-0040207B E303 JECXZSHORTT-BPE32.00402080 ;测试看解密是否完成
| ;I8
|0040207D 59 POPECX
|0040207E ^EBDE JMPSHORTT-BPE32.0040205E ;继续进行解密
\-->00402080 59 POPECX
00402081 61 POPAD
00402082 C3 RETN2.7重建指令流程
针对解密器,BPE32对执行先后顺序无关的代码,进行了重新排列,首先BPE32现将这些功能分成8个部分,即greg0~greg7个处理例程。
其中:
greg0 --产生SEH部分代码
greg1 --产生SEH部分代码
greg2 --产生movRx,src类代码
greg3 --产生movRx,cnt类代码
以上部分例程不进行代码重排序。
greg4 -- 产生密钥自增代码
greg5 --产生待解密数据自增代码
greg6 --产生计数器自减的代码
greg7 --产生解密跳转的代码
BPE32会对greg4~greg6进行重排序,因这几部分代码进行重排序,不会影响解密代码功能,以此来达到代码混淆的目的。
同时这几部分功能都有能力产生,功能一致但代码不同的新指令如:
greg4提供4种等效方案,供随机选择
1:
XCHGEAX,Rx
XORRx,Rx
ORRx,EAX
ADDRx,value
2:
addRx,value
3:
moveax,value
addRx,eax
4:
moveax,Rx
addeax,value
xchgeax,Rx
greg5提供多种等效方案,供随机选择,如
1:
incRx ;执行4次
2:
3:
moveax,Rx, moveax,4
addeax,4 addRx,eax
xchgeax,Rx
greg6提供了4种等效方案,供随机选择
1:
subRx,1
2:
decRx,1
3:
moveax,random_v
subRx,eax
addreg,random-1
4:
xchgeax,Rx
deceax
xchgeax,Rx
greg7提供了两种等效方案,供随机选择
1:
pushecx
movecx,reg
jecxzlabel
popecx
jmpdecrypt_loop
label:
popecx
2:
xoreax,eax
deceax
addeax,reg
jnsdecrypt_loop
而整体greg4~greg6的排序规则由如下代码产生:
push6 ;产生0~5种方案的随机排列顺序
callrandom
testeax,eax
jeg5 ;greg4-keyincremention
cmpal,1 ;greg5-sourceincremention
jeg1 ;greg6-countdecremention
cmpal,2 ;greg7-decryptionloop
jeg2
cmpal,3
jeg3
cmpal,4
jeg4
g0:
callgg1
callgreg6
jmpg_end
g1:
callgg2
callgreg5
jmpg_end
g2:
callgreg5
callgg2
jmpg_end
g3:
callgreg5
gg3:
callgreg6
jmpg_out
g4:
callgreg6
callgg1
jmpg_end
g5:
callgreg6
callgreg5
g_out:
callgreg4
g_end:
callgreg7
moval,61h
stosb
callrjunk
moval,0c3h
stosb
popeax
subeax,edi
negeax
mov[esp.Pushad_eax],eax
popad
ret ;整个BPE32结束
三代码解析
下面将对BPE32关键处的代码做简要的注释;
RDTCS equ
SALC equ
BPE32 Proc
pushad ;saveallregs
pushedi ;savetheseregsforl8ruse
pushecx ; ...
movedx,edi ;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- BPE32 多态引擎剖析 引擎 剖析