尾山中学吧 关注:63贴子:736
  • 4回复贴,共1

PE结构是那一类!获取导入表和导出表的类!方便使用!

只看楼主收藏回复

标 题: 【分享】PE结构是那一类!获取导入表和导出表的类!方便使用!
作 者: menting
时 间: 2007-10-19,17:02
链 接: http://bbs.pediy.com/showthread.php?t=53536

我想高手们都别笑话!我发出来希望有研究PE结构的朋友们喜欢,为了不占空间,我把关键的几个发出来,其它的大同小异,我想自己组也能组成一个类,然后,自己使用的,目前网络上没有一个是完整的点的例子,这里是我自己整理添加的,供大家参考!!!:

//--------------------------------------PNExeInfo.h----------------------------------------------------

//加载调试辅助:
#include "IMAGEHLP.H"
#pragma comment(lib,"ImageHlp.lib")

#include "tlhelp32.h"
#pragma comment(lib,"th32.lib")

class CPNExeInfo  
{
public:
  CPNExeInfo();
  virtual ~CPNExeInfo();
public:
  BOOL Release();
  int     LoadPE(DWORD pId);              //进程装载
  int      LoadPE(DWORD pId,DWORD mId);    //模块装载
  int      LoadPE(LPCTSTR path);           //文件装载
  DWORD  GetSize(){return dwFileSize;}

  //文件头函数:
  PIMAGE_DOS_HEADER       GetDosHeader(){return _dosHeader;}
  PIMAGE_NT_HEADERS       GetNTHeaders(){return _ntHeader;}
  PIMAGE_SECTION_HEADER    GetSection(DWORD dwRVA=NULL);
  //输入表函数:
  PIMAGE_IMPORT_DESCRIPTOR GetImportModule(DWORD *dwSize=NULL,LPCTSTR *name=NULL);
  PIMAGE_THUNK_DATA     GetProcOfModule(LPCTSTR name,DWORD *dwSize=NULL,
                       LPCTSTR *ProcName=NULL,DWORD *Hint=NULL,
                       DWORD *Offset=NULL,DWORD *Value=NULL,DWORD *Rva=NULL);
  PIMAGE_THUNK_DATA     GetProcOfModule(int count,DWORD *dwSize=NULL,
                       LPCTSTR *ProcName=NULL,DWORD *Hint=NULL,
                       DWORD *Offset=NULL,DWORD *Value=NULL,DWORD *Rva=NULL);
  //输出表函数:
  PIMAGE_EXPORT_DIRECTORY GetExportInfo(DWORD *dwSize=NULL,LPCTSTR *strFun=NULL,DWORD *dwAddr=NULL,
                       DWORD *dwOrdin=NULL,DWORD *dwOffset=NULL,LPTSTR DllName=NULL);
protected:
  LPCTSTR    m_path;  //路径

  HANDLE    hFile;      //打开文件句柄
  DWORD    dwFileSize; //文件大小
private:
  HANDLE    hMapping; //映射句柄
  LPVOID    m_pData;
  
  PIMAGE_DOS_HEADER  _dosHeader;
  PIMAGE_NT_HEADERS  _ntHeader;
};


//-----------------------------------------PNExeInfo.cpp

