吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4082|回复: 4
收起左侧

[其他原创] 一个简易版的 PE View

[复制链接]
Aperodry 发表于 2017-10-4 15:17
没什么技术含量,就是学习PE结构写的一个小工具 捕获.PNG



[C] 纯文本查看 复制代码
]// PE View.cpp : 定义控制台应用程序的入口点。
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 头文件
#include "stdafx.h"
#include "stdio.h"
#include <time.h> 
#include <malloc.h>
#include <Shlwapi.h>
#include <Windows.h>
#pragma comment( lib, "Shlwapi.lib")
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 定义声明
using namespace std;

void GetMachine(WORD wMachine);//打印运行平台
void stamp_to_standard(int stampTime);//时间戳到标准时间
DWORD RVAToRAW(DWORD dwRVA);//转换到文件偏移
FILE *fpPeFile;
_TCHAR szFileName[MAX_PATH] = {0};
IMAGE_DOS_HEADER DosHander;
IMAGE_NT_HEADERS32 NtHander32;	//x32 NT头
PIMAGE_SECTION_HEADER pSectionHander;//节区头指针

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//开始位置
int _tmain(int argc, _TCHAR* argv[])
{
#if _DEBUG	//调试环境下读取自身
argv[1] = argv[0];
argc = 2;
#endif

////////////////////////////////////////////
if (argc < 2)
{
printf("Not File Analysis\n");
system("pause");
exit(EXIT_FAILURE);
}
SetConsoleTitle(argv[1]);
strcpy_s(szFileName, argv[1]);
PathStripPath(szFileName);//取文件名
fopen_s(&fpPeFile, argv[1], "rb");// 以二进制方式打开文件
if (!fpPeFile)
{
fprintf (stderr, "Error Open File \n");
exit (EXIT_FAILURE);
}
fread_s(&DosHander.e_magic,sizeof(DosHander), 1, sizeof(DosHander), fpPeFile);//读取DOS头
if (DosHander.e_magic!=IMAGE_DOS_SIGNATURE)//DOS 签名 "MZ"
{
fprintf(stderr, "Error Dos e_magic \n");
exit(EXIT_FAILURE);
}

fseek (fpPeFile, DosHander.e_lfanew, SEEK_SET);//移动文件指针到NT头
fread_s(&NtHander32.Signature,sizeof(NtHander32), 1, sizeof(NtHander32), fpPeFile);//读取NT头

if (NtHander32.Signature!=IMAGE_NT_SIGNATURE)//签名 "PE"
{
fprintf(stderr, "Error Signature \n");
exit(EXIT_FAILURE);
}
//fseek(fpPeFile, sizeof(NtHander32), SEEK_CUR);//移动文件指针到节区头
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//打印PE信息
printf("File Name:%s \n", szFileName);//文件名

if (NtHander32.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)	//PE
{
printf("File Type: PE \n");
} else if (NtHander32.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC){	//PE+
printf("File Type: PE++ \n");
}

GetMachine(NtHander32.FileHeader.Machine);//运行平台
printf("ImageBase:%08X\n", NtHander32.OptionalHeader.ImageBase);//基址
printf("EntryPoint:%08X\n", NtHander32.OptionalHeader.AddressOfEntryPoint);//入口地址
printf("SizeOfHeaders%08X\n",NtHander32.OptionalHeader.SizeOfHeaders);//PE大小
printf("SectionAlignment:%08X\n",NtHander32.OptionalHeader.SectionAlignment);//节区在内存中对齐大小
printf("FileAlignment%08X\n", NtHander32.OptionalHeader.FileAlignment);//节区在文件中对齐大小
stamp_to_standard(NtHander32.FileHeader.TimeDateStamp);//时间戳打印标准时间
printf("\n==================================SectionS=======================================\n=");
//申请区段内存
pSectionHander = (IMAGE_SECTION_HEADER*)malloc(NtHander32.FileHeader.NumberOfSections*sizeof(IMAGE_SECTION_HEADER));
printf("\tName\t\tRVA\t\tV.Size\t\tOffset\t\tR.size\t=\n");
for (int i = 0; i < NtHander32.FileHeader.NumberOfSections; i++)//区段数量
{
//fread_s(&SectionHander, sizeof(SectionHander), 1, sizeof(SectionHander), fpPeFile);//读取节区头
fread_s(&pSectionHander[i], sizeof(IMAGE_SECTION_HEADER), 1, sizeof(IMAGE_SECTION_HEADER), fpPeFile);
printf("=\t%-8s\t", pSectionHander[i].Name);//MSDN定义 8BYTE
printf("%X\t\t", pSectionHander[i].VirtualAddress);
printf("%X\t\t",pSectionHander[i].Misc.VirtualSize);
printf("%X\t\t",pSectionHander[i].PointerToRawData);
printf("%X\t=\n",pSectionHander[i].SizeOfRawData);
}
printf("==================================Section End====================================\n");
system("pause");
free(pSectionHander);
fclose(fpPeFile);//关闭文件
return 0;
}

