PE学习笔记2

此博客给出一段C++代码,用于读取PE文件。代码先打开指定的PE文件,检查文件格式,接着读取PE头信息,判断是否为PE格式。之后读取节表信息,找到资源节,再读取资源目录和资源项,根据资源项的名称或ID输出资源类型。

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

#include "stdafx.h"

using std::cout;
using std::endl;
LPCTSTR lpszFileToOpen = _T("c://windows//explorer.exe");
char* GetResType(int id);

int main(int argc, char* argv[])
{
 CFile f;
 TCHAR szRsRc[8];
 if (f.Open(lpszFileToOpen, CFile::typeBinary|CFile::shareDenyNone) == FALSE)
 {
  cout << "File open error." << endl;
  return 0;
 }

 f.Seek(0x3c, CFile::begin);
 short nbuf;
 f.Read(&nbuf, sizeof (short));

 try{f.Seek(nbuf, CFile::begin);}
 catch (...)
 {
  cout << "File format error." << endl;
  return 0;
 }
 IMAGE_NT_HEADERS stPEHeader;
 f.Read(&stPEHeader, sizeof stPEHeader);
 if (stPEHeader.Signature != 17744)
 {
  cout << "It isn't PE format." << endl;
  return 0;
 }
 short nSection = stPEHeader.FileHeader.NumberOfSections;
 IMAGE_SECTION_HEADER *pstSection=NULL;
 pstSection = new IMAGE_SECTION_HEADER[nSection];
 DWORD ptResource=0;
 for (int i=0; i<nSection; i++)
 {
  f.Read(&pstSection[i], sizeof (IMAGE_SECTION_HEADER));
  lstrcpy(szRsRc, (LPCSTR)pstSection[i].Name);
  if (!lstrcmp(szRsRc, _T(".rsrc/0/0")))
  {
   ptResource = pstSection[i].PointerToRawData;
  }
  cout << pstSection[i].Name << endl;
 }
 delete [] pstSection;

 IMAGE_RESOURCE_DIRECTORY stResourceDir;
 IMAGE_RESOURCE_DIRECTORY_ENTRY *pstResDirEntry1;
 IMAGE_RESOURCE_DIRECTORY *pstResourceDir1;
 IMAGE_RESOURCE_DIR_STRING_U stResDirStrU;
 TCHAR wResname[128];
 WORD nResource=0;
 long tmpSeek=0;
 if (ptResource)
 {
  f.Seek(ptResource, CFile::begin);
  f.Read(&stResourceDir, sizeof (stResourceDir));
  nResource = stResourceDir.NumberOfIdEntries+stResourceDir.NumberOfNamedEntries;

  pstResourceDir1 = new IMAGE_RESOURCE_DIRECTORY[nResource];
  pstResDirEntry1 = new IMAGE_RESOURCE_DIRECTORY_ENTRY[nResource];
  for (i=0; i<nResource; i++)
  {
   f.Read(&pstResDirEntry1[i], sizeof (IMAGE_RESOURCE_DIRECTORY_ENTRY));
  }
  for (i=0; i<nResource; i++)
  {
   f.Read(&pstResourceDir1[i], sizeof (IMAGE_RESOURCE_DIRECTORY));
   if (pstResDirEntry1[i].Name>=IMAGE_RESOURCE_NAME_IS_STRING)
   {
    cout << "........" << endl;
    tmpSeek = f.Seek(0, CFile::current);
    f.Seek(pstResDirEntry1[i].NameOffset+ptResource, CFile::begin);
    f.Read(&stResDirStrU, sizeof (IMAGE_RESOURCE_DIR_STRING_U));
    f.Read(wResname, (stResDirStrU.Length - 1)*2);
    cout << wResname << endl;
    f.Seek(tmpSeek, CFile::begin);
   }
   else
   {
    cout << GetResType(pstResDirEntry1[i].Id) << endl;
   }
  }
  delete [] pstResourceDir1;
  delete [] pstResDirEntry1;
 }
 return 0;
}

char* GetResType(int id)
{
 static char cc[36];
 sprintf(cc,"id%d: ",id);
 switch(id)
 {
 case 1: strcat(cc,"cursor/0");break;
    case 2: strcat(cc,"bitmap/0");break;
    case 3: strcat(cc,"icon/0");break;
    case 4: strcat(cc,"menu/0");break;
    case 5: strcat(cc,"dialog/0");break;
    case 6: strcat(cc,"string table/0");break;
    case 7: strcat(cc,"font directory/0");break;
    case 8: strcat(cc,"font/0");break;
    case 9: strcat(cc,"accelerators/0");break;
    case 10: strcat(cc,"unformatted resource data/0");break;
    case 11: strcat(cc,"message table/0");break;
    case 12: strcat(cc,"group cursor/0");break;
    case 14: strcat(cc,"group icon/0");break;
    case 16: strcat(cc,"version information/0");break;
 default:strcat(cc,"unkowned resource/0");
 }
 return cc;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值