Delphi/C++ Builder Map文件格式解析

http://www.tuicool.com/articles/FV32ymn

首先,我们来看第一段:

Delphi/Pascal

Start         Length     Name                   Class
 0001:00401000 00227CC8H .text                   CODE
 0002:00629000 00001728H .itext                  ICODE
 0003:0062B000 00017AC4H .data                   DATA
 0004:00643000 00005860H .bss                    BSS
 0005:00000000 00000040H .tls                    TLS
 0006:00400000 00000000H .pdata                  PDATA

Start         Length Name Class

0001 : 00401000 00227CC8H . text CODE

0002 : 00629000 00001728H . itext                   ICODE

0003 : 0062B000 00017AC4H . data                   DATA

0004 : 00643000 00005860H . bss                     BSS

0005 : 00000000 00000040H . tls                     TLS

0006 : 00400000 00000000H . pdata                   PDATA

Start小节中,前面是序号,后面是偏移地址,可以看到代码段的起始偏移地址是0x00401000,其长度是0x00227CC8(2260168)。

接下来的小节是模块映射段,记录了模块的地址偏移:

Delphi/Pascal

Detailed map of segments

 0001:00000000 0000D0A0 C=CODE     S=.text    G=(none)   M=System   ACBP=A9
 0001:0000D0A0 00000734 C=CODE     S=.text    G=(none)   M=SysInit  ACBP=A9
 0001:0000D7D4 00001A8C C=CODE     S=.text    G=(none)   M=System.Types ACBP=A9
 0001:0000F260 00000768 C=CODE     S=.text    G=(none)   M=System.UITypes ACBP=A9
 0001:0000F9C8 00001C88 C=CODE     S=.text    G=(none)   M=Winapi.Windows ACBP=A9
 0001:00011650 00000330 C=CODE     S=.text    G=(none)   M=Winapi.Messages ACBP=A9
 0001:00011980 00000390 C=CODE     S=.text    G=(none)   M=System.SysConst ACBP=A9
 0001:00011D10 00000320 C=CODE     S=.text    G=(none)   M=System.RTLConsts ACBP=A9

Detailed map of segments

0001 : 00000000 0000D0A0 C = CODE S = . text G = ( none ) M = System  ACBP = A9

0001 : 0000D0A0 00000734 C = CODE S = . text G = ( none ) M = SysInit  ACBP = A9

0001 : 0000D7D4 00001A8C C = CODE S = . text G = ( none ) M = System .Types ACBP = A9

0001 : 0000F260 00000768 C = CODE S = . text G = ( none ) M = System .UITypes ACBP = A9

0001 : 0000F9C8 00001C88 C = CODE S = . text G = ( none ) M = Winapi .Windows ACBP = A9

0001 : 00011650 00000330 C = CODE S = . text G = ( none ) M = Winapi .Messages ACBP = A9

0001 : 00011980 00000390 C = CODE S = . text G = ( none ) M = System .SysConst ACBP = A9

0001 : 00011D10 00000320 C = CODE S = . text G = ( none ) M = System .RTLConsts ACBP = A9

一般我们关心的是C=CODE类型的记录,M指定了所隶属的模块名称,可以方便我们定位到特定的文件。

再接下来是函数地址映射段,记录了每个函数的地址偏移:

Delphi/Pascal

Address             Publics by Name

 0001:0021E30C       main..TAutoFreeTestObject
 0001:0021CFE0       main..TForm1
 0001:0021EE1C       main..TForm1.Button20Click$15$ActRec
 0001:0021F4C4       main..TForm1.Button31Click$30$ActRec
 0003:00017374       main.ACount
 0001:0021F37C       main.DoFreeJobDataC1
 0001:0021EA90       main.DoGlobalJob
 0004:0000585C       main.Form1
 0001:0021F874       main.RunWithPoster

Address             Publics by Name

0001 : 0021E30C main . . TAutoFreeTestObject

0001 : 0021CFE0 main . . TForm1

