飘云 发表于 2015-1-9 11:00:06

抛砖引玉-PE64简单解析代码

周五了,O(∩_∩)O哈哈~很久没进Windows了,开虚拟机随手写一段烂代码玩玩,纯属支持小Q x64版块~~~{:soso_e113:}


/*
winnt.h 中VS做了平台宏判断,所以直接用即可,不用刻意区分32、64

详见:
#ifdef _WIN64
typedef IMAGE_NT_HEADERS64                  IMAGE_NT_HEADERS;
typedef PIMAGE_NT_HEADERS64               PIMAGE_NT_HEADERS;
#else
typedef IMAGE_NT_HEADERS32                  IMAGE_NT_HEADERS;
typedef PIMAGE_NT_HEADERS32               PIMAGE_NT_HEADERS;
#endif
*/

/*
PE64 简单解析 By 飘云/P.Y.G
2015-01-09
https://www.chinapyg.com
*/

#include <stdio.h>
#include <windows.h>

int main()
{
      FILE *fp;
      char szFileName;

      IMAGE_DOS_HEADER DOS_Header;                        // DOS头结构
      IMAGE_NT_HEADERS NT_Header;                              // PE头结构
      IMAGE_SECTION_HEADER *lpSection_Header;      // 区段表结构指针

      printf("请输入文件路径:");
      gets(szFileName);

      fp = fopen(szFileName, "rb");
      if(!fp)
      {
                printf("\n--打开文件出错,请重试!\n");
                getchar();
                exit(0);
      }

      printf("\n--------------------PE基本信息-------------------\n");
      // 读取Dos头
      fread(&DOS_Header, sizeof(IMAGE_DOS_HEADER), 1, fp);

      // 验证PE合法性
      if (DOS_Header.e_magic != IMAGE_DOS_SIGNATURE)
      {
                printf("--非PE文件!\n");      
                fclose(fp);
                getchar();
                exit(0);
      }

      // PE头偏移
      printf("PE头偏移:0x%.2X\n", DOS_Header.e_lfanew);

      // 定位到PE头
      fseek(fp, DOS_Header.e_lfanew, 0);
      // 读取PE头数据
      fread(&NT_Header, sizeof(IMAGE_NT_HEADERS), 1, fp);

      // 继续验证PE合法性
      if(NT_Header.Signature != IMAGE_NT_SIGNATURE)
      {
                printf("--非PE文件!\n");
                fclose(fp);
                getchar();
                exit(0);
      }

      printf("区段数量:0x%.2X\n", NT_Header.FileHeader.NumberOfSections);
      printf("入 口 点:0x%.8X\n", NT_Header.OptionalHeader.AddressOfEntryPoint);
      printf("镜像基址:0x%.16X\n", NT_Header.OptionalHeader.ImageBase);
      printf("镜像大小:0x%.8X\n", NT_Header.OptionalHeader.SizeOfImage);
      
      printf("\n------------------各区段详细信息-----------------\n\n");

      // 定位到区段首地址
      fseek(fp, DOS_Header.e_lfanew + sizeof(IMAGE_NT_SIGNATURE) + NT_Header.FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER), 0);
      lpSection_Header = new IMAGE_SECTION_HEADER;
      // 读取区段数据
      fread(lpSection_Header, NT_Header.FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER), 1, fp);

      printf("Name      Offset         V.Addr          V.Size   R.Size   Flags\n");
      printf("-------------------------------------------------\n");
      for(int i = 0; i<NT_Header.FileHeader.NumberOfSections; i++)
      {
                printf("%s      ", lpSection_Header.Name);
                printf("%.8X ", lpSection_Header.PointerToRawData);
                printf("%.8X ", lpSection_Header.VirtualAddress);
                printf("%.8X ", lpSection_Header.Misc.VirtualSize);
                printf("%.8X ", lpSection_Header.SizeOfRawData);
                printf("%.8X \n", lpSection_Header.Characteristics);
      }
      fclose(fp);
      getchar();
      return 0;
}

Dxer 发表于 2015-1-9 12:34:59

正在转向64位。谢谢飘哥 分享代码

LIwianwpIO 发表于 2015-1-9 13:50:50

多谢坛主分享

lcy925 发表于 2015-1-9 14:37:03

高手!
学习……

Crack_Qs 发表于 2015-1-9 14:55:12

感谢飘哥分享

gujin162 发表于 2015-1-9 15:25:56


果断回帖,如果沉了就是我弄沉的很有成就感。

lucky_789 发表于 2015-1-9 19:23:20

学习了{:soso_e179:}

small-q 发表于 2015-1-11 08:17:31

{:soso_e179:}嘿嘿,又多了一份精品

yuzhenyujia 发表于 2015-4-9 15:56:27

马上学习飘大的作品

Bunken 发表于 2017-6-1 11:39:13

感谢飘哥,向飘哥学习
页: [1]
查看完整版本: 抛砖引玉-PE64简单解析代码