0

Я хочу перехватить системный вызов connect() и использовать собственную собственную реализацию. Пользовательская реализация сделает некоторые действия, такие как печать журнала для простоты, а затем последует дальнейшая реализация системы.Как подключить системные вызовы моего приложения android

Я смотрел на Audrey's blog, где подход заключается в исправлении PLT. Но, к сожалению, этот код падает при попытке изменить адрес в таблице перемещения.

После того, как я очнулся, я столкнулся с This already answered question. Но описанный здесь подход дает мне следующую ошибку.

***** переход на метку кейса [-fpermissive] jni/test.cpp: 107: 20: ошибка: пересекает инициализацию 'uint32_t entry_page_start' jni/test.cpp: 106: 15: ошибка: перекрещивает инициализацию of '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() в неправильное место? есть ли у нас кто-нибудь, кто сделал это с помощью блога Андрея? Любой другой подход? Меня заблокировали. Любая помощь будет оценена по достоинству.

ответ

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; 

}

Символ * переход к метке случая ... ошибка: кресты инициализация обычно происходит, когда переменные не правильно 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 "... –

+0

Мне нужно добавить некоторые так? или какой-то флаг компоновщика? –

+0

Мне удалось подключить вызов соединения. Почему я не могу подключить вызов записи, вызвав ту же функцию снова, но с другим параметром имени функции ** pOldWrite = (void *) hook_call («libjavacore.so», «write», (void *) my_write); ** –

Смежные вопросы