首页
论坛
课程
招聘
[原创]PE文件学习之 编写PE文件分析工具
2008-12-17 17:42 34652

[原创]PE文件学习之 编写PE文件分析工具

2008-12-17 17:42
34652
题记:
大家好,本来是打算写C++逆向的内容呢; 但由于时间关系,而写表达式与运算符其实更多的是写编码解码机制和汇编语言; 所以不知道怎么来定位;但后期我会慢慢的整理出来,说实话,加密解密三这书写的很棒,以前在看加密解密二的时候就对PE文件格式研究了好一阵; 直到如今慢慢的才基本理解;从编程的角度来看,PE文件格式只不是一堆互相嵌套的数据结构; 然而从系统的角度来看,这部分就比较伤神了,比如,逻辑地址到物理地址转换,文件加载的过程,动态函数的链接,RAV等内容的理解,也是对刚接触的新手来说,是有些障碍;
但如果你相信你自己能,你也许就真的能; 如果一开始你就觉得你不能做,那么你永远都做不了; 小菜我在写这个程序的时候,就遇到不少问题,但由于没有放弃,现在就能发文章了;

关于这篇文章:
    有关PE文件格式的详解,请大家参照加密解密三,书上很详细,由于写PE分析器,主要的在于文件打开和文件映射这一部分代码的实现,而PE文件的那一部分,加密解密三上有很详细的代码;
所以希望大家在看玩此代码后,能继续把,输入表,输出表那一部分写出来; 因为那才是PE文件的核心和重点; 好了,废话不说;

关于这个程序:

  由于是第一次写这程序,鉴于本人的无工作经验,仅为学习练手用,有不是之处,还希望大家指出,声明,PE文件的相关代码,参考了加密解密三书上的; 所以,前面几步实现了的,后面应该就不难了;

  你可以在此程序的基础上,再做扩充,比如: RVA转换,输入,输出表的显示,等等; 相信,不用多久,打造属于你自己的山寨PE查看器就不成问题了 ; ( 山寨这一词,首次在看雪见了, 好喜欢哦,想起了小说花木兰,嘿嘿) ;

代码:
#include<windows.h>

#include "resource.h"



BOOL CALLBACK DlgProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam);

//Pe文件处理函数声明
BOOL IsPeFile(LPVOID ImageBase);
PIMAGE_NT_HEADERS	GetNtHeader(LPVOID	ImageBase);
PIMAGE_FILE_HEADER	WINAPI	GetFileHeader(LPVOID	Imagebase);
PIMAGE_OPTIONAL_HEADER	GetOptionalHeader(LPVOID	ImageBase);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowcmd)
{
    DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG),NULL,DlgProc);

    return 0;
}


