在c中读取PE文件

问题描述 投票:0回答:1

我需要检查文件是否是PE文件。我需要检查前两个字节是否为 MZ,我这样做了。

这是我的任务:在验证PE格式时,不仅要根据MZ表达式,还要使用读取IMAGE_NT_HEADERS结构体并通过读取IMAGE_FILE_HEADER字段来验证Signature字段并且Machine字段等于的条件值 IMAGE_FILE_MACHINE_I386 或 IMAGE_FILE_MACHINE_AMD64。

我不知道如何才能完成其余的事情。我希望你能帮助我。

int checkPE(char *file){
    int fd=open(file,READ_FLAGS,0777);
    char buffer[TWOBYTE+1] = {'\0'};
    size_t bytes_read;
    char ch;

    if(fd==-1){ //if file cannot be opened give a error message.
        perror("The file cannot be opened.\n");
        return -1;
    }
    
    bytes_read = read(fd,buffer,TWOBYTE); 
    if(bytes_read==-1){ 
        perror("Error while reading file\n");
        return -1;
    }

    if(strcmp(buffer,MZ)!=0){
        return -1;
    }
  
    int closeFlag = close(fd); 
    if(closeFlag==-1){ 
        perror("The file cannot be closed.\n");
        return -1;
    }
}
c portable-executable
1个回答
1
投票

无非就是解析一些结构而已。你已经有了算法。我认为您只需要实施。考虑以下示例实用程序。

PS:欲了解更多详情,请在下面评论。

#include <stdio.h> 
#include <windows.h>
 
BOOL CheckValidity(BYTE* baseAddress);

int main(int argc, char* argv[]) {
    if (argc != 2)
    {
        printf("You didn't specified a PE file.\n");
        printf("Usage: CheckPEImage.exe <Full path of PE File>\n");
        return -1;
    }
    HANDLE hFile = CreateFileA(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    if (hFile == INVALID_HANDLE_VALUE)
        return -1;
    HANDLE hMemoryMap = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    if (!hMemoryMap)
        return -2;
    PBYTE baseAddress = (PBYTE)MapViewOfFile(hMemoryMap, FILE_MAP_READ, 0, 0, 0);
    if (!baseAddress)
        return -3;
    printf("PE Image is %s.\n", CheckValidity(baseAddress) ? "valid" : "invalid");
    getchar();
    return 0;
} 

BOOL CheckValidity(BYTE* baseAddress)
{
    PIMAGE_DOS_HEADER lpDosHeader;
    PIMAGE_FILE_HEADER lpFileHeader;
    PIMAGE_NT_HEADERS lpNtHeaders;
    PIMAGE_OPTIONAL_HEADER lpOptionalHeader;
    lpDosHeader = (PIMAGE_DOS_HEADER)baseAddress;
    lpNtHeaders = (PIMAGE_NT_HEADERS)(baseAddress + lpDosHeader->e_lfanew); 
    if (lpDosHeader->e_magic != IMAGE_DOS_SIGNATURE) 
        return FALSE;
    if (lpNtHeaders->Signature != IMAGE_NT_SIGNATURE) 
        return FALSE;
    if (lpNtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_I386 && lpNtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64 && lpNtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_IA64)
        return FALSE;
    return TRUE;
}
© www.soinside.com 2019 - 2024. All rights reserved.