0

connect() 시스템 호출을 가로 채고 내 자신의 사용자 정의 구현을 사용하고 싶습니다. 커스텀 구현은 단순성을 위해 로그를 인쇄하는 것과 같은 몇 가지 작업을 수행 한 다음 시스템 구현을 추가로 호출합니다.내 안드로이드 애플 리케이션의 시스템 호출을 연결하는 방법

Audrey's blog에서 PLT를 패치하는 방법을 살펴 보았습니다. 그러나 불행하게도이 코드는 재배치 테이블의 주소를 변경하려고 할 때 충돌합니다.

잠시 고글 거리고 난 후에 나는 This already answered question를 만났다. 그러나 여기에 설명 된 접근 방식은 나에게 다음과 같은 오류를 준다.

***** 점퍼 레이블로 이동 [-fpermissive] jni/test.cpp : 107 : 20 : 오류 : 'uint32_t entry_page_start'의 초기화 교차 jni/test.cpp : 106 : 15 : 오류 : 교차 초기화 'uint32_t page_size'*****

제안 된 변경 사항 Here 이후 Andrey's blog의 후크 호출 방법은 다음과 같습니다.

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; 

}

* 표시의 경우 라벨에 점프 ... 오류 : 변수가 제대로 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); ** –