本文共 39658 字,大约阅读时间需要 132 分钟。
// INTInject.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include#include #include 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 returnedDWORD 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// 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// 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//#include 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 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;}
转载于:https://blog.51cto.com/haidragon/2306933