• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 315
  • Last Modified:

Getting a symbol name from it's address in a DLL

Hi,

I have a problem here. I have got the base address of a DLL loaded into
my process address space. I have an address of a function in the DLL (RVA).
Is there any SDK API by which I can get the name of the function.

How does the VC++ tool Dependency Walker gets the ordinal list with
the names and address of the functions. I want to do something like
that only, with given addresses and to find the names.

I'd appreciate a VERY quick response as I am stuck up with this issue.

Thanx.

Nitin
0
purinitin
Asked:
purinitin
  • 7
  • 5
  • 3
  • +2
2 Solutions
 
jkrCommented:
>>Is there any SDK API by which I can get the name of the function.

'SymGetSymFromAddr()' is the API you are looking for. Matt Pietrek describes using the debug/sybol APIs in this "Under the Hood" column: http://www.microsoft.com/msj/defaultframe.asp?page=/msj/0597/hood0597.htm&nav=/msj/0597/newnav.htm

Basically, you would

     if     (     !SymInitialize     (     hProcess,
                                        NULL,
                                        FALSE
                                   )
          )
          {
               // error
          }


     PIMAGEHLP_SYMBOL     pimgSym;
     DWORD                    dwDisplacement;

     pimgSym     =     ( PIMAGEHLP_SYMBOL) malloc (     sizeof     (     IMAGEHLP_SYMBOL)     +     256);

     pimgSym->SizeOfStruct     =     sizeof     (     IMAGEHLP_SYMBOL)     +     256;
     pimgSym->MaxNameLength     =     256;


          if     (     !SymGetSymFromAddr     (     hProcess,
                                                  dwAdress,
                                                  &dwDisplacement,
                                                  pimgSym
                                             )
               )
               {
                    // error
               }

     free     (     pimgSym);

0
 
purinitinAuthor Commented:
Thanx for the input jkr.

But SymGetSymFromAddr() requires that my DLL should
be created with /DEBUG option.
In my case, the application is release built, hence
there is no program database (.pdb) file because
of which this call would fail.

Please suggest.

Thanx.

Nitin
0
 
jkrCommented:
>>In my case, the application is release built, hence
>>there is no program database (.pdb) file because
>>of which this call would fail.

:o)

See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/_core_turn_on_generation_of_debug_information_for_the_release_build.asp

("Turn on Generation of Debug Information for the Release Build")
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
HermeticCommented:
If you have access to MSDN, there is a technical
article on viewing this type of information along with
source code.  The article is titled:
"YAHU, or Yet Another Header Utility"
There is a source file called peview.cpp that contains
a function called DumpExports. This function includes
computing the address of the export and retrieving the
textual name of the export.  I think that this could
easily be used to do what you are considering.
0
 
BeyondWuCommented:
>>I have an address of a function in the DLL (RVA).
I think you can walk through the Import/Export table of this dll. But this method need the functions exported by name, If the function exported by ordinal you can't do this. You can walk through the export table, get each thunk, compare the address with the target address. refer to IMAGE_EXPORT_DESCRIPTOR structure.
>>Is there any SDK API by which ..
Yes, for debug version or release version which has debug info, you can use SymGetSymFromAddr or other DbgHelp Functions. If you can know the whole functions name list, there is a lame method, use GetProcAddress for all these list, and then compare it with your know address.
0
 
DanRollinsCommented:
For a release build in which no debugging info has been provided, there is exactly one way to get the symbol name of variables:

    Contact the programmer and ask her to email you the .MAP file.    Or download the source code (wll, two ways :)

-- Dan
0
 
purinitinAuthor Commented:
Thanx for the input jkr.

But SymGetSymFromAddr() requires that my DLL should
be created with /DEBUG option.
In my case, the application is release built, hence
there is no program database (.pdb) file because
of which this call would fail.

Please suggest.

Thanx.

Nitin
0
 
BeyondWuCommented:
Have you seen my comments?
0
 
purinitinAuthor Commented:
Ok. Few things.

1. The DLL is provided to me i.e it's a customer DLL.
   Hence, I cannot rebuild it.
2. I cannot assume that all the functions will be
   exported, hence cannot walk through the export table.
3. I have the DLL and the address of the function passed
   on by the DLL to my application. So I can only
   play around with the address of the function.

Now if the function is not exported, can I still get it's
name from the DLL. I mean, isn't there a section in the DLL
which saves the names of all the functions in the DLL ?
If there is, then that might be helpful.

What do you experts think of it ?




0
 
