吾爱汇编

 找回密码
 立即注册

QQ登录

绑定QQ避免忘记帐号

查看: 1742|回复: 2

[C/C++] PE结构中导出表分析

[复制链接]
TImor 发表于 2018-8-22 20:29 | 显示全部楼层 |阅读模式

本帖最后由 TImor 于 2018-8-22 20:31 编辑

说好的导出表晚了一点更新

导出表结构分析:


[C] 纯文本查看 复制代码
typedef struct _IMAGE_EXPORT_DIRECTORY {                    
    DWORD   Characteristics;             // 未使用    
    DWORD   TimeDateStamp;               // 时间戳    
    WORD    MajorVersion;               // 未使用    
    WORD    MinorVersion;               // 未使用    
    DWORD   Name;                // 指向该导出表文件名字符串       
    DWORD   Base;                // 导出函数起始序号       
    DWORD   NumberOfFunctions;               // 所有导出函数的个数      
    DWORD   NumberOfNames;               // 以函数名字导出的函数个数       
    DWORD   AddressOfFunctions;     // 导出函数地址表RVA                     
    DWORD   AddressOfNames;         // 导出函数名称表RVA                     
    DWORD   AddressOfNameOrdinals;  // 导出函数序号表RVA                    
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;         


有用的就后边的这几个,本文解析的只是后三个,由于是RVA需要先转换为FOA;
原理:1、先判断属于哪个节通过数据目录项的virtualaddress  跟每个节的Virtualaddress+misc.virtualsize判断

           2、判断属于哪个节了以后减去该节的VirtuallAddress
           3、将减完成的差值加上PointerToRawData就是相对于文件的偏移,也就是物理地址;
先贴上自写的RVAToFOA代码:
[C] 纯文本查看 复制代码
DWORD RVATOFOA(IN DWORD RVA,OUT DWORD FOA,IN LPVOID pFileBuffer){
 
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNtHeaders = NULL;
    PIMAGE_FILE_HEADER pFileHeader = NULL;
    PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
 
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
    pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeaders + 4);
    pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
 
    size_t count = 0;
    //先判断在哪个节里边
    for (count = 1; RVA > (pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize); count++, pSectionHeader++);
 
    FOA = RVA - pSectionHeader->VirtualAddress + pSectionHeader->PointerToRawData;
 
    return FOA;
}

有了这个以后再解析导出表的信息:
[C] 纯文本查看 复制代码
VOID ExportDirectoryPrintf(){
    //定义PE头部指针变量
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNtHeaders = NULL;
    PIMAGE_FILE_HEADER pFileHeader = NULL;
    PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL;
    PIMAGE_DATA_DIRECTORY pDataDirectory = NULL;
    PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;
 
     
    DWORD ExportFOA = 0;
    DWORD FcFOA = 0;
    DWORD NameFOA = 0;
    DWORD NameOrdinalsFOA = 0;
    PDWORD pFunction = NULL;
    PDWORD pName = NULL;
    PDWORD pNameOrdinals = NULL;
 
    LPVOID pFileBuffer = NULL;
 
 
    ReadPEFile(INDLLPATH, &pFileBuffer);
     
    if (!pFileBuffer){
        printf("文件(dll)打开失败!\n");
        free(pFileBuffer);
    }
     
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew);
    pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNtHeaders + 4);
    pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
    pDataDirectory = (PIMAGE_DATA_DIRECTORY)((DWORD)pOptionalHeader + 96);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
     
    printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
    printf("导出表RVA:%x\n",pDataDirectory->VirtualAddress);
    ExportFOA=RVATOFOA(pDataDirectory->VirtualAddress,ExportFOA,pFileBuffer);
     
    //这个地方需要把导出表的virtualAddress转换为FOA
    printf("导出表的FOA:%x\n",ExportFOA);
    //转换完成以后用directory指针加上就到导出表的地址了 (文件中地址)
 
    pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + ExportFOA);
 
 
    FcFOA = RVATOFOA(pExportDirectory->AddressOfFunctions, FcFOA, pFileBuffer);
 
    NameOrdinalsFOA = RVATOFOA(pExportDirectory->AddressOfNameOrdinals, NameOrdinalsFOA, pFileBuffer);
 
    NameFOA = RVATOFOA(pExportDirectory->AddressOfNames, NameFOA, pFileBuffer);
    printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
    //先打印函数地址表
    pFunction =(PDWORD)((DWORD)pFileBuffer + FcFOA);
 
    printf(" 导出函数地址表RVA:%x\n", pExportDirectory->AddressOfFunctions);
 
    printf(" 导出函数地址表FOA:%x\n", FcFOA);
 
    for (size_t i = 0; i < pExportDirectory->NumberOfFunctions; i++, pFunction++)
    {
        printf("函数地址%d:%x\n", i, pFunction);
    }
    printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
    //打印函数名称表
    pName = (PDWORD)((DWORD)pFileBuffer + NameFOA);
 
    printf(" 导出函数名称表RVA:%x\n", pExportDirectory->AddressOfNames);
     
    printf(" 导出函数名称表FOA:%x\n", NameFOA);
 
    for (size_t i = 0; i < pExportDirectory->NumberOfNames; i++, pName++)
    {
        printf("函数名称表%d:%x\n", i, pName);
    }
    printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
    //打印导出函数序号表
    pNameOrdinals = (PDWORD)((DWORD)pFileBuffer + NameOrdinalsFOA);
 
    printf(" 导出函数序号表RVA:%x\n", pExportDirectory->AddressOfNameOrdinals);
 
    printf(" 导出函数序号表FOA:%x\n", NameOrdinalsFOA);
 
    for (size_t i = 0; i < pExportDirectory->NumberOfNames; i++, pNameOrdinals++)
    {
        printf("函数序号表第%d个:%x\n", i, pNameOrdinals);
    }
    printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
     
}

这个地方使用的是自己写的DLL里边一共四个函数运行结果为:




index.png

评分

参与人数 4HB +2 THX +3 收起 理由
消逝的过去 + 1
zxjzzh + 1 [吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守!
agan8888 + 1
山梦 + 1 + 1 [快捷评语] - 吃水不忘打井人,给个评分懂感恩!

查看全部评分

吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
山梦 发表于 2018-8-23 14:04 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
pinkgun 发表于 2019-6-11 19:09 来自手机端 | 显示全部楼层

感谢楼主正遇到一个pe结构的软件
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

警告:本站严惩灌水回复,尊重自己从尊重他人开始!

1层
2层
3层

免责声明

吾爱汇编(www.52hb.com)所讨论的技术及相关工具仅限用于研究学习,皆在提高软件产品的安全性,严禁用于不良动机。任何个人、团体、组织不得将其用于非法目的,否则,一切后果自行承担。吾爱汇编不承担任何因为技术滥用所产生的连带责任。吾爱汇编内容源于网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除。如有侵权请邮件或微信与我们联系处理。

站长邮箱:SharkHeng@sina.com
站长QQ:1140549900


QQ|RSS|手机版|小黑屋|帮助|吾爱汇编 ( 京公网安备11011502005403号 , 京ICP备20003498号-6 )|网站地图

Powered by Discuz!

吾爱汇编 www.52hb.com

快速回复 返回顶部 返回列表