C/C++知识点之IAT 注入ImportInject(dll)
小标 2019-03-01 来源 : 阅读 674 评论 0

摘要:本文主要向大家介绍了 C/C++知识点之IAT 注入ImportInject(dll),通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

本文主要向大家介绍了 C/C++知识点之IAT 注入ImportInject(dll),通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

C/C++知识点之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;
    //文件对齐
    <span class="hlj    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C/C+频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程