//去掉最高位
function StripHighBit(L: Longint): DWORD;
begin
Result := L and IMAGE_OFFSET_STRIP_HIGH;
end;
begin
getmem(buffer,256);
int:=false;
ofn.lStructSize:=sizeof(openfilename);
ofn.nMaxFile:=512;
ofn.lpstrFile:=buffer;
ofn.lpstrFilter:='*.exe';
ofn.Flags:=OFN_FILEMUSTEXIST or OFN_HIDEREADONLY or OFN_EXPLORER;
GetOpenFileNameA(ofn);
CopyFile(buffer,'New.exe',false);
fhandle:=createfile(buffer,GENERIC_READ, FILE_SHARE_READ,nil,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);
hMapping:=CreateFileMapping(fhandle,NiL,PAGE_READONLY,0,0,0);
map:=mapviewoffile(hmapping,FILE_MAP_READ,0,0,0);
dos:=map;
if dos^.e_magic<>IMAGE_DOS_SIGNATURE then
messagebox(0,'错误的PE文件格式!','OK',0);
cardinal(nts):=cardinal(dos)+dos^._lfanew;
if nts^.Signature<>IMAGE_NT_SIGNATURE then
messagebox(0,'错误的PE文件格式!1','OK',0);
SEChea := PImageSectionHeader(NTS);
Inc(PImageNtHeaders(SEChea));
for I := 0 to NTS^.FileHeader.NumberOfSections - 1 do
begin
if Strlicomp(@SEChea^.Name, PChar('.rsrc'), IMAGE_SIZEOF_SHORT_NAME) = 0 then
begin
FResourceBase := PImageResourceDirectory(SEChea^.PointerToRawData + LongWord(Dos));
messagebox(0,pchar('OK FOUND FILES IS '+IntToHex(LongWord(@FResourceBase),8)),'OK',0);
break;
end;
Inc(SEChea);
continue;
end;
sourceBase:=PImageResourceDirectory(SEChea^.PointerToRawData + LongWord(Dos));
Entry:=PImageResourceDirectoryEntry(longWORD(sourceBase)+sizeof(TImageResourceDirectory));
te:=entry;
for J := 1 to FResourceBase^.NumberOfIdEntries+FResourceBase^.NumberOfNamedEntries do
BEGIN
if te^.Name = 3 THEN
BEGIN
iconEntry:=PIMAGERESOURCEDIRECTORYENTRY(LongWord(FResourceBase)+StripHighBit(te^.OffsetToData));//找到 Icon 的资源目录了!!!
BREAK;
end;
inc(te);
CONTINUE;
END;
tempDir:=PIMAGERESOURCEDIRECTORY(iconEntry);
tempEntry:=PIMAGERESOURCEDIRECTORYENTRY(LongWord(tempDir)+sizeof(TIMAGERESOURCEDIRECTORY));
for K := 0 to tempDir^.NumberOfIdEntries+tempDir^.NumberOfNamedEntries - 1 do
begin
if (StripHighBit(tempEntry.OffsetToData) >0) and(k=0) THEN
BEGIN
firstIconDir:=PIMAGERESOURCEDIRECTORY(LongWord(FResourceBase)+StripHighBit(tempEntry.OffsetToData));
firstIconEntry:=PIMAGERESOURCEDIRECTORYENTRY(LongWord(firstIconDir)+sizeof(TIMAGERESOURCEDIRECTORY));
firstIconData:= PIMAGERESOURCEDATAENTRY(LongWord(FResourceBase)+StripHighBit(firstIconEntry.OffsetToData));
end;
inc(entry);
END;
pFirstIcon:= firstIconData.OffsetToData - sechea.VirtualAddress + LongWord(FResourceBase);
writeln('file address : '+inttohex(pFirstIcon,8));
writeln('file rva address : '+inttohex(firstIconData.OffsetToData,8));
writeln('file size : '+inttohex(firstIconData.Size,8));
function IsValidIcon(P: Pointer; Size: Cardinal): Boolean;
var
ItemCount: Cardinal;
begin
Result := False;
if Size < Cardinal(SizeOf(Word) * 3) then
Exit;
if (PChar(P)[0] = 'M') and (PChar(P)[1] = 'Z') then
Exit;
ItemCount := PIcoHeader(P).ItemCount;
if Size < Cardinal((SizeOf(Word) * 3) + (ItemCount * SizeOf(TIcoItem))) then
Exit;
P := @PIcoHeader(P).Items;
while ItemCount > Cardinal(0) do begin
if (Cardinal(PIcoItem(P).Offset + PIcoItem(P).Header.ImageSize) < Cardinal(PIcoItem(P).Offset)) or
(Cardinal(PIcoItem(P).Offset + PIcoItem(P).Header.ImageSize) > Cardinal(Size)) then
Exit;
Inc(PIcoItem(P));
Dec(ItemCount);
end;
Result := True;
end;
var
H: THandle;
M: HMODULE;
R: HRSRC;
Res: HGLOBAL;
GroupIconDir, NewGroupIconDir: PGroupIconDir;
I: Integer;
wLanguage: Word;
F: TFile;
Ico: PIcoHeader;
N: Cardinal;
NewGroupIconDirSize: LongInt;
begin
if Win32Platform <> VER_PLATFORM_WIN32_NT then
Error('仅支持 Windows NT 和后期版本');
Ico := nil;
try
{ Load the icons }
F := TFile.Create(IcoFileName, fdOpenExisting, faRead, fsRead);
try
N := F.CappedSize;
if Cardinal(N) > Cardinal($100000) then { sanity check }
Error('图标文件太大');
GetMem(Ico, N);
F.ReadBuffer(Ico^, N);
finally
F.Free;
end;
{ Ensure the icon is valid }
if not IsValidIcon(Ico, N) then
Error('图标文件无效');
{ Update the resources }
H := BeginUpdateResource(PChar(FileName), False);
if H = 0 then
ErrorWithLastError('BeginUpdateResource 无效 (1)');
try
M := LoadLibraryEx(PChar(FileName), 0, LOAD_LIBRARY_AS_DATAFILE);
if M = 0 then
ErrorWithLastError('LoadLibraryEx 无效 (1)');
try
{ Load the 'MAINICON' group icon resource }
R := FindResource(M, 'MAINICON', RT_GROUP_ICON);
if R = 0 then
ErrorWithLastError('FindResource 无效 (1)');
Res := LoadResource(M, R);
if Res = 0 then
ErrorWithLastError('LoadResource 无效 (1)');
GroupIconDir := LockResource(Res);
if GroupIconDir = nil then
ErrorWithLastError('LockResource 无效 (1)');
{ Delete 'MAINICON' }
if not GetResourceLanguage(M, RT_GROUP_ICON, 'MAINICON', wLanguage) then
Error('GetResourceLanguage 无效 (1)');
if not UpdateResource(H, RT_GROUP_ICON, 'MAINICON', wLanguage, nil, 0) then
ErrorWithLastError('UpdateResource 无效 (1)');
{ Delete the RT_ICON icon resources that belonged to 'MAINICON' }
for I := 0 to GroupIconDir.ItemCount-1 do begin
if not GetResourceLanguage(M, RT_ICON, MakeIntResource(GroupIconDir.Items[I].Id), wLanguage) then
Error('GetResourceLanguage 无效 (2)');
if not UpdateResource(H, RT_ICON, MakeIntResource(GroupIconDir.Items[I].Id), wLanguage, nil, 0) then
ErrorWithLastError('UpdateResource 无效 (2)');
end;
{ Build the new group icon resource }
NewGroupIconDirSize := 3*SizeOf(Word)+Ico.ItemCount*SizeOf(TGroupIconDirItem);
GetMem(NewGroupIconDir, NewGroupIconDirSize);
try
{ Build the new group icon resource }
NewGroupIconDir.Reserved := GroupIconDir.Reserved;
NewGroupIconDir.Typ := GroupIconDir.Typ;
NewGroupIconDir.ItemCount := Ico.ItemCount;
for I := 0 to NewGroupIconDir.ItemCount-1 do begin
NewGroupIconDir.Items[I].Header := Ico.Items[I].Header;
NewGroupIconDir.Items[I].Id := I+1; //assumes that there aren't any icons left
end;
{ Update 'MAINICON' }
for I := 0 to NewGroupIconDir.ItemCount-1 do
if not UpdateResource(H, RT_ICON, MakeIntResource(NewGroupIconDir.Items[I].Id), 2052, Pointer(DWORD(Ico) + Ico.Items[I].Offset), Ico.Items[I].Header.ImageSize) then
ErrorWithLastError('UpdateResource 无效 (3)');
{ Update the icons }
if not UpdateResource(H, RT_GROUP_ICON, 'MAINICON', 2052, NewGroupIconDir, NewGroupIconDirSize) then
ErrorWithLastError('UpdateResource 无效 (4)');
finally
FreeMem(NewGroupIconDir);
end;
finally
FreeLibrary(M);
end;
except
EndUpdateResource(H, True); { discard changes }
raise;
end;
if not EndUpdateResource(H, False) then
ErrorWithLastError('EndUpdateResource 无效');
finally
FreeMem(Ico);
end;
end;