阅读背景:

PE总结11--PE文件结构之 解析导入表

来源:互联网 
// 导入表2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
#include <windows.h>

DWORD  Rva2Offset(DWORD Rva, PIMAGE_NT_HEADERS32 pNt)
{
  DWORD dwOffset = 0;
  
  //获取区段表
  PIMAGE_SECTION_HEADER  pSecction = IMAGE_FIRST_SECTION(pNt);

  //获取区段的数量  --- nt表中的文件头中
  DWORD dwSize = pNt->FileHeader.NumberOfSections;

  for (DWORD i = 0; i < dwSize; i++)
  {
     if (Rva >= pSecction[i].VirtualAddress &&
       Rva < (pSecction[i].VirtualAddress + pSecction[i].Misc.VirtualSize))
     {
       dwOffset = Rva - pSecction[i].VirtualAddress + pSecction[i].PointerToRawData;
       return dwOffset;
     }
  }

  return dwOffset;
}

 
void ToImpl(PVOID lpFileImage, DWORD dwRet)
{
  //获取DOS头
  PIMAGE_DOS_HEADER  dosHeader = (PIMAGE_DOS_HEADER)lpFileImage;

  if (IMAGE_DOS_SIGNATURE !=dosHeader->e_magic)
  {
     return;
  }

  //获取NT
  PIMAGE_NT_HEADERS32 pNt = (PIMAGE_NT_HEADERS32)((DWORD)lpFileImage + dosHeader->e_lfanew);

  if ( IMAGE_NT_SIGNATURE != pNt->Signature )
  {
     return;
  }

  //获取数据目录表 ----扩展头中
  PIMAGE_DATA_DIRECTORY  pData = pNt->OptionalHeader.DataDirectory;

  //获取导入表RVA
  pData = &(pData[IMAGE_DIRECTORY_ENTRY_IMPORT]);

  //找到文件的偏移
  DWORD dwImpOffset = Rva2Offset(pData->VirtualAddress, pNt);

  //获取导入表的结构
  PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)lpFileImage + dwImpOffset);

  while (pImport->Name)
  {
     //获取导入文件的名称
     DWORD dwImpName = Rva2Offset(pImport->Name, pNt);
     PCHAR pModName = PCHAR((DWORD)lpFileImage + dwImpName);

     printf("\n%s \n", pModName);

     //获取IAT信息
     DWORD dwIATOffset = Rva2Offset(pImport->FirstThunk, pNt);

     PIMAGE_THUNK_DATA32 pIat = (PIMAGE_THUNK_DATA32)((DWORD)lpFileImage + dwIATOffset);
      
     while (pIat->u1.Function)
     {
       //判断最高位是否为1 不为1说明按名称进行导入的
       if (!IMAGE_SNAP_BY_ORDINAL32(pIat->u1.Ordinal))
       {
          ///将名称进行输出
          DWORD dwFunName = Rva2Offset(pIat->u1.AddressOfData, pNt);
          PIMAGE_IMPORT_BY_NAME pFunName = (PIMAGE_IMPORT_BY_NAME)((DWORD)lpFileImage+dwFunName);

          printf("\n hit name %s \n",  pFunName->Name);
       }
       else
       {
          printf("\n %p \n", pIat->u1.Ordinal & 0xFFFF);
       }
       pIat++;
     }
     pImport++;
  }

}


int _tmain(int argc, _TCHAR* argv[])
{
  HANDLE  hFile = nullptr;
  DWORD dwSize = 0;

  LPCTSTR strPath = L"D:\Users\PE\pe01\Debug\HelloWorld.exe";

  //加载到内存
  if (INVALID_HANDLE_VALUE == (hFile = CreateFile(strPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)))
  {
     
     return 0;
  }

  //获取大小
  if (INVALID_FILE_SIZE == (dwSize = GetFileSize(hFile, NULL)))
  {
     CloseHandle(hFile);
     return 0;
  }

  PVOID lpFileImage = nullptr;
  //开辟空间
  if (!(lpFileImage = VirtualAlloc(NULL, dwSize,MEM_COMMIT,PAGE_READWRITE )))
  {
     CloseHandle(hFile);
     return 0;
  }

  DWORD dwRet;
  //读取文件
  if (!ReadFile(hFile, lpFileImage, dwSize, &dwRet, NULL))
  {
     CloseHandle(hFile);
     VirtualFree(lpFileImage, 0, MEM_RELEASE);
     return 0;
  }

  ToImpl(lpFileImage, dwRet);

  system("pause");
  return 0;
}

 
// 导入表2.cpp : 定义控制台应用程序的入口点。
//

#include "stda



你的当前访问异常,请进行认证后继续阅读剩余内容。

分享到: