1.封装一个类,实现PE文件的读取
//PEFile.h
#ifndef _PEFILE_
#define _PEFILE_
#include <windows.h>
enum PEFILE_ACCESS
{
PEFILE_ACCESS_READ = 0,
PEFILE_ACCESS_WRITE ,
PEFILE_ACCESS_RW,
PEFILE_ACCESS_INVLID,
};
class PEFile
{
public:
PEFile();
~PEFile();
BOOL ReadLine(char *pReadBuff, const DWORD dwSize, const DWORD dwCountLine);
BOOL WriteLine(char *pWriteBuff, const DWORD dwSize, const DWORD dwCountLine);
BOOL ReadLastLine(char *pReadBuff, DWORD dwSize);
BOOL WriteLastLine(const char *pWriteBuff, DWORD dwSize);
BOOL OpenPEFile(const char *pszFileName, PEFILE_ACCESS eAccess = PEFILE_ACCESS_READ);
VOID ClosePEFile();
DWORD GetTotalSize();
DWORD GetTotalLine();
private:
VOID Init();
BOOL OpenPEFileWrite();
BOOL OpenPEFileRead();
BOOL OpenPEFileRW();
private:
//char m_szLineBuffer[100]; // 一行中的内容
DWORD m_dwTotalSize; // 文件总大小
DWORD m_dwTotalLine; // 文件总行数
DWORD m_dwLastLineBlanks; //最后一行空格数
HANDLE m_hFile; // 文件句柄
HANDLE m_hMapFile; // 映像内存句柄
LPVOID m_pViewMem; // 进程映像视图内存首地址
BOOL m_bOpenFlag; // PE文件打开标志
const char *m_pFileName; //文件名
PEFILE_ACCESS m_eAccess; //文件访问方式
};
#endif
//PEFile.cpp
#include "stdafx.h"
#include "PEFile.h"
#include <stdio.h>
#include <iostream>
using namespace std;
const char *pAddrFormat = "%08x";
const char *pHexFormat = "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x";
const char *pTwoBlanks = " ";
const char chOneBlank = ' ';
const char chSplit ='_';
const char *pchReturn = "\n";
PEFile::PEFile()
: m_eAccess(PEFILE_ACCESS_INVLID)
, m_dwTotalLine(0)
, m_dwTotalSize(0)
, m_dwLastLineBlanks(0)
, m_hFile(NULL)
, m_hMapFile(NULL)
, m_pViewMem(NULL)
, m_bOpenFlag(FALSE)
, m_pFileName(NULL)
{
//memset(m_szLineBuffer, 0, sizeof(m_szLineBuffer));
}
PEFile::~PEFile()
{
if(NULL != m_pViewMem)
{
UnmapViewOfFile(m_pViewMem);
m_pViewMem = NULL;
}
if(NULL != m_hMapFile)
{
CloseHandle (m_hMapFile);
m_hMapFile = NULL;
}
if(NULL != m_hFile)
{
CloseHandle (m_hFile);
m_hFile = NULL;
}
}
VOID PEFile::Init()
{
if(NULL != m_pViewMem)
{
UnmapViewOfFile(m_pViewMem);
m_pViewMem = NULL;
}
if(NULL != m_hMapFile)
{
CloseHandle (m_hMapFile);
m_hMapFile = NULL;
}
if(NULL != m_hFile)
{
CloseHandle (m_hFile);
m_hFile = NULL;
}
m_eAccess = PEFILE_ACCESS_INVLID;
m_dwLastLineBlanks = 0;
m_dwTotalLine = 0;
m_dwTotalSize = 0;
m_pFileName = NULL;
m_bOpenFlag = FALSE;
}
VOID PEFile::ClosePEFile()
{
Init();
}
BOOL PEFile::OpenPEFile(const char *pszFileName, PEFILE_ACCESS eAccess)
{
if(TRUE == m_bOpenFlag)
{
return TRUE;
}
if(NULL == pszFileName)
{
printf("open file fail \n");
return FALSE;
}
m_pFileName = pszFileName;
m_eAccess = eAccess;
BOOL bResult = FALSE;
switch(m_eAccess)
{
case PEFILE_ACCESS_READ:
bResult = OpenPEFileRead();
break;
case PEFILE_ACCESS_WRITE:
//bResult = OpenPEFileWrite();
break;
case PEFILE_ACCESS_RW:
//bResult = OpenPEFileRW();
break;
default:
break;
}
return bResult;
}
BOOL PEFile::OpenPEFileRead()
{
m_hFile = CreateFile(m_pFileName, GENERIC_READ, (FILE_SHARE_READ | FILE_SHARE_WRITE),
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL);
if(INVALID_HANDLE_VALUE == m_hFile)
{
printf("open file fail!\n");
return FALSE;
}
m_dwTotalSize = GetFileSize(m_hFile, NULL);
m_dwTotalLine = m_dwTotalSize / 16;
m_dwLastLineBlanks = m_dwTotalSize % 16;
m_hMapFile = CreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if(NULL == m_hMapFile)
{
printf("Create file mapping fail!\n");
return FALSE;
}
m_pViewMem = MapViewOfFile(m_hMapFile, FILE_MAP_READ, 0, 0, 0);
if(NULL == m_pViewMem)
{
CloseHandle (m_hMapFile);
CloseHandle (m_hFile);
printf("Map View of File fail!\n");
return FALSE;
}
return TRUE;
}
BOOL PEFile::ReadLine(char *pReadBuff, const DWORD dwSize, const DWORD dwCountLine)
{
if(NULL == pReadBuff || dwSize < 90 || dwCountLine > m_dwTotalLine )
{
return FALSE;
}
BYTE *pBuf = (BYTE *)m_pViewMem + dwCountLine * 16;
if((m_dwLastLineBlanks != 0) && (dwCountLine == m_dwTotalLine))
{
return ReadLastLine(pReadBuff, dwSize);
}
memset(pReadBuff, 0, dwSize);
char byAsciiBuffer[17]; //第三列ASCII码字符显示
char byHex[50]; //第二列中的Hex
memset(byAsciiBuffer, 0, sizeof(byAsciiBuffer));
memset(byHex, 0, sizeof(byHex));
//第一列写入行buf中
sprintf(pReadBuff, pAddrFormat, dwCountLine * 16);
//第一列与第二列中间添加2个空格
strcat(pReadBuff, pTwoBlanks);
//第二列数据写入行buf中
sprintf(byHex, pHexFormat, pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4],
pBuf[5], pBuf[6], pBuf[7], pBuf[8],pBuf[9], pBuf[10],
pBuf[11], pBuf[2], pBuf[13], pBuf[14], pBuf[15]);
strcat(pReadBuff, byHex);
//第二列与第三列中间添加2个空格
strcat(pReadBuff, pTwoBlanks);
DWORD dwIndex = 0; //计数,逢16则重新计
for (dwIndex = 0; dwIndex < 16; dwIndex ++)
{
if(pBuf[dwIndex] > 0x20 && pBuf[dwIndex] < 0x7e)
{
byAsciiBuffer[dwIndex] = pBuf[dwIndex];
}
else
{
byAsciiBuffer[dwIndex] = '.';
}
}
//第三列写入行buf中
strcat(pReadBuff, byAsciiBuffer);
//换行符写入buf中
strcat(pReadBuff, pchReturn);
return TRUE;
}
BOOL PEFile::ReadLastLine(char *pReadBuff, DWORD dwSize)
{
if(NULL == pReadBuff || dwSize < 90)
{
return FALSE;
}
if (m_dwLastLineBlanks == 0)
{
return ReadLine(pReadBuff, dwSize, m_dwTotalLine);
}
memset(pReadBuff, 0, dwSize);
char byAsciiBuffer[17]; //第三列ASCII码字符显示
char byHex[3]; //第二列中的Hex
memset(byAsciiBuffer, 0, sizeof(byAsciiBuffer));
memset(byHex, 0, sizeof(byHex));
DWORD dwIndex = 0;
BYTE *pBuf = (BYTE *)m_pViewMem + m_dwTotalLine * 16;
//第一列写入行buf中
sprintf(pReadBuff, pAddrFormat, m_dwTotalLine * 16);
//第一列与第二列中间添加2个空格
strcat(pReadBuff, pTwoBlanks);
for(dwIndex = 0; dwIndex < m_dwLastLineBlanks; dwIndex ++)
{
memset(byHex, 0, sizeof(byHex));
sprintf(byHex, "%02x ",pBuf[dwIndex]);
if(pBuf[dwIndex] > 0x20 && pBuf[dwIndex] < 0x7e)
{
byAsciiBuffer[dwIndex] = pBuf[dwIndex];
}
else
{
byAsciiBuffer[dwIndex] = '.';
}
strcat(pReadBuff, byHex);
}
//第二列不足时候,补添空格
dwIndex = (16 - m_dwLastLineBlanks) * 2 -1;
while(dwIndex > 0)
{
strcat(pReadBuff, " ");
dwIndex --;
}
//第三列不足时候,补添.
dwIndex = 16 - m_dwLastLineBlanks;
while (dwIndex > 0)
{
strcat(byAsciiBuffer, " ");
dwIndex --;
}
//第二列与第三列中间添加2个空格
strcat(pReadBuff, pTwoBlanks);
//第三列写入行buf中
strcat(pReadBuff, byAsciiBuffer);
//换行符写入buf中
strcat(pReadBuff, pchReturn);
return TRUE;
}
DWORD PEFile::GetTotalSize()
{
return m_dwTotalSize;
}
DWORD PEFile::GetTotalLine()
{
return m_dwTotalLine;
}
//test.cpp
const char *pPath = "D:\\HelloWord.exe";
int _tmain(int argc, _TCHAR* argv[])
{
PEFile cPeFile;
char szBuf[100];
memset(szBuf, 0, sizeof(szBuf));
cPeFile.OpenPEFile(pPath);
DWORD dwTotalLine = cPeFile.GetTotalLine();
DWORD dwCountLine = 0;
while(dwCountLine <= dwTotalLine)
{
cPeFile.ReadLine(szBuf, sizeof(szBuf), dwCountLine);
printf("%s", szBuf);
dwCountLine ++;
}
getchar();
return 0;
}
3.运行结果如下图: