为了账号安全,请及时绑定邮箱和手机立即绑定

IAT 注入ImportInject(dll)

标签:
C++

原理:

PE文件中的每一个导入表都代表一个库(dll),所以你添加一个导入表时,当你调用函数时就会去加载相应的DLL而达到注入。

写法一:

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

//

#include "stdafx.h"

#include<Windows.h>

#include <exception>

#include <iostream>

using namespace std;

BOOL AddImportTable(const WCHAR * wzPEFilePath, char * szInjectDllName, char *szFunctionName);

BOOL AddNewImportDescriptor(const WCHAR * wzPEFilePath, char * szInjectDllName, char *szImportFunctionName);

BOOL AddNewSection(LPCTSTR lpModulePath, DWORD dwNewSectionSize);

DWORD PEAlign(DWORD dwTarNumber, DWORD dwAlignTo);

DWORD RVAToOffset(PIMAGE_NT_HEADERS pImageNTHeader, DWORD dwRVA);

PIMAGE_SECTION_HEADER ImageRVAToSection(PIMAGE_NT_HEADERS pImageNTHeader, DWORD dwRVA);

int main()

{

    WCHAR TargetPath[0x20] = { 0 };

    char DllPath[0x20] = "InjectDll.dll"; //要注入的DLL

    printf("Please Input Target Full Path:\r\n");

    //scanf_s(TargetPath, "%s");

    wcin >> TargetPath;

    AddImportTable(TargetPath, DllPath, "InjectFunction");   //InjectFunction  dll里导出的函数名

    return 0;

}

BOOL AddImportTable(const WCHAR * wzPEFilePath, char * szInjectDllName, char *szFunctionName)

{

    BOOL bOk = FALSE;

    try

    {

        //增加一个叫"WINSUN"的节

        bOk = AddNewSection(wzPEFilePath, 256);

        if (!bOk)

        {

            MessageBox(NULL, L"Add New Section Fail", L"Error", MB_OK);

            return bOk;

        }

        //增加一个导入表

        AddNewImportDescriptor(wzPEFilePath, szInjectDllName, szFunctionName);

    }

    catch (exception* e)

    {

        return bOk;

    }

    return bOk;

}

//

//增加导入表项

//

BOOL AddNewSection(LPCTSTR lpModulePath, DWORD dwNewSectionSize)

{

    BOOL   bOk = FALSE;

    LPVOID lpMemoryModule = NULL;

    LPBYTE lpData = NULL;

    DWORD  dwNewSectionFileSize, dwNewSectionMemorySize;

    HANDLE FileHandle = INVALID_HANDLE_VALUE, MappingHandle = INVALID_HANDLE_VALUE;

    PIMAGE_NT_HEADERS NtHeader = NULL;

    PIMAGE_SECTION_HEADER NewSection = NULL, LastSection = NULL;

    printf("[!] AddNewSection Enter!\n");

    //TODO:可能还涉及关闭windows文件保护

    __try

    {

        //pe文件映射到内存

        FileHandle = CreateFile(

            lpModulePath,

            GENERIC_READ | GENERIC_WRITE,

            FILE_SHARE_READ | FILE_SHARE_WRITE,

            NULL,

            OPEN_EXISTING,

            FILE_ATTRIBUTE_NORMAL,

            NULL

        );

        if (INVALID_HANDLE_VALUE == FileHandle)

        {

            printf("[-] AddNewSection CreateFile Fail!\n");

            goto _EXIT_;

        }

        DWORD dwFileLength = GetFileSize(FileHandle, NULL);

        //映射PE文件

        MappingHandle = CreateFileMapping(FileHandle, NULL, PAGE_READWRITE/* | SEC_IMAGE*/, 0, dwFileLength, L"WINSUN_MAPPING_FILE");

        if (NULL == MappingHandle)

        {

            printf("[-] AddNewSection CreateFileMapping Fail!\n");

            goto _EXIT_;

        }

        lpMemoryModule = MapViewOfFile(MappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, dwFileLength);

        if (NULL == lpMemoryModule)

        {

            printf("[-] AddNewSection MapViewOfFile Fail!\n");

            goto _EXIT_;

        }

        lpData = (LPBYTE)lpMemoryModule;

        //判断是否是PE文件

        if (((PIMAGE_DOS_HEADER)lpData)->e_magic != IMAGE_DOS_SIGNATURE)

        {

            printf("[-] AddNewSection PE Header MZ error!\n");

            goto _EXIT_;

        }

        NtHeader = (PIMAGE_NT_HEADERS)(lpData + ((PIMAGE_DOS_HEADER)(lpData))->e_lfanew);

        if (NtHeader->Signature != IMAGE_NT_SIGNATURE)

        {

            printf("[-] AddNewSection PE Header PE Error!\n");

            goto _EXIT_;

        }

        //判断是否可以增加一个新节

        if (((NtHeader->FileHeader.NumberOfSections + 1) * sizeof(IMAGE_SECTION_HEADER)) > (NtHeader->OptionalHeader.SizeOfHeaders))

        {

            printf("[-] AddNewSection Cannot Add A New Section!\n");

            goto _EXIT_;

        }

        NewSection = (PIMAGE_SECTION_HEADER)(NtHeader + 1) + NtHeader->FileHeader.NumberOfSections;

        LastSection = NewSection - 1;

        DWORD rSize, vSize, rOffset, vOffset;

        //对齐偏移和RVA

        rSize = PEAlign(dwNewSectionSize,

            NtHeader->OptionalHeader.FileAlignment);

        rOffset = PEAlign(LastSection->PointerToRawData + LastSection->SizeOfRawData,

            NtHeader->OptionalHeader.FileAlignment);

        vSize = PEAlign(dwNewSectionSize,

            NtHeader->OptionalHeader.SectionAlignment);

        vOffset = PEAlign(LastSection->VirtualAddress + LastSection->Misc.VirtualSize,

            NtHeader->OptionalHeader.SectionAlignment);

        //填充新节表

        memcpy(NewSection->Name, "WINSUN", strlen("WINSUN"));

        NewSection->VirtualAddress = vOffset;

        NewSection->PointerToRawData = rOffset;

        NewSection->Misc.VirtualSize = vSize;

        NewSection->SizeOfRawData = rSize;

        NewSection->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;

        //修改IMAGE_NT_HEADERS,增加新节表

        NtHeader->FileHeader.NumberOfSections++;

        NtHeader->OptionalHeader.SizeOfImage += vSize;

        NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;

        NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;

        //增加新节到文件尾部

        DWORD dwWriteBytes;

        SetFilePointer(FileHandle, 0, 0, FILE_END);

        PBYTE pbNewSectionContent = new BYTE[rSize];

        ZeroMemory(pbNewSectionContent, rSize);

        bOk = WriteFile(FileHandle, pbNewSectionContent, rSize, &dwWriteBytes, NULL);

        if (!bOk)

        {

            MessageBox(NULL, L"新增节失败", L"Error", MB_OK);

            goto _EXIT_;

        }

    }

    __except (EXCEPTION_EXECUTE_HANDLER)

    {

        printf("[-] AddImportTableItem  Exception!\n");

        return false;

    }

    printf("[!] AddNewSection Exit!\n");

    bOk = true;

_EXIT_:

    if (FileHandle)

    {

        CloseHandle(FileHandle);

    }

    if (lpMemoryModule)

    {

        UnmapViewOfFile(lpMemoryModule);

    }

    if (MappingHandle)

    {

        CloseHandle(MappingHandle);

    }

    return true;

}

