IAT 注入ImportInject(dll)
阿新 • • 發佈:2018-11-08
原理:
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;
}