ํŒŒ์ผ์„ ์—ด ๋•Œ ํŒŒ์ผ ์ ‘๊ทผ ์œ ํ˜•์„ ๋ช…์‹œํ•ด์•ผ ํ•˜๋Š”๋ฐ, ๋Œ€ํ‘œ์ ์œผ๋กœ ์ฝ๊ธฐ ๋ฐ ์“ฐ๊ธฐ ๋ชจ๋“œ๊ฐ€ ์žˆ๋‹ค.

์ฝ๊ธฐ ๋ชจ๋“œ๋กœ ํŒŒ์ผ์„ ์—ด๊ณ , ํŒŒ์ผ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ž‘์„ฑํ•˜๋ ค ํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ๊ธฐ๋Šฅ์ด ์ˆ˜ํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.

 

๋ชจ๋“  ํŒŒ์ผ ํ•จ์ˆ˜๋Š” fopen ํ•จ์ˆ˜์—์„œ ๋ฐ˜ํ™˜ํ•œ ํŒŒ์ผ ํฌ์ธํ„ฐ๋ฅผ ์ธ์ž๋กœ ์ „๋‹ฌ๋ฐ›๊ณ , ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์ „์— ํŒŒ์ผ ํฌ์ธํ„ฐ๋ฅผ ์ฐธ์กฐํ•ด ํŒŒ์ผ ์ •๋ณด๋ฅผ ๋จผ์ € ํ™•์ธํ•œ๋‹ค. ํŒŒ์ผ์˜ ์ •๋ณด๋กœ๋Š” ํŒŒ์ผ์ด ์–ด๋–ค ๋ชจ๋“œ๋กœ ์—ด๋ ธ์œผ๋ฉฐ, ํŒŒ์ผ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜ ์ฃผ์†Œ๊ฐ€ ํฌํ•จ๋œ๋‹ค

-> ํŒŒ์ผ ์ž‘์—…์ด ์–ด๋–ป๊ฒŒ ์ด๋ค„์ง€๋Š”์ง€ ์•Œ๊ธฐ ์œ„ํ•ด์„œ๋Š” ํŒŒ์ผ ๊ตฌ์กฐ์ฒด๋ฅผ ์ดํ•ดํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค.

 

 

 

_IO_FILE ์‹ค์Šต ์˜ˆ์ œ ์ฝ”๋“œ

// Name: iofile.c
// Compile: gcc -o iofile iofile.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
void file_info(FILE *buf) {
  printf("_flags: %x\n", buf->_flags);
  printf("_fileno: %d", buf->_fileno);
}
int main() {
  FILE *fp;
  char buf[256];
  strcpy(buf, "THIS IS TESTFILE!");
  fp = fopen("testfile", "w");
  fwrite(buf, 1, strlen(buf), fp);
  file_info(fp);
  fclose(fp);
  return 0;
}

 

 

 

_IO_FILE

_IO_FILE์€ ๋ฆฌ๋ˆ…์Šค ์‹œ์Šคํ…œ์˜ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ํŒŒ์ผ์ŠคํŠธ๋ฆผ์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•œ ๊ตฌ์กฐ์ฒด์ด๋‹ค.

-> ํŒŒ์ผ์„ ์—ด๊ธฐ ์œ„ํ•œ fopenํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ํž™ ์˜์—ญ์— ํ• ๋‹น๋œ๋‹ค.

 

_IO_FILE ๊ตฌ์กฐ์ฒด

	struct _IO_FILE_plus
{
  FILE file;
  const struct _IO_jump_t *vtable;
};
struct _IO_FILE
{
  int _flags;		/* High-order word is _IO_MAGIC; rest is flags. */
  /* The following pointers correspond to the C++ streambuf protocol. */
  char *_IO_read_ptr;	/* Current read pointer */
  char *_IO_read_end;	/* End of get area. */
  char *_IO_read_base;	/* Start of putback+get area. */
  char *_IO_write_base;	/* Start of put area. */
  char *_IO_write_ptr;	/* Current put pointer. */
  char *_IO_write_end;	/* End of put area. */
  char *_IO_buf_base;	/* Start of reserve area. */
  char *_IO_buf_end;	/* End of reserve area. */
  /* The following fields are used to support backing up and undo. */
  char *_IO_save_base; /* Pointer to start of non-current get area. */
  char *_IO_backup_base;  /* Pointer to first valid character of backup area */
  char *_IO_save_end; /* Pointer to end of non-current get area. */
  struct _IO_marker *_markers;
  struct _IO_FILE *_chain;
  int _fileno;
  int _flags2;
  __off_t _old_offset; /* This used to be _offset but it's too small.  */
  /* 1+column number of pbase(); 0 is unknown. */
  unsigned short _cur_column;
  signed char _vtable_offset;
  char _shortbuf[1];
  _IO_lock_t *_lock;
#ifdef _IO_USE_OLD_IO_FILE
};

 

