PE文件之旅(C语言描述) -- 第一篇 Sections

无论是作为一名或者立志成为一名拥有真正技术的Top Cracker(当然我是属于后者啦,哈),对PE文件格式的熟悉绝对是必须要研究通透和掌握的技术,这一点相信应该没有什么争议吧(当然如果不研究Windows平台下解密那就另说了)?看过网上好多的PE文件教程,理论居多,只是看好象都明白,到了应用的时候,比如脱壳,对于IAT表在脑海中仍然是稀里糊涂一片(呵呵,至少我是这样D,菜啊~), 学习就是这样,只是学习原理,而没有去实践,好象是懂了,到真正去做的时候,却不知道从何下手。尤其是计算机这门实践性很强的学科,必须要辅以实践才能真正把知识学到手。这里要感谢 MengLong[DFCG],他的< >从编程实践的角度剖析PE文件格式,同时也让我有了研究下去的想法。 好了,罗嗦了这么多,忘了说了,纯属菜鸟教程,让高手贻笑大方了。 PE文件之旅(C语言描述) -- 第一篇 Sections 平台 : windows XP SP1 编译器 : VC++6.0 时间 : 2004.12 -- 2005.01 参考资料: 看雪< <加密解密ii> >,MengLong[DFCG]< >,< >. Coded by: prince E-mail : Cracker_prince@163.com 注意:这篇教程直接从Sections开始讲解,前面的知识和代码请参阅< >.以下列出的仅是核心部分代码,完整代码见后续篇幅。 首先请大家直观地看一下PE文件格局。这也是PE文件存放在磁盘上的格局。 offset 0 ------------------------------- | IMAGE_DOS_HEADER | <-- Dos部首 PE Signature ------------------------------- / | 'PE',0,0 | <-- PE文件标志 | ------------------------------- | | IMAGE_FILE_HEADER | <-- 映像文件头 | -- IMAGE_NT_HEADERS ------------------------------- | | IMAGE_OPTIONAL_HEADER32 | <-- 映像可选头 | ------------------------------- / ------------| Section Table | <-- 节表 -- IMAGE_SECTION_HEADER (Array) | | | | | ------------------------------- | | | | /-->| .text | <-- 代码区段 | | | | ------------------------------- | | | /---->| .data | <-- 数据区段 | | | ------------------------------- | | /------>| .idata | <-- 输入表 | | ------------------------------- | /-------->| .edata | <-- 输出表 | ------------------------------- /---------->| .reloc | <-- 重定位表区段 ------------------------------- | .... | ------------------------------- | 调试信息 | ------------------------------- 我们由IMAGE_DOS_HEADER.e_lfanew得到PE文件头在PE文件中的偏移,即IMAGE_NT_HEADERS结构,如下: typedef struct _IMAGE_NT_HEADERS { DWORD Signature; **PE文件标识 "PE",0,0 IMAGE_FILE_HEADER FileHeader; **映像文件头 (其中的NumberOfSections成员指定了Sections的个数) IMAGE_OPTIONAL_HEADER32 OptionalHeader; **映像可选头 } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; 核心代码: IMAGE_DOS_HEADER myDosHeader; LONG e_lfanew; FILE *pFile; pFile = fopen("文件路径", r+b); fread(&myDosHeader, sizeof(IMAGE_DOS_HEADER), 1, pFile); // pFile 为打开的文件指针 e_lfanew = myDosHeader.e_lfanew; // 保存PE文件头偏移 IMAGE_FILE_HEADER myFileHeader; int nSectionCount; fseek(pFile, (e_lfanew + sizeof(DWORD)), SEEK_SET); fread(&myFileHeader, sizeof(IMAGE_FILE_HEADER), 1, pFile); nSectionCount = myFileHeader.NumberOfSections; // 保存Section个数 // 过了IMAGE_NT_HEADERS结构就是IMAGE_SECTION_HEADER结构数组了,注意是结构数组,有几个Section该结构就有几个元素 // 这里动态开辟NumberOfSections个内存来存储不同的Section信息 IMAGE_SECTION_HEADER *pmySectionHeader = (IMAGE_SECTION_HEADER *)calloc(nSectionCount, sizeof(IMAGE_SECTION_HEADER)); fseek(pFile, (e_lfanew + sizeof(IMAGE_NT_HEADERS)), SEEK_SET); fread(pmySectionHeader, sizeof(IMAGE_SECTION_HEADER), nSectionCount, pFile); // 打印Sections信息 for (int i = 0; i < nSectionCount; i++, pmySectionHeader++) { printf("Name: %s/n", pmySectionHeader->Name); printf("union_PhysicalAddress: %08x/n", pmySectionHeader->Misc.PhysicalAddress); printf("union_VirtualSize: %04x/n", pmySectionHeader->Misc.VirtualSize); printf("VirtualAddress: %08x/n", pmySectionHeader->VirtualAddress); printf("SizeOfRawData: %08x/n", pmySectionHeader->SizeOfRawData); printf("PointerToRawData: %04x/n", pmySectionHeader->PointerToRawData); printf("PointerToRelocations: %04x/n", pmySectionHeader->PointerToRelocations); printf("PointerToLinenumbers: %04x/n", pmySectionHeader->PointerToLinenumbers); printf("NumberOfRelocations: %04x/n", pmySectionHeader->NumberOfRelocations); printf("NumberOfLinenumbers: %04x/n", pmySectionHeader->NumberOfLinenumbers); printf("Charateristics: %04x/n", pmySectionHeader->Characteristics); } // 恢复指针 pmySectionHeader -= m_nSectionCount; if (pmySectionHeader != NULL) // 释放内存 { free(pmySectionHeader); pmySectionHeader = NULL; } // 最后不要忘记关闭文件 fclose(pFile); 我将以上代码改写了一个Win32程序,可以很方便地查看PE文件的Section信息。本人菜鸟,错误及不妥之处难免存在,如果大家发现有什么问题,不要吝啬啊,请告之。那么关于PE文件格式Section的C语言描述到此就结束了,下一篇将继续我们的PE文件研究,DLL的秘密 -- 输出表。 prince 2005.01.06
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值