首 页 | 新 闻 | Symbian | Android| Windows Mobile | J2ME | 下载中心 | 游戏策划招聘与求职 | 购书指南 | 视频教程
您现在的位置: 开发视界 >> Symbian英文资料 >> Tools SDK >> 正文
How to dump DLL exports using LIB files
作者:佚名    文章来源:不详    更新时间:2006-5-7 11:21:54

How to dump DLL exports using LIB files

Sometimes it is necessary to figure out what system API functions my application is linked to. On other occasions it is needed to find an ordinal of an exported function. This ordinal can be passed to RLibrary::Lookup (TInt anOrdinal) for dynamic linking.

Petran

Symbian provides some tools for exploring content of a Symbian executable. For example, petran.exe (included with SDK) is normally used during build to convert PE executable to Symbian E32 format. But petran can also be used to dump content of E32 file. For example:

petran HelloWorld.app

will print content of the E32 file headers, print a binary dump of the executable code and print a list of imported functions, for example:


............
4 imports from APPARC[10003a3d].DLL
       3
       6
       27
       71
............
7 imports from EUSER[100039e5].DLL
       3
       809
       828
       858
       1504
       1582
       1611
............
See Symbian Executable File Format for more information. C++ sources for petran are available as a part of Symbian OS C++ Build Tools. You can find a download link at Symbian OS Tools . The big limitation of petran is that it cannot print names for the imported functions because these names are not present in the E32 file.

DepTool

Another tool called "DepTool" is available from the same download link. It is also discussed at DepTool. Unlike petran, DepTool is written in Perl. It mostly does the same think as petran: examines E32 file format and prints file imports and exports (it does not print file header and binary dump, however). DepTool has an important extra benefit: it is trying to locate a LIB file correspondent to the given E32 file and extract exported file names from it. This feature is valuable for DLL writers, but it does not work for HelloWorld because it is not a DLL and does not have a LIB file. I didn’t find a way to extract export names of EUSER.DLL using DepTool. It may be possible to write my own Perl program, which will use DepDb.pm (the engine of DepTool), but there is a much simpler approach explained below.

Binutils

In order to figure out what is the mysterious export #3 from EUSER.DLL (as an example) we need to examine euser.lib import libraries. For Windows Emulator libraries (in Epoc32\release\wins\udeb) the task is easy: simply run


dumpbin /exports %EPOCROOT%Epoc32\release\wins\udeb\euser.lib

to see all exports. But the ordinal numbers are different from Symbian version. Unfortunately, dumpbin cannot be used on Symbian version of euser.lib in Epoc32\release\armi\urel because it was created using GNU tools. To do that we need to use GNU Binary Utilities (binutils) included in Symbian SDK at Epoc32\gcc\bin. There are a number of utilities available for working with lib archives. For example, "ar" allows enumerating object files in the archive as well as extracting files. For example:


ar -t %EPOCROOT%Epoc32\release\armi\urel\euser.lib

prints a long list of object files:


............
ds00003.o
ds00001.o
ds00002.o
ds01621.o
............
A more detailed information is provided by "nm", for example:


nm --demangle %EPOCROOT%Epoc32\release\armi\urel\euser.lib

prints:


............
ds00003.o:
00000000 b .bss
00000000 d .data
00000000 ? .idata$4
00000000 ? .idata$5
00000000 ? .idata$6
00000000 ? .idata$7
00000000 t .text
00000000 ? CBase::__imp_newL(unsigned int)
        U _head____EPOC32_RELEASE_ARMI_UREL_EUSER_LIB
00000000 ? _imp__newL__5CBaseUi
00000000 T CBase::newL(unsigned int)
.............
In fact, we already found an answer to our question. It appears that starting from version 6.1 "filename of the export stub file in LIB files matches the ordinal number". This quote is from a comment in file DepDb.pm available as a part of DepTool mentioned above. If this is true, then ds00003.o corresponds to the ordinal #3 and it’s name is "CBase::newL(unsigned int)". This was the first of functions from EUSER imported by HelloWorld (see above).

DepDb.pm provides two techniques for extracting ordinal numbers: ReadLib and ReadLibExtreme. ReadLib invokes the "nm —demangle lib-name" and relies on the fact that file names match ordinal numbers. ReadLibExtreme does a more thorough job and extracts the ordinal from an import stub. First it extracts an object file from the LIB using "ar -p lib-file obj-file", then it invokes "objdump -s -j .idata\$5 obj-file-name" to dump the .idata\$5 section, which contains the ordinal number integer.

A simple export dumper.

I happened to develop my own export dumper before I found DepTool and DepDb.pm. My tool simply calls "objdump —disassemble-all —demangle lib-file" to dump all object files in the archive, then it parses it for ".text" section (which has the exported function name as the label) and for ".idata$5" section, which contains the ordinal. Here is a dump of the same "ds00003.o" object, which contains CBase::newL(unsigned int):


C:/DOCUME~1/INBUIL~1/LOCALS~1/Temp/d1000s_00003.o:     file format epoc-pe-arm-little

Disassembly of section .text:

00000000 <CBase::newL(unsigned int)>:
  0:        e59fc004         ldr        r12, [pc, #4]        ; c <CBase::newL(unsigned int)+0xc>
  4:        e59cc000         ldr        r12, [r12]
  8:        e12fff1c         bx        r12
  c:        00000000         andeq        r0, r0, r0
Disassembly of section .data:
Disassembly of section .idata$7:

00000000 <.idata$7>:
  0:        00000000         andeq        r0, r0, r0
Disassembly of section .idata$5:

00000000 <CBase::__imp_newL(unsigned int)>:
  0:        80000003         andhi        r0, r0, r3
Disassembly of section .idata$4:

00000000 <.idata$4>:
  0:        80000003         andhi        r0, r0, r3
Disassembly of section .idata$6:
For more information about import table and stubs search microsoft.com for ".idata$5".

Here is my Perl source code:

File 1: epoc_exports.pl:


# Purpose: reads a dump of a EPOC import library from standard input,
# extracts and dumps ordinal:name pairs of exported functions.
# The dump must be created by "objdump --disassemble-all --demangle library_path.lib"

my $InSection = "";
my $Name = "";
while (<STDIN>) {
   #print("$_\n");
   if(($F1) = (m/Disassembly of section (\S+)\:/)) {
       #Example: Disassembly of section .text:
       #Example: Disassembly of section .idata$5:
                $InSection = $F1;
        }
   elsif(($InSection eq ".text") && (($F1) = (m/00000000 \<(.+)\>\:/))) {
       #Example: 00000000 <CBase::newL(unsigned int)>:
       $Name = $F1;
   }
   elsif(($InSection eq '.idata$5') && (($F1) = (m/^\s+0\:\s+(\S+)/))) {
       #Example:    0:        80000003         andhi        r0, r0, r3
       $Ordinal = hex($F1) & 0x7fffffff;
       printf("%d(0x%x):%s\n", $Ordinal, $Ordinal, $Name);
   }
}
File 2: epoc_dump_and_export.pl:

# Purpose: enumerates all EPOC .lib files in the given directory and dumps ordinal:name pairs # Usage: perl epoc_dump_and_export.pl directory # Requires EPOC version of objdump on the PATH, File::Basename Perl module and # epoc_exports.pl in the same directory as the present file.

use File::Basename;

$dir=shift(@ARGV);
$our_dir=dirname($0);
opendir(DIR, $dir) || die "can't opendir $dir: $!"; while($file = readdir(DIR)) {
   if(index($file,".lib") > 0) {
       $path = "$dir/$file";
       print("$path\n");
       system("objdump --disassemble-all --demangle $path | perl $our_dir/epoc_exports.pl > $file.exp");
   }
}
closedir DIR;

Usage: To dump a single LIB file use:


objdump --disassemble-all --demangle %EPOCROOT%Epoc32\release\armi\urel\euser.lib | perl epoc_exports.pl
This will generate a very long list of all exports from EUSER.DLL:


.............
3(0x3):CBase::newL(unsigned int)
1(0x1):memset
2(0x2):memcpy
1621(0x655):TUidType::operator[](int) const
1620(0x654):TRegion::operator[](int) const
1619(0x653):CObjectIx::operator[](int)
1618(0x652):CObjectCon::operator[](int)
.............

To dump all LIB files:


perl epoc_dump_and_export.pl %EPOCROOT%Epoc32\release\armi\urel\
This will generate a file with extension .lib.exp for each lib file in the given directory.

Conclusion: Knowing imported and exported function names and ordinals helps to debug and troubleshoot applications and DLL as well as to load libraries and call functions dynamically.

相关文章:
How to reset the alternate makmake entry in Codewarrior
Carbide.vs - Disabling the MMP/PKG File update feature
Codewarrior: how to avoid the "Too Many Include Paths" error when using the UIQ 2.1 SDK
Carbide.c++: Setting up On Target Debugging
Display the extended panic code in Emulator or Device
Start automatically an application or an exe after its installation
Compress Your Symbian C++ Executables
How To Freeze New Exports From Dll
 

站点地图 | 加入收藏 | 联系站长 | 广告服务 |
QQ:280529124  Tel:0592-8271361 辽ICP备05021703号