The LDD and NM described in this article are two useful tools for analyzing programs under Linux. LDD is a tool used to analyze the dynamic libraries that a program needs to rely on when it runs; nm is a tool for viewing the contents of a symbol table in a specified program. Here are some examples of these two tools:
1. LDD, look at the following example, using LDD to see the dynamic library on which CS programs depend:
[email protected]:~/public$ ldd cslinux-gate.so.1 = (0xffffe000) libz.so.1 =/lib/libz.so.1 (0xb7f8c000) libpthread.so.0 =/lib/libpthread.so.0 (0xb7f75000) libcrypto.so.0.9.8 =/usr/lib/libcrypto.so.0.9.8 ( 0xb7e4d000) libpcre.so.0 =/usr/lib/libpcre.so.0 (0xb7e21000) libstdc++.so.6 =/usr/local/gcc4.5.1/lib/ Libstdc++.so.6 (0xb7d40000) libm.so.6 =/lib/libm.so.6 (0xb7d18000) libgcc_s.so.1 =/usr/local/gcc4.5.1/lib/ Libgcc_s.so.1 (0xb7cfd000) libc.so.6 =/lib/libc.so.6 (0xb7bbc000)/lib/ld-linux.so.2 (0xb7fab000) libdl.so.2 = /lib/libdl.so.2 (0xb7bb7000) |
In the above example, the results of LDD can be divided into three columns:
- First column: What library does the program need to rely on
- Second column: The library that the system provides for the library that the program needs
- Column three: Start address of insecure library download
Through the above information, we can get the following information:
- (1) By comparing the first column and the second column, we can analyze whether the program needs to depend on the library and the system is actually provided, matches
- (2) By observing the third column, we can know where the symbol in the current library begins in the corresponding process's address space
2. NM, we introduce the NM tool using the following example:
Let's take a look at this simple program:
#include "iostream" using namespace std; class Test{public: void Hello() { cout<<"Hello world!" << Endl; }}; int main(){ test test; Test. Hello (); } |
Next, we compile the program and then look at the results of NM:
[email protected]:~/public$ g++ test.cc-o test[email protected]:~/public$ nm TEST08049F10 D _ Dynamic08049ff4 d _global_offset_table_080486f0 t _global__i_main080487fc R _io_stdin_used W _Jv_RegisterClasses08 0486b0 T _z41__static_initialization_and_destruction_0ii0804870c W _zn4test5helloev U [email protected] @GLIBC xx_3.4 u [email protected] @GLIBCXX_3.4 U [email protected] @GLIBCXX_3.40804a040 B [Email pro Tected] @GLIBCXX_3.4 U [email protected] @GLIBCXX_3.40804a0d4 b _zstl8__ioinit U [email protected] @GLIBCXX_3.408049f00 d __ctor_end__08049ef8 D __ctor_list__08049f08 D __dtor_end__08049f04 D __dtor_list__080488c8 R __ frame_end__08049f0c d __jcr_end__08049f0c D __jcr_list__0804a02c A __bss_start U [email protected] @GLIBC_2.1. 30804a024 d __data_start080487b0 t __do_global_ctors_aux08048610 t __do_global_dtors_aux0804a028 D __dso_handle W __gmon_start__ U [Email protecteD] @CXXABI_1.3080487AA t __i686.get_pc_thunk.bx08049ef8 d __init_array_end08049ef8 d __init_array_start08048740 t __ libc_csu_fini08048750 T __libc_csu_init U [email protected] @GLIBC_2.00804a02c a _edata0804a0d8 a _END080487DC T _fini080487f8 R _fp_hw08048508 t _init080485e0 t _start0804a0cc b completed.70650804a024 W data_start0804a0d0 b dtor_id x.706708048670 T frame_dummy08048694 t main |
Above is the test of all the symbols in this program, the first need to introduce the above content format:
- First column: Address of the current symbol
- Second column: The type of the current symbol (for a description of the type, a friend of interest can read it in man nm)
- Third column: Name of the current symbol
In the above results, like _zn4test5helloev, a lot of reader friends may be dizzy, here is a little trick, in NM, with the-C option, you can convert these difficult to understand the symbols to facilitate our reading of the symbol Testhello (). This is mainly caused by the mangle mechanism in C + +, and the specified symbols listed are demangle. Say so much, in the end nm to our program what specific help, I think there are mainly the following aspects:
(1) Determine whether the specified symbol is defined in the specified program (the more common way: nm-c proc | grep symbol)
(2) Fix undefined reference error during program compile, and mutiple definition error
(3) View the address of a symbol and the approximate location of the process space (BSS, data, text area, which can be judged by the type of the second column)