오늘은... 다른 버전의 glibc를 설치하다가 발생한 오류를 작성해보려한다..
fastbin_dup을 찾아보다가, 현재 설치되어있는 Ubuntu 18.04에서 테스트를 해보고 싶었다.
그러나, glibc-2.26이상부터는 tcachebins가 먼저 사용되어, fastbin을 볼 수 없었고, 결국 다른 버전의 glibc를 설치하고 링킹하여 해당 바이너리를 까보기로 했다...
✔ Glibc Download Link : https://ftp.gnu.org/gnu/glibc/
시작하기 전 다른 버전의 glibc를 다운로드 받은 곳을 적어두겠다.
이제 GoGo!
Ubuntu 18.04.6은 기본적으로 glibc-2.27가 설치되어있다.
해당 OS에서 glibc 버전을 바꾸려고 시도했을 때, 다른 버전의 glibc를 설치하고 링킹을 시도할 경우 링킹 중간에 OS Command들이 먹히지 않았다...😡
이유는 리눅스의 Command들이(바이너리 파일들이) dynamic하게 빌드되어, glibc를 바꿀 경우 모든 것을 새로 빌드해야한다고.. 뒤늦게 구글링을 통해 찾아봤다... 해당 Ubuntu OS는 하늘나라로 보내줬다...😇
우선 glibc-2.27 버전에서의 free 후 Chunk가 어디들어가는지 확인해보자!
#include <stdio.h>
#include <stdlib.h>
int main(){
int *p = (int *)malloc(0x30);
free(p);
free(p);
return 0;
}
테스트할 코드는 굉장히 간단하다! malloc을 통해 할당받고, free를 두 번 시켜준다.
우선 첫 번째 free 함수 이후에 멈추고, heap 명령어를 통해 어떤 bin에 들어가있는지 확인해보자. Go~!
해당 부분에서 멈추고,
heap
heap command를 통해 확인할 경우, Free 된 Chunk는 tcachebins에 들어가게 된다!
이제 glibc-2.24를 설치하여, 링킹을 시도해보자..
설치하다가 오류가 발생한 부분은 압축을 풀고, build 디렉터리를 만들고 등등.. make 명령어를 실행할 때이다!
처음 loc1 어쩌고 하는 이상 오류가 발생했다....
구글링끝에 해결했는데, 글 맨 아래 URL을 적어두었으니 참고하길 바란다.
우선 첫 번째 오류 해결 방법이다!
위와 같은 loc1@GLIBC_2.2.5 ~~와 같은 오류가 발생할 때, regexp.c 파일의 내용을 수정해준다.
regexp.c 파일을 찾아서 해당 파일의 내용을 수정해주면 된다.. 수정 내용은 아래의 그림과 같다.
해당 파일의 경로는 아래에 적어두었다...🥤
(misc 폴더 하위에 존재, 설치 경로에 따라 경로가 조금 달라질 수 있음)
✔ Path : /root/glibc/glibc-2.24/misc/regexp.c
위와 같이 수정해준다..!
char *loc1 __attribute__ ((nocommon));
char *loc2 __attribute__ ((nocommon));
char *locs __attribute__ ((nocommon));
다음은 두 번째 오류 해결방법이다..
아래와 같은 오류가 발생할 때, 다음과 같이 수정해주면 된다.
checkint 함수부분에서 Error가 발생하는 것으로 보인다.
마찬가지로 해당 파일의 경로는 아래와 같다.
✔ Path : /root/glibc/glibc-2.24/sysdeps/ieee754/dbl-64/e_pow.c
주석처리된 부분은 이전 코드를 의미한다.
checkint (double x)
{
union
{
int4 i[2];
double x;
} u;
int k, m, n;
u.x = x;
m = u.i[HIGH_HALF] & 0x7fffffff; /* no sign */
if (m >= 0x7ff00000)
return 0; /* x is +/-inf or NaN */
if (m >= 0x43400000)
return 1; /* |x| >= 2**53 */
if (m < 0x40000000)
return 0; /* |x| < 2, can not be 0 or 1 */
n = u.i[LOW_HALF];
k = (m >> 20) - 1023; /* 1 <= k <= 52 */
if (k == 52)
return (n & 1) ? -1 : 1; /* odd or even */
if (k > 20)
{
if (n << (k - 20) !=0) // if (n << (k - 20))
return 0; /* if not integer */
return (n << (k - 21) !=0) ? -1 : 1; // return (n << (k - 21)) ? -1 : 1;
}
if (n)
return 0; /*if not integer */
if (k == 20)
return (m & 1) ? -1 : 1;
if (m << (k + 12) !=0) // (m << (k + 12))
return 0;
return (m << (k + 11) !=0) ? -1 : 1; // (m << (k + 11)) ? -1 : 1;
}
위와 같은 오류가 발생했을 경우 아래와 같이 수정해준다.
파일 경로는 아래와 같다.
✔ Path : /root/glibc/glibc-2.24/sunrpc/rpc_parse.cs
참고로 주석은 이전 코드이다...
char name[MAXLINESIZE];
다음으로는 아래와 같은 오류가 발생했을 경우이다..
nisplus-alias.c 파일에서 아래와 같이 수정해준다.
파일의 경로는 아래와 같다..
✔ Path : /root/glibc/glibc-2.24/nis/nss_nisplus/nisplus-alias.c
마찬가지로 수정한 코드는 아래와 같다!
char buf[tablename_len + 9];
snprintf (buf, sizeof (buf), "[name=],%s", tablename_val);
마지막 오류이다... 해당 파일이 없어서 생기는 문제 같다!
아래와 같이
cd /etc/
touch ld.so.conf
위의 Command를 통해 ld.so.conf 파일을 생성해준다!!!
설치된 glibc를 통해 바이너리 파일을 링킹하고, ldd 명령어를 통해 확인하면, 🙌 쨘!
glibc-2.24 버전을 통해 링킹된 것을 확인할 수 있다! 👏👏👏
마지막으로 설치한 glibc-2.24 버전을 통해 바이너리 파일을 생성하여, gdb로 까보자!
마찬가지로 free 직후 heap 명령어를 통해 확인한다.
아까와는 달리 Free 된 Chunk가 fastbins에 들어가있는 것을 확인할 수 있다 !
다른 버전의 glibc를 드디어 성공적으로 설치했는데.. 이런 건 어떻게 찾았는지 대단하다...!😅
참고 URL : https://blog.csdn.net/jiuweideqixu/article/details/104408432
감사합니다....
'이유는 리눅스의 Command들이(바이너리 파일들이) dynamic하게 빌드되어, glibc를 바꿀 경우 모든 것을 새로 빌드해야한다고..' 덕분에 삽질 여기서 멈추고 그냥 OS 밀어버려야 겠네요...