首页 » 技术分享 » 初次解析PE

初次解析PE

 

知识点补充

=======================================================================================================
1.LPVOID
LPVOID,是一个没有类型的指针,也就是说你可以将LPVOID类型的变量赋值给任意类型的指针。
比如在参数传递时就可以把任意类型传递给一个LPVOID类型为参数的方法,然后在方法内再将这个“任意类型”从传递时的“LPVOID类型”转换回来

2.LPSTR
在WINNT.H中有如下定义:
typedef char CHAR;
typedef CHAR *LPSTR,*PSTR
也就是说LPSTR与PSTR定义的变量与char *定义的变量完全相同,都可以作为指向字符串的指针
不过,LPSTR的字面意思是指向字符串的长指针(相对于16位而言),PSTR的字面意思是指向字符串的指针,但是由于32位的普及,从Visual C++ 6.0开始它们完全相同,没有任何区别,只是由于习惯大家还分别在不同的地方使用它们

3.void *memset(void *s,int c,size_t n)
作用:将已开辟内存空间 s 的首 n 个字节的值设为值 c。

4.sprintf,swprintf
用于将格式化的数据写入字符串。使用这两个方法需要包含<stdio.h>头文件
原型:
int sprintf( char *buffer, const char *format [, argument] ... );
int swprintf( wchar_t *buffer, const wchar_t *format [, argument] ... );

5.HANDLE CreateFile(
LPCTSTR lpFileName, //指向文件名的指针
DWORD dwDesiredAccess, //访问模式
DWORD dwShareMode, //共享模式
LPSECURITY_ATTRIBUTES lpSecurityAttributes, //指向安全属性的指针
DWORD dwCreationDispostion , //如何创建
DWORD dwFlagsAndAttributes, //文件属性
HANDLE hTemplateFile ); //用于复制文件的句柄

/
使用文件映射的方式进行共享数据:
先要使用函数CreateFileMapping来创建一个想共享的文件数据句柄,
然后使用MapViewOfFile来获取共享的内存地址,
然后使用OpenFileMapping函数在另一个进程里打开共享文件的名称,
这样就可以实现不同的进程共享数据
/

5.HANDLE CreateFileMapping(
HANDLE hFile, //创建共享文件的句柄
LPSECURITY_ATTRIBUTES lpFileMappingAttributes, //文件共享的属性
DWORD flProtect, //当文件映射时读写文件的属性
DWORD dwMaximumSizeHigh, //文件共享的大小高位字节
DWORD dwMaximumSizeLow, //文件共享的大小高位字节
LPCTSTR lpName ); //共享文件对象名称

6.LPVOID MapViewOfFile( 
HANDLE hFileMappingObject, //共享文件对象
DWORD dwDesiredAccess, //文件共享属性
DWORD dwFileOffsetHigh, //文件共享区的偏移地址
DWORD dwFileOffsetLow, //文件共享区的偏移地址
DWORD dwNumberOfBytesToMap ); //共享数据长度


=========================================================================================
typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
    WORD   e_magic;                     // Magic number
    WORD   e_cblp;                      // Bytes on last page of file
    WORD   e_cp;                        // Pages in file
    WORD   e_crlc;                      // Relocations
    WORD   e_cparhdr;                   // Size of header in paragraphs
    WORD   e_minalloc;                  // Minimum extra paragraphs needed
    WORD   e_maxalloc;                  // Maximum extra paragraphs needed
    WORD   e_ss;                        // Initial (relative) SS value
    WORD   e_sp;                        // Initial SP value
    WORD   e_csum;                      // Checksum
    WORD   e_ip;                        // Initial IP value
    WORD   e_cs;                        // Initial (relative) CS value
    WORD   e_lfarlc;                    // File address of relocation table
    WORD   e_ovno;                      // Overlay number
    WORD   e_res[4];                    // Reserved words
    WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
    WORD   e_oeminfo;                   // OEM information; e_oemid specific
    WORD   e_res2[10];                  // Reserved words
    LONG   e_lfanew;                    // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
  
typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

