导入表解析与IATHook

news/2024/12/29 2:31:21/
  • IAT:导入地址表
    // PE文件解析.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    //#define  _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    #include <Windows.h>//函数向前声明
    DWORD RvaToFoa(DWORD dwRva, const char* szBuffer);
    char* LoadFile(const char* szFilePath);
    void LoadDosHeader(const char* szBuffer);
    void LoadFileHeader(const char* szBuffer);
    void LoadOptionalHeader(const char* szBuffer);
    void LoadDirectories(const char*szBuffer);
    void LoadImportTable(const char* szBuffer);
    void LoadSectionHeader(const char* szBuffer);//数据目录表名称
    const char* DataDirName[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]{"EXPORT""IMPORT""RESOURCE","EXCEPTION","SECURITY","BASERELOC","DEBUG","COPYRIGHT","ARCHITECTURE","GLOBALPTR","TLS","LOAD_CONFIG","BOUND_IMPORT","IAT","DELAY_IMPORT","COM_DESCRIPTOR"
    };int main()
    {const char* FileBuffer = LoadFile("C:\\Users\\lenovo\\Desktop\\目标程序.exe");printf("Dos Header:\r\n:");LoadDosHeader(FileBuffer);printf("File Header:");LoadFileHeader(FileBuffer);printf("OptionalHeader Header:");LoadOptionalHeader(FileBuffer);printf("Directories:\r\n");LoadDirectories(FileBuffer);printf("Sections Header:");LoadSectionHeader(FileBuffer);system("pause");return 0;
    }DWORD RvaToFoa(DWORD dwRva, const char * szBuffer)
    {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)szBuffer;PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)(szBuffer + pDosHeader->e_lfanew);PIMAGE_FILE_HEADER pFileHeader = (PIMAGE_FILE_HEADER)&pNtHeaders->FileHeader;PIMAGE_OPTIONAL_HEADER pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)&pNtHeaders->OptionalHeader;PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNtHeaders);if (dwRva < pFileHeader->SizeOfOptionalHeader) {return dwRva;}for (int i = 0; i < pFileHeader->NumberOfSections; i++) {if (dwRva > pSectionHeader->VirtualAddress&&dwRva <= pSectionHeader->VirtualAddress + pSectionHeader->SizeOfRawData) {return dwRva - pSectionHeader->VirtualAddress + pSectionHeader->PointerToRawData;}}
    }char* LoadFile(const char* szFilePath)
    {HANDLE hFile = CreateFileA(szFilePath, GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (hFile == INVALID_HANDLE_VALUE) {return FALSE;}DWORD dwFileSize = GetFileSize(hFile, NULL);char* szBuffer = new char[dwFileSize];memset(szBuffer, 0, dwFileSize);DWORD dwReadSize = 0;BOOL bRet = ReadFile(hFile, szBuffer, dwFileSize, &dwReadSize, NULL);if (bRet) {return szBuffer;}else {return NULL;}
    }void LoadDosHeader(const char * szBuffer)
    {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)szBuffer;printf("Dos Tag:", pDosHeader->e_magic);printf("PE Headers offset:%X\r\n", pDosHeader->e_lfanew);
    }void LoadFileHeader(const char * szBuffer)
    {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)szBuffer;PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)(szBuffer + pDosHeader->e_lfanew);printf("PE Tag:", pNtHeaders->Signature);PIMAGE_FILE_HEADER pFileHeader = (PIMAGE_FILE_HEADER)&pNtHeaders->FileHeader;printf("区段数目:%08X\t\n", pFileHeader->NumberOfSections);printf("日期时间标志:%08X\t\n", pFileHeader->TimeDateStamp);printf("可选PE头大小:%08X\t\n", pFileHeader->SizeOfOptionalHeader);printf("特征值:%08X\t\n", pFileHeader->Characteristics);
    }void LoadOptionalHeader(const char * szBuffer)
    {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)szBuffer;PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)(szBuffer + pDosHeader->e_lfanew);PIMAGE_OPTIONAL_HEADER pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)&pNtHeaders->OptionalHeader;printf("入口点:%08X\t\n", pOptionalHeader->AddressOfEntryPoint);printf("镜像地址:%08X\t\n", pOptionalHeader->ImageBase);printf("镜像大小:%08X\t\n", pOptionalHeader->SizeOfImage);printf("代码基址:%08X\t\n", pOptionalHeader->BaseOfCode);printf("内存对齐:%08X\t\n", pOptionalHeader->SectionAlignment);printf("文件对齐:%08X\t\n", pOptionalHeader->FileAlignment);printf("标志:%08X\t\n", pOptionalHeader->Magic);printf("子系统:%08X\t\n", pOptionalHeader->Subsystem);printf("部首大小:%08X\t\n", pOptionalHeader->SizeOfHeaders);printf("校验和:%08X\t\n", pOptionalHeader->CheckSum);printf("数据目录表的个数:%08X\t\n", pOptionalHeader->NumberOfRvaAndSizes);
    }void LoadDirectories(const char * szBuffer)
    {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)szBuffer;PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)(szBuffer + pDosHeader->e_lfanew);PIMAGE_OPTIONAL_HEADER pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)&pNtHeaders->OptionalHeader;for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++) {printf("Name:%s\r\n", DataDirName[i]);printf("VirtualAddress:0x%X\r\n", pOptionalHeader->DataDirectory[i].VirtualAddress);printf("Size:0x%X\r\n\r\n",pOptionalHeader->DataDirectory[i].Size);}
    }void LoadImportTable(const char * szBuffer)
    {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)szBuffer;PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)(szBuffer + pDosHeader->e_lfanew);PIMAGE_OPTIONAL_HEADER pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)&pNtHeaders->OptionalHeader;PIMAGE_DATA_DIRECTORY pImportDir = pOptionalHeader->DataDirectory + IMAGE_DIRECTORY_ENTRY_IMPORT;PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)(RvaToFoa(pImportDir->VirtualAddress, szBuffer) + szBuffer);while (pImport->Name != NULL) {char* szModuleName = (char*)(RvaToFoa(pImport->Name, szBuffer) + szBuffer);printf("模块名称:%s\r\n", szModuleName);printf("日期时间标志:%08X\r\n", pImport->TimeDateStamp);printf("ForwarderChain:%08X\r\n", pImport->ForwarderChain);printf("FirstThunk:%08X\r\n", pImport->FirstThunk);printf("OriginaFirstThunk:%08X\r\n", pImport->OriginalFirstThunk);//IAT表:PIMAGE_THUNK_DATA pIAT = (PIMAGE_THUNK_DATA)(RvaToFoa(pImport->OriginalFirstThunk, szBuffer) + szBuffer);DWORD dwIndex = 0;while (pIAT->u1.Ordinal != 0) {printf("ThunkRVA:%08X\r\n", pImport->OriginalFirstThunk + dwIndex);printf("ThunkOffset:%08X\r\n", RvaToFoa(pImport->OriginalFirstThunk, szBuffer) + dwIndex);dwIndex += 4;if ((pIAT->u1.Ordinal & 0x80000000) != 1) {PIMAGE_IMPORT_BY_NAME pName = (PIMAGE_IMPORT_BY_NAME)(RvaToFoa(pIAT->u1.AddressOfData, szBuffer) + szBuffer);__try {printf("API名称:%s\r\n", pName->Name);printf("HINT:%04X\r\n", pName->Hint);}__except (EXCEPTION_EXECUTE_HANDLER) {int nOun = pIAT->u1.Function - 0x80000000;char szNameBuffer[MAX_PATH] = { 0 };sprintf(szNameBuffer, "序号:%Xh %dd", nOun, nOun);printf("API名称:%s\r\n",szNameBuffer);printf("HINT:-\r\n");}printf("ThunkValue:%08X\r\n\r\n", pIAT->u1.Function);}pIAT++;}pImport++;}}void LoadSectionHeader(const char * szBuffer)
    {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)szBuffer;PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)(szBuffer + pDosHeader->e_lfanew);PIMAGE_FILE_HEADER pFileHeader = (PIMAGE_FILE_HEADER)&pNtHeaders->FileHeader;PIMAGE_OPTIONAL_HEADER pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)&pNtHeaders->OptionalHeader;PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNtHeaders);for (int i = 0; i < pFileHeader->NumberOfSections; i++) {printf("Section %d:\r\n", i);char szName[9] = { 0 };memcpy(szName, pSectionHeader[i].Name, 8);printf("VOffset(虚拟相对地址):%08X\r\n", pSectionHeader[i].VirtualAddress);printf("VSIZE(区段大小):%d\r\n", pSectionHeader[i].Misc.VirtualSize);printf("ROFFSET(文件偏移):%08X\r\n", pSectionHeader[i].PointerToRawData);printf("RSIZE(文件中区段的大小):%X\r\n", pSectionHeader[i].SizeOfRawData);printf("标记:%X\r\n\r\n", pSectionHeader[i].Characteristics);}
    }

