The offset in the value of the symbol nm?

To give you some context, this is what I am trying to achieve: I embed a const char * in the general object file to have a version string in the .so file itself. I am doing data analysis, and this line lets me tell you which version of the software created it. All of this works great.

The problem I am facing is when I try to directly read a line from the .so library. I tried to use

nm libSMPselection.so | grep _version_info 

and get

 000000000003d968 D __SMPselection_version_info 

everything is fine and as expected (char * is called _SMPselection_version_info). However, I expected that now you can open the file, search for 0x3d968 and start reading my line, but all I get is garbage.

When I open the .so file and just look at the contents of the line (I know how it starts), I can find it at 0x2e0b4. At this address it is there, zero completed and as expected. (I am using this method at the moment.)

I am not a computer scientist. Can someone explain to me why the symbol value shown by nm is incorrect or otherwise, what is the symbol value if it is not the address of the symbol?

(By the way, I work on Mac with OSX 10.7)

+6
source share
4 answers

No one suggested the easiest way: Make a binary that dynamically loads your library (give it a name on the command line) and do dlsym () for your character (or it can get it on the command line) string pointer and print it to standard output .

+2
source

Assuming this is an ELF or similarly structured binary, you should consider the address where the material is loaded, which is affected by things in the ELF header.

Using objdump -Fd in your binary, you can have a disassembler that also displays the exact offset of the character file.

Using objdump -x , you can find this bootloader address, usually 0x400000 for standard linux executables.

The next thing you need to be careful with is to see if its an indirect string, which you can do most easily using objdump -g . When a string is found as an indirect string, in the position output by objdump -Fd , you will not find the string, but the address. From this you must subtract the bootloader address again. Let me show you an example for one of my binaries:

 objdump -Fd BIN | grep VersionString 45152f: 48 8b 1d 9a df 87 00 mov 0x87df9a(%rip),%rbx # ccf4d0 <acVersionString> (File Offset: 0x8cf4d0) objdump -x BIN ... LOAD off 0x0000000000000000 vaddr 0x0000000000400000 paddr 0x0000000000400000 align 2**12 ... 

So, we look at 0x8cf4d0 in the file and find in hexeditor:

 008C:F4D0 D8 C1 89 00 00 00 00 00 01 00 00 00 FF FF FF FF 

So, we take 0x89C1D8 there, subtract 0x400000 and have 0x49c1d8, and when we look there in the hexeditor, we find:

 0049:C1D0 FF FF 7F 7F FF FF 7F FF 74 72 75 6E 6B 5F 38 30 0049:C1E0 34 33 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

What does "trunk_8043" mean.

YMMV, especially when its a different file format, but it’s a common way to structure these things, with lots of warts and details that are rejected for special occasions.

+5
source

On Linux, you have the "strings" command, which helps you extract strings from binary files.

http://linux.about.com/library/cmd/blcmdl1_strings.htm

HPUX (and I think other Unix combinations) have a similar command called "what." It only extracts lines starting with "@ (#)", but if you control the contents of the line, this is not a problem.

+1
source

Why do you expect the offset displayed by nm to be the offset to the .so file? .so files are not just memory images; they contain a lot of other information, and also have a more or less complex format. On Unix (at least on most Unices), shared objects use elves. To find the information, you will have to interpret the various fields in the file to find the desired character in which segment and where this segment begins in the file. (You may find a library that makes them easier to read.)

In addition, if you correctly said that you entered char const* , i.e. that your code contains something like:

 char const* version = "..."; 

then the address or offset version is the address or offset of the pointer, not the string data it points to. Define it as:

 char const version[] = "..."; 

will solve it.

Finally, the simplest solution might simply be to make sure that the string has some highly identifiable pattern and scans the entire file linearly looking for that pattern.

+1
source

Source: https://habr.com/ru/post/914800/


All Articles