如何挂接我的android应用程序的系统调用

问题描述:

我想拦截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的博客帮助下完成了这项工作?任何其他方法?我被*了。任何帮助,将不胜感激。

错误与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