摘要:本文主要向大家介绍了 C/C++知识点之IAT 注入ImportInject(dll),通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。
本文主要向大家介绍了 C/C++知识点之IAT 注入ImportInject(dll),通过具体的内容向大家展示,希望对大家学习C/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;
//文件对齐
<span class="hlj
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C/C+频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号