0

我想攔截connect()系統調用並使用我自己的自定義實現。自定義實現將執行一些操作,如打印日誌以簡化操作,然後進一步調用系統實現。如何掛接我的android應用程序的系統調用

我看着Audrey's blog其中的方法是修補PLT。但不幸的是,當嘗試更改重定位表中的地址時,此代碼崩潰。

經過一段時間的護目鏡後,我碰到This already answered question。但是這裏描述的方法給了我以下錯誤。

*****跳轉到case標籤[-fpermissive] jni/test.cpp:107:20:錯誤:交叉初始化'uint32_t entry_page_start'jni/test.cpp:106:15:錯誤:交叉初始化'uint32_t page_size'*****

Andrey's blog掛鉤呼叫方法後建議更改Here,看起來像這樣。

int hook_call(char *soname, char *symbol, unsigned newval) { 
soinfo *si = NULL; 
Elf32_Rel *rel = NULL; 
Elf32_Sym *s = NULL; 
unsigned int sym_offset = 0; 
if (!soname || !symbol || !newval) 
return 0; 
si = (soinfo*) dlopen(soname, 0); 
if (!si) 
return 0; 
s = soinfo_elf_lookup(si, elfhash(symbol), symbol); 
if (!s) 
return 0; 
sym_offset = s - si->symtab; 
rel = si->plt_rel; 
/* walk through reloc table, find symbol index matching one we've got */ 
for (int i = 0; i < si->plt_rel_count; i++, rel++) { 
    unsigned type = ELF32_R_TYPE(rel->r_info); 
    unsigned sym = ELF32_R_SYM(rel->r_info); 
    unsigned reloc = (unsigned)(rel->r_offset + si->base); 
    unsigned oldval = 0; 
    if (sym_offset == sym) { 
    switch(type) { 
    case R_ARM_JUMP_SLOT: 
     // YOUR LINES 
     uint32_t page_size = getpagesize(); 
     uint32_t entry_page_start = reloc& (~(page_size - 1)); 
     mprotect((uint32_t *)entry_page_start, page_size, PROT_READ | PROT_WRITE); 

     /* we do not have to read original value, but it would be good 
     idea to make sure it contains what we are looking for */ 
    oldval = *(unsigned*) reloc; 
    *((unsigned*)reloc) = newval; 
    return 1; 
    default: 
    return 0; 
} 

我在做什麼錯,我把mProtect()方法放在一些錯誤的地方?我們有沒有人在Andrey的博客幫助下完成了這項工作?任何其他方法?我被封鎖了。任何幫助,將不勝感激。

回答

2

錯誤與mProtect()無關。這實際上也是我放置代碼片段的完全相同的地方。這裏是我的代碼,它工作正常:

void* hook_call(char *soname, char *symbol, void* newval) { 
soinfo *si = NULL; 
    Elf32_Rel *rel = NULL; 
    Elf32_Sym *s = NULL; 
    unsigned int sym_offset = 0; 
    if (!soname || !symbol || !newval) 
     return 0; 

    si = (soinfo*) dlopen(soname, RTLD_LAZY); 
    if (!si) 
    return 0; 


    s = soinfo_elf_lookup(si, elfhash(symbol), symbol); 
    if (!s) 
    return 0; 

    sym_offset = s - si->symtab; 
    rel = si->plt_rel; 


    const char *strtab = si->strtab; 
    Elf32_Sym *symtab = si->symtab; 

    /* walk through reloc table, find symbol index matching one we've got */ 
    int i; 

    for (i = 0; i < si->plt_rel_count; i++, rel++) { 
    unsigned type = ELF32_R_TYPE(rel->r_info); 
    unsigned sym = ELF32_R_SYM(rel->r_info); 
    unsigned reloc = (unsigned)(rel->r_offset + si->base); 
    //unsigned oldval = 0; 
    void* pOldFun; 

    if (sym_offset == sym) { 

    switch(type) { 
     case R_ARM_JUMP_SLOT: 
      //Set appropriate memory access rights 
      uint32_t page_size = getpagesize(); 
      uint32_t entry_page_start = reloc& (~(page_size - 1)); 
      mprotect((uint32_t *)entry_page_start, page_size, PROT_READ | PROT_WRITE); 

     pOldFun = (void *)*((unsigned *)reloc); 

      *((unsigned int*)reloc)= (unsigned)newval; 

      return pOldFun; 
     default: 
      return 0; 
    } 
    } 
    } 
    return 0; 

}

的*跳轉到case標籤...錯誤:越過正常使用的開關的情況下,即在初始化時出現初始化變量時,不能正確initilized一個案例在另一個案例中使用。看看這個question。類似的錯誤發生並已解決。

+0

12-09 16:53:51.453 E/dalvikvm(20622):dlopen(「/ data/app-lib/com.fun-1/libtest.so」)失敗:dlopen失敗:找不到符號「getpagesize 「引用」libtest.so「... – 2014-12-09 11:27:32

+0

我需要添加一些嗎?或一些鏈接器標誌? – 2014-12-09 13:12:04

+0

我設法掛鉤連接調用,爲什麼我不能通過再次調用相同的函數但使用不同的函數名參數來掛接寫入調用** pOldWrite =(void *)hook_call(「libjavacore.so」,「write」, (void *)my_write); ** – 2014-12-10 11:15:57

相關問題