首页
社区
课程
招聘
[旧帖] [求助][求助]PE结构的ICON导出问题 0.00雪花
发表于: 2008-9-10 22:16 3034

[旧帖] [求助][求助]PE结构的ICON导出问题 0.00雪花

2008-9-10 22:16
3034
我写了一个程序,目的是为了导出PE文件里面所有的icon文件,但是遇到了一个很奇怪的问题,当导出图标的时候,会出现
对话框接着程序就中断退出了,郁闷了好常时间了,什么办法都想了,就是不行,现献出源代码,希望有高手帮小弟分析分析!
program a;
{$APPTYPE CONSOLE}
uses
  SysUtils,
  Windows,
  TlHelp32,
  CommDlg,
  UPEConst,
  Classes,
  graphics,
  shellapi;

var
lian:array of link;
i,bb:word;
xxx,ddd:array of byte;
resname:PImageResourceDirStringU;
int:boolean;
FResourceBase,iconroot:PImageResourceDirectory ;
te,entry:PImageResourceDirectoryEntry;
iconEntry,iconEntry1,iconEntry2:PImageResourceDirectoryEntry;
iconDir:PImageResourceDirectory;
bit:word;
SEChea:PImageSectionHeader;
fhandle:LongWord;
DOS:PImageDosHeader;
 nts:PImageNtHeaders;
 buffer:pchar;
j:integer;
ofn:openfilename;
hMapping:thandle;
map:pointer;

//去掉最高位
function StripHighBit(L: Longint): DWORD;
begin
  Result := L and IMAGE_OFFSET_STRIP_HIGH;
end;

function CREATEICON(lian:link):boolean;
var
fill:array [0..$16-1] of byte;
r,w:tfilestream;
by:word;
wish:array of byte ;
begin

w:=tfilestream.Create(lian.filename,fmcreate);
r:=tfilestream.Create('1.exe',fmopenreadwrite);
if (w.Handle=0) and (r.Handle=0) then
begin
result:=false;
exit;
end;
//*****************************I C O N头部结构*********************************
{(一、文件头6字节)
000(000)2    保留的字节            00 00
002(002)2    资源类型             01 00 (01为图标,02为光标)
004(004)2    图象个数             01 00
 (二、图像信息块16字节)
006(006)1    图标宽度             10
007(007)1    图标高度             10
008(008)1    颜色计数             10(02=单色, 00≥256色)
009(009)1    未用                00
010(00A)4    保留的              00 00 00 00
014(00E)4    图象数据块的长度                28 01 00 00(10进制=296)
018(012)4    图象数据块相对于文件头部的偏移量 16 00 00 00(10进制=22)
}

try
//FillChar(xxx,lian.size, #0);
//FillChar(fill,Sizeof(ticonheader), #0);
 r.Seek(lian.offset+4,0);
r.Read(by,2);
// backup icon file to 123 ico !
fill[0]:=$0;fill[1]:=$0; fill[2]:=$01;fill[3]:=$0;fill[4]:=$01;fill[5]:=$00;
if by=2 then
by:=$20 else
by:=$10;
fill[6]:=by;fill[7]:=by;fill[8]:=$10;fill[9]:=$0;fill[10]:=$0;fill[11]:=$0;
fill[12]:=$0;fill[13]:=$0;
pointer(wish):=@lian.size;
fill[14]:=wish[0];
fill[15]:=wish[1];
fill[16]:=wish[2];fill[17]:=wish[3];
fill[18]:=$16;fill[19]:=$0;fill[20]:=$0;fill[21]:=$0;

w.Seek(0,0);
w.Write(fill,sizeof(ticonheader)-2);
if 0=lian.offset then
exit;
writeln('file offset:『'+inttohex(lian.offset,8)+'』');
r.Seek(lian.offset,0);
r.Read(xxx,lian.size);
w.Seek(22,0);
w.Write(xxx,lian.size);
finally
r.Free;
w.Free;
end;
result:=true;
end;

procedure view(lian:link);
begin
writeln(lian.filename);
writeln('.............');
write('file size:『'+inttohex(lian.size,8)+'』,');
writeln('file offset:『'+inttohex(lian.offset,8)+'』');
end;

function kernelproc(num:integer;iconentrys:dword):boolean;stdcall;
var
i:integer;
firstIconData: PImageResourceDataEntry;
icentry:PImageResourceDirectoryEntry;
begin
 pointer(lian):=allocmem((iconroot.NumberOfIdEntries+iconroot.NumberOfNamedEntries)*sizeof(link));
//getmem(pointer(lian),num*sizeof(link)+1);
for  i := 0 to  num- 1 do
begin

//FillChar(lian,$60, #0);
icentry:=PImageResourceDirectoryEntry(longWORD(iconDIR)+sizeof(TImageResourceDirectory)+$18*I);
//recor:=cardinal(iconentry1);

firsticondata:=PImageResourceDataEntry(cardinal(FResourceBase)+icentry.offsettodata);
//RVA转换为物理地址
lian[i].offset:=firstIconData.OffsetToData - sechea.VirtualAddress+SEChea^.PointerToRawData;

lian[i].size:=firsticondata.Size;
lian[i].filename:=inttohex(i,5)+'.ico';
view(lian[i]);

end;

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,'1.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,'错误的NT文件格式!','OK',0);

SEChea := PImageSectionHeader(NTS);
Inc(PImageNtHeaders(SEChea));
 for j := 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));
   break;
    end;
    Inc(SEChea);
    continue;
  end;
Entry:=PImageResourceDirectoryEntry(longWORD(fresourceBase)+sizeof(TImageResourceDirectory));
te:=entry;

for J := 1 to FResourceBase^.NumberOfIdEntries+FResourceBase^.NumberOfNamedEntries  do
 BEGIN
if te^.Name = 3  THEN
 BEGIN
iconroot:=PImageResourceDirectory(LongWord(FResourceBase)+StripHighBit(te^.OffsetToData));//找到 Icon 的资源目录了!!!
BREAK;
  end;
  inc(te);
  CONTINUE;
END;
iconentry:=PImageResourceDirectoryEntry(longWORD(iconroot)+sizeof(TImageResourceDirectory));
ICONDIR:=PImageResourceDirectory(LongWord(FResourceBase)+StripHighBit(iconEntry.OffsetToData));
//i:=0;
writeln(inttohex(iconroot.NumberOfIdEntries+iconroot.NumberOfNamedEntries,8));
iconentry1:=PImageResourceDirectoryEntry(longWORD(iconDIR)+sizeof(TImageResourceDirectory)-$18);
kernelproc(iconroot.NumberOfIdEntries+iconroot.NumberOfNamedEntries,dword(iconentry1));
for I := 1 to iconroot.NumberOfIdEntries+iconroot.NumberOfNamedEntries do
begin
writeln(inttohex(i,4));
if createicon(lian[i])=false then
exit;
sleep($50);
end;
end.
    

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//