在上文中,我们想得到变量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的地址提取出来了。