BOOL CALLBACK DlgProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam)
{


	OPENFILENAME	FileName = {0,0,0},*lpFileName = &FileName;
	HANDLE			hFile,hFileMap; 
	TCHAR			szPe[]="\"PE File(*.exe)\" \0*.exe;*.dll;*.scr;*.fon;*.drv;\0\"*.All File(*.*) \0*.*\0\0";
	TCHAR			szFileName[256]={""};

	LPVOID			lpMemory;

	TCHAR			Buff[16];
	PIMAGE_FILE_HEADER	pFileHeader = NULL;
	PIMAGE_OPTIONAL_HEADER	pOptionHeader = NULL;

	switch(message)
	{
		case	WM_INITDIALOG:
				break;
		case	WM_CLOSE:
				
				EndDialog(hDlg,NULL);
				break;
	  
		case	WM_COMMAND:
				  switch(LOWORD(wParam))
			 {
				  case	IDM_OPEN:
				FileName.hInstance = (HINSTANCE)hDlg;
				FileName.hwndOwner = hDlg;
				FileName.lStructSize = sizeof(OPENFILENAME);
				FileName.lpstrFilter = szPe;
				FileName.lpstrFile = szFileName;
				FileName.Flags = OFN_FILEMUSTEXIST||OFN_PATHMUSTEXIST;
				FileName.nMaxFile = sizeof(szFileName);
				
				
				 if(!GetOpenFileName(lpFileName))
				 {
					 MessageBox(hDlg,"GetOpenFileName 调用失败","ERROR",NULL);
					 break;
				 }
				
				SetDlgItemText(hDlg,IDC_FILENAME,szFileName);
 
				hFile = CreateFile(FileName.lpstrFile,           // open  pe file 
                GENERIC_READ,              // open for reading 
                FILE_SHARE_READ|| FILE_SHARE_WRITE,           // share for reading 
                NULL,                      // no security 
                OPEN_EXISTING,             // existing file only 
                FILE_ATTRIBUTE_NORMAL,     // normal file 
                NULL);                     // no attr. template 
 
				if (hFile == INVALID_HANDLE_VALUE) 
				{ 
					 MessageBox(hDlg,"Could not open file.","ERROR",MB_ICONERROR); 
					 break;// process error 
				} 

				if(GetFileSize(hFile,NULL)!=0)
				{
					hFileMap = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
					if(hFileMap!=0)
					{
					lpMemory = MapViewOfFile(hFileMap,FILE_MAP_READ,NULL,NULL,NULL);
					}
				}
				
				if(IsPeFile(lpMemory))
				{
					
					pFileHeader = GetFileHeader(lpMemory);
					pOptionHeader = GetOptionalHeader(lpMemory);
					if(!(pFileHeader&&pOptionHeader))
					{
						MessageBox(hDlg,"获取文件头指针失败","PEINFO",MB_ICONERROR);
						break;
					}
					else
					{
						wsprintf(Buff,"%04lX",pFileHeader->Machine);
						SetDlgItemText(hDlg,IDC_MACHINE,Buff);

						wsprintf(Buff,"%04lX",pFileHeader->NumberOfSections);
						SetDlgItemText(hDlg,IDC_NUMSECTION,Buff);

						wsprintf(Buff,"%04lX",pOptionHeader->Magic);
						SetDlgItemText(hDlg,IDC_MAGIC,Buff);

						wsprintf(Buff,"%08lX",pOptionHeader->AddressOfEntryPoint);
						SetDlgItemText(hDlg,IDC_ENTERPOINT,Buff);
						
						wsprintf(Buff,"%08lX",pOptionHeader->DataDirectory[0].VirtualAddress);
						SetDlgItemText(hDlg,IDC_EDIT_RVA_EXPORT,Buff);
						
						wsprintf(Buff,"%08lX",pOptionHeader->DataDirectory[0].Size);
						SetDlgItemText(hDlg,IDC_EDIT_SIZE_EXPORT,Buff);

						wsprintf(Buff,"%08lX",pOptionHeader->DataDirectory[1].VirtualAddress);
						SetDlgItemText(hDlg,IDC_EDIT_RVA_IMPORT,Buff);
						
						wsprintf(Buff,"%08lX",pOptionHeader->DataDirectory[1].Size);
						SetDlgItemText(hDlg,IDC_EDIT_SIZE_IMPORT,Buff);

						wsprintf(Buff,"%08lX",pOptionHeader->DataDirectory[2].VirtualAddress);
						SetDlgItemText(hDlg,IDC_EDIT_RVA_RES,Buff);
						
						wsprintf(Buff,"%08lX",pOptionHeader->DataDirectory[2].Size);
						SetDlgItemText(hDlg,IDC_EDIT_SIZE_RES,Buff);



					}


				}
				else
				{
					MessageBox(hDlg,"你选择的不是PE文件","error",MB_ICONERROR);
					UnmapViewOfFile(lpMemory);
					CloseHandle(hFileMap);
					CloseHandle(hFile);
				}
				UnmapViewOfFile(lpMemory);
				CloseHandle(hFileMap);
				CloseHandle(hFile);
				
				break;


			}
		
					
	}
    return FALSE;
}

