function TkzFileInfoExecutable.GetCustom: TExecutable;
var
FS: TStream;
Len: Int64;
dwSig: DWORD;
wSig: Word;
bSig: Byte;
i: Integer;
s:
string;
begin
SetLastError(ERROR_SUCCESS);
Result.HasMain := False;
fHasInfo := Result.HasMain;
if (
not fCreated)
then
Exit;
with fMain
do
begin
Is64Bit := kzFileInfo.CodeBase.Is64Bit(fFileName);
try
Len := 0;
FS := TFileStream.Create(fFileName, fmOpenRead
or fmShareDenyNone);
try
try
FS.
Read(HeaderDos, SizeOf(IMAGE_DOS_HEADER));
if ((HeaderDos.e_magic = IMAGE_DOS_SIGNATURE)
or (HeaderDos.e_magic = IMAGE_DOSSTUB_SIGNATURE)
or (HeaderDos.e_magic = IMAGE_OS2_SIGNATURE))
then
begin
try
PHeaderDos := @HeaderDos;
HasHeaderDos := (PHeaderDos <>
nil);
HasMain := HasHeaderDos;
FS.Seek(HeaderDos._lfanew, soFromBeginning);
FS.
Read(wSig, SizeOf(wSig));
FS.Seek(HeaderDos._lfanew, soFromBeginning);
FS.
Read(dwSig, SizeOf(dwSig));
case HeaderDos.e_magic
of
IMAGE_DOS_SIGNATURE: HeaderSignature := Format('
MZ [' + rsHexAndNumber + '
]', [HeaderDos.e_magic, HeaderDos.e_magic], fFormatSettings);
IMAGE_DOSSTUB_SIGNATURE: HeaderSignature := Format('
ZM (calling dos stub) [' + rsHexAndNumber + '
]', [HeaderDos.e_magic, HeaderDos.e_magic], fFormatSettings);
IMAGE_OS2_SIGNATURE: HeaderSignature := Format('
NE (calling dos stub with segment registers DS=CS) [' + rsHexAndNumber + '
]', [HeaderDos.e_magic, HeaderDos.e_magic], fFormatSettings);
end;
except
end;
try
case wSig
of
IMAGE_OS2_SIGNATURE:
begin
FS.Seek(HeaderDos._lfanew, soFromBeginning);
HeaderSignature := Format('
NE [' + rsHexAndNumber + '
]', [wSig, wSig], fFormatSettings);
FS.
Read(HeaderNE, SizeOf(IMAGE_NE_HEADER));
PHeaderNE := @HeaderNE;
HasHeaderNE := (PHeaderNE <>
nil);
// messagebox(0, pchar(inttostr(fs.position)), pchar(inttostr(fs.position)), mb_ok);
end;
IMAGE_VXD_SIGNATURE:
begin
HeaderSignature := Format('
LE [' + rsHexAndNumber + '
]', [wSig, wSig], fFormatSettings);
end;
IMAGE_NT_SIGNATURE:
begin
HeaderSignature := Format('
PE [' + rsHexAndNumber + '
]', [wSig, wSig], fFormatSettings);
FS.
Read(HeaderFile, SizeOf(IMAGE_FILE_HEADER));
PHeaderFile := @HeaderFile;
HasHeaderFile := (PHeaderFile <>
nil);
end;
else
HeaderSignature := Format('
Unknown Signature: ' + rsHexAndNumber, [dwSig, dwSig], fFormatSettings);
end;
Len := FS.Position;
except
end;
if HasHeaderFile
then
begin
if (HeaderFile.SizeOfOptionalHeader > 0)
then
begin
i := FS.Position;
FS.
Read(wSig, SizeOf(wSig));
Is64Bit := (wSig = IMAGE_NT_OPTIONAL_HDR64_MAGIC);
HeaderMagicPEw := wSig;
FS.Seek(i, soFromBeginning);
FS.
Read(dwSig, SizeOf(dwSig));
HeaderMagicPEdw := dwSig;
FS.Seek(i, soFromBeginning);
if Is64Bit
then
begin
try
FS.
Read(HeaderOptional64, SizeOf(IMAGE_OPTIONAL_HEADER64));
PHeaderOptional64 := @HeaderOptional64;
HasHeaderOptional := (PHeaderOptional64 <>
nil);
IsROM := (HeaderOptional64.Magic = IMAGE_ROM_OPTIONAL_HDR_MAGIC);
except
end;
end
else
begin
try
FS.
Read(HeaderOptional32, SizeOf(IMAGE_OPTIONAL_HEADER32));
PHeaderOptional32 := @HeaderOptional32;
HasHeaderOptional := (PHeaderOptional32 <>
nil);
IsROM := (HeaderOptional32.Magic = IMAGE_ROM_OPTIONAL_HDR_MAGIC);
except
end;
end;
if IsROM
then
begin
try
FS.Seek(Len, soFromBeginning);
FS.
Read(HeaderROM, SizeOf(IMAGE_ROM_OPTIONAL_HEADER));
PHeaderROM := @HeaderROM;
HasHeaderROM := (PHeaderROM <>
nil);
except
end;
end;
end;
{ fill array with sections and compute filesize by header data }
if (HeaderFile.NumberOfSections > 0)
then
begin
try
FileSizeHeader := 0;
SetLength(HeaderSection, HeaderFile.NumberOfSections);
SetLength(PHeaderSection, HeaderFile.NumberOfSections);
for i := 1
to HeaderFile.NumberOfSections
do
begin
FS.
Read(HeaderSection[i - 1], SizeOf(IMAGE_SECTION_HEADER));
PHeaderSection[i - 1] := @HeaderSection[i - 1];
with PHeaderSection[i - 1]^
do
// if ((PointerToRawData + SizeOfRawData > fFileSizeFromHeader) and (PointerToRawData + SizeOfRawData <= fFileSize)) then
if (PointerToRawData + SizeOfRawData > FileSizeHeader)
then
FileSizeHeader := PointerToRawData + SizeOfRawData;
end;
HasHeaderSection := (Length(HeaderSection) > 0);
except
end;
end;
end;
{ extract NE specific description }
if HasHeaderNE
then
begin
try
FS.Seek(HeaderNE.NonresidentNameTableOffset, soFromBeginning);
FS.
Read(bSig, SizeOf(bSig));
Len := bSig;
s := '
';
for i := 0
to Len
do
begin
FS.
Read(bSig, SizeOf(bSig));
s := s + Char(bSig);
end;
DescriptionNE := Trim(s);
except
end;
end;
end;
except
end;
finally
FS.Free;
end;
except
end;
BinaryType := GetBinType(fFileName);
ImageCheckSum := GetImageCheckSum(fFileName);
fHasInfo := HasMain;
if (HasHeaderDos)
then
DumpDos := DumpHeaderDos;
if (HasHeaderFile)
then
DumpFile := DumpHeaderFile;
if (HasHeaderOptional)
then
DumpOptional := DumpHeaderOptional;
if (HasHeaderRom)
then
DumpRom := DumpHeaderRom;
if (HasHeaderNE)
then
DumpNE := DumpHeaderNE;
if (HasHeaderDos)
then
Entropy := GetEntropy;
end;
Result := fMain;
end;