map文件介绍及使用查错 9个预定义段

 

map文件介绍及使用查错

来源:网络 | 时间:2010-01-23 |  点击: 69次

先简单介绍 一下map文件中的遇到的各个段,起始它们是在PE中的公共段。 
一个Windows NT的应用程序典型地拥有9个预定义段,它们是.text、.bss、.rdata、.data、.rsrc、.edata、.idata、.pdata和.debug。一些应用程序不需要所有的这些段,同样还有一些应用程序为了自己特殊的需要而定义了更多的段。这种做法与MS-DOS和Windows 3.1中的代码段和数据段相似。事实上,应用程序定义一个独特的段的方法是使用标准编译器来指示对代码段和数据段的命名,或者使用名称段编译器选项-NT--就和Windows 3.1中应用程序定义独特的代码段和数据段一样。 
可执行代码段,.text 
Windows NT将所有的代码段组成了一个单独的段,名为".text"。 
数据段,.bss、.rdata、.data 
.bss段表示应用程序的未初始化数据,包括所有函数或源模块中声明为static的变量。bss段(Block Started by Symbol segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域,一般在初始化时bss 段部分将会清零。bss段属于静态内存分配,即程序一开始就将其清零了。在《Programming ground up》里对.bss的解释为:There is another section called the .bss. This section is like the data section, except that it doesn't take up space in the executable. 
text和data段都在可执行文件中(在嵌入式系统里一般是固化在镜像文件中),由系统从可执行文件中加载;而bss段不在可执行文件中,由系统初始化。 
.rdata段表示只读的数据,比如字符串文字量、常量和调试目录信息。 
导入数据段,.idata 
调试信息段,.debug 
所有其它变量(除了出现在栈上的自动变量)存储在.data段之中。基本上,这些是应用程序或模块的全局变量。 
资源段,.rsrc 
下面介绍如何使用map文件查错 
1 首先必须生成程序的 MAP 文件。什么是 MAP 文件?简单地讲, MAP 文件是程序的全局符号、源文件和代码行号信息的唯一的文本表示方法,它可以在任何地方、任何时候使用,不需要有额外的程序进行支持。而且,这是唯一能找出程序崩溃的地方的救星。 
好吧,既然 MAP 文件如此神奇,那么我们应该如何生成它呢?在 VC 中,我们可以按下 Alt+F7 ,打开"Project Settings"选项页,选择C/C++ 选项卡,并在最下面的 Project Options 里面输入:/Zd ,然后要选择Link 选项卡,在最下面的 Project Options 里面输入:/mapinfo:lines和 /map:PROJECT_NAME.map 。最后按下 F7 来编译生成 EXE 可执行文件和 MAP 文件。 
在此我先解释一下加入的参数的含义: 
/Zd 表示在编译的时候生成行信息 
/map[:filename] 表示生成 MAP 文件的路径和文件名 
/mapinfo:lines 表示生成 MAP 文件时,加入行信息 
/mapinfo:exports 表示生成 MAP 文件时,加入 exported functions (如果生成的是 DLL 文件,这个选项就要加上) 
OK,通过上面的步骤,我们已经得到了 MAP 文件,那么我们该如何利用它呢? 
void Crash() 

int i = 0; 
int j = 1; 
int k = j/i; 

void main() 

Crash(); 

很显然本程序有"除0错误",在 Debug 方式下编译的话,运行时肯定会产生"非法操作"。好,让我们运行它,果然,"非法操作"对话框出现了,这时我们点击"详细信息"按钮,记录下产生崩溃的地址--在我的机器上是 0x0040104a 。 
再看看它的 MAP 文件:(由于文件内容太长,中间没用的部分我进行了省略) 
CrashDemo 
Timestamp is 3e430a76 (Fri Feb 07 09:23:02 2003) 
Preferred load address is 00400000 
Start Length Name Class 
0001:00000000 0000de04H .text CODE 
0001:0000de04 0001000cH .textbss CODE 
0002:00000000 00001346H .rdata DATA 
0002:00001346 00000000H .edata DATA 
0003:00000000 00000104H .CRT$XCA DATA 
0003:00000104 00000104H .CRT$XCZ DATA 
0003:00000208 00000104H .CRT$XIA DATA 

Address Publics by Value Rva+Base Lib:Object 
0001:00000020 ?Crash@@YAXXZ 00401020 f CrashDemo.obj 
0001:00000070 _main 00401070 f CrashDemo.obj 
0004:00000000 __IMPORT_DESCRIPTOR_KERNEL32 00424000 kernel32:KERNEL32.dll 
0004:00000014 __NULL_IMPORT_DESCRIPTOR 00424014 kernel32:KERNEL32.dll 
0004:00000138 __imp__GetCommandLineA@0 00424138 kernel32:KERNEL32.dll 
0004:0000013c __imp__GetVersion@0 0042413c kernel32:KERNEL32.dll 
0004:00000140 __imp__ExitProcess@4 00424140 kernel32:KERNEL32.dll 
0004:00000144 __imp__DebugBreak@0 00424144 kernel32:KERNEL32.dll 
0004:00000148 __imp__GetStdHandle@4 00424148 kernel32:KERNEL32.dll 
0004:0000014c __imp__WriteFile@20 0042414c kernel32:KERNEL32.dll 
.. 
entry point at 0001:000000f0 
Line numbers for ./Debug/CrashDemo.obj(d:/msdev/myprojects/crashdem o/crashdemo.cpp) segment .text
预定义段  

   一个Windows NT的应用程序典型地拥有9个预定义段,它们是.text、.bss、.rdata、.data、.rsrc、.edata、.idata、.pdata和.debug。一些应用程序不需要所有的这些段,同样还有一些应用程序为了自己特殊的需要而定义了更多的段。这种做法与MS-DOS和Windows 3.1中的代码段和数据段相似。事实上,应用程序定义一个独特的段的方法是使用标准编译器来指示对代码段和数据段的命名,或者使用名称段编译器选项-NT——就和Windows 3.1中应用程序定义独特的代码段和数据段一样。  
   以下是一个关于Windows NT PE文件之中一些有趣的公共段的讨论。  

可执行代码段,.text  

   Windows 3.1和Windows NT之间的一个区别就是Windows NT默认的做法是将所有的代码段(正如它们在Windows 3.1中所提到的那样)组成了一个单独的段,名为“.text”。既然Windows NT使用了基于页面的虚拟内存管理系统,那么将分开的代码放入不同的段之中的做法就不太明智了。因此,拥有一个大的代码段对于操作系统和应用程序开发者来说,都是十分方便的。  
   .text段也包含了早先提到过的入口点。IAT亦存在于.text段之中的模块入口点之前。(IAT在.text段之中的存在非常有意义,因为这个表事实上是一系列的跳转指令,并且它们的跳转目标位置是已固定的地址。)当Windows NT的可执行映像装载入进程的地址空间时,IAT就和每一个导入函数的物理地址一同确定了。要在.text段之中查找IAT,装载器只用将模块的入口点定位,而IAT恰恰出现于入口点之前。既然每个入口拥有相同的尺寸,那么向后退查找这个表的起始位置就很容易了。  

数据段,.bss、.rdata、.data  

   .bss段表示应用程序的未初始化数据,包括所有函数或源模块中声明为static的变量。  
   .rdata段表示只读的数据,比如字符串文字量、常量和调试目录信息。  
   所有其它变量(除了出现在栈上的自动变量)存储在.data段之中。基本上,这些是应用程序或模块的全局变量。  

资源段,.rsrc  

   .rsrc段包含了模块的资源信息。它起始于一个资源目录结构,这个结构就像其它大多数结构一样,但是它的数据被更进一步地组织在了一棵资源树之中。以下的IMAGE_RESOURCE_DIRECTORY结构形成了这棵树的根和各个结点。

导出数据段,.edata  

   .edata段包含了应用程序或DLL的导出数据。在这个段出现的时候,它会包含一个到达导出信息的导出目录。

导入数据段,.idata  

   .idata段是导入数据,包括导入库和导入地址名称表。虽然定义了IMAGE_DIRECTORY_ENTRY_IMPORT,但是WINNT.H之中并无相应的导入目录结构。作为代替,其中有若干其它的结构,名为IMAGE_IMPORT_BY_NAME、IMAGE_THUNK_DATA与IMAGE_IMPORT_DESCRIPTOR。在我个人看来,我实在不知道这些结构是如何和.idata段发生关联的,所以我花了若干个小时来破译.idata段实体并且得到了一个更简单的结构,我名之为IMAGE_IMPORT_MODULE_DIRECTORY。

调试信息段,.debug  

   调试信息位于.debug段之中,同时PE文件格式也支持单独的调试文件(通常由.DBG扩展名标识)作为一种将调试信息集中的方法。调试段包含了调试信息,但是调试目录却位于早先提到的.rdata段之中。这其中每个目录都涉及了.debug段之中的调试信息。调试目录的结构IMAGE_DEBUG_DIRECTORY被定义为:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 以下是使用MATLAB语言读取索引色图像文件、查询和显示其信息的示例代码: ```matlab % 读取索引色图像文件 img = imread('example.gif'); % 显示图像 imshow(img); % 查询图像信息 width = size(img, 2); height = size(img, 1); num_colors = size(img, 3); color_map = colormap; % 显示图像信息 fprintf('图像宽度:%d 像素\n', width); fprintf('图像高度:%d 像素\n', height); fprintf('图像颜色数量:%d 种\n', num_colors); fprintf('颜色映射矩阵:\n'); disp(color_map); ``` 在这个例子中,我们首先使用 `imread` 函数读取名为 "example.gif" 的索引色图像文件。然后使用 `imshow` 函数显示该图像。接下来,我们使用 `size` 函数查询图像的宽度、高度和颜色数量,并使用 `colormap` 函数查询颜色映射矩阵。最后,使用 `fprintf` 和 `disp` 函数分别显示图像信息和颜色映射矩阵。 ### 回答2: 索引色图像是一种颜色编码方式,其中像素值表示图像中的颜色索引。Matlab语言可以用来查询和显示索引色图像文件的信息。 在Matlab中,可以使用imfinfo函数来查询图像文件的信息。这个函数将返回一个结构体,其中包括图像的宽度、高度、色彩类型等信息。通过读取索引色图像文件的信息,我们可以获得有关图像的基本属性。 要显示索引色图像,可以使用imread函数来读取图像文件。读取索引色图像时,可以将'Index'设置为1,以便将图像作为索引颜色图像读取。读取后的图像数据将是一个二维数组,每个元素表示对应像素的颜色索引。 为了显示索引色图像,可以使用imshow函数。在显示图像之前,需要使用一个关于颜色映射的调色板来将索引值映射到RGB颜色。调色板可以由colormap函数来设置,可以选择一些预定义或自定义的调色板。然后,使用imshow函数来显示处理后的图像数据。 综上所述,使用Matlab语言完成一幅索引色图像文件信息查询和显示的步骤如下: 1. 使用imfinfo函数查询图像文件信息,获得图像的基本属性。 2. 使用imread函数读取索引色图像数据。 3. 设置调色板并使用imshow函数显示处理后的图像数据。 通过以上步骤,可以方便地查询索引色图像文件的信息,并用Matlab显示出来。 ### 回答3: 要使用Matlab语言完成一幅索引色图像文件信息查询和显示,可以按照以下步骤操作: 1. 首先,使用Matlab的imread函数读取索引色图像文件。这个函数将图像文件读取为一个矩阵,包含图像的每个像素的索引值。 2. 使用imfinfo函数获取图像文件的相关信息,例如图像的宽度、高度、颜色映射等。 3. 使用imshow函数显示图像。如果图像是索引色图像,还需要设置显示时的颜色映射,可以使用colormap函数指定索引到颜色的映射关系。 以下是一个示例代码: ```matlab % 读取索引色图像文件 img = imread('index_image.jpg'); % 获取图像文件的相关信息 info = imfinfo('index_image.jpg'); width = info.Width; height = info.Height; color_map = info.Colormap; % 设置颜色映射 colormap(color_map); % 显示图像 imshow(img); % 显示图像信息 fprintf('图像宽度:%d 像素\n', width); fprintf('图像高度:%d 像素\n', height); fprintf('图像颜色数:%d\n', size(color_map, 1)); ``` 通过以上代码,可以读取索引色图像文件,并显示图像。同时,还可以获取图像的宽度、高度和颜色数等信息,并打印输出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值