首页 | 资讯动态 | linux基础 | 系统管理 | 网络管理 | 编程开发 | linux数据库 | 服务器技术 | linux相关 | linux认证 | 嵌入式 | 下载中心 | 专题 | linux招聘 | 镜像站
OKLinux中文技术站
·设为首页
·加入收藏
·联系我们
系统管理: 中文环境 系统管理 桌面应用 内核技术 | Linux基础: 基础入门 安装配置 常用命令 经验技巧 软件应用 | Linux数据库: Mysql Postgre Oracle DB2 Sybase other
网络管理: 网络安全 网络应用 Linux服务器 环境配置 黑客安全 | 编程开发: PHP CC++ Python Perl Shell 嵌入式开发 java jsp | PHP技术: PHP基础 PHP技巧 PHP应用 PHP文摘
Linux资讯 Linux招聘 Linux专题 Apache | Linux相关: 硬件相关 Linux解决方案 Linux认证 企业应用 其它Unix | 相关下载: 资料下载 参考手册 开发工具 服务器类 软路由 其它
 技术搜索:
会员中心 注册会员 高级搜索  
  → 当前位置:首页>编程开发>cc++>正文

PE文件格式详解(4)

http://www.oklinux.cn  2003-05-01  来源: 互联网  本站整理   会员收藏  游客收藏  【 】 

PE文件段

  PE文件规范由目前为止定义的那些头部以及一个名为“段”的一般对象组成。段包含了文件的内容,包括代码、数据、资源以及其它可执行信息,每个段都有一个头部和一个实体(原始数据)。我将在下面描述段头部的有关信息,但是段实体则缺少一个严格的文件结构。因此,它们几乎可以被链接器按任何的方法组织,只要它的头部填充了足够能够解释数据的信息。

段头部

  PE文件格式中,所有的段头部位于可选头部之后。每个段头部为40个字节长,并且没有任何的填充信息。段头部被定义为以下的结构:
WINNT.H
#define IMAGE_SIZEOF_SHORT_NAME 8
typedef struct _IMAGE_SECTION_HEADER {
UCHAR Name[IMAGE_SIZEOF_SHORT_NAME];
union {
ULONG PhysicalAddress;
ULONG VirtualSize;
} Misc;
ULONG VirtualAddress;
ULONG SizeOfRawData;
ULONG PointerToRawData;
ULONG PointerToRelocations;
ULONG PointerToLinenumbers;
USHORT NumberOfRelocations;
USHORT NumberOfLinenumbers;
ULONG Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
  你如何才能获得一个特定段的段头部信息?既然段头部是被连续的组织起来的,而且没有一个特定的顺序,那么段头部必须由名称来定位。以下的函数示范了如何从一个给定了段名称的PE映像文件中获得一个段头部:
PEFILE.C
BOOL WINAPI GetSectionHdrByName(LPVOID lpFile,
IMAGE_SECTION_HEADER *sh, char *szSection)
{
PIMAGE_SECTION_HEADER psh;
int nSections = NumOfSections (lpFile);
int i;
if ((psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET(lpFile))
!= NULL)
{
/* 由名称查找段 */
for (i = 0; i <nSections; i++)
{
if (!strcmp(psh->Name, szSection))
{
/* 向头部复制数据 */
CopyMemory((LPVOID)sh, (LPVOID)psh,
sizeof(IMAGE_SECTION_HEADER));
return TRUE;
}
else
psh++;
}
}
return FALSE;
}
  这个函数通过SECHDROFFSET宏将第一个段头部定位,然后它开始在所有段中循环,并将要寻找的段名称和每个段的名称相比较,直到找到了正确的那一个为止。当找到了段的时候,函数将内存映像文件的数据复制到传入函数的结构中,然后IMAGE_SECTION_HEADER结构的各域就能够被直接存取了。

段头部的域

  ·Name。每个段都有一个8字符长的名称域,并且第一个字符必须是一个句点。
  ·PhysicalAddress或VirtualSize。第二个域是一个union域,现在已不使用了。
  ·VirtualAddress。这个域标识了进程地址空间中要装载这个段的虚拟地址。实际的地址由将这个域的值加上可选头部结构中的ImageBase虚拟地址得到。切记,如果这个映像文件是一个DLL,那么这个DLL就不一定会装载到ImageBase要求的位置。所以一旦这个文件被装载进入了一个进程,实际的ImageBase值应该通过使用GetModuleHandle来检验。
  ·SizeOfRawData。这个域表示了相对FileAlignment的段实体尺寸。文件中实际的段实体尺寸将少于或等于FileAlignment的整倍数。一旦映像被装载进入了一个进程的地址空间,段实体的尺寸将会变得少于或等于FileAlignment的整倍数。
  ·PointerToRawData。这是一个文件中段实体位置的偏移量。
  ·PointerToRelocations、PointerToLinenumbers、NumberOfRelocations、NumberOfLinenumbers。这些域在PE格式中不使用。
  ·Characteristics。定义了段的特征。这些值可以在WINNT.H及本光盘(译注:MSDN的光盘)的PE格式规范中找到。



上一篇:PE文件格式详解(5)   下一篇:PE文件格式详解(3)


收藏于收藏夹】 【评论】 【推荐】 【打印】 【关闭
相关文档
·PE文件格式详解(5)
·PE文件格式详解(3)
·PE文件格式详解(2)
·PE文件格式详解(6)
·PE文件格式详解(1)
·PE文件格式详解(7)
·PCI
·Processes (进程)
·Networks(网络)
·References and arrays
·Reserved Names
·Modules
·Scheduling (调度)
·Memory Management (内存管理)
·Software Basic(软件基础)
·Macro Definitions of Functions
发表评论
密码: 匿名评论
评论内容:

(不超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规)
 
  最新文档
·用Eclipse平台进行C/C 开发
·在 Linux 中使用共享对象
·VS:针对Java开发人员的C#编程语言
·使用智能设备扩展在C#中开发自定义控件
·Visual C# 常见问题
·二级C语言实例解答
·一种被忽视的构造和整数溢出重现
·轻轻松松C to C
·与用于 C 的ISO标准保持一致
·用C 的托管扩展针对Windows编程
·运行时和编译时的安全性检查
·轻轻松松C to C (二)
  阅读排行
·c/c++ 学习-read 函数和 write 函数
·程序员眼中的qmail(qmail源代码分析)
·Awk 基础入门:Awk 实例编程
·autoconf 和automake生成Makefile文件
·Linux下的多进程编程
·入门文章:教你学会编写Linux设备驱动
·C++自动化(模板元)编程基础与应用
·使用 GDB 调试多进程程序
·Qt 不规则窗体的实现
·嵌入式程序员应知道的几个基本问题
·Linux操作系统中GCC的应用介绍
·C语言中的指针和内存泄漏
·用GNU profiler提高代码运行速度
·vi 中的正则表达式 (Regular Expressio
·Linux 套接字编程中的 5 个隐患
网摘收藏: