前段時間遇到個怪問題,有個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)
trace_type(lookup, "found %s in %s (%p) %zd",
name, si->name, reinterpret_cast(s->st_value),
static_cast(s->st_size));
return s;
case stb_local:
if (lookup_scope != symbollookupscope::kallowlocal)
trace_type(lookup, "found local %s in %s (%p) %zd",
name, si->name, reinterpret_cast(s->st_value),
static_cast(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)
return h;
}
hash節 結構如下:
在資料中如下:
根據算好的hash值,用公式unsigned n = bucket[hash % nbucket]; unsigned n2 = chain[n]
n2就是改符號應該存在的符號表偏移,然後用這個偏移到符號表去找,如果正好就是這個,那麼恭喜你。。運氣真好。
如果是被手動修改了符號名字串,那麼一般都不會正好是這個偏移。
如果不是,就要繼續,n2 = chain[n2] 如果這時的n2不等於0,就要繼續n2 = chain[n2]直到等於0為止,然後在這個偏移寫入之前查好的符號表偏移。
大功告成!
可執行檔案 ELF 格式
elf executable and linking format 是一種物件檔案的格式,用於定義不同型別的物件檔案 object files 中都放了什麼東西 以及都以什麼樣的格式去放這些東西。它自最早在 system v 系統上出現後,被 unix 世界所廣泛接受,作為預設的二進位制檔案格式來使...
ELF學習 可執行檔案
相比較重定位檔案,可執行檔案的elf header中入口位址是0x8048320.而且除了section header外,還存在program header.program header起始於第52個位元組,因此program header應該是緊接著elf header。可執行檔案的elf 布局如...
可執行檔案格式elf和bin
常用的可執行檔案包含兩類 原始二進位制檔案 bin 和可載入執行的二進位制檔案,在linux中可載入執行的二進位制檔案為elf檔案。在linux os上,為了執行可執行檔案,他們是遵循elf格式的,通常gcc o test test.c,生成的test檔案就是elf格式的。執行elf檔案時核心會使用...