IATHook

dllmain:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"//LPVOID OldMessageBoxW = NULL;
typedef int
(WINAPI *FuncMessageBoxW)(_In_opt_ HWND hWnd,_In_opt_ LPCWSTR lpText,_In_opt_ LPCWSTR lpCaption,_In_ UINT uType);
FuncMessageBoxW OldMessageBoxW = NULL;int
WINAPI
MyMessageBoxW(_In_opt_ HWND hWnd,_In_opt_ LPCWSTR lpText,_In_opt_ LPCWSTR lpCaption,_In_ UINT uType) {return OldMessageBoxW(hWnd, L"我的MessageBox", L"提示", NULL);
}VOID IATHook() {//保存原来的函数地址OldMessageBoxW = (FuncMessageBoxW)GetProcAddress(GetModuleHandle(L"user32.dll"), "MessageBoxW");//这里GetModuleHandle如果传入参数位NULL,那么就会获取.exe的基址//获取头部信息PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandle(NULL);PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);PIMAGE_OPTIONAL_HEADER pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)&pNtHeader->OptionalHeader;//获取导出表地址偏移(这里时进程中获取的内存,所以我们之际使用RVA就可以)DWORD dwImportTable = pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pDosHeader + dwImportTable);PIMAGE_THUNK_DATA pFirstThunk;while (pImport->Characteristics && pImport->FirstThunk != NULL) {pFirstThunk = (PIMAGE_THUNK_DATA)(pImport->FirstThunk + (DWORD)pDosHeader);while (*(DWORD*)pFirstThunk != NULL) {if (*(DWORD*)pFirstThunk == (DWORD)OldMessageBoxW) {DWORD dwOldProtect = 0;VirtualProtectEx(GetCurrentProcess(), pFirstThunk, 0x8, PAGE_EXECUTE_READWRITE, &dwOldProtect);DWORD dwFuncAddr = (DWORD)MyMessageBoxW;memcpy(pFirstThunk, (DWORD*)&dwFuncAddr, 4);VirtualProtectEx(GetCurrentProcess(), pFirstThunk, 0x8, PAGE_EXECUTE_READWRITE, &dwOldProtect);}pFirstThunk++;}pImport++;}
}BOOL APIENTRY DllMain( HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:IATHook();break;case DLL_THREAD_ATTACH:break;case DLL_THREAD_DETACH:break;case DLL_PROCESS_DETACH:break;}return TRUE;
}

Hook检测:

我们首先运行目标程序:

#include <iostream>
#include <Windows.h>int main()
{MessageBox(NULL, L"WdIg111", L"提示", NULL);system("pause");MessageBox(NULL, L"WdIg222", L"提示", NULL);
}

然后注入dll:
注入dll
继续运行程序,发现Hook成功:
注入成功


http://www.ppmy.cn/news/1071757.html

相关文章

Mac下使用Homebrew安装MySQL5.7

Mac下使用Homebrew安装MySQL5.7 1. 安装Homebrew & Oh-My-Zsh2. 查询软件信息3. 执行安装命令4. 开机启动5. 服务状态查询6. 初始化配置7. 登录测试7.1 终端登录7.2 客户端登录 参考 1. 安装Homebrew & Oh-My-Zsh mac下如何安装homebrew MacOS安装Homebrew与Oh-My-Zsh…

第62步 深度学习图像识别:多分类建模(Pytorch)

基于WIN10的64位系统演示 一、写在前面 上期我们基于TensorFlow环境做了图像识别的多分类任务建模。 本期以健康组、肺结核组、COVID-19组、细菌性&#xff08;病毒性&#xff09;肺炎组为数据集&#xff0c;基于Pytorch环境&#xff0c;构建SqueezeNet多分类模型&#xff0…

4399面试总结C/C++游戏开发

主要流程 首先询问了C/C知识点 然后询问操作系统&#xff0c;计算机组成&#xff0c;数据结构&#xff0c;计算机网络哪两门熟悉 涉及的相关问题 多态的概念 tcp,udp&#xff1f; tcp,udp区别 tcp可靠&#xff0c;udp不可靠 tcp这个链接的过程? 一个TCP连接必须要经过三次“…

YOLOv5、YOLOv8改进:BoTNet Transformer

目录 1.简介 2.YOLOv5改进 2.1增加以下yolov5s_botnet.yaml文件 2.2common.py配置 2.3 yolo.py配置修改 1.简介 论文地址 Paper 本文提出的BoTNet是一种简单高效的网络&#xff0c;有效的将SA应用到多种视觉任务&#xff0c;如图像识别、目标检测、实例分割任务。通过将R…

带你深入了解分布式系统

一.前言 当我们进行购物的时候,不知道大家有没有想过,每个人有那么多订单,要浏览海量商品,要加载许多网页,屏幕背后的网站是怎么完成这一系列的网页响应,数据存储的?本文将带大家深入了解这背后的机制和原理. 在进⾏技术学习过程中&#xff0c;由于⼤部分人没有经历过⼀些中⼤…

Kao框架学习

中间件&#xff1a;洋葱模型 这是官网上给出的示例&#xff0c;从logger依次往下执行&#xff0c;执行到最底层的response往回退&#xff0c;结构很像同心圆的洋葱从外层向内层再由内层向外层。 next表示暂停当前层的代码进入下一层&#xff0c; 当最后一层执行完毕开始回溯&a…

h5分享页适配手机电脑

实现思路 通过media媒体查询结合rem继承html文字大小来实现。 快捷插件配置 这里使用了VSCode的px to rem插件。 先在插件市场搜索cssrem下载插件&#xff1b; 配置插件 页面编写流程及适配详情 配置meta h5常用配置信息:<meta name"viewport" content&quo…

Royal TSX 6 Mac多协议远程软件

Royal TSX是一款功能强大的远程桌面管理软件&#xff0c;适用于Mac操作系统。它允许用户通过一个集成的界面来管理和访问多个远程计算机和服务器。 Royal TSX支持多种远程协议&#xff0c;包括RDP、VNC、SSH、Telnet和FTP等&#xff0c;可以方便地连接到Windows、Linux、Mac和其…