Android中GOT表HOOK手動實現續

2021-08-11 12:37:58 字數 2443 閱讀 3021

上篇實現了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 因為程式的分支很多,並不是所有的分支都能跑到,比如異常處理,異常處理分支中的動態鏈結庫裡面的函式也許永遠都跑不到 所以,一上來就解析所有出現過的動態庫裡面的函式時個浪費的辦法,...