0001 : 0021EE1C main . . TForm1 . Button20Click $ 15 $ ActRec

0001 : 0021F4C4 main . . TForm1 . Button31Click $ 30 $ ActRec

0003 : 00017374 main . ACount

0001 : 0021F37C main . DoFreeJobDataC1

0001 : 0021EA90 main . DoGlobalJob

0004 : 0000585C main . Form1

0001 : 0021F874 main . RunWithPoster

再跟在后面的每个源码行对应的偏移:

Delphi/Pascal

Line numbers for qstring(qstring.pas) segment .text

   585 0001:001DA8E4   586 0001:001DA8EB   587 0001:001DA8F6   588 0001:001DA915
   589 0001:001DA920   591 0001:001DA92C   592 0001:001DA933   597 0001:001DA938
   598 0001:001DA958   599 0001:001DA966   600 0001:001DA96A   603 0001:001DA98E

Line numbers for qstring ( qstring . pas ) segment . text

585 0001 : 001DA8E4 586 0001 : 001DA8EB 587 0001 : 001DA8F6 5880001 : 001DA915

589 0001 : 001DA920 591 0001 : 001DA92C 592 0001 : 001DA933 597 0001: 001DA938

598 0001 : 001DA958 599 0001 : 001DA966 600 0001 : 001DA96A 603 0001: 001DA98E

前面是行号,后面是类型:偏移地址。

然后是绑定的资源文件信息:

Delphi/Pascal

Bound resource files

c:program files (x86)embarcaderostudio15.0libWin32
eleasecontrols.res
c:program files (x86)embarcaderostudio15.0libWin32
eleaseuttons.res
c:program files (x86)embarcaderostudio15.0libWin32
eleaseextdlgs.res
main.dfm
qworkerdemo.res
qworkerdemo.drf

Bound resource files

c : program files ( x86 ) embarcadero studio 15.0 lib Win32 release controls. res

c : program files ( x86 ) embarcadero studio 15.0 lib Win32 release buttons. res

c : program files ( x86 ) embarcadero studio 15.0 lib Win32 release extdlgs. res

main . dfm

qworkerdemo . res

qworkerdemo . drf

最后是程序入口地址:

Delphi/Pascal

Program entry point at 0002:000016D4

Program entry point at 0002 : 000016D4

注意计算实际程序时址时,要加上一个起始偏移量的,如

QQ截图20140924154616

图中的代码地址是0x006206CB,转换成Map文件中的地址要减去第一个段中声明的代码段的起始偏移量0x00401000,得到的结果是0x21F6CB,然后我们在Map文件中找这个地址,可以得出结果为:

Delphi/Pascal

Line numbers for main(main.pas) segment .text
...
480 0001:0021F665   483 0001:0021F6B8   484 0001:0021F6CB   485 0001:0021F6E2
...

Line numbers for main ( main . pas ) segment . text

. . .

480 0001 : 0021F665 483 0001 : 0021F6B8 484 0001 : 0021F6CB 485 0001 :0021F6E2

. . .

也就是说,现在的位置是main.pas的第484行。

在Map文件中,在函数地址映射段中,我们可以找到:

Delphi/Pascal

0001:0021F598       main.TForm1.Button31Click$30$ActRec.$0$Body
 0001:0021F6B8       main.TForm1.Button32Click
 0001:0021F704       main.TForm1.Button3Click

0001 : 0021F598 main . TForm1 . Button31Click $ 30 $ ActRec . $ 0 $ Body

0001 : 0021F6B8 main . TForm1 . Button32Click

0001 : 0021F704 main . TForm1 . Button3Click

所以,我也可以得到结果是在main单元的函数TForm1.Button32Click。

【补充】

在Delphi或C++Builder中要生成Map文件,需要在工程选项里,将 Linker 里的 Map file generate 设置为Detail模式,否则是没有Map文件的。

原文地址:https://www.cnblogs.com/jackStudy/p/5050487.html