在上文中,我们想得到变量i的地址,必须首先运行使用nm命令,我们本文使用linux中的bfd库,自己编写函数来提取变量的地址,代码如下:
list10.c
#include "ptrace.h" void main(int argc,char *argv[]) { long storage_needed,num_symbols,i; asymbol **symbol_table; bfd *abfd; char filename[10]; bfd_init(); abfd=bfd_openr(argv[1],NULL); assert(abfd!=NULL); bfd_check_format(abfd,bfd_object); storage_needed=bfd_get_symtab_upper_bound(abfd); assert(storage_needed>=0); printf("storage=%d\n",storage_needed); symbol_table=(asymbol **)malloc(storage_needed); num_symbols=bfd_canonicalize_symtab(abfd,symbol_table); assert(num_symbols>=0); printf("num syms =%d\n",num_symbols); for(i=0;i<num_symbols;i++) printf("%s:\t\t%p\n",bfd_asymbol_name(symbol_table[i]),bfd_asymbol_value(symbol_table[i])); }
为了使用linux的bfd库,需要对头文件加以修改,如下所示:
ptrace.h
#include <bfd.h> #include <assert.h> #include <dlfcn.h> #include <stdlib.h> #include <sys/ptrace.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <sys/user.h> /* For struct user_regs_sturct */ #include <sys/syscall.h> /* For SYS_write etc */ #include <sys/reg.h> /* For constants ORI_EAX etc */ #include <signal.h> #include <stdio.h> /*for stdio*/
编译方式如下:
#gcc list10.c -o list10.o -liberty -ldl -lbfd
我们运行list1o.o
#./list10.o child4.o
可以得到如下输出;
从这里我们可以看出,程序已经成功将变量i的地址提取出来了。