what is glibc IFUNC

glibc를 보다 보니 strlen 함수에서 브레이크포인터가 안걸리고 __strlen_evex 여기에서 걸리는 것을 확인할 수 있었다.

이게 뭘까?

C
pwndbg> disass __strlen_
__strlen_avx2      __strlen_avx2_rtm  __strlen_evex      __strlen_sse2  

직접 확인을 해보니 strlen이 다양한 변형이 있었다.

C
pwndbg> disass __memcpy_
__memcpy_avx512_no_vzeroupper        __memcpy_chk_erms
__memcpy_avx512_unaligned            __memcpy_chk_evex_unaligned
__memcpy_avx512_unaligned_erms       __memcpy_chk_evex_unaligned_erms
__memcpy_avx_unaligned               __memcpy_chk_ifunc
__memcpy_avx_unaligned_erms          __memcpy_chk_sse2_unaligned
__memcpy_avx_unaligned_erms_rtm      __memcpy_chk_sse2_unaligned_erms
__memcpy_avx_unaligned_rtm           __memcpy_chk_ssse3
__memcpy_chk                         __memcpy_chk_ssse3_back
__memcpy_chk_avx512_no_vzeroupper    __memcpy_erms
__memcpy_chk_avx512_unaligned        __memcpy_evex_unaligned
__memcpy_chk_avx512_unaligned_erms   __memcpy_evex_unaligned_erms
__memcpy_chk_avx_unaligned           __memcpy_sse2_unaligned
__memcpy_chk_avx_unaligned_erms      __memcpy_sse2_unaligned_erms
__memcpy_chk_avx_unaligned_erms_rtm  __memcpy_ssse3
__memcpy_chk_avx_unaligned_rtm       __memcpy_ssse3_back

memcpy는 훨신 많은 종류가 있었다.

이를 분석해보니 glibc에서 IFUNC 이라는 개념을 사용하고 있었다.

memcpy, memmove, memset, memchr, memcmp, strlen, strnlen, strcmp, strncmp 와 같이 주로 메모리 관련된 그리고 자주 쓰이는 함수들에 대해서 최적화 ( 아키텍쳐별로 , ISA 별로 ) 버전을 나누어 놓은 것이다.

근데 이러면 각 함수별로 위치가 지정되지 않으므로 glibc 내부에서도 plt와 got를 사용해서 동적재배치가 필요하다.

해당 관련글은