Các Magic
lĩnh vực IMAGE_OPTIONAL_HEADER
(mặc dù không có gì là không bắt buộc về tiêu đề trong Windows hình ảnh thực thi (file DLL / EXE)) sẽ cho bạn biết kiến trúc của PE.
Đây là một ví dụ về lấy kiến trúc từ một tập tin.
public static ushort GetImageArchitecture(string filepath) {
using (var stream = new System.IO.FileStream(filepath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
using (var reader = new System.IO.BinaryReader(stream)) {
//check the MZ signature to ensure it's a valid Portable Executable image
if (reader.ReadUInt16() != 23117)
throw new BadImageFormatException("Not a valid Portable Executable image", filepath);
// seek to, and read, e_lfanew then advance the stream to there (start of NT header)
stream.Seek(0x3A, System.IO.SeekOrigin.Current);
stream.Seek(reader.ReadUInt32(), System.IO.SeekOrigin.Begin);
// Ensure the NT header is valid by checking the "PE\0\0" signature
if (reader.ReadUInt32() != 17744)
throw new BadImageFormatException("Not a valid Portable Executable image", filepath);
// seek past the file header, then read the magic number from the optional header
stream.Seek(20, System.IO.SeekOrigin.Current);
return reader.ReadUInt16();
}
}
Hai hằng số kiến trúc duy nhất tại thời điểm này là:
0x10b - PE32
0x20b - PE32+
Chúc mừng
CẬP NHẬT
Đã được một thời gian kể từ khi tôi đăng câu trả lời này, nhưng tôi vẫn thấy rằng nó nhận được một vài upvote bây giờ và vì vậy tôi nhận thấy nó đáng để cập nhật. Tôi đã viết một cách để có được kiến trúc của một Portable Executable
hình ảnh, cũng kiểm tra xem nó có được biên dịch thành không AnyCPU
. Thật không may, câu trả lời là trong C ++, nhưng không quá khó để chuyển sang C # nếu bạn có vài phút để tìm kiếm các cấu trúc trong đó WinNT.h
. Nếu mọi người quan tâm tôi sẽ viết một cổng bằng C #, nhưng trừ khi mọi người thực sự muốn nó, tôi sẽ không dành nhiều thời gian để nhấn mạnh về nó.
#include <Windows.h>
#define MKPTR(p1,p2) ((DWORD_PTR)(p1) + (DWORD_PTR)(p2))
typedef enum _pe_architecture {
PE_ARCHITECTURE_UNKNOWN = 0x0000,
PE_ARCHITECTURE_ANYCPU = 0x0001,
PE_ARCHITECTURE_X86 = 0x010B,
PE_ARCHITECTURE_x64 = 0x020B
} PE_ARCHITECTURE;
LPVOID GetOffsetFromRva(IMAGE_DOS_HEADER *pDos, IMAGE_NT_HEADERS *pNt, DWORD rva) {
IMAGE_SECTION_HEADER *pSecHd = IMAGE_FIRST_SECTION(pNt);
for(unsigned long i = 0; i < pNt->FileHeader.NumberOfSections; ++i, ++pSecHd) {
// Lookup which section contains this RVA so we can translate the VA to a file offset
if (rva >= pSecHd->VirtualAddress && rva < (pSecHd->VirtualAddress + pSecHd->Misc.VirtualSize)) {
DWORD delta = pSecHd->VirtualAddress - pSecHd->PointerToRawData;
return (LPVOID)MKPTR(pDos, rva - delta);
}
}
return NULL;
}
PE_ARCHITECTURE GetImageArchitecture(void *pImageBase) {
// Parse and validate the DOS header
IMAGE_DOS_HEADER *pDosHd = (IMAGE_DOS_HEADER*)pImageBase;
if (IsBadReadPtr(pDosHd, sizeof(pDosHd->e_magic)) || pDosHd->e_magic != IMAGE_DOS_SIGNATURE)
return PE_ARCHITECTURE_UNKNOWN;
// Parse and validate the NT header
IMAGE_NT_HEADERS *pNtHd = (IMAGE_NT_HEADERS*)MKPTR(pDosHd, pDosHd->e_lfanew);
if (IsBadReadPtr(pNtHd, sizeof(pNtHd->Signature)) || pNtHd->Signature != IMAGE_NT_SIGNATURE)
return PE_ARCHITECTURE_UNKNOWN;
// First, naive, check based on the 'Magic' number in the Optional Header.
PE_ARCHITECTURE architecture = (PE_ARCHITECTURE)pNtHd->OptionalHeader.Magic;
// If the architecture is x86, there is still a possibility that the image is 'AnyCPU'
if (architecture == PE_ARCHITECTURE_X86) {
IMAGE_DATA_DIRECTORY comDirectory = pNtHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR];
if (comDirectory.Size) {
IMAGE_COR20_HEADER *pClrHd = (IMAGE_COR20_HEADER*)GetOffsetFromRva(pDosHd, pNtHd, comDirectory.VirtualAddress);
// Check to see if the CLR header contains the 32BITONLY flag, if not then the image is actually AnyCpu
if ((pClrHd->Flags & COMIMAGE_FLAGS_32BITREQUIRED) == 0)
architecture = PE_ARCHITECTURE_ANYCPU;
}
}
return architecture;
}
Hàm chấp nhận một con trỏ tới hình ảnh PE trong bộ nhớ (vì vậy bạn có thể chọn chất độc của mình về cách lấy nó; ánh xạ bộ nhớ hoặc đọc toàn bộ vào bộ nhớ ... bất cứ điều gì).