首页 > 其他分享 >C语言打印节表--PE文件解析

C语言打印节表--PE文件解析

时间:2022-11-20 19:14:38浏览次数:44  
标签:Option Header -- Section 节表 C语言 --- header printf

void Funcation4()
{
    char* file_buffer;
    long file_size = 0;
    FILE* fp;
    fp = fopen("notepad-32bit.exe", "rb");
    fseek(fp, 0, SEEK_END);
    file_size = ftell(fp);
    printf("文件大小为:%d字节\n", file_size);
    //这里重新指向开头
    rewind(fp);
    //申请内存空间
    file_buffer = (char*)malloc(file_size);
    printf("file_buffer:%x\n", file_buffer);
    //初始化内存空间
    memset(file_buffer, 0, file_size);
    //将文件读入内存中
    fread(file_buffer, file_size, 1, fp);
    //这里是用windows.h头文件,使用了Windows.h之后才有下面的内容,定义一个结构体指向那块内存
    //这个就是DOS头获取的方式?
    PIMAGE_DOS_HEADER Dos = (PIMAGE_DOS_HEADER)file_buffer;
    printf("DOS:%x\n", Dos);
    printf("********************DOS头********************\n");
    printf("MZ标识---E_magic:%x\n", Dos->e_magic);
    printf("PE偏移---e_lfarlc:%x\n", Dos->e_lfarlc);
    printf("Dos->e_lfanew:%x\n", Dos->e_lfanew);
    //打印NT头内容
    //判断是否是有效的PE文件
    if (*((PDWORD)((DWORD)file_buffer + Dos->e_lfanew)) != IMAGE_NT_SIGNATURE)
    {
        printf("不是有效的PE标志\n");
        free(file_buffer);
        return;
    }
    //获取NT头位置,这句话主要解释下这里:file_buffer(DOS初始位置) + Dos->e_lfanew,file_buffer + Dos->e_lfanew就是NT开始位置
    printf("********************NT头********************\n");
    PIMAGE_NT_HEADERS Nt_Header = (PIMAGE_NT_HEADERS)(file_buffer + Dos->e_lfanew);
    printf("nt:%x\n", file_buffer + Dos->e_lfanew);
    printf("nt--Signature:%x\n", Nt_Header->Signature);
    //nt指向fileheader
    printf("nt--FileHeader:%x\n", Nt_Header->FileHeader);
    //nt指向OptionalHeader
    printf("nt--OptionalHeader:%x\n", Nt_Header->OptionalHeader);
    //这里加4个字节越过nt--Signature,得到machine的位置
    printf("********************File_header********************\n");
    PIMAGE_FILE_HEADER File_header = (PIMAGE_FILE_HEADER)(file_buffer + Dos->e_lfanew + 4);
    printf("File_header---Machine:%x\n", File_header->Machine);
    printf("File_header---NumberOfSections:%x\n", File_header->NumberOfSections);
    printf("File_header---TimeDateStamp:%x\n", File_header->TimeDateStamp);
    printf("File_header---SizeOfOptionalHeader:%x\n", File_header->SizeOfOptionalHeader);
    printf("File_header---Characteristics:%x\n", File_header->Characteristics);
    //这里在fileheader 的基础上越过20个字节得到Option_header
    printf("********************Option_header********************\n");
    PIMAGE_OPTIONAL_HEADER Option_header = (PIMAGE_OPTIONAL_HEADER)(file_buffer + Dos->e_lfanew + 4 + 20);
    printf("Option_header---Magic:%x\n", Option_header->Magic);
    printf("Option_header---SizeOfCode:%x\n", Option_header->SizeOfCode);
    printf("Option_header---SizeOfInitializedData:%x\n", Option_header->SizeOfInitializedData);
    printf("Option_header---AddressOfEntryPoint:%x\n", Option_header->AddressOfEntryPoint);
    printf("Option_header---BaseOfCode:%x\n", Option_header->BaseOfCode);
    printf("Option_header---BaseOfData:%x\n", Option_header->BaseOfData);
    printf("Option_header---ImageBase:%x\n", Option_header->ImageBase);
    printf("Option_header---SectionAlignment:%x\n", Option_header->SectionAlignment);
    printf("Option_header---FileAlignment:%x\n", Option_header->FileAlignment);
    printf("Option_header---SizeOfHeaders:%x\n", Option_header->SizeOfHeaders);
    printf("Option_header---CheckSum:%x\n", Option_header->CheckSum);
    printf("Option_header---SizeOfStackReserve:%x\n", Option_header->SizeOfStackReserve);
    printf("Option_header---SizeOfStackCommit:%x\n", Option_header->SizeOfStackCommit);
    printf("Option_header---SizeOfHeapReserve:%x\n", Option_header->SizeOfHeapReserve);
    printf("Option_header---SizeOfHeapCommit:%x\n", Option_header->SizeOfHeapCommit);
    printf("Option_header---NumberOfRvaAndSizes:%x\n", Option_header->NumberOfRvaAndSizes);
    //这里重新指向开头
    //rewind(fp);
    //这里遍历节表
    printf("********************遍历节表********************\n");
    //首先获取有几个节表,通过NumberOfSections获取节表个数,获取节表起始位置,节表起始位置位于File_header---Characteristics
    //往后加E0个字节
    printf("节表个数:%x\n", File_header->NumberOfSections);
    printf("节表起始位置:%x\n", Dos + File_header->Characteristics + 0xE0);
    //我们通过windowsAPI------------IMAGE_FIRST_SECTION(pNtH)直接获得区块表的首地址
    //PIMAGE_SECTION_HEADER Section_Header = IMAGE_FIRST_SECTION(Nt_Header);
    //PIMAGE_SECTION_HEADER Section_Header = (PIMAGE_SECTION_HEADER)(Option_header + File_header->SizeOfOptionalHeader);
    printf("Option_header:%x\n", Option_header);
    printf("(DWORD)Option_header:%x\n", (DWORD)Option_header);
    //dword必须申明
    PIMAGE_SECTION_HEADER Section_Header = (PIMAGE_SECTION_HEADER)((DWORD)Option_header + File_header->SizeOfOptionalHeader);
    printf("Section_Header:%x\n", Section_Header);
    for (size_t i = 0; i < File_header->NumberOfSections; i++)
    {
        printf("\t-----------------------节表%d-----------------------\t\n", i+1);
        printf("Section_Header->Name名称:%s\n", Section_Header->Name);
        printf("Section_Header->Misc(内存中的大小--没对齐前的真实尺寸):%.8x\n", Section_Header->Misc);
        printf("Section_Header->VirtualAddress(内存中的地址,需要加上imagebase,内存中的偏移):%.8x\n", Section_Header->VirtualAddress);
        printf("Section_Header->SizeOfRawData(在文件中的尺寸,大小):%.8x\n", Section_Header->SizeOfRawData);
        printf("Section_Header->PointerToRawData(在文件中的偏移):%.8x\n", Section_Header->PointerToRawData);
        printf("Section_Header->PointerToRelocations(重定位表个数):%.8x\n", Section_Header->PointerToRelocations);
        printf("Section_Header->PointerToLinenumbers(行号表的位置):%.8x\n", Section_Header->PointerToLinenumbers);
        printf("Section_Header->NumberOfLinenumbers(行号数量):%.8x\n", Section_Header->NumberOfLinenumbers);
        printf("Section_Header->Characteristics(节属性):%.8x\n", Section_Header->Characteristics);
        Section_Header++;
    }
    free(file_buffer);
}
///20221120获取pe文件结构