์ค‘์š” ๋ฉค๋ฒ„ ๋ณ€์ˆ˜

๋ฉค๋ฒ„ ๋ณ€์ˆ˜ ์„ค๋ช…
_flags ํŒŒ์ผ์— ๋Œ€ํ•œ ์ฝ๊ธฐ/์“ฐ๊ธฐ/์ถ”๊ฐ€ ๊ถŒํ•œ
0xfbad0000 ๊ฐ’์„ ๋งค์ง ๊ฐ’์œผ๋กœ, ํ•˜์œ„ 2๋ฐ”์ดํŠธ๋Š” ๋น„ํŠธ ํ”Œ๋ž˜๊ทธ๋กœ ์‚ฌ์šฉ๋จ
_IO_read_ptr ํŒŒ์ผ ์ฝ๊ธฐ ๋ฒ„ํผ์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ
_IO_read_end ํŒŒ์ผ ์ฝ๊ธฐ ๋ฒ„ํผ ์ฃผ์†Œ์˜ ๋์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ
_IO_read_base ํŒŒ์ผ ์ฝ๊ธฐ ๋ฒ„ํผ ์ฃผ์†Œ์˜ ์‹œ์ž‘์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ
_IO_write_base ํŒŒ์ผ ์“ฐ๊ธฐ ๋ฒ„ํผ ์ฃผ์†Œ์˜ ์‹œ์ž‘์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ
_IO_write_ptr ์“ฐ๊ธฐ ๋ฒ„ํผ์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ
_IO_write_end ํŒŒ์ผ ์“ฐ๊ธฐ ๋ฒ„ํผ ์ฃผ์†Œ์˜ ๋์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ
_chain ํ”„๋กœ์„ธ์Šค์˜ _IO_FILE ๊ตฌ์กฐ์ฒด๋Š” _chain ํ•„๋“œ๋ฅผ ํ†ตํ•ด ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ฆ
๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ์˜ ํ—ค๋”๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ „์—ญ ๋ณ€์ˆ˜์ธ _IO_list_all์— ์ €์žฅ๋จ
_fileno ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ์˜ ๊ฐ’
_IO_jump_ t *vtable ํŒŒ์ผ ๊ด€๋ จ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฐ€์ƒ ํ•จ์ˆ˜ ํ…Œ์ด๋ธ”

 

 

_IO_FILE: _flags

_flags ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋Š” ํŒŒ์ผ์˜ ์„ฑ์งˆ์„ ๋‚˜ํƒ€๋‚ด๋Š” ํ•„๋“œ์ด๋‹ค.

ํ•ด๋‹น ํ•„๋“œ๋Š” fopen ํ•จ์ˆ˜๋กœ ํŒŒ์ผ์„ ์—ด ๋•Œ ์ „๋‹ฌํ•œ ๋ชจ๋“œ์— ๋”ฐ๋ผ ๊ฐ’์ด ์„ค์ •๋œ๋‹ค.

 

๋‹ค์Œ์€ _flags ๋ณ€์ˆ˜๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๊ฐ ๋น„ํŠธ๋“ค์˜ ์ง‘ํ•ฉ์ด๋‹ค.

#define _IO_MAGIC         0xFBAD0000 /* Magic number */
#define _IO_MAGIC_MASK    0xFFFF0000
#define _IO_USER_BUF          0x0001 /* Don't deallocate buffer on close. */
#define _IO_UNBUFFERED        0x0002
#define _IO_NO_READS          0x0004 /* Reading not allowed.  */
#define _IO_NO_WRITES         0x0008 /* Writing not allowed.  */
#define _IO_EOF_SEEN          0x0010
#define _IO_ERR_SEEN          0x0020
#define _IO_DELETE_DONT_CLOSE 0x0040 /* Don't call close(_fileno) on close.  */
#define _IO_LINKED            0x0080 /* In the list of all open files.  */
#define _IO_IN_BACKUP         0x0100
#define _IO_LINE_BUF          0x0200
#define _IO_TIED_PUT_GET      0x0400 /* Put and get pointer move in unison.  */
#define _IO_CURRENTLY_PUTTING 0x0800
#define _IO_IS_APPENDING      0x1000
#define _IO_IS_FILEBUF        0x2000
                           /* 0x4000  No longer used, reserved for compat.  */
#define _IO_USER_LOCK         0x8000

 

 

์œ„์˜ ์‹ค์Šต ์ฝ”๋“œ(iofile.c)๋ฅผ ์ปดํŒŒ์ผํ•˜๊ณ  ์‹คํ–‰ํ•ด๋ณด์ž.

0xfbad2c84:  _IO_MAGIC์ด๋ผ๋Š” ๋งค์ง ๋„˜๋ฒ„๋ฅผ ํฌํ•จํ•œ ๊ฐ ๊ถŒํ•œ์„ ์˜๋ฏธ

  • ํ•ด๋‹น ๊ฐ’์€ _flags ๋ฉค๋ฒ„ ๋ณ€์ˆ˜ ๋น„ํŠธ ์ง‘ํ•ฉ์„ ํ™•์ธํ•ด๋ณด๋ฉด _IO_MAGIC, _IO_NO_READS, _IO_LINKED, _IO_TIED_PUT_GET, _IO_CURRENTLY_PUTTING, _IO_IS_FILEBUF ๋น„ํŠธ๊ฐ€ ํฌํ•จ๋œ ๊ฑธ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 

๋‹ค์Œ ํ•จ์ˆ˜๋Š” fopen ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ์‹คํ–‰๋˜๋Š” ๋‚ด๋ถ€ ํ•จ์ˆ˜์ธ _IO_new_file_fopen์ด๋‹ค.