typedef struct _IMAGE_FILE_HEADER {
    WORD    Machine;
    WORD    NumberOfSections;
    DWORD   TimeDateStamp;
    DWORD   PointerToSymbolTable;
    DWORD   NumberOfSymbols;
    WORD    SizeOfOptionalHeader;
    WORD    Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

// dtd_10.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <time.h>


typedef struct _MAP_FILE_STRUCT
{
HANDLE hFile;
HANDLE hMapping;
LPVOID ImageBase;
} MAP_FILE_STRUCT, *PMAP_FILE_STRUCT;

bool LoadFile(LPTSTR lpFileName, PMAP_FILE_STRUCT pstMapFile)
{
	if (lpFileName == NULL)
	{
		return false;
	}
	HANDLE hFile;
	HANDLE hMapping;
	LPVOID ImageBase;

	memset(pstMapFile, 0, sizeof(MAP_FILE_STRUCT));

	hFile = CreateFile(lpFileName, GENERIC_READ, FILE_SHARE_READ, 
		NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
	if (!hFile)
	{
		return false;
	}

	hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, 0);
	if (!hMapping)
	{
		CloseHandle(hFile);
		return false;
	}

	ImageBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
	if (!ImageBase)
	{
		CloseHandle(hFile);
		CloseHandle(hMapping);
		return false;
	}
	pstMapFile->hFile = hFile;
	pstMapFile->hMapping = hMapping;
	pstMapFile->ImageBase = ImageBase;
	return true;
}


void UnLoadFile(PMAP_FILE_STRUCT pstMapFile)
{
	if (pstMapFile->hFile)
	{
		CloseHandle(pstMapFile->hFile);
	}


	if (pstMapFile->hMapping)
	{
		CloseHandle(pstMapFile->hMapping);
	}


	if (pstMapFile->ImageBase)
	{
		UnmapViewOfFile(pstMapFile->ImageBase);
	}
}

bool IsPEFile(LPVOID ImageBase)
{
	PIMAGE_DOS_HEADER pDH = NULL;
	PIMAGE_NT_HEADERS32 pNtH = NULL;

	if (!ImageBase)
	{
		return false;
	}

	pDH = (PIMAGE_DOS_HEADER)ImageBase;
	if (pDH->e_magic != IMAGE_DOS_SIGNATURE)  //"MZ"
	{
		return false;
	}

	pNtH = (PIMAGE_NT_HEADERS32) ( (DWORD)pDH + pDH->e_lfanew);
	if (pNtH->Signature != IMAGE_NT_SIGNATURE) //"PE"
	{
		return false;
	}

	return true;
}

// _IMAGE_NT_HEADERS
PIMAGE_NT_HEADERS GetNtHeaders(LPVOID ImageBase)
{
	PIMAGE_DOS_HEADER pDH = NULL;
	PIMAGE_NT_HEADERS pNtH = NULL;
	if (!IsPEFile(ImageBase))
	{
		return NULL;
	}

	pDH = (PIMAGE_DOS_HEADER)ImageBase;
	pNtH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);
	return pNtH;
}

// _IMAGE_FILE_HEADER
PIMAGE_FILE_HEADER GetFileHeader(LPVOID ImageBase)
{
	PIMAGE_NT_HEADERS pNtH = GetNtHeaders(ImageBase);
	if (!pNtH)
	{
		return NULL;
	}
	return &(pNtH->FileHeader);
}

// _IMAGE_OPTIOANAL_HEADER
PIMAGE_OPTIONAL_HEADER GetOptionalHeader(LPVOID ImageBase)
{
	PIMAGE_NT_HEADERS pNtH = GetNtHeaders(ImageBase);
	if (!pNtH)
	{
		return NULL;
	}
	return &(pNtH->OptionalHeader);
}

void ShowFileHeaderInfo(PMAP_FILE_STRUCT stMapFile)
{
	char strTmp[1024] = {0};
	PIMAGE_FILE_HEADER pFH = NULL;
	PIMAGE_OPTIONAL_HEADER pOH = NULL;

	pFH = GetFileHeader(stMapFile->ImageBase);
	if (!pFH)
	{
		printf("Get File Header failed!\n");
		return;
	}

	// format time
	time_t t = pFH->TimeDateStamp;
	char strTime[26] = {0};
	tm* ptmBegin = localtime(&t);
	strftime(strTime, 26, "%Y/%m/%d %H:%M:%S", ptmBegin);

	// result to HEX
	char *strFileHeaderFormat ="\
IMAGE_FILE_HEADER:\n\
Machine:                   %04lX\n\
NumberOfSections:          %04lX\n\
TimeDateStamp:             %s (%04lX)\n\
PointerToSymbolTable:      %08X\n\
NumberOfSymbols:           %08lX\n\
SizeOfOptionalHeader:      %04lX\n\
Characteristics:           %04lX\n\n\
";

	sprintf(strTmp, strFileHeaderFormat, pFH->Machine, pFH->NumberOfSections, strTime, pFH->TimeDateStamp, pFH->PointerToSymbolTable, pFH->NumberOfSymbols,
	        pFH->SizeOfOptionalHeader, pFH->Characteristics);
	printf("%s", strTmp);

	memset(strTmp, 0, sizeof(strTmp));

	char *strFileOptHeaderFormat = "\
IMAGE_OPTIONAL_HEADER:\n\
Entry Point:              %08lX\n\
Image Base:               %08lX\n\
Code Base:                %08lX\n\
Data Base:                %08lX\n\
Image Size:               %08lX\n\
Headers Size:             %08lX\n\
Section Alignment:        %08lX\n\
File Alignment:           %08lX\n\
Subsystem:                %08lX\n\
Check Sum:                %04lX\n\
Dll Flags:                %04lX\n\
";
	pOH= GetOptionalHeader(stMapFile->ImageBase);
	if (!pOH)
	{
		printf("Get File Optional Header failed!\n");
		return;
	}
	sprintf(strTmp, strFileOptHeaderFormat, pOH->AddressOfEntryPoint, pOH->ImageBase, pOH->BaseOfCode, pOH->BaseOfData,
	        pOH->SizeOfImage, pOH->SizeOfHeaders, pOH->SectionAlignment, pOH->FileAlignment, pOH->Subsystem, pOH->CheckSum, pOH->DllCharacteristics);
	printf("%s", strTmp);
}

MAP_FILE_STRUCT stMapFile = { NULL, NULL, NULL };

int main()
{
	LPTSTR filePath = TEXT("c:\\D\\StuPE.exe");
	UnLoadFile(&stMapFile);
	if (!LoadFile(filePath, &stMapFile))
	{
		return -1;
	}

	if (!IsPEFile(stMapFile.ImageBase))
	{
		UnLoadFile(&stMapFile);
		return -1;
	}

	ShowFileHeaderInfo(&stMapFile);

	UnLoadFile(&stMapFile);

	return 0;
}

[2017-05-01]

转载自原文链接, 如需删除请联系管理员。

原文链接:初次解析PE,转载请注明来源!

0