fgets 작동원리 질문..
우선 풀다가 못풀겠어서 다른 사람들이 푼 writeup을 봤습니다.
봤는데 char* _IO_buf_base; 이 변수를 조작해서 exploit했습니다. 그러나 제가 지금 분석하는 과정에서는 _IO_buf_base를 어디서 사용하는지 알수가 없습니다 ㅠㅠ
glibc-2.23 source code를 보면서 fgets함수의 구현을 보면서 디버깅하니 fgets는 결국 _IO_getline(char *buf, size_t size, int n, _IO_FILE *fp) 함수를 호출합니다.
char *
__fgets_chk (char *buf, size_t size, int n, _IO_FILE *fp)
{
// 중략
fp->_IO_file_flags &= ~_IO_ERR_SEEN;
count = _IO_getline (fp, buf, MIN ((size_t) n - 1, size), '\n', 1);
// 중략
return result;
}
그리고 _IO_getline함수는 _IO_getline_info를 호출합니다.
_IO_size_t
_IO_getline (_IO_FILE *fp, char *buf, _IO_size_t n, int delim,
int extract_delim)
{
return _IO_getline_info (fp, buf, n, delim, extract_delim, (int *) 0);
}
그리고 이제 _IO_getline_info 함수를 보면
_IO_size_t
_IO_getline_info (_IO_FILE *fp, char *buf, _IO_size_t n, int delim,
int extract_delim, int *eof)
{
char *ptr = buf;
if (eof != NULL)
*eof = 0;
if (__builtin_expect (fp->_mode, -1) == 0)
_IO_fwide (fp, -1);
while (n != 0)
{
_IO_ssize_t len = fp->_IO_read_end - fp->_IO_read_ptr;
if (len <= 0)
{
int c = __uflow (fp);
if (c == EOF)
{
if (eof)
*eof = c;
break;
}
if (c == delim)
{
if (extract_delim > 0)
*ptr++ = c;
else if (extract_delim < 0)
_IO_sputbackc (fp, c);
if (extract_delim > 0)
++len;
return ptr - buf;
}
*ptr++ = c;
n--;
}
else
{
char *t;
if ((_IO_size_t) len >= n)
len = n;
t = (char *) memchr ((void *) fp->_IO_read_ptr, delim, len);
if (t != NULL)
{
_IO_size_t old_len = ptr-buf;
len = t - fp->_IO_read_ptr;
if (extract_delim >= 0)
{
++t;
if (extract_delim > 0)
++len;
}
memcpy ((void *) ptr, (void *) fp->_IO_read_ptr, len);
fp->_IO_read_ptr = t;
return old_len + len;
}
memcpy ((void *) ptr, (void *) fp->_IO_read_ptr, len);
fp->_IO_read_ptr += len;
ptr += len;
n -= len;
}
}
return ptr - buf;
}
이 부분을 아무리 봐도 _IO_buf_base를 어디서 사용하는지 모르겠습니다.
답변해주시면 감사하겠습니다 ㅠ
수정---------
성급한 질문 죄송합니다..
writeup 코드로 디버깅하는 과정에서 호출되는 부분을 찾았습니다.
int c = __uflow (fp);
...
return _IO_UFLOW (fp); // _IO_default_uflow 호출
...
int ch = _IO_UNDERFLOW (fp); // _IO_file_underflow 호출
...
int
_IO_new_file_underflow (_IO_FILE *fp)
// 내부에 있습니다..
`
dong_
댓글 34