钞sir 发表于 2019-3-16 12:33:39

PE工具编写

主要源代码参考《加密与解密 第四版》书中内容,把它改装成了命令行程序,简化了一些编程步骤:
peload.h:
#pragma once
#define _PEFUNCS_H_
#pragma comment(lib,"imageHlp.lib")
#define GETTHUNK(pImportDesc) ((DWORD)                        \
         ((PIMAGE_IMPORT_DESCRIPTOR)pImportDesc->OriginalFirstThunk ?                      \
         (PIMAGE_IMPORT_DESCRIPTOR)pImportDesc->OriginalFirstThunk:(PIMAGE_IMPORT_DESCRIPTOR)pImportDesc->FirstThunk \
          ))
#include<imagehlp.h>
#include <iostream>
using namespace std;
typedef struct _MAP_FILE_STRUCT
{
      HANDLE hFile;
      HANDLE hMapping;
      HANDLE ImageBase;
} MAP_FILE_STRUCT, *PMAP_FILE_STRUCT;


BOOL LoadPEFile(LPTSTR lpFilename, PMAP_FILE_STRUCT pstMapFile)
{
      PIMAGE_DOS_HEADER pDH = NULL;
      PIMAGE_NT_HEADERS pNtH = NULL;
      HANDLE hFile;
      HANDLE hMapping;
      LPVOID ImageBase;
      //HANDLE ImageBase;
      hFile = CreateFile(lpFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL, 0);
      if (!hFile)
                return FALSE;
      hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
      if (!hMapping)
      {
                CloseHandle(hFile);
                return FALSE;
      }
      //获得映像基址
      ImageBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
      if (!ImageBase)
      {
                CloseHandle(hMapping);
                CloseHandle(hFile);
                return FALSE;
      }
      pstMapFile->hFile = hFile;
      pstMapFile->hMapping = hMapping;
      pstMapFile->ImageBase = ImageBase;
      return TRUE;
}

BOOL IsPEFile(LPVOID ImageBase)
{
      PIMAGE_DOS_HEADERpDH = NULL;
      PIMAGE_NT_HEADERSpNtH = NULL;
      pDH = (PIMAGE_DOS_HEADER)ImageBase;
      if (pDH->e_magic != IMAGE_DOS_SIGNATURE)         //判断是否'MZ'
      {
                printf("不是有效的PE文件!\n");
                return FALSE;
      }
      pNtH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);      //判断是否'PE'格式
      if (pNtH->Signature != IMAGE_NT_SIGNATURE)
      {
                printf("不是有效的PE文件!\n");
                return FALSE;
      }
      return true;
}

PIMAGE_NT_HEADERS GetNTHeaders(LPVOID ImageBase)
{
      PIMAGE_DOS_HEADER pDH = NULL;
      PIMAGE_NT_HEADERS pNtH = NULL;
      if (!IsPEFile(ImageBase))
                return NULL;
      pDH = (PIMAGE_DOS_HEADER)ImageBase;
      pNtH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);
      return pNtH;
}

PIMAGE_FILE_HEADER GetFileHeader(LPVOID ImageBase)
{
      PIMAGE_NT_HEADERS pNtH = NULL;
      PIMAGE_FILE_HEADER pFH = NULL;
      pNtH = GetNTHeaders(ImageBase);
      if (!pNtH)
                return NULL;
      pFH = &pNtH->FileHeader;
      return pFH;
}

PIMAGE_OPTIONAL_HEADER WINAPI GetOptionalHeader(LPVOID ImageBase)
{
      PIMAGE_OPTIONAL_HEADER pOH = NULL;
      PIMAGE_NT_HEADERS pNtH = NULL;
      pNtH = GetNTHeaders(ImageBase);
      if (!pNtH)
                return NULL;
      pOH = &pNtH->OptionalHeader;
      return pOH;
}

void ShowFileHeaderInfo(LPVOID LocalImageBase)
{
      PIMAGE_DOS_HEADER pDH = NULL;
      PIMAGE_NT_HEADERS pNTH = NULL;
      PIMAGE_FILE_HEADER pFH = NULL;
      pDH = (PIMAGE_DOS_HEADER)LocalImageBase;
      pNTH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);
      pFH = &pNTH->FileHeader;
      cout << "Machine:" << hex << pFH->Machine << endl;
      cout << "NumberOfSections:" << hex << pFH->NumberOfSections << endl;
      cout << "TimeDateStamp:" << hex << pFH->TimeDateStamp << endl;
      cout << "NumberOfSymbols:" << hex << pFH->NumberOfSymbols << endl;
      cout << "SizeOfOptionalHeader:" << hex << pFH->SizeOfOptionalHeader << endl;
      cout << "Characteristics:" << hex << pFH->Characteristics << endl;
}

