如何从 lib .so 文件中查找函数?

Posted

技术标签:

【中文标题】如何从 lib .so 文件中查找函数?【英文标题】:How to find function from lib .so files? 【发布时间】:2016-08-24 08:02:04 【问题描述】:

我可以打印一个 *.so 文件的导出函数列表,例如

nm -C lib/libopencv_ml.so

然后找到我的函数

nm -C lib/libopencv_ml.so | grep myfunction

但是当我想从所有 .so 文件中查找函数时,如何确定哪个 .so 包含我的函数?

这只是打印函数的所有条目,但我需要知道它出现在哪个 .so 文件中。

nm -C lib/*.so | grep cvSetZero

似乎-H 选项也没有帮助。 -H, --with-filename print the file name for each match

nm -C lib/*.so | grep -Hn cvSetZero

生成如下输出:

(standard input):98:                 U cvSetZero
(standard input):796:                 U cvSetZero
(standard input):2564:00000000000b2540 T cvSetZero
(standard input):8673:                 U cvSetZero
(standard input):12233:                 U cvSetZero
(standard input):15503:                 U cvSetZero
(standard input):17460:                 U cvSetZero
(standard input):18727:                 U cvSetZero
(standard input):20865:                 U cvSetZero

【问题讨论】:

for f in dir/*.so ; do nm -C "$f" | grep foo && echo "$f"; done 【参考方案1】:

我找到了解决办法

nm -C -A lib/*.so | grep cvSetZero

它产生这种输出:

lib/libopencv_calib3d.so:                 U cvSetZero
lib/libopencv_contrib.so:                 U cvSetZero
lib/libopencv_core.so:00000000000b2540 T cvSetZero
lib/libopencv_highgui.so:                 U cvSetZero
lib/libopencv_imgproc.so:                 U cvSetZero
lib/libopencv_legacy.so:                 U cvSetZero
lib/libopencv_ml.so:                 U cvSetZero
lib/libopencv_objdetect.so:                 U cvSetZero
lib/libopencv_video.so:                 U cvSetZero

【讨论】:

【参考方案2】:

你可以添加最后一个 :| c++filt

为了消除符号。同样作为一般说明,gcc-nm 应该在使用 LTO 编译的系统中使用。

编辑:使用nm 的另一种方法是使用-D--defined-only,然后将可能的错误重定向到/dev/nullgrep 精确 带有'\bsymbol_name\b' 的符号。

$ nm -Dn -o --defined-only /lib/* /usr/lib64/* 2> /dev/null | grep '\bprintf\b'
/lib/libc-2.26.so:0000000000058ee0 T printf
/lib/libc.so.6:0000000000058ee0 T printf

这种方式可以搜索定义符号名称的库,而不仅仅是使用它。 -D 只允许在动态库 (.so) 中搜索。

但似乎是扫描定义(+)或不(-)符号的库的最终方法是scanelf

$ scanelf -qRys +printf /lib64/
printf  /lib64/lib/clang/3.7.0/lib/linux/libclang_rt.asan-i386.so
printf  /lib64/lib/clang/3.7.0/lib/linux/libclang_rt.asan-x86_64.so
printf  /lib64/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libasan.so.2.0.0
printf  /lib64/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libtsan.so.0.0.0
printf  /lib64/lib/gcc/x86_64-pc-linux-gnu/5.4.0/32/libasan.so.2.0.0
printf  /lib64/libc-2.26.so
$ scanelf -qRys -printf /lib64/
printf  /lib64/lib/ConsoleKit/ck-collect-session-info
printf  /lib64/libnsl-2.26.so

运行 scanelf-m 选项在 / 上搜索整个系统,而不跨越挂载点。

【讨论】:

以上是关于如何从 lib .so 文件中查找函数?的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向Android 进程注入工具开发 ( 注入代码分析 | 获取 远程 目标进程 中的 /system/lib/libc.so 动态库中的 mmap 函数地址 )

linux中把.c的文件编译成.so

linux中把.c的文件编译成.so

如何在Android Gradle中添加原生so文件依赖

linux c++ 怎么 调用自己函数的

C++学习(三零零)windows如何查看so文件里的函数