ELF格式可执行文件,更改符号名称要注意的地方

前段时间遇到个怪问题,有个so,用readelf跟ida,或者直接写工具分析,都能找到导出函数名对应的符号表,info啊,之类的也都对。

但在手机上dlsym却不行,困扰了一下,后来发现是有人手动改了导出函数的名字,但是没有在hash节做处理。那么要如何更改hash节呢。


首先找到符号表段,然后根据符号表的name找到名字。然后更改。


但是这还没完,由于linker加载的时候是根据elfhash查找的名字,所以还要改hash段。

static ElfW(Sym)* soinfo_elf_lookup(soinfo* si, unsigned hash, const char* name, const SymbolLookupScope& lookup_scope) {
  ElfW(Sym)* symtab = si->symtab;
  const char* strtab = si->strtab;

  TRACE_TYPE(LOOKUP, "SEARCH %s in %s@%p %x %zd",
             name, si->name, reinterpret_cast<void*>(si->base), hash, hash % si->nbucket);

  for (unsigned n = si->bucket[hash % si->nbucket]; n != 0; n = si->chain[n]) {
    ElfW(Sym)* s = symtab + n;
    if (strcmp(strtab + s->st_name, name)) continue;

    switch (ELF_ST_BIND(s->st_info)) {
      case STB_GLOBAL:
      case STB_WEAK:
        if (s->st_shndx == SHN_UNDEF) {
          continue;
        }

        TRACE_TYPE(LOOKUP, "FOUND %s in %s (%p) %zd",
                 name, si->name, reinterpret_cast<void*>(s->st_value),
                 static_cast<size_t>(s->st_size));
        return s;
      case STB_LOCAL:
        if (lookup_scope != SymbolLookupScope::kAllowLocal) {
          continue;
        }
        TRACE_TYPE(LOOKUP, "FOUND LOCAL %s in %s (%p) %zd",
                name, si->name, reinterpret_cast<void*>(s->st_value),
                static_cast<size_t>(s->st_size));
        return s;
      default:
        __libc_fatal("ERROR: Unexpected ST_BIND value: %d for '%s' in '%s'",
            ELF_ST_BIND(s->st_info), name, si->name);
    }
  }

  return NULL;
}


更改方法:


首先根据字符串节的偏移,对比符号表,找到这个符号在符号表中的偏移。每个符号表是0x10个字节,这个要注意。


然后用如下函数算出你更改名字后的hash。


static unsigned elfhash(const char* _name) {
	const unsigned char* name = reinterpret_cast<const unsigned char*>(_name);
	unsigned h = 0, g;

	while (*name) {
		h = (h << 4) + *name++;
		g = h & 0xf0000000;
		h ^= g;
		h ^= g >> 24;
	}
	return h;
}


hash节 结构如下:



在数据中如下:



根据算好的hash值,用公式unsigned n = bucket[hash % nbucket];  unsigned n2 = chain[n]

n2就是改符号应该存在的符号表偏移,然后用这个偏移到符号表去找,如果正好就是这个,那么恭喜你。。运气真好。


如果是被手动修改了符号名字符串,那么一般都不会正好是这个偏移。

如果不是,就要继续,n2 = chain[n2] 如果这时的n2不等于0,就要继续n2 = chain[n2]直到等于0为止,然后在这个偏移写入之前查好的符号表偏移。


大功告成!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值