• 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文件的。

  • 相关阅读:
    CentOS查看和修改MySQL字符集
    centos修改mysql密码或者进入mysql后解决Access denied for user ''@'localhost' to database 'mysql错误
    Centos设置开机启动Apache和Mysql
    centos搭建ftp服务器
    1QT在线帮助文档
    storm学习
    java提高篇之理解java的三大特性——多态
    基于AQS的锁
    反转单链表的几种方法
    Java:基于LinkedList实现栈和队列
  • 原文地址:https://www.cnblogs.com/jackStudy/p/5050487.html
Copyright © 2020-2023  润新知