读取exe程序,并输出字段信息

# define _CRT_SECURE_NO_WARNINGS
# include <stdio.h>
# include <stdlib.h>
# include <string.h>

typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;

typedef struct _Dos_Header
{
    WORD e_magic;
    WORD e_cblp;
    WORD e_cp;
    WORD e_crlc;
    WORD e_aparhdr;
    WORD e_minalloc;
    WORD e_maxalloc;
    WORD e_ss;
    WORD e_sp;
    WORD e_csum;
    WORD e_ip;
    WORD e_cs;
    WORD e_lfarlc;
    WORD e_ovno;
    WORD e_res[4];
    WORD e_oeminfo;
    WORD e_res2[10];
    DWORD e_lfanew;
} Dos_Header;

typedef struct _File_Header
{
    WORD        Machine;
    WORD        NumberOfSections;
    DWORD     TimeDateStamp;
    DWORD    PointerToSymbolTable;
    DWORD    NumberOfSymbols;
    WORD        SizeOfOptionalHeader;
    WORD        Characteristics;
}File_Header;

typedef struct _Optional_Header
{
    WORD    Magic;
    BYTE    MajorLinkerVersion;
    BYTE    MinorLinkerVersion;
    DWORD   SizeOfCode;
    DWORD   SizeOfInitializedData;
    DWORD   SizeOfUninitializedData;
    DWORD   AddressOfEntryPoint;
    DWORD   BaseOfCode;
    DWORD   BaseOfData;
    DWORD   ImageBase;
    DWORD   SectionAlignment;
    DWORD   FileAlignment;
    WORD    MajorOperatingSystemVersion;
    WORD    MinorOperatingSystemVersion;
    WORD    MajorImageVersion;
    WORD    MinorImageVersion;
    WORD    MajorSubsystemVersion;
    WORD    MinorSubsystemVersion;
    DWORD   Win32VersionValue;
    DWORD   SizeOfImage;
    DWORD   SizeOfHeaders;
    DWORD   CheckSum;
    WORD    Subsystem;
    WORD    DllCharacteristics;
    DWORD   SizeOfStackReserve;
    DWORD   SizeOfStackCommit;
    DWORD   SizeOfHeapReserve;
    DWORD   SizeOfHeapCommit;
    DWORD   LoaderFlags;
    DWORD   NumberOfRvaAndSizes;
}Optional_Header;

typedef struct _NT_Header
{
    DWORD Signature;
    File_Header FileHeader;
    Optional_Header OptionalHeader;
}NT_Header;

//计算文件长度
int File_Lenth(FILE* pf)
{
    fseek(pf, 0, SEEK_END);//指向文件结尾
    int num = ftell(pf);//首尾间的距离
    fseek(pf, 0, SEEK_SET);//恢复

    return num;
}

//FillBuffer
char* File_Read(const char* p)
{
    FILE* pf = fopen(p, "rb");
    int len = File_Lenth(pf);
    char* pb = (char*)malloc(sizeof(char) * len);
    fread(pb, len, 1, pf);

    return pb;
}

Dos_Header* Dos_Read(char* p)
{
    Dos_Header* Dos = (Dos_Header*)malloc(sizeof(Dos_Header));分配dos头需要的内存
    memcpy(Dos, p, sizeof(Dos_Header));//内存复制
    
    return Dos;
}

//打印DOS头
int Dos_Print(Dos_Header* Dos) { printf("Dos->e_magic:%X\n", Dos->e_magic); printf("Dos->e_lfanew:%X\n", Dos->e_lfanew); int offset = Dos->e_lfanew; return offset; } NT_Header* NT_Read(char* p, int offset) { NT_Header* NT = (NT_Header*)malloc(sizeof(NT_Header));//分配nt头需要的内存 memcpy(NT, p + offset, sizeof(NT_Header));//内存复制 return NT; } void File_Print(File_Header* File) { printf("File->Machine:%X\n", File->Machine); } void Optional_Print(Optional_Header* Optional) { printf("Optional->Magic:%X\n", Optional->Magic); printf("Optional->ImageBase:%X\n", Optional->ImageBase); }
//打印NT头
void NT_Print(NT_Header* NT) { printf("NT->Signature:%X\n", NT->Signature); File_Print(&NT->FileHeader); Optional_Print(&NT->OptionalHeader); } int main() { char* pfb = File_Read("C:/Windows/System32/notepad.exe"); Dos_Header* Dos = Dos_Read(pfb); int offset = Dos_Print(Dos); NT_Header* NT = NT_Read(pfb, offset); NT_Print(NT); return 0; }

用fopen函数打开notepad.exe是,发现有一字节数据丢失,将参数“r”改成“rb”时,问题解决。

用16进制编辑器查看note.exe

 

 当参数为“r“时,fopen函数将0D0A转换为0A,而“rb”都会读取,所以使用时尽可能使用“rb”比较好

posted @ 2021-03-11 10:14  Yanmo  阅读(404)  评论(0)    收藏  举报