?
Solved

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

Posted on 2003-03-14
22
Medium Priority
?
304 Views
Last Modified: 2013-12-03
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
Comment
Question by:purinitin
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 5
  • 3
  • +2
22 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 8136208
>>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
 

Author Comment

by:purinitin
ID: 8136967
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
 
LVL 86

Expert Comment

by:jkr
ID: 8137035
>>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
Get your Disaster Recovery as a Service basics

Disaster Recovery as a Service is one go-to solution that revolutionizes DR planning. Implementing DRaaS could be an efficient process, easily accessible to non-DR experts. Learn about monitoring, testing, executing failovers and failbacks to ensure a "healthy" DR environment.

 
LVL 1

Expert Comment

by:Hermetic
ID: 8139941
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
 
LVL 9

Expert Comment

by:BeyondWu
ID: 8142583
>>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
 
LVL 49

Expert Comment

by:DanRollins
ID: 8144390
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
 

Author Comment

by:purinitin
ID: 8149907
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
 
LVL 9

Expert Comment

by:BeyondWu
ID: 8149922
Have you seen my comments?
0
 

Author Comment

by:purinitin
ID: 8149941
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
 
LVL 9

Expert Comment

by:BeyondWu
ID: 8149960
I only can say, no way! I recommend you give up it:)
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 8149995
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
 

Author Comment

by:purinitin
ID: 8150513
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
 
LVL 49

Expert Comment

by:DanRollins
ID: 8150581
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
 

Author Comment

by:purinitin
ID: 8151783
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
 
LVL 86

Expert Comment

by:jkr
ID: 8151863
>>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
 
LVL 49

Expert Comment

by:DanRollins
ID: 8154154
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
 

Author Comment

by:purinitin
ID: 8179950
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
 

Author Comment

by:purinitin
ID: 8179985
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
 
LVL 49

Assisted Solution

by:DanRollins
DanRollins earned 500 total points
ID: 8182451
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

Get your Disaster Recovery as a Service basics

Disaster Recovery as a Service is one go-to solution that revolutionizes DR planning. Implementing DRaaS could be an efficient process, easily accessible to non-DR experts. Learn about monitoring, testing, executing failovers and failbacks to ensure a "healthy" DR environment.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows how to make a Windows 7 gadget that accepts files dropped from the Windows Explorer.  It also illustrates how to give your gadget a non-rectangular shape and how to add some nifty visual effects to text displayed in a your gadget.…
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question