C - 打印存储在符号位置的值

Posted

技术标签:

【中文标题】C - 打印存储在符号位置的值【英文标题】:C - Print value stored at symbol location 【发布时间】:2016-09-27 22:05:39 【问题描述】:

我有一个简单的命令行应用程序(自定义 dir 二进制文件),我想对其进行检测。调试符号已启用,我可以在objdumpnm -D 的输出中看到我感兴趣的全局字符串指针the_full_path_name

是否有可能在c 中以某种方式查找该符号名称/位置,并使用代码注入打印它指向的内存内容(即:LD_PRELOAD 库与自定义 gcc attribute((constructor)) 和附加职能)?我需要完成此操作,而无需将 gdb 附加到进程。

谢谢。

【问题讨论】:

C 不支持自省。但是如果你知道变量,你可以简单地printf("%d", the_var)int以外的其他转换类型说明符)。 据我了解,这应该可以通过LD_PRELOAD 实现。您是否尝试过使用全局声明 extern char *the_full_path_name;(或其确切类型)导入符号,然后打印? 你用-rdynamic编译程序了吗? 【参考方案1】:

我不确定我是否理解了您的问题,但以下内容对您有帮助吗?

包含全局指针的文件

$ cat global.c     
char mylongstring[] = "myname is nulled pointer";

$ gcc -fPIC -shared global.c -o libglobal.so

原始库

$ cat get_orig.c 
#include <stdio.h>    
extern char * mylongstring;
char *get()

  mylongstring = "get from orig";
  return mylongstring;


$ gcc -fPIC  -shared  get_orig.c -o libget_orig.so -L. -lglobal

假图书馆

$ cat get_dup.c 
#include <stdio.h>
extern char * mylongstring;
char *get()

  mylongstring = "get from dup";
  return mylongstring;


$ gcc -fPIC  -shared  get_dup.c -o libget_dup.so -L. -lglobal

全局变量的实际消费者:

$ cat printglobal.c 
#include <stdio.h>

char *get();

int main(void)

 printf("global value=%s\n",get());
 return 0;

$ gcc printglobal.c -L. -lglobal -lget_orig -o a.out

otool 输出

$ otool -L a.out 
a.out:
        libglobal.so (compatibility version 0.0.0, current version 0.0.0)
        libget_orig.so (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)

运行a.out

$ DYLD_LIBRARY_PATH=./ ./a.out                                                                                                                                                           
global value=get from orig

替换库

$ cp /tmp/libget_dup.so libget_orig.so 
$ DYLD_LIBRARY_PATH=./ ./a.out
global value=get from dup

顺便说一句,我在 MAC 上对此进行了测试,所以 .so 真的是 .dylib 的误称

【讨论】:

以上是关于C - 打印存储在符号位置的值的主要内容,如果未能解决你的问题,请参考以下文章

c和指针

c语言的数据类型,运算符,存储类型

C Primer Plus学习笔记- 运算符表达式和语句

scarpy设置日志打印级别和存储位置

我似乎无法访问存储在数组位置 0 和 1 中的值

linux下进程内存布局及变量存储位置检查