如何钩我的Andr​​oid应用程序的系统调用

如何钩我的Andr​​oid应用程序的系统调用

本文介绍了如何钩我的Andr​​oid应用程序的系统调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要拦截connect()系统调用和使用自己定制的实现。自定义实现会做一些动作,例如打印日志为简单起见,然后再调用系统的实现。

I want to intercept the connect() system call and use my own custom implementation. The custom implementation will do some action like printing a log for simplicity and then call the system implementation further.

我看着其中的方法是修补PLT。但不幸的是这code试图在重定位表更改地址时崩溃。

I looked at Audrey's blog where the approach is to patch the PLT. But unfortunately this code is crashing when trying to change the address in the relocation table.

goggling过了一会儿,我碰到This已经回答的问题。但这里介绍的方法给我下面的错误。

After goggling a while i came across This already answered question. But the approach described here gives me the following error.

*****跳转到case标号[-fpermissive] JNI / TEST.CPP:107:20:错误:穿越的'uint32_t的entry_page_startJNI / TEST.CPP初始化:106:15:错误:跨越初始化uint32_t的PAGE_SIZE*****

*****jump to case label [-fpermissive] jni/test.cpp:107:20: error: crosses initialization of 'uint32_t entry_page_start' jni/test.cpp:106:15: error: crosses initialization of 'uint32_t page_size'*****

从建议更改后的,看起来是这样的。

the hook call method from the Andrey's blog after the suggested changes Here, looks like this.

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()方法有些不对的地方吗?我们有任何人谁曾与安德烈的博客的帮助下完成的呢?任何其他办法?我阻止。任何帮助将是AP preciated。

What wrong am I doing, Am i putting the mProtect() method at some wrong place ? do we have anyone who has done it with the help of Andrey's blog ? Any other approach ? I am blocked. Any help would be appreciated.

推荐答案

错误HAST无关的mprotect()对。这实际上是完全一样的地方,我放置了code段为好。这里是我的code和正常工作:

The error hast nothing to do with the mProtect(). This is actually the exact same place I have placed the code snippet as well. Here is my code and it works fine:

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发生。看看这个。发生了类似的错误,并得到解决。

The *jump to case label ... error: crosses initialization normally occurs when variables are not correctly initilized when using the switch case i.e. initialized in one case and used in another. Have a look at this question. A similar error occurred and was resolved.

这篇关于如何钩我的Andr​​oid应用程序的系统调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 22:43