【滴水逆向三期41作业】C语言提取文件PE头部信息

简介: 【滴水逆向三期41作业】C语言提取文件PE头部信息

这里给出的提取文件PE头部信息到控制台的代码:

// PETool自编版.cpp : Defines the entry point for the console application.
//
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <malloc.h>
#include "Function.h"
int main(int argc, char* argv[]){
  FILE *fp1,*fp2;
  int File_length,choose1,choose2;
  DWORD i=1,j=0;
  char *File_Buffer;
  char Filename[20];
  printf("***************************欢迎使用PETool自编版***************************\n");
  //用户输入
  //printf("请输入想要查看的文件(exe文件):");
  //打开文件
  fp1=File_open(Filename);
  //计算文件大小
  File_length=File_size(fp1);
  //申请内存
  File_Buffer=File_malloc(File_length);
  //向内存缓冲区写入数据
  if(File_read(File_Buffer,1,File_length,fp1)){
  printf("向内存缓冲区写入数据成功!\n");
  }else{
    printf("写入数据失败!\n");
  }
  //用户选择
  printf("***********************1.在控制台输出PE头信息。***************************\n");
  //printf("***********************2.将PE头信息保存到txt文件中(暂时不可用)。********\n");
  printf("请输入您需要的项目:"); 
  scanf("%d",&choose1);
  printf("**************************1.输出所有PE头部信息。**************************\n");
  printf("**************************2.输出DOS头信息。    ***************************\n");
  printf("**************************3.输出标准PE头部信息。**************************\n");
  printf("**************************4.输出可选PE头部信息。**************************\n");
  printf("**************************5.节表信息。          **************************\n");
  printf("请选择您要输出的项目:");
  scanf("%d",&choose2); 
  //实例化结构体
  IMAGE_DOS_HEADER pDosHeader;
  IMAGE_NT_HEADERS pNTHeader;
  IMAGE_SECTION_HEADER pSectionHeader;
  switch (choose1){
    case 1:{
      switch(choose2){
        case 2:{
          //输出DOS头部
          pDosHeader=*(IMAGE_DOS_HEADER*)File_Buffer;
          printf("********************************DOS头部********************************\n");
          printf("e_magic(MZ标志):   0x%x\n",pDosHeader.e_magic);
          printf("e_lfanew(PE偏移):  0x%x\n\n",pDosHeader.e_lfanew);
          break;
        }
        case 1:{
          //输出DOS头部
          pDosHeader=*(IMAGE_DOS_HEADER*)File_Buffer;
          printf("********************************DOS头部********************************\n");
          printf("e_magic(MZ标志):   0x%x\n",pDosHeader.e_magic);
          printf("e_lfanew(PE偏移):  0x%x\n\n",pDosHeader.e_lfanew);
          }
        case 3:{
          //输出标准PE头部
          if(*((PDWORD)((DWORD)File_Buffer+pDosHeader.e_lfanew)) == IMAGE_NT_SIGNATURE){
            printf("经检测是有效的PE标志(有效的PE文件)。\n\n");
          }else{
            printf("不是有效的PE标志!\n"); 
            free(File_Buffer);
          }
          pNTHeader=*(IMAGE_NT_HEADERS*)(File_Buffer+pDosHeader.e_lfanew);
          printf("****************************标准PE头部信息*****************************\n");
          printf("Machine(运行平台):               0x%x\n",pNTHeader.FileHeader.Machine);
          printf("NumberOfSections(区块的数量):    0x%x\n",pNTHeader.FileHeader.NumberOfSections);
          printf("TimeDataStap(时间戳):            0x%x\n",pNTHeader.FileHeader.TimeDateStamp);
          printf("SizeOfOptionalHeader(可选PE头的大小):  0x%x\n",pNTHeader.FileHeader.SizeOfOptionalHeader);
          printf("Characteristics(特征/特性):      0x%x\n\n",pNTHeader.FileHeader.Characteristics);
          if(choose2==3)break;
        }
        case 4:{
          printf("****************************可选PE头部信息*****************************\n");
          printf("Magic()     0x%d",pNTHeader.OptionalHeader.Magic);
          printf("AddressOfEntryPoint(程序入口RVA)     0x%d\n",pNTHeader.OptionalHeader.AddressOfEntryPoint);
          printf("ImageBase(内存镜像基址)                0x%d\n",pNTHeader.OptionalHeader.ImageBase);
          printf("SectionAlignment(内存对齐大小)                0x%d\n",pNTHeader.OptionalHeader.SectionAlignment);
          printf("FileAlignment(文件对齐大小)                0x%d\n",pNTHeader.OptionalHeader.FileAlignment);
          printf("SizeOfImage(映像装入内存后的大小)                0x%d\n",pNTHeader.OptionalHeader.SizeOfImage);
          printf("SizeOfHeaders(所有头按照文件对齐后的大小和)                0x%d\n\n",pNTHeader.OptionalHeader.SizeOfHeaders);
          if(choose2==4)break;
        }
        case 5:{
          printf("*****************************节表信息**********************************\n");
          //i=(DWORD)i;
          pDosHeader=*(IMAGE_DOS_HEADER*)File_Buffer;
          pNTHeader=*(IMAGE_NT_HEADERS*)(File_Buffer+pDosHeader.e_lfanew);
          pSectionHeader=*(IMAGE_SECTION_HEADER*)((DWORD)File_Buffer+pDosHeader.e_lfanew+20+pNTHeader.FileHeader.SizeOfOptionalHeader);
          for(i=1;i<=pNTHeader.FileHeader.NumberOfSections;i++){
            printf("*****************************第%d个节表信息*****************************\n",i);
            printf("name(名称):         %c",pSectionHeader.Name);
            for(j = 1;j<IMAGE_SIZEOF_SHORT_NAME+1;j++)
            { 
              printf("%c",pSectionHeader.Name[j]);
            }
            printf("\nMisc(区块的数据没有对齐前的实际大小):         %x\n",pSectionHeader.Misc.VirtualSize);
            printf("VirtualAddress(该块装在到内存的RVA):          %x\n",pSectionHeader.VirtualAddress);
            printf("SizeOfRvaData(该块在磁盘文件中所占大小):      %x\n",pSectionHeader.SizeOfRawData);
            printf("PointToRvaDta(该块在磁盘文件中的偏移):        %x\n",pSectionHeader.PointerToRawData);
            printf("Characteristics(块属性):                      %x\n\n",pSectionHeader.Characteristics);
            pSectionHeader=*(((IMAGE_SECTION_HEADER*)((DWORD)File_Buffer+pDosHeader.e_lfanew+(DWORD)20+pNTHeader.FileHeader.SizeOfOptionalHeader))+i);
          }
          if(choose2=5)break; 
        } 
      }
    }
  }
  return 0;
}

代码中还有许多可优化的地方,希望大家指出,我会非常虚心地听取大家的建议,希望我们能共同进步!

相关文章
|
29天前
|
存储 编译器 C语言
如何在 C 语言中判断文件缓冲区是否需要刷新?
在C语言中,可以通过检查文件流的内部状态或使用`fflush`函数尝试刷新缓冲区来判断文件缓冲区是否需要刷新。通常,当缓冲区满、遇到换行符或显式调用`fflush`时,缓冲区会自动刷新。
|
29天前
|
存储 编译器 C语言
C语言:文件缓冲区刷新方式有几种
C语言中文件缓冲区的刷新方式主要包括三种:自动刷新(如遇到换行符或缓冲区满)、显式调用 fflush() 函数强制刷新、以及关闭文件时自动刷新。这些方法确保数据及时写入文件。
|
1月前
|
C语言
【C语言】探索文件读写函数的全貌(三)
【C语言】探索文件读写函数的全貌
|
1月前
|
存储 C语言
【C语言】探索文件读写函数的全貌(二)
【C语言】探索文件读写函数的全貌
|
1月前
|
C语言
【C语言】探索文件读写函数的全貌(一)
【C语言】探索文件读写函数的全貌
|
1月前
|
存储 文件存储 C语言
【C语言】深入了解文件:简明指南
【C语言】深入了解文件:简明指南
|
2月前
|
Linux C语言
C语言 文件IO (系统调用)
本文介绍了Linux系统调用中的文件I/O操作,包括文件描述符、`open`、`read`、`write`、`lseek`、`close`、`dup`、`dup2`等函数,以及如何获取文件属性信息(`stat`)、用户信息(`getpwuid`)和组信息(`getgrgid`)。此外还介绍了目录操作函数如`opendir`、`readdir`、`rewinddir`和`closedir`,并提供了相关示例代码。系统调用直接与内核交互,没有缓冲机制,效率相对较低,但实时性更高。
|
3月前
|
存储 C语言
【c语言】职工信息管理系统 包含读取写入txt文件,职工信息的增删改查
【c语言】职工信息管理系统 包含读取写入txt文件,职工信息的增删改查
|
3月前
|
存储 自然语言处理 程序员
【C语言】文件的编译链接和预处理
【C语言】文件的编译链接和预处理
|
3月前
|
存储 数据可视化 C语言
【C语言】C语言-学生籍贯信息记录系统(源码+论文)【独一无二】
【C语言】C语言-学生籍贯信息记录系统(源码+论文)【独一无二】