原理:
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博客作者土匪猿的原创作品,如需转载,请注明出处,否则将追究法律责任
共同学习,写下你的评论
评论加载中...
作者其他优质文章