FILE *_IO_new_file_fopen(FILE *fp, const char *filename, const char *mode,
                         int is32not64) {
  int oflags = 0, omode;
  int read_write;
  int oprot = 0666;
  int i;
  FILE *result;
  const char *cs;
  const char *last_recognized;
  if (_IO_file_is_open(fp)) return 0;
  switch (*mode) {
    case 'r':
      omode = O_RDONLY;
      read_write = _IO_NO_WRITES;
      break;
    case 'w':
      omode = O_WRONLY;
      oflags = O_CREAT | O_TRUNC;
      read_write = _IO_NO_READS;
      break;
    case 'a':
      omode = O_WRONLY;
      oflags = O_CREAT | O_APPEND;
      read_write = _IO_NO_READS | _IO_IS_APPENDING;
      break;
      ...
  }

์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๋ฉด, fopen ํ•จ์ˆ˜์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ž์ธ mode ๋ณ€์ˆ˜๊ฐ€ 'r', 'w', 'a' ๋ฌธ์ž์ธ์ง€ ํ™•์ธํ•˜๊ณ , ๊ฐ ๊ถŒํ•œ์— ํ•ด๋‹น๋˜๋Š” ๋น„ํŠธ๊ฐ€ ํ• ๋‹น๋˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ read_write ๋ฟ๋งŒ์ด ์•„๋‹ˆ๋ผ omode ๋ณ€์ˆ˜์—๋„ O_RDONLY, O_WRONLY ๋“ฑ์˜ ๊ฐ’์ด ์ €์žฅ๋˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

fopen ํ•จ์ˆ˜๋Š” ๊ฒฐ๊ตญ open ์‹œ์Šคํ…œ ์ฝœ์„ ํ˜ธ์ถœํ•ด ํŒŒ์ผ์„ ์—ฌ๋Š”๋ฐ, ์ด๋•Œ ํ•ด๋‹น ์‹œ์Šคํ…œ ์ฝœ์˜ ์ธ์ž๋กœ ์ „๋‹ฌ๋œ๋‹ค.

 

 

 

_IO_FILE: vtable

_IO_FILE_plus ๊ตฌ์กฐ์ฒด๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด vtable ํฌ์ธํ„ฐ๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

Virtual function Table(vtable)์€ ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์—์„œ ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•˜๊ณ , ๊ฐ€์ƒ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ํ• ๋‹น๋˜๋Š” ํ…Œ์ด๋ธ”์ด๋‹ค.

-> ๋ฉ”๋ชจ๋ฆฌ์— ๊ฐ€์ƒ ํ•จ์ˆ˜๋ฅผ ๋‹ด์„ ์˜์—ญ์„ ํ• ๋‹น

-> ํ•จ์ˆ˜์˜ ์ฃผ์†Œ๋ฅผ ๊ธฐ๋ก

๊ฐ€์ƒ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น ํ…Œ์ด๋ธ”์„ ๊ธฐ์ค€์œผ๋กœ ์ƒ๋Œ€ ์ฃผ์†Œ๋ฅผ ํ†ตํ•ด ํ˜ธ์ถœํ•œ๋‹ค.

 

ํŒŒ์ผ ๊ตฌ์กฐ์ฒด๋Š” ๊ฐ ํŒŒ์ผ๋งˆ๋‹ค ํ•จ์ˆ˜ ํ…Œ์ด๋ธ”์„ ๊ฐ–๊ณ  ์žˆ๋‹ค. 

vtable ๋ณ€์ˆ˜๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ. ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ํ…Œ์ด๋ธ”๊ณผ ๋น„์Šทํ•˜๊ฒŒ ๊ตฌํ˜„๋˜์–ด์žˆ๊ณ , ํŒŒ์ผ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํ•ด๋‹น ํ…Œ์ด๋ธ”์„ ์ฐธ์กฐํ•˜๊ณ , ์‹ค์ œ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

 

๋‹ค์Œ์€ ํŒŒ์ผ ํ•จ์ˆ˜์˜ ํ…Œ์ด๋ธ”์„ ์ •์˜ํ•œ _IO_jump_t ๊ตฌ์กฐ์ฒด์ด๋‹ค.

struct _IO_jump_t
{
    JUMP_FIELD(size_t, __dummy);
    JUMP_FIELD(size_t, __dummy2);
    JUMP_FIELD(_IO_finish_t, __finish);
    JUMP_FIELD(_IO_overflow_t, __overflow);
    JUMP_FIELD(_IO_underflow_t, __underflow);
    JUMP_FIELD(_IO_underflow_t, __uflow);
    JUMP_FIELD(_IO_pbackfail_t, __pbackfail);
    /* showmany */
    JUMP_FIELD(_IO_xsputn_t, __xsputn);
    JUMP_FIELD(_IO_xsgetn_t, __xsgetn);
    JUMP_FIELD(_IO_seekoff_t, __seekoff);
    JUMP_FIELD(_IO_seekpos_t, __seekpos);
    JUMP_FIELD(_IO_setbuf_t, __setbuf);
    JUMP_FIELD(_IO_sync_t, __sync);
    JUMP_FIELD(_IO_doallocate_t, __doallocate);
    JUMP_FIELD(_IO_read_t, __read);
    JUMP_FIELD(_IO_write_t, __write);
    JUMP_FIELD(_IO_seek_t, __seek);
    JUMP_FIELD(_IO_close_t, __close);
    JUMP_FIELD(_IO_stat_t, __stat);
    JUMP_FIELD(_IO_showmanyc_t, __showmanyc);
    JUMP_FIELD(_IO_imbue_t, __imbue);
};

๊ตฌ์กฐ์ฒด๋ฅผ ์‚ดํŽด๋ณด๋ฉด, 16๋ฐ”์ดํŠธ ํฌ๊ธฐ์˜ ๋”๋ฏธ ๋ฐ”์ดํŠธ๋ฅผ ํฌํ•จํ•ด ๋‹ค์–‘ํ•œ ํ•จ์ˆ˜๊ฐ€ ์ •์˜๋œ ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๋””๋ฒ„๊น… ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค

gdb-peda$ p *(struct _IO_jump_t *)0x00007ffff7dca2a0
$32 = {
  __dummy = 0x0, 
  __dummy2 = 0x0, 
  __finish = 0x7ffff7a6e400 <_IO_new_file_finish>, 
  __overflow = 0x7ffff7a6f3d0 <_IO_new_file_overflow>, 
  __underflow = 0x7ffff7a6f0f0 <_IO_new_file_underflow>, 
  __uflow = 0x7ffff7a70490 <__GI__IO_default_uflow>, 
  __pbackfail = 0x7ffff7a71d20 <__GI__IO_default_pbackfail>, 
  __xsputn = 0x7ffff7a6da00 <_IO_new_file_xsputn>, 
  __xsgetn = 0x7ffff7a6d660 <__GI__IO_file_xsgetn>, 
  __seekoff = 0x7ffff7a6cc60 <_IO_new_file_seekoff>, 
  __seekpos = 0x7ffff7a70a60 <_IO_default_seekpos>, 
  __setbuf = 0x7ffff7a6c920 <_IO_new_file_setbuf>, 
  __sync = 0x7ffff7a6c7a0 <_IO_new_file_sync>, 
  __doallocate = 0x7ffff7a601e0 <__GI__IO_file_doallocate>, 
  __read = 0x7ffff7a6d9e0 <__GI__IO_file_read>, 
  __write = 0x7ffff7a6d260 <_IO_new_file_write>, 
  __seek = 0x7ffff7a6c9e0 <__GI__IO_file_seek>, 
  __close = 0x7ffff7a6c910 <__GI__IO_file_close>, 
  __stat = 0x7ffff7a6d250 <__GI__IO_file_stat>, 
  __showmanyc = 0x7ffff7a71ea0 <_IO_default_showmanyc>, 
  __imbue = 0x7ffff7a71eb0 <_IO_default_imbue>
}

 

 

 

 

_IO_FILE: vtable ํ˜ธ์ถœ ๊ณผ์ •

fread ํ•จ์ˆ˜์˜ ํ˜ธ์ถœ ๊ณผ์ •์„ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•ด๋ณด๋ฉฐ _IO_jump_t ๊ตฌ์กฐ์ฒด์— ์–ด๋–ป๊ฒŒ ์ ‘๊ทผํ•˜๋Š”์ง€ ์•Œ์•„๋ณด์ž.

#define fread(p, m, n, s) _IO_fread (p, m, n, s)
size_t
_IO_fread (void *buf, size_t size, size_t count, FILE *fp)
{
  size_t bytes_requested = size * count;
  size_t bytes_read;
  CHECK_FILE (fp, 0);
  if (bytes_requested == 0)
    return 0;
  _IO_acquire_lock (fp);
  bytes_read = _IO_sgetn (fp, (char *) buf, bytes_requested);
  _IO_release_lock (fp);
  return bytes_requested == bytes_read ? count : bytes_read / size;
}

๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด fread ํ•จ์ˆ˜๋Š” _IO_fread ํ•จ์ˆ˜์™€ ๋™์ผํ•˜๊ฒŒ ์ •์˜๋œ ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•ด๋‹น ํ•จ์ˆ˜ ๋‚ด์—์„œ _IO_sgetn ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

 

#define _IO_XSGETN(FP, DATA, N) JUMP2 (__xsgetn, FP, DATA, N)
#define JUMP2(FUNC, THIS, X1, X2) (_IO_JUMPS_FUNC(THIS)->FUNC) (THIS, X1, X2)
#define _IO_JUMPS_FUNC(THIS) (IO_validate_vtable ( (THIS)))
size_t
_IO_sgetn (FILE *fp, void *data, size_t n)
{
  /* FIXME handle putback buffer here! */
  return _IO_XSGETN (fp, data, n);
}

๋‹ค์Œ์€ _IO_sgetn ํ•จ์ˆ˜์˜ ๊ตฌํ˜„์ฒด์ด๋‹ค. 

์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๋ฉด _IO_XSGETN์„ ํ˜ธ์ถœํ•˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฝ”๋“œ ์ƒ๋‹จ์˜ ๋ฉ”ํฌ๋กœ๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด vtable ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

fread๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ํ•จ์ˆ˜๋Š” ๊ฐ€์ƒ ํ•จ์ˆ˜ ํ…Œ์ด๋ธ”์„ ์ฐธ์กฐํ•ด์„œ ํŒŒ์ผ ์ž‘์—…์„ ์‹œ๋„ํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ํ•ด๋‹น ํ•จ์ˆ˜ ํ…Œ์ด๋ธ”์€ ๋™์ ์œผ๋กœ ํ• ๋‹น๋˜๋Š” ์˜์—ญ์œผ๋กœ, ์“ฐ๊ธฐ ๊ถŒํ•œ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ณต๊ฒฉ์— ์•…์šฉ๋  ์ˆ˜ ์žˆ๋‹ค.

'DreamHack > SystemHacking' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Dreamhack System Hacking] send_sig  (0) 2022.11.14
[Dreamhack System Hacking] SigReturn-Oriented Programming  (0) 2022.11.14
[Dreamhack System Hacking] SROP  (0) 2022.11.14
[DreamHack System Hacking] rtld  (0) 2022.09.22
[DreamHack System Hacking] __eviron  (0) 2022.09.21
๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค!