안드로이드 Relocation Table 분석

홈 > 안드로이드 > 안드로이드
안드로이드

안드로이드 Relocation Table 분석

M LIN 30 13145 3


구글은 AOSP(Android Open Source Project)라고 해서 안드로이드 소스 코드를 오픈 소스로 관리하고 있습니다. 그러다 보니 libc, libdl 등 다양한 라이브러리 코드를 확인할 수 있는데요. 저희는 이 코드를 통해 dlopen() 소스코드를 확인하고 GOT가 어떻게 쓰여지는지 확인해보겠습니다. 다음 URL (https://android.googlesource.com/platform/bionic/+refs)을 통해 각각의 버전에 맞는 소스 코드를 확인할 수 있습니다.

본격적으로 설명드리기에 앞서 ELF 구조에 대해서 어느정도 지식이 있어야 이해가 가실겁니다. 구글에 검색만 하시더라도 이미 많은 분들께서 ELF 구조에 대해 아주 자세하게 설명을 해놓았기 때문에 해당 글들을 보고 오신 다음에 제 글을 읽으시면 될듯합니다.

Relocation Table 재배치 과정

ELF에는 많은 섹션들중에 relocation 섹션이 존재합니다. 해당 섹션은 심볼릭 정의를 참조하는 테이블인데요. ELF 내 심볼이 가리키는 위치(r_offset)를 실행시에 재배치해주는 역할을 합니다. 저희가 C언어로 코딩할때 각종 시스템 함수(printf, memcpy, memset 등)들을 사용하는데요. 이러한 함수들은 libc.so 라이브러리를 동적 링킹하여 사용하는 구조입니다. 컴파일 과정에서 libc.so 를 동적 링킹하여 사용하겠다 명시하게 되는거죠. 빌드 과정을 거치면 최종 라이브러리 파일이 생성이 되는데, 이때 라이브러리 파일을 열어서 확인해보면 dynamic section에서 "DT_NEEDED libc.so" 라고 명시가 되어 있는것을 확인할 수 있습니다. 또한 심볼 정보를 보시면 printf, memcpy 등의 함수들이 있는것을 확인할 수 있습니다. 그런데 여기서 해당 심볼을 확인하시면 r_offset 값이 0으로 지정되어 있습니다. 그렇다면 실제 동작할때에는 어떻게 libc.so를 동적 링킹하여 사용할 수 있는걸까요? 이때 방금 말씀드린 Relocation Table을 확인하여 시스템 함수의 GOT 주소에 실제 로드된 libc.so의 함수 주소를 Write 하게 됩니다.

즉, Relocation Table은 "프로그램 동작 시에 해당 주소를 재배치 해줘" 라고 알려주는 것입니다.

내부 text section에 존재하는 코드를 보시면 bl memcpy 등의 시스템 함수 분기문을 확인할 수 있는데, 이때 memcpy plt 주소로 분기하고 plt는 GOT 주소를 읽고 PC가 해당 주소로 바뀌는 어셈블리어 코드를 확인할 수 있습니다. 이러한 과정을 거쳐 실제 함수의 위치로 분기할 수 있는것이죠.

img.pngSymbol Section

 

자 그림을 보면서 하나하나씩 따라가 봅시다. 방금 말씀드린것 처럼 두번째 필드(st_value)가 실제 프로그램 내 Text Section 에 존재하지 않으니 0으로 할당되어 있는것을 확인할 수 있습니다.

img.pngRelocation Section

 

Relocation Table에는 다음과 같이 정의가 되어 있습니다. 21번째 인덱스인 심볼(memcpy)이 재배치할 주소는 0x1AEA4라고 알려주고 있습니다.

img.pngmemcpy GOT

 

0x1AEA4를 따라가보면 GOT 주소를 가리키고 있는것을 확인할 수 있죠?

여기서 R_ARM_JUMP_SLOT은 함수 주소의 재배치를 뜻합니다. ELF는 이러한 정보를 명시해놓은채로 dlopen()함수를 통해 메모리로 로드되는데요. dloepn()소스코드를 확인하시면 어떻게 재배치를 하는지 정확히 확인할 수 있습니다.

img.png

< dlopen Source Code 1 >

dlopen() 전체 소스 코드를 보기에는 너무 방대합니다. 그래서 Relcaton Section을 확인하고 어떻게 실제 주소를 Write 하는지 과정만 요약하여 살펴보도록 하겠습니다. 우선 Dynamic Section에서 "DT_NEEDED ???.so"라고 명시해놓았던 라이브러리를 모두 dlopen()함수를 호출하여 메모리로 로드시킵니다.

img.png

그다음 plt_rel 변수를 Relocation Section 주소로 할당하고 soinfo_relocate() 함수를 호출합니다.

img.png

Relocation Table에서 type과 symbol index를 파싱한 뒤 symbol index가 있을 경우, 심볼 이름을 인자로 soinfo_do_lookup() 호출합니다.

이때 자기 자신의 심볼부터 탐색해보고 없다면 needed로 로드했던 라이브러리에서 심볼을 탐색하게 되는것이죠.

img.png
img.png
img.png

그림으로 확인하셨다시피 GOT에 실제 로드되어 있는 라이브러리내 함수의 주소를 GOT에 Write하는 과정을 살펴보았습니다. 모든 동적 링킹된 함수들은 이러한 시퀀스로 모두 주소가 바뀌고 DT_INIT부터 시작하게 되는것이죠.

그렇다면 PLT는 어떻게 GOT를 가리킬까요? 이 과정도 살펴봅시다.

img.png

PLT 어셈블리어 코드 분석

plt 시작 위치인 0x3DF8에서 IP에 PC 값을 넣게되는데, 이때 PC라면 현재 위치인 0x3DF8을 넣어줘야 되는데 0x3E00으로 바꿔놓은것을 확인할 수 있습니다. 그 이유는 armv7의 경우 pipe line(fetch -> decode -> execute)과정을 거치기 때문에 실제 실행시인 execute과정에서는 0x3E00 주소가 IP에 들어가게 됩니다. 그런 뒤 GOT 주소를 read하고 PC인 현재 위치를 바꾸는것까지 확인할 수 있습니다.

30 Comments
S 코드몽키 2019.10.03 14:53  
처음부분에서 음.... 그렇군... 중간부분에서.. 끄응,,,, 마지막에와서는 다시 음.....
역시 이 분야의 공부는 끝이 없다는걸 느낍니다^^;
3 라피스넷 2019.10.03 15:45  
대학시절에 공부하던게 쏙쏙 떠오르네요
2 mlsand 2019.10.03 20:02  
보다보니 어렵네요
2 마루야 2019.10.03 22:18  
눈이 핑글 핑글 도는 군요....;;
6 지존 2019.10.04 00:04  
좋은분석 감사합니다
26 세월강태공 2019.10.04 18:48  
공부.공부.공부~~
1 어흥어흥 2019.10.04 19:17  
잘 읽었습니다.
제목에 살짝 오타가 있네요 (Relcation -> Relocation)
1 dante8472 2019.10.04 20:34  
좋은 분석 감사합니다 공부해야 겠군요
2 냅스타블룩 2019.10.05 14:02  
분석 친절하게 올려주셔서 감사합니다 좋은 공부가 되었네요
1 rok795 2019.10.21 12:08  
좋은 정보 감사합니다.
2 에스트 2019.11.04 12:41  
감사합니다
4 hekadan 2019.12.03 14:42  
감사합니다!!
1 또리쓰마 2019.12.03 21:41  
감사합니다!!
2 masu 2019.12.04 01:12  
감사합니다.
2 95grit 2019.12.06 23:50  
감사합니다
2 songod 2019.12.19 17:09  
감사합니다.
1 rafael 2019.12.28 12:27  
감사합니다
1 케록 2020.01.08 16:36  
크아......
13 Rohas 2020.01.09 16:12  
감사합니다
4 stuhkg 2020.01.19 06:07  
좋은분석 감사합니다

Congratulation! You win the 8 축하드립니다! 당첨되셨어요~!

4 stuhkg 2020.01.19 06:07  
감사합니다
5 Bugday 2020.02.04 08:49  
스크랩 해놨다가 여러 번 봐야겠네요... 넘 어렵..
1 리로드 2020.02.23 19:27  
감사합니다
2 루미에르 2020.03.20 10:50  
감사합니다!
7 래바리 2020.04.03 18:50  
감사합니다.
3 Linjjang 2020.04.14 09:32  
감사합니다
1 h2ro 2020.05.16 19:03  
감사합니다 ㅎ
7 임중호 2020.05.24 01:27  
실패했습니다....
1 almaystro79 2023.10.20 18:40  
i was using my phone to translate but thank u
1 bcqaur 2023.11.21 17:26  
Linux와 달리 dlopen을 통해 GOT에 바로 주소값이 바로 Write되면 PLT는 정확히 어떤 역할을 하는걸까요?