学逆向论坛

找回密码
立即注册

只需一步,快速开始

发新帖

340

积分

3

好友

9

主题

[原创图文] PE工具编写

发表于 2019-3-16 12:33:39 | 查看: 5772| 回复: 0
主要源代码参考《加密与解密 第四版》书中内容,把它改装成了命令行程序,简化了一些编程步骤:
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_HEADER  pDH = NULL;
        PIMAGE_NT_HEADERS  pNtH = 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[0].VirtualAddress << endl;
        cout << "  Export Table Size:" << hex << pOH->DataDirectory[0].Size << endl;
        cout << "  Import Table Rva:" << hex << pOH->DataDirectory[1].VirtualAddress << endl;
        cout << "  Import Table Size:" << hex << pOH->DataDirectory[1].Size << endl;
        cout << "  Resourse Table Rva:" << hex << pOH->DataDirectory[2].VirtualAddress << endl;
        cout << "  Resourse Table Size:" << hex << pOH->DataDirectory[2].Size << endl;
        cout << "  Exception Table Rva:" << hex << pOH->DataDirectory[3].VirtualAddress << endl;
        cout << "  Exception Table Size:" << hex << pOH->DataDirectory[3].Size << endl;
        cout << "  Security Table Rva:" << hex << pOH->DataDirectory[4].VirtualAddress << endl;
        cout << "  Security Table Size:" << hex << pOH->DataDirectory[4].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_DIRECTORY  GetExportDirectory(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[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
        if (!pExportDir)
                return NULL;
        return  pExportDir;
}

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 name  will 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[j])
                                {
                                        szFuncName = (char*)RvaToPtr(pNTH, ImageBase, pdwNames[j]);
                                        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[1].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 name  will 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[1].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 [0x" << pdwThunk << "]:    " << 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[1];
        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:  在此处引用程序需要的其他头文件
运行效果:
效果.png
温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的认可,还可以获得学币奖励,请尊重他人的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。

小黑屋|手机版|站务邮箱|学逆向论坛 ( 粤ICP备2021023307号 )|网站地图

GMT+8, 2024-4-17 07:48 , Processed in 0.119202 second(s), 42 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表