SRC: .NET или нет?
От: vladsm Россия  
Дата: 31.08.02 20:15
Оценка: 22 (2)
Функция для определения является ли .exe или .dll файл .Net'овским или нет. Замечания, пожелания, комментарии, как всегда, приветствуются.

#include <windows.h>

#define EIT_IS_DLL(t) ((-1!=(t))&&((t) & 0x1))
#define EIT_IS_DOTNET(t) ((-1!=(t))&&((t) & 0x2))

//-------------------------------------------------------------------
// Функция для проверки типа исполняемого файла
//
// Параметры:
//   
//   fileName - путь к проверяемому файлу
// 
// Возвращаемое значение:
//   
//   Если младший бит возвр.значения установлен, то файл является
//   динамической библиотекой (dll), иначе это exe-файл. Для 
//   проверки можно использовать макрос EIT_IS_DLL();
//   
//   Второй бит возвр.значения установлен, то файл является
//   файлом .NET;
//   
//   В случае неудачи возвращается -1.
//-------------------------------------------------------------------
WORD GetExecutableImageType(LPCTSTR fileName)
{
  HANDLE hFile;
  HANDLE hMap;
  PBYTE pFileBase;
  PIMAGE_DOS_HEADER pDosHeader;
  PIMAGE_NT_HEADERS pNtHeader;
  WORD result = 0;
  
  // Открываем файл и отображаем его в память
  hFile = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, 0,
                     OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if(INVALID_HANDLE_VALUE == hFile)
    return -1;

  hMap = CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, 0);
  if(!hMap)
  {
    CloseHandle(hFile);  
    return -1;
  }  

  pFileBase = (PBYTE)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
  if(!pFileBase)
  {
    CloseHandle(hMap);
    CloseHandle(hFile);
    return -1;
  }
  
  // Убеждаемся в корректности
  pDosHeader = (PIMAGE_DOS_HEADER)pFileBase;
  if(IMAGE_DOS_SIGNATURE == pDosHeader->e_magic)
  {
    pNtHeader = (PIMAGE_NT_HEADERS)(pFileBase + pDosHeader->e_lfanew);
    if((!IsBadReadPtr(pNtHeader, sizeof(pNtHeader->Signature))) &&
       (IMAGE_NT_SIGNATURE == pNtHeader->Signature) &&
       (pNtHeader->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE))
    {
      // Делаем необходимые проверки
      if(pNtHeader->FileHeader.Characteristics & IMAGE_FILE_DLL)
        result |= 0x1;   
      if(!pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size)
        result |= 0x2;
    }
  }  
  // Убираем после себя                      
  UnmapViewOfFile(pFileBase);
  CloseHandle(hMap);
  CloseHandle(hFile);                   
  return result;
}


Использование:
TCHAR testFile[] = _TEXT("System.Windows.Forms.dll");
WORD type = GetExecutableImageType(testFile);
if(!type)
  cout<<"Error!"<<endl;
cout<<testFile<<" is ";
if(EIT_IS_DOTNET(type))
  cout<<"not ";
cout<<".NET ";  
if(EIT_IS_DLL(type))
  cout<<"dll";
else
  cout<<"exe";  
cout<<endl;
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.