BOOL	IsPeFile(LPVOID	ImageBase)   //判断是否是PE文件结构
{
	PIMAGE_DOS_HEADER	pDosHeader = NULL;
	PIMAGE_NT_HEADERS	pNtHeader  = NULL;
	
	if(!ImageBase)
		return FALSE;
	pDosHeader = (PIMAGE_DOS_HEADER) ImageBase;
	if(pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
		return FALSE;
	pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader+pDosHeader->e_lfanew);
	if(pNtHeader->Signature != IMAGE_NT_SIGNATURE )
		return	FALSE;
	return		TRUE;
}

//FileHeader 内容的读取

PIMAGE_NT_HEADERS	GetNtHeader(LPVOID	ImageBase) //获取NT结构指针
{
	PIMAGE_DOS_HEADER	pDosHeader = NULL;
	PIMAGE_NT_HEADERS	pNtHeader  = NULL;

	if(!IsPeFile(ImageBase))
		return	NULL;
	pDosHeader = (PIMAGE_DOS_HEADER)ImageBase;
	pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader+pDosHeader->e_lfanew);
	return		pNtHeader;
}

PIMAGE_FILE_HEADER	WINAPI	GetFileHeader(LPVOID	Imagebase)
{
	PIMAGE_FILE_HEADER	pFileHeader;
	PIMAGE_NT_HEADERS	pNtHeader = NULL;
	pNtHeader = GetNtHeader(Imagebase);
	if(!pNtHeader)
		return	NULL;
	pFileHeader = & pNtHeader->FileHeader; 
	return	pFileHeader;
}

PIMAGE_OPTIONAL_HEADER	GetOptionalHeader(LPVOID	ImageBase)
{
	PIMAGE_OPTIONAL_HEADER	pOptionHeader = NULL;
	PIMAGE_NT_HEADERS	pNtHeader = NULL;
	pNtHeader = GetNtHeader(ImageBase);
	if(!pNtHeader)
		return	NULL;
	pOptionHeader = & pNtHeader->OptionalHeader;
	return	pOptionHeader;
}


	

看雪招聘平台创建简历并且简历完整度达到90%及以上可获得500看雪币~

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (13)
雪    币: 201
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zhjiqi 活跃值 2008-12-19 19:32
2
0
看不懂了!帮顶一下!
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
gzbuzou 活跃值 2008-12-24 00:17
3
0
我也看不明白,我今天才记住看雪论坛的网址 pediy  PE我知道,呵呵
我是从疯狂的程序员知道这个论坛的,我以后会经常来和前辈学习的
雪    币: 273
活跃值: 活跃值 (14)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
liyiwen 活跃值 1 2009-5-6 19:44
4
0
学习,谢谢分享。
对于理解PE很有帮助。
雪    币: 404
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
末日 活跃值 2009-5-6 21:32
5
0
正在学习这一章 对我很有帮助
雪    币: 3
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yuredwaves 活跃值 2009-10-27 10:04
6
0
正在学呢,哈哈~~~~谢谢哈!
雪    币: 34
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Funnyhe 活跃值 2010-7-14 09:18
7
0
谢谢正在学习
雪    币: 219
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
风雷坎泽 活跃值 2010-7-14 09:57
8
0
学习一下,就是看不太懂
雪    币: 669
活跃值: 活跃值 (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jackieruo 活跃值 2010-8-9 14:07
9
0
学习
雪    币: 50
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
precker 活跃值 2010-8-9 15:00
10
0
这个主题很不错,确实有必要自己写一个PE工具,哪怕实战时用别人的工具。
雪    币: 232
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wsslcj 活跃值 2010-9-6 22:43
11
0
虽然看不太懂,但还是感谢分享.
雪    币: 100
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ity 活跃值 2010-9-7 08:29
12
0
不错的东西,谢谢楼主分享
雪    币: 49
活跃值: 活跃值 (17)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
邓韬 活跃值 9 2010-10-2 14:29
13
0
膜拜!学习了
雪    币: 49
活跃值: 活跃值 (17)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
邓韬 活跃值 9 2010-10-2 14:40
14
0
希望楼主多弄点类似的教程
游客
登录 | 注册 方可回帖
返回