欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

pe结构学习心得(二)--获取pe头信息

程序员文章站 2022-07-10 09:55:18
// PeHeaders.cpp : 定义控制台应用程序的入口点。 //   #include "stdafx.h" #include
// PeHeaders.cpp : 定义控制台应用程序的入口点。
//
 
#include "stdafx.h"
#include <windows.h>
#include <time.h>
#include <imagehlp.h>
#pragma comment (lib, "imagehlp.lib") 
 
int _tmain(int argc, _TCHAR* argv[])
{
  while (TRUE) {
    WCHAR cFile[256] = {0};
    printf("Please enter the file name and path:");
    wscanf(L"%s",cFile);
 
    HANDLE hFile = NULL;
    hFile = ::CreateFile((LPCWSTR)cFile,GENERIC_READ,0,NULL,OPEN_EXISTING,NULL,NULL); 
    if (hFile == INVALID_HANDLE_VALUE){
      printf("Create file failed! (%d).\n\n", GetLastError());
      system("pause");
      return 0;
    }
 
    //创建文件映射
    HANDLE hMap = NULL;
    hMap = ::CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,0);
    if (!hMap){
      printf("Create file mapping failed! (%d).\n\n", GetLastError());
      system("pause");
      return 0;
    }
 
    //映射进自己的进程空间
    LPVOID pMap = NULL;
 
    pMap = ::MapViewOfFile(hMap,FILE_MAP_READ,0,0,0);
    if (!pMap){
      printf("Mapping file failed (%d).\n\n", GetLastError());
      system("pause");
      return 0;
    }
   
    //获得DOS头文件指针
    PIMAGE_DOS_HEADER pDosHeader = NULL;//DOS头文件
    pDosHeader = (PIMAGE_DOS_HEADER)pMap;
   
    //判断DOS头标志IMAGE_DOS_SIGNATURE 0x5A4D MZ
    if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE){
      printf("Not DOS Header! (%d).\n\n", GetLastError());  
      system("pause");
      return 0;
    }
   
    //获得PE头文件指针
    PIMAGE_NT_HEADERS pPeHeaders = NULL;//PE头文件
    pPeHeaders = (PIMAGE_NT_HEADERS)((LONG)pMap + pDosHeader->e_lfanew);
 
    //判断PE头标志IMAGE_NT_SIGNATURE 0x00004550 PE00
    if (pPeHeaders->Signature != IMAGE_NT_SIGNATURE){
      printf("Not PE Header! (%d).\n\n", GetLastError());
      system("pause");
      return 0;
    }
 
    //打印是否PE32还是PE32+或者ROM
    if (pPeHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC){
      printf("PE32\n");
    }
    else if(pPeHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC){
      printf("PE32+\n");
    } 
    else if(pPeHeaders->OptionalHeader.Magic == IMAGE_ROM_OPTIONAL_HDR_MAGIC){
      printf("ROM\n");
    }
    else{
      printf("Unknow!\n\n");
    }
 
    //打印可执行文件的目标CPU类型
    switch (pPeHeaders->FileHeader.Machine) {
 
      case IMAGE_FILE_MACHINE_I386:
        printf("CUP Type: Intel 386\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_R3000:
        printf("CUP Type: MIPS little-endian, 0x160 big-endian\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_R4000:
        printf("CUP Type: MIPS little-endian\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_R10000:
        printf("CUP Type: MIPS little-endian\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_WCEMIPSV2:
        printf("CUP Type: MIPS little-endian WCE v2\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_ALPHA:
        printf("CUP Type: Alpha_AXP\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_SH3:
        printf("CUP Type: SH3 little-endian\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_SH3DSP:
        printf("CUP Type: SH3E little-endian\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_SH3E:
        printf("CUP Type: Intel 386\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_SH4:
        printf("CUP Type: SH4 little-endian\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_SH5:
        printf("CUP Type: SH5\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_ARM:
        printf("CUP Type: ARM Little-Endian\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_THUMB:
        printf("CUP Type: THUMB\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_AM33:
        printf("CUP Type: AM33\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_POWERPC:
        printf("CUP Type: IBM PowerPC Little-Endian\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_POWERPCFP:
        printf("CUP Type: POWERPCFP\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_IA64:
        printf("CUP Type: Intel 64\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_MIPS16:
        printf("CUP Type: MIPS16\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_ALPHA64:
        printf("CUP Type: ALPHA64\n\n");
        break;
 
        case IMAGE_FILE_MACHINE_MIPSFPU:
        printf("CUP Type: MIPSFPU\n\n");
        break;
 
      /*case IMAGE_FILE_MACHINE_AXP64:
        printf("CUP Type: AXP64\n\n");
        break;*/
 
      case IMAGE_FILE_MACHINE_TRICORE:
        printf("CUP Type: TRICORE\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_CEF:
        printf("CUP Type: CEF\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_EBC:
        printf("CUP Type: EFI Byte Code\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_AMD64:
        printf("CUP Type: AMD64 (K8)\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_M32R:
        printf("CUP Type: M32R little-endian\n\n");
        break;
 
      case IMAGE_FILE_MACHINE_CEE:
        printf("CUP Type: CEE\n\n");
        break;
 
      default:
        printf("CUP Type: UNKNOWN\n\n");
        break;
    }
 
   
    //打印PE头信息IMAGE_NT_HEADERS
    printf("|--PE HEADERS\n"
      "\t|--DWORD\tpPeHeaders.Signature:\t0x%08x\t(%s)\n" \
      //pPeHeaders.FileHeader
      "\t|--STRUCT\tpPeHeaders.FileHeader\n" \
      "\t\t|--WORD\t\tMachine:\t\t0x%08x\n" \
      "\t\t|--WORD\t\tNumberOfSections:\t0x%08x\n" \
      "\t\t|--DWORD\tTimeDateStamp:\t\t0x%08x\n" \
      "\t\t|--DWORD\tPointerToSymbolTable:\t0x%08x\n" \
      "\t\t|--DWORD\tNumberOfSymbols:\t0x%08x\n" \
      "\t\t|--WORD\t\tSizeOfOptionalHeader:\t0x%08x\n" \
      "\t\t|--WORD\t\tCharacteristics:\t0x%08x\n" \
      //pPeHeaders.OptionalHeader
      "\t|--STRUCT\tpPeHeaders.OptionalHeader\n" \
      "\t\t|--WORD\t\tMagic:\t\t\t\t0x%08x\n" \
      "\t\t|--WORD\t\tMajorLinkerVersion:\t\t0x%08x\n" \
      "\t\t|--DWORD\tMinorLinkerVersion:\t\t0x%08x\n" \
      "\t\t|--DWORD\tSizeOfCode:\t\t\t0x%08x\n" \
      "\t\t|--DWORD\tSizeOfInitializedData:\t\t0x%08x\n" \
      "\t\t|--WORD\t\tSizeOfUninitializedData:\t0x%08x\n" \
      "\t\t|--WORD\t\tAddressOfEntryPoint:\t\t0x%08x\n" \
      "\t\t|--WORD\t\tBaseOfCode:\t\t\t0x%08x\n" \
      "\t\t|--WORD\t\tBaseOfData:\t\t\t0x%08x\n" \
      "\t\t|--DWORD\tImageBase:\t\t\t0x%08x\n" \
      "\t\t|--DWORD\tSectionAlignment:\t\t0x%08x\n" \
      "\t\t|--DWORD\tFileAlignment:\t\t\t0x%08x\n" \
      "\t\t|--WORD\t\tMajorOperatingSystemVersion:\t0x%08x\n" \
      "\t\t|--WORD\t\tMinorOperatingSystemVersion:\t0x%08x\n" \
      "\t\t|--WORD\t\tMajorImageVersion:\t\t0x%08x\n" \
      "\t\t|--WORD\t\tMinorImageVersion:\t\t0x%08x\n" \
      "\t\t|--DWORD\tMajorSubsystemVersion:\t\t0x%08x\n" \
      "\t\t|--DWORD\tMinorSubsystemVersion:\t\t0x%08x\n" \
      "\t\t|--DWORD\tWin32VersionValue:\t\t0x%08x\n" \
      "\t\t|--WORD\t\tSizeOfImage:\t\t\t0x%08x\n" \
      "\t\t|--WORD\t\tSizeOfHeaders:\t\t\t0x%08x\n" \
      "\t\t|--WORD\t\tCheckSum:\t\t\t0x%08x\n" \
      "\t\t|--WORD\t\tSubsystem:\t\t\t0x%08x\n" \
      "\t\t|--DWORD\tDllCharacteristics:\t\t0x%08x\n" \
      "\t\t|--DWORD\tSizeOfStackReserve:\t\t0x%08x\n" \
      "\t\t|--DWORD\tSizeOfStackCommit:\t\t0x%08x\n" \
      "\t\t|--WORD\t\tSizeOfHeapReserve:\t\t0x%08x\n" \
      "\t\t|--WORD\t\tSizeOfHeapCommit:\t\t0x%08x\n" \
      "\t\t|--WORD\t\tLoaderFlags:\t\t\t0x%08x\n" \
      "\t\t|--WORD\t\tNumberOfRvaAndSizes:\t\t0x%08x\n",
      //pPeHeaders.Signature
      pPeHeaders->Signature,&pPeHeaders->Signature,               // PE,0,0
      //pPeHeaders.FileHeader
      pPeHeaders->FileHeader.Machine,             // 文件运行所要求的CPU平台
      pPeHeaders->FileHeader.NumberOfSections,         // 文件的节数目
      pPeHeaders->FileHeader.TimeDateStamp,         // 文件创建日期和时间
      pPeHeaders->FileHeader.PointerToSymbolTable,       // 用于调试
      pPeHeaders->FileHeader.NumberOfSymbols,         // 用于调试
      pPeHeaders->FileHeader.SizeOfOptionalHeader,       // 指示紧随本结构之后的OptionalHeader结构大小,必须为有效值
      pPeHeaders->FileHeader.Characteristics,         // 文件信息标志
      //pPeHeaders.OptionalHeader 
      pPeHeaders->OptionalHeader.Magic,           // 标记
      pPeHeaders->OptionalHeader.MajorLinkerVersion,     // 链接器的主版本号
      pPeHeaders->OptionalHeader.MinorLinkerVersion,     // 链接器的次版本号
      pPeHeaders->OptionalHeader.SizeOfCode,         // 可执行代码的长度
      pPeHeaders->OptionalHeader.SizeOfInitializedData,   // 初始化数据的长度(数据段)
      pPeHeaders->OptionalHeader.SizeOfUninitializedData,   // 未初始化数据的长度(bss段)
      pPeHeaders->OptionalHeader.AddressOfEntryPoint,     // 代码的入口RVA地址,程序从这儿开始执行
      pPeHeaders->OptionalHeader.BaseOfCode,         // 可执行代码起始位置
      pPeHeaders->OptionalHeader.BaseOfData,         // 初始化数据起始位置
      pPeHeaders->OptionalHeader.ImageBase,         // 载入程序首选的VA地址
      pPeHeaders->OptionalHeader.SectionAlignment,       // 段加载后在内存中的对齐方式
      pPeHeaders->OptionalHeader.FileAlignment,       // 段在文件中的对齐方式
      pPeHeaders->OptionalHeader.MajorOperatingSystemVersion, // 操作系统主版本号
      pPeHeaders->OptionalHeader.MinorOperatingSystemVersion, // 操作系统次版本号
      pPeHeaders->OptionalHeader.MajorImageVersion,     // 程序主版本号
      pPeHeaders->OptionalHeader.MinorImageVersion,     // 程序次版本号
      pPeHeaders->OptionalHeader.MajorSubsystemVersion,   // 子系统主版本号
      pPeHeaders->OptionalHeader.MinorSubsystemVersion,   // 子系统次版本号
      pPeHeaders->OptionalHeader.Win32VersionValue,     // 目前都为0
      pPeHeaders->OptionalHeader.SizeOfImage,         // 程序调入后占用内存大小(字节),等于所有段的长度之和
      pPeHeaders->OptionalHeader.SizeOfHeaders,       // 所有文件头的长度之和(从文件开始到第一个段之间的大小)
      pPeHeaders->OptionalHeader.CheckSum,           // 校验和
      pPeHeaders->OptionalHeader.Subsystem,         // NT子系统
      pPeHeaders->OptionalHeader.DllCharacteristics,     // Dll状态
      pPeHeaders->OptionalHeader.SizeOfStackReserve,     // 保留堆栈大小
      pPeHeaders->OptionalHeader.SizeOfStackCommit,     // 启动后实际申请的堆栈数,可随实际情况变大
      pPeHeaders->OptionalHeader.SizeOfHeapReserve,     // 保留堆大小
      pPeHeaders->OptionalHeader.SizeOfHeapCommit,       // 实际堆大小
      pPeHeaders->OptionalHeader.LoaderFlags,         // 装载标志
      pPeHeaders->OptionalHeader.NumberOfRvaAndSizes);     // 下面的目录表入口个数
     //打印IMAGE_DATA_DIRECTORY结构
     printf("\t\t|--STRUCT\tpPeHeaders.OptionalHeader.DataDirectory\n");
     for (int i=0;i<IMAGE_NUMBEROF_DIRECTORY_ENTRIES;i++){
     printf("\t\t\t|--STRUCT\tDataDirectory[%d]\n" \
      "\t\t\t\t|--WORD\tVirtualAddress:\t0x%08x\n" \
      "\t\t\t\t|--WORD\tSize:\t\t0x%08x\n" ,
      i,
      pPeHeaders->OptionalHeader.DataDirectory[i].VirtualAddress,
      pPeHeaders->OptionalHeader.DataDirectory[i].Size);
     }
 
     printf("\n");
   
     //关闭打开的句柄,释放资源
    ::UnmapViewOfFile(pMap);
    ::CloseHandle(hMap);
    ::CloseHandle(hFile);
  }
 
  system("pause");
  return 0;
}

作者 陈卫华