How to know which library a specific function is defined in? - gdb

[root#xxx memcached-1.4.5]# objdump -R memcached-debug |grep freeaddrinfo
0000000000629e10 R_X86_64_JUMP_SLOT freeaddrinfo
...
(gdb) disas freeaddrinfo
Dump of assembler code for function freeaddrinfo:
0x00000037aa4baf10 <freeaddrinfo+0>: push %rbp
0x00000037aa4baf11 <freeaddrinfo+1>: push %rbx
0x00000037aa4baf12 <freeaddrinfo+2>: mov %rdi,%rbx
So I know freeaddrinfo is a dynamically linked function,but how to know which .so it's defined in?

See this answer. The info symbol freeadrinfo is one way to find out.
On Linux and Solaris you can also use ldd and LD_DEBUG=symbols. For example, if you wanted to find out where localtime in /bin/date is coming from:
LD_DEBUG=bindings ldd -r /bin/date 2>&1 | grep localtime
26322: binding file /bin/date [0] to /lib/libc.so.6 [0]: normal symbol `localtime' [GLIBC_2.2.5]

For certain low version gdb, "info symbol " could not work as you want.
So please use below method:
Run 'p symbol_name' to get symbol address
(gdb) p test_fun
$1 = {<text variable, no debug info>} 0x84bcc4 <test_fun>
Check /proc/PID/maps to find out the module which the symbol address is in.
# more /proc/23275/maps
007ce000-0085f000 r-xp 00000000 fd:00 3524598 /usr/lib/libtest.so
0x84bcc4 is in [007ce000, 0085f000]

Inside the libraries directory you could execute the following command to search for a specific symbol on all libraries:
for file in $(ls -1 *.so); do echo "-------> $file"; nm $file; done | c++filt | grep SYMBOL*
An enhanced version would be to list all libraries that are linked to the executable (through ldd) and go after each library listed searching if the symbol is defined there. Depending on your *nix you might have to tweak the cut parsing:
APP=firefox; for symbol in $(nm -D $APP | grep "U " | cut -b12-); do for library in $(ldd $APP | cut -d ' ' -f3- | cut -d' ' -f1); do for lib_symbol in $(nm -D $library | grep "T " | cut -b12-); do if [ $symbol == $lib_symbol ]; then echo "Found symbol: $symbol at [$library]"; fi ; done; done; done;

Related

gdb - assign pipe output to a variable

I have the following command , I would like to assign his output to a variable:
(gdb) pipe monitor get info | grep cross2_Release.nss | cut -c 3-13
0x566f80400
Tried this
set $main = 'pipe monitor get info | grep cross2_Release.nss | cut -c 3-14'
No symbol table is loaded. Use the "file" command.
Expected result would be to have $main equals to 0x566f80400
At first, I thought this would work:
python output = gdb.execute('pipe monitor get info | grep cross2_Release.nss | cut -c 3-13', to_string=True)
python gdb.set_convenience_variable('main', gdb.parse_and_eval(output))
But this fails because the pipe command sends output to GDB's stdout rather than to a stream that gdb.execute can capture and put into a string. So here's something a little more crude:
shell printf 'set $main = ' > ~/.gdbtmp
pipe monitor get info | grep cross2_Release.nss | cut -c 3-13 >> ~/.gdbtmp
source ~/.gdbtmp
Using the python subprocess.check_output() function it's relatively simple to do that:
py gdb.set_convenience_variable('main', gdb.parse_and_eval(subprocess.check_output('grep cross2_Release.nss | cut -c 3-13', shell=True, input=gdb.execute('monitor get info', to_string=True), text=True)))
But that's a lot to type, so I would pack that into a gdb convenience function:
import subprocess
class Pipe(gdb.Function):
def __init__(self):
super(Pipe, self).__init__("pipe")
def invoke(self, gdb_cmd, pipe_cmd):
return gdb.parse_and_eval(subprocess.check_output(pipe_cmd.string(), shell=True, input=gdb.execute(gdb_cmd.string(), to_string=True), text=True))
Pipe()
Which then could be used like this:
set $main = $pipe("monitor get info", "grep cross2_Release.nss | cut -c 3-14")

dynamic string search in shell script

I have a string in shell script which is
list="apr/2018-06-24 17_10_39/2018-06-24 17_10_39.html
apr/2018-06-24 17_10_39/access_log.zip
apr/2018-06-25 17_12_48/2018-06-25 17_12_48.html
apr/2018-06-25 17_12_48/access_log.zip
apr/2018-06-26 17_13_36/2018-06-26 17_13_36.html
DS_BLS_731.dat
DS_BLS_732.dat
DS_BLS_733.dat
apr/2018-06-26 17_13_37/ DS_BLS_739.dat
apr/2018-06-26 17_13_38/ DS_BLS_738.dat
apr/2018-06-26 17_13_39/ DS_BLS_737.dat"
I need to find DS_BLS_max(sequence number).dat
here DS_BLS_max(sequence number).dat=DS_BLS_739.dat
grep -o 'DS_BLS_[0-9]*\.dat' <<< "$list" | sort -V | tail -n 1
Output:
DS_BLS_739.dat
See: The Stack Overflow Regular Expressions FAQ

How to download latest version of software from same url using wget

I would like to download a latest source code of software (WRF) from some url and automate the installation process thereafter. A sample url like is given below:-
http://www2.mmm.ucar.edu/wrf/src/WRFV3.6.1.TAR.gz
In the above url, the version number may change time to time after the developer release the new version. Now I would like to download the latest available version from the main script. I tried the following:-
wget -k -l 0 "http://www2.mmm.ucar.edu/wrf/src/" -O index.html ; cat index.html | grep -o 'http:[^"]*.gz' | grep 'WRFV'
With above code, I could pull all available version of the software. The output of the above code is below:-
http://www2.mmm.ucar.edu/wrf/src/WRFV2.0.3.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV2.1.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV2.1.2.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV2.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV2.2.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV2.2.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3-Chem-3.0.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3-Chem-3.0.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3-Chem-3.1.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3-Chem-3.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3-Chem-3.2.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3-Chem-3.2.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3-Chem-3.3.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3-Chem-3.3.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3-Chem-3.4.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3-Chem-3.4.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3-Chem-3.5.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3-Chem-3.5.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3-Chem-3.6.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3-Chem-3.6.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3-Var-do-not-use.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3.0.1.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3.0.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3.1.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3.2.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3.2.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3.2.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3.3.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3.3.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3.4.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3.4.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3.5.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3.5.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3.6.1.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3.6.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3.TAR.gz
http://www2.mmm.ucar.edu/wrf/src/WRFV3_OVERLAY_3.0.1.1.TAR.gz
However, I am unable to go further to filter out only later version from the link.
Usually, for processing the html-pages i recommendig some perl tools, but because this is an Directory Index output, (probably) can be done by bash tools like grep sed and such...
The following code is divided to several smaller bash functions, for easy changes
#!/bin/bash
#getdata - should output html source of the page
getdata() {
#use wget with output to stdout or curl or fetch
curl -s "http://www2.mmm.ucar.edu/wrf/src/"
#cat index.html
}
#filer_rows - get the filename and the date columns
filter_rows() {
sed -n 's:<tr><td.*href="\([^"]*\)">.*>\([0-9].*\)</td>.*</td>.*</td></tr>:\2#\1:p' | grep "${1:-.}"
}
#sort_by_date - probably don't need comment... sorts the lines by date... ;)
sort_by_date() {
while IFS=# read -r date file
do
echo "$(date --date="$date" +%s)#$file"
done | sort -gr
}
#MAIN
file=$(getdata | filter_rows WRFV | sort_by_date | head -1 | cut -d# -f2)
echo "You want download: $file"
prints
You want download: WRFV3-Chem-3.6.1.TAR.gz
What about adding a numeric sort and taking the top line:
wget -k -l 0 "http://www2.mmm.ucar.edu/wrf/src/" -O index.html ; cat index.html | grep -o 'http:[^"]*.gz' | grep 'WRFV[0-9]*[0-9]\.[0-9]' | sort -r -n | head -1

C++ Name Mangler [duplicate]

Is there any way to get back the mangled name from demangled name in g++.
For example , I have the demangled name func(char*, int), what should I do to get the mangled name i.e _Z4funcPci back?
My question is g++ specific.
You can simply use g++ to compile an empty function with the signature you require and extract the name from that. For example:
echo "int f1(char *, int) {} " | g++ -x c++ -S - -o- | grep "^_.*:$" | sed -e 's/:$//'
gives output
_Z2f1Pci
which is I think what you require. Make sure that you include any relevant header files as they will affect the way the symbols are mangled.
Based on the Bojan Nikolic's approach, here's a better script:
mangle.bash:
IFS='::' read -a array <<< "$1"
indexes=("${!array[#]}")
prefix=""
middle=""
suffix=""
rettype=""
if [ -z "$2" ]; then
rettype="void"
fi
for index in "${indexes[#]}"
do
#echo "$index ${array[index]}"
if [ $index == ${indexes[-1]} ]; then
#echo "last"
middle="$rettype ${array[index]};"
elif [ -n "${array[index]}" ]; then
#echo "not empty"
prefix="${prefix}struct ${array[index]}{"
suffix="${suffix}};"
fi
done
#echo "$prefix$middle$suffix $rettype $1{}"
echo "$prefix$middle$suffix $rettype $1{}" | g++ -x c++ -S - -o- | grep "^_.*:$" | sed -e 's/:$//'
Use:
$ ./mangle.bash "abc::def::ghi()"
_ZN3abc3def3ghiEv
$ ./mangle.bash "abc::def::ghi(int i, char c)"
_ZN3abc3def3ghiEic
$ ./mangle.bash "abc::def::def(int i, char c)" constr
_ZN3abc3defC2Eic
$ ./mangle.bash "abc::def::~def()" destr
_ZN3abc3defD2Ev
But as to constructors and destructors, remember that there are C0 C1 C2 and D0 D1 D2 ones.
What's worst, sometimes you cannot mangle a name because you must get more than one result.
See https://reverseengineering.stackexchange.com/q/4323/4398 (there are multiple destructors in VFT, and all of them are demangled as ClassName::~ClassName()). (The same applies to constructors, I have seen C0 and C2 constructors.)
On the other hand, that answer references the Itanium ABI: https://refspecs.linuxbase.org/cxxabi-1.75.html#mangling-type where mangling is specified.
The itanium-abi Haskell package: it did not work for me (May 2014)
There is a Haskell package
http://hackage.haskell.org/package/itanium-abi
that promises both demangling and mangling, but I could run only the demangling:
Installation on Ubuntu Precise:
sudo aptitude install ghc
sudo aptitude install cabal-install
cabal update
cabal install itanium-abi
Then you run ghci and after import ABI.Itanium and import Data.Either you get:
Prelude ABI.Itanium Data.Either> cxxNameToText $ head (rights [ demangleName "_ZTI13QSystemLocale" ])
"typeinfo for QSystemLocale"
There is mangleName, but it takes a DecodedName which is a data structure rather than a string, and that data structure is produced only by demangleName (unless I overlooked something). Hopefully, this will get better in some future release.
The clang code
I did not try the clang code.

Getting mangled name from demangled name

Is there any way to get back the mangled name from demangled name in g++.
For example , I have the demangled name func(char*, int), what should I do to get the mangled name i.e _Z4funcPci back?
My question is g++ specific.
You can simply use g++ to compile an empty function with the signature you require and extract the name from that. For example:
echo "int f1(char *, int) {} " | g++ -x c++ -S - -o- | grep "^_.*:$" | sed -e 's/:$//'
gives output
_Z2f1Pci
which is I think what you require. Make sure that you include any relevant header files as they will affect the way the symbols are mangled.
Based on the Bojan Nikolic's approach, here's a better script:
mangle.bash:
IFS='::' read -a array <<< "$1"
indexes=("${!array[#]}")
prefix=""
middle=""
suffix=""
rettype=""
if [ -z "$2" ]; then
rettype="void"
fi
for index in "${indexes[#]}"
do
#echo "$index ${array[index]}"
if [ $index == ${indexes[-1]} ]; then
#echo "last"
middle="$rettype ${array[index]};"
elif [ -n "${array[index]}" ]; then
#echo "not empty"
prefix="${prefix}struct ${array[index]}{"
suffix="${suffix}};"
fi
done
#echo "$prefix$middle$suffix $rettype $1{}"
echo "$prefix$middle$suffix $rettype $1{}" | g++ -x c++ -S - -o- | grep "^_.*:$" | sed -e 's/:$//'
Use:
$ ./mangle.bash "abc::def::ghi()"
_ZN3abc3def3ghiEv
$ ./mangle.bash "abc::def::ghi(int i, char c)"
_ZN3abc3def3ghiEic
$ ./mangle.bash "abc::def::def(int i, char c)" constr
_ZN3abc3defC2Eic
$ ./mangle.bash "abc::def::~def()" destr
_ZN3abc3defD2Ev
But as to constructors and destructors, remember that there are C0 C1 C2 and D0 D1 D2 ones.
What's worst, sometimes you cannot mangle a name because you must get more than one result.
See https://reverseengineering.stackexchange.com/q/4323/4398 (there are multiple destructors in VFT, and all of them are demangled as ClassName::~ClassName()). (The same applies to constructors, I have seen C0 and C2 constructors.)
On the other hand, that answer references the Itanium ABI: https://refspecs.linuxbase.org/cxxabi-1.75.html#mangling-type where mangling is specified.
The itanium-abi Haskell package: it did not work for me (May 2014)
There is a Haskell package
http://hackage.haskell.org/package/itanium-abi
that promises both demangling and mangling, but I could run only the demangling:
Installation on Ubuntu Precise:
sudo aptitude install ghc
sudo aptitude install cabal-install
cabal update
cabal install itanium-abi
Then you run ghci and after import ABI.Itanium and import Data.Either you get:
Prelude ABI.Itanium Data.Either> cxxNameToText $ head (rights [ demangleName "_ZTI13QSystemLocale" ])
"typeinfo for QSystemLocale"
There is mangleName, but it takes a DecodedName which is a data structure rather than a string, and that data structure is produced only by demangleName (unless I overlooked something). Hopefully, this will get better in some future release.
The clang code
I did not try the clang code.