Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Определить тип приложения [D7, Win95/98, WinME, NT4, Win2k, WinXP]


Страницы:   1 2 3 4

-=GaLaN=- ©   (2005-05-27 01:03:00) 

У меня есть путь к файлу exe. Как можно определить тип приложения - консольное ли оно, DOS, Win32?


Digitman   (2005-06-06 08:16:00) [1]


> пытаюсь открыть с помощью других программ


каких ?


Оля   (2005-06-06 02:26:00) [2]

Удалено модератором


Defunct   (2005-05-27 15:53:00) [3]

-=GaLaN=-   (27.05.05 15:30) [73]

Вам забесплатно дали функцию [60] и описание констант и структур данных к ней - [61].

Остальные модули Игорь не считает нужным выкладывать на всеобщее обозрение, их там требуется ни много, ни мало все с тэгом HS. На то есть его право.


Defunct   (2005-05-27 15:47:00) [4]

wal ©   (27.05.05 14:03) [68]

ну и что с того?
По расширению (COM/EXE) определяется, что надо запустить загрузчик PE файла.
Далее,
Загрузчик открыл файл, нашел там 'MZ' и начал подготавливать этот файл к запуску как EXE (а не как ком, хоть файл и с расширением COM).

Вот лучше проведите другой эксперимент, частично затрите заголовок EXE файла и попробуйте его запустить.


Игорь Шевченко   (2005-05-27 15:47:00) [5]

-=GaLaN=-   (27.05.05 15:30) [73]

Я вообще-то в посте написал, что это "кусок программы". И не рассчитывал на то, что кто-то компилировать мой код. Там еще нескольких юниов не хватает. Надо кодом обычно рекомендуется думать, смотреть, как реализованы те или иные идеи, применять эту реализацию к своему коду.


-=GaLaN=-   (2005-05-27 15:30:00) [6]

2Просто Джо:
Спасибо, работает неплохо на графических и консольных Win32, но... на DOS-приложениях функция скопытивается и выдаёт либо Unknown, либо Ambigous - и при том, что опциональный заголовок отсутствует, функция считает, будто он есть.

А Игорь Шевченко респект! У меня только маааленький вопросик - а где взять HSDosImage? Не компилит за отсутствием HSDosImage.dcu. :(

2All:
Честно говоря, нет смысла забирать com файлы. Пользователи моей программы будут сами себе злобные буратины, если начнут переименовывать всякие com в exe. Если консольность, графичность или dos'ность приложения не подтвердится, то его просто CreateProcess'ну - пускай система сама разбирается что к чему...


Eraser   (2005-05-27 14:56:00) [7]

wal ©   (27.05.05 14:53) [71]

Ну тогда единственный способ узнать тип файла - отослать его по почте в M$ дождаться их ответа.


wal   (2005-05-27 14:53:00) [8]


> [69] Eraser ©   (27.05.05 14:39)
> Если заголовка нету, это com файл.

Или бессмысленный набор байтов.

> Чаще всего в таких файлах первая команда - безусловный переход.

Во первых не всегда, а во вторых это и есть анализ кода, о котором я говорил ;)

С уважением.


Eraser   (2005-05-27 14:40:00) [9]

Игорь Шевченко ©

Мда - весч впчатляет. Респект.


Eraser   (2005-05-27 14:39:00) [10]

wal ©   (27.05.05 14:03) [68]

Если заголовка нету, это com файл. Чаще всего в таких файлах первая команда - безусловный переход.


wal   (2005-05-27 14:03:00) [11]


> [67] Defunct ©   (27.05.05 13:21)

1. Возьми в C:\WINNT\system32\ файл command.com
2. Скопируй его куда-нибудь.
3. Запусти и убедись, что работает
4. Переименуй его в command.exe
5. Запусти и убедись, что работает
6. Посмотри на его "изнутри" и убедись, что никаких MZ- и тем более PE-заголовка там нет.
7. А теперь на основании расширения (.exe) и заголовка (которого нет) определи однозначно, что это исполняемый файл.

С уважением.


Defunct   (2005-05-27 13:21:00) [12]

wal ©   (27.05.05 11:56) [66]

Как раз по расширению и заголовку тип файла определяется однозначно. Иначе бы Windows и гроша ломаного не стоила.

Анализом кода только антивирусы занимаются.


wal   (2005-05-27 11:56:00) [13]


> [65] Digitman ©   (27.05.05 11:11)

Дак я об том и говорю, что однозначно определить только по расширению и заголовку программа это или нет без анализа кода невозможно. Так что времена хоть и "злые", но ничего существенно неизменилось. Только не виснет вся система, а вирт. машина ошибку выдает.

С уважением.


Digitman   (2005-05-27 11:11:00) [14]


> wal ©   (27.05.05 09:56) [56]



> wal ©   (27.05.05 09:56) [56]



> В старые добрые времена


нынешние времена злые пошли .. "шаг влево, шаг вправо - попытка к побегу, расстрел на месте" )

иду я, к примеру, в папку c:\winnt\system32 и рассматриваю в лупу известный edit.com ... вижу там 'MZ' - значит, явно не com-формат ... но системе это по барабану - на мое требование запуска задачи система тут же стартует экземпляр виртуальной ДОС-машины, а та уже сама разбирается, как его, этот исп.файл, запустить - по EXE- или СОМ-соглашениям...

логика здесь, очевидно, такова :

- система, обнаружив что файл имеет одно из расширений - ЕХЕ или СОМ, шарит по заголовкам

- обнаружив в корректных заголовках все признаки того, что файл есть образ исполняемого Win32-модуля, система делает попытку старта соответствующего Win32-процесса

- обнаружив корректный ДОС-заголовок, но не обнаружив признаков образа исполняемого Win32-модуля, либо не обнаружив вообще никаких заголовков, система подразумевает что дан.файл является образом ДОС16-модуля и стартует новый процесс вирт. ДОС-машины, которая уже собственно и пытается исполнить код ДОС-задачи

- если файл в реальности не содержит ДОС16-образ  (например, в файле некая абракадабра, внешне похожая на СОМ-файл, но при выполнении кода которого как правило возникнет искл.ситуация), вирт.машина сообщает об этом, и после подтверждения юзера система немедля снимает процесс вирт.машины с выполнения


Просто Джо   (2005-05-27 10:59:00) [15]

Игорь Шевченко ©  
Спасибо, проделанная работа действительно впечатляет. Думаю, что автору топика это подойдет в самый раз. Да и я себе в заначку положу, на досуге поковыряюсь :)


Игорь Шевченко   (2005-05-27 10:46:00) [16]

Просто Джо ©   (27.05.05 10:18) [59]

procedure TPEImage.Load(Mapper: THSFileMapper);
begin
 inherited;
 FNtHeaders := PIMAGE_NT_HEADERS(Mapper.Map + DosHeader^._lfanew);
 LoadSections (Mapper);
 LoadModuleReferences (Mapper);
end;

procedure TPEImage.LoadDelayImports;
var
 RawOffset: Integer;
 ImportDescriptor: PDelayLoadImportTableItem;
 DllName: string;
 PFunctionsAddress: PDWORD;
 ImportAddress: DWORD;
begin
 with NtHeaders^.OptionalHeader.DataDirectory[
     IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT] do begin
   if (VirtualAddress = 0) or (Size = 0) then
     Exit;
   RawOffset := RawAddress(VirtualAddress);
 end;
 ImportDescriptor := PDelayLoadImportTableItem(RawData + RawOffset);
 while ImportDescriptor^.DllName <> 0 do begin
   if ImportDescriptor^.Flags = 1 then begin
     RawOffset := RawAddress(ImportDescriptor^.DllName);
     if RawOffset <> 0 then
       DllName := UpperCase(StrPas(RawData + RawOffset));
     RawOffset := RawAddress(ImportDescriptor^.ImportNameTable);
     PFunctionsAddress := PDWORD(RawData + RawOffset);
     while PFunctionsAddress^ <> 0 do begin
       ImportAddress := PFunctionsAddress^;
       FDelayImports.Add(GetImportedFunctionName(DllName, ImportAddress));
       Inc(PFunctionsAddress);
     end;
   end;
   Inc(ImportDescriptor);
 end;
end;

procedure TPEImage.LoadImports;
var
 RawOffset: Integer;
 ImportDescriptor: PIMAGE_IMPORT_DESCRIPTOR;
 DllName: string;
 PFunctionsAddress: PDWORD;
 ImportAddress: DWORD;
begin
 with NtHeaders^.OptionalHeader.DataDirectory[
     IMAGE_DIRECTORY_ENTRY_IMPORT] do begin
   if (VirtualAddress = 0) or (Size = 0) then
     Exit;
   RawOffset := RawAddress(VirtualAddress);
 end;
 ImportDescriptor := PIMAGE_IMPORT_DESCRIPTOR(RawData + RawOffset);
 while ImportDescriptor^.Name <> 0 do begin
   RawOffset := RawAddress(ImportDescriptor^.Name);
   if RawOffset <> 0 then
     DllName := UpperCase(StrPas(RawData + RawOffset));
   if ImportDescriptor^.Characteristics = 0 then
     RawOffset := RawAddress(ImportDescriptor^.FirstThunk)
   else
     RawOffset := RawAddress(ImportDescriptor^.Characteristics);
   PFunctionsAddress := PDWORD(RawData + RawOffset);
   while PFunctionsAddress^ <> 0 do begin
     ImportAddress := PFunctionsAddress^;
     FImports.Add(GetImportedFunctionName(DllName, ImportAddress));
     Inc(PFunctionsAddress);
   end;
   Inc(ImportDescriptor);
 end;
end;

procedure TPEImage.LoadModuleReferences(Mapper: THSFileMapper);
var
 IAddr: DWORD;
 PImport: PIMAGE_IMPORT_DESCRIPTOR;
 PModName: PChar;
begin
 with NtHeaders^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] do
   if Size <> 0 then begin
     IAddr := RawAddress(VirtualAddress);
     PImport := PIMAGE_IMPORT_DESCRIPTOR(Mapper.Map + IAddr);
     while PImport^.Name <> 0 do begin
       PModName := Mapper.Map + RawAddress(PImport^.Name);
       FModuleReferences.Add(PModName);
       FImportLibraries.Add(UpperCase(PModName));
       Inc(PImport);
     end;
   end;
end;

procedure TPEImage.LoadSections(Mapper: THSFileMapper);
var
 PSection: PImageSectionHeader;
 I: Integer;
begin
 PSection := PImageSectionHeader(DWORD(@(NtHeaders^.OptionalHeader)) +
       NtHeaders^.FileHeader.SizeOfOptionalHeader);
 for I:=1 to NtHeaders^.FileHeader.NumberOfSections do begin
   FSections.Add (PSection);
   Inc(PSection);
 end;
end;

function TPEImage.RawAddress(VirtualAddress: Cardinal): Cardinal;
var
 I: Integer;
 Position: Cardinal;
begin
 Result := 0;
 for I := 0 to Pred(FSections.Count) do
   if (Sections[I].VirtualAddress <= VirtualAddress) and
      (VirtualAddress < Sections[I].VirtualAddress +
       Sections[I].SizeOfRawData) then begin
     Position := VirtualAddress - Sections[I].VirtualAddress;
     Result := Sections[I].PointerToRawData + Position;
     Break;
   end;
end;

end.


Кусок программы, анализирующей исполняемые файлы.


Игорь Шевченко   (2005-05-27 10:44:00) [17]

Просто Джо ©   (27.05.05 10:18) [59]


implementation

{ TPEImage }

constructor TPEImage.Create(const FileName: string);
begin
 inherited Create(FileName);
 FSections := TList.Create;
 FModuleReferences := TStringList.Create;
 FImportLibraries := TStringList.Create;
 with FImportLibraries do begin
   Sorted := true;
   Duplicates := dupIgnore;
 end;
 FMapper := THSFileMapper.Create (FileName);
 Load (FMapper);
end;

destructor TPEImage.Destroy;
begin
 FMapper.Free;
 FImportLibraries.Free;
 FModuleReferences.Free;
 FSections.Free;
 FImports.Free;
 FDelayImports.Free;
 inherited;
end;

function TPEImage.EpCode: PByteArray;
var
 EpAddr: DWORD;
begin
 EpAddr := RawAddress(NtHeaders^.OptionalHeader.AddressOfEntryPoint);
 if EpAddr <> 0 then
   Result := PByteArray(FMapper.Map + EpAddr)
 else
   Result := nil;
end;

function TPEImage.FindSection(
 VirtualAddress: Cardinal): PImageSectionHeader;
var
 I: Integer;
begin
 Result := nil;
 for I := 0 to Pred(FSections.Count) do
   if (Sections[I].VirtualAddress <= VirtualAddress) and
      (VirtualAddress < Sections[I].VirtualAddress +
       Sections[I].SizeOfRawData) then begin
     Result := Sections[I];
     Break;
   end;
end;

function TPEImage.GetDelayImports: TStrings;
begin
 if not Assigned(FDelayImports) then begin
   FDelayImports := TStringList.Create;
   FDelayImports.Sorted := true;
   FDelayImports.Duplicates := dupIgnore;
   LoadDelayImports;
 end;
 Result := FDelayImports;
end;

function TPEImage.GetFullImportedFunctionName(const DllName: string;
 IATEntryRVA: DWORD): string;
begin
 if (IATEntryRVA and $80000000) <> 0 then
   Result := Format('%s.%d', [ChangeFileExt(DllName, ''),
     (IATEntryRVA and $7FFFFFFF)])
 else
   Result := Format('%s.%s', [ChangeFileExt(DllName, ''),
     GetImportedNameFromIATEntry(IATEntryRVA, true)]);
end;

function TPEImage.GetImportedFunctionName(const DllName: string;
 IATEntryRVA: DWORD): string;
begin
 if (IATEntryRVA and $80000000) <> 0 then
   Result := Format('%s.%d', [ChangeFileExt(DllName, ''),
     (IATEntryRVA and $7FFFFFFF)])
 else
   Result := Format('%s.%s', [ChangeFileExt(DllName, ''),
     GetImportedNameFromIATEntry(IATEntryRVA)]);
end;

function TPEImage.GetImportedNameFromIATEntry(IATEntryRVA: DWORD;
 FullInfo: Boolean): string;
var
 RawOffset: DWORD;
begin
 RawOffset := RawAddress (IATEntryRVA);
 Result := StrPas(RawData + RawOffset + SizeOf(Word));
 if FullInfo then
   Result := Format('%s (Hint=%.4x)', [Result,
     PIMAGE_IMPORT_BY_NAME(RawData + RawOffset)^.Hint]);
end;

function TPEImage.GetImports: TStrings;
begin
 if not Assigned(FImports) then begin
   FImports := TStringList.Create;
   FImports.Sorted := true;
   FImports.Duplicates := dupIgnore;
   LoadImports;
 end;
 Result := FImports;
end;

function TPEImage.GetSection(I: Integer): PImageSectionHeader;
begin
 Result := PImageSectionHeader(FSections[I]);
end;

function TPEImage.GetSubSystem: THSSubSystem;
begin
 with NtHeaders.OptionalHeader.DataDirectory[
     IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR] do
   if (VirtualAddress <> 0) and (Size <> 0) then
     Result := hsssDotNet
   else
     case NtHeaders^.OptionalHeader.Subsystem of
     IMAGE_SUBSYSTEM_WINDOWS_GUI:
       Result := hsssGUI32;
     IMAGE_SUBSYSTEM_WINDOWS_CUI:
       Result := hsssCon32;
     IMAGE_SUBSYSTEM_NATIVE:
       Result := hsssNative;
     else
       Result := hsssUnknown;
     end;
end;


Игорь Шевченко   (2005-05-27 10:43:00) [18]

Просто Джо ©   (27.05.05 10:18) [59]

{
  Модуль: HSPEImage

  Описание: Класс для образа 32-битного исполняемого файла Windows

  Автор: Игорь Шевченко

  Дата создания: 23.02.2003

  История изменений:
  03.04.2003 Добавлен метод получения имени импортируемой функции по адресу
             в таблице импорта.
             Добавлен метод получения импортируемых функций.
  04.04.2003 Добавлено описание для структур .Net. При описании использовалась
             статья Павла Румянцева в RSDN Magazine №2 2003.
}
unit HSPEImage;

interface
uses
 Windows, HSDosImage, HSFileMapper, Classes, SysUtils, HSImageUtils,
 HSObjectList;

