文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>ltrace的源代码分析以及修改。

ltrace的源代码分析以及修改。

时间:2007-04-02  来源:loughsky

  ltrace其可以打印出程序运行过程中的库函数调用,其原理是通过解析elf文件,找到需要解析的符号,及该符号所对应的地址。在程序运行起来后,首先使用ptrace技术,将该符号对应的位置替换为软件中断,这样在程序运行到该中断时,会通知ltrace,ltrace从而能打印出当时所调用的函数。   在ltrace中,只时能够列出库函数的调用,那么如何来列出自身的函数调用呢? 在elf文件中,我们可以找到symbol的section,该section中包含了程序中所用到的所有符号。 其格式如下   typedef struct {
      Elf32_Word st_name;
      Elf32_Addr st_value;
      Elf32_Word st_size;
      unsigned char st_info;
      unsigned char st_other;
      Elf32_Half st_shndx;
  } Elf32_Sym;
  st_name为symbol section所连接的string section的偏移量。   * st_value   This member gives the value of the associated symbol. Depending on
  the context, this may be an absolute value, an address, etc.;
  details appear below.
  * st_info   This member specifies the symbol's type and binding attributes.  A
  list of the values and meanings appears below. The following code
  shows how to manipulate the values.
    #define ELF32_ST_BIND(i) ((i)>>4)
    #define ELF32_ST_TYPE(i) ((i)&0xf)
    #define ELF32_ST_INFO(b, t) (((b)<<4)+((t)&0xf))
  + Figure 1-18: Symbol Types, ELF32_ST_TYPE   Name         Value
  ====         =====
  STT_NOTYPE       0
  STT_OBJECT       1
  STT_FUNC         2
  STT_SECTION      3
  STT_FILE         4
  STT_LOPROC      13
  STT_HIPROC      15
  所以我们找到symbol表中,type为STT_FUNC,其st_value就是该函数所对应的起始位置。   在这里我们只要修改ltrace中的elf.c文件中的do_init_elf (struct ltelf *lte, const char *filename); 增加如下部分,来读取SYMTAB表。  else if (shdr.sh_type == SHT_SYMTAB)
 {
   Elf_Data *data;
   size_t j;
   lte->symbol = elf_getdata (scn, NULL);
   if (lte->symbol == NULL || elf_getdata (scn, lte->symbol) != NULL)
     error (EXIT_FAILURE, 0, "Couldn't get .symbol data from \"%s\"",
     filename);
      
      lte->symbol_count=shdr.sh_size/shdr.sh_entsize;
 
     scn = elf_getscn (lte->elf, shdr.sh_link);
     if (scn == NULL || gelf_getshdr (scn, &shdr) == NULL)
       error (EXIT_FAILURE, 0, "Couldn't get section header from \"%s\"",
         filename);
    data = elf_getdata (scn, NULL);
     if (data == NULL || elf_getdata (scn, data) != NULL
       || shdr.sh_size != data->d_size || data->d_off)
     error (EXIT_FAILURE, 0, "Couldn't get .symbolstr data from \"%s\"",
     filename);
    lte->symbolstr = data->d_buf;
    }
  修改read_elf (const char *filename)   for (i = 0; i < lte->symbol_count; ++i)   //读取每个符号
  {
     GElf_Sym sym;
     const char *name;
     GElf_Addr addr;
     if(gelf_getsym(lte->symbol,i,&sym) == NULL)  
         error (EXIT_FAILURE, 0, "Couldn't get symbol data from \"%s\"",filename);
     if (ELF32_ST_TYPE(sym.st_info) != STT_FUNC)  //找出符号类型为STT_FUNC
         continue;    
    
     name=lte->symbolstr+sym.st_name;        //将符号名称从偏移量转换为具体的值。
     if (in_load_libraries (name, lte))
     {
        addr = sym.st_value;
        if (addr != 0)
           add_library_symbol (addr, name, &library_symbols);  //将符号加入到全局的hash表中。
     }
  }
  其他代码就不用修改了,可见ltrace代码的结构性与层次性非常的清晰。  
相关阅读 更多 +
排行榜 更多 +
暗夜格斗手游

暗夜格斗手游

棋牌卡牌 下载
魔渊之刃手游

魔渊之刃手游

角色扮演 下载
像素火影次世代手游版

像素火影次世代手游版

体育竞技 下载