BeyondWuCommented:
I only can say, no way! I recommend you give up it:)
0
 
DanRollinsCommented:
Great!  Since you know that the address is not the address of a function named in the export table, and we know that you do not have access to the source code (or presumably the .Map file) we have narrowed down the possibilities and at last it can be stated unequivocally:

It is not possible for you to to obtain the function name that is associated with that address.

Glad to help!

-- Dan
0
 
purinitinAuthor Commented:
OK. I get your point. :-)

There is another way I can get this fixed.
In the same scenario, as I mentioned above, can
I make sure that I always load the customer DLL
at a specific location in my program address space ?

Again, I cannot rebuild the DLL, but I want to do it
through my program itself. Any APIs ?

Please help.

Thanx,

Nitin
0
 
DanRollinsCommented:
How about this:

Tell us exactly what you are trying to do.  Odds are there is a very simple way to do it, but you have gotten off on this "get the symbol name" tangent and you need to get back on track.  So tell us all of the details, but don't mention symbol names because they are not relevant.

-- Dan
0
 
purinitinAuthor Commented:
Ok.
So I have got a user DLL which has a few callback
functions. I have an interface through which I get
the function pointers. I once load this DLL into my
program and run it.
Now I have to restart my program and have to fire a
callback function in the user DLL.
The problem is that I can get the function pointers
the first time. So I have to save the function pointers
so that when I restart my program, I can use
these function pointers to call the functions.
Now it cannot be assumed that the DLL would be loaded
at the same location everytime. Hence, I try to save the
names of the callback functions the first time, so that
the next time on I can use GetProcAddress() to get this
function pointer. But to get the names I have to use
SymGetSymFromAddr() which requires that the DLL be DEBUG built. And this I cannot assume as it is the user DLL.

I hope I have made the problem clear rather than confusing
you guys.

Nitin
0
 
jkrCommented:
>>I have an interface through which I get the function pointers

Why don't you use that very interface to get the function pointers again after you restarted your application?
0
 
DanRollinsCommented:
As I thought, you want to keep it a secret.  Fine.

At least you cleared up one thing: the symbol names are irrelevant.  You can just as easily call then "Fn1" and "Fn2" or FnPtr[0...99].

I am not certain that you are using the term "callback function" meaninginfully.  Do you just mean "a function in the DLL that you wish to call"?

The simple solution is to do what jkr implies -- use whatever discovery technique you are currently using each time you need to access the DLL.  But there may also be a middle ground.  If you can learn the address of even one function ... via GetProcAddress..., then the other addresses will be offsets from that address.

-- Dan
0
 
purinitinAuthor Commented:
Ok.
So I have got a user DLL which has a few callback
functions. I have an interface through which I get
the function pointers. I once load this DLL into my
program and run it.
Now I have to restart my program and have to fire a
callback function in the user DLL.
The problem is that I can get the function pointers
the first time. So I have to save the function pointers
so that when I restart my program, I can use
these function pointers to call the functions.
Now it cannot be assumed that the DLL would be loaded
at the same location everytime. Hence, I try to save the
names of the callback functions the first time, so that
the next time on I can use GetProcAddress() to get this
function pointer. But to get the names I have to use
SymGetSymFromAddr() which requires that the DLL be DEBUG built. And this I cannot assume as it is the user DLL.

I hope I have made the problem clear rather than confusing
you guys.

Nitin
0
 
purinitinAuthor Commented:
Dan,

Your observation is absolutely correct that I could use
the same interface calls to get the function pointer
"every time". The problem here is that I provide a function
call to the user through which he passes his function pointers to my program. Once my program is running, I get
these function pointers from the application. After that,
the user won't be making any calls to register his
functions with my program, or in other words, won't be
sending across his function pointers again when I restart
my program.

0
 
DanRollinsCommented:
You will need to change your system design -- there is no way you will be able to save and reuse a callback address across loads of your DLL

In your new design, you will need to require that your users pass in their callback address each time they access your program.  A common technique is to force them to 'open' access to your DLL and you return a 'handle' (an arbitrary unique value) which you save in an internal handle table.  Then they must pass that handle to you with each call.  When you look to see if that is a valid handle, you can fail gracefully if it is not in your 'saved handle table.'

-- Dan
0

Featured Post

Take Control of Web Hosting For Your Clients

As a web developer or IT admin, successfully managing multiple client accounts can be challenging. In this webinar we will look at the tools provided by Media Temple and Plesk to make managing your clients’ hosting easier.

  • 7
  • 5
  • 3
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now