void GetMachine(WORD wMachine)
{
_TCHAR szType[50];
if (wMachine==IMAGE_FILE_MACHINE_UNKNOWN)
strcpy_s(szType, "Machine: Unknwn \n");
else if (wMachine==IMAGE_FILE_MACHINE_I386)
strcpy_s(szType, "Machine: Intel x86 \n");
else if (wMachine==IMAGE_FILE_MACHINE_IA64)
strcpy_s(szType, "Machine: Intel x64 \n");
else if (wMachine==IMAGE_FILE_MACHINE_AMD64)
strcpy_s(szType, "Machine: AMD64 (K8) \n");
printf("%s", szType);
//cout << szType;
//其他未补充
/*
#define IMAGE_FILE_MACHINE_UNKNOWN 0
#define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386.
#define IMAGE_FILE_MACHINE_R3000 0x0162 // MIPS little-endian, 0x160 big-endian
#define IMAGE_FILE_MACHINE_R4000 0x0166 // MIPS little-endian
#define IMAGE_FILE_MACHINE_R10000 0x0168 // MIPS little-endian
#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 // MIPS little-endian WCE v2
#define IMAGE_FILE_MACHINE_ALPHA 0x0184 // Alpha_AXP
#define IMAGE_FILE_MACHINE_SH3 0x01a2 // SH3 little-endian
#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3
#define IMAGE_FILE_MACHINE_SH3E 0x01a4 // SH3E little-endian
#define IMAGE_FILE_MACHINE_SH4 0x01a6 // SH4 little-endian
#define IMAGE_FILE_MACHINE_SH5 0x01a8 // SH5
#define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian
#define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian
#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian
#define IMAGE_FILE_MACHINE_AM33 0x01d3
#define IMAGE_FILE_MACHINE_POWERPC 0x01F0 // IBM PowerPC Little-Endian
#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1
#define IMAGE_FILE_MACHINE_IA64 0x0200 // Intel 64
#define IMAGE_FILE_MACHINE_MIPS16 0x0266 // MIPS
#define IMAGE_FILE_MACHINE_ALPHA64 0x0284 // ALPHA64
#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 // MIPS
#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 // MIPS
#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64
#define IMAGE_FILE_MACHINE_TRICORE 0x0520 // Infineon
#define IMAGE_FILE_MACHINE_CEF 0x0CEF
#define IMAGE_FILE_MACHINE_EBC 0x0EBC // EFI Byte Code
#define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8)
#define IMAGE_FILE_MACHINE_M32R 0x9041 // M32R little-endian
#define IMAGE_FILE_MACHINE_CEE 0xC0EE*/
}
typedef struct times
{
int Year;	//年
int Mon;	//月
int Day;	//日
int Hour;	//时
int Min;	//分
int Second;	//秒
}Times;

void stamp_to_standard(int stampTime)
{
time_t tick = (time_t)stampTime;
struct tm tm;
char s[100];
Times standard;

//tick = time(NULL);
localtime_s(&tm,&tick);
strftime(s, sizeof(s), "Create Date: %Y-%m-%d %H:%M:%S", &tm);
printf("%s\n", s);


standard.Year = atoi(s);
standard.Mon = atoi(s + 5);
standard.Day = atoi(s + 8);
standard.Hour = atoi(s + 11);
standard.Min = atoi(s + 14);
standard.Second = atoi(s + 17);

/*wsprintf(szBuffer, "%d-%d-%d %d:%d:%d", 
standard.Year, 
standard.Mon, 
standard.Day, 
standard.Hour, 
standard.Min, 
standard.Second);*/
}


IAT和EAT的话用这个函数获取到它的RVA 在转换到RAW读取就是了

[C] 纯文本查看 复制代码
]//转换到文件偏移
DWORD RVAToRAW(DWORD dwRVA)
{
DWORD dwOffset;
DWORD dwRAW;
for (int i = 1; i < NtHander32.FileHeader.NumberOfSections; i++)
{
if (pSectionHander[i].VirtualAddress>dwRVA&&i>0)
{
if (pSectionHander[i-1].VirtualAddress<=dwRVA)
{
//	//RAW=RVA-VirtualAddress+PointerToRawData
dwOffset = dwRVA - pSectionHander[i-1].VirtualAddress;
dwRAW = dwOffset + pSectionHander[i-1].PointerToRawData;
return dwRAW;
}
}
}
return -1;
}


如获得INI表第一个函数名就这样写:

[C] 纯文本查看 复制代码
//设置文件指针为导入表起始地址
fseek(fpPeFile, RVAToRAW(NtHander32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress), SEEK_SET);
//读取导入表
fread_s(&ImportDescpiptor, sizeof(IMAGE_IMPORT_DESCRIPTOR), 1, sizeof(IMAGE_IMPORT_DESCRIPTOR), fpPeFile);
dwThunkINI = RVAToRAW(ImportDescpiptor.OriginalFirstThunk);
//设置文件指针为INI地址
fseek(fpPeFile, dwThunkINI, SEEK_SET);
DWORD addr;
fread_s(&addr, sizeof(addr), 1, sizeof(addr), fpPeFile);
addr = RVAToRAW(addr);
fseek(fpPeFile, addr, SEEK_SET);
struct MyStruct
{
WORD Hint;
CHAR Name[20];
}TEST;
fread_s(&TEST, sizeof(TEST), 1, sizeof(TEST), fpPeFile);
printf("%s\n", TEST.name);

到时候我整理一下个人学习PE结构的资料分享给各位坛友!!

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

yxk67888 发表于 2017-10-4 15:42
学习学习,楼主辛苦
cxj98 发表于 2017-10-4 16:06
【开★心快乐】 发表于 2017-10-4 18:32
wax126 发表于 2017-10-6 06:27 来自手机
楼主原创的吗?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-14 23:14

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表