2011-06-10 19 views
13

Jeśli masz już uszkodzone rozszerzenia plików, w jaki sposób odróżnić plik wykonywalny od biblioteki DLL?Jak sprawdzić, czy plik jest plikiem EXE lub DLL?

Obaj wydają się mieć punkty wejścia i wszystko ...

+0

programowo? – CharlesB

+0

@OmerPT, @CharlesB: Chodzi mi o bardziej jak poprzez ich funkcje (np. Ich nagłówki PE, ich demontaż itp.) – Mehrdad

+0

Zmień nazwę na rozszerzenie 'exe' i spróbuj wykonać to w środowisku Windows. Jeśli coś robi, to jest exe. : P Właściwie to jestem ciekawy ... – bdares

Odpowiedz

5

Spójrz na this article, aby uzyskać dobre wyjaśnienie przenośnego pliku wykonywalnego w systemie Windows.

A następnie spójrz na sekcję o nagłówku PE. Również kod tam w C pokazuje sposób otwierania i badania pliku PE przy użyciu Win32. Te informacje, których szukasz, są przechowywane w IMAGE_FILE_HEADER. W szczególności w polu Characteristics, które zawierałoby flagę IMAGE_FILE_DLL 0x2000, jeśli jest to biblioteka DLL.

To powinno dać ci wystarczającą ilość informacji, aby utworzyć małe narzędzie, które decyduje o wiązce plików, jeśli tego właśnie szukasz.

Najbardziej odpowiednie fragmenty kodu w celach referencyjnych, skopiowane z powyższego artykułu i poddane edycji w celu usunięcia zbędnych szczegółów/obsługi błędów.

void DumpFile(LPWSTR filename) 
{ 
    HANDLE hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 

    HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); 

    LPVOID lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);  

    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpFileBase; 

    PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew); 

    if ((pNTHeader->FileHeader.Characteristics & IMAGE_FILE_DLL)) 
     printf("dll"); 
    if ((pNTHeader->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) 
     printf("exe"); 
    else 
     printf("????"); 

    UnmapViewOfFile(lpFileBase); 
    CloseHandle(hFileMapping); 
    CloseHandle(hFile); 
} 
+0

Myśląc o tym nieco więcej, zdaję sobie sprawę, że powyższy kod nie zadziała (minęło dużo czasu). To nie będzie poprawnie dostać się do nagłówka pliku. Kiedy dostanę chwilę, spróbuję to poprawić – dkackman

+0

Naprawiono kod. Myślę, że teraz zadziała – dkackman

0

Grab OllyDbg i otwórz EXE/DLL w nim. Wyświetl mapę pamięci, klikając duży przycisk M u góry. Przewiń w dół, aż znajdziesz nagłówek PE modułu, który odpowiada Twojemu programowi. Kliknij dwukrotnie, aby otworzyć go w zrzucie pamięci. Przewiń w dół do miejsca, w którym zobaczysz podpis PE (prawdopodobnie 0xF8 z bazy obrazów), a jeśli jest to DLL, to Characteristics będzie zawierał flagę DLL. Charakterystyka powinna należeć do kilku elementów z podpisu PE.

2
dumpbin *.* | grep "File Type" 

pracuje dla mnie. Nie pamiętam dokładnie, czego używać, jeśli nie masz zainstalowanego grep, ale proponuję, abyś to zrobił.

6

Informacja ta znajduje się w nagłówku PE. Aby go wyświetlić, możesz otworzyć go za pomocą eksploratora PE, takiego jak NTCore CFF Explorer i otworzyć pole Characterics nagłówka pliku, w którym można znaleźć, czy jest to DLL czy plik wykonywalny.

enter image description here

+0

+1 to jest niesamowite. Dzięki! – Mehrdad

5

jeśli ktoś zainteresowany tu jest kod w języku C#, testowane na 32-bitowe pliki PE.

public static class PECheck 
    { 

     public static bool IsDll(Stream stream) 
     { 

      using (BinaryReader reader = new BinaryReader(stream)) 
      { 

       byte[] header = reader.ReadBytes(2); //Read MZ 
       if (header[0] != (byte)'M' && header[1] != (byte)'Z') 
        throw new Exception("Invalid PE file"); 

       stream.Seek(64 - 4, SeekOrigin.Begin);//read elf_new this is the offset where the IMAGE_NT_HEADER begins 
       int offset = reader.ReadInt32(); 
       stream.Seek(offset, SeekOrigin.Begin); 
       header = reader.ReadBytes(2); 
       if (header[0] != (byte)'P' && header[1] != (byte)'E') 
        throw new Exception("Invalid PE file"); 

       stream.Seek(20, SeekOrigin.Current); //point to last word of IMAGE_FILE_HEADER 
       short readInt16 = reader.ReadInt16(); 
       return (readInt16 & 0x2000) == 0x2000; 

      } 
     } 
    }