当前位置: 首页 > wzjs >正文

敬请期待哦seo推广是做什么的

敬请期待哦,seo推广是做什么的,wordpress 七牛云优化,唐山市住建局官方网站1、前言 上一篇文章中讲到了PE文件中的导出表, 用于定位PE文件中所有的导出函数。而这一篇详细介绍一下数据目录中的导入数据表。 2、导入表 相比于导出表,导入表的设计相对复杂,共分为四种:导入表、绑定导入表、导入地址表和延…

1、前言

上一篇文章中讲到了PE文件中的导出表, 用于定位PE文件中所有的导出函数。而这一篇详细介绍一下数据目录中的导入数据表。

2、导入表

相比于导出表,导入表的设计相对复杂,共分为四种:导入表、绑定导入表、导入地址表和延迟导入表。不同导入表的作用不一,在不同的场合发挥作用。

  • 导入表IMAGE_DIRECTORY_ENTRY_IMPORT

通常所知道的导入表,在PE文件加载时,会根据这个表里的内容加载依赖库,并填充所需函数的地址。而导入表的基本结构如下所示:

typedef struct _IMAGE_IMPORT_DESCRIPTOR {union {DWORD   Characteristics;            // 0 for terminating null import descriptorDWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)} DUMMYUNIONNAME;DWORD   TimeDateStamp;                  // 映象绑定前值 = 0// 旧式绑定后值 = 导入模块的时间戳// 新式绑定值 = -1(时间戳存储在绑定导入表中)DWORD   ForwarderChain;                 // -1 if no forwardersDWORD   Name;                           // 导入库名称的RVADWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;typedef struct _IMAGE_THUNK_DATA32 {union {DWORD ForwarderString;      // PBYTE DWORD Function;             // PDWORDDWORD Ordinal;DWORD AddressOfData;        // PIMAGE_IMPORT_BY_NAME} u1;
} IMAGE_THUNK_DATA32;typedef struct _IMAGE_IMPORT_BY_NAME {WORD    Hint;CHAR   Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

其中OriginalFirstThunkFirstThunk都指向一个IMAGE_THUNK_DATA的数组。在PE文件中,两个字段指向的数组中存储的数据完全一致,这种情况下,IMAGE_THUNK_DATA32结构中实际生效的是AddressOfData。而在加载到内存中后,FirstThunk中的Function开始生效,他指向实际的函数地址,即FirstThunk将指向IAT表中的一个位置。

由于函数导入方式有按函数名导入和序号导入两种,而IMAGE_THUNK_DATA使用一个联合体用来存储数据,因此在这里使用了一个巧妙的设计,即使用Ordinal的最高位表示是否是序号导入。如果最高位为1,就是按序号导入的,这时候,低16位就是导入序号,如果最高位是0,则AddressOfData是指向IMAGE_IMPORT_BY_NAME结构的RVA,用来保存名字信息。

PIMAGE_IMPORT_DESCRIPTOR import_descriptor =(PIMAGE_IMPORT_DESCRIPTOR)((DWORD_PTR)mod_base + RVA2FOA(file_header, import_rva));
// 遍历导入表
while (import_descriptor->Characteristics) {// 获取模块名const char* dll_name = (const char*)mod_base + RVA2FOA(file_header, import_descriptor->Name);// 获取导入函数IMAGE_THUNK_DATA* import_thunk =(IMAGE_THUNK_DATA*)((DWORD_PTR)mod_base + RVA2FOA(file_header, import_descriptor->OriginalFirstThunk));// 遍历导入函数ExportFunctionTb function_tb;while (import_thunk->u1.AddressOfData != 0) {// 判断是否为序号导入if (IMAGE_SNAP_BY_ORDINAL(import_thunk->u1.Ordinal)) {// 对于序号导入,低16位存储了序号值WORD ordinal = static_cast<WORD>(import_thunk->u1.Ordinal & 0xFFFF);function_tb.push_back({ordinal, NULL, "N/A"});} else {// 对于名称导入,低31位存储了名称表RVAIMAGE_IMPORT_BY_NAME* import_byname =(IMAGE_IMPORT_BY_NAME*)((DWORD_PTR)mod_base + RVA2FOA(file_header, import_thunk->u1.AddressOfData));function_tb.push_back({import_byname->Hint, NULL, import_byname->Name});}// 移动到下一个导入函数import_thunk++;}// 是否绑定导入if (import_descriptor->TimeDateStamp) {IMAGE_THUNK_DATA* import_thunk =(IMAGE_THUNK_DATA*)((DWORD_PTR)mod_base + RVA2FOA(file_header, import_descriptor->FirstThunk));// 遍历导入函数int index = 0;while (import_thunk->u1.AddressOfData != 0) {function_tb[index++].entry_point = import_thunk->u1.Function;// 移动到下一个导入函数import_thunk++;}}table.push_back({dll_name, function_tb});// 移动到下一个导入描述符import_descriptor++;
}
  • 绑定导入表

由于一般导入表中导入地址的修正是在PE加载时完成,当一个PE文件导入库或者函数过多时会影响程序的加载速度,因此出现了绑定导入的方式,文件链接时提前将函数地址写入IAT表,加快了程序的加载速度。但是不同操作系统之间函数地址可能存在差异,因此需额外的结构来确保地址的正确性。

typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR {DWORD   TimeDateStamp;    // PE文件生成时间戳WORD    OffsetModuleName; // DLL名偏移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;

以上两个模块的结构基本一致,TimeDateStamp存储PE文件时间戳,在加载后与对于PE文件中的时间戳对比,判断是否需要重新计算 IAT 中的值,弃用原本记录的绑定信息。OffsetModuleName用于存储模块名偏移地址,值得注意的是这里的偏移是相对于绑定导入表的,而非模块基址。NumberOfModuleForwarderRefs仅用于一级绑定导入,当绑定的PE文件需要导入其他的PE文件的函数,这个值就是指依赖的其他PE文件的数量。

// 获取导入表描述符
PIMAGE_BOUND_IMPORT_DESCRIPTOR bound_descriptor =(PIMAGE_BOUND_IMPORT_DESCRIPTOR)((DWORD_PTR)mod_base + RVA2FOA(file_header, import_rva));
// 遍历导入表
for (int i = 0; bound_descriptor[i].TimeDateStamp; i++) {const char* dll_name = (const char*)bound_descriptor + bound_descriptor[i].OffsetModuleName;table.push_back({dll_name, bound_descriptor[i].TimeDateStamp, 0});PIMAGE_BOUND_FORWARDER_REF bound_ref_descriptor = (PIMAGE_BOUND_FORWARDER_REF)(bound_descriptor + 1);for (int j = 0; j < bound_descriptor[i].NumberOfModuleForwarderRefs; j++) {const char* dll_name = (const char*)bound_descriptor + bound_ref_descriptor[i + j].OffsetModuleName;table.push_back({dll_name, bound_ref_descriptor[i + j].TimeDateStamp, 1});}i += bound_descriptor[i].NumberOfModuleForwarderRefs;
}
  • 延迟导入表IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT

一个PE文件也许提供了很多功能,也导入了很多其他PE,但是并非每次加载都会用到它提供的所有功能,因此延迟导入就出现了,只有在一个PE文件真正用到需要的PE,这个PE才会被加载,甚至于只有真正使用某个导入函数,这个函数地址才会被修正。

typedef struct _IMAGE_DELAYLOAD_DESCRIPTOR {union {DWORD AllAttributes;struct {DWORD RvaBased : 1;             // Delay load version 2DWORD ReservedAttributes : 31;} DUMMYSTRUCTNAME;} Attributes;DWORD DllNameRVA;                       // 导入库名称的RVADWORD ModuleHandleRVA;                  // RVA to the HMODULE caching location (PHMODULE)DWORD ImportAddressTableRVA;            // RVA to the start of the IAT (PIMAGE_THUNK_DATA)DWORD ImportNameTableRVA;               // RVA to the start of the name table (PIMAGE_THUNK_DATA::AddressOfData)DWORD BoundImportAddressTableRVA;       // RVA to an optional bound IATDWORD UnloadInformationTableRVA;        // RVA to an optional unload info tableDWORD TimeDateStamp;                    // 0 if not bound,// Otherwise, date/time of the target DLL
} IMAGE_DELAYLOAD_DESCRIPTOR, *PIMAGE_DELAYLOAD_DESCRIPTOR;

延迟导入表中ImportNameTableRVAImportAddressTableRVA都指向一个IMAGE_THUNK_DATA的数组。不过ImportNameTableRVA指向的数组中存储的是函数名信息,而ImportAddressTableRVA则存储的是函数地址,与OriginalFirstThunkFirstThunk类似。

// 获取导入表描述符
PIMAGE_DELAYLOAD_DESCRIPTOR delayload_descriptor =(PIMAGE_DELAYLOAD_DESCRIPTOR)((DWORD_PTR)mod_base + RVA2FOA(file_header, import_rva));
// 遍历导入表
while (delayload_descriptor->Attributes.AllAttributes) {// 获取模块名const char* dll_name = (const char*)mod_base + RVA2FOA(file_header, delayload_descriptor->DllNameRVA);// 获取导入函数IMAGE_THUNK_DATA* import_thunk =(IMAGE_THUNK_DATA*)((DWORD_PTR)mod_base + RVA2FOA(file_header, delayload_descriptor->ImportNameTableRVA));// 遍历导入函数ExportFunctionTb function_tb;while (import_thunk->u1.AddressOfData != 0) {// 判断是否为序号导入if (IMAGE_SNAP_BY_ORDINAL(import_thunk->u1.Ordinal)) {// 对于序号导入,低16位存储了序号值WORD ordinal = static_cast<WORD>(import_thunk->u1.Ordinal & 0xFFFF);function_tb.push_back({ordinal, NULL, "N/A"});} else {// 对于名称导入,低31位存储了名称表RVAIMAGE_IMPORT_BY_NAME* import_byname =(IMAGE_IMPORT_BY_NAME*)((DWORD_PTR)mod_base + RVA2FOA(file_header, import_thunk->u1.AddressOfData));function_tb.push_back({import_byname->Hint, NULL, import_byname->Name});}// 移动到下一个导入函数import_thunk++;}table.push_back({dll_name, function_tb});// 移动到下一个导入描述符delayload_descriptor++;
}
  • 导入地址表IMAGE_DIRECTORY_ENTRY_IAT

真正的函数地址填充的位置,通常情况下该表在PE文件中为空,但是当PE文件中存在绑定导入时,该表中会存储对应的函数地址。


文章转载自:

http://m3aZZghk.xgqbL.cn
http://jUpru2oQ.xgqbL.cn
http://F1BTWeo7.xgqbL.cn
http://zrxMiyyt.xgqbL.cn
http://js37elgF.xgqbL.cn
http://ZBNChYSR.xgqbL.cn
http://eAeP60qO.xgqbL.cn
http://1bwRQyUK.xgqbL.cn
http://Ds3AHDGi.xgqbL.cn
http://icUhqW8q.xgqbL.cn
http://lUwIgsey.xgqbL.cn
http://MPoDAigq.xgqbL.cn
http://QANhpSHz.xgqbL.cn
http://A0Iqyp0D.xgqbL.cn
http://lFB7RwT3.xgqbL.cn
http://eJyYo5Cl.xgqbL.cn
http://5p1Vpv3O.xgqbL.cn
http://yVxO1L3q.xgqbL.cn
http://XwiqL5Xt.xgqbL.cn
http://c9viBMau.xgqbL.cn
http://OQlxwBi3.xgqbL.cn
http://Y8pD7bRL.xgqbL.cn
http://YDLGbNBa.xgqbL.cn
http://1T19HI0w.xgqbL.cn
http://Sf2QRNhK.xgqbL.cn
http://SJ6vRx9M.xgqbL.cn
http://gu5COwbz.xgqbL.cn
http://Ftjc2j0f.xgqbL.cn
http://QYNLWLny.xgqbL.cn
http://wljQgFa9.xgqbL.cn
http://www.dtcms.com/wzjs/709127.html

相关文章:

  • wordpress建淘宝客网站蒲城县住房和城乡建设局网站
  • 青岛手机网站设计公司网络营销方式举例
  • 做淘宝主要看哪些网站有哪些内容wordpress横菜单间隔
  • 网站源码和模板wordpress站点推荐
  • 网站建设东莞长安镇怎样在百度上作网站推广
  • seo网站推广有哪些网站开发和浏览器兼容问题
  • 杭州网站建设哪家公司好网站充值提现公司账务怎么做
  • 杭州做网站哪家便宜seo工程师是什么职业
  • 宣城市建设银行网站首页网站制作赚钱吗
  • 易优建站不同网站的主机和域名
  • 简单的网站建设找哪个公司seo整站优化一年价格多少
  • 安监网站安全建设信息网站怎么做响应式
  • 松江做微网站十大互联网培训机构
  • 视频网站开发 视频采集公司网站设计欣赏
  • 百度的官方网站wordpress数据库查询数据库
  • 个人作品展示网站高新西区网站建设
  • 张家界seo网站优化深圳网站设计 创同盟
  • 石家庄网站建设接单中铁建设集团有限公司董事长
  • 科技部网站建设合同做视频网站视频存放在哪里
  • 网站建设的会计分录室内设计软件排行榜
  • 杭州模板开发建站罗湖中心区做网站
  • 建设网站的不足装修设计费收费标准2022
  • 杭州网站的优化中铁建设集团门户网站
  • 梅州建站怎么做装修网站设计图推荐
  • 南通网站建设策划浙江网站建站
  • 抓取网站后台网站续费模版
  • 想看外国的网站怎么做想学软件编程 哪个学校好啊
  • 安卓网站客户端制作软件网站建设报告论文
  • 一级a做爰片免费网站国产黄页号码是什么意思啊?
  • 好大夫官方网站网上预约挂号东莞网站设计开发