int main(void)
{
    Funcation4();
    return 0;
}

 

标签:Option,Header,--,Section,节表,C语言,---,header,printf
From: https://www.cnblogs.com/0x200/p/16909218.html

相关文章

  • Java通过反射生成并操作对象
    Java通过反射生成并操作对象1.*使用反射生成并操作对象Class对象可以获得该类里的方法(由Method对象表示)、构造器(由Constructor对象表示)、Field(由Field对象表示),这3个类都......
  • 博弈论与强化学习 一 Minimax Q, Nash Q ,FFQ
    博弈解与强化学习二基础算法2.1引言一个随机博弈可以看成是一个多智能体强化学习过程,但其实这两个概念不能完全等价,随机博弈中假定每个状态的奖励矩阵是已知的,不需要......
  • 并发编程理论和进程理论
    目录一、并发编程理论操作系统发展史1、手工操作——穿孔卡片2、批处理——磁带存储1.联机批处理系统2.脱机批处理系统二、多道程序设计技术单道技术多道技术多道技术......
  • osgearth仿真平台之特效(4)
    osgearth特效主要是开发了圆锥波、菱形波、干扰、通信、爆炸等特效,因为特效开发起来比较麻烦,有时候在osg上效果很好,放到osgearth上效果就不行了,特效如下:卫星轨道的添加: ......
  • Windows 无法启动 VMware Authorization Service 服务
    错误提示:问题分析:出现“系统找不到指定的文件”,说明你的“vmware-authd.exe”文件(在你安装vmware的目录下找到这个文件)与服务中的VMwareAuthorizationService路径不......
  • Html:<a>标签中target的作用
    1.定义和用法:<a>标签的target属性规定在何处打开链接文档。如果在一个<a>标签内包含一个target属性,浏览器将会载入和显示用这个标签的href属性命名的、名称与这......
  • 决策树剪枝
    一、决策树剪枝1.目的  剪枝(pruning)是决策树学习算法解决过拟合问题的主要手段。  在决策树学习中,为了尽可能正确分类训练样本,节点划分过程将不断重复,有时会造成决......
  • 解决 虚拟机VMWARE AUTHORIZATION SERVICE未能启动的四种方法
    转载声明:https://www.freesion.com/article/6159299205/下面记录的方法可以挨个尝试一下.我先用了方式三,然后用了方式一.仅记录个人学习原由最近装系统装上瘾了,要测......
  • 各厂商服务器存储默认管理口登录信息(默认IP、用户名、密码)收集
    在此收集了一些厂商的服务器存储设备的默认管理口信息,以供大家日后运维时方便查找,若有错误的地方请指正,谢谢!服务器管理口信息:存储管理口信息: 光纤交换机管理口信息:......
  • 01.两数之和
    classSolution{publicint[]twoSum(int[]nums,inttarget){//暴力法for(inti=0;i<nums.length;i++){for(intj=i+1;j<num......