What Happens If You Implement PltHook?
plt 니 got 니 이론부터 보려니 머리가 아픕니다.
직접 해보는게 이해하기 빠르겠죠
Bytehook(https://github.com/bytedance/bhook/tree/main) 을 이용하여 fopen 함수를 plthook 했더니, 로그가 잘 찍힙니다.
plthook 전이나 후나 libc.so 에 있는 fopen 함수 시작부의 메모리는 차이가 없습니다. (즉, c함수 인라인후킹 아님)
ELF 파일에서 많은 c함수들의 주소가 GOT(Global Offset Table) 에 저장됩니다.
c함수 호출시 이 GOT 테이블에 있는 함수 주소값을 참고하여 호출하게 되는 것이죠.
plthook 은 예컨대, 이 GOT에 저장되는 fopen 함수의 주소값을 fake_fopen 함수의 주소값으로 바꿔치기 하는 것입니다.
XELFViewer(https://github.com/horsicq/XELFViewer) 로 libart.so 파일의 .dynsym 섹션을 보죠.
심볼 테이블에서 fopen 함수는 530(0x212) 번째 심볼이군요.
.rela.plt 섹션을 보죠. 530(0x212)번째 심볼 fopen 함수의 offset은 0x6a6480 이라고 하네요. 즉, 오프셋 0x6a6480 에 fopen 함수의 주소를 저장합니다.
자 이제 libart.so 의 offset 0x6a6480 으로 이동해봅시다. 0x721774d8e8 이라는 주소가 저장되어 있네요.
그 밖에도 여러 주소가 저장되어 있는게 보이는데, 이곳이 GOT 테이블의 일부인 것입니다.
어쨌든 저장되어 있는 주소 0x721774d8e8 로 이동해보죠. GOT 테이블에 저장되어 있는 fopen 함수의 주소로 이동했더니 위치가 제가 만든 libplthooktest.so 라이브러리에 속해 있습니다. fake_fopen 주소인 것이죠.
즉, plthook 결과 got 테이블에 libc.so 의 fopen 주소가 아닌 libplthooktest.so 의 fake_fopen 주소가 저장되므로 fopen 함수 호출시 fake_fopen 함수가 대신 호출되는 것입니다.