1. 程式人生 > >IAT 注入ImportInject(dll)

IAT 注入ImportInject(dll)

原理:
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;
}