PE格式文件的读取

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.运行结果如下图:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值