오늘은... 다른 버전의 glibc를 설치하다가 발생한 오류를 작성해보려한다..

fastbin_dup을 찾아보다가, 현재 설치되어있는 Ubuntu 18.04에서 테스트를 해보고 싶었다.
그러나, glibc-2.26이상부터는 tcachebins가 먼저 사용되어, fastbin을 볼 수 없었고, 결국 다른 버전의 glibc를 설치하고 링킹하여 해당 바이너리를 까보기로 했다...


그래서 시작한 게 바로 다른 버전의 glibc 설치이다! 오늘 포스팅은 다른 버전의 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을 적어두었으니 참고하길 바란다.


1. loc(in regexp.c) Error


우선 첫 번째 오류 해결 방법이다!
위와 같은 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));





2. checkint(in e_pow.o) Error


다음은 두 번째 오류 해결방법이다..
아래와 같은 오류가 발생할 때, 다음과 같이 수정해주면 된다.

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;
}





3. get_prog_declaration Error

위와 같은 오류가 발생했을 경우 아래와 같이 수정해준다.

파일 경로는 아래와 같다.

✔ Path : /root/glibc/glibc-2.24/sunrpc/rpc_parse.cs

참고로 주석은 이전 코드이다...

char name[MAXLINESIZE];





4. _nss_nisplus_getaliasbyname_r(in nisplus-alias.os) Error


다음으로는 아래와 같은 오류가 발생했을 경우이다..

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);





5. ld File Error


마지막 오류이다... 해당 파일이 없어서 생기는 문제 같다!

아래와 같이

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

profile
화이팅!

1개의 댓글

comment-user-thumbnail
2023년 11월 6일

감사합니다....
'이유는 리눅스의 Command들이(바이너리 파일들이) dynamic하게 빌드되어, glibc를 바꿀 경우 모든 것을 새로 빌드해야한다고..' 덕분에 삽질 여기서 멈추고 그냥 OS 밀어버려야 겠네요...

답글 달기
Powered by GraphCDN, the GraphQL CDN