动态库、可执行文件符号表分析
发布日期:2021-06-23 04:43:30
浏览次数:4
分类:技术文章
本文共 10657 字,大约阅读时间需要 35 分钟。
动态库内容分析
文章目录
1. 动态库编译
基本思路为:
- 先编写两个C文件,其中各自实现几个函数,变量,然后将其分别编译为动态库;
- 再编写一个实现main函数的C文件,分别调用上述第一步动态库中的函数;
- 分析最后的可执行文件和动态库文件的符号表;
1.1 第一个C文件:basic.c
这个C文件只定义并实现了四个不同形参的函数、五个静态变量、一个全局变量。由于只关心符号表或者其他二进制内容,因此不具体实现特定功能。
/************************************************************************* > File Name: basic.c > Author: Toney Sun > Mail: vip_13031075266@163.com > Created Time: 2020年04月20日 星期一 09时50分51秒 ************************************************************************/#includeint basic_func=4;static char *Author="Toney Sun";void func1(){ int tmp_var; static char *Mail="vip_13031075266@163.com";}void func2(int x){ static char *Mail="vip_13031075266@163.com";}int func3(char *a){ static char *Mail="vip_13031075266@163.com";}char * func4(int x, int y){ static char *Mail="vip_13031075266@163.com";}
1.2第二个C文件:demo.c
在demo.c中我定义一个结构体udphdr。然后分别定义了两个全局变量,实现了三个函数:func5, func6, fun7。
/************************************************************************* > File Name: demo.c > Author: Toney Sun > Mail: vip_13031075266@163.com > Created Time: 2020年04月19日 星期日 22时33分39秒 ************************************************************************/#includestruct udphdr{ short dstport; short srcport; short checksum; short length;};enum Date{ Monday, Tuesday, Wensday, Thursday, Friday, Saturday, Sunday,};struct udphdr udp1;enum Date today = Monday;int iphdr1=10;extern void func1();extern void func2(int x);extern int func3(char *);extern char * func4(int x, int y);int fun5(int a){ struct udphdr udp2; func1(); printf("aaaaaaaaaaa\n");} int fun6(char *a){ static struct udphdr udp1; func2(10); printf("aaaaaaaaaaa\n");}int fun7(int a, char *b){ func3("test"); printf("aaaaaaaaaaa\n");}
1.3第三个C文件:main.c
main.c主要用来实现main函数,并调用其他C文件中实现的函数和全局变量。从而观察对比不同的函数、变量在符号表中的异同。
/************************************************************************* > File Name: main.c > Author: Toney Sun > Mail: vip_13031075266@163.com > Created Time: 2020年04月20日 星期一 09时44分38秒 ************************************************************************/#includeextern void func1();extern int fun5(int a); extern int fun6(char *a);extern int fun7(int a, char *b);extern struct udphdr udp;extern int iphdr;int myAge=25;char *mail="vip_13031075266@163.com";int show(){ printf("Author: Toney Sun\n");}int main(int argc, char **argv){ int a=10; int b=11; fun5(a); fun6("aaaaa"); fun7(a, "Toney Sun"); show(); udp.srcport=4500; iphdr=10; return 0;}
2.动态库编译
-
使用gcc工具将basic.c编译为libbasic.so;
-
使用gcc工具将demo.c编译为libdemo.so;
-
使用gcc工具将main.c链接上述两个动态库后编译为a.out
**注意:**我们不是为了执行该a.out, 而是想查看上述三个二进制文件的内容(符号表)。
toney@ubantu$ gcc -shared -fpic -o libdemo.so demo.c toney@ubantu$ gcc -shared -fpic -o libbasic.so basic.c toney@ubantu$ gcc main.c -L./ -ldemo -lbasictoney@ubantu$ ls -ltotal 35-rwxrwxrwx 1 root root 8552 4月 20 10:18 a.out-rwxrwxrwx 1 root root 454 4月 20 09:52 basic.c-rwxrwxrwx 1 root root 763 4月 20 09:49 demo.c-rwxrwxrwx 1 root root 8016 4月 20 09:43 demo.so-rwxrwxrwx 1 root root 7528 4月 20 10:17 libbasic.so-rwxrwxrwx 1 root root 8128 4月 20 10:17 libdemo.so-rwxrwxrwx 1 root root 846 4月 20 10:18 main.c
链接怎么还有个顺序问题:(
toney@ubantu$ gcc main.c -L./ -lbasic -ldemo.//libdemo.so: undefined reference to `func3'.//libdemo.so: undefined reference to `func1'.//libdemo.so: undefined reference to `func2'collect2: error: ld returned 1 exit statustoney@ubantu$ gcc main.c -L./ -ldemo -lbasictoney@ubantu$
3.二进制内容分析
3.1 libbasic.so分析
3.1.1 basic.c内容汇总
序号 | 函数或变量 | 性质 |
---|---|---|
1 | void func1() | 自定义函数 |
2 | void func2(int x) | 自定义函数 |
3 | int func3(char *a) | 自定义函数 |
4 | char * func4(int x, int y) | 自定义函数 |
5 | int basic_func; | 自定义全局变量 |
6 | static char *Author; | 自定义全局静态变量 |
7 | static char *Mail; | func1内定义局部静态变量 |
8 | static char *Mail; | func2内定义局部静态变量 |
9 | static char *Mail; | func3内定义局部静态变量 |
10 | static char *Mail; | func4内定义局部静态变量 |
3.1.2 libbasic.so符号表
- 使用nm工具查看符号表内容(当然也可以使用其他工具查看,例如objdump, readelf, ldd等):
toney@ubantu$ nm libbasic.so 0000000000201028 d Author ==================全局静态变量=================0000000000201020 D basic_func ====================全局变量==================0000000000201050 B __bss_start0000000000201050 b completed.7698 w __cxa_finalize00000000000005a0 t deregister_tm_clones0000000000000630 t __do_global_dtors_aux0000000000200e88 t __do_global_dtors_aux_fini_array_entry0000000000201018 d __dso_handle0000000000200e90 d _DYNAMIC0000000000201050 D _edata0000000000201058 B _end00000000000006a4 T _fini0000000000000670 t frame_dummy0000000000200e80 t __frame_dummy_init_array_entry00000000000007e8 r __FRAME_END__000000000000067a T func1 ===================实现函数===================0000000000000681 T func2 ===================实现函数===================000000000000068b T func3 ===================实现函数===================0000000000000696 T func4 ===================实现函数===================0000000000201000 d _GLOBAL_OFFSET_TABLE_ w __gmon_start__00000000000006d0 r __GNU_EH_FRAME_HDR0000000000000568 T _init w _ITM_deregisterTMCloneTable w _ITM_registerTMCloneTable0000000000201030 d Mail.2252 ================局部静态变量===================0000000000201038 d Mail.2256 ================局部静态变量===================0000000000201040 d Mail.2260 ================局部静态变量===================0000000000201048 d Mail.2265 ================局部静态变量===================00000000000005e0 t register_tm_clones0000000000201050 d __TMC_END__
- 使用nm -Da 查看本动态库定义的内容信息
toney@ubantu$ nm -Da libbasic.so 0000000000201020 D basic_func ----------------1----------------0000000000201050 B __bss_start w __cxa_finalize0000000000201050 D _edata0000000000201058 B _end00000000000006a4 T _fini000000000000067a T func1 ----------------2----------------0000000000000681 T func2 ----------------3----------------000000000000068b T func3 ----------------4----------------0000000000000696 T func4 ----------------5---------------- w __gmon_start__0000000000000568 T _init w _ITM_deregisterTMCloneTable w _ITM_registerTMCloneTable
3.1.3 小结
- 本文件内定义的全局变量用‘D’来表示;
- 本文件内定义的全局静态变量用‘d’来表示;
- 本文件内实现的函数用‘T’来表示;
- 不同函数内定义的静态变量在符号表中的符号有所差别,因此不会出现混淆的问题。
- 从上述内容可以猜测:使用‘d’表示的变量不能被其他文件引用(上述‘d’标识的都是静态变量,这也比较合理)
3.2 libdemo.so分析
3.2.1 demo.c内容汇总
序号 | 函数或变量 | 性质 |
---|---|---|
1 | struct udphdr udp1; | 自定义的全局结构体变量 |
2 | static struct udphdr udp2; | 自定义全局静态变量 |
3 | struct udphdr udp2; | 自定义局部变量 |
4 | enum Date today | 自定义全局枚举变量 |
5 | int iphdr; | 自定义全局变量 |
6 | extern void func1(); | 外部函数 |
7 | extern void func2(int x); | 外部函数 |
8 | extern int func3(char *); | 外部函数 |
9 | extern char * func4(int x, int y); | 外部函数 |
10 | int fun5(int a) | 自定义函数 |
11 | int fun6(char *a) | 自定义函数 |
12 | int fun7(int a, char *b) | 自定义函数 |
3.2.2 demo.so符号表
同样的,我们使用nm工具来查看动态库符号表信息:
toney@ubantu$ nm libdemo.so 0000000000201044 B __bss_start0000000000201048 b completed.7698 w __cxa_finalize@@GLIBC_2.2.500000000000006b0 t deregister_tm_clones0000000000000740 t __do_global_dtors_aux0000000000200e18 t __do_global_dtors_aux_fini_array_entry0000000000201038 d __dso_handle0000000000200e20 d _DYNAMIC0000000000201044 D _edata0000000000201068 B _end0000000000000800 T _fini0000000000000780 t frame_dummy0000000000200e10 t __frame_dummy_init_array_entry0000000000000908 r __FRAME_END__000000000000078a T fun5 =============================00000000000007ae T fun6 =============================00000000000007d3 T fun7 ============================= U func1 ============================= U func2 ============================= U func3 =============================0000000000201000 d _GLOBAL_OFFSET_TABLE_ w __gmon_start__000000000000081c r __GNU_EH_FRAME_HDR0000000000000638 T _init0000000000201040 D iphdr1 ============================= w _ITM_deregisterTMCloneTable w _ITM_registerTMCloneTable U puts@@GLIBC_2.2.500000000000006f0 t register_tm_clones0000000000201048 d __TMC_END__0000000000201050 B today =============================0000000000201060 B udp1 =============================0000000000201058 b udp1.2278 =============================
3.2.3 小结
- 结构体变量(非基本型变量)使用‘B’或‘b’来标识。
- 全局结构体变量使用‘B’标识
- 局部静态结构体变量使用‘b’标识
- 局部变量不会显示在符号表中
- 本文件内使用的函数使用‘T’标识
- 引用其他文件的函数使用‘U’标识
3.3 可执行文件a.out分析
3.3.1 main.c内容汇总
序号 | 函数或变量 | 性质 |
---|---|---|
1 | extern void func1(); | 引用外部函数 |
2 | extern int fun5(int a); | 引用外部函数 |
3 | extern int fun6(char *a); | 引用外部函数 |
4 | extern int fun7(int a, char *b); | 引用外部函数 |
5 | extern struct udphdr udp1; | 引用外部结构体变量 |
6 | extern int iphdr1; | 引用外部基本类型变量 |
7 | int myAge=25; | 本地全局变量 |
8 | char *mail=“vip_13031075266@163.com”; | 本地全局静态变量 |
3.3.2 a.out符号表
同样使用nm工具进行查看:
toney@ubantu$ nm a.out 0000000000201020 B __bss_start0000000000201030 b completed.7698 w __cxa_finalize@@GLIBC_2.2.50000000000201000 D __data_start0000000000201000 W data_start00000000000007a0 t deregister_tm_clones0000000000000830 t __do_global_dtors_aux0000000000200d88 t __do_global_dtors_aux_fini_array_entry0000000000201008 D __dso_handle0000000000200d90 d _DYNAMIC0000000000201020 D _edata0000000000201038 B _end0000000000000974 T _fini0000000000000870 t frame_dummy0000000000200d80 t __frame_dummy_init_array_entry0000000000000b2c r __FRAME_END__ U fun5 ============1============== U fun6 ============2============== U fun7 ============3==============0000000000200fa0 d _GLOBAL_OFFSET_TABLE_ w __gmon_start__00000000000009c0 r __GNU_EH_FRAME_HDR00000000000006f8 T _init0000000000200d88 t __init_array_end0000000000200d80 t __init_array_start0000000000000980 R _IO_stdin_used0000000000201020 B iphdr1 ============4============= w _ITM_deregisterTMCloneTable w _ITM_registerTMCloneTable0000000000000970 T __libc_csu_fini0000000000000900 T __libc_csu_init U __libc_start_main@@GLIBC_2.2.50000000000201018 d mail ============5==============000000000000088d T main ============6==============0000000000201010 D myAge ============7============== U puts@@GLIBC_2.2.500000000000007e0 t register_tm_clones000000000000087a T show ============8==============0000000000000770 T _start0000000000201020 D __TMC_END__0000000000201028 B udp1 ============9==============
3.3.3 小结
- 引用的外部函数使用‘U’来标识
- 全局变量使用‘D’来标识
- 全局静态变量使用‘d’来标识
- 引用的外部全局变量(简单类型和复杂类型)使用‘B’来标识
4.总结
对符号表中常见的变量、函数标识总结如下:
序号 | 标识 | 说明 |
---|---|---|
1 | T | 自定义函数(本文件内) |
2 | t | 尚未分析 |
3 | D | 自定义标准类型全局变量(如int, char, float等) |
4 | d | 自定义标准类型静态变量(包括全局静态变量、局部静态变量) |
5 | B | 自定义扩展类型全局变量(如结构体类型,枚举型等)、引用的外部全局变量 |
6 | b | 自定义静态扩展类型变量(包括全局静态、局部静态类型变量) |
7 | U | 引用的外部函数 |
8 | 局部变量在符号表中是不存在的。 | |
… | … | … |
转载地址:https://blog.csdn.net/s2603898260/article/details/105632270 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
感谢大佬
[***.8.128.20]2024年03月27日 21时33分43秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
java判断ipv6地址类型_IPv6地址类型与格式
2019-04-21
linux java jdk_linux安装JDK
2019-04-21
JAVA中math的作用_Java中Random 和 Math 的概述及使用(二十六)
2019-04-21
mysql排序rank_MySQL_实现组内排序-Oracle中的rank()函数的功能
2019-04-21
linux 模拟键盘输入到进程,Linux 下模拟键盘输入
2019-04-21
linux服务器上已安装R 用户下载R包,R语言安装R package的2种方法
2019-04-21
linux下mysql 备份方法,Linux下mysql数据库备份方法小结
2019-04-21
肺部ct重建_胸片检查容易漏诊肺癌,去年正常今年晚期常发生,体检一定要做CT...
2019-04-21
x86so文件装换成arm64位_64位系统正式发布说明及介绍!!
2019-04-21
for循环中取出最大最小 累加_LeetCode之长度最小的子数组
2019-04-21
如何打开老公人脸识别_【话题】南宁已有小区启用人脸识别门禁,有人点赞有人忧...
2019-04-21