Fork me on GitHub

PE头结构解析(代码实现)

PE头结构解析(代码实现)

图表实现在:https://www.cnblogs.com/juicyhumberger/articles/17064764.html

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//#define F_PATH "C:\\cntflx\\ipmsg.exe"

int* OpenFile()
{
    FILE* PointToFile = NULL;
    int FileSize = 0;
    int* StrBuffer = NULL;
    int Num = 0;

    //打开文件
    if ((PointToFile = fopen("C:\\WINDOWS\\system32\\notepad.exe","rb")) == NULL) {
        printf("打开文件失败!\n");
        exit(1);
    }

    //获取文件大小
    fseek(PointToFile,0,2);
    FileSize = ftell(PointToFile);

    //重定位指针
    fseek(PointToFile,0,0);

    //buffer指向申请的堆
    StrBuffer = (int*)(malloc(FileSize));
    if (!StrBuffer)
    {
        printf("堆空间分配失败!\n");
        free(StrBuffer);
        return 0;
    }

    //读取文件内容
    Num = fread(StrBuffer,FileSize,1,PointToFile);
    if (!Num)
    {
        printf("读取文件内容失败!\n");
        free(StrBuffer);
        return 0;
    }

    //关闭文件
    fclose(PointToFile);

    //将缓冲区内的文件内容的地址返回到调用函数的地方
    return StrBuffer;
}

int* FileSizes = OpenFile();

int PrintfNtHeaders()
{
    //文件指针
    unsigned int* PointBuffer = (unsigned int*)FileSizes;
    unsigned short* pBuffer = (unsigned short*)PointBuffer;
    unsigned char* pcBuffer = (unsigned char*)PointBuffer;

    //判断MZ和PE的标志
    unsigned short Cmp1 = 0x5A4D;
    unsigned int Cmp2 = 0x00004550;

    //判断文件是否读取成功
    if(!PointBuffer)
    {
        printf("文件读取失败!\n");
        free(PointBuffer);
        return 0;
    }

    //判断是否为MZ标志
    if (*pBuffer != Cmp1)
    {
        printf("不是有效MZ标志!\n");
        printf("%X\n",*pBuffer);
        free(PointBuffer);
        return 0;
    }
    printf("*********打印DOS头*********\n");
    printf("e_magic:\t\t\t%X\n",*(pBuffer));
    printf("e_ifanew:\t\t\t%08X\n\n\n",*(PointBuffer+15));

    //判断是否为PE标志
    if (*(PointBuffer+56) != Cmp2)
    {
        printf("不是有效的PE标志!\n");
        printf("%X\n",*(PointBuffer+56));
        free(PointBuffer);
        return 0;
    }

    printf("*********打印标准PE文件头*********\n");

    printf("PE标志:\t\t\t\t%X\n",*(PointBuffer+56));

    printf("Machine:\t\t\t%04X\n",*(pBuffer+114));
    printf("NumberOfSection:\t\t%04X\n",*(pBuffer+115));
    printf("TimeDateStamp:\t\t\t%08X\n",*(PointBuffer+58));
    printf("PointerToSymbolTable:\t\t%08X\n",*(PointBuffer+59));
    printf("NumberOfSymbols:\t\t%08X\n",*(PointBuffer+60));
    printf("SizeOfOptionalHeader:\t\t%04X\n",*(pBuffer+122));
    printf("Chrarcteristics:\t\t%04X\n\n\n",*(pBuffer+123));

    printf("*********打印标准可选PE头*********\n");

    printf("Magic:\t\t\t\t%04X\n", *(pBuffer+124));
    printf("MajorLinkerVersion:\t\t%02X\n", *(pcBuffer+250));
    printf("MinorLinkerVersion:\t\t%02X\n", *(pcBuffer+251));
    printf("SizeOfCode:\t\t\t%08X\n", *(PointBuffer+63));
    printf("SizeOfInitializedData:\t\t%08X\n", *(PointBuffer+64));
    printf("SizeOfUninitializedData:\t%08X\n", *(PointBuffer+65));
    printf("AddressOfEntryPoint:\t\t%08X\n", *(PointBuffer+66));
    printf("BaseOfCode:\t\t\t%08X\n", *(PointBuffer+67));
    printf("BaseOfData:\t\t\t%08X\n", *(PointBuffer+68));
    printf("ImageBase:\t\t\t%08X\n", *(PointBuffer+69));
    printf("SectionAlignment:\t\t%08X\n", *(PointBuffer+70));
    printf("FileAlignment:\t\t\t%08X\n", *(PointBuffer+71));
    printf("MajorOperatingSystemVersion:\t%04X\n", *(pBuffer+144));
    printf("MinorOperatingSystemVersion:\t%04X\n", *(pBuffer+145));
    printf("MajorImageVersion:\t\t%04X\n", *(pBuffer+146));
    printf("MinorImageVersion:\t\t%04X\n", *(pBuffer+147));
    printf("MajorSubsystemVersion:\t\t%04X\n", *(pBuffer+148));
    printf("MinorSubsystemVersion:\t\t%04X\n", *(pBuffer+149));
    printf("Win32VersionValue:\t\t%08X\n", *(PointBuffer+75));
    printf("SizeOfImage:\t\t\t%08X\n", *(PointBuffer+76));
    printf("SizeOfHeaders:\t\t\t%08X\n", *(PointBuffer+77));
    printf("CheckSum:\t\t\t%08X\n", *(PointBuffer+78));
    printf("Subsystem:\t\t\t%04X\n", *(pBuffer+158));
    printf("DllCharacteristics:\t\t%04X\n", *(pBuffer+159));
    printf("SizeOfStackReserve:\t\t%08X\n", *(PointBuffer+80));
    printf("SizeOfStackCommit:\t\t%08X\n", *(PointBuffer+81));
    printf("SizeOfHeapReserve:\t\t%08X\n", *(PointBuffer+82));
    printf("SizeOfHeapCommit:\t\t%08X\n", *(PointBuffer+83));
    printf("LoaderFlags:\t\t\t%08X\n", *(PointBuffer+84));
    printf("NumberOfRvaAndSizes:\t\t%08X\n\n\n", *(PointBuffer+85));

    printf("*********打印PE节表成员信息*********\n");

/*
Name:                   0x000001d8     [.text]      [名称,长度:8位(16字节)的ASCII码.]
Misc:                     0x000001e0     00007748     [V(VS),内存中大小(对齐前的长度).]
VirtualAddress:         0x000001e4     00001000     [V(VO),内存中偏移(该块的RVA).]
SizeOfRawData:          0x000001e8     00007800     [R(RS),文件中大小(对齐后的长度).]
PointerToRawData:       0x000001ec     00000400     [R(RO),文件中偏移.]
PointerToRelocation:    0x000001f0     00000000     [在OBJ文件中使用,重定位的偏移.]
PointerToLinenumbers:   0x000001f4     00000000     [行号表的偏移,提供调试.]
NumberOfRelocations:    0x000001f6     0000         [在OBJ文件中使用,重定位项数目.]
NumberOfLinenumbers:    0x000001f8     0000         [行号表中行号的数目.]
Characteristics:        0x000001fc     60000020     [标志(块属性):20000000h 40000000h 00000020h ]

*/

    printf("*********打印PE节表[.text]成员信息*********\n");

    printf("Name:\t\t\t\t0x%08X%08X\n", (*(PointBuffer+119)),(*(PointBuffer+118)));
    printf("Misc:\t\t\t\t0x%08X\n", *(PointBuffer+120));
    printf("VirtualAddress:\t\t\t0x%08X\n", *(PointBuffer+121));
    printf("SizeOfRawData:\t\t\t0x%08X\n", *(PointBuffer+122));
    printf("PointerToRawData:\t\t0x%08X\n", *(PointBuffer+123));
    printf("PointerToRelocation:\t\t0x%08X\n", *(PointBuffer+124));
    printf("PointerToLinenumbers:\t\t0x%08X\n", *(PointBuffer+125));
    printf("NumberOfRelocations:\t\t0x%04X\n", *(pBuffer+251));
    printf("NumberOfLinenumbers:\t\t0x%04X\n", *(pBuffer+252));
    printf("Characteristics:\t\t0x%08X\n\n\n", *(PointBuffer+127));

    printf("*********打印PE节表[.data]成员信息*********\n");

    printf("Name:\t\t\t\t0x%08X%08X\n", (*(PointBuffer+129)),(*(PointBuffer+128)));
    printf("Misc:\t\t\t\t0x%08X\n", *(PointBuffer+130));
    printf("VirtualAddress:\t\t\t0x%08X\n", *(PointBuffer+131));
    printf("SizeOfRawData:\t\t\t0x%08X\n", *(PointBuffer+132));
    printf("PointerToRawData:\t\t0x%08X\n", *(PointBuffer+133));
    printf("PointerToRelocation:\t\t0x%08X\n", *(PointBuffer+134));
    printf("PointerToLinenumbers:\t\t0x%08X\n", *(PointBuffer+135));
    printf("NumberOfRelocations:\t\t0x%04X\n", *(pBuffer+271));
    printf("NumberOfLinenumbers:\t\t0x%04X\n", *(pBuffer+272));
    printf("Characteristics:\t\t0x%08X\n\n\n", *(PointBuffer+137));

    printf("*********打印PE节表[.rsrc]成员信息*********\n");

    printf("Name:\t\t\t\t0x%08X%08X\n", (*(PointBuffer+139)),(*(PointBuffer+138)));
    printf("Misc:\t\t\t\t0x%08X\n", *(PointBuffer+140));
    printf("VirtualAddress:\t\t\t0x%08X\n", *(PointBuffer+141));
    printf("SizeOfRawData:\t\t\t0x%08X\n", *(PointBuffer+142));
    printf("PointerToRawData:\t\t0x%08X\n", *(PointBuffer+143));
    printf("PointerToRelocation:\t\t0x%08X\n", *(PointBuffer+144));
    printf("PointerToLinenumbers:\t\t0x%08X\n", *(PointBuffer+145));
    printf("NumberOfRelocations:\t\t0x%04X\n", *(pBuffer+291));
    printf("NumberOfLinenumbers:\t\t0x%04X\n", *(pBuffer+292));
    printf("Characteristics:\t\t0x%08X\n\n\n", *(PointBuffer+147));

    free(PointBuffer);
    return 0;
}

int main()
{
    PrintfNtHeaders();
     OpenFile();
     return 0;
}
posted @ 2023-02-20 20:22  汁汁小汉堡  阅读(59)  评论(0编辑  收藏  举报