上篇實現了got表的手動hook,這裡需要說明一下,got表其實包含了匯入表和匯出表,匯出表指將當前動態庫的一些函式符號保留,供外部呼叫,之前針對hook的就是這種型別的函式。而針對匯入表,這樣的做法顯然不行的,匯入表中的函式實際是在該動態庫中呼叫外部的匯出函式。
匯入表在對應在動態鏈結段.got.plt(dt_pltgot)指向處,但是每項的詳細是和got表中的表項對應的,因此,在解析動態鏈結段時,需要解析dt_jmprel、dt_symtab,前者指向了每乙個匯入表表項的偏移位址和相關資訊,包括在got表中偏移,後者為got表。
hook時只需要判斷找到匯入表表項對應的偏移位址,替換內容為需要跳轉的位址即可。
基於此,我實現了乙個匯入表hook的示例,呼叫returngivevalue函式檢視log日誌即可發現hook成功。
#include
#include
#include
#include
#include
#define logd(...) ((void)__android_log_print(android_log_debug, "ror_got_hook", __va_args__))
#define mem_page_size 4096
#define mem_page_mask (mem_page_size-1)
#define mem_page_start(x) ((x) & ~mem_page_mask)
#define mem_page_end(x) mem_page_start((x) + (mem_page_size-1))
#define elfw(type) elf32_ ## type
char str = "return give value";
jniexport void jnicall returngivevalue()
; strncpy(logstr,str,strlen(str));
logd("%x",(unsigned
int)strncpy);
logd("show : %s",logstr);
}int my_strncpy(char* s1, char* s2, int n)
int __attribute__((constructor)) gothook()
elfw(phdr)* phdr_table = (elfw(phdr)*)(nbase + header->e_phoff);
if (phdr_table == 0)
size_t phdr_count = header->e_phnum;
logd("phdr_count : %d", phdr_count);
//遍歷program header table,ptype等於pt_dynamic即為dynameic,獲取到p_offset
unsigned
long dynamicaddr = 0;
unsigned
int dynamicsize = 0;
for (int i = 0; i < phdr_count; i++)
}logd("dynamic addr : %x",dynamicaddr);
logd("dynamic size : %x",dynamicsize);
/*typedef struct dynamic d_un;
} elf32_dyn;
*/ elfw(dyn)* dynamic_table = (elfw(dyn)*)(dynamicaddr);
unsigned
long jmpreloff = 0;
unsigned
long strtaboff = 0;
unsigned
long pltrelsz = 0;
unsigned
long symtaboff = 0;
int i;
for(i=0;i < dynamicsize / 8;i ++)
if (dynamic_table[i].d_tag == dt_strtab)
if (dynamic_table[i].d_tag == dt_pltrelsz)
if (dynamic_table[i].d_tag == dt_symtab)
}elfw(rel)* rel_table = (elfw(rel)*)(jmpreloff+nbase);
logd("jmpreloff : %x",jmpreloff);
logd("strtaboff : %x",strtaboff);
logd("symtaboff : %x",symtaboff);
//遍歷查詢要hook的匯入函式,這裡以strncpy做示例
for(i=0;i < pltrelsz / 8;i++)
}return
0;}
PLT表和GOT表學習
我們用乙個非常簡單的例子來講解,如下 圖1 然後我們編譯 我們直接 gdb.a.out 來進行反編譯處理,然後通過disas main檢視main函式中的反編譯 如下 圖3 我們可以觀察到 gets plt 和 puts plt 這兩個函式,為什麼後面加了個 plt 因為這個為 plt 表中的資料的...
GOT表覆寫技術
概念 每乙個外部定義的符號在全域性偏移表 global offset table 中有相應的條目,got位於elf的資料段中,叫做got段。作用 把位置無關的位址計算重定位到乙個絕對位址。程式首次呼叫某個庫函式時,執行時連線編輯器 rtld 找到相應的符號,並將它重定位到got之後每次呼叫這個函式都...
PWN基礎15 GOT表 和 PLT表
感謝各位作者的分享精神 事實上,直到第一次呼叫這個函式,都並不知道這個函式的位址,這個功能叫做延遲繫結 lazy bind 因為程式的分支很多,並不是所有的分支都能跑到,比如異常處理,異常處理分支中的動態鏈結庫裡面的函式也許永遠都跑不到 所以,一上來就解析所有出現過的動態庫裡面的函式時個浪費的辦法,...