//内存对齐

DWORD PEAlign(DWORD dwTarNumber, DWORD dwAlignTo)

{

    return(((dwTarNumber + dwAlignTo - 1) / dwAlignTo)*dwAlignTo);

}

//增加一个导入表

BOOL AddNewImportDescriptor(const WCHAR * wzPEFilePath, char * szInjectDllName, char *szImportFunctionName)

{

    BOOL bOk = FALSE;

    LPVOID lpMemoryModule = NULL;

    LPBYTE lpData = NULL;

    DWORD  dwNewSecFileSize, dwNewSecMemSize;

    HANDLE FileHandle = INVALID_HANDLE_VALUE, MappingHandle = INVALID_HANDLE_VALUE;

    PIMAGE_NT_HEADERS NtHeader = NULL;

    PIMAGE_IMPORT_DESCRIPTOR ImportTable = NULL;

    PIMAGE_SECTION_HEADER    SectionHeader = NULL;

    __try

    {

        //pe文件映射到内存

        FileHandle = CreateFile(

            wzPEFilePath,

            GENERIC_READ | GENERIC_WRITE,

            FILE_SHARE_READ | FILE_SHARE_WRITE,

            NULL,

            OPEN_EXISTING,

            FILE_ATTRIBUTE_NORMAL,

            NULL

        );

        if (INVALID_HANDLE_VALUE == FileHandle)

        {

            printf("[-] AddNewImportDescriptor CreateFile fail!\n");

            goto _EXIT_;

        }

        DWORD dwFileLength = GetFileSize(FileHandle, NULL);

        MappingHandle = CreateFileMapping(FileHandle, NULL, PAGE_READWRITE/* | SEC_IMAGE*/, 0, dwFileLength, L"WINSUN_MAPPING_FILE");

        if (NULL == MappingHandle)

        {

            printf("[-] AddNewImportDescriptor CreateFileMapping fail!\n");

            goto _EXIT_;

        }

        lpMemoryModule = MapViewOfFile(MappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, dwFileLength);

        if (NULL == lpMemoryModule)

        {

            printf("[-] AddNewImportDescriptor MapViewOfFile fail!\n");

            goto _EXIT_;

        }

        lpData = (LPBYTE)lpMemoryModule;

        //判断是否是PE

        if (((PIMAGE_DOS_HEADER)lpData)->e_magic != IMAGE_DOS_SIGNATURE)

        {

            printf("[-] AddNewImportDescriptor PE Header MZ error!\n");

            goto _EXIT_;

        }

        NtHeader = (PIMAGE_NT_HEADERS)(lpData + ((PIMAGE_DOS_HEADER)(lpData))->e_lfanew);

        if (NtHeader->Signature != IMAGE_NT_SIGNATURE)

        {

            printf("[-] AddNewImportDescriptor PE Header PE error!\n");

            goto _EXIT_;

        }

        ImportTable = (PIMAGE_IMPORT_DESCRIPTOR)(lpData + RVAToOffset(NtHeader, NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));

        BOOL bBoundImport = FALSE;

        if (ImportTable->Characteristics == 0 && ImportTable->FirstThunk != 0)

        {

            bBoundImport = TRUE;

            NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;

            NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;

        }

        SectionHeader = (PIMAGE_SECTION_HEADER)(NtHeader + 1) + NtHeader->FileHeader.NumberOfSections - 1;

        PBYTE pbNewSection = SectionHeader->PointerToRawData + lpData;

        int i = 0;

        while (ImportTable->FirstThunk != 0)

        {

            memcpy(pbNewSection, ImportTable, sizeof(IMAGE_IMPORT_DESCRIPTOR));

            ImportTable++;

            pbNewSection += sizeof(IMAGE_IMPORT_DESCRIPTOR);

            i++;

        }

        memcpy(pbNewSection, (pbNewSection - sizeof(IMAGE_IMPORT_DESCRIPTOR)), sizeof(IMAGE_IMPORT_DESCRIPTOR));

        DWORD dwDelt = SectionHeader->VirtualAddress - SectionHeader->PointerToRawData;

        //avoid import not need table

        PIMAGE_THUNK_DATA pImgThunkData = (PIMAGE_THUNK_DATA)(pbNewSection + sizeof(IMAGE_IMPORT_DESCRIPTOR) * 2);

        //import dll name

        PBYTE pszDllNamePosition = (PBYTE)(pImgThunkData + 2);

        memcpy(pszDllNamePosition, szInjectDllName, strlen(szInjectDllName));

        pszDllNamePosition[strlen(szInjectDllName)] = 0;

        //确定IMAGE_IMPORT_BY_NAM的位置

        PIMAGE_IMPORT_BY_NAME pImgImportByName = (PIMAGE_IMPORT_BY_NAME)(pszDllNamePosition + strlen(szInjectDllName) + 1);

        //init IMAGE_THUNK_DATA

        pImgThunkData->u1.Ordinal = dwDelt + (DWORD)pImgImportByName - (DWORD)lpData;

        //init IMAGE_IMPORT_BY_NAME

        pImgImportByName->Hint = 1;

        memcpy(pImgImportByName->Name, szImportFunctionName, strlen(szImportFunctionName)); //== dwDelt + (DWORD)pszFuncNamePosition - (DWORD)lpData ;

        pImgImportByName->Name[strlen(szImportFunctionName)] = 0;

        //init OriginalFirstThunk

        if (bBoundImport)

        {

            ((PIMAGE_IMPORT_DESCRIPTOR)pbNewSection)->OriginalFirstThunk = 0;

        }

        else

            ((PIMAGE_IMPORT_DESCRIPTOR)pbNewSection)->OriginalFirstThunk = dwDelt + (DWORD)pImgThunkData - (DWORD)lpData;

        //init FirstThunk

        ((PIMAGE_IMPORT_DESCRIPTOR)pbNewSection)->FirstThunk = dwDelt + (DWORD)pImgThunkData - (DWORD)lpData;

        //init Name

        ((PIMAGE_IMPORT_DESCRIPTOR)pbNewSection)->Name = dwDelt + (DWORD)pszDllNamePosition - (DWORD)lpData;

        //改变导入表

        NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = SectionHeader->VirtualAddress;

        NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = (i + 1) * sizeof(IMAGE_IMPORT_DESCRIPTOR);

    }

    __except (EXCEPTION_EXECUTE_HANDLER)

    {

        printf("[-] AddNewImportDescriptor  Exception!\n");

        return false;

    }

_EXIT_:

    if (FileHandle)

    {

        CloseHandle(FileHandle);

    }

    if (lpMemoryModule)

    {

        UnmapViewOfFile(lpMemoryModule);

    }

    if (MappingHandle)

    {

        CloseHandle(MappingHandle);

    }

    return true;

}