type
 PDwordArray = ^TDwordArray;
 TDwordArray = array[0..8191] of DWORD;
 USHORT = Word;

 PIMAGE_NT_HEADERS = PImageNtHeaders;
 PIMAGE_DATA_DIRECTORY = ^IMAGE_DATA_DIRECTORY;

 PIMAGE_IMPORT_DESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR;
 IMAGE_IMPORT_DESCRIPTOR = packed record
   Characteristics: Cardinal;  // 0 for terminating null import descriptor
                                // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
   TimeDateStamp: Cardinal;    // 0 if not bound,
                                // -1 if bound, and real date\time stamp
                                //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
                                // O.W. date/time stamp of DLL bound to (Old BIND)

   ForwarderChain: Cardinal;   // -1 if no forwarders
   Name: Cardinal;
   FirstThunk: Cardinal;       // RVA to IAT (if bound this IAT has actual addresses)
 end;

 IMAGE_IMPORT_BY_NAME = packed record
   Hint: WORD;
   Name: Char;
 end;
 PIMAGE_IMPORT_BY_NAME = ^IMAGE_IMPORT_BY_NAME;

 TDelayLoadImportTableItem = packed record
   Flags: LongInt;
   DllName: Cardinal;
   Handle: Cardinal; //RVA to DATA segment
   EpAddresses: Cardinal; //Array of entry point addresses for this library
   ImportNameTable: Cardinal; //RVA of Module name table
   Reserved2: Cardinal; //Don't know
   Reserved3: Cardinal; //Don't know
   Reserved4: Cardinal; //Don't know
 end;
 PDelayLoadImportTableItem = ^TDelayLoadImportTableItem;

 TDelayLoadImportTableItemArray = array [0..1024] of TDelayLoadImportTableItem;
 PDelayLoadImportTableItemArray = ^TDelayLoadImportTableItemArray;

 PDelayLoadEntryItem = PIMAGE_IMPORT_BY_NAME;

 IMAGE_COR20_HEADER = packed record
   //Информация о версии
   cb: ULONG;
   MajorRuntimeVersion: USHORT;
   MinorRuntimeVersion: USHORT;
   //Таблицы метаданных, флаги и информация о точке входа
   MetaData: IMAGE_DATA_DIRECTORY;
   Flags: ULONG;
   EntryPointToken: ULONG;
   Resources: IMAGE_DATA_DIRECTORY;
   StrongNameSignature: IMAGE_DATA_DIRECTORY;
   CodeManagerTable: IMAGE_DATA_DIRECTORY;
   VTableFixups: IMAGE_DATA_DIRECTORY;
   ExportAddressTableJumps: IMAGE_DATA_DIRECTORY;
   // Информация о прекомпилированном образе файла (только для внутреннего
   //  использования)
   ManagedNativeHeader: IMAGE_DATA_DIRECTORY;
 end;
 PIMAGE_COR20_HEADER = ^IMAGE_COR20_HEADER;

 // метадата .Net
 STORAGESIGNATURE = packed record
   lSignature: ULONG; // "Магическая" сигнатура ($424A5342)
   iMajorVer: USHORT; // Старшая часть версии файла
   iMinorVer: USHORT; // Младшая часть версии файла
   iExtraData: ULONG;  // Смещение следующей структуры с информацией
   iVersionString: ULONG; // длина строки с названием версии
   pVersion: array[0..0] of Char; //строка, содержащая название версии,
                   // длина определяется полем iVersionString
 end;
 PSTORAGESIGNATURE = ^STORAGESIGNATURE;

 STORAGEHEADER = packed record
   fFlags: BYTE; // Флаги STGHDR_
   Pad: BYTE;
   iStreams: USHORT; // Число стримов
 end;
 PSTORAGEHEADER = ^STORAGEHEADER;

 STORAGESTREAM = packed record
   iOffset: ULONG;
   iSize: ULONG;
   rcName: array[0..0] of Char;
 end;
 PSTORAGESTREAM = ^STORAGESTREAM;

 TPEImage = class(TDosImage)
 private
   FMapper: THSFileMapper;
   FModuleReferences: TStrings;
   FImportLibraries: TStringList;
   FNtHeaders: PIMAGE_NT_HEADERS;
   FSections: TList;
   FImports: TStringList;
   FDelayImports: TStringList;
   function GetSection(I: Integer): PImageSectionHeader;
   procedure LoadSections (Mapper: THSFileMapper);
   procedure LoadModuleReferences (Mapper: THSFileMapper);
   function GetImportedNameFromIATEntry (IATEntryRVA: DWORD;
     FullInfo: Boolean = false): string;
   function GetSubSystem: THSSubSystem;
   function GetImports: TStrings;
   procedure LoadImports;
   procedure LoadDelayImports;
   function GetDelayImports: TStrings;
 protected
   procedure Load (Mapper: THSFileMapper); override;
 public
   constructor Create (const FileName: string); override;
   destructor Destroy; override;
   function EpCode: PByteArray; override;
   function RawAddress (VirtualAddress: Cardinal): Cardinal;
   function GetFullImportedFunctionName(const DllName: string;
     IATEntryRVA: DWORD): string;
   function GetImportedFunctionName(const DllName: string;
     IATEntryRVA: DWORD): string;
   function FindSection (VirtualAddress: Cardinal): PImageSectionHeader;
   property Mapper: THSFileMapper read FMapper;
   property ModuleReferences: TStrings read FModuleReferences;
   property ImportLibraries: TStringList read FImportLibraries;
   property NtHeaders: PIMAGE_NT_HEADERS read FNtHeaders;
   property SectionList: TList read FSections;
   property Sections[I: Integer]: PImageSectionHeader read GetSection;
   property Subsystem: THSSubSystem read GetSubSystem;
   property Imports: TStrings read GetImports;
   property DelayImports: TStrings read GetDelayImports;
 end;

{ Не вошедшие в Windows.pas константы из Platform SDK }
const
 IMAGE_FILE_LARGE_ADDRESS_AWARE = $0020;

 IMAGE_SUBSYSTEM_NATIVE_WINDOWS = 8;   // image is a native Win9x driver.
 IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9;   // Image runs in the Windows CE subsystem.
 IMAGE_SUBSYSTEM_EFI_APPLICATION = 10;
 IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11;
 IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12;
 IMAGE_SUBSYSTEM_EFI_ROM = 13;
 IMAGE_SUBSYSTEM_XBOX = 14;

 IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = $0200;    // Image understands
                                                   // isolation and doesn't
                                                   // want it
 IMAGE_DLLCHARACTERISTICS_NO_SEH = $0400;     // Image does not use SEH.
                                              // No SE handler may reside
                                              // in this image
 IMAGE_DLLCHARACTERISTICS_NO_BIND = $0800;     // Do not bind this image.
 IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = $2000;     // Driver uses WDM model
 IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = $8000;

 IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT  = 13;   // Delay Load Import Descriptors
 IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = 14;   // COM Runtime descriptor


Игорь Шевченко   (2005-05-27 10:40:00) [19]

Просто Джо ©   (27.05.05 10:18) [59]

type
 THSBinaryType = (hsbtError, hsbtWin32, hsbtWin16, hsbtDos16, hsbtCom,
   hsbtVxd, hsbtW3, hsBtUnknown);

function HSGetBinaryType (const FileName: string): THSBinaryType;
type
 PIMAGE_DOS_HEADER = ^IMAGE_DOS_HEADER;
 PIMAGE_NT_HEADERS = PImageNtHeaders;
var
 Mapper: THSFileMapper;
 DosHeader: PIMAGE_DOS_HEADER;
 FileHeader: PIMAGE_NT_HEADERS;
begin
 Result := hsbtError;
 Mapper := THSFileMapper.Create (FileName);
 try
   if (Mapper.Map[0] <> 'M') or (Mapper.Map[1] <> 'Z') then begin
     if UpperCase(ExtractFileExt(FileName)) = '.COM' then
       Result := hsbtCom;
     Exit;
   end else if Mapper.FileSize >= SizeOf(IMAGE_DOS_HEADER) then begin
     DosHeader := PIMAGE_DOS_HEADER(Mapper.Map);
     if (DosHeader^._lfanew > $40) { Matt Pietrek } and
        (DWORD(DosHeader^._lfanew) < Mapper.FileSize - SizeOf(WORD)) then begin
       FileHeader := PIMAGE_NT_HEADERS(DWORD(DosHeader) +
                                       DWORD(DosHeader^._lfanew));
       if FileHeader^.Signature = IMAGE_NT_SIGNATURE then
         Result := hsbtWin32
       else if WORD(FileHeader^.Signature) = IMAGE_OS2_SIGNATURE then
         Result := hsbtWin16
       else if WORD(FileHeader^.Signature) = IMAGE_VXD_SIGNATURE then
         Result := hsbtVxd
       else if WORD(FileHeader^.Signature) = IMAGE_W3_SIGNATURE then
         Result := hsbtW3
       else
         Result := hsbtUnknown;
     end else
       Result := hsbtDos16;
   end;
 finally
   Mapper.Free;
 end;
end;


Просто Джо   (2005-05-27 10:18:00) [20]

А все-таки, функцией GetBinaryType не определишь - консольное оно или нет, все равно придется в хэдэрах ковыряться.


Страницы:   1 2 3 4

Наверх

Титульная страница Поиск, карта сайта Написать письмо