//装载文件:
int CPNExeInfo::LoadPE(LPCTSTR path)
{
  DWORD dwRead=NULL;
  //保存路径:
  m_path=path;

  //以只读方式,其他进程对文件有读写权,打开文件:
  hFile=CreateFile(m_path,GENERIC_READ,FILE_SHARE_WRITE|FILE_SHARE_READ,
                   NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
  if(hFile==INVALID_HANDLE_VALUE){return  -10;}  //-10代表打开文件失败;

  //获取文件大小:
  dwFileSize=GetFileSize(hFile,NULL);
  if(dwFileSize <= 0){CloseHandle(hFile);return -11;} //-11代表获取文件大小失败;

  /*
  //创建镜像:
  hMapping=::CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
  if(hMapping==NULL){
    CloseHandle(hFile);return -20;}  //-20创建镜像出错;

  //映射地址:
  m_pData=::MapViewOfFile(hMapping,FILE_MAP_READ,0,0,0);
  if(m_pData==NULL){CloseHandle(hFile);return -21;} //-21代表影射地址出错;
  */

  //方便以后销毁,采用分配内存方式:



IP属地:北京1楼2007-10-21 00:32回复
      m_pData=(DWORD*)::VirtualAlloc(NULL,dwFileSize,MEM_COMMIT,PAGE_READWRITE);

      ReadFile(hFile,m_pData,dwFileSize,&dwRead,NULL);
      //方便其他函数调用,初始化函数头:
        _dosHeader =(PIMAGE_DOS_HEADER)m_pData;
        _ntHeader  =(PIMAGE_NT_HEADERS)((LONG)_dosHeader+(LONG)_dosHeader->e_lfanew);
      
      //关闭文件:
      CloseHandle(hFile);
      return 0;
    }


    //装载其它进程,方便获得导出,和导入表:
    int CPNExeInfo::LoadPE(DWORD pId)
    {
      DWORD  dwRead=NULL;
      HANDLE hModule=NULL;
        MODULEENTRY32* minfo=new MODULEENTRY32;

      if((int)pId<=0){return -10;}
      
      hModule=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,pId);
      if((DWORD)hModule<=0){return -11;}
      Module32First(hModule, minfo);

      HANDLE hOpenProcess=::OpenProcess(PROCESS_VM_READ|PROCESS_VM_WRITE,FALSE,pId);
      
      //创建地址:
      m_pData=(DWORD*)::VirtualAlloc(NULL,minfo->modBaseSize,MEM_COMMIT,PAGE_READWRITE);
      //读取进程:
      ::ReadProcessMemory(hOpenProcess,minfo->modBaseAddr,m_pData,minfo->modBaseSize,&dwRead);

      _dosHeader =(PIMAGE_DOS_HEADER)m_pData;
        _ntHeader  =(PIMAGE_NT_HEADERS)((LONG)_dosHeader+(LONG)_dosHeader->e_lfanew);
      
      //释放:
      if(hModule!=NULL){CloseHandle(hModule);} 
      if(hOpenProcess!=NULL){CloseHandle(hOpenProcess);}
      return 0;
    }


    //好了,我们只要能加载了,什么都好说:

    输出表:

    PIMAGE_EXPORT_DIRECTORY CPNExeInfo::GetExportInfo(DWORD *dwSize,LPCTSTR *strFun,DWORD *dwAddr,
                           DWORD *dwOrdin,DWORD *dwOffset,LPTSTR DllName)
    {
      PIMAGE_EXPORT_DIRECTORY _exportDir=NULL;
      _exportDir=(PIMAGE_EXPORT_DIRECTORY)_ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
      
      if(_exportDir==NULL){return NULL;}

      _exportDir=(PIMAGE_EXPORT_DIRECTORY)ImageRvaToVa(_ntHeader,_dosHeader,(DWORD)_exportDir,NULL);
      
      //数量初始化:
      DWORD dwNum=_exportDir->NumberOfNames;
      if(dwNum<_exportDir->NumberOfFunctions){dwNum=_exportDir->NumberOfFunctions;}
      if(dwSize!=NULL){*dwSize=dwNum;}

      //名称初始化:
      DWORD **ppdwNames = (DWORD **)_exportDir->AddressOfNames;
        ppdwNames = (PDWORD*)ImageRvaToVa(_ntHeader,_dosHeader,(DWORD)ppdwNames,NULL);
      if(!ppdwNames){return NULL;}

      //地址初始化:
      DWORD **ppdwAddr  = (DWORD **)_exportDir->AddressOfFunctions;
        ppdwAddr = (PDWORD*)ImageRvaToVa(_ntHeader,_dosHeader,(DWORD)ppdwAddr,NULL);
      if(!ppdwAddr){return NULL;}

      //序号初始化:
      DWORD *ppdwOrdin=(DWORD*)ImageRvaToVa(_ntHeader,_dosHeader,(DWORD)_exportDir->AddressOfNameOrdinals,NULL);
      if(!ppdwOrdin){return NULL;}
      
      //获取文件名:
      if(DllName!=NULL){
        char *szdllName=(PSTR)ImageRvaToVa(_ntHeader,_dosHeader,(DWORD)_exportDir->Name,NULL);
        //DllName=szdllName;
        strcpy(DllName,szdllName);
      }

      for(DWORD i=0;i<dwNum;i++)
      {
        char* szFun=(PSTR)ImageRvaToVa(_ntHeader,_dosHeader,(DWORD)*ppdwNames,NULL);
        if(strFun!=NULL){strFun[i]=szFun;}
        if(dwAddr!=NULL){dwAddr[i]=(DWORD)*ppdwAddr;}
        if(dwOffset!=NULL){
          dwOffset[i]=(DWORD)ImageRvaToVa(_ntHeader,_dosHeader,(DWORD)*ppdwAddr,NULL);
          dwOffset[i]=dwOffset[i]-(DWORD)_dosHeader;
    


    IP属地:北京2楼2007-10-21 00:32
    回复
          }
          if(dwOrdin!=NULL){dwOrdin[i]=(WORD)*ppdwOrdin;}

          ppdwOrdin=(DWORD*)((DWORD)ppdwOrdin+2);
          ppdwAddr++;
          ppdwNames++;
        }

        return _exportDir;
      }


      //输入模块:
      PIMAGE_IMPORT_DESCRIPTOR CPNExeInfo::GetImportModule(DWORD *dwSize,LPCTSTR *name)
      {
        PIMAGE_IMPORT_DESCRIPTOR  _importDesc=NULL;

        //获取输入表虚拟地址:
        _importDesc=(PIMAGE_IMPORT_DESCRIPTOR)_ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
        if(_importDesc==NULL){return NULL;}  
        
        //将虚拟地址进行转换:
        _importDesc=(PIMAGE_IMPORT_DESCRIPTOR)::ImageRvaToVa(_ntHeader,m_pData,(DWORD)_importDesc,NULL);
        
        DWORD  dwRe=(DWORD)_importDesc;
        int i=0;
        if(name!=NULL)
        {
          for(;_importDesc->Name!=NULL;i++)
          {
            char *szName=(PSTR)ImageRvaToVa(_ntHeader, _dosHeader, (DWORD)_importDesc->Name, 0);
            name[i]=szName;
            _importDesc++;
          }
        }
        if(dwSize!=NULL)memcpy(dwSize,(DWORD*)&i,sizeof(DWORD));
        _importDesc=(PIMAGE_IMPORT_DESCRIPTOR)dwRe;

        return _importDesc;
      }

      //获取模块的函数:
      PIMAGE_THUNK_DATA CPNExeInfo::GetProcOfModule(LPCTSTR ModuleName,DWORD *dwSize,LPCTSTR *ProcName,
                              DWORD *Hint,DWORD *Offset,DWORD *Value,DWORD *Rva)
      {
        DWORD    dwThunk=NULL;
        PIMAGE_THUNK_DATA  _pThunk=NULL;

        PIMAGE_IMPORT_DESCRIPTOR  _importDesc=NULL;

        //获取输入表虚拟地址:
        _importDesc=(PIMAGE_IMPORT_DESCRIPTOR)_ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
        if(_importDesc==NULL){return NULL;}  
        
        //将虚拟地址进行转换:
        _importDesc=(PIMAGE_IMPORT_DESCRIPTOR)::ImageRvaToVa(_ntHeader,m_pData,(DWORD)_importDesc,NULL);

        for(int i=0;_importDesc->Name!=NULL;i++)
        {
          char *szName=(PSTR)ImageRvaToVa(_ntHeader, _dosHeader, (DWORD)_importDesc->Name, 0);
          if(lstrcmp(ModuleName,szName)==0)
          {
            if(_importDesc->OriginalFirstThunk!=0)
            {
              dwThunk=_importDesc->OriginalFirstThunk;
              _pThunk=(PIMAGE_THUNK_DATA)ImageRvaToVa(_ntHeader,_dosHeader,
                (DWORD)_importDesc->OriginalFirstThunk,NULL);
              break;
            }
            else
            {
              dwThunk=_importDesc->FirstThunk;
              _pThunk=(PIMAGE_THUNK_DATA)ImageRvaToVa(_ntHeader,_dosHeader,
                (DWORD)_importDesc->FirstThunk,NULL);
              break;
            }
          }
          _importDesc++;
        }

        DWORD dwRe=(DWORD)_pThunk;

        if(ProcName==NULL){return _pThunk;}
        for(i=0;_pThunk->u1.AddressOfData!=NULL;i++)
        {
          char *szFun=(PSTR)ImageRvaToVa(_ntHeader,_dosHeader,(DWORD)_pThunk->u1.AddressOfData->Name, 0);
          
          ProcName[i]=szFun;
          if(Hint!=NULL){
            if(szFun!=NULL){memcpy(&Hint[i],szFun-2,2);}
            else{Hint[i]=-1;}
          }
          if(Offset!=NULL){
            Offset[i]=(DWORD)ImageRvaToVa(_ntHeader,_dosHeader,(DWORD)dwThunk,NULL);
            Offset[i]=Offset[i]-(DWORD)m_pData;
          }
          if(Value!=NULL){
            Value[i]=(DWORD)_pThunk->u1.AddressOfData;
            if((Value[i]&0x80000000)==0x80000000){Value[i]&=0x7FFFFFFF;}
          }
          if(Rva!=NULL){
            Rva[i]=dwThunk;
          }
          dwThunk+=4;
          _pThunk++;
        }

        if(dwSize!=NULL)memcpy(dwSize,(DWORD*)&i,sizeof(DWORD));
        _pThunk=(PIMAGE_THUNK_DATA)dwRe;
        return _pThunk;
      }
       
      


      IP属地:北京3楼2007-10-21 00:32
      回复
        好贴,顶了!感谢LZ分享


        IP属地:荷兰4楼2010-07-02 19:18
        回复
          好吧四楼我很无语地飘过。因为我都不知道lz想要表达什么、


          IP属地:福建5楼2011-01-26 15:43
          回复