-
-
[旧帖] [求助][求助]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.
对话框接着程序就中断退出了,郁闷了好常时间了,什么办法都想了,就是不行,现献出源代码,希望有高手帮小弟分析分析!
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虚拟机自动化脱壳的方法
赞赏
看原图
赞赏
雪币:
留言: