pe文件的文件格式

pe文件的文件格式,第1张

A.DOS STUB和DOS头

DOS插桩程序在大多数情况下由汇编器/编译器自动产生.通常它调用INT 21H服务9来显示上述字符串.可以通过IMAGE_DOS_HEADER结构来识别一个合法的DOS头.这个结构的头两个字节肯定是MZ.可通过该结构的e_lfanew成员来找到PE文件的开始标志.MS-DOS头部占据了PE文件的头64个字节.在微软的WINNT.H中可以找到其内容结构的描述. 在DOS STUB后是PE文件头(PE header).PE文件头是PE相关结构IMGAE_NT_HEADERS的简称,即NT映像头,存放PE整个文件信息发布的重要字段,包含了PE装载器用到的重要域.执行体在 *** 作系统中执行时,PE装载器将从DOS MZ头中找到PE头文件的起始偏移量e_lfanew,从而跳过DOS STUB直接定位真正的PE文件.它由3部分组成:

(1)PE文件标志(4H字节)

PE文件标志0x50450000即PE00,标志着NT映像头的开始,也是PE文件中与windows有关内容的开始.

(2)映像文件(14H字节)

是NT映像文件的主要部分,包含PE文件的基本信息

(3)可选映像头

包含PE文件的逻辑分布信息.

C.节表

节表其实是紧跟NT映像文件的一个结构数组.其成员数目由映像文件头结构NumberOFSectios域的值来决定.

D.节

PE文件的真正内容划分为块,称之为节.节的划分基于各组数据的共同属性.惟有节的属性设置决定了节的特性和功能.典型的windows NT应用程序可以具有9个节:.texr,.bss.rdata,.data,.rsrc,edata,idata,pdata,.debug

判断一个文件是否为PE文件

var //检测指定文件是否有效PE文件

PEDosHead: TImageDosHeader

PENTHead: TImageNtHeaders

m_file: integer

begin

Result := False

m_file := FileOpen(filename, fmOpenRead or fmShareDenyNone)//只读和其它任意

if m_File >0 then

try

FileSeek(m_file, 0, soFromBeginning)//将指针挪至文件头

FileRead(m_file, PEDosHead, SizeOf(PEDosHead))//读PEDosHead结构

FileSeek(m_file, PEDosHead._lfanew, soFromBeginning)//将指针挪至_lfanew

FileRead(m_file, PENTHead, SizeOf(PENTHead))//读PENTHead结构

finally

FileClose(m_file)

end

if (PENTHead.Signature = IMAGE_NT_SIGNATURE) then //检验文件头部第一个字的值是否等于 IMAGE_DOS_SIGNATURE

Result := True

end

pe文件结构图

自然不会,每一个变量(包括函数)都有自己的生命周期,程序结束后释放所有的内存,程序运行时只有被声明为inline内联函数,或者正在被调用的函数(也就是你上面收提及的第一种情况)存储在内存中(栈区),调用完毕后立即释放内存。

回答完毕,祝楼主学习进步。

谈及C语言,我想凡是学过它的朋友都有这样一种感觉,那就是“让我欢喜让我忧。”欢喜的是,C语言功能非常强大、应用广泛,一旦掌握了后,你就可以理直气壮地对他人说“我是电脑高手!”,而且以后若是再自学其他语言就显得轻而易举了。忧虑的是,C语言犹如“少林武功”一般博大精深,太难学了。其实就笔者认为C语言并非是“difficult(困难)”的,只要你能理清思路,掌握它的精髓,那么自学C语言是一件非常容易且又其乐无穷的事。今天本人就与大家一起谈谈如何学习C语言或者说学习C语言应从哪几方面着手。

了解一些基本知识

一.C语言的背景

就个人感触,无论学习哪门语言首先应该了解一下自己所学语言的背景,也可以说它的发展史。

C语言属于高级程序语言的一种,它的前身是“ALGOL”。其创始人是布朗·W·卡尼汉和丹尼斯·M·利奇。C语言问世时是带有很大的局限性,因为它只能用于UNIX系统上。然而随着科学技术的进步,计算机工业的发展,C语言逐渐脱离UNIX。1987年美国标准化协会制定了C语言的国际标准,简称“ANSI C”,从此以后它便成为一种广泛使用的程序语言。C语言的优点很多,主要的有如下四点:

1.兼备高级语言与低级语言的优点,属于一种中间语言。

2.它是一种结构化程序设计语言,非常适合结构化程序设计。

3.有较丰富的数据类型、运算符以及函数供以选用。

4.直接与内存打交道,使修改、编辑其他程序与文档变得轻松,简单。

二.二大语系二种不同的学习方法

笔者学习过很多程序语言,例如:C,C++(C语言的扩展),QBASIC,VB(BASIC的可视化),JAVASCRIPT,JSCRIPT ,VBSCRIPT,JAVA,ASP,FOXPRO,PERL等等,就本人实践所得,其实高级程序语言分为两大语系。一路是以C为主的程序语言,例如:JAVASCRIPT,JAVA等,这类语言在函数的调用,程序语句的书写,循环的控制都极为相似。另一路是以BASIC为首的程序语言,例如:FOXPRO,VBSCRIPT等,此类语言同样具有相似的函数调用,程序语句书写以及循环控制,但与C语系是不同的。因此若是您以前是从QBASIC起家的,那么在学习C语言前最好是先洗洗脑,千万不要把学习BASIC的方法以及思路用在C身上。

讲到这里,我想大家对C语言一定有了感性认识吧!下面让我们再升华一下,全方位亲密接触它。学习C语言必须从以下四点入手,也就是说,只要你能掌握这四点的内容,那么基本上就大功告成了。

亲密接触C语言

一.输入输出

C语言的输入输出是非常严格的,或许在其他程序语言中我们可以不关心这个问题,但在C语言中,我们必须要彻底了解它。由于篇幅有限,因此笔者不能详谈,有兴趣的朋友可以参考由著名程序语言教授谭浩强先生主编,由清华大学出版社出版的《C程序设计第二版》。不过这里笔者还是有几点要谈一下。

1.二维浮点数数组的输入

二维浮点数数组的输入(即:通过键盘给二维浮点数数组赋值)在很多专业书中都没有详细讲过这个问题。在给二维浮点数数组赋值时一定要先声明一个变量,接着把数值赋予这个变量,最后把变量数值赋予二维浮点数数组赋值。实例如下:

# include stdio.h

main()

{

float a[2][3],x

int i,j

for(i=0i<2i++)

for(j=0j<3j++)

{scanf(%f,&x)

a[i][j]=x}

}

不能写成:

# include stdio.h

main()

{

float a[2][3]

int i,j

for(i=0i<2i++)

for(j=0j<3j++)

scanf(%f,&a[i][j])

}

同样道理,在结构性浮点数组变量中也一定要按照这种格式输入。实例如下:

# include stdio.h

struct student

{float b[3]

int x

}a[2]

main()

{

float x

int i,j

for(i=0i<2i++)

for(j=0j<3j++)

{scanf(%f,&x)

a[i].b[j]=x}

}

2.注意输出格式中“%”后的字符

C语言的输出说复杂不复杂,因为常用的都很简单。可说不复杂也未必,记得曾在一次等级考前辅导我们C语言的教授讲道:“如果C语言要考得很难的话,根本不用考什么指针,只要专考输出格式,我想百分之九十九的学生都不及格。”当时我们无不认同。从这则事例中可以看出C语言的输出格式之复杂程度。因此大家在学习它时千万要学会辨别输出格式中“%”后的字符,每个字符都有其意义,也都有其作用。

二.优先级

说道优先级,有很多朋友都不是很了解或说很模糊。为此笔者想先通过一个例子让各位有个概念。什么叫优先级?比方说,我们在公交车终点站排座队时总会遇到70岁以上的老人不需要排队就能上车的情景,这就是优先级的涵义。C程序在运行时也象排队坐车一样,首先照顾那些优先级高的运算符,若是优先级相同,那么就象遇到两位(或两位以上)70岁以上的老人那样,让他们依次上车。但是C语言中的优先级的运算并不是千篇一律的,只能说是在大多数情况下,有些运算符的优先级有其自己的特点,因此这点大家要注意。例如条件表达式:条件?结果1:结果2,这种表达式很多朋友都知道,它的作用与IF…ELSE…条件判断语句很雷同,它运算时的优先级就不是按照C语言的规则来完成的。所以说对于优先级各位编程爱好者一定灵活掌握,不要死记硬背。

三.指针

就个人认为,C语言中的指针是最有特色的,当然也是最难学的。指针说穿了,其实是变量的一种表现形式,只不过这种变量记载的不是数值而是地址。就象一个人可以用姓名来表示自己,也可以用身份z号码来表示自己一样。笔者涉足编程已经有三年多了,在这期间曾经收到过很多网友的电子邮件询问学习指针的方法。就本人感触,学习指针最好是先学些计算机硬件工作的原理,例如:直接寻址,间接寻址等,只有了解了这些内容以后,你再学指针就比较容易理会,毕竟C语言是一门介于机器语言与高级语言中间的语言,没有一些硬件工作知识是很难领悟它的真谛的。然而事事并非绝对,如果你没有这些知识也不要紧,只要清楚知道以下笔者总结的二点再加上多练习便可:

1.指针是地址变量:它的值有两种:其一是地址,其二是内容。不同的表达方式可以取不同的值,这有点象一个家庭地址在不同的场合标识的人物也不同。例如:父母亲在他们的单位所登记的家庭地址就代表他们自己,而你在学校中登记的同样的家庭地址就代表你自己。

2.指针是可以运算的,它的运算法则与变量是一致的。

另外,在编写一个程序时,除非万不得已,一般不要使用指针变量。因为指针是比较复杂的,用不好就“当机”。所以笔者建议各位对于指针只要能看懂就行,当然如果你是准备参加考试的就另当别论了。

四.函数

虽说很多程序语言都有函数这一内容,但笔者觉得C语言的函数是最有魅力的。如果你能完全掌握C语言的函数,那么学习C++就不成问题了(C++是一门建立在C语言上,但又不同于C语言的高级程序语言,它增添了很多函数。)。学习函数的方法是比较简单的,只有两个字“牢记”,即:牢记函数的功能,牢记函数的用途以及如何输入输出。有些朋友认为,程序语言中的函数没有多大用处,其实这并不正确,函数从本质上讲是一段通用程序,用它可以帮助我们节约很多编程的时间,一个聪明的编程者在编写程序前往往总是先找自己所编写的程序中有多少是可以用函数来代替的。笔者曾经作过一个比较字符串的实验,用C语言中的strcmp()函数只要一句话,而自己编写的话30句话都摆不平,可想而知函数是多么实用呀!

写到这里笔者该告一段落了,下面送一个本人自己用C 语言编写的注册表比较程序给诸位。此段程序的注释请看“/*…*/”后的文字,程序运行时(在DOS模式下)输入的方式如下:compare xx1.reg xxx2.reg xxx3.txt,注意字段与字段之间是有空格的。(compare是程序名)

程序代码:

# include stdio.h /*定义头文件或说包含文件*/

main(argc,argv) /*定义带参数的主函数*/

int argc/*定义参数类型*/

char *argv[]/*定义第二参数类型*/

{ FILE *fp1,*fp2,*fp3/*定义文件指针*/

char a,b/*定义字符变量*/

if((fp1=fopen(argv[1],r))==NULL)

/*打开第一的注册表备份文件,如果不存在则跳出程序并显示“The file don`t open!”*/

{ printf(The file don`t open!)

exit(0)}

if((fp2=fopen(argv[2],r))==NULL) /*打开第二的注册表备份文件,如果不存在则跳出程序并显示“The file don`t open!”*/

{ printf(The file don`t open!)

exit(0)}

if((fp3=fopen(argv[3],w))==NULL) /*建立新的文本文件,用于存放比较结果。*/

{printf(The file don`t open!)

exit(0)}

rewind(fp1)/*规定文件指针fp1指向第一个注册表文件头部*/

rewind(fp2)/*规定文件指针fp2指向第二个注册表文件头部*/

while(!feof(fp1)||!feof(fp2)) /*开始比较*/

{ a=fgetc(fp1)/*读取第一个注册表文件内容并赋予给字符变量a*/

b=fgetc(fp2)/*读取第二个注册表文件内容并赋予给字符变量b*/

if(a!=b) fputc(b,fp3)

/*字符变量a与b不相同的话,那么把不同之处写入新建的文本文件中*/

if(feof(fp1)) fputc(b,fp3)

/*如果第一个注册表文件已经读完,第二个文件还有未读取部分,那么把第二个文件的剩余部分全部写入新建文件中*/

if(feof(fp2)) fputc(a,fp3)} /*如果第二个注册表文件已经读完,第一个文件还有未读取部分,那么把第一个文件的剩余部分全部写入新建文件中*/

fclose(fp1)/*关闭第一个注册表文件*/

fclose(fp2)/*关闭第二个注册表文件*/

fclose(fp3)/*关闭新建文件*/

}

对于高深莫测的C语言来说,寥寥3千字并不能说清楚的什么问题。但只要您看了此文后,我想对于您学习此语言一定有很大的帮助,同时也能了知晓如何用最短的时间学会C语言以及掌握C语言的精髓所在。另外,此文中所涉及的知识点都是 通过实践得出的,因此若是其他专业书籍没有讲到过的问题可以参考本文。最后祝 学习C语言顺利!

[基础教程]C语言入门必备手册

[基础教程]非缓冲文件系统

[基础教程]缓冲文件系统

[基础教程]共用体

[基础教程]链表的建立、插入和删除

[基础教程]结构体指针的定义和引用

[基础教程]结构体数组的定义和引用

[基础教程]结构体类型变量的定义和引用

[基础教程]main函数的参数

[基础教程]指向指针的指针

[基础教程]指针数组

[基础教程]指针的地址分配

[基础教程]指针与数组

[基础教程]指针与指针变量

[基础教程]数组的初始化

[基础教程]指针变量的定义与引用

[基础教程]指针运算符与指针表达式

[基础教程]二维数组

[基础教程]一维数组

[基础教程]C语言程序应用举例

[基础教程]多维数组

[基础教程]C语言的预处理程序与注释

[基础教程]C语言函数库和文件

[基础教程]实现问题

[基础教程]C语言递归

[基础教程]C语言函数的作用域规则

[基础教程]C语言函数的调用与参数

[基础教程]C语言函数说明与返回值

[基础教程]C语言循环控制语句

[基础教程]C语言条件控制语句

[基础教程]C语言数据的输入与输出

[基础教程]C程序的三种基本结构

[基础教程]C语言表达式

[基础教程]C语言运算符

[基础教程]C语言字符型数据

[基础教程]C语言整型数据

[基础教程]C语言常量与变量

[基础教程]C语言实型数据

[基础教程]C语言的数据类型

[基础教程]算法

[基础教程]C语言的程序结构

[基础教程]C语言的特点

[基础教程]程序设计语言的发展

[基础教程]C语言中的三大定律

[基础教程]PE文件格式详解(2)

[基础教程]PE文件格式详解(1)

[基础教程]Turbo C(V2.0)使用指南

[基础教程]C语言的编程风格

[基础教程]C/C++头文件一览

[基础教程]Turbo C(V2.0)编译错误信息

[基础教程]教你理解复杂的C/C++声明

[基础教程]C/C++中的整型常识

[基础教程]C语言入门之文件(2)

[基础教程]C语言入门之预处理

[基础教程]C语言入门之文件(1)

[基础教程]C语言入门之联合

[基础教程]C语言入门之枚举与位运算(2)

[基础教程]C语言入门之枚举与位运算(1)

[基础教程]C语言入门之结构(3)

[基础教程]C语言入门之结构(2)

[基础教程]C语言入门之结构(1)

[基础教程]C语言入门之多维数组的指针变量

[基础教程]C语言入门之指针的慨念(2)

[基础教程]C语言入门之指针的慨念(1)

[基础教程]C语言入门之函数(5)

[基础教程]C语言入门之函数(4)

[基础教程]C语言入门之函数(3)

[基础教程]C语言入门之函数(2)

[基础教程]C语言入门之函数(1)

[基础教程]C语言入门之数组(2)

[基础教程]C语言入门之数组(1)

[基础教程]C语言入门之转移语句

[基础教程]C语言入门之循环结构

[基础教程]C语言入门之分支结构(2)

[基础教程]C语言入门之分支结构(1)

[基础教程]C语言入门之输入输出(2)

[基础教程]C语言入门之输入输出(1)

[基础教程]C语言入门之运算符和表达式(2)

[基础教程]C语言入门之运算符和表达式(1)

[基础教程]C语言入门之基础语句

[基础教程]C语言入门之数据类型(6)

[基础教程]C语言入门之数据类型(5)

[基础教程]C语言入门之数据类型(4)

[基础教程]C语言入门之数据类型(3)

[基础教程]C语言入门之数据类型(2)

[基础教程]C语言入门之数据类型(1)

基础教程]C程序设计语言概论(3)

[基础教程]C程序设计语言概论(2)

[基础教程]C程序设计语言概论(1)

[基础教程]用户的第一个C程序

[基础教程]C语言的发展

[基础教程]C语言文件系统应用举例

[基础教程]程序设计语言

[基础教程]C语言程序设计(第9章 实用编程技巧)02

[基础教程]C语言程序设计(第9章 实用编程技巧)01

[基础教程]C语言程序设计(第8章 输入输出和文件系统)02

[基础教程]C语言程序设计(第8章 输入输出和文件系统)01

[基础教程]C语言程序设计(第7章 结构体与共用体)03

基础教程]C语言程序设计(第7章 结构体与共用体)02

[基础教程]C语言程序设计(第7章 结构体与共用体)01

[基础教程]C语言程序设计(第6章 指针)03

[基础教程]C语言程序设计(第6章 指针)02

[基础教程]C语言程序设计(第6章 指针)01

[基础教程]C语言程序设计(第5章 数组)

[基础教程]C语言程序设计(第4章 函数)--续

[基础教程]C语言程序设计(第4章 函数)

[基础教程]C语言程序设计(第3章 程序控制语句)--续

[基础教程]C语言程序设计(第3章 程序控制语句)

[基础教程]C语言程序设计(第2章 数据类型、运算符和表达式)--续

[基础教程]C语言程序设计(第2章 数据类型、运算符和表达式)

[基础教程]C语言程序设计(第1章 程序设计与算法)

[基础教程]C语言基础(07-C语言中的关键字)

[基础教程]C语言基础(06-逻辑运算符和逻辑表达式)

[基础教程]C语言基础(05-运算符和表达式)

[基础教程]C语言基础(03-先学2个库函数)

[基础教程]编程者说之C语言

[基础教程]C语言基础(02-数据类型、运算符与表达式)

[基础教程]C语言基础(01-引言及预备知识)

[基础教程]TCP/IP网络重复型服务器通信软件的设计

基础教程]Eclipse3.06 + MinGW3.1配置标准C/C++开发环境

[基础教程]C/C++中结构体(struct)知识点强化

[基础教程]C/C++中的结构体

[基础教程]游戏开发新手入门指南

[基础教程]C语言中的面向对象(4)-面向对象思想

[基础教程]C语言中的面向对象(3)-类模拟的性能分析

[基础教程]C语言中的面向对象(2)-C语言的多态实现

[基础教程]C语言中的面向对象(1)

[基础教程]PE文件格式详解(6)

[基础教程]PE文件格式详解(7)

[基础教程]PE文件格式详解(5)

[基础教程]PE文件格式详解(4)

[基础教程]PE文件格式详解(3)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/11847597.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-19
下一篇 2023-05-19

发表评论

登录后才能评论

评论列表(0条)

保存