void ShowOptionalHeaderInfo(LPVOID LocalImageBase)
{
      PIMAGE_DOS_HEADER pDH = NULL;
      PIMAGE_NT_HEADERS pNTH = NULL;
      PIMAGE_OPTIONAL_HEADER pOH = NULL;
      pDH = (PIMAGE_DOS_HEADER)LocalImageBase;
      pNTH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);
      pOH = &pNTH->OptionalHeader;
      cout << "AddressOfEntryPoint:" << hex << pOH->AddressOfEntryPoint << endl;
      cout << "BaseOfCode:" << hex << pOH->BaseOfCode << endl;
      cout << "BaseOfData:" << hex << pOH->BaseOfData << endl;
      cout << "ImageBase:" << hex << pOH->ImageBase << endl;
      cout << "SectionAlignmet:" << hex << pOH->SectionAlignment << endl;
      cout << "FileAlignment:" << hex << pOH->FileAlignment << endl;
      cout << "SizeOfHeaders:" << hex << pOH->SizeOfHeaders << endl;
      cout << "NumberOfRvaAndSizes:" << hex << pOH->NumberOfRvaAndSizes << endl;

}
void ShowDataDirInfo(LPVOID ImageBase)
{
      PIMAGE_DOS_HEADER pDH = NULL;
      PIMAGE_NT_HEADERS pNTH = NULL;
      PIMAGE_OPTIONAL_HEADER pOH = NULL;
      pDH = (PIMAGE_DOS_HEADER)ImageBase;
      pNTH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);
      pOH = &pNTH->OptionalHeader;

      cout << "Export Table Rva:" << hex << pOH->DataDirectory.VirtualAddress << endl;
      cout << "Export Table Size:" << hex << pOH->DataDirectory.Size << endl;
      cout << "Import Table Rva:" << hex << pOH->DataDirectory.VirtualAddress << endl;
      cout << "Import Table Size:" << hex << pOH->DataDirectory.Size << endl;
      cout << "Resourse Table Rva:" << hex << pOH->DataDirectory.VirtualAddress << endl;
      cout << "Resourse Table Size:" << hex << pOH->DataDirectory.Size << endl;
      cout << "Exception Table Rva:" << hex << pOH->DataDirectory.VirtualAddress << endl;
      cout << "Exception Table Size:" << hex << pOH->DataDirectory.Size << endl;
      cout << "Security Table Rva:" << hex << pOH->DataDirectory.VirtualAddress << endl;
      cout << "Security Table Size:" << hex << pOH->DataDirectory.Size << endl;
}

PIMAGE_SECTION_HEADER GetFirstSectionHeader(LPVOID ImageBase)
{
      PIMAGE_NT_HEADERS pNtH;
      pNtH = GetNTHeaders(ImageBase);
      PIMAGE_SECTION_HEADER pSH;
      pSH = IMAGE_FIRST_SECTION(pNtH);
      return pSH;
}

void ShowSectionHeaderInfo(LPVOID ImageNase)
{
      WORD i;
      PIMAGE_FILE_HEADER pFH = NULL;
      PIMAGE_SECTION_HEADER pSH = NULL;
      pFH = GetFileHeader(ImageNase);
      if (!pFH)
                return;
      pSH = GetFirstSectionHeader(ImageNase);
      for (i = 0; i<pFH->NumberOfSections; i++)
      {
                cout << "["<< i <<"]Section Name:" << pSH->Name << endl;
                cout << " VirtualAddress:" << hex << pSH->VirtualAddress << endl;
                cout << " SizeOfRawData:" << hex << pSH->SizeOfRawData << endl;
                cout << " PointerToRelocations:" << hex << pSH->PointerToRelocations << endl;
                cout << " NumberOfLinenumbers:" << hex << pSH->NumberOfLinenumbers << endl;
                cout << " Characteristics:" << hex << pSH->Characteristics << endl;
                cout << endl;
                ++pSH;
      }
}

LPVOID RvaToPtr(PIMAGE_NT_HEADERS pNtH, LPVOID ImageBase, DWORD dwRVA)
{
      return ImageRvaToVa(pNtH, ImageBase, dwRVA, NULL);
}

PIMAGE_EXPORT_DIRECTORYGetExportDirectory(LPVOID ImageBase)
{
      PIMAGE_DOS_HEADER pDH = NULL;
      PIMAGE_NT_HEADERS pNTH = NULL;
      PIMAGE_OPTIONAL_HEADER pOH = NULL;
      PIMAGE_EXPORT_DIRECTORY pExportDir = NULL;
      pDH = (PIMAGE_DOS_HEADER)ImageBase;
      pNTH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);
      pOH = &pNTH->OptionalHeader;
      //theRVA addr must be turn to VA
      pExportDir = (PIMAGE_EXPORT_DIRECTORY)RvaToPtr(pNTH, ImageBase, pOH->DataDirectory.VirtualAddress);
      if (!pExportDir)
                return NULL;
      returnpExportDir;
}

int   ShowExportDirInfo(LPVOID ImageBase)
{

      PIMAGE_DOS_HEADER pDH = NULL;
      PIMAGE_NT_HEADERS pNTH = NULL;
      PIMAGE_OPTIONAL_HEADER pOH = NULL;
      PIMAGE_EXPORT_DIRECTORY pExportDir = NULL;
      pDH = (PIMAGE_DOS_HEADER)ImageBase;
      pNTH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);
      pOH = &pNTH->OptionalHeader;
      pExportDir = GetExportDirectory(ImageBase);
      if (!pExportDir)
      {
                int error = GetLastError();
                if (error == 0)
                        cout << "This File is not include Export Table!" << endl;
                else
                        cout << "Can't get Export Directory:(   ,error code:" << error << endl;
                return 0;
      }
      cout << "AddressOfFunctions:    " << hex << pExportDir->AddressOfFunctions << endl;
      cout << "AddressOfNameOrdinals: " << hex << pExportDir->AddressOfNameOrdinals << endl;
      cout << "AddressOfNames:      " << hex << pExportDir->AddressOfNames << endl;
      cout << "Base:                  " << hex << pExportDir->Base << endl;
      cout << "MajorVersion:          " << hex << pExportDir->MajorVersion << endl;
      cout << "MinorVersion:          " << hex << pExportDir->MinorVersion << endl;
      cout << "Characteristics:       " << hex << pExportDir->Characteristics << endl;
      cout << "Name:                  " << hex << pExportDir->Name << endl;
      cout << "NumberOfFunctions:   " << hex << pExportDir->NumberOfFunctions << endl;
      cout << "NumberOfNames:         " << hex << pExportDir->NumberOfNames << endl;
      cout << "TimeDateStamp:         " << hex << pExportDir->TimeDateStamp << endl;

      //Sometime the string of namewill be error here
      cout << " pExportDir->Name:         " << (char *)ImageRvaToVa(pNTH, ImageBase, pExportDir->Name, NULL) << endl;
      return 1;
}

void   ShowExportFuncsInfo(LPVOID ImageBase)
{

      char*szFuncName;
      UINT                  iNumOfName = 0;
      PDWORD                  pdwRvas, pdwNames;
      PWORD                   pwOrds;
      UINT                  i = 0, j = 0, k = 0;
      PIMAGE_DOS_HEADER pDH = NULL;
      PIMAGE_NT_HEADERS pNTH = NULL;
      PIMAGE_OPTIONAL_HEADER pOH = NULL;
      PIMAGE_EXPORT_DIRECTORY pExportDir = NULL;
      pDH = (PIMAGE_DOS_HEADER)ImageBase;
      pNTH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);
      pOH = &pNTH->OptionalHeader;
      pExportDir = GetExportDirectory(ImageBase);
      if (!pNTH)
                return;
      pExportDir = (PIMAGE_EXPORT_DIRECTORY)GetExportDirectory(ImageBase);
      if (!pExportDir)
                return;

      pwOrds = (PWORD)RvaToPtr(pNTH,ImageBase, pExportDir->AddressOfNameOrdinals);
      pdwRvas = (PDWORD)RvaToPtr(pNTH, ImageBase, pExportDir->AddressOfFunctions);
      pdwNames = (PDWORD)RvaToPtr(pNTH, ImageBase, pExportDir->AddressOfNames);

      if (!pdwRvas)
                return;

      iNumOfName = pExportDir->NumberOfNames;
      printf("123456798");
      for (i = 0; i<pExportDir->NumberOfFunctions; i++)
      {
                if (*pdwRvas)
                {
                        for (j = 0; j<iNumOfName; j++)
                        {
                              if (i == pwOrds)
                              {
                                        szFuncName = (char*)RvaToPtr(pNTH, ImageBase, pdwNames);
                                        cout<<" pExportDir->Name ["<<i+1<<"]:    "<<szFuncName<<endl;
                              }
                        }
                }
                ++pdwRvas;
      }
}

void   ShowImportDirInfo(LPVOID ImageBase)
{
      DWORD dwDataStartRVA;
      PIMAGE_DOS_HEADER pDH = NULL;
      PIMAGE_NT_HEADERS pNTH = NULL;
      PIMAGE_OPTIONAL_HEADER pOH = NULL;
      PIMAGE_IMPORT_DESCRIPTOR pImportDir = NULL;
      pDH = (PIMAGE_DOS_HEADER)ImageBase;
      pNTH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);

      pOH = &pNTH->OptionalHeader;
      dwDataStartRVA = pOH->DataDirectory.VirtualAddress;

      pImportDir = (PIMAGE_IMPORT_DESCRIPTOR)RvaToPtr(pNTH, ImageBase, dwDataStartRVA);

      if (!pImportDir)
      {
                int error = GetLastError();
                if (error == 0)
                        cout << "This File is not include Import Table!" << endl;
                else
                        cout << "Can't get Import Directory:(   ,error code:" << error << endl;
                return;
      }
      while (pImportDir->FirstThunk)
      {
                cout << "Characteristics:            " << hex << pImportDir->Characteristics << endl;
                cout << "FirstThunk(IAT):            " << hex << pImportDir->FirstThunk << endl;
                cout << "ForwarderChain:             " << hex << pImportDir->ForwarderChain << endl;
                cout << "TimeDateStamp:            " << hex << pImportDir->TimeDateStamp << endl;
                cout << "Name:                     " << hex << pImportDir->Name << endl;
                cout << "OriginalFirstThunk(INT):    " << hex << pImportDir->OriginalFirstThunk << endl;

                //Sometime the string of namewill be error here
                cout << " pImportDir->Name:         " << (char *)ImageRvaToVa(pNTH, ImageBase, pImportDir->Name, NULL) << endl;
                ++pImportDir;
      }
}

void ShowImportFuncsByDllIndex(LPVOID ImageBase)
{

      char    * szFuncName;
      DWORD      dwThunk, *pdwThunk = NULL;
      int i = 0;
      DWORD dwDataStartRVA;
      PIMAGE_DOS_HEADER pDH = NULL;
      PIMAGE_NT_HEADERS pNTH = NULL;
      PIMAGE_OPTIONAL_HEADER pOH = NULL;
      PIMAGE_IMPORT_DESCRIPTOR pImportDir = NULL;
      pDH = (PIMAGE_DOS_HEADER)ImageBase;
      pNTH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);

      pOH = &pNTH->OptionalHeader;
      //Get Import Table Addr
      dwDataStartRVA = pOH->DataDirectory.VirtualAddress;
      pImportDir = (PIMAGE_IMPORT_DESCRIPTOR)RvaToPtr(pNTH, ImageBase, dwDataStartRVA);

      PIMAGE_IMPORT_BY_NAME   pByName = NULL;
      dwThunk = GETTHUNK(pImportDir);

      pdwThunk = (DWORD*)RvaToPtr(pNTH, ImageBase, dwThunk);
      if (!pdwThunk)
                return;

      while (*pdwThunk)
      {
                pByName = (PIMAGE_IMPORT_BY_NAME)RvaToPtr(pNTH, ImageBase, (DWORD)(*pdwThunk));
                if (pByName)
                {
                        szFuncName = (char *)pByName->Name;
                        cout << " ImportFuncsByDllIndex :    " << szFuncName << endl;
                }
                ++pdwThunk;
      }
}
PEload.cpp:
// PEload.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>
#include<CommCtrl.h>
#include"peload.h"
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
      LPTSTR lpFilename = argv;
      LPVOID ImageBase;
      PMAP_FILE_STRUCT pstMapFile;
      if (argc == 1)
      {
                printf("没有文件!\n");
                return 0;
      }
      if (LoadPEFile(lpFilename, pstMapFile))
      {
                ImageBase = pstMapFile->ImageBase;
                if (IsPEFile(ImageBase))
                {
                        printf("****************ShowFileHeaderInfo*******************\n");
                        ShowFileHeaderInfo(ImageBase);
                        printf("****************ShowOptionalHeaderInfo***************\n");
                        ShowOptionalHeaderInfo(ImageBase);
                        printf("****************ShowDataDirInfo**********************\n");
                        ShowDataDirInfo(ImageBase);
                        printf("****************ShowSectionHeaderInfo****************\n");
                        ShowSectionHeaderInfo(ImageBase);
                        printf("****************ShowExportDirInfo********************\n");
                        if (ShowExportDirInfo(ImageBase))
                        {
                              printf("****************ShowExportFuncsInfo******************\n");
                              ShowExportFuncsInfo(ImageBase);
                        }
                        printf("****************ShowImportDirInfo********************\n");
                        ShowImportDirInfo(ImageBase);
                        printf("****************ShowImportFuncsByDllIndex************\n");
                        ShowImportFuncsByDllIndex(ImageBase);
                }
      }
      system("pause");
    return 0;
}
stdafx.h:
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//

#pragma once

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>

// TODO:在此处引用程序需要的其他头文件
运行效果:

页: [1]
查看完整版本: PE工具编写