Android ELF 파일 got 테이블 기호 오프셋 확인

1932 단어
모두가 알다시피 안드로이드의 동적 링크기는 링크이고, iOS는dyld이며, linux는ld-linux이다.so.2.같은 linux 핵이기 때문에 안드로이드의 linker는 linux와 매우 비슷하다. 가장 큰 차이점은 linker가 게으른 귀속을 지원하지 않는다는 것이다. 게으른 귀속에 관한 지식은 나의 다른 블로그인 linuxplt의 실현을 참고하십시오.그래서 안드로이드의 so나 실행 가능한 파일이 외부에서 정의한 함수를 호출하기 전에 링크가 함수의 편이를 got표에 썼을 때, ELF 파일의 구조를 통해 got표의 편이를 가져오는 방법을 살펴봅시다.
우선 내가 구해야겠어.dynsym .dynstr .rel.plt 세 절의 데이터
.rel.plt 및 dynsym의 정의는 다음과 같습니다.
typedef struct{
Elf32_Addr  r_offset;
Elf32_Word  r_info;
} Elf32_Rel;

typedef structelf32_sym{
     Elf32_Word    st_name;
     Elf32_Addr    st_value;
     Elf32_Word    st_size;
     unsignedcharst_info;
     unsignedcharst_other;
     Elf32_Half     st_shndx;
} Elf32_Sym;


얻다.rel.plt 각 재배치 테이블에 해당하는 기호의 단계: 1, ELF32 사용R_SYM 매크로(.rel.plt 매개변수의 r info) 기호는.dynsym의 편향 2, 대응하는 dynsym을 찾으면 가져옵니다.dynsym의stname 필드입니다. 그러나 이 필드는 문자열이 아니라 편이입니다.dynstr 절의 편향 3、편향을 통해 해당하는 기호를 얻을 수 있습니다
다음 코드는 네트워크에서 나온 것으로 got 기호를 찾는 프로그램의 구현입니다.
for (i = 0; i < relplt_shdr->sh_size / sizeof(Elf32_Rel); i++){ 
    uint16_t ndx = ELF32_R_SYM(rel_ent->r_info); 
    LOGD("ndx = %d, str = %s", ndx, dynstr + dynsymtab[ndx].st_name);
    if (strcmp(dynstr + dynsymtab[ndx].st_name, symbol_name) == 0) { 
      LOGD("  %s got       : 0x%x", symbol_name, rel_ent->r_offset); 
      offset = rel_ent->r_offset; 
      break;
    } 
    if(read(fd, rel_ent, sizeof(Elf32_Rel)) != sizeof(Elf32_Rel)) {
    LOGD("    %s        ", symbol_name); return -1; }
}

정적 귀속 기호라면 가져오는 것입니다.dynsym 구조체stvalue 필드의 값
for(i = 0; i < (dynsym_shdr->sh_size) / sizeof(Elf32_Sym); ++i) { 
    if(strcmp(dynstr + dynsymtab[i].st_name, symbol_name) == 0) { 
        LOGD("  %s    : 0x%x", symbol_name, dynsymtab[i].st_value); 
        offset = dynsymtab[i].st_value; 
        break; 
    }
 }

위 코드는 Android GOT 표 HOOK 기술에서 나온 것입니다.

좋은 웹페이지 즐겨찾기