//

// calulates the Offset from a RVA

// Base    - base of the MMF

// dwRVA - the RVA to calculate

// returns 0 if an error occurred else the calculated Offset will be returned

DWORD RVAToOffset(PIMAGE_NT_HEADERS pImageNTHeader, DWORD dwRVA)

{

    DWORD _offset;

    PIMAGE_SECTION_HEADER section;

    section = ImageRVAToSection(pImageNTHeader, dwRVA);//ImageRvaToSection(pimage_nt_headers,Base,dwRVA);

    if (section == NULL)

    {

        return(0);

    }

    _offset = dwRVA + section->PointerToRawData - section->VirtualAddress;

    return(_offset);

}

PIMAGE_SECTION_HEADER ImageRVAToSection(PIMAGE_NT_HEADERS pImageNTHeader, DWORD dwRVA)

{

    int i;

    PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)(pImageNTHeader + 1);

    for (i = 0; i < pImageNTHeader->FileHeader.NumberOfSections; i++)

    {

        if ((dwRVA >= (pSectionHeader + i)->VirtualAddress) && (dwRVA <= ((pSectionHeader + i)->VirtualAddress + (pSectionHeader + i)->SizeOfRawData)))

        {

            return ((PIMAGE_SECTION_HEADER)(pSectionHeader + i));

        }

    }

    return(NULL);

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

写法二:

// ImportInject.h

#pragma once

#include "afxcmn.h"

// ImportInject 对话框

class ImportInject : public CDialogEx

{

    DECLARE_DYNAMIC(ImportInject)

public:

    ImportInject(CWnd* pParent = NULL);   // 标准构造函数

    virtual ~ImportInject();

// 对话框数据

    enum { IDD = IDD_DIALOG1 };

protected:

    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

    DECLARE_MESSAGE_MAP()

public:

    CString m_strFile;

    CString m_strDll;

    CString m_strFun;

    CString m_strTempPath;

    afx_msg void OnBnClickedButton1();

    afx_msg void OnBnClickedButton2();

    CListCtrl m_strFunList;

    afx_msg void OnBnClickedButton3();

};

// ImportInject.cpp

// ImportInject.cpp : 实现文件

//

#include "stdafx.h"

#include "MyInjectTool.h"

#include "ImportInject.h"

#include "afxdialogex.h"

#include "PEFuncs.h"

#include <IMAGEHLP.H>

// ImportInject 对话框

IMPLEMENT_DYNAMIC(ImportInject, CDialogEx)

ImportInject::ImportInject(CWnd* pParent /*=NULL*/)

    : CDialogEx(ImportInject::IDD, pParent)

    , m_strFile(_T(""))

    , m_strDll(_T(""))

    , m_strFun(_T(""))

{

}

ImportInject::~ImportInject()

{

}

void ImportInject::DoDataExchange(CDataExchange* pDX)

{

    CDialogEx::DoDataExchange(pDX);

    DDX_Text(pDX, IDC_EDIT1, m_strFile);

    DDX_Text(pDX, IDC_EDIT2, m_strDll);

    DDX_Text(pDX, IDC_EDIT3, m_strFun);

    DDX_Control(pDX, IDC_LIST1, m_strFunList);

}

BEGIN_MESSAGE_MAP(ImportInject, CDialogEx)

    ON_BN_CLICKED(IDC_BUTTON1, &ImportInject::OnBnClickedButton1)

    ON_BN_CLICKED(IDC_BUTTON2, &ImportInject::OnBnClickedButton2)

    ON_BN_CLICKED(IDC_BUTTON3, &ImportInject::OnBnClickedButton3)

END_MESSAGE_MAP()

// ImportInject 消息处理程序

/*******************************************************

*函数功能:计算内存对齐或者文件对齐后的大小

*函数参数:参数1:实际大小,参数2:对齐值

*函数返回:DWORD

*注意事项:无 

*******************************************************/

DWORD ClacAlignment(DWORD dwSize, DWORD dwAlign)

{

    if (dwSize % dwAlign != 0)

    {

        return (dwSize / dwAlign + 1)*dwAlign;

    }

    else

    {

        return dwSize;

    }

}

void ImportInject::OnBnClickedButton1()

{

    // TODO:  在此添加控件通知处理程序代码

    BOOL bRet = FALSE;

    // TODO: Add your control notification handler code here

    char szFilter[] = "可执行文件|*.exe";

    CFileDialog fileDlg(TRUE, "exe", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);

    char szExePath[MAX_PATH] = { 0 };

    char *szExe = "Temp.exe";

    //获取当前进程已加载模块的文件的完整路径

    GetModuleFileName(NULL, szExePath, MAX_PATH);

    (strrchr(szExePath, '\\'))[1] = 0;

    //将两个char类型连接

    strcat(szExePath, szExe);

    m_strTempPath = szExePath;

    if (fileDlg.DoModal() == IDOK)

    {

        m_strFile = fileDlg.GetPathName();

    }

    //复制一份文件用于修改,源文件保留。

    bRet = ::CopyFile(m_strFile.GetBuffer(0), m_strTempPath.GetBuffer(0), FALSE);

    if (bRet == 0)

    {

        MessageBox("复制文件失败");

    }

    //创建文件映射

    LoadFileR(m_strFile.GetBuffer(0), &theApp.m_stMapFile);

// 唯一的一个 CMyInjectToolApp 对象

//CMyInjectToolApp theApp;

//MAP_FILE_STRUCT m_stMapFile;

//#include "MyInjectTool.h"

//typedef struct _MAP_FILE_STRUCT

//{

//  HANDLE hFile;

//  HANDLE hMapping;

//  LPVOID ImageBase;

//}  MAP_FILE_STRUCT, *PMAP_FILE_STRUCT;

    //简单判断是否为PE

    if (!IsPEFile(theApp.m_stMapFile.ImageBase))

    {

        ::MessageBox(m_hWnd, "不是有效的PE文件", "不是有效的PE文件", MB_OK);

        //卸载文件映射

        UnLoadFile(&theApp.m_stMapFile);

        //EnableEditCtrl(hWnd, FALSE);

        return;

    }

    UpdateData(FALSE);

}

void ImportInject::OnBnClickedButton2()

{

    // TODO:  在此添加控件通知处理程序代码

    UpdateData(TRUE);

    if (m_strFun.GetLength() == 0)

    {

        MessageBox("请输入DLL函数名");

        return;

    }

    static int nIndex = 0;

    m_strFunList.InsertItem(nIndex, m_strFun);

    m_strFun.Empty();

    nIndex++;

}

void ImportInject::OnBnClickedButton3()

{

    // TODO:  在此添加控件通知处理程序代码

    UpdateData(FALSE);

    // TODO: Add your control notification handler code here

    FILE* fp;

    //最后一个节

    PIMAGE_SECTION_HEADER lpImgLastSection;

    //要添加的区块

    IMAGE_SECTION_HEADER ImgNewSection;

    //第一个节头

    PIMAGE_SECTION_HEADER lpFirstSectionHeader;

    //打开源文件修改。

    PIMAGE_NT_HEADERS lpNtHeader = new IMAGE_NT_HEADERS;

    PIMAGE_NT_HEADERS lpNewNtHeader = new IMAGE_NT_HEADERS;

    //节的数目

    int nSectionNum = 0;

    //新节的RVA

    DWORD dwNewSectionRVA, dwNewImportRva;

    //新节的文件偏移

    DWORD dwNewFA = 0;

    //节对齐

    int nSectionAlignment = 0;

    //文件对齐

    int nFileAlignment = 0;

    //DLL名称的长度

    int nDllLen = 0;

    //需要写入的函数数目

    int nFunNum = m_strFunList.GetItemCount();

    //相对于新节的文件偏移

    DWORD dwNewOffset = 0;

    //要添加的节表头

    //IMAGE_SECTION_HEADER ImgNewSection;

    PIMAGE_IMPORT_DESCRIPTOR lpImport, lpNewImport;

    //原来导入表的大小,和新导入表的大小

    DWORD dwImportSize, dwNewImportSize;

    //计算新节头的文件偏移

    DWORD dwNewSectionOffset;

    fp = ::fopen(m_strTempPath.GetBuffer(0), "rb+");

    if (fp == NULL)

    {

        ::DeleteFile(m_strTempPath.GetBuffer(0));

        MessageBox("打开临时文件失败!!");

        return;

    }

    lpFirstSectionHeader = GetFirstSectionHeader(theApp.m_stMapFile.ImageBase);

    lpNtHeader = GetNtHeaders(theApp.m_stMapFile.ImageBase);

    nSectionNum = lpNtHeader->FileHeader.NumberOfSections;

    nSectionAlignment = lpNtHeader->OptionalHeader.SectionAlignment;

    nFileAlignment = lpNtHeader->OptionalHeader.FileAlignment;

    //获取导入表的指针

    lpImport = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(theApp.m_stMapFile.ImageBase, FALSE, IMAGE_DIRECTORY_ENTRY_IMPORT, &dwImportSize);

    //计算新的导入表的大小:旧的导入表大小 + 新的导入表大小

    dwNewImportSize = dwImportSize + sizeof(IMAGE_IMPORT_DESCRIPTOR);

    //获取最后一个节头

    lpImgLastSection = lpFirstSectionHeader + (nSectionNum - 1);

    //获取新节的RVA

    dwNewSectionRVA = lpImgLastSection->VirtualAddress

        + ClacAlignment(lpImgLastSection->Misc.VirtualSize, nSectionAlignment);

    //计算新的文件偏移

    dwNewFA = lpImgLastSection->PointerToRawData

        + ClacAlignment(lpImgLastSection->SizeOfRawData, nFileAlignment);

    //1.在复制的文件中写入DLL名

    fseek(fp, dwNewFA, SEEK_SET);

    dwNewOffset = m_strDll.GetLength() + 1;

    fwrite(m_strDll.GetBuffer(0), dwNewOffset, 1, fp);

    DWORD *arrINTRva = new DWORD[nFunNum + 1];

    memset(arrINTRva, 0, sizeof(DWORD)*(nFunNum + 1));

    //2.写入所有的的IMAGE_IMPORT_BY_NAME结构,也就是写入所有函数名

    for (int i = 0; i < nFunNum; i++)

    {

        DWORD dwTempRva = 0;

        static int nFunLen = 0;

        PIMAGE_IMPORT_BY_NAME pImportFun = new IMAGE_IMPORT_BY_NAME;

        pImportFun->Hint = i;

        CString strFunName = m_strFunList.GetItemText(i, 0);

        fseek(fp, dwNewFA + dwNewOffset, SEEK_SET);

        //计算IMAGE_IMPORT_BY_NAME的RVA存入数组

        dwTempRva = dwNewSectionRVA + dwNewOffset;

        arrINTRva[i] = dwTempRva;

        dwNewOffset = dwNewOffset + strFunName.GetLength() + 1 + sizeof(WORD);

        memcpy(pImportFun->Name, strFunName.GetBuffer(0), strFunName.GetLength() + 1);

        fwrite(pImportFun, strFunName.GetLength() + 1 + sizeof(WORD), 1, fp);

    }

    DWORD dwINTRVA = dwNewSectionRVA + dwNewOffset;

    //3.写入所有的的INT结构

    for (int i = 0; i < nFunNum + 1; i++)

    {

        fseek(fp, dwNewFA + dwNewOffset, SEEK_SET);

        dwNewOffset += sizeof(DWORD);

        //末尾填充0结构体

        fwrite(&arrINTRva[i], sizeof(DWORD), 1, fp);

    }

    //4.申请新空间存放旧的的IID和新的IID

    lpNewImport = (PIMAGE_IMPORT_DESCRIPTOR)malloc(dwNewImportSize);

    memset(lpNewImport, 0, dwNewImportSize);

    memcpy(lpNewImport, lpImport, dwImportSize);

    int i = 0;

    while (1)

    {

        if (lpNewImport[i].OriginalFirstThunk == 0 && lpNewImport[i].TimeDateStamp == 0 &&

            lpNewImport[i].ForwarderChain == 0 && lpNewImport[i].Name == 0 && lpNewImport[i].FirstThunk == 0)

        {

            lpNewImport[i].Name = dwNewSectionRVA;

            lpNewImport[i].TimeDateStamp = 0;

            lpNewImport[i].ForwarderChain = 0;

            lpNewImport[i].FirstThunk = dwINTRVA;

            lpNewImport[i].OriginalFirstThunk = dwINTRVA;

            break;

        }

        else i++;

    }

    //计算新的导入表RVA

    dwNewImportRva = dwNewSectionRVA + dwNewOffset;

    //写入所有的导入表项

    fseek(fp, dwNewFA + dwNewOffset, SEEK_SET);

    fwrite(lpNewImport, dwNewImportSize, 1, fp);

    dwNewOffset += dwNewImportSize;

    //计算文件对齐需要补零的值

    DWORD dwFileAlign = ClacAlignment(dwNewOffset, nFileAlignment) - dwNewOffset;

    for (size_t i = 0; i < dwFileAlign; i++)

    {

        fputc('\0', fp);

    }

    //5.添加一个新节表头项

    memset(&ImgNewSection, 0, sizeof(IMAGE_SECTION_HEADER));

    //添加名为.newsec的新节

    strcpy((char*)ImgNewSection.Name, ".newsec");

    ImgNewSection.VirtualAddress = dwNewSectionRVA;

    ImgNewSection.PointerToRawData = dwNewFA;

    ImgNewSection.Misc.VirtualSize = ClacAlignment(dwNewOffset, nSectionAlignment);

    ImgNewSection.SizeOfRawData = ClacAlignment(dwNewOffset, nFileAlignment);

    ImgNewSection.Characteristics = 0xC0000040;

    //计算新节头的文件偏移

    dwNewSectionOffset = (DWORD)lpFirstSectionHeader -

        (DWORD)theApp.m_stMapFile.ImageBase + sizeof(IMAGE_SECTION_HEADER)*nSectionNum;

    fseek(fp, dwNewSectionOffset, 0);

    //写入节表头

    fwrite(&ImgNewSection, sizeof(IMAGE_SECTION_HEADER), 1, fp);

    memcpy(&ImgNewSection, lpFirstSectionHeader, sizeof(IMAGE_SECTION_HEADER));

    fseek(fp, (DWORD)lpFirstSectionHeader - (DWORD)theApp.m_stMapFile.ImageBase, SEEK_SET);

    fwrite(&ImgNewSection, sizeof(IMAGE_SECTION_HEADER), 1, fp);

    //6.更新NT头数据

    memcpy(lpNewNtHeader, lpNtHeader, sizeof(IMAGE_NT_HEADERS));

    int nNewImageSize = lpNtHeader->OptionalHeader.SizeOfImage + ClacAlignment(dwNewOffset, nSectionAlignment);

    lpNewNtHeader->OptionalHeader.SizeOfImage = nNewImageSize;

    lpNewNtHeader->OptionalHeader.DataDirectory[11].Size = 0;

    lpNewNtHeader->OptionalHeader.DataDirectory[11].VirtualAddress = 0;

    lpNewNtHeader->OptionalHeader.DataDirectory[12].Size = 0;

    lpNewNtHeader->OptionalHeader.DataDirectory[12].VirtualAddress = 0;

    lpNewNtHeader->FileHeader.NumberOfSections = nSectionNum + 1;

    lpNewNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = dwNewImportRva;

    lpNewNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = dwNewImportSize;

    //写入新的NT头

    fseek(fp, (DWORD)(lpNtHeader)-(DWORD)theApp.m_stMapFile.ImageBase, SEEK_SET);

    fwrite(lpNewNtHeader, sizeof(IMAGE_NT_HEADERS), 1, fp);

    if (fp != NULL)

    {

        fclose(fp);

    }

    UnLoadFile(&theApp.m_stMapFile);

    //释放扫尾工作

    if (arrINTRva != NULL)

    {

        delete[] arrINTRva;

        arrINTRva = NULL;

    }

}

//MyInjectTool.h

// ImportInject.cpp : 实现文件

//

#include "stdafx.h"

#include "MyInjectTool.h"

#include "ImportInject.h"

#include "afxdialogex.h"

#include "PEFuncs.h"

#include <IMAGEHLP.H>

// ImportInject 对话框

IMPLEMENT_DYNAMIC(ImportInject, CDialogEx)

ImportInject::ImportInject(CWnd* pParent /*=NULL*/)

    : CDialogEx(ImportInject::IDD, pParent)

    , m_strFile(_T(""))

    , m_strDll(_T(""))

    , m_strFun(_T(""))

{

}

ImportInject::~ImportInject()

{

}

void ImportInject::DoDataExchange(CDataExchange* pDX)

{

    CDialogEx::DoDataExchange(pDX);

    DDX_Text(pDX, IDC_EDIT1, m_strFile);

    DDX_Text(pDX, IDC_EDIT2, m_strDll);

    DDX_Text(pDX, IDC_EDIT3, m_strFun);

    DDX_Control(pDX, IDC_LIST1, m_strFunList);

}

BEGIN_MESSAGE_MAP(ImportInject, CDialogEx)

    ON_BN_CLICKED(IDC_BUTTON1, &ImportInject::OnBnClickedButton1)

    ON_BN_CLICKED(IDC_BUTTON2, &ImportInject::OnBnClickedButton2)

    ON_BN_CLICKED(IDC_BUTTON3, &ImportInject::OnBnClickedButton3)

END_MESSAGE_MAP()

// ImportInject 消息处理程序

/*******************************************************

*函数功能:计算内存对齐或者文件对齐后的大小

*函数参数:参数1:实际大小,参数2:对齐值

*函数返回:DWORD

*注意事项:无 

*******************************************************/

DWORD ClacAlignment(DWORD dwSize, DWORD dwAlign)

{

    if (dwSize % dwAlign != 0)

    {

        return (dwSize / dwAlign + 1)*dwAlign;

    }

    else

    {

        return dwSize;

    }

}

void ImportInject::OnBnClickedButton1()

{

    // TODO:  在此添加控件通知处理程序代码

    BOOL bRet = FALSE;

    // TODO: Add your control notification handler code here

    char szFilter[] = "可执行文件|*.exe";

    CFileDialog fileDlg(TRUE, "exe", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);

    char szExePath[MAX_PATH] = { 0 };

    char *szExe = "Temp.exe";

    //获取当前进程已加载模块的文件的完整路径

    GetModuleFileName(NULL, szExePath, MAX_PATH);

    (strrchr(szExePath, '\\'))[1] = 0;

    //将两个char类型连接

    strcat(szExePath, szExe);

    m_strTempPath = szExePath;

    if (fileDlg.DoModal() == IDOK)

    {

        m_strFile = fileDlg.GetPathName();

    }

    //复制一份文件用于修改,源文件保留。

    bRet = ::CopyFile(m_strFile.GetBuffer(0), m_strTempPath.GetBuffer(0), FALSE);

    if (bRet == 0)

    {

        MessageBox("复制文件失败");

    }

    //创建文件映射

    LoadFileR(m_strFile.GetBuffer(0), &theApp.m_stMapFile);

// 唯一的一个 CMyInjectToolApp 对象

//CMyInjectToolApp theApp;

//MAP_FILE_STRUCT m_stMapFile;

//#include "MyInjectTool.h"

//typedef struct _MAP_FILE_STRUCT

//{

//  HANDLE hFile;

//  HANDLE hMapping;

//  LPVOID ImageBase;

//}  MAP_FILE_STRUCT, *PMAP_FILE_STRUCT;

    //简单判断是否为PE

    if (!IsPEFile(theApp.m_stMapFile.ImageBase))

    {

        ::MessageBox(m_hWnd, "不是有效的PE文件", "不是有效的PE文件", MB_OK);

        //卸载文件映射

        UnLoadFile(&theApp.m_stMapFile);

        //EnableEditCtrl(hWnd, FALSE);

        return;

    }

    UpdateData(FALSE);

}

void ImportInject::OnBnClickedButton2()

{

    // TODO:  在此添加控件通知处理程序代码

    UpdateData(TRUE);

    if (m_strFun.GetLength() == 0)

    {

        MessageBox("请输入DLL函数名");

        return;

    }

    static int nIndex = 0;

    m_strFunList.InsertItem(nIndex, m_strFun);

    m_strFun.Empty();

    nIndex++;

}

void ImportInject::OnBnClickedButton3()

{

    // TODO:  在此添加控件通知处理程序代码

    UpdateData(FALSE);

    // TODO: Add your control notification handler code here

    FILE* fp;

    //最后一个节

    PIMAGE_SECTION_HEADER lpImgLastSection;

    //要添加的区块

    IMAGE_SECTION_HEADER ImgNewSection;

    //第一个节头

    PIMAGE_SECTION_HEADER lpFirstSectionHeader;

    //打开源文件修改。

    PIMAGE_NT_HEADERS lpNtHeader = new IMAGE_NT_HEADERS;

    PIMAGE_NT_HEADERS lpNewNtHeader = new IMAGE_NT_HEADERS;

    //节的数目

    int nSectionNum = 0;

    //新节的RVA

    DWORD dwNewSectionRVA, dwNewImportRva;

    //新节的文件偏移

    DWORD dwNewFA = 0;

    //节对齐

    int nSectionAlignment = 0;

    //文件对齐

    int nFileAlignment = 0;

    //DLL名称的长度

    int nDllLen = 0;

    //需要写入的函数数目

    int nFunNum = m_strFunList.GetItemCount();

    //相对于新节的文件偏移

    DWORD dwNewOffset = 0;

    //要添加的节表头

    //IMAGE_SECTION_HEADER ImgNewSection;

    PIMAGE_IMPORT_DESCRIPTOR lpImport, lpNewImport;

    //原来导入表的大小,和新导入表的大小

    DWORD dwImportSize, dwNewImportSize;

    //计算新节头的文件偏移

    DWORD dwNewSectionOffset;

    fp = ::fopen(m_strTempPath.GetBuffer(0), "rb+");

    if (fp == NULL)

    {

        ::DeleteFile(m_strTempPath.GetBuffer(0));

        MessageBox("打开临时文件失败!!");

        return;

    }

    lpFirstSectionHeader = GetFirstSectionHeader(theApp.m_stMapFile.ImageBase);

    lpNtHeader = GetNtHeaders(theApp.m_stMapFile.ImageBase);

    nSectionNum = lpNtHeader->FileHeader.NumberOfSections;

    nSectionAlignment = lpNtHeader->OptionalHeader.SectionAlignment;

    nFileAlignment = lpNtHeader->OptionalHeader.FileAlignment;

    //获取导入表的指针

    lpImport = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(theApp.m_stMapFile.ImageBase, FALSE, IMAGE_DIRECTORY_ENTRY_IMPORT, &dwImportSize);

    //计算新的导入表的大小:旧的导入表大小 + 新的导入表大小

    dwNewImportSize = dwImportSize + sizeof(IMAGE_IMPORT_DESCRIPTOR);

    //获取最后一个节头

    lpImgLastSection = lpFirstSectionHeader + (nSectionNum - 1);

    //获取新节的RVA

    dwNewSectionRVA = lpImgLastSection->VirtualAddress

        + ClacAlignment(lpImgLastSection->Misc.VirtualSize, nSectionAlignment);

    //计算新的文件偏移

    dwNewFA = lpImgLastSection->PointerToRawData

        + ClacAlignment(lpImgLastSection->SizeOfRawData, nFileAlignment);

    //1.在复制的文件中写入DLL名

    fseek(fp, dwNewFA, SEEK_SET);

    dwNewOffset = m_strDll.GetLength() + 1;

    fwrite(m_strDll.GetBuffer(0), dwNewOffset, 1, fp);

    DWORD *arrINTRva = new DWORD[nFunNum + 1];

    memset(arrINTRva, 0, sizeof(DWORD)*(nFunNum + 1));

    //2.写入所有的的IMAGE_IMPORT_BY_NAME结构,也就是写入所有函数名

    for (int i = 0; i < nFunNum; i++)

    {

        DWORD dwTempRva = 0;

        static int nFunLen = 0;

        PIMAGE_IMPORT_BY_NAME pImportFun = new IMAGE_IMPORT_BY_NAME;

        pImportFun->Hint = i;

        CString strFunName = m_strFunList.GetItemText(i, 0);

        fseek(fp, dwNewFA + dwNewOffset, SEEK_SET);

        //计算IMAGE_IMPORT_BY_NAME的RVA存入数组

        dwTempRva = dwNewSectionRVA + dwNewOffset;

        arrINTRva[i] = dwTempRva;

        dwNewOffset = dwNewOffset + strFunName.GetLength() + 1 + sizeof(WORD);

        memcpy(pImportFun->Name, strFunName.GetBuffer(0), strFunName.GetLength() + 1);

        fwrite(pImportFun, strFunName.GetLength() + 1 + sizeof(WORD), 1, fp);

    }

    DWORD dwINTRVA = dwNewSectionRVA + dwNewOffset;

    //3.写入所有的的INT结构

    for (int i = 0; i < nFunNum + 1; i++)

    {

        fseek(fp, dwNewFA + dwNewOffset, SEEK_SET);

        dwNewOffset += sizeof(DWORD);

        //末尾填充0结构体

        fwrite(&arrINTRva[i], sizeof(DWORD), 1, fp);

    }

    //4.申请新空间存放旧的的IID和新的IID

    lpNewImport = (PIMAGE_IMPORT_DESCRIPTOR)malloc(dwNewImportSize);

    memset(lpNewImport, 0, dwNewImportSize);

    memcpy(lpNewImport, lpImport, dwImportSize);

    int i = 0;

    while (1)

    {

        if (lpNewImport[i].OriginalFirstThunk == 0 && lpNewImport[i].TimeDateStamp == 0 &&

            lpNewImport[i].ForwarderChain == 0 && lpNewImport[i].Name == 0 && lpNewImport[i].FirstThunk == 0)

        {

            lpNewImport[i].Name = dwNewSectionRVA;

            lpNewImport[i].TimeDateStamp = 0;

            lpNewImport[i].ForwarderChain = 0;

            lpNewImport[i].FirstThunk = dwINTRVA;

            lpNewImport[i].OriginalFirstThunk = dwINTRVA;

            break;

        }

        else i++;

    }

    //计算新的导入表RVA

    dwNewImportRva = dwNewSectionRVA + dwNewOffset;

    //写入所有的导入表项

    fseek(fp, dwNewFA + dwNewOffset, SEEK_SET);

    fwrite(lpNewImport, dwNewImportSize, 1, fp);

    dwNewOffset += dwNewImportSize;

    //计算文件对齐需要补零的值

    DWORD dwFileAlign = ClacAlignment(dwNewOffset, nFileAlignment) - dwNewOffset;

    for (size_t i = 0; i < dwFileAlign; i++)

    {

        fputc('\0', fp);

    }

    //5.添加一个新节表头项

    memset(&ImgNewSection, 0, sizeof(IMAGE_SECTION_HEADER));

    //添加名为.newsec的新节

    strcpy((char*)ImgNewSection.Name, ".newsec");

    ImgNewSection.VirtualAddress = dwNewSectionRVA;

    ImgNewSection.PointerToRawData = dwNewFA;

    ImgNewSection.Misc.VirtualSize = ClacAlignment(dwNewOffset, nSectionAlignment);

    ImgNewSection.SizeOfRawData = ClacAlignment(dwNewOffset, nFileAlignment);

    ImgNewSection.Characteristics = 0xC0000040;

    //计算新节头的文件偏移

    dwNewSectionOffset = (DWORD)lpFirstSectionHeader -

        (DWORD)theApp.m_stMapFile.ImageBase + sizeof(IMAGE_SECTION_HEADER)*nSectionNum;

    fseek(fp, dwNewSectionOffset, 0);

    //写入节表头

    fwrite(&ImgNewSection, sizeof(IMAGE_SECTION_HEADER), 1, fp);

    memcpy(&ImgNewSection, lpFirstSectionHeader, sizeof(IMAGE_SECTION_HEADER));

    fseek(fp, (DWORD)lpFirstSectionHeader - (DWORD)theApp.m_stMapFile.ImageBase, SEEK_SET);

    fwrite(&ImgNewSection, sizeof(IMAGE_SECTION_HEADER), 1, fp);

    //6.更新NT头数据

    memcpy(lpNewNtHeader, lpNtHeader, sizeof(IMAGE_NT_HEADERS));

    int nNewImageSize = lpNtHeader->OptionalHeader.SizeOfImage + ClacAlignment(dwNewOffset, nSectionAlignment);

    lpNewNtHeader->OptionalHeader.SizeOfImage = nNewImageSize;

    lpNewNtHeader->OptionalHeader.DataDirectory[11].Size = 0;

    lpNewNtHeader->OptionalHeader.DataDirectory[11].VirtualAddress = 0;

    lpNewNtHeader->OptionalHeader.DataDirectory[12].Size = 0;

    lpNewNtHeader->OptionalHeader.DataDirectory[12].VirtualAddress = 0;

    lpNewNtHeader->FileHeader.NumberOfSections = nSectionNum + 1;

    lpNewNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = dwNewImportRva;

    lpNewNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = dwNewImportSize;

    //写入新的NT头

    fseek(fp, (DWORD)(lpNtHeader)-(DWORD)theApp.m_stMapFile.ImageBase, SEEK_SET);

    fwrite(lpNewNtHeader, sizeof(IMAGE_NT_HEADERS), 1, fp);

    if (fp != NULL)

    {

        fclose(fp);

    }

    UnLoadFile(&theApp.m_stMapFile);

    //释放扫尾工作

    if (arrINTRva != NULL)

    {

        delete[] arrINTRva;

        arrINTRva = NULL;

    }

}

//PEFuncs.h

#ifndef _PEFUNCS_H_

#define _PEFUNCS_H_

typedef struct _MAP_FILE_STRUCT

{

    HANDLE hFile;

    HANDLE hMapping;

    LPVOID ImageBase;

}  MAP_FILE_STRUCT,* PMAP_FILE_STRUCT;

BOOL LoadFileR(LPTSTR lpFilename,PMAP_FILE_STRUCT pstMapFile);

void UnLoadFile(PMAP_FILE_STRUCT pstMapFile);

BOOL IsPEFile(LPVOID ImageBase);

PIMAGE_NT_HEADERS      GetNtHeaders(LPVOID ImageBase);

PIMAGE_FILE_HEADER     GetFileHeader(LPVOID ImageBase);

PIMAGE_OPTIONAL_HEADER GetOptionalHeader(LPVOID ImageBase);

PIMAGE_SECTION_HEADER  GetFirstSectionHeader(LPVOID ImageBase);

PIMAGE_DOS_HEADER GetDosHeader(LPVOID ImageBase);

LPVOID MyRvaToPtr(PIMAGE_NT_HEADERS pNtH,void* ImageBase,unsigned long dwRVA);

LPVOID GetDirectoryEntryToData(LPVOID ImageBase,USHORT DirectoryEntry);

PIMAGE_EXPORT_DIRECTORY GetExportDirectory(LPVOID ImageBase);

PIMAGE_IMPORT_DESCRIPTOR  GetFirstImportDesc(LPVOID ImageBase);

DWORD   GetNumOfExportFuncs(LPVOID ImageBase,PIMAGE_EXPORT_DIRECTORY pExportDir);

BOOL    IsDataDirPresent(LPVOID ImageBase,USHORT DirectoryEntry);

PIMAGE_BASE_RELOCATION GetFirstRelocation(LPVOID ImageBase);

PIMAGE_RESOURCE_DIRECTORY GetFirstResDirectory(LPVOID ImageBase);

DWORD GetDirectorySize(LPVOID ImageBase, USHORT DirectoryEntry);

PIMAGE_BASE_RELOCATION GetNextRelocation(int nSum, LPVOID ImageBase);

#endif

//PEFuncs.cpp

#include "stdafx.h"

#include "PEFuncs.h"

#include <imagehlp.h>

//#include <Dbghelp.h>

BOOL  LoadFileR(LPTSTR lpFilename,PMAP_FILE_STRUCT pstMapFile)

{

    HANDLE hFile;

    HANDLE hMapping;

    LPVOID ImageBase;

    memset(pstMapFile,0,sizeof(MAP_FILE_STRUCT));

    hFile = CreateFile(lpFilename, GENERIC_READ | STANDARD_RIGHTS_ALL, 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;

}

void UnLoadFile(PMAP_FILE_STRUCT pstMapFile)

{

    if(pstMapFile->ImageBase)

        UnmapViewOfFile(pstMapFile->ImageBase);

    if(pstMapFile->hMapping)

        CloseHandle(pstMapFile->hMapping);

    if(pstMapFile->hFile)

        CloseHandle(pstMapFile->hFile);

}

BOOL IsPEFile(LPVOID ImageBase)

{

    PIMAGE_DOS_HEADER  pDH=NULL;

    PIMAGE_NT_HEADERS  pNtH=NULL;

    if(!ImageBase)

      return FALSE;

    pDH=(PIMAGE_DOS_HEADER)ImageBase;

    if(pDH->e_magic!=IMAGE_DOS_SIGNATURE)

         return FALSE;

#ifdef _WIN64

    pNtH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);

#else 

    pNtH = (PIMAGE_NT_HEADERS32)((DWORD)pDH + pDH->e_lfanew);

#endif

    if (pNtH->Signature != IMAGE_NT_SIGNATURE )

        return FALSE;

    return TRUE;

}

//

PIMAGE_NT_HEADERS  GetNtHeaders(LPVOID ImageBase)

{

    if(!IsPEFile(ImageBase))

        return NULL;

    PIMAGE_NT_HEADERS  pNtH;

    PIMAGE_DOS_HEADER  pDH;

    pDH=(PIMAGE_DOS_HEADER)ImageBase;

    pNtH=(PIMAGE_NT_HEADERS)((DWORD)pDH+pDH->e_lfanew);

    return pNtH;

}

//

PIMAGE_FILE_HEADER   GetFileHeader(LPVOID ImageBase)

{

    PIMAGE_DOS_HEADER  pDH=NULL;

    PIMAGE_NT_HEADERS  pNtH=NULL;

    PIMAGE_FILE_HEADER pFH=NULL;

    if(!IsPEFile(ImageBase))

        return NULL;

    pDH=(PIMAGE_DOS_HEADER)ImageBase;

    pNtH=(PIMAGE_NT_HEADERS)((DWORD)pDH+pDH->e_lfanew);

    pFH=&pNtH->FileHeader;

    return pFH;

}

PIMAGE_OPTIONAL_HEADER GetOptionalHeader(LPVOID ImageBase)

{

    PIMAGE_DOS_HEADER  pDH=NULL;

    PIMAGE_NT_HEADERS  pNtH=NULL;

    PIMAGE_OPTIONAL_HEADER pOH=NULL;

     if(!IsPEFile(ImageBase))

        return NULL;

    pDH=(PIMAGE_DOS_HEADER)ImageBase;

    pNtH=(PIMAGE_NT_HEADERS)((DWORD)pDH+pDH->e_lfanew);

    pOH=&pNtH->OptionalHeader;

    return pOH;

}

PIMAGE_SECTION_HEADER GetFirstSectionHeader(LPVOID ImageBase)

{

    PIMAGE_NT_HEADERS     pNtH=NULL;

    PIMAGE_SECTION_HEADER pSH=NULL;

    pNtH=GetNtHeaders(ImageBase);

    pSH=IMAGE_FIRST_SECTION(pNtH);

    return  pSH;

}

LPVOID MyRvaToPtr(PIMAGE_NT_HEADERS pNtH,void* ImageBase,unsigned long dwRVA)

{   

    return ImageRvaToVa(pNtH,ImageBase,dwRVA,NULL);

}

LPVOID GetDirectoryEntryToData(LPVOID ImageBase,USHORT DirectoryEntry)

{

    DWORD dwDataStartRVA;

    LPVOID pDirData=NULL;

    PIMAGE_NT_HEADERS     pNtH=NULL;

    PIMAGE_OPTIONAL_HEADER pOH=NULL;

    pNtH=GetNtHeaders(ImageBase);

    if(!pNtH)

        return NULL;

    pOH=GetOptionalHeader(ImageBase);

    if(!pOH)

        return NULL;

    dwDataStartRVA=pOH->DataDirectory[DirectoryEntry].VirtualAddress;

      if(!dwDataStartRVA)

        return NULL;

    pDirData=MyRvaToPtr(pNtH,ImageBase,dwDataStartRVA);

   if(!pDirData)

        return NULL;     

    return  pDirData;

}

DWORD GetDirectorySize(LPVOID ImageBase, USHORT DirectoryEntry)

{

    DWORD dwSize;

    LPVOID pDirData = NULL;

    PIMAGE_NT_HEADERS     pNtH = NULL;

    PIMAGE_OPTIONAL_HEADER pOH = NULL;

    pNtH = GetNtHeaders(ImageBase);

    if (!pNtH)

        return NULL;

    pOH = GetOptionalHeader(ImageBase);

    if (!pOH)

        return NULL;

    dwSize = pOH->DataDirectory[DirectoryEntry].Size;

    return  dwSize;

}

PIMAGE_EXPORT_DIRECTORY  GetExportDirectory(LPVOID ImageBase)

{

    PIMAGE_EXPORT_DIRECTORY pExportDir=NULL;

    pExportDir=(PIMAGE_EXPORT_DIRECTORY)GetDirectoryEntryToData(ImageBase,IMAGE_DIRECTORY_ENTRY_EXPORT);

    if(!pExportDir)

        return NULL;     

    return  pExportDir;

}

PIMAGE_BASE_RELOCATION GetFirstRelocation(LPVOID ImageBase)

{

    PIMAGE_BASE_RELOCATION pImageBase;

    pImageBase = (PIMAGE_BASE_RELOCATION)GetDirectoryEntryToData(ImageBase, IMAGE_DIRECTORY_ENTRY_BASERELOC);

    if (!pImageBase)

    {

        return NULL;

    }

    return pImageBase;

}

PIMAGE_BASE_RELOCATION GetNextRelocation(int nSum, LPVOID ImageBase)

{

    PIMAGE_BASE_RELOCATION pTempImageBase;

    PIMAGE_BASE_RELOCATION pImageBase;

    DWORD dwNewAddr = NULL;

    dwNewAddr = (DWORD)GetDirectoryEntryToData(ImageBase, IMAGE_DIRECTORY_ENTRY_BASERELOC);

    pImageBase = (PIMAGE_BASE_RELOCATION)(dwNewAddr + nSum);

    if (!pImageBase)

    {

        return NULL;

    }

    return pImageBase;

}

PIMAGE_RESOURCE_DIRECTORY GetFirstResDirectory(LPVOID ImageBase)

{

    PIMAGE_RESOURCE_DIRECTORY pImageBase;

    pImageBase = (PIMAGE_RESOURCE_DIRECTORY)GetDirectoryEntryToData(ImageBase, IMAGE_DIRECTORY_ENTRY_RESOURCE);

    if (!pImageBase)

    {

        return NULL;

    }

    return pImageBase;

}

PIMAGE_IMPORT_DESCRIPTOR  GetFirstImportDesc(LPVOID ImageBase)

{

    PIMAGE_IMPORT_DESCRIPTOR pImportDesc;

    pImportDesc=(PIMAGE_IMPORT_DESCRIPTOR)GetDirectoryEntryToData(ImageBase,IMAGE_DIRECTORY_ENTRY_IMPORT);

    if(!pImportDesc)

        return NULL;     

    return  pImportDesc;

}

DWORD   GetNumOfExportFuncs(LPVOID ImageBase,PIMAGE_EXPORT_DIRECTORY pExportDir)

{

    DWORD   dwnum=0;

    PDWORD pdwRvas=NULL;

/*  if(!IsPEFile(ImageBase))

        return NULL;

*/

 PIMAGE_NT_HEADERS pNtH=GetNtHeaders(ImageBase);

  pdwRvas=(PDWORD)MyRvaToPtr(pNtH,ImageBase,pExportDir->AddressOfFunctions);

    for(DWORD i=0;i<pExportDir->NumberOfFunctions;i++)

    {   

        if(*pdwRvas)

            ++dwnum;

        ++pdwRvas;

    } 

    return dwnum;

}

BOOL  IsDataDirPresent(LPVOID ImageBase,USHORT DirectoryEntry)

{

    if(!GetDirectoryEntryToData(ImageBase,DirectoryEntry))

        return FALSE;

    return TRUE;

}

PIMAGE_DOS_HEADER GetDosHeader(LPVOID ImageBase)

{

    PIMAGE_DOS_HEADER  pDH = NULL;

    if (!IsPEFile(ImageBase))

    {

        return NULL;

    }

    pDH = (PIMAGE_DOS_HEADER)ImageBase;

    return pDH;

}

©著作权归作者所有:来自51CTO博客作者土匪猿的原创作品,如需转载,请注明出处,否则将追究法律责任


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消