滴水逆向-绑定导入表

课堂知识点

文字知识点

点击查看代码
打印绑定导入表
绑定导入表结构:
PE加载EXE相关的DLL时,首先会根据IMAGE_IMPORT_DESCRIPTOR结构中的TimeDateStamp来判断是否要重新
计算IAT表中的地址。
TimeDateStamp == 0 未绑定
TimeDateStamp == -1 已绑定 真正的绑定时间为IMAGE_BOUND_IMPORT_DESCRIPTOR的TimeDateStamp
绑定导入表的定位:
绑定导入表位于数据目录的第12
typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR {
DWORD TimeDateStamp;
WORD OffsetModuleName;
WORD NumberOfModuleForwarderRefs;
// Array of zero or more IMAGE_BOUND_FORWARDER_REF follows
} IMAGE_BOUND_IMPORT_DESCRIPTOR, *PIMAGE_BOUND_IMPORT_DESCRIPTOR;
typedef struct _IMAGE_BOUND_FORWARDER_REF {
DWORD TimeDateStamp;
WORD OffsetModuleName;
WORD Reserved;
} IMAGE_BOUND_FORWARDER_REF, *PIMAGE_BOUND_FORWARDER_REF;
特别说明:
当IMAGE_BOUND_IMPORT_DESCRIPTOR结构中的TimeDateStamp与DLL文件标准PE头中的TimeDateStamp值不相符
时,或者DLL需要重新定位的时候,就会重新计算IAT中的值.

打印绑定导入表相关代码

点击查看代码
//绑定导入表打印
//IMAGE_BOUND_IMPORT_DESCRIPTOR
VOID LogBoundImportTable(IN LPVOID pFileBuffer)
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
PIMAGE_FILE_HEADER pPEHeader = NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
PIMAGE_DATA_DIRECTORY pDataDirectory_BoundImportTable = NULL;
PIMAGE_BOUND_IMPORT_DESCRIPTOR pBoundImportTable = NULL;
PIMAGE_BOUND_FORWARDER_REF pBoundForwarderTable = NULL;
if (pFileBuffer == NULL)
{
printf("FileBuffer获取失败!\r\n");
return;
}
//判断是否是有效的MZ标志
if (*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("无效的MZ标识\r\n");
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
//判断是否是有效的PE标志
if (*((PDWORD)((DWORD)pFileBuffer+pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE)
{
printf("无效的PE标记\r\n");
return;
}
//定位各种头
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew);
pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+0x04);
pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER);
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader);
pDataDirectory = (PIMAGE_DATA_DIRECTORY)pOptionHeader->DataDirectory;
//根据可选PE头里面的数据目录这个数组准确定位到导入表位置,导入表是在数据目录的第二个位置,下面两种方式都可以
//#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers
//pDataDirectory_BoundImportTable = &pDataDirectory[11];
pDataDirectory_BoundImportTable = &pDataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT];
if (!pDataDirectory_BoundImportTable->VirtualAddress)
{
printf("pDataDirectory_BoundImportTable 这个程序不存在绑定导入表\r\n");
return;
}
//验证打印导出表RVA和FOA地址
printf("BoundImport Table RVA: %#010x\r\n",pDataDirectory_BoundImportTable->VirtualAddress);
DWORD FOA_BoundImportTable = RvaToFileOffset(pFileBuffer,pDataDirectory_BoundImportTable->VirtualAddress);
printf("BoundImport Table FOA: %#010x\r\n",FOA_BoundImportTable);
//确认好FOA地址之后,开始指针偏移到文件的导入表位置
pBoundImportTable = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((DWORD)pDosHeader+FOA_BoundImportTable);
//打印查看对应结构体pBoundImportTable的3个字段的值
printf("pBoundImportTable->NumberOfModuleForwarderRefs: %#x\r\n",pBoundImportTable->NumberOfModuleForwarderRefs);
printf("pBoundImportTable->OffsetModuleName: %#x\r\n",pBoundImportTable->OffsetModuleName);
printf("pBoundImportTable->TimeDateStamp: %#d\r\n",pBoundImportTable->TimeDateStamp);
//验证偏移好的pBoundImportTable内存地址和对应内存地址的内容
printf("*pBoundImportTable: %#010x\r\n",*pBoundImportTable);
printf("pBoundImportTable: %#010x\r\n",pBoundImportTable);
DWORD BoundImportTableBase = (DWORD)pBoundImportTable;
printf("BoundImportTableBase: %#010x\r\n",BoundImportTableBase);
//根据绑定导入表的算法,和上面验证的结果,得出结论是要像得到绑定导入表的名称,需要使用偏移的内存地址;
//使用此偏移的内存地址然后加上绑定导入表的OffsetModuleName的值,即可得到准确的绑定导入表的名称对应的内存地址;
//然后就可以直接打印内存地址对应的名称即可;
while (*(PDWORD)pBoundImportTable)
{
PDWORD pOffsetModuleName = (PDWORD)(BoundImportTableBase+pBoundImportTable->OffsetModuleName);
printf("BoundImportTable Module Name: %#s\r\n",pOffsetModuleName);
pBoundImportTable++;
}
}

打印结果

posted @   皇帽讲绿帽带法技巧  阅读(149)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2020-09-29 Vulnhub-靶机-DIGITALWORLD.LOCAL: DEVELOPMENT
2020-09-29 Upload-labs-11-13
点击右上角即可分享
微信分享提示