# Cách đọc từ stream của fgets
## Tản mạn
- Đây là kiến thức mình gặp khi tham gia 1 giải khá lmao nhưng tự nhiên minh gặp 1 bài easy nhưng lại có 1 cái trick khá là lạ

- Challenge cho hàm `win` đọc flag ở thư mục cha, tuy không thể ROP để set-up nhảy thằng từ đầu nhưng mà có thể nhảy thẳng đến open để đọc flag. Nhưng chuyện đơn giản vậy thì đâu có gì để nói.

-> **segmentation fault rồi**

-> Tại sao `flag` lại ghi đè luôn saved rip của `_IO_getline_info`
- Đẻ giải mã tại sao flag có thể ghi đè được như vậy thì mình quyết định debug xem `fgets` đã làm gì ?
## Deep debug
- Sau khi debug thì đoạn xử lí từ file vào buffer sẽ là hàm `_IO_default_uflow` [source](https://elixir.bootlin.com/glibc/glibc-2.35/source/libio/genops.c#L360)


- Đọc 1 hồi debug + reverse + đọc source của glibc mình tìm ra đoạn mà đọc từ buffer (heap) vào stack [source](https://elixir.bootlin.com/glibc/glibc-2.35/source/libio/iogetline.c#L100)
```c
if (t != NULL)
{
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;
```


-> Ở đây `_IO_default_uflow` sẽ sao chép nội dung ở heap vào stack
- `Debug` tiếp xem đoạn này của `stack` xuất phát từ đâu, ảnh hưởng gì đến `segfault`

```
stack = 0x7fffffffde81
saved rip = 0x7fffffffde98
-> Nếu flag quá dài thì hoàn toàn có thể gây ra buffer overflow
```
## Bypass
:::warning
- Câu hỏi đặt ra bây giờ là có thể bypass được đoạn này không ??
-> Chúng ta sẽ xem địa chỉ stack này lấy từ đâu
:::