当前位置: 移动技术网 > 网络运营>安全>加解密 > pe结构学习心得(二)--获取pe头信息

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

2018年04月09日  | 移动技术网网络运营  | 我要评论
// 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;
}

作者 陈卫华

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网