function DetectPE32Overlay(
out Offset, Size: DWORD): Boolean;
type
PImageSectionHeaders = ^TImageSectionHeaders;
TImageSectionHeaders =
array [Word]
of TImageSectionHeader;
var
Hand: THandle;
Read: DWORD;
DosHdr: TImageDosHeader;
NtHdrs: TImageNtHeaders;
SecHdr: PImageSectionHeaders;
SecIdx: Word;
begin
Result := False;
// Datei zum Lesen oeffnen...
Hand := CreateFile(PChar(ParamStr(0)), GENERIC_READ, FILE_SHARE_READ,
nil, OPEN_EXISTING, 0, 0);
if (Hand <> INVALID_HANDLE_VALUE)
then
try
// MS-DOS Datei-Header einlesen um den Offset des PE32-Headers zu erhalten
// (unter einigen OS nicht zwingend; aber in fast allen Faellen vorhanden)
if not ReadFile(Hand, DosHdr, SizeOf(TImageDosHeader),
Read,
nil)
or
(
Read <> SizeOf(TImageDosHeader))
or
(DosHdr.e_magic <> IMAGE_DOS_SIGNATURE)
then
DosHdr._lfanew := 0;
// PE32-Header einlesen (inklusive 'optionalem' Header)
if (SetFilePointer(Hand, DosHdr._lfanew,
nil, FILE_BEGIN) <> DWORD(-1))
and
(ReadFile(Hand, NtHdrs, SizeOf(TImageNtHeaders),
Read,
nil)
and
(
Read = SizeOf(TImageNtHeaders)))
and
(NtHdrs.Signature = IMAGE_NT_SIGNATURE)
then
// 'Optionalen' Header pruefen
with NtHdrs, FileHeader, OptionalHeader
do
if (SizeOfOptionalHeader >= IMAGE_SIZEOF_NT_OPTIONAL_HEADER)
and
(OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC)
then
begin
// Sektionen durchlaufen und letzte merken
SecHdr := GetMemory(NumberOfSections * SizeOf(TImageSectionHeader));
if (SecHdr <>
nil)
then
try
if (SetFilePointer(Hand,
SizeOfOptionalHeader - IMAGE_SIZEOF_NT_OPTIONAL_HEADER,
nil, FILE_CURRENT) <> DWORD(-1))
and
ReadFile(Hand, SecHdr^,
NumberOfSections * SizeOf(TImageSectionHeader),
Read,
nil)
and
(
Read = NumberOfSections * SizeOf(TImageSectionHeader))
then
begin
Offset := 0;
for SecIdx := 0
to NumberOfSections - 1
do
with SecHdr[SecIdx]
do
if ((PointerToRawData + SizeOfRawData) > Offset)
then
Offset := (PointerToRawData + SizeOfRawData);
Size := GetFileSize(Hand,
nil) - Offset;
Result := True;
end;
finally
FreeMemory(SecHdr);
end;
end;
finally
CloseHandle(Hand);
end;
end;