<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Greedun's archieve</title>
    <link>https://greedun.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sun, 23 Aug 2026 08:12:53 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Greedun (lr-x-dl)</managingEditor>
    <item>
      <title>1_heap 청크, bin들의 구조 및 원리</title>
      <link>https://greedun.tistory.com/145</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 청크의 구조&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwn_21_1.png&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qscm3/btsP8DOn15l/c5GWoOTmwQBPl4YHCYQh5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qscm3/btsP8DOn15l/c5GWoOTmwQBPl4YHCYQh5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qscm3/btsP8DOn15l/c5GWoOTmwQBPl4YHCYQh5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqscm3%2FbtsP8DOn15l%2Fc5GWoOTmwQBPl4YHCYQh5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;218&quot; data-filename=&quot;pwn_21_1.png&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;-&amp;nbsp;prev_size&amp;nbsp;:&amp;nbsp;바로&amp;nbsp;앞에&amp;nbsp;해제된&amp;nbsp;청크의&amp;nbsp;크기&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;앞에&amp;nbsp;해제가&amp;nbsp;없을경우엔&amp;nbsp;별다른&amp;nbsp;의미없는&amp;nbsp;공간이다.&amp;gt;&lt;br /&gt;-&amp;nbsp;size&amp;nbsp;:&amp;nbsp;요청한&amp;nbsp;크기&amp;nbsp;+&amp;nbsp;헤더크기(+flag포함)&lt;br /&gt;-&amp;nbsp;data&amp;nbsp;:&amp;nbsp;입력된&amp;nbsp;값들이&amp;nbsp;저장되는&amp;nbsp;공간&lt;br /&gt;&lt;br /&gt;-&amp;nbsp;fd&amp;nbsp;:&amp;nbsp;linkedlist로&amp;nbsp;앞에&amp;nbsp;연결된&amp;nbsp;해제된&amp;nbsp;청크&amp;nbsp;주소&lt;br /&gt;-&amp;nbsp;bk&amp;nbsp;:&amp;nbsp;linkedlist로&amp;nbsp;뒤에&amp;nbsp;연결된&amp;nbsp;해제된&amp;nbsp;청크&amp;nbsp;주소&lt;br /&gt;-&amp;nbsp;fd_nextsize&amp;nbsp;:&amp;nbsp;같은&amp;nbsp;largebin크기의&amp;nbsp;앞에&amp;nbsp;해제된&amp;nbsp;청크의&amp;nbsp;주소&lt;br /&gt;-&amp;nbsp;bk_nextsize&amp;nbsp;:&amp;nbsp;같은&amp;nbsp;largebin크기의&amp;nbsp;뒤에&amp;nbsp;해제된&amp;nbsp;청크의&amp;nbsp;주소&lt;br /&gt;&amp;rArr;&amp;nbsp;위에&amp;nbsp;4개영역은&amp;nbsp;해제될때&amp;nbsp;data영역에&amp;nbsp;덮어서&amp;nbsp;사용된다.&lt;br /&gt;&lt;br /&gt;(flag비트)&lt;br /&gt;&amp;rArr;&amp;nbsp;0x08&amp;nbsp;&amp;rarr;&amp;nbsp;0000&amp;nbsp;0000&amp;nbsp;0000&amp;nbsp;1&amp;lt;span&amp;nbsp;style=&quot;color:red&quot;&amp;gt;000&amp;lt;/span&amp;gt;&lt;br /&gt;-&amp;nbsp;PREV_INUSE(0x1)&amp;nbsp;:&amp;nbsp;인접한&amp;nbsp;이전&amp;nbsp;청크가&amp;nbsp;사용중일&amp;nbsp;경우&amp;nbsp;1&lt;br /&gt;-&amp;nbsp;IS_MMAPPED(0x2)&amp;nbsp;:&amp;nbsp;해당&amp;nbsp;청크가&amp;nbsp;mmap()으로부터&amp;nbsp;할당된&amp;nbsp;경우&amp;nbsp;1&lt;br /&gt;-&amp;nbsp;NON_MAIN_ARENA(0x4)&amp;nbsp;:&amp;nbsp;해당&amp;nbsp;청크가&amp;nbsp;main_arena에서&amp;nbsp;관리&amp;nbsp;안&amp;nbsp;할&amp;nbsp;경우&lt;br /&gt;&amp;rArr;&amp;nbsp;32bit경우&amp;nbsp;8byte를&amp;nbsp;이용하므로&amp;nbsp;하위&amp;nbsp;3비트를&amp;nbsp;flag로&amp;nbsp;사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;br /&gt;2. bin의 종류&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bin이란 청크가 해제시 담기는 통이다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;(bin종류)&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;(크기 제한)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;fastbin&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;(32bit)&amp;nbsp;16&amp;nbsp;-&amp;nbsp;64byte&amp;nbsp;/&amp;nbsp;(64bit)&amp;nbsp;32&amp;nbsp;-&amp;nbsp;128byte&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;smallbin&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;fastbin보다는&amp;nbsp;크고&amp;nbsp;1024byte보다는&amp;nbsp;작은&amp;nbsp;크기&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;large&amp;nbsp;bin&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;1024byte이상&amp;nbsp;크기&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Unsorted&amp;nbsp;bin&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;제한&amp;nbsp;없음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;tcache(2.26버전&amp;nbsp;이상)&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;(32bit)&amp;nbsp;12&amp;nbsp;-&amp;nbsp;516byte&amp;nbsp;/&amp;nbsp;(64bit)&amp;nbsp;24&amp;nbsp;-&amp;nbsp;1032byte&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;fastbin, tcache크기범위가 겹치는데 2.26버전에서는 tcache가 효율적이기에 먼저 쓰고 &lt;br /&gt;만약 tcache가 관리할 범위를 넘어서면 그때부터 fastbin을 사용하게 된다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;2-1. fastbin 관리&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-1-1. 원리 요약&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwn_21_2.png&quot; data-origin-width=&quot;686&quot; data-origin-height=&quot;270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRHU49/btsP8xAQfE9/p1yiXHkJIJ47rHQ9PehjYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRHU49/btsP8xAQfE9/p1yiXHkJIJ47rHQ9PehjYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRHU49/btsP8xAQfE9/p1yiXHkJIJ47rHQ9PehjYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRHU49%2FbtsP8xAQfE9%2Fp1yiXHkJIJ47rHQ9PehjYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;197&quot; data-filename=&quot;pwn_21_2.png&quot; data-origin-width=&quot;686&quot; data-origin-height=&quot;270&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LIFO구조를 사용하여 같은 크기의 해제된 청크를 단일 linked list로 관리되는 bin이&lt;br /&gt;할당 요청이 있을때 &amp;ldquo;요청크기+헤더&amp;rdquo;크기의 청크가 bin에 있다면 해당 청크를 연결해제후 재할당해준다.&lt;br /&gt;&lt;br /&gt;(특징)&lt;br /&gt;1.&amp;nbsp;검증루틴이&amp;nbsp;적어서&amp;nbsp;할당,&amp;nbsp;해제속도가&amp;nbsp;빠르다.&lt;br /&gt;2.&amp;nbsp;할당,&amp;nbsp;해제시&amp;nbsp;LIFO방식으로&amp;nbsp;처리한다.&lt;br /&gt;3. 인접해서 해제되어도 병합되지 않는다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;2-1-2. free함수에서 해제 원리&lt;/h4&gt;
&lt;pre id=&quot;code_1756309143248&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// free(fastbin)
if ((unsigned long)(size) &amp;lt;= (unsigned long)(get_max_fast ())
#if TRIM_FASTBINS
      /*
	If TRIM_FASTBINS set, don't place chunks
	bordering top into fastbins
      */
      &amp;amp;&amp;amp; (chunk_at_offset(p, size) != av-&amp;gt;top)
#endif
      ) {
    if (__builtin_expect (chunk_at_offset (p, size)-&amp;gt;size &amp;lt;= 2 * SIZE_SZ, 0)
	|| __builtin_expect (chunksize (chunk_at_offset (p, size))
			     &amp;gt;= av-&amp;gt;system_mem, 0))
      {
	/* We might not have a lock at this point and concurrent modifications
	   of system_mem might have let to a false positive.  Redo the test
	   after getting the lock.  */
	if (have_lock
	    || ({ assert (locked == 0);
		  mutex_lock(&amp;amp;av-&amp;gt;mutex);
		  locked = 1;
		  chunk_at_offset (p, size)-&amp;gt;size &amp;lt;= 2 * SIZE_SZ
		    || chunksize (chunk_at_offset (p, size)) &amp;gt;= av-&amp;gt;system_mem;
	      }))
	  {
	    errstr = &quot;free(): invalid next size (fast)&quot;;
	    goto errout;
	  }
	if (! have_lock)
	  {
	    (void)mutex_unlock(&amp;amp;av-&amp;gt;mutex);
	    locked = 0;
	  }
      }
    free_perturb (chunk2mem(p), size - 2 * SIZE_SZ);
    set_fastchunks(av);
    unsigned int idx = fastbin_index(size);
    fb = &amp;amp;fastbin (av, idx);
    /* Atomically link P to its fastbin: P-&amp;gt;FD = *FB; *FB = P;  */
    mchunkptr old = *fb, old2;
    unsigned int old_idx = ~0u;
    do
      {
	/* Check that the top of the bin is not the record we are going to add
	   (i.e., double free).  */
	if (__builtin_expect (old == p, 0))
	  {
	    errstr = &quot;double free or corruption (fasttop)&quot;;
	    goto errout;
	  }
	/* Check that size of fastbin chunk at the top is the same as
	   size of the chunk that we are adding.  We can dereference OLD
	   only if we have the lock, otherwise it might have already been
	   deallocated.  See use of OLD_IDX below for the actual check.  */
	if (have_lock &amp;amp;&amp;amp; old != NULL)
	  old_idx = fastbin_index(chunksize(old));
	p-&amp;gt;fd = old2 = old;
      }
    while ((old = catomic_compare_and_exchange_val_rel (fb, p, old2)) != old2);
    if (have_lock &amp;amp;&amp;amp; old != NULL &amp;amp;&amp;amp; __builtin_expect (old_idx != idx, 0))
      {
	errstr = &quot;invalid fastbin entry (free)&quot;;
	goto errout;
      }
  }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;1.&amp;nbsp;해제된&amp;nbsp;청크의&amp;nbsp;범위가&amp;nbsp;fastbin의&amp;nbsp;범위이다.&lt;br /&gt;2.&amp;nbsp;&amp;ldquo;fb&amp;nbsp;=&amp;nbsp;&amp;amp;fastbin&amp;nbsp;(av,&amp;nbsp;idx);&amp;rdquo;&amp;nbsp;&amp;rArr;&amp;nbsp;현재&amp;nbsp;청크의&amp;nbsp;크기에&amp;nbsp;해당하는&amp;nbsp;리스트를&amp;nbsp;가져온다.&lt;br /&gt;3.&amp;nbsp;&amp;ldquo;p-&amp;gt;fd&amp;nbsp;=&amp;nbsp;old2&amp;nbsp;=&amp;nbsp;old;&amp;rdquo;&amp;nbsp;&amp;rArr;&amp;nbsp;받아온&amp;nbsp;리스트에&amp;nbsp;해제할&amp;nbsp;청크의&amp;nbsp;주소를연결해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-1-3. fastbin에서 재할당 원리&lt;/h4&gt;
&lt;pre id=&quot;code_1756309232946&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// malloc(fastbin)
if ((unsigned long) (nb) &amp;lt;= (unsigned long) (get_max_fast ()))
    {
      idx = fastbin_index (nb);
      mfastbinptr *fb = &amp;amp;fastbin (av, idx);
      mchunkptr pp = *fb;
      do
        {
          victim = pp;
          if (victim == NULL)
            break;
        }
      while ((pp = catomic_compare_and_exchange_val_acq (fb, victim-&amp;gt;fd, victim))
             != victim);
      if (victim != 0)
        {
          if (__builtin_expect (fastbin_index (chunksize (victim)) != idx, 0))
            {
              errstr = &quot;malloc(): memory corruption (fast)&quot;;
            errout:
              malloc_printerr (check_action, errstr, chunk2mem (victim), av);
              return NULL;
            }
          check_remalloced_chunk (av, victim, nb);
          void *p = chunk2mem (victim); //return chunk ptr
          alloc_perturb (p, bytes); //init
          return p;
        }
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;1.&amp;nbsp;&amp;ldquo;mfastbinptr&amp;nbsp;*fb&amp;nbsp;=&amp;nbsp;&amp;amp;fastbin&amp;nbsp;(av,&amp;nbsp;idx);&amp;rdquo;&amp;nbsp;&amp;rArr;&amp;nbsp;요청한&amp;nbsp;fastbin크기에&amp;nbsp;맞는&amp;nbsp;인덱스를&amp;nbsp;찾는다.&lt;br /&gt;2.&amp;nbsp;while&amp;nbsp;((pp&amp;nbsp;=&amp;nbsp;catomic_compare_and_exchange_val_acq&amp;nbsp;(fb,&amp;nbsp;victim-&amp;gt;fd,&amp;nbsp;victim))!=&amp;nbsp;victim);&amp;nbsp;&amp;rArr;&amp;nbsp;찾은&amp;nbsp;청크의&amp;nbsp;fd의&amp;nbsp;값을&amp;nbsp;첫번째&amp;nbsp;값으로&amp;nbsp;업데이트하여&amp;nbsp;LIFO구조를&amp;nbsp;유지한다.&lt;br /&gt;3.&amp;nbsp;return&amp;nbsp;p;&amp;nbsp;&amp;rArr;&amp;nbsp;할당의&amp;nbsp;결과로&amp;nbsp;청크의&amp;nbsp;주소가&amp;nbsp;반환&amp;nbsp;된다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-2. top청크&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwn_21_3.png&quot; data-origin-width=&quot;1034&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YFXGg/btsP7x8XMzF/1WSMAWjOiAEYkUfCM1E3E0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YFXGg/btsP7x8XMzF/1WSMAWjOiAEYkUfCM1E3E0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YFXGg/btsP7x8XMzF/1WSMAWjOiAEYkUfCM1E3E0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYFXGg%2FbtsP7x8XMzF%2F1WSMAWjOiAEYkUfCM1E3E0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;290&quot; data-filename=&quot;pwn_21_3.png&quot; data-origin-width=&quot;1034&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;힙&amp;nbsp;영역에서&amp;nbsp;할당된&amp;nbsp;청크를&amp;nbsp;뺀&amp;nbsp;나머지&amp;nbsp;영역으로서&amp;nbsp;smallbin,&amp;nbsp;largebin크기의&amp;nbsp;청크가&amp;nbsp;top청크&amp;nbsp;근처에서&amp;nbsp;해제시&amp;nbsp;병합되어&amp;nbsp;진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-3. unsorted bin관리&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwn_21_4.png&quot; data-origin-width=&quot;803&quot; data-origin-height=&quot;276&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqfegH/btsP8GqOjaX/GmgDrPLiEfApf1T7YCCn4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqfegH/btsP8GqOjaX/GmgDrPLiEfApf1T7YCCn4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqfegH/btsP8GqOjaX/GmgDrPLiEfApf1T7YCCn4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqfegH%2FbtsP8GqOjaX%2FGmgDrPLiEfApf1T7YCCn4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;803&quot; height=&quot;276&quot; data-filename=&quot;pwn_21_4.png&quot; data-origin-width=&quot;803&quot; data-origin-height=&quot;276&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;- smallbin, largebin크기의 청크가 해제될 경우 바로 bin으로 들어가는게 아닌 unsorted bin에 할당요청이 들어오기 전까지 머물게 된다.&lt;br /&gt;- unsorted bin은 FIFO구조로 원형 linkedlist로 관리된다.&lt;br /&gt;- 이후 요청이 들어오게 된다면 해당 bin을 먼저 확인하여 같거나 큰 청크를 쪼개거나 그대로 재할당을 해주게 된다.&lt;br /&gt;-&amp;nbsp;하지만&amp;nbsp;해당&amp;nbsp;bin에&amp;nbsp;원하는&amp;nbsp;큰&amp;nbsp;청크가&amp;nbsp;없을&amp;nbsp;수도&amp;nbsp;있는데&amp;nbsp;그때는&amp;nbsp;내부에&amp;nbsp;있던&amp;nbsp;청크들은&amp;nbsp;smallbin,&amp;nbsp;largebin으로&amp;nbsp;보내고&amp;nbsp;top청크에서&amp;nbsp;잘라서&amp;nbsp;할당해주게&amp;nbsp;된다.&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(0번과 2번청크를 해제한 이유는 인접한 청크가 해제되었다면 병합되기 때문)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-3-2. 재할당&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwn_21_5.png&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;298&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bN2Uog/btsQadBlwuE/d8LZNikqt1ngf2Kv4MJYPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bN2Uog/btsQadBlwuE/d8LZNikqt1ngf2Kv4MJYPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bN2Uog/btsQadBlwuE/d8LZNikqt1ngf2Kv4MJYPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbN2Uog%2FbtsQadBlwuE%2Fd8LZNikqt1ngf2Kv4MJYPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;825&quot; height=&quot;298&quot; data-filename=&quot;pwn_21_5.png&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;298&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rArr;&amp;nbsp;smallbin,&amp;nbsp;largebin에서도&amp;nbsp;작은&amp;nbsp;크기의&amp;nbsp;경우&amp;nbsp;자른&amp;nbsp;후&amp;nbsp;할당해준다.&lt;br /&gt;&lt;br /&gt;이때&amp;nbsp;자르고&amp;nbsp;남은&amp;nbsp;청크는&amp;nbsp;fastbin크기면&amp;nbsp;fastbin으로&amp;nbsp;들어가고&amp;nbsp;보다&amp;nbsp;크면&amp;nbsp;unsorted&amp;nbsp;bin으로&amp;nbsp;들어가게&amp;nbsp;된다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-4. small bin관리&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwn_21_6.png&quot; data-origin-width=&quot;821&quot; data-origin-height=&quot;278&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xtMGL/btsP77IYx6X/8jKDcTPKtado0xfQkGVePK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xtMGL/btsP77IYx6X/8jKDcTPKtado0xfQkGVePK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xtMGL/btsP77IYx6X/8jKDcTPKtado0xfQkGVePK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxtMGL%2FbtsP77IYx6X%2F8jKDcTPKtado0xfQkGVePK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;821&quot; height=&quot;278&quot; data-filename=&quot;pwn_21_6.png&quot; data-origin-width=&quot;821&quot; data-origin-height=&quot;278&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;-&amp;nbsp;unsorted&amp;nbsp;bin에서&amp;nbsp;넘어온&amp;nbsp;청크들은&amp;nbsp;fastbin처럼&amp;nbsp;크기별로&amp;nbsp;관리하게&amp;nbsp;된다.&lt;br /&gt;-&amp;nbsp;fd,&amp;nbsp;bk영역에&amp;nbsp;주소를&amp;nbsp;담아서&amp;nbsp;원형&amp;nbsp;linkedlist로&amp;nbsp;가리켜서&amp;nbsp;관리하게&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1756309581944&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if (in_smallbin_range (nb))
{
  idx = smallbin_index (nb);
  bin = bin_at (av, idx);
  if ((victim = last (bin)) != bin)
    {
      if (victim == 0) /* initialization check */
        malloc_consolidate (av);
      else
        {
          bck = victim-&amp;gt;bk;
if (__glibc_unlikely (bck-&amp;gt;fd != victim))
            {
              errstr = &quot;malloc(): smallbin double linked list corrupted&quot;;
              goto errout;
            }
          set_inuse_bit_at_offset (victim, nb);
          bin-&amp;gt;bk = bck;
          bck-&amp;gt;fd = bin;
          if (av != &amp;amp;main_arena)
            victim-&amp;gt;size |= NON_MAIN_ARENA;
          check_malloced_chunk (av, victim, nb);
          void *p = chunk2mem (victim);
          alloc_perturb (p, bytes);
          return p;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;1.&amp;nbsp;해제한&amp;nbsp;크기가&amp;nbsp;smallbin크기에&amp;nbsp;부합할때&amp;nbsp;해제한&amp;nbsp;크기에&amp;nbsp;맞는&amp;nbsp;인덱스를&amp;nbsp;찾는다.&lt;br /&gt;2.&amp;nbsp;(1)만약&amp;nbsp;비어있다면&amp;nbsp;fastbin이&amp;nbsp;있는지&amp;nbsp;확인하고&amp;nbsp;있다면&amp;nbsp;병합한다.&amp;nbsp;(2)비어있지않다면&amp;nbsp;smallbin에&amp;nbsp;있는&amp;nbsp;청크를&amp;nbsp;재할당해준다.&lt;br /&gt;3.&amp;nbsp;재할당할&amp;nbsp;청크의&amp;nbsp;prev_size비트를&amp;nbsp;설정하고&amp;nbsp;fd,bk를&amp;nbsp;FIFO구조가&amp;nbsp;유지되게&amp;nbsp;업데이트해준다.&lt;br /&gt;4.&amp;nbsp;업데이트가&amp;nbsp;완료되면&amp;nbsp;청크의&amp;nbsp;주소가&amp;nbsp;반환된다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-5. large bin관리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;small&amp;nbsp;bin처럼&amp;nbsp;FIFO구조&amp;nbsp;원형&amp;nbsp;linkedlist로&amp;nbsp;관리되지만&amp;nbsp;차이점은&amp;nbsp;크기&amp;nbsp;범위별로&amp;nbsp;관리가&amp;nbsp;된다는&amp;nbsp;점이다.&lt;br /&gt;&lt;br /&gt;(1)&amp;nbsp;fd,&amp;nbsp;bk&amp;nbsp;관리&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwn_21_7.png&quot; data-origin-width=&quot;434&quot; data-origin-height=&quot;275&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHwD8H/btsQaQy6Rpf/Tbln7bHIZLHZ6tkcSEXi8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHwD8H/btsQaQy6Rpf/Tbln7bHIZLHZ6tkcSEXi8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHwD8H/btsQaQy6Rpf/Tbln7bHIZLHZ6tkcSEXi8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHwD8H%2FbtsQaQy6Rpf%2FTbln7bHIZLHZ6tkcSEXi8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;434&quot; height=&quot;275&quot; data-filename=&quot;pwn_21_7.png&quot; data-origin-width=&quot;434&quot; data-origin-height=&quot;275&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;-&amp;nbsp;fd,&amp;nbsp;bk영역은&amp;nbsp;small&amp;nbsp;bin에서&amp;nbsp;처럼&amp;nbsp;연결되지만&amp;nbsp;크기가&amp;nbsp;자동&amp;nbsp;정렬되어&amp;nbsp;연결이&amp;nbsp;된다.&lt;br /&gt;&lt;br /&gt;(2)&amp;nbsp;fd_nextsize,&amp;nbsp;bk_nextsize관리&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwn_21_8.png&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;285&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bD2irB/btsP8jiwqdM/r7NHtdYbtapbGqcDTKMkA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bD2irB/btsP8jiwqdM/r7NHtdYbtapbGqcDTKMkA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bD2irB/btsP8jiwqdM/r7NHtdYbtapbGqcDTKMkA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbD2irB%2FbtsP8jiwqdM%2Fr7NHtdYbtapbGqcDTKMkA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;508&quot; height=&quot;285&quot; data-filename=&quot;pwn_21_8.png&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;285&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;-&amp;nbsp;fd_nextsize,&amp;nbsp;bk_nextsize영역은&amp;nbsp;크기별&amp;nbsp;첫번째&amp;nbsp;청크를&amp;nbsp;가리키기&amp;nbsp;위해&amp;nbsp;사용된다.&lt;br /&gt;-&amp;nbsp;따라서&amp;nbsp;제일&amp;nbsp;작은&amp;nbsp;크기의&amp;nbsp;청크를&amp;nbsp;main_arena를&amp;nbsp;가리키는&amp;nbsp;대신&amp;nbsp;젤&amp;nbsp;큰&amp;nbsp;청크를&amp;nbsp;가리킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1756309695091&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if (!in_smallbin_range (nb))
        {
          bin = bin_at (av, idx);
          /* skip scan if empty or largest chunk is too small */
          if ((victim = first (bin)) != bin &amp;amp;&amp;amp;
              (unsigned long) (victim-&amp;gt;size) &amp;gt;= (unsigned long) (nb))
            {
              victim = victim-&amp;gt;bk_nextsize;
              while (((unsigned long) (size = chunksize (victim)) &amp;lt;
                      (unsigned long) (nb)))
                victim = victim-&amp;gt;bk_nextsize;
              /* Avoid removing the first entry for a size so that the skip
                 list does not have to be rerouted.  */
              if (victim != last (bin) &amp;amp;&amp;amp; victim-&amp;gt;size == victim-&amp;gt;fd-&amp;gt;size)
                victim = victim-&amp;gt;fd;
              remainder_size = size - nb;
              unlink (av, victim, bck, fwd);
              /* Exhaust */
              if (remainder_size &amp;lt; MINSIZE)
                {
                  set_inuse_bit_at_offset (victim, size);
                  if (av != &amp;amp;main_arena)
                    victim-&amp;gt;size |= NON_MAIN_ARENA;
                }
              /* Split */
              else
                {
                  remainder = chunk_at_offset (victim, nb);
                  /* We cannot assume the unsorted list is empty and therefore
                     have to perform a complete insert here.  */
                  bck = unsorted_chunks (av);
                  fwd = bck-&amp;gt;fd;
	  if (__glibc_unlikely (fwd-&amp;gt;bk != bck))
                    {
                      errstr = &quot;malloc(): corrupted unsorted chunks&quot;;
                      goto errout;
                    }
                  remainder-&amp;gt;bk = bck;
                  remainder-&amp;gt;fd = fwd;
                  bck-&amp;gt;fd = remainder;
                  fwd-&amp;gt;bk = remainder;
                  if (!in_smallbin_range (remainder_size))
                    {
                      remainder-&amp;gt;fd_nextsize = NULL;
                      remainder-&amp;gt;bk_nextsize = NULL;
                    }
                  set_head (victim, nb | PREV_INUSE |
                            (av != &amp;amp;main_arena ? NON_MAIN_ARENA : 0));
                  set_head (remainder, remainder_size | PREV_INUSE);
                  set_foot (remainder, remainder_size);
                }
              check_malloced_chunk (av, victim, nb);
              void *p = chunk2mem (victim);
              alloc_perturb (p, bytes);
              return p;
            }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;1.&amp;nbsp;요청한&amp;nbsp;크기가&amp;nbsp;largebin이라면&amp;nbsp;largebin과&amp;nbsp;내부에&amp;nbsp;bk_nextsize로&amp;nbsp;순회하며&amp;nbsp;부합하는&amp;nbsp;청크가&amp;nbsp;있는지&amp;nbsp;찾는다.&lt;br /&gt;2.&amp;nbsp;만약&amp;nbsp;반환될&amp;nbsp;청크가&amp;nbsp;있다면&amp;nbsp;fd,bk,fd_nextsize,bk_nextsize의&amp;nbsp;업데이트로&amp;nbsp;연결리스트를&amp;nbsp;유지한다.&lt;br /&gt;3.&amp;nbsp;smallbin과&amp;nbsp;마찬가지로&amp;nbsp;연결리스트의&amp;nbsp;업데이트가&amp;nbsp;완료되었다면&amp;nbsp;청크의&amp;nbsp;주소를&amp;nbsp;반환한다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. main_arena&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bkr시스템&amp;nbsp;콜을&amp;nbsp;사용하여&amp;nbsp;할당된&amp;nbsp;힙을&amp;nbsp;효율적으로&amp;nbsp;관리하게&amp;nbsp;위한&amp;nbsp;malloc_state구조체이다.&lt;br /&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(하지만 top청크보다 큰 크기의 요청이 들어올 경우 mmap시스템콜을 사용하여 새로운 페이지를 할당후 main_arena에서는 관리를 안한다.)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;(구조)&lt;/p&gt;
&lt;pre id=&quot;code_1756310100021&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// main_arena
static struct malloc_state main_arena =
{
  .mutex = _LIBC_LOCK_INITIALIZER,
  .next = &amp;amp;main_arena,
  .attached_threads = 1
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1756310124084&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// malloc_state
struct malloc_state
{
  /* Serialize access.  */
  __libc_lock_define (, mutex);
  /* Flags (formerly in max_fast).  */
  int flags;
  /* Fastbins */
  mfastbinptr fastbinsY[NFASTBINS];
  /* Base of the topmost chunk -- not otherwise kept in a bin */
  mchunkptr top;
  /* The remainder from the most recent split of a small request */
  mchunkptr last_remainder;
  /* Normal bins packed as described above */
  mchunkptr bins[NBINS * 2 - 2];
  /* Bitmap of bins */
  unsigned int binmap[BINMAPSIZE];
  /* Linked list */
  struct malloc_state *next;
  /* Linked list for free arenas.  Access to this field is serialized
     by free_list_lock in arena.c.  */
  struct malloc_state *next_free;
  /* Number of threads attached to this arena.  0 if the arena is on
     the free list.  Access to this field is serialized by
     free_list_lock in arena.c.  */
  INTERNAL_SIZE_T attached_threads;
  /* Memory allocated from the system in this arena.  */
  INTERNAL_SIZE_T system_mem;
  INTERNAL_SIZE_T max_system_mem;
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;참고링크&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://m.blog.naver.com/yjw_sz/221547262765)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://m.blog.naver.com/yjw_sz/221547262765&lt;/a&gt;&lt;br /&gt;- &lt;a href=&quot;https://jjeongsu.tistory.com/68)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://jjeongsu.tistory.com/68&lt;/a&gt;&lt;/p&gt;</description>
      <category>Pwnable/Heap</category>
      <category>glibc</category>
      <category>heap</category>
      <category>malloc.c</category>
      <author>Greedun (lr-x-dl)</author>
      <guid isPermaLink="true">https://greedun.tistory.com/145</guid>
      <comments>https://greedun.tistory.com/145#entry145comment</comments>
      <pubDate>Thu, 28 Aug 2025 01:03:42 +0900</pubDate>
    </item>
    <item>
      <title>[crypto] Block - TEA 알고리즘</title>
      <link>https://greedun.tistory.com/144</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. TEA 알고리즘이란?&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.1 기본 정보&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;TEA(Tiny&amp;nbsp;Encryption&amp;nbsp;Algorithm)는&amp;nbsp;1994년&amp;nbsp;David&amp;nbsp;Wheeler와&amp;nbsp;Roger&amp;nbsp;Needham에&amp;nbsp;의해&amp;nbsp;개발된&amp;nbsp;블록&amp;nbsp;암호&amp;nbsp;알고리즘입니다.&lt;br /&gt;&lt;br /&gt;(주요 특징)&lt;br /&gt;- 블록 크기: 64비트&lt;br /&gt;- 키 길이: 128비트&lt;br /&gt;- 라운드 수: 32라운드&lt;br /&gt;- 구조: Feistel 네트워크 기반&lt;br /&gt;&lt;br /&gt;장점&lt;br /&gt;-&amp;nbsp;구현이&amp;nbsp;매우&amp;nbsp;간단하고&amp;nbsp;빠름&lt;br /&gt;-&amp;nbsp;메모리&amp;nbsp;사용량이&amp;nbsp;적음&lt;br /&gt;-&amp;nbsp;복잡한&amp;nbsp;S-Box나&amp;nbsp;치환&amp;nbsp;테이블이&amp;nbsp;불필요&lt;br /&gt;&lt;br /&gt;단점&lt;br /&gt;-&amp;nbsp;보안상&amp;nbsp;취약점이&amp;nbsp;발견되어&amp;nbsp;현재는&amp;nbsp;실용적으로&amp;nbsp;사용되지&amp;nbsp;않음&lt;br /&gt;- 관련키 공격(Related-key attack)에 취약&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Feistel 구조&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.1 Feistel 네트워크란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1973년 IBM의 Horst Feistel이 개발한 블록 암호 설계 방법론으로, DES 알고리즘에서 처음 사용되었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;732&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHL3Mr/btsPp55hiFg/Hxs5AVOUrnF4n9ySgMdpV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHL3Mr/btsPp55hiFg/Hxs5AVOUrnF4n9ySgMdpV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHL3Mr/btsPp55hiFg/Hxs5AVOUrnF4n9ySgMdpV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHL3Mr%2FbtsPp55hiFg%2FHxs5AVOUrnF4n9ySgMdpV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;439&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;732&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;(핵심&amp;nbsp;원리)&lt;br /&gt;1. 블록 분할 : 평문을 두 개의 동일한 크기 부분으로 나눔 (L, R)&lt;br /&gt;2. 라운드 함수 : 각 라운드에서 한쪽 부분만 변형하고 다른 쪽과 XOR 연산&lt;br /&gt;3. 교환 : 두 부분의 역할을 교환하며 여러 라운드 반복&lt;br /&gt;&lt;br /&gt;(Feistel&amp;nbsp;구조의&amp;nbsp;특징)&lt;br /&gt;- 가역성 보장 : 라운드 함수가 가역적이지 않아도 전체 구조는 가역적&lt;br /&gt;- 구현 효율성 : 암복호화에 같은 알고리즘 사용, 메모리 효율적&lt;br /&gt;- 분석 용이성 : 수학적 분석이 상대적으로 쉬움&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.2. TEA의 Feistel 구조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(일반적인 Feistel과의 차이점)&lt;br /&gt;-&amp;nbsp;전통적인&amp;nbsp;Feistel에서는&amp;nbsp;라운드마다&amp;nbsp;L,&amp;nbsp;R이&amp;nbsp;단순&amp;nbsp;교환&lt;br /&gt;-&amp;nbsp;TEA는&amp;nbsp;각&amp;nbsp;라운드에서&amp;nbsp;양쪽&amp;nbsp;블록을&amp;nbsp;모두&amp;nbsp;업데이트&lt;br /&gt;- 라운드 함수&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;L[i+1] = R[i]
R[i+1] = L[i] &amp;oplus; F(R[i], K[i])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;br /&gt;3. 보안메커니즘&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.1. sum값의 역할&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;(기본&amp;nbsp;기능)&lt;br /&gt;1.&amp;nbsp;라운드&amp;nbsp;카운터&amp;nbsp;역할&lt;br /&gt;2.&amp;nbsp;키&amp;nbsp;스케줄링&amp;nbsp;메커니즘&lt;br /&gt;&lt;br /&gt;(보안적&amp;nbsp;역할)&lt;br /&gt;1.&amp;nbsp;키&amp;nbsp;다양성&amp;nbsp;제공&lt;br /&gt;&amp;nbsp; &amp;nbsp; - 같은 128비트 키를 사용하더라도 각 라운드에서 다른 서브키 사용&lt;br /&gt;&amp;nbsp; &amp;nbsp; - `sum &amp;amp; 3`과 `(sum &amp;gt;&amp;gt; 11) &amp;amp; 3`로 4개의 32비트 키 워드를 순환 사용&lt;br /&gt;2.&amp;nbsp;슬라이딩&amp;nbsp;공격&amp;nbsp;방지&lt;br /&gt;&amp;nbsp; &amp;nbsp; - 각 라운드가 고유한 sum값을 가짐으로써 라운드 간 구별이 가능&lt;br /&gt;&amp;nbsp; &amp;nbsp; - 단순한 반복 패턴을 방지한다.&lt;br /&gt;3.&amp;nbsp;대칭성&amp;nbsp;파괴&lt;br /&gt;&amp;nbsp; &amp;nbsp; - 암복호화에서 sum의 진행방향이 반대&lt;br /&gt;&amp;nbsp; &amp;nbsp; - 이로 인해 구조적 대칭성이 파괴된다.&lt;br /&gt;&lt;br /&gt;(한계점)&lt;br /&gt;-&amp;nbsp;단순한&amp;nbsp;키&amp;nbsp;스케줄링으로&amp;nbsp;인한&amp;nbsp;관련키&amp;nbsp;공격&amp;nbsp;취약성&lt;br /&gt;-&amp;nbsp;예측&amp;nbsp;가능한&amp;nbsp;선형&amp;nbsp;증가&amp;nbsp;패턴&lt;br /&gt;&lt;br /&gt;=&amp;gt; sum값은 TEA의 핵심 구성 요소로,&amp;nbsp;간단하면서도 효과적인 키 스케줄링을 제공하지만&amp;nbsp;동시에&amp;nbsp;알고리즘의&amp;nbsp;주요&amp;nbsp;취약점&amp;nbsp;중&amp;nbsp;하나이다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.2. 매직 상수&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 값 : 0x9e3779b9&lt;br /&gt;&amp;nbsp;&lt;br /&gt;(수학적 의미)&lt;br /&gt;-&amp;nbsp;황금비와의&amp;nbsp;관계:&amp;nbsp;`(&amp;radic;5&amp;nbsp;-&amp;nbsp;1)&amp;nbsp;/&amp;nbsp;2&amp;nbsp;&amp;times;&amp;nbsp;2&amp;sup3;&amp;sup2;`&lt;br /&gt;-&amp;nbsp;황금비의&amp;nbsp;역수에&amp;nbsp;2&amp;sup3;&amp;sup2;를&amp;nbsp;곱한&amp;nbsp;값&lt;br /&gt;-&amp;nbsp;수학적으로&amp;nbsp;좋은&amp;nbsp;분포&amp;nbsp;특성을&amp;nbsp;제공&lt;br /&gt;&amp;nbsp;&lt;br /&gt;(암호학적 효과)&lt;br /&gt;-&amp;nbsp;의사난수&amp;nbsp;생성에서&amp;nbsp;좋은&amp;nbsp;확산&amp;nbsp;특성&lt;br /&gt;-&amp;nbsp;해시&amp;nbsp;함수에서&amp;nbsp;균등한&amp;nbsp;분포&amp;nbsp;제공&lt;br /&gt;- 암호화 과정에서 예측 불가능성 향상&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;황금비의 수학적 특성을 활용하여 암호화 과정에서 좋은 확산 특성과 예측 불가능성을 제공하지만, &lt;br /&gt;동시에 TEA의 단순함으로 인한 보안 취약점도 가지고 있습니다.&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;br /&gt;&lt;br /&gt;4. Tea알고리즘 동작 과정&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;372&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTmKGm/btsPpvcrL6m/m4SrFScWEoU5krkeodAupk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cTmKGm/btsPpvcrL6m/m4SrFScWEoU5krkeodAupk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cTmKGm/btsPpvcrL6m/m4SrFScWEoU5krkeodAupk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcTmKGm%2FbtsPpvcrL6m%2Fm4SrFScWEoU5krkeodAupk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;446&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;372&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;4.1. 기본 구성&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;- 블록 크기 : 64bit(8byte)
- 키 길이 : 128bit(16byte)
- 라운드 수 : 32 (각 라운드마다 연산 2번 수행)
- 연산 구조 : Feistel 구조&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;=&amp;gt;&amp;nbsp;복잡한&amp;nbsp;S-Box나&amp;nbsp;치환&amp;nbsp;테이블없이&amp;nbsp;기본적인&amp;nbsp;산술&amp;nbsp;연산만을&amp;nbsp;이용하여&amp;nbsp;구현된다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.2. 초기 단계&amp;nbsp;&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;- 데이터 분할 : P = (L₀, R₀) (64비트를 32비트씩 분할)
- 키 분할 : K = (K₀, K₁, K₂, K₃) (128비트를 32비트씩 분할)
- 델타 상수 설정 : &amp;delta; = 0x9E3779B9&amp;delta;(황금비율 상수)
- 라운드 카운터 초기화 : n = 0(최종 라운드 수 32)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;4.3. 암호화 단계&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;총&amp;nbsp;32라운드에&amp;nbsp;걸쳐&amp;nbsp;다음과&amp;nbsp;같은&amp;nbsp;과정을&amp;nbsp;반복한다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;1. 초기 sum: 0
2. 각 라운드마다:
&amp;nbsp;&amp;nbsp; - 델타 누적: sum = sum + &amp;delta;
&amp;nbsp;&amp;nbsp; - v0 업데이트: v0 += ((v1 &amp;lt;&amp;lt; 4) + k0) ^ (v1 + sum) ^ ((v1 &amp;gt;&amp;gt; 5) + k1)
&amp;nbsp;&amp;nbsp; - v1 업데이트: v1 += ((v0 &amp;lt;&amp;lt; 4) + k2) ^ (v0 + sum) ^ ((v0 &amp;gt;&amp;gt; 5) + k3)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.4. 복호화 단계&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;총 32라운드에 걸쳐 암호화의 역순 수행:&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;1. 초기 sum: 32 &amp;times; &amp;delta;
2. 각 라운드마다:
&amp;nbsp;&amp;nbsp; - v1 업데이트: v1 -= ((v0 &amp;lt;&amp;lt; 4) + k2) ^ (v0 + sum) ^ ((v0 &amp;gt;&amp;gt; 5) + k3)
&amp;nbsp;&amp;nbsp; - v0 업데이트: v0 -= ((v1 &amp;lt;&amp;lt; 4) + k0) ^ (v1 + sum) ^ ((v1 &amp;gt;&amp;gt; 5) + k1)
&amp;nbsp;&amp;nbsp; - 델타 감소: sum = sum - &amp;delta;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;br /&gt;5. 보안 분석&lt;/h2&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;- 확산(Diffusion)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- 평문의 작은 변화가 암호문 전체에 영향
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- Feistel 구조의 반복을 통해 달성

- 혼돈(Confusion)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- 평문과 암호문, 키 간의 관계를 복잡하게 만듦
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- 라운드 함수의 비선형 연산으로 달성&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;(알려진 취약점)&lt;br /&gt;- 관련키 공격(Related-key attack)에 취약&lt;br /&gt;- 슬라이드 공격(Slide attack)에 일부 취약성&lt;br /&gt;- 단순한 키 스케줄링으로 인한 패턴 분석 가능&lt;br /&gt;&lt;br /&gt;=&amp;gt;&amp;nbsp;이후&amp;nbsp;XTEA나&amp;nbsp;다른&amp;nbsp;현대&amp;nbsp;암호&amp;nbsp;알고리즘이&amp;nbsp;사용된다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(참고링크)&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/%ED%8C%8C%EC%9D%B4%EC%8A%A4%ED%85%94_%EC%95%94%ED%98%B8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;- &lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/%ED%8C%8C%EC%9D%B4%EC%8A%A4%ED%85%94_%EC%95%94%ED%98%B8&quot; target=&quot;_self&quot;&gt;&lt;span&gt;https://ko.wikipedia.org/wiki/%ED%8C%8C%EC%9D%B4%EC%8A%A4%ED%85%94_%EC%95%94%ED%98%B8&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;- &lt;a href=&quot;https://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;- &lt;a href=&quot;https://en.wikipedia.org/wiki/C_(programming_language)&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://en.wikipedia.org/wiki/C_(programming_language)&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;- &lt;a href=&quot;https://berom.tistory.com/171&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://berom.tistory.com/171&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Crypto</category>
      <category>Block</category>
      <category>Crypto</category>
      <category>Feistel</category>
      <category>tea알고리즘</category>
      <author>Greedun (lr-x-dl)</author>
      <guid isPermaLink="true">https://greedun.tistory.com/144</guid>
      <comments>https://greedun.tistory.com/144#entry144comment</comments>
      <pubDate>Sat, 19 Jul 2025 00:11:12 +0900</pubDate>
    </item>
    <item>
      <title>[Know] tar에 다양한 옵션이 있는 이유</title>
      <link>https://greedun.tistory.com/143</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. tar의 기본 사용법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;(종류)&lt;/span&gt;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;기본 tar, gzip, bzip2, xz&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;(압축하기)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1751812479528&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 기본 tar 압축 (압축 없음)
tar -cf archive.tar files/

# gzip 압축 (.tar.gz)
tar -czf archive.tar.gz files/

# bzip2 압축 (.tar.bz2)
tar -cjf archive.tar.bz2 files/

# xz 압축 (.tar.xz)
tar -cJf archive.tar.xz files/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(압축해제)&lt;/p&gt;
&lt;pre id=&quot;code_1751812504775&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# tar 해제
tar -xf archive.tar

# gzip 해제
tar -xzf archive.tar.gz

# bzip2 해제
tar -xjf archive.tar.bz2

# xz 해제
tar -xJf archive.tar.xz

# 특정 디렉토리에 해제
tar -xzf archive.tar.gz -C /path/to/directory&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 기타 활용법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1) 압축률 비교&lt;/p&gt;
&lt;pre id=&quot;code_1751812620507&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 속도 우선 (빠름, 큰 용량)
tar -czf fast.tar.gz files/

# 압축률 우선 (느림, 작은 용량)
tar -cjf small.tar.bz2 files/

# 최고 압축률 (가장 느림, 가장 작음)
tar -cJf smallest.tar.xz files/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(2) 진행률 표시&lt;/p&gt;
&lt;pre id=&quot;code_1751812649683&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# pv 사용 (설치 필요: sudo apt install pv)
tar -czf - files/ | pv &amp;gt; backup.tar.gz

# 파일 개수 표시
tar -czf backup.tar.gz files/ --checkpoint=1000 --checkpoint-action=dot&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 각 압축의 차이점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1970년대 - tar의 탄생)&lt;/p&gt;
&lt;pre id=&quot;code_1751812688295&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 원래 tar는 &quot;Tape ARchive&quot;
# 테이프 백업용으로 만들어짐 - 압축 기능 없음
tar -cf backup.tar files/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(압축의 진화)&lt;/p&gt;
&lt;pre id=&quot;code_1751812708799&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. 1970년대 - tar
2. 1980년대 - compress(.Z)
3. 1990년대 - gzip(.gz)
4. 2000년대 - bzip2(.bz2)
5. 2010년대 - xz(.xz)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(각 압축방식의 특징)&lt;/p&gt;
&lt;pre id=&quot;code_1751812728597&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;- 하드웨어 환경
    # 저성능 시스템 &amp;rarr; gzip
    # 고성능 시스템 &amp;rarr; xz
    # 네트워크 대역폭 제한 &amp;rarr; bzip2/xz
- 호환성 요구사항
    # 오래된 시스템 지원 &amp;rarr; gzip
    # 최신 시스템만 &amp;rarr; xz
    # 범용성 &amp;rarr; gzip&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1) gzip(-z)&lt;/p&gt;
&lt;pre id=&quot;code_1751812749019&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;tar -czf archive.tar.gz files/&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;장점 : 빠른 속도, 널리 지원&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;단점 : 상대적으로 낮은 압축률&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;용도 : 일반적인 압축, 웹서버등&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(2) bzip2(-j)&lt;/p&gt;
&lt;pre id=&quot;code_1751812781463&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;tar -cjf archive.tar.bz2 files/&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;장점 : gzip보다 높은 압축률&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;단점 : 더 느린 속도 &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;용도 : 저장 공간이 중요할 떄&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(3) xz(-J)&lt;/p&gt;
&lt;pre id=&quot;code_1751812806619&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;tar -cJf archive.tar.xz files/&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-mark=&quot;-&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;장점 : 최고 압축률, 병렬 처리 지원&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;단점 : 가장 느림, 메모리 사용량 높음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;용도 : 배포용 패키지, 장기 보관&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;(성능 비교)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1751812829696&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 같은 1GB 디렉토리를 압축했을 때:

# gzip: 2분, 300MB
time tar -czf test.tar.gz large_dir/

# bzip2: 8분, 250MB  
time tar -cjf test.tar.bz2 large_dir/

# xz: 15분, 200MB
time tar -cJf test.tar.xz large_dir/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 새로운 압축 알고리즘&lt;/h2&gt;
&lt;pre id=&quot;code_1751812857869&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 새로운 압축 알고리즘들
# zstd (Facebook 개발) - 속도와 압축률의 균형
tar --zstd -cf archive.tar.zst files/

# lz4 - 초고속 압축
# brotli - 웹 최적화&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Linux</category>
      <category>tar</category>
      <author>Greedun (lr-x-dl)</author>
      <guid isPermaLink="true">https://greedun.tistory.com/143</guid>
      <comments>https://greedun.tistory.com/143#entry143comment</comments>
      <pubDate>Sun, 6 Jul 2025 23:41:11 +0900</pubDate>
    </item>
    <item>
      <title>[Python] pip설치시 externally-managed-environment 오류</title>
      <link>https://greedun.tistory.com/120</link>
      <description>&lt;pre id=&quot;code_1734225536575&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;greedun@lr-x-dl:~/RD/auto_ctfd$ sudo pip3 install virtualenv
error: externally-managed-environment

&amp;times; This environment is externally managed
╰─&amp;gt; To install Python packages system-wide, try apt install
    python3-xyz, where xyz is the package you are trying to
    install.
    
    If you wish to install a non-Debian-packaged Python package,
    create a virtual environment using python3 -m venv path/to/venv.
    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
    sure you have python3-full installed.
    
    If you wish to install a non-Debian packaged Python application,
    it may be easiest to use pipx install xyz, which will manage a
    virtual environment for you. Make sure you have pipx installed.
    
    See /usr/share/doc/python3.12/README.venv for more information.

note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(해결방법)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;python3&amp;nbsp;-m&amp;nbsp;pip&amp;nbsp;config&amp;nbsp;set&amp;nbsp;global.break-system-packages&amp;nbsp;true&lt;/p&gt;
&lt;pre id=&quot;code_1734225689230&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;greedun@lr-x-dl:~/RD/auto_ctfd$ python3 -m pip config set global.break-system-packages true
Writing to /home/greedun/.config/pip/pip.conf&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(+) sudo를 사용한 pip의 설치의 경우 위 과정에서도 sudo로 진행해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;참고링크&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1) - &lt;a href=&quot;https://blog.naver.com/kim1417/223493704161&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.naver.com/kim1417/223493704161&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>환경구축 &amp;amp; Tip/Etc</category>
      <category>error</category>
      <category>Python</category>
      <category>TIP</category>
      <author>Greedun (lr-x-dl)</author>
      <guid isPermaLink="true">https://greedun.tistory.com/120</guid>
      <comments>https://greedun.tistory.com/120#entry120comment</comments>
      <pubDate>Sun, 15 Dec 2024 10:24:01 +0900</pubDate>
    </item>
    <item>
      <title>ICCP 프로토콜</title>
      <link>https://greedun.tistory.com/119</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. ICCP 프로토콜&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ICCP(Inter&amp;nbsp;Control-Centre&amp;nbsp;Communication&amp;nbsp;Protocol)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;:&amp;nbsp;여러&amp;nbsp;프로토콜을&amp;nbsp;사용하는&amp;nbsp;전력&amp;nbsp;제어센터들&amp;nbsp;사이에서&amp;nbsp;실시간&amp;nbsp;데이터&amp;nbsp;교환에&amp;nbsp;사용되는&amp;nbsp;프로토콜&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;미국 전력연구소에서 전력 제어센터간 통신을 담당하는 프로토콜로 발표한 통신 규약&lt;/li&gt;
&lt;li&gt;제어센터
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;전력망과 관련된 정보를 받고 상황에 따라 적절한 명령을 내려서 시스템이 안전한 상태로 유지시키는 역할&lt;/li&gt;
&lt;li&gt;여러 프로토콜을 사용하는데 자동화용 통신 규약인 MMS를 응용계층 하부 규약으로 지정하여 서로 다른 기종간의 원활한 통신을 지원&lt;/li&gt;
&lt;li&gt;지원 내역으로는 장치제어, 일반적인 메세지(report), 원격제어 센터의 프로그램 제어등이 존재&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. ICCP 프로토콜의 표준&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;전기 공학 및 전력 시스템 자동화 애플리케이션에서 원격제어(감독 제어 및 데이터 수집)에 사용되는 시스템을 정의 (IEC 60870)&lt;/li&gt;
&lt;li&gt;전기 공학 및 전력 시스템 자동화 분야의 IEC 60870 6부&lt;/li&gt;
&lt;li&gt;IEC 60870-6-503 : 서비스 및 프로토콜&lt;/li&gt;
&lt;li&gt;IEC 60870-6-602 : 전송 프로토콜&lt;/li&gt;
&lt;li&gt;IEC 60870-6-702 : 프로파일&lt;/li&gt;
&lt;li&gt;IEC 60870-6-802 : 객체 모델&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. ICCP 프로토콜의 구조&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-1. 전체적인 구조&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ICCP_3_1_Protocol_Stack.png&quot; data-origin-width=&quot;331&quot; data-origin-height=&quot;370&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/02vQP/btsLdFIYj9K/mqkntGJ5KcaAk3fB58sJjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/02vQP/btsLdFIYj9K/mqkntGJ5KcaAk3fB58sJjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/02vQP/btsLdFIYj9K/mqkntGJ5KcaAk3fB58sJjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F02vQP%2FbtsLdFIYj9K%2FmqkntGJ5KcaAk3fB58sJjk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;331&quot; height=&quot;370&quot; data-filename=&quot;ICCP_3_1_Protocol_Stack.png&quot; data-origin-width=&quot;331&quot; data-origin-height=&quot;370&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ICCP_4_2_PDU.png&quot; data-origin-width=&quot;725&quot; data-origin-height=&quot;491&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mQeSf/btsLdzvj94A/3PK7Y1jX2w524AqkmOkPkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mQeSf/btsLdzvj94A/3PK7Y1jX2w524AqkmOkPkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mQeSf/btsLdzvj94A/3PK7Y1jX2w524AqkmOkPkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmQeSf%2FbtsLdzvj94A%2F3PK7Y1jX2w524AqkmOkPkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;406&quot; data-filename=&quot;ICCP_4_2_PDU.png&quot; data-origin-width=&quot;725&quot; data-origin-height=&quot;491&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ICCP프로토콜은 OSI 7 Layer의 애플리케이션 계층에서 동작&lt;/li&gt;
&lt;li&gt;응용계층의 하부 계층으로 MMS, ACSE를 이용하여 MMS의 장점을 상속&lt;br /&gt;(상호 운용성, 통합의 편리성)&lt;/li&gt;
&lt;li&gt;서버-클라이언트 모델을 사용하여 통신하며 구조화된 데이터 블록인 PDU를 이용하여 통신&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-2. 응용계층&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-2-1. MMS&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(Manufacturing&amp;nbsp;Message&amp;nbsp;Specification)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서로 다른 제조회사의 서로 다른 단위제어기기 간에 메세지 교환을 위해 사용하는 프로토콜&lt;/li&gt;
&lt;li&gt;제정된 표준
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ISO/IEC 9506-1&lt;br /&gt;&amp;nbsp;&amp;nbsp;: 가상제조기기(VMD), 네트워크 상에서 교환되는 메세지, VMD에 관련된 속성과 파라미터에 대해 기술&lt;/li&gt;
&lt;li&gt;ISO/IEC 9506-2&lt;br /&gt;&amp;nbsp;&amp;nbsp;: 프로토콜의 사양을 표현계층의 추상구문표현 ASN.1로 기술되어있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MMS가 서버-클라이언트 모델을 사용하여 통신&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(MMS의 이점)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다른 제조사 기기간 서로 다른 프로토콜을 사용하는 기기들 간 통신을 가능하게 하는 &quot;상호운용성&quot;이 크다.&lt;/li&gt;
&lt;li&gt;이외에도 통합의 편리성, 설치비용과 유지보수 비용감소, 응용프로그램 이식등 이점이 존재&lt;/li&gt;
&lt;li&gt;가상제조기기(VMD)로서 각각의 디바이스를 표현하여 통일된 통신을 할 수 있는 환경을 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-2-2. ACSE&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(Association Control Service Element)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하나의 애플리케이션 프로그램 간에 호출을 설정하기 위한 OSI방법&lt;/li&gt;
&lt;li&gt;2개의 사용자 응용 프로세스(AP)간에 통신을 위해서 데이터 교환 전에 하나의 논리적인 통신 채널을 설정하는데 이를 &quot;결합&quot;이라 명칭&lt;/li&gt;
&lt;li&gt;ACSE는 이 결합을 설정하고 해제하는 기능을 수행하는 ASE(응용 서비스 요소)&lt;/li&gt;
&lt;li&gt;ACSE를 통해 엔티티의 ID와 컨텍스트를 확인하고 인증 보안 검사를 적용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-2-3. ICCP와 MMS의 관계&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실제 데이터 센터를 나타내기 위해 가상제어센터(VCC)라는 추상적인 개념을 사용&lt;/li&gt;
&lt;li&gt;MMS의 가상제조기기(VMD)개념의 확대로 실제 계통운영센터의 모든 데이터들을 추상화하여 표현&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ICCP_4_3_relation.png&quot; data-origin-width=&quot;494&quot; data-origin-height=&quot;552&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8whQt/btsLb0VmnZF/NdJjV54OxdCSvjCSkclXs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8whQt/btsLb0VmnZF/NdJjV54OxdCSvjCSkclXs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8whQt/btsLb0VmnZF/NdJjV54OxdCSvjCSkclXs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8whQt%2FbtsLb0VmnZF%2FNdJjV54OxdCSvjCSkclXs0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;335&quot; data-filename=&quot;ICCP_4_3_relation.png&quot; data-origin-width=&quot;494&quot; data-origin-height=&quot;552&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MMS의 객체와 서비스들 중 일부분이 매핑되어서 사용&lt;/li&gt;
&lt;li&gt;ICCP의 서비스
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;제어센터 응용어플리케이션으로 서비스를 제공&lt;/li&gt;
&lt;li&gt;MMS의 서비스와 프로토콜, 그리고 기능을 이용하는 표준화된 응용프로토콜&lt;/li&gt;
&lt;li&gt;MMS객체에 매핑되어있는 구조화된 데이터를 표현&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(MMS와&amp;nbsp;ICCP의&amp;nbsp;차이점)&lt;br /&gt;=&amp;gt;&amp;nbsp;둘다&amp;nbsp;사용자에게&amp;nbsp;서비스를&amp;nbsp;제공한다는&amp;nbsp;점은&amp;nbsp;같지만&amp;nbsp;&lt;br /&gt;ICCP는&amp;nbsp;제어센터간에&amp;nbsp;메세지&amp;nbsp;교환을&amp;nbsp;위해&amp;nbsp;최적화&amp;nbsp;되었다는&amp;nbsp;점에서&amp;nbsp;다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-3. 전송계층&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; OSI&amp;nbsp;7계층&amp;nbsp;구조에서&amp;nbsp;ICCP를&amp;nbsp;사용하기&amp;nbsp;위해&amp;nbsp;COTP,&amp;nbsp;TPKT&amp;nbsp;프로토콜이&amp;nbsp;필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;COTP
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;TCP와 기능이 거의 유사하지만&lt;/li&gt;
&lt;li&gt;TCP는 스트림 기반의 통신을 제공 / COTP는 패킷 기반의 통신을 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;TPKT
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;TCP/IP&amp;nbsp;스택&amp;nbsp;위에서&amp;nbsp;COTP를&amp;nbsp;사용하기&amp;nbsp;위해&amp;nbsp;제공&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. ICCP 프로토콜의 특징&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-1. ICCP의 사용모델&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ICCP_2_6_model.png&quot; data-origin-width=&quot;777&quot; data-origin-height=&quot;407&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PTSuc/btsLdf4Wa4U/ncBy70hnCKSQvmbiQ2B9nK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PTSuc/btsLdf4Wa4U/ncBy70hnCKSQvmbiQ2B9nK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PTSuc/btsLdf4Wa4U/ncBy70hnCKSQvmbiQ2B9nK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPTSuc%2FbtsLdf4Wa4U%2FncBy70hnCKSQvmbiQ2B9nK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;450&quot; height=&quot;236&quot; data-filename=&quot;ICCP_2_6_model.png&quot; data-origin-width=&quot;777&quot; data-origin-height=&quot;407&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ICCP를 사용시 서로 다른 여러 프로세스간의 통신을 진행&lt;/li&gt;
&lt;li&gt;각 시스템 통신시 각자의 통신규약 대신 ICCP 하나의 통신을 이용하여 통신 가능&lt;/li&gt;
&lt;li&gt;시스템 통합시 비교적 적은 비용으로 통합을 이룰 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4-1-1. 제어센터 구분&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(제어센터)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하나 또는 그 이상의 가상제어센터로 모델링&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(가상제어센터)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;제조환경의 실제 디바이스의 기능을 매핑한 것으로 서버기능의 집결체&lt;/li&gt;
&lt;li&gt;응용프로그램과 실제 디바이스 사이에 위치하여&amp;nbsp;&lt;br /&gt;&amp;nbsp;기계의 실제 기능과 동작을 MMS의 추상적인 객체로 매핑하는 수단&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; ICCP&amp;nbsp;가상제어센터(VCC)를&amp;nbsp;MMS&amp;nbsp;가상제조기기(VMD)로&amp;nbsp;매핑하여&amp;nbsp;&lt;br /&gt;ICCP&amp;nbsp;VCC는&amp;nbsp;MMS&amp;nbsp;VMD가&amp;nbsp;실제&amp;nbsp;디바이스를&amp;nbsp;위해&amp;nbsp;행하는&amp;nbsp;것처럼&amp;nbsp;제어센터를&amp;nbsp;위해&amp;nbsp;같은&amp;nbsp;기능을&amp;nbsp;수행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4-1-2. 클라이언트, 서버 모델&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ICCP_2_7_operation.png&quot; data-origin-width=&quot;845&quot; data-origin-height=&quot;609&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kKGtQ/btsLbUOhGKu/kKr8dNrheOZCj2HwSxkfW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kKGtQ/btsLbUOhGKu/kKr8dNrheOZCj2HwSxkfW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kKGtQ/btsLbUOhGKu/kKr8dNrheOZCj2HwSxkfW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkKGtQ%2FbtsLbUOhGKu%2FkKr8dNrheOZCj2HwSxkfW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;450&quot; height=&quot;324&quot; data-filename=&quot;ICCP_2_7_operation.png&quot; data-origin-width=&quot;845&quot; data-origin-height=&quot;609&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가상제어센터의 의미와 관련지어 클라이언트와 서버를 정의&lt;/li&gt;
&lt;li&gt;클라이언트
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ICCP 서비스 요청을 위해서 가상제어센터를 이용하는 통신 개체&lt;/li&gt;
&lt;li&gt;Method : Operation (클라이언트의 요청에 응답)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;서버
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스 요청에 대해 가상제어센터로서 행동하는 통신 개체&lt;/li&gt;
&lt;li&gt;Method : Action (서버에서 설정된 매커니즘에 따라 보내는 report)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-2. Conformance&amp;nbsp;Block&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;표준에서&amp;nbsp;서버의&amp;nbsp;역할에&amp;nbsp;따라&amp;nbsp;객체를&amp;nbsp;그룹핑한&amp;nbsp;것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ICCP_1_4_iccp_stack.png&quot; data-origin-width=&quot;748&quot; data-origin-height=&quot;770&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bR3Iki/btsLcJS47gi/NDZCjdDa3CqWFg4pcycSWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bR3Iki/btsLcJS47gi/NDZCjdDa3CqWFg4pcycSWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bR3Iki/btsLcJS47gi/NDZCjdDa3CqWFg4pcycSWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbR3Iki%2FbtsLcJS47gi%2FNDZCjdDa3CqWFg4pcycSWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;309&quot; data-filename=&quot;ICCP_1_4_iccp_stack.png&quot; data-origin-width=&quot;748&quot; data-origin-height=&quot;770&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Block 1&lt;br /&gt;: 기본적인 통신에 대한 부분으로써 모든 ICCP서버가 필수적으로 가져야하는 항목&lt;/li&gt;
&lt;li&gt;나머지 블록&lt;br /&gt;: 서버가 수행하는 역할에 따라 선택 가능&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-3. Biteral Table&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버에서 요청유형에 따라 접근제어하기 위한 테이블&lt;/li&gt;
&lt;li&gt;서버에 존재하는 정보에 대해 4가지 종류의 설정이 가능&lt;br /&gt;&amp;nbsp;&amp;nbsp;(&quot;실행&quot;, &quot;읽기와 쓰기&quot;, &quot;읽기&quot;, &quot;접근불가&quot;)&lt;/li&gt;
&lt;li&gt;VCC에 정의된 command, 가상변수를 table에 지정하여 지정된 정보나 동작만 수행할 수 있게 해준다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. ICCP 프로토콜 통신&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt;&amp;nbsp;iccp2.pcap에&amp;nbsp;대한&amp;nbsp;패킷&amp;nbsp;흐름&amp;nbsp;쫒아감&lt;/p&gt;
&lt;pre id=&quot;code_1733760626668&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;구현 언어 : C
사용한 라이브러리 : libtase2
동작 플랫폼 : Ubuntu&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;client.c, server.c 코드는 비공개&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1) server.c&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(코드)&lt;/p&gt;
&lt;pre id=&quot;code_1733760676807&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;- VCC구성
	- buffer, IndicatePoint(내부 변수 및 state), Command등 등록
	- DS Transfer
	  =&amp;gt; report할 때 어떤 정보를 내보낼 것인가?
- Biteral tables
	- 접근하는 ap에 따라서 어떤 IndicatePoint나 command에 접근하게 할껀지 정의

- 일정시간이 지날때마다 정의된 코드 수행&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(2) client.c&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(코드)&lt;/p&gt;
&lt;pre id=&quot;code_1733760702744&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(setting)
- AP Setting
- handler 함수

(initial)
- server ip, apTitle을 통해 연결시도
- 연결된 서버의 내부 정보 인식
- IM TransferSet
  =&amp;gt; Report 정보
- 기존에 있던 DataSet삭제 후 재정의

(Read Value)
- domain에서 얻은 DataSet에서 얻은 데이터들을 출력&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(3) 동작 패킷 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; client, server의 통신내역 캡쳐(pcap)&lt;/p&gt;
&lt;pre id=&quot;code_1733760739201&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. TCP SYN, ACK
2. COTP SYN,ACK
3. ASCE 
4. MMS
	- TASE.Version, Support Feature 값에 대한 요청
	- identify(MZ automation, TASE.2, 2.3.0) 값 요청
	- IM_Transfer_Set설정(report용)
	- read동작전 이전 DataSet 및 재정의
	- domain요청후 내부 가상변수가 무엇인지 반환
	- 각 가상변수에 해당하는 값 반환
5. TCP FIN, ACK&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. ICCP의 보안요소&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-1. 기존의 ICCP&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Biteral Table을 이용한 데이터 접근 제어만을 보안요소로 가지고 있다.&lt;/li&gt;
&lt;li&gt;그래서 데이터 위/변조, 데이터 유출과 같은 문제에 대한 대응책이 없음&lt;/li&gt;
&lt;li&gt;보안에 취약하기 때문에 일부 Secure ICCP를 제공(암호화, 인증)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-2. Secure ICCP&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SSL/TLS가 데이터 위/변조 혹은 데이터 유출과 같은 보안 위협에 대응책으로 사용됨&lt;/li&gt;
&lt;li&gt;하지만 복호화하는 과정에서 키를 알고 있어야하기 때문에 &quot;키 교환에 대한 문제점&quot;이 존재&lt;/li&gt;
&lt;li&gt;그래서 &quot;키 교환 과정&quot;에서 공개키-개인키가 쓰인다.&lt;/li&gt;
&lt;li&gt;정상적인 제어센터인지 파악을 위해서 X.509를 적용한 인증서 기반의 인증을 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-3. 추가 고려해야할 보안요소&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ICCP 통신과정에서 &quot;하위계층&quot; 보안 취약점
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ex) 2006년 퍼징으로 COTP, TPKT의 보안 취약점&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;&lt;span&gt;&amp;nbsp;키&lt;/span&gt;관리의 어려움&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;실제 출시되는 ICCP제품의 경우 Secure ICCP가 지원하지 않거나, 일부만 지원하여 다른 보안 요소가 정상적으로 동작하여도 안전성을 보장받을 수 없다.&lt;/li&gt;
&lt;li&gt;적용되는 보안 기술이 구 버전의 보안기술일 경우 문제점이 있을 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-4. 대응책&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ICCP의 보안에 관련된 표준 IEC 62531이 존재하지만 Secure ICCP 제품마다 조금씩 다른 보안기술이 적용되고 있다.&lt;/li&gt;
&lt;li&gt;(보안기술)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SSL/TLS, 인증서, 공개키-개인키&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;(인증)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일부 장치가 ICCP 프로토콜을 지원해도 인프라 부재시 사용할 수 없기 때문에 인프라가 필요하다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;(하위계층 보안고려)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2006년 이후 COTP, TPKT에서 새로 발혀진 취약점은 존재하지 않지만&lt;/li&gt;
&lt;li&gt;하위 게층에서 이용되는 프로토콜의 취약점 여부는 지속적인 확인이 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>OT Security</category>
      <category>iccp</category>
      <category>OT</category>
      <category>protocol</category>
      <category>전력망</category>
      <author>Greedun (lr-x-dl)</author>
      <guid isPermaLink="true">https://greedun.tistory.com/119</guid>
      <comments>https://greedun.tistory.com/119#entry119comment</comments>
      <pubDate>Tue, 10 Dec 2024 00:53:18 +0900</pubDate>
    </item>
    <item>
      <title>Ubuntu에서 바이너리 작게 만드는 musl-gcc 컴파일러 설치</title>
      <link>https://greedun.tistory.com/113</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1.&amp;nbsp;musl이란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스&amp;nbsp;커널&amp;nbsp;기반의&amp;nbsp;운영체제용으로&amp;nbsp;고안된&amp;nbsp;표준&amp;nbsp;라이브러리이다.&lt;br /&gt;표준을&amp;nbsp;준수하는&amp;nbsp;libc&amp;nbsp;구현체를&amp;nbsp;개발하는&amp;nbsp;것을&amp;nbsp;목적으로&amp;nbsp;개발했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(특징)&lt;/b&gt;&lt;br /&gt;-&amp;nbsp;가볍고&amp;nbsp;빠르며&amp;nbsp;간단하고&amp;nbsp;무료이다.&lt;br /&gt;-&amp;nbsp;표준&amp;nbsp;준수하고&amp;nbsp;안정성&amp;nbsp;측면에서&amp;nbsp;정확성을&amp;nbsp;추구&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. musl-gcc&amp;nbsp;설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex)&lt;/p&gt;
&lt;pre id=&quot;code_1729338787626&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// test.c
#include &amp;lt;stdio.h&amp;gt;

int main(){
	printf(&quot;Hello World\n&quot;);
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴파일할&amp;nbsp;코드는&amp;nbsp;c언어를&amp;nbsp;접했다면&amp;nbsp;한번쯤은&amp;nbsp;봤을&amp;nbsp;hello코드이다.&lt;br /&gt;&lt;br /&gt;musl.cc&amp;nbsp;바이너리들이&amp;nbsp;모여있는&amp;nbsp;아래&amp;nbsp;링크에서&amp;nbsp;원하는&amp;nbsp;아키텍처에&amp;nbsp;따라&amp;nbsp;다운&amp;nbsp;받으면&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(&lt;a href=&quot;http://musl.cc/#binaries)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;http://musl.cc/#binaries)&lt;/a&gt;&lt;br /&gt;-&amp;nbsp;x86_64&amp;nbsp;:&amp;nbsp;&quot;x86_64-linux-musl-native.tgz&quot;&lt;br /&gt;-&amp;nbsp;arm&amp;nbsp;:&amp;nbsp;&quot;aarch64-linux-musl-cross.tgz&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) x86_64환경&lt;/p&gt;
&lt;pre id=&quot;code_1729338814356&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ wget http://musl.cc/x86_64-linux-musl-native.tgz
$ tar -xvf x86_64-linux-musl-native.tgz

$ ls x86_64-linux-musl-native
bin  include  lib  libexec  share  usr  x86_64-linux-musl

$ x86_64-linux-musl-native/bin/gcc -o test test.c
$ ls 
test  test.c  x86_64-linux-musl-native  x86_64-linux-musl-native.tgz&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위&amp;nbsp;과정을&amp;nbsp;거치면&amp;nbsp;musl을&amp;nbsp;이용하는&amp;nbsp;gcc로&amp;nbsp;test.c를&amp;nbsp;컴파일하여&amp;nbsp;test바이너리가&amp;nbsp;만들어기게&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1729338846863&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ ./test
bash: ./test: No such file or directory

$ file test
test: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, not stripped
$ ldd test
./test: error while loading shared libraries: /lib/x86_64-linux-gnu/libc.so: invalid ELF header&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;test바이너리를&amp;nbsp;실행했을때&amp;nbsp;분명&amp;nbsp;파일이&amp;nbsp;있지만&amp;nbsp;없는&amp;nbsp;바이너리라고&amp;nbsp;표시된다.&lt;br /&gt;&lt;br /&gt;그래서&amp;nbsp;추가적으로&amp;nbsp;file,&amp;nbsp;ldd명령어를&amp;nbsp;확인했는데&amp;nbsp;다음과&amp;nbsp;같이&amp;nbsp;에러가&amp;nbsp;발생했다.&lt;br /&gt;일단&amp;nbsp;이유로는&amp;nbsp;dynamic&amp;nbsp;바이너리&amp;nbsp;이기&amp;nbsp;때문에&amp;nbsp;libc파일을&amp;nbsp;시스템에서&amp;nbsp;자동으로&amp;nbsp;찾게&amp;nbsp;되는데&amp;nbsp;그&amp;nbsp;과정에서&amp;nbsp;glibc를&amp;nbsp;가르켜서&amp;nbsp;생긴&amp;nbsp;문제라고&amp;nbsp;ldd명령어로&amp;nbsp;추측했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 에러사항 해결&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서&amp;nbsp;여러&amp;nbsp;실험으로&amp;nbsp;해결한&amp;nbsp;방법은&amp;nbsp;다음과&amp;nbsp;같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;1 - 다운받은 폴더의 bin폴더까지 들어가서 gcc바이너리 이용&lt;br /&gt;2 - dynamic 방식이 아닌 static 옵션으로 staic바이너리로 컴파일 하기&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-1. 내부에&amp;nbsp;bin폴더로&amp;nbsp;들어간뒤&amp;nbsp;gcc바이너리&amp;nbsp;이용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(2)번링크&amp;nbsp;블로그를&amp;nbsp;참조하면&amp;nbsp;내부에&amp;nbsp;bin폴더를&amp;nbsp;들어가서&amp;nbsp;gcc컴파일을&amp;nbsp;하는&amp;nbsp;것을&amp;nbsp;보고&amp;nbsp;처음에는&amp;nbsp;확실하게&amp;nbsp;그&amp;nbsp;바이너리를&amp;nbsp;쓸려고&amp;nbsp;저렇게&amp;nbsp;하는거나&amp;nbsp;생각했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1729338950983&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ cd x86_64-linux-musl-native/bin 
$ ./gcc -o test test.c

$ ./test
Hello World&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만&amp;nbsp;방법을&amp;nbsp;찾기&amp;nbsp;위해&amp;nbsp;여러가지&amp;nbsp;시도해&amp;nbsp;보던&amp;nbsp;중&amp;nbsp;설마하고&amp;nbsp;해봤는데&amp;nbsp;dynamic방식,&amp;nbsp;static방식으로&amp;nbsp;컴파일한&amp;nbsp;바이너리가&amp;nbsp;둘다&amp;nbsp;정상적으로&amp;nbsp;실행되는거&amp;nbsp;보면서&amp;nbsp;이유가&amp;nbsp;있었구나라는&amp;nbsp;것을&amp;nbsp;깨달았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1729338978641&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ file test
test: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=7bd8ff67bf97268f97ddde0a9fe1162f67b07bb9, for GNU/Linux 3.2.0, not stripped

$ ldd test
        linux-vdso.so.1 (0x00007ffce7b65000)
        libc.so.6 =&amp;gt; /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4807a00000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f4807c68000)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저런&amp;nbsp;방식으로&amp;nbsp;했을때&amp;nbsp;왜&amp;nbsp;실행이&amp;nbsp;되는지를&amp;nbsp;한번&amp;nbsp;생각해봤다.&lt;br /&gt;이전에&amp;nbsp;외부에서&amp;nbsp;musl-gcc를&amp;nbsp;실행했을때는&amp;nbsp;없던&amp;nbsp;BuildID가&amp;nbsp;생기고&amp;nbsp;ldd명령어도&amp;nbsp;정상적으로&amp;nbsp;확인이&amp;nbsp;가능하다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신기한&amp;nbsp;일이다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1729338996994&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;x86_64-linux-musl-native/bin$ ls ../
bin  include  lib  libexec  share  test  usr  x86_64-linux-musl&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가적인&amp;nbsp;이유로&amp;nbsp;x86_64-linux-musl-native란&amp;nbsp;폴더가&amp;nbsp;기존&amp;nbsp;우분투&amp;nbsp;시스템&amp;nbsp;안에&amp;nbsp;또다른&amp;nbsp;작은&amp;nbsp;시스템을&amp;nbsp;필요한&amp;nbsp;파일들만&amp;nbsp;갖추고&amp;nbsp;형성한&amp;nbsp;것이라고&amp;nbsp;추측한다.&lt;br /&gt;&lt;br /&gt;그래서&amp;nbsp;&quot;/usr/bin/musl-gcc&quot;로&amp;nbsp;바이너리를&amp;nbsp;카피해서&amp;nbsp;쓰거나&amp;nbsp;내부의&amp;nbsp;bin폴더를&amp;nbsp;외부에서&amp;nbsp;접근해서&amp;nbsp;컴파일&amp;nbsp;시도하면&amp;nbsp;필요한&amp;nbsp;파일들을&amp;nbsp;찾지&amp;nbsp;못하여&amp;nbsp;링킹과정이&amp;nbsp;불완전해지고&amp;nbsp;실행이&amp;nbsp;안되지&amp;nbsp;않을까&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-2. static&amp;nbsp;옵션으로&amp;nbsp;staic바이너리로&amp;nbsp;컴파일&amp;nbsp;하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두번째&amp;nbsp;방법은&amp;nbsp;원래&amp;nbsp;이&amp;nbsp;방식으로&amp;nbsp;컴파일하던&amp;nbsp;목적이&amp;nbsp;커널&amp;nbsp;익스를&amp;nbsp;위한&amp;nbsp;바이너리를&amp;nbsp;만들기&amp;nbsp;위해서&amp;nbsp;였기&amp;nbsp;때문에&amp;nbsp;static방식으로&amp;nbsp;컴파일&amp;nbsp;했어야&amp;nbsp;했다.&lt;br /&gt;&lt;br /&gt;ldd명령어로&amp;nbsp;라이브러리&amp;nbsp;링킹과정에서&amp;nbsp;문제가&amp;nbsp;발생했다는&amp;nbsp;것을&amp;nbsp;확인했기&amp;nbsp;때문에&amp;nbsp;static방식으로&amp;nbsp;컴파일하면&amp;nbsp;이&amp;nbsp;문제를&amp;nbsp;피할&amp;nbsp;수&amp;nbsp;있다고&amp;nbsp;판단했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1729339027772&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ x86_64-linux-musl-native/bin/gcc -o test test.c --static
$ ./test
Hello World&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;static바이너리로&amp;nbsp;컴파일&amp;nbsp;시도후&amp;nbsp;실행을&amp;nbsp;해봤고&amp;nbsp;다행히&amp;nbsp;잘&amp;nbsp;실행되는&amp;nbsp;것을&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-3. 우분투&amp;nbsp;시스템으로&amp;nbsp;바이너리&amp;nbsp;복제시&amp;nbsp;에러사항&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매번&amp;nbsp;musl-gcc의&amp;nbsp;폴더안에&amp;nbsp;gcc바이너리를&amp;nbsp;찾고&amp;nbsp;실행구문이&amp;nbsp;길어지는&amp;nbsp;것은&amp;nbsp;비효율적이라&amp;nbsp;생각해서&amp;nbsp;&quot;/usr/bin/musl-gcc&quot;경로로&amp;nbsp;gcc&amp;nbsp;바이너리를&amp;nbsp;복사하고&amp;nbsp;컴파일&amp;nbsp;시도를&amp;nbsp;해봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1729339060128&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ sudo cp x86_64-linux-musl-native/bin/gcc /usr/bin/musl-gcc

$ musl-gcc -o test2 test.c
musl-gcc: fatal error: cannot execute &amp;lsquo;cc1&amp;rsquo;: execvp: No such file or directory
compilation terminated.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴파일&amp;nbsp;시도를&amp;nbsp;하자마자&amp;nbsp;한번도&amp;nbsp;보지&amp;nbsp;못한&amp;nbsp;에러가&amp;nbsp;발생했다.&lt;br /&gt;여태껏&amp;nbsp;gcc컴파일하면&amp;nbsp;한번도&amp;nbsp;본적이&amp;nbsp;없는&amp;nbsp;에러라&amp;nbsp;뭔가&amp;nbsp;싶었고&amp;nbsp;이대로&amp;nbsp;그냥&amp;nbsp;매번&amp;nbsp;컴파일&amp;nbsp;할때마다&amp;nbsp;경로를&amp;nbsp;찾아야하나&amp;nbsp;싶었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1729339073197&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ cp -r x86_64-linux-musl-native ~/
$ sudo ln -s /home/greedun/x86_64-linux-musl-native/bin/x86_64-linux-musl-gcc /usr/bin/musl-gcc

$ musl-gcc -o test2 test.c --static
$ ./test2
Hello World&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러다&amp;nbsp;마지막으로&amp;nbsp;시도해보자&amp;nbsp;한&amp;nbsp;방법은&amp;nbsp;심볼릭&amp;nbsp;링크를&amp;nbsp;이용한&amp;nbsp;방법이다.&lt;br /&gt;임베디드&amp;nbsp;시스템이나&amp;nbsp;다른&amp;nbsp;시스템을&amp;nbsp;들어가서&amp;nbsp;확인해보면&amp;nbsp;은근&amp;nbsp;심볼릭&amp;nbsp;링크된&amp;nbsp;처리가&amp;nbsp;많다는&amp;nbsp;것이&amp;nbsp;생각났다.&lt;br /&gt;home폴더로 다운받은 내용들을 옮기고 거기로 &quot;/usr/bin/musl-gcc&quot;란 심볼릭링크를 생성하고 내부에 gcc바이너리를 가르키게 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. glibc,&amp;nbsp;musl방식의&amp;nbsp;용량&amp;nbsp;차이&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-10-19 20.42.36.png&quot; data-origin-width=&quot;740&quot; data-origin-height=&quot;126&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/duldBs/btsKcPNjj57/0oGc7sg4hCMKIlOvttmyDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/duldBs/btsKcPNjj57/0oGc7sg4hCMKIlOvttmyDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/duldBs/btsKcPNjj57/0oGc7sg4hCMKIlOvttmyDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FduldBs%2FbtsKcPNjj57%2F0oGc7sg4hCMKIlOvttmyDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;68&quot; data-filename=&quot;스크린샷 2024-10-19 20.42.36.png&quot; data-origin-width=&quot;740&quot; data-origin-height=&quot;126&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;musl-gcc(static)보다&amp;nbsp;musl-gcc(dynamic)가&amp;nbsp;크기가&amp;nbsp;크게&amp;nbsp;나왔는데.....&lt;br /&gt;(2)번&amp;nbsp;참조한&amp;nbsp;블로그에서도&amp;nbsp;그렇고&amp;nbsp;내&amp;nbsp;지식으로도&amp;nbsp;static의&amp;nbsp;크기가&amp;nbsp;적게&amp;nbsp;나오는게&amp;nbsp;맞는데....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1729339144540&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;greedun@lr-x-dl:~/RD/kernel/musl_test$ file musl_sta
musl_sta: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), static-pie linked, not stripped

greedun@lr-x-dl:~/RD/kernel/musl_test$ file musl_dyn 
musl_dyn: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=7bd8ff67bf97268f97ddde0a9fe1162f67b07bb9, for GNU/Linux 3.2.0, not stripped

greedun@lr-x-dl:~/RD/kernel/musl_test$ file glibc_sta
glibc_sta: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=8c75dfa1d4c5c748220f2b4cbcb54bbcf3270af1, for GNU/Linux 3.2.0, not stripped

greedun@lr-x-dl:~/RD/kernel/musl_test$ file glibc_dyn
glibc_dyn: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=7bd8ff67bf97268f97ddde0a9fe1162f67b07bb9, for GNU/Linux 3.2.0, not stripped&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서&amp;nbsp;추가적으로&amp;nbsp;file로&amp;nbsp;실수로&amp;nbsp;dynamic으로&amp;nbsp;컴파일을&amp;nbsp;시도했나&amp;nbsp;했지만&amp;nbsp;file명령어로&amp;nbsp;봤을때는&amp;nbsp;static으로&amp;nbsp;컴파일&amp;nbsp;한거&amp;nbsp;같았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(+) 해결은 아니지만 달라진점&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;위에서&amp;nbsp;다운받은&amp;nbsp;폴더&amp;nbsp;밖에서&amp;nbsp;수행하면&amp;nbsp;glibc가&amp;nbsp;링킹&amp;nbsp;시도하여&amp;nbsp;바이너리&amp;nbsp;실행시&amp;nbsp;파일이&amp;nbsp;없다고&amp;nbsp;하는&amp;nbsp;문제가&amp;nbsp;있었다는&amp;nbsp;생각에&amp;nbsp;혹시나해서&amp;nbsp;내부에서&amp;nbsp;static컴파일&amp;nbsp;시도를&amp;nbsp;해봤다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-10-19 20.45.42.png&quot; data-origin-width=&quot;734&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d24bkI/btsKbLZdzZ4/yYBOMwES5NHOX2WXeY8BI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d24bkI/btsKbLZdzZ4/yYBOMwES5NHOX2WXeY8BI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d24bkI/btsKbLZdzZ4/yYBOMwES5NHOX2WXeY8BI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd24bkI%2FbtsKbLZdzZ4%2FyYBOMwES5NHOX2WXeY8BI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;120&quot; data-filename=&quot;스크린샷 2024-10-19 20.45.42.png&quot; data-origin-width=&quot;734&quot; data-origin-height=&quot;220&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그랬더니&amp;nbsp;static컴파일&amp;nbsp;하는&amp;nbsp;과정에서&amp;nbsp;glibc가&amp;nbsp;가져와서&amp;nbsp;컴파일되어&amp;nbsp;용량이&amp;nbsp;dynamic과&amp;nbsp;비슷하진것이었다.&lt;br /&gt;&lt;br /&gt;내부에서&amp;nbsp;컴파일을&amp;nbsp;시도해보니&amp;nbsp;용량이&amp;nbsp;오히려&amp;nbsp;더&amp;nbsp;작아졌다.&lt;br /&gt;의문점이&amp;nbsp;해결된&amp;nbsp;것은&amp;nbsp;아니지만&amp;nbsp;나중에&amp;nbsp;해결의&amp;nbsp;실마리가&amp;nbsp;될&amp;nbsp;수&amp;nbsp;있기&amp;nbsp;때문에&amp;nbsp;적어놓겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;참고링크&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1)&amp;nbsp;&lt;a href=&quot;https://musl.libc.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://musl.libc.org/&lt;/a&gt;&lt;br /&gt;=&amp;gt;&amp;nbsp;공식&amp;nbsp;사이트&lt;br /&gt;&lt;br /&gt;(2)&amp;nbsp;&lt;a href=&quot;https://zshchun.github.io/posts/musl-gcc%EB%A1%9C-%EB%B9%8C%EB%93%9C%ED%95%98%EA%B8%B0/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://zshchun.github.io/posts/musl-gcc%EB%A1%9C-%EB%B9%8C%EB%93%9C%ED%95%98%EA%B8%B0/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;(3)&amp;nbsp;&lt;a href=&quot;https://www.freecodecamp.org/korean/news/rinugseu-symlink-tyutorieol-simbolrig-ringkeu-symbolic-link-reul-saengseonghago-sagjehaneun-bangbeob/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.freecodecamp.org/korean/news/rinugseu-symlink-tyutorieol-simbolrig-ringkeu-symbolic-link-reul-saengseonghago-sagjehaneun-bangbeob/&lt;/a&gt;&lt;br /&gt;=&amp;gt;&amp;nbsp;심볼릭&amp;nbsp;링크&amp;nbsp;생성&lt;br /&gt;&lt;br /&gt;(4)&amp;nbsp;&lt;a href=&quot;https://ko.wikipedia.org/wiki/Musl&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ko.wikipedia.org/wiki/Musl&lt;/a&gt;&lt;br /&gt;=&amp;gt;&amp;nbsp;musl에&amp;nbsp;대한&amp;nbsp;위키백과&lt;br /&gt;&lt;br /&gt;(5)&amp;nbsp;&lt;a href=&quot;http://musl.cc/#binaries&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;http://musl.cc/#binaries&lt;/a&gt;&lt;br /&gt;=&amp;gt;&amp;nbsp;musl.cc&amp;nbsp;바이너리들&amp;nbsp;모여있는&amp;nbsp;곳&lt;/p&gt;</description>
      <category>Pwnable/Kernel</category>
      <category>compile</category>
      <category>Kernel</category>
      <category>musl</category>
      <category>musl-gcc</category>
      <author>Greedun (lr-x-dl)</author>
      <guid isPermaLink="true">https://greedun.tistory.com/113</guid>
      <comments>https://greedun.tistory.com/113#entry113comment</comments>
      <pubDate>Sat, 19 Oct 2024 21:03:00 +0900</pubDate>
    </item>
    <item>
      <title>[Tip] 맥북에서 usb시리얼 통신하는 법</title>
      <link>https://greedun.tistory.com/112</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. serial통신 터미널 연결&lt;/h2&gt;
&lt;pre id=&quot;code_1728467144739&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1 - usb연결 수 /dev에서 찾기
2 - screen명령어를 통해 터미널로 접속&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1) usb연결 후 /dev에서 찾기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/dev 폴더에 &quot;ls /dev/*usb*&quot;를 했을 때 처음에는 아무것도 표시가 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 usb를 연결한 이후에 다시 확인하면 (사진1)과 같이 새로운 표시된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Tip_serial_1.png&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;120&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BhImQ/btsJZkttFMa/LMYTqKSdvlWFdCkJJTpk4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BhImQ/btsJZkttFMa/LMYTqKSdvlWFdCkJJTpk4k/img.png&quot; data-alt=&quot;(사진1) serial포트 연결&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BhImQ/btsJZkttFMa/LMYTqKSdvlWFdCkJJTpk4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBhImQ%2FbtsJZkttFMa%2FLMYTqKSdvlWFdCkJJTpk4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;65&quot; data-filename=&quot;Tip_serial_1.png&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;120&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(사진1) serial포트 연결&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- cu : 시리얼 통신에 사용되는 컨트롤러를 의미&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- tty : 시리얼 장치의 터미널을 의미&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(2) screen명령어를 통해 터미널로 접속&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;screen [tty.로 시작하는 파일명] [시리얼 통신 속도]&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;를 통해 터미널에 접속할 수 있다.&lt;br /&gt;&amp;lt;윈도우의 경우 putty프로그램을 쓰면 쉽게 접속할 수 있다.&amp;gt;&lt;/p&gt;
&lt;pre id=&quot;code_1728467417429&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;screen /dev/tty.usbserial-0001 115200&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1728467562663&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[시리얼 통신 속도]
- 데이터가 전송되는 속도를 비트 단위로 나타낸다.
- 초당 전송되는 비트의 수를 나타내는데 장비마다 지원하는 속도가 다르다.
- 따라서 통신할 장비의 사양에 고려한 적절한 속도를 찾아야한다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. screen 명령어&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로도 이 작업을 할 떄 유용한 명령어에 관해서 정리해두려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1728467607840&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 스크린 생성
screen -S {지정할 이름} /dev/tty.usbserial-0001 115200

# 스크린 나열
screen -ls

# 스크린 삭제
screen -X -S {스크린 이름} Kill

# 스크린을 계속 돌리는 상태에서 원래 터미널로 돌아가는 명령어(deattach)
control + a + d

# 스크린 재진입
screen -r {스크린 이름}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고링크&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1&amp;nbsp;-&amp;nbsp;&lt;a href=&quot;https://seaotter.tistory.com/106&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://seaotter.tistory.com/106&lt;/a&gt;&lt;br /&gt;=&amp;gt;&amp;nbsp;맥북에서&amp;nbsp;usb2시리얼&amp;nbsp;통신&lt;br /&gt;2&amp;nbsp;-&amp;nbsp;&lt;a href=&quot;https://daje0601.tistory.com/325&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://daje0601.tistory.com/325&lt;/a&gt;&lt;br /&gt;=&amp;gt;&amp;nbsp;screen&amp;nbsp;명령어&amp;nbsp;사용법&lt;/p&gt;</description>
      <category>환경구축 &amp;amp; Tip/Etc</category>
      <category>screen명령어</category>
      <category>Serial통신</category>
      <category>맥북 serial통신</category>
      <author>Greedun (lr-x-dl)</author>
      <guid isPermaLink="true">https://greedun.tistory.com/112</guid>
      <comments>https://greedun.tistory.com/112#entry112comment</comments>
      <pubDate>Wed, 9 Oct 2024 18:54:38 +0900</pubDate>
    </item>
    <item>
      <title>Shellcoding</title>
      <link>https://greedun.tistory.com/94</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Shellcoding란?&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-1. 개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(Shellcode란?)&lt;br /&gt;익스플로잇을&amp;nbsp;위해&amp;nbsp;제작된&amp;nbsp;어셈블리&amp;nbsp;코드&amp;nbsp;조각이다.&lt;br /&gt;어셈블리어와&amp;nbsp;기계어&amp;nbsp;코드는&amp;nbsp;일대일&amp;nbsp;대응이기&amp;nbsp;때문에&amp;nbsp;공격자가&amp;nbsp;rip를&amp;nbsp;주입한&amp;nbsp;shellcode로&amp;nbsp;옮긴다면&amp;nbsp;cpu에게&amp;nbsp;원하는&amp;nbsp;명령을&amp;nbsp;하도록&amp;nbsp;유도할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;[shellcode작성법을 알아야하는 이유]&lt;br /&gt;수행할 대상의 아키텍처와 운영체제 그리고 수행 목적에 따라 어셈블리어는 다르게 작성되어야 한다. &lt;br /&gt;&lt;br /&gt;아키텍처별로 자주 사용하는 쉘코드를 공유하는 사이트가 있지만 &lt;br /&gt;해당 쉘코드들은 범용적으로 작성되었기 때문에 제대로 작동이 안 될 가능성이 있다. &lt;br /&gt;&lt;br /&gt;따라서 타겟 시스템에 맞는 최적의 쉘코드를 상황에 따라서 언제든지 작성할 수 있어야한다. &lt;br /&gt;&lt;br /&gt;=&amp;gt; 쉘코드 모음 사이트 : http://shell-storm.org/shellcode/index.html&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(기계어 변환 과정)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwnable_shellcoding_Fig1.png&quot; data-origin-width=&quot;1624&quot; data-origin-height=&quot;558&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bh4Ihk/btsIUKN4be3/QCs3WUVyY8FaHA51M2jDpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bh4Ihk/btsIUKN4be3/QCs3WUVyY8FaHA51M2jDpk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bh4Ihk/btsIUKN4be3/QCs3WUVyY8FaHA51M2jDpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbh4Ihk%2FbtsIUKN4be3%2FQCs3WUVyY8FaHA51M2jDpk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1624&quot; height=&quot;558&quot; data-filename=&quot;pwnable_shellcoding_Fig1.png&quot; data-origin-width=&quot;1624&quot; data-origin-height=&quot;558&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;현재 사용중인 프로그램은 고수준의 언어가 컴파일 과정을 거쳐서 Assembly, Machine code같은 저수준 언어로 변경된 것이다.&lt;/li&gt;
&lt;li&gt;이렇게 변환된 Machine code는 실행시 메모리에 올라가서 코드를 실행하게 된다.&lt;/li&gt;
&lt;li&gt;어셈블리어와 기계어코드는 일대일대응이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-2. Syscall&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;[필요한 사전지식]&lt;br /&gt;- 레지스터 bit별 표현단위 &lt;br /&gt;- 어셈블리어 &lt;br /&gt;- 함수호출규약&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;assembly&amp;nbsp;code에서&amp;nbsp;시스템&amp;nbsp;함수를&amp;nbsp;호출하기&amp;nbsp;위해&amp;nbsp;&quot;int&amp;nbsp;0x80&quot;(32),&amp;nbsp;&quot;syscall&quot;(32,64)명령어를&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(system&amp;nbsp;call&amp;nbsp;번호&amp;nbsp;확인)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwnable_shellcoding_Fig2.png&quot; data-origin-width=&quot;1512&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bimIB5/btsIV90DBeN/xntJSKyM601BQTgn9KfVNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bimIB5/btsIV90DBeN/xntJSKyM601BQTgn9KfVNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bimIB5/btsIV90DBeN/xntJSKyM601BQTgn9KfVNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbimIB5%2FbtsIV90DBeN%2FxntJSKyM601BQTgn9KfVNK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1512&quot; height=&quot;418&quot; data-filename=&quot;pwnable_shellcoding_Fig2.png&quot; data-origin-width=&quot;1512&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;32bit - /usr/include/x86_64-linux-gnu/asm/unistd_32.h &lt;br /&gt;64bit - /usr/include/x86_64-linux-gnu/asm/unistd_64.h&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;system&amp;nbsp;call&amp;nbsp;정보는&amp;nbsp;운영체제,&amp;nbsp;프로세서의&amp;nbsp;아키텍처마다&amp;nbsp;다르기&amp;nbsp;때문에&amp;nbsp;맞춰서&amp;nbsp;작성해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(system&amp;nbsp;call&amp;nbsp;인자&amp;nbsp;전달)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pwnable_shellcoding_Fig3.png&quot; data-origin-width=&quot;1822&quot; data-origin-height=&quot;334&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQJRbr/btsIWgk1y3H/kPbkkWlPOPfVoosXZjGFUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQJRbr/btsIWgk1y3H/kPbkkWlPOPfVoosXZjGFUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQJRbr/btsIWgk1y3H/kPbkkWlPOPfVoosXZjGFUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQJRbr%2FbtsIWgk1y3H%2FkPbkkWlPOPfVoosXZjGFUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1822&quot; height=&quot;334&quot; data-filename=&quot;pwnable_shellcoding_Fig3.png&quot; data-origin-width=&quot;1822&quot; data-origin-height=&quot;334&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-3. asm파일의&amp;nbsp;바이너리&amp;nbsp;변환&amp;nbsp;과정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[32bit&amp;nbsp;-&amp;nbsp;ASM32.asm]&lt;/p&gt;
&lt;pre id=&quot;code_1722926557724&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;section .data                           ; 데이터 세그먼트
    msg db  &quot;Hello, world!&quot;,0x0a, 0x0d  ; 문자열과 새 줄 문자, 개행 문자 바이트
  
section .text                           ; 텍스트 세그먼트
    global  _start                      ; ELF 링킹을 위한 초기 엔트리 포인트
  
_start:
    ; SYSCALL: write(1,msg,14)
    mov eax, 4      ; 쓰기 시스템 콜의 번호 '4' 를 eax 에 저장합니다.
    mov ebx, 1      ; 표준 출력를 나타내는 번호 '1'을 ebx에 저장합니다.
    mov ecx, msg    ; 문자열 주소를 ecx에 저장니다.
    mov edx, 14     ; 문자열의 길이 '14'를 edx에 저장합니다.
    int 0x80        ; 시스템 콜을 합니다.
  
    ; SYSCALL: exit(0)
    mov eax, 1      ; exit 시스템 콜의 번호 '1'을 eax 에 저장합니다.
    mov ebx, 0      ; 정상 종료를 의미하는 '0'을 ebx에 저장 합니다.
    int 0x80        ; 시스템 콜을 합니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt;&amp;nbsp;32,&amp;nbsp;64bit&amp;nbsp;asm의&amp;nbsp;차이점은&amp;nbsp;인자전달에&amp;nbsp;사용되는&amp;nbsp;레지스터와&amp;nbsp;시스템&amp;nbsp;콜&amp;nbsp;번호이기&amp;nbsp;때문에&lt;br /&gt;asm코드는&amp;nbsp;32bit만&amp;nbsp;작성해두겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(Build)&lt;/p&gt;
&lt;pre id=&quot;code_1722926590119&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(32bit)
$ nasm -f elf ASM32.asm
$ ld -m elf_i386 -o hello ASM32.o

$ ./hello
Hello, world!

$ file ./hello
`./hello: ELF`&amp;nbsp;`32``-bit LSB executable, Intel`&amp;nbsp;`80386``, version`&amp;nbsp;`1`&amp;nbsp;`(SYSV), statically linked, not stripped`


(64bit)
$ nasm -f elf64 ASM64.asm
$ ld -o hello64 ASM64.o

$ ./hello64
hello, world!

$ file ./hello64
./hello64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;f인자 : nasm으로 어셈블하여 ELF바이너리로 링크할 수 있는 목적(object)파일로 만든 것&lt;/li&gt;
&lt;li&gt;ld명령어 : 어셈블된 목적 파일에서 실행가능한 바이너리로 변환&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Shellcoding 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;(목적파일(.o)이 쉘코드가 안되는 이유) &lt;br /&gt;- 메모리 세그먼트를 사용 &lt;br /&gt;- 목적파일은 독립적으로 실행 가능한 프로그램이 아니라 &lt;br /&gt;- 링커에 의해 연결되어야 하는 프로그램의 일부이기 때문&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-1. 바이트 형태로 전달&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;(독자적으로 동작 가능하게끔 변경) &lt;br /&gt;- 텍스트, 데이터 세그먼트를 사용하지 않음 &lt;br /&gt;- 함수의 호출을 call명령어를 사용 &lt;br /&gt;- 함수에서 사용될 문자를 해당 명령어 뒤에 작성후 스택포인터 조절로 사용&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[32bit - ASM32.s]&lt;/p&gt;
&lt;pre id=&quot;code_1722926723292&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;BITS 32                         ; nasm에게 32비트 코드임을 알린다
  
call helloworld                 ; 아래 mark_below의 명령을 call한다.
db &quot;Hello, world!&quot;, 0x0a, 0x0d  ; 새 줄 바이트와 개행 문자 바이트
  
helloworld:
    ; ssize_t write(int fd, const void *buf, size_t count);
    pop ecx         ; 리턴 주소를 팝해서 exc에 저장합니다.
    mov eax, 4      ; 시스템 콜 번호를 씁니다.
    mov ebx, 1      ; STDOUT 파일 서술자
    mov edx, 15     ; 문자열 길이
    int 0x80        ; 시스템 콜: write(1,string, 14)
  
    ; void _exit(int status);
    mov eax,1       ;exit 시스템 콜 번호
    mov ebx,0       ;Status = 0
    int 0x80        ;시스템 콜: exit(0)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(build)&lt;/p&gt;
&lt;pre id=&quot;code_1722926742162&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ nasm ASM32.s
$ ndisasm -b32 ASM32&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(Test)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt;&amp;nbsp;python3에&amp;nbsp;쉘코드&amp;nbsp;바이트값&amp;nbsp;전달하여&amp;nbsp;수행&lt;/p&gt;
&lt;pre id=&quot;code_1722940572061&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# print bytecode
f = open('ASM32','r')
data = f.read()
print(data) # 바이트 값 출력&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1722940583056&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// shellcode.c
#include&amp;lt;stdio.h&amp;gt;
#include&amp;lt;string.h&amp;gt;
 
unsigned char shellcode [] = &quot;\xe8\x0f\x00\x00\x00Hello, world!\n\rY\
\xb8\x04\x00\x00\x00\xbb\x01\x00\x00\x00\xba\x0f\x00\x00\x00\xcd\x80\
\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80&quot;;
unsigned char code[];
 
void main(){
    int len = strlen(shellcode);
    printf(&quot;Shellcode len : %d\n&quot;,len);
    strcpy(code,shellcode);
    (*(void(*)()) code)();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(Build &amp;amp; Run)&lt;/p&gt;
&lt;pre id=&quot;code_1722940740618&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ gcc -o shellcode -fno-stack-protector -z execstack --no-pie -m32 shellcode.c
$ ./shellcode
Shellcode len : 2
Segmentation fault (core dumped)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt;&amp;nbsp;에러&amp;nbsp;발생????&lt;br /&gt;-&amp;gt;&amp;nbsp;문제의&amp;nbsp;원인&amp;nbsp;및&amp;nbsp;해결&amp;nbsp;방식은&amp;nbsp;아래&amp;nbsp;3번에서&amp;nbsp;서술&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(\x00이 제거된 asm코드)&lt;/p&gt;
&lt;pre id=&quot;code_1722940764833&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;BITS 32         ; nasm에게 32비트 코드임을 알린다
 
jmp short last  ; 맨 끝으로 점프한다.
helloworld:
    ; ssize_t write(int fd, const void *buf, size_t count);
    pop ecx     ; 리턴 주소를 팝해서 exc에 저장합니다.
    xor eax,eax ; eax 레지스터의 값을 0으로 초기화합니다.
    mov al, 4   ; 시스템 콜 번호를 씁니다.
    xor ebx,ebx ; ebx 레지스터의 값을 0으로 초기화합니다.
    mov bl, 1   ; STDOUT 파일 서술자
    xor edx,edx ; edx 레지스터의 값을 0으로 초기화합니다.
    mov dl, 15  ; 문자열 길지
    int 0x80    ; 시스템 콜: write(1,string, 14)
 
    ; void _exit(int status);
    mov al,1    ;exit 시스템 콜 번호
    xor ebx,ebx ;Status = 0
    int 0x80    ;시스템 콜: exit(0)
  
last:
    call helloworld ; 널 바이트를 해결하기 위해 위로 돌아간다.
    db &quot;Hello, world!&quot;, 0x0a, 0x0d  ; 새 줄 바이트와 개행 문자 바이트&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(Test)&lt;/p&gt;
&lt;pre id=&quot;code_1722940794212&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include&amp;lt;stdio.h&amp;gt;
#include&amp;lt;string.h&amp;gt;
 
unsigned char shellcode [] = &quot;\xeb\x15\x59\x31\xc0\xb0\x04\x31\xdb\xb3\
\x01\x31\xd2\xb2\x0f\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8\xe6\xff\xff\xff\
Hello, world!\n\r&quot;;
unsigned char code[] = &quot;&quot;;
 
void main()
{
    int len = strlen(shellcode);
    printf(&quot;Shellcode len : %d\n&quot;,len);
    strcpy(code,shellcode);
    (*(void(*)()) code)();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1722940807826&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ gcc -o shellcode2 -fno-stack-protector -z execstack --no-pie -m32 shellcode2.c
$ ./shellcode2
Shellcode len : 43
Hello, world!&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-2. 인라인 어셈&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;[순서]&amp;nbsp;&lt;br /&gt;1. 실행할 어셈블리어&amp;nbsp;&lt;br /&gt;2. 테스트할 c코드 작성&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(asm코드)&lt;/p&gt;
&lt;pre id=&quot;code_1722940855200&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;; write(1,&quot;Hello world!&quot;,12)
mov rax, 0x646c72
push rax
mov rax, 0x6f57206f6c6c6548
push rax
xor rdi, rdi
inc 0x1
mov rsi, rsp
xor rdx rdx
add rdx 0xc
xor rax, rax
int 1
syscall&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(c코드)&lt;/p&gt;
&lt;pre id=&quot;code_1722940873020&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// write(1, &quot;Hello world&quot;, 12);
// exit(0);
__asm__(
    &quot;.global run_sh\n&quot;
    &quot;run_sh:\n&quot;

    &quot;mov rax, 0x646c72\n&quot;
    &quot;push rax\n&quot;
    &quot;mov rax, 0x6f57206f6c6c6548\n&quot;
    &quot;push rax\n&quot;
    &quot;xor rdi, rdi\n&quot;
    &quot;inc rdi\n&quot;
    &quot;mov rsi, rsp\n&quot;
    &quot;xor rdx, rdx\n&quot;
    &quot;add rdx, 0xc\n&quot;
    &quot;xor rax, rax\n&quot;
    &quot;inc rax\n&quot;
    &quot;syscall\n&quot;
    &quot;\n&quot;
    &quot;xor rdi, rdi      # rdi = 0\n&quot;
    &quot;mov rax, 0x3c	   # rax = sys_exit\n&quot;
    &quot;syscall		   # exit(0)&quot;);

void run_sh();

int main() { run_sh(); }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(컴파일)&lt;/p&gt;
&lt;pre id=&quot;code_1722940887170&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ gcc -o test test.c -masm=intel
$ ./test
Hello World&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. Shellcode&amp;nbsp;작성시&amp;nbsp;주의사항&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(쉘코드에&amp;nbsp;0x00바이트가&amp;nbsp;들어가면&amp;nbsp;생기는&amp;nbsp;문제)&lt;br /&gt;-&amp;gt;&amp;nbsp;에러가&amp;nbsp;발생한&amp;nbsp;이유&amp;nbsp;:&amp;nbsp;쉘코드에&amp;nbsp;포함되어있는&amp;nbsp;0x00값&amp;nbsp;때문&lt;br /&gt;(문자열을&amp;nbsp;다루는&amp;nbsp;함수들은&amp;nbsp;문자열의&amp;nbsp;끝을&amp;nbsp;0x00으로&amp;nbsp;판단한다.)&lt;br /&gt;-&amp;gt;&amp;nbsp;따라서&amp;nbsp;쉘코드상에서&amp;nbsp;0x00을&amp;nbsp;제거하는&amp;nbsp;작업을&amp;nbsp;해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;[\x00 바이트 제거방법]&lt;br /&gt;1. jmp &quot;다른 함수&quot;&lt;br /&gt;2. mov 명령어&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(\x00 바이트 제거방법)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1) jmp&amp;nbsp;&quot;다른&amp;nbsp;함수&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;[null byte가 들어간 이유] &lt;br /&gt;call명령어의 피연산자에서 사용 가능한 값의 크기는 dword(32bits)이기 때문에 &lt;br /&gt;작은 값을 사용 될 경우 남는 부분에 null byte가 포함되게 된다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(해결법)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하단의 새로운 함수(a)를 생성&lt;/li&gt;
&lt;li&gt;jmp명령어를 사용해 해당 함수로 점프&lt;/li&gt;
&lt;li&gt;그리고 해당 함수에서는 원래 사용하려던 함수를 재호출한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(디스어셈블 확인)&lt;/p&gt;
&lt;pre id=&quot;code_1722940974963&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ nasm ASM32-2.s
$ ndisasm -b32 ASM32-2
00000000  EB1E              jmp short 0x20
00000002  59                pop ecx
00000003  B804000000        mov eax,0x4
00000008  BB01000000        mov ebx,0x1
0000000D  BA0F000000        mov edx,0xf
00000012  CD80              int 0x80
00000014  B801000000        mov eax,0x1
00000019  BB00000000        mov ebx,0x0
0000001E  CD80              int 0x80
00000020  E8DDFFFFFF        call dword 0x2
00000025  48                dec eax
00000026  656C              gs insb
00000028  6C                insb
00000029  6F                outsd
0000002A  2C20              sub al,0x20
0000002C  776F              ja 0x9d
0000002E  726C              jc 0x9c
00000030  64210A            and [fs:edx],ecx
00000033  0D                db 0x0d&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt;&amp;nbsp;컴파일된&amp;nbsp;어셈블리어를&amp;nbsp;보면&amp;nbsp;call명령어가&amp;nbsp;들어가&amp;nbsp;있음에도&amp;nbsp;null&amp;nbsp;byte가&amp;nbsp;제거된&amp;nbsp;것을&amp;nbsp;볼&amp;nbsp;수&amp;nbsp;있다.&lt;br /&gt;-&amp;gt;&amp;nbsp;제거된&amp;nbsp;이유는&amp;nbsp;음수이기&amp;nbsp;때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;jmp short 0x20로 주소 0x20으로 이동&lt;/li&gt;
&lt;li&gt;(jmp명령어의 피연산자에서 사용 가능한 값의 크기 dword(32bits))&lt;br /&gt;&amp;nbsp;&amp;nbsp;=&amp;gt; 사용 가능한 값의 크기 -128 ~ 127&lt;/li&gt;
&lt;li&gt;call명령어 helloworld함수를 호출하기 위해 -0x20으로(0x2-0x24)로 이동&lt;/li&gt;
&lt;li&gt;-0x22를 표현하기 위해 2의 보수로 값을 표현하게 된다.&lt;/li&gt;
&lt;li&gt;이 과정에서 null byte가 제거되게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(2) mov 명령어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(레지스터의&amp;nbsp;범위)&lt;br /&gt;64bit&amp;nbsp;-&amp;nbsp;8bit&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(레지스터&amp;nbsp;값을&amp;nbsp;초기화하는&amp;nbsp;방법)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;[레지스터 영역을 사용하기 전 초기화하는 이유] &lt;br /&gt;=&amp;gt; 쉘코드가 실행되기 이전의 레지스터의 값을 그대로 사용하기 때문 &lt;br /&gt;- 그럼 하위비트의 값만 변경한다면?&lt;br /&gt;&amp;nbsp; &amp;nbsp; -&amp;gt; 명령어마다 어떤 단위의 레지스터를 사용할지 다 알 수 없고. &lt;br /&gt;&amp;nbsp; &amp;nbsp; 그전에 존재하는 값들이 무엇인지 알 수도 없기때문에 0x00으로 초기화하는 것이 좋다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(해결법)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;1. sub명령어를 이용한 초기화 &lt;br /&gt;2. xor명령어를 이용한 초기화&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(어셈)&lt;/p&gt;
&lt;pre id=&quot;code_1722941113084&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;section .text
    global _start

_start:
    ; XOR을 사용하여 eax를 0으로 만들기
    mov eax, 5          ; eax = 5
    xor eax, eax        ; eax = eax ^ eax = 0

    ; SUB을 사용하여 ebx를 0으로 만들기
    mov ebx, 5          ; ebx = 5
    sub ebx, ebx        ; ebx = ebx - ebx = 0

    ; 프로그램 종료
    mov eax, 1          ; 시스템 호출 번호 (exit)
    xor ebx, ebx        ; 반환 값 0
    int 0x80            ; 시스템 호출&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(결론)&lt;br /&gt;=&amp;gt;&amp;nbsp;sub명령어는&amp;nbsp;플래그&amp;nbsp;레지스터에&amp;nbsp;영향을&amp;nbsp;주어&amp;nbsp;이후&amp;nbsp;분기&amp;nbsp;명령어에&amp;nbsp;영향을&amp;nbsp;줄&amp;nbsp;수&amp;nbsp;있기&amp;nbsp;때문에&amp;nbsp;xor명령어로&amp;nbsp;레지스터&amp;nbsp;값을&amp;nbsp;초기화하는&amp;nbsp;것이&amp;nbsp;효율적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;참고링크&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1)&amp;nbsp;&lt;a href=&quot;https://www.lazenca.net/display/TEC/01.The+basics+technic+of+Shellcode&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.lazenca.net/display/TEC/01.The+basics+technic+of+Shellcode&lt;/a&gt;&lt;br /&gt;(2)&amp;nbsp;System&amp;nbsp;V&amp;nbsp;ABI&quot;&amp;nbsp;Calling&amp;nbsp;Convention&lt;/p&gt;</description>
      <category>Pwnable/stack</category>
      <author>Greedun (lr-x-dl)</author>
      <guid isPermaLink="true">https://greedun.tistory.com/94</guid>
      <comments>https://greedun.tistory.com/94#entry94comment</comments>
      <pubDate>Tue, 6 Aug 2024 15:14:30 +0900</pubDate>
    </item>
    <item>
      <title>1 - 시간복잡도와 빅오 표기법</title>
      <link>https://greedun.tistory.com/86</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 알고리즘&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-1. 알고리즘이란?&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-09 23.35.20.png&quot; data-origin-width=&quot;1014&quot; data-origin-height=&quot;420&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ewpxO9/btsIwXz5iCY/isrbHpOIDWQbR6f2ubwKp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ewpxO9/btsIwXz5iCY/isrbHpOIDWQbR6f2ubwKp0/img.png&quot; data-alt=&quot;[Fig1. ]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ewpxO9/btsIwXz5iCY/isrbHpOIDWQbR6f2ubwKp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FewpxO9%2FbtsIwXz5iCY%2FisrbHpOIDWQbR6f2ubwKp0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;166&quot; data-filename=&quot;스크린샷 2024-07-09 23.35.20.png&quot; data-origin-width=&quot;1014&quot; data-origin-height=&quot;420&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[Fig1. ]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;입력 정수에서 출력 정수를 구하기 위한 일반화된 작업을 정리하여 의사코드나 소스코드의 형태로 구현한 것이다.&lt;/li&gt;
&lt;li&gt;문제를 해결하는 방법 그 자체를 말한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(알고리즘&amp;nbsp;충족&amp;nbsp;조건)&lt;br /&gt;ex) 요리 레시피&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;타당성 : &lt;b&gt;구현할 수 있고 실용적이어야 한다. &lt;br /&gt;&lt;/b&gt;=&amp;gt; 알고리즘의 성능 담당&lt;/li&gt;
&lt;li&gt;정밀성 : 변하지 않는 명확한 작업 단계를 가져야 한다.&lt;/li&gt;
&lt;li&gt;유일성 : 각 단계마다 명확한 다음 단계를 가져야 한다.&lt;/li&gt;
&lt;li&gt;유한성 : 특정 수의 작업 이후에 정지해야한다.&lt;/li&gt;
&lt;li&gt;입력 : 정의된 입력을 받아들일 수 있어야 한다.&lt;/li&gt;
&lt;li&gt;출력 : 답으로 출력을 내보낼 수 있어야 한다.&lt;/li&gt;
&lt;li&gt;일반성 : 정의된 입력들에 일반적으로 적용할 수 있어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-2. 알고리즘 성능 기준&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-09 23.42.22.png&quot; data-origin-width=&quot;1214&quot; data-origin-height=&quot;790&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NWa2S/btsIxlgpWVW/M9gjxPeRLrur16s3OGM4Fk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NWa2S/btsIxlgpWVW/M9gjxPeRLrur16s3OGM4Fk/img.png&quot; data-alt=&quot;[Fig2. ]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NWa2S/btsIxlgpWVW/M9gjxPeRLrur16s3OGM4Fk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNWa2S%2FbtsIxlgpWVW%2FM9gjxPeRLrur16s3OGM4Fk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;350&quot; height=&quot;228&quot; data-filename=&quot;스크린샷 2024-07-09 23.42.22.png&quot; data-origin-width=&quot;1214&quot; data-origin-height=&quot;790&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[Fig2. ]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;시간 기준 - 알고리즘이 적은 시간이 사용될 수록 빠르게 동작했다는 것을 의미한다.&lt;/li&gt;
&lt;li&gt;공간 기준 - 알고리즘이 적은 공간을 사용 할수록 적은 용량의 메모리를 사용했다는 것을 의미한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(어떤 것을 기준으로 하는 것이 중요한가?)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주어진 상황에 따라서 필요한 속도, 메모리의 기준이 다르기 때문에 명확하게 정할 수 없다.&lt;/li&gt;
&lt;li&gt;하지만 코딩테스트에서는 제한 시간 및 사용가능한 메모리가 주어지기 때문에 명확하다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;따라서 알고리즘의 수행속도와 특성을 분석하는 능력을 키우는게 필요하다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 시간 복잡도 분석&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;:&amp;nbsp;동일한&amp;nbsp;입력값으로부터&amp;nbsp;출력값까지의&amp;nbsp;시간을&amp;nbsp;측정하는&amp;nbsp;방법으로&amp;nbsp;&lt;br /&gt;좀&amp;nbsp;더&amp;nbsp;빠른&amp;nbsp;알고리즘을&amp;nbsp;만들기&amp;nbsp;위해는&amp;nbsp;&quot;알고리즘의&amp;nbsp;속도를&amp;nbsp;어떻게&amp;nbsp;측정할지&quot;를&amp;nbsp;정해야&amp;nbsp;한다.&lt;br /&gt;&lt;br /&gt;(알고리즘 속도 측정을 해야하는 이유는?)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;알고리즘을 바뀌었을때 어떤 알고리즘이 더 빠른지 알 수 없지 때문에&lt;/li&gt;
&lt;li&gt;문제에서 해결할 입력의 크기가 매우 작을 경우 시간복잡도는 큰 의미를 갖지 못할 수 있다.&lt;br /&gt;-&amp;gt; 따라서 입력값이 매우 크다고 보통 가정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;(1) 절대시간 측정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 알고리즘이 동작이 완료 할때까지 걸리는 시간 측정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(절대시간 측정시 문제점)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여러가지 변수에 따라 결과가 다르게 나올 수 있기 때문에 환경에 제약받지 않는 기준이 있어야 한다.&lt;br /&gt;&amp;nbsp;ex) 언어, 하드웨어, 운영체제, 컴파일러등&lt;/li&gt;
&lt;li&gt;수행시간이 다양한 입력에 대한 실행시간을 반영하지 못한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;(2) 연산횟수 측정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 알고리즘의 동작이 완료될 때까지 연산횟수가 몇번인지 계산&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;코딩테스트에서는 제한시간 내에 수행 할 수 있을지가 중요하기 때문에, &lt;br /&gt;최악의 경우를 기준으로 연산 횟수를 정하는게 합리적&lt;/li&gt;
&lt;li&gt;알고리즘의 수행시간을 지배하는 것은 반복문이다.&lt;br /&gt;=&amp;gt; 입력의 크기에 따라 수행횟수가 정해질 수 있기 때문&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex)&lt;br /&gt;-&amp;nbsp;(입력의&amp;nbsp;크기가&amp;nbsp;작을때)&amp;nbsp;반복문보다&amp;nbsp;다른&amp;nbsp;부분이&amp;nbsp;갖는&amp;nbsp;비중이&amp;nbsp;클&amp;nbsp;수&amp;nbsp;있음&lt;br /&gt;- (입력의 크기가 클 때) 반복문이 알고리즘 수행시간을 지배함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 함수에 따른 시간복잡도&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(함수에 따른 시간복잡도 크기)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-10 04.24.24.png&quot; data-origin-width=&quot;1540&quot; data-origin-height=&quot;664&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QjSyA/btsIxjQphBI/REVUCOOpYXUUfz92gqmGK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QjSyA/btsIxjQphBI/REVUCOOpYXUUfz92gqmGK0/img.png&quot; data-alt=&quot;[Fig3. ]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QjSyA/btsIxjQphBI/REVUCOOpYXUUfz92gqmGK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQjSyA%2FbtsIxjQphBI%2FREVUCOOpYXUUfz92gqmGK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;216&quot; data-filename=&quot;스크린샷 2024-07-10 04.24.24.png&quot; data-origin-width=&quot;1540&quot; data-origin-height=&quot;664&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[Fig3. ]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt;&amp;nbsp;(1)부터&amp;nbsp;(7)까지&amp;nbsp;우선순위이면&amp;nbsp;높은&amp;nbsp;순위일수록&amp;nbsp;복잡한&amp;nbsp;함수라고&amp;nbsp;볼&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(시간 복잡도에 영향을 미치는 것)&lt;br /&gt;ex) 다항(지수) vs 선형 vs 선형이하(로그)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-11 20.05.51.png&quot; data-origin-width=&quot;1764&quot; data-origin-height=&quot;1198&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DHIL6/btsIyjvgtac/kl1cG7ptcfSFT6t6GDuYl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DHIL6/btsIyjvgtac/kl1cG7ptcfSFT6t6GDuYl1/img.png&quot; data-alt=&quot;[Fig4. ]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DHIL6/btsIyjvgtac/kl1cG7ptcfSFT6t6GDuYl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDHIL6%2FbtsIyjvgtac%2Fkl1cG7ptcfSFT6t6GDuYl1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;550&quot; height=&quot;374&quot; data-filename=&quot;스크린샷 2024-07-11 20.05.51.png&quot; data-origin-width=&quot;1764&quot; data-origin-height=&quot;1198&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[Fig4. ]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt;&amp;nbsp;주로&amp;nbsp;입력되는&amp;nbsp;값에&amp;nbsp;따라서&amp;nbsp;알고리즘을&amp;nbsp;다르게&amp;nbsp;써야할&amp;nbsp;수도&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex)&amp;nbsp;간단하게&amp;nbsp;밑값이&amp;nbsp;2인&amp;nbsp;식들을&amp;nbsp;기준으로&amp;nbsp;예시로&amp;nbsp;잡았다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그래프를 보면(root 2 ~ 4) 범위를 기준으로 값의 대소관계가 바뀐다.&lt;/li&gt;
&lt;li&gt;만약에 주로 쓰이는 입력값이 해당 범위 내부에 속한다면 오히려 지수함수를 쓰는게 더 효율적일수 있다.&lt;/li&gt;
&lt;li&gt;따라서 시간복잡도로 알고리즘의 성능을 파악할 수도 있지만 &lt;br /&gt;주로 쓰이는 입력값의 분포나 특징도 파악하는 것도 알고리즘을 선택시 반영하는게 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-1. 선형시간 알고리즘&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt;&amp;nbsp;다항함수,&amp;nbsp;로그함수와&amp;nbsp;다항함수의&amp;nbsp;조합&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex)&amp;nbsp;배열&amp;nbsp;내부의&amp;nbsp;최대값을&amp;nbsp;찾는&amp;nbsp;코드&lt;/p&gt;
&lt;pre id=&quot;code_1720765188364&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int findMax(int arr[], int n) {
    int max = arr[0];
    for (int i = 1; i &amp;lt; n; i++) {
        if (arr[i] &amp;gt; max) {
            max = arr[i];
        }
    }
    return max;
}

int main() {
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    int n = sizeof(arr) / sizeof(arr[0]);
    int max = findMax(arr, n);
    printf(&quot;The maximum value in the array is: %d\n&quot;, max);
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;findmax함수 내부에서 배열의 크기 N 만큼만 실행되기 때문에 시간복잡도는 N이다.&lt;/li&gt;
&lt;li&gt;입력값을 넣으면 직선의 형태를 띠고 있기 때문에 선형 시간 알고리즘이라고 부른다.&lt;/li&gt;
&lt;li&gt;선형 시간에 실행되는 알고리즘을 대개 우리가 찾을 수 있는 알고리즘 중 가장 좋은 알고리즘이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-2. 선형이하 시간 알고리즘&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt;&amp;nbsp;로그함수,&amp;nbsp;상수함수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 배열내에 값 검색&lt;/p&gt;
&lt;pre id=&quot;code_1720765243331&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int binarySearch(int arr[], int l, int r, int x) {
    while (l &amp;lt;= r) {
        int m = l + (r - l) / 2;

        // 값이 중간 값과 같은 경우
        if (arr[m] == x)
            return m;

        // 값이 중간 값보다 작은 경우
        if (arr[m] &amp;lt; x)
            l = m + 1;

        // 값이 중간 값보다 큰 경우
        else
            r = m - 1;
    }

    // 값이 배열에 없는 경우
    return -1;
}

int main() {
    int arr[] = {2, 3, 4, 10, 40};
    int n = sizeof(arr) / sizeof(arr[0]);
    int x = 10;
    int result = binarySearch(arr, 0, n - 1, x);
    if (result != -1)
        printf(&quot;Element is present at index %d\n&quot;, result);
    else
        printf(&quot;Element is not present in array\n&quot;);
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;binarysearch함수는 내부에서 이미 정렬된 배열에서 원하는 값을 함수이다.&lt;/li&gt;
&lt;li&gt;매 반복마다 탐색 범위를 절반으로 줄이기 때문에 배열의 크기가 n이라고 할 때 시간복잡도는 log_2(n)이다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(증명&amp;nbsp;-&amp;nbsp;왜&amp;nbsp;시간복잡도가&amp;nbsp;지수함수인가?)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;1&amp;nbsp;+&amp;nbsp;2^1&amp;nbsp;+&amp;nbsp;2^2&amp;nbsp;+&amp;nbsp;...&amp;nbsp;+&amp;nbsp;2^k&amp;nbsp;=&amp;nbsp;N&amp;nbsp;&quot;&amp;nbsp;식에&amp;nbsp;대한&amp;nbsp;등비수열의&amp;nbsp;합&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$$&amp;nbsp;N&amp;nbsp;=&amp;nbsp;\frac{a(1&amp;nbsp;-&amp;nbsp;r^n)}{1&amp;nbsp;-&amp;nbsp;r}&amp;nbsp;(r=2)&amp;nbsp;$$&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-12 15.22.44.png&quot; data-origin-width=&quot;1182&quot; data-origin-height=&quot;108&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZmf0m/btsIykgEyFn/fdRJuovxIkjafgukKbvPsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZmf0m/btsIykgEyFn/fdRJuovxIkjafgukKbvPsK/img.png&quot; data-alt=&quot;[Fig5. ]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZmf0m/btsIykgEyFn/fdRJuovxIkjafgukKbvPsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZmf0m%2FbtsIykgEyFn%2FfdRJuovxIkjafgukKbvPsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1182&quot; height=&quot;108&quot; data-filename=&quot;스크린샷 2024-07-12 15.22.44.png&quot; data-origin-width=&quot;1182&quot; data-origin-height=&quot;108&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[Fig5. ]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;r=2이고&amp;nbsp;a=1이기&amp;nbsp;때문에&amp;nbsp;식을&amp;nbsp;전개했을&amp;nbsp;때&amp;nbsp;&quot;N&amp;nbsp;=&amp;nbsp;2^k&quot;가&amp;nbsp;나온다.&lt;br /&gt;지수로그&amp;nbsp;변환으로&amp;nbsp;k&amp;nbsp;=&amp;nbsp;log_2(N)이&amp;nbsp;된다.&lt;br /&gt;따라서&amp;nbsp;이분탐색알고리즘의&amp;nbsp;시간복잡도는&amp;nbsp;로그함수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-3. 지수시간 알고리즘&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 지수 함수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 재귀함수&amp;nbsp;형식의&amp;nbsp;피보니치&amp;nbsp;수열&lt;/p&gt;
&lt;pre id=&quot;code_1720765425807&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

// 재귀적으로 피보나치 수를 계산하는 함수
int fibonacci(int n) {
    if (n &amp;lt;= 1)
        return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

int main() {
    int n = 10; // 계산할 피보나치 수의 위치
    printf(&quot;Fibonacci number at position %d is: %d\n&quot;, n, fibonacci(n));
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;n이 1이 될때까지 2개의 재귀함수를 호출하여 진행된다.&lt;/li&gt;
&lt;li&gt;반복횟수는 &quot;func(n) = func(n-1) + func(n-2)&quot;로 계속 중복되는 하위 함수들이 반복되기 때문에 2^n이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-4. 재귀적 팩토리얼 함수&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 가장 비효율적인 수식&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 재귀적&amp;nbsp;팩토리얼&amp;nbsp;계산&lt;/p&gt;
&lt;pre id=&quot;code_1720765477905&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

// 재귀적으로 팩토리얼을 계산하는 함수
int factorial(int n) {
    if (n == 0 || n == 1)
        return 1;
    return n * factorial(n - 1);
}

int main() {
    int n = 5; // 계산할 팩토리얼의 값
    printf(&quot;Factorial of %d is: %d\n&quot;, n, factorial(n));
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&quot;팩토리얼 계산&quot;이란 n!이라고 표기될 때 n부터 1사이에 모든 정수를 곱한 값을 의미한다.&lt;/li&gt;
&lt;li&gt;해당 값을 계산하기 위해 매번 값을 나열 할 수 없기 때문에 반복문이나 재귀함수로 자동으로 처리한다.&lt;/li&gt;
&lt;li&gt;재귀함수로 이루어진 알고리즘의 경우 계속되는 함수 호출로 인한 메모리 오버헤드 발생으로 인해 스택 오버플로우가 발생할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1720765516287&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[가장 비효율적인 알고리즘]
1. 지수 시간 알고리즘
2. 재귀적 팩토리얼 시간 알고리즘
3. 다항 시간 안에 해결할 수 없는 NP-완전 문제&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-5. 재귀적 알고리즘 vs 반복적 알고리즘&lt;/h3&gt;
&lt;pre id=&quot;code_1720765529948&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[요약]
- 재귀적 알고리즘 : 문제의 자연스러운 표현을 제공하고 코드를 간결하게 만들어준다.
- 반복적 알고리즘 : 효율적인 실행속도와 메모리 관리를 제공한다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt;&amp;nbsp;재귀함수로&amp;nbsp;피보나치&amp;nbsp;수열,&amp;nbsp;팩토리얼&amp;nbsp;함수를&amp;nbsp;위에&amp;nbsp;예시로&amp;nbsp;들었다.&lt;br /&gt;위에&amp;nbsp;함수들은&amp;nbsp;연산횟수면에서&amp;nbsp;비효율적이기&amp;nbsp;때문에&amp;nbsp;반복적&amp;nbsp;알고리즘으로&amp;nbsp;바꿀&amp;nbsp;필요가&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex)&amp;nbsp;반복적&amp;nbsp;팩토리얼을&amp;nbsp;계산하는&amp;nbsp;함수&lt;/p&gt;
&lt;pre id=&quot;code_1720775827517&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

// 반복적으로 팩토리얼을 계산하는 함수
int factorial_iterative(int n) {
    int result = 1;
    for (int i = 1; i &amp;lt;= n; i++) {
        result *= i;
    }
    return result;
}

int main() {
    int n = 5;
    printf(&quot;Factorial of %d is: %d\n&quot;, n, factorial_iterative(n));
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 반복적 피보나치 수열을 계산하는 함수&lt;/p&gt;
&lt;pre id=&quot;code_1720775849314&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

// 반복적으로 피보나치 수열을 계산하는 함수
int fibonacci_iterative(int n) {
    if (n &amp;lt;= 1)
        return n;
    
    int a = 0, b = 1, temp;
    for (int i = 2; i &amp;lt;= n; i++) {
        temp = a + b;
        a = b;
        b = temp;
    }
    return b;
}

int main() {
    int n = 5;
    printf(&quot;Fibonacci number at position %d is: %d\n&quot;, n, fibonacci_iterative(n));
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팩토리얼의&amp;nbsp;경우&amp;nbsp;반복문으로&amp;nbsp;변경했어도&amp;nbsp;큰&amp;nbsp;차이가&amp;nbsp;없어&amp;nbsp;보이지만&amp;nbsp;&lt;br /&gt;피보나치&amp;nbsp;수열의&amp;nbsp;경우&amp;nbsp;반복문으로&amp;nbsp;변경했을&amp;nbsp;경우&amp;nbsp;내부&amp;nbsp;연산이&amp;nbsp;추가된&amp;nbsp;것을&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-11 17.09.13.png&quot; data-origin-width=&quot;1648&quot; data-origin-height=&quot;546&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbWYil/btsIy187SZ9/rBkXVRG9RTZamDE0olroJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbWYil/btsIy187SZ9/rBkXVRG9RTZamDE0olroJK/img.png&quot; data-alt=&quot;[Fig6. ]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbWYil/btsIy187SZ9/rBkXVRG9RTZamDE0olroJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbWYil%2FbtsIy187SZ9%2FrBkXVRG9RTZamDE0olroJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;232&quot; data-filename=&quot;스크린샷 2024-07-11 17.09.13.png&quot; data-origin-width=&quot;1648&quot; data-origin-height=&quot;546&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[Fig6. ]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를&amp;nbsp;비교해봤을때&amp;nbsp;재귀적,&amp;nbsp;반복적&amp;nbsp;알고리즘마다&amp;nbsp;장단점이&amp;nbsp;존재하며&amp;nbsp;위와&amp;nbsp;같이&amp;nbsp;정리할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(재귀적&amp;nbsp;알고리즘을&amp;nbsp;사용해야하는&amp;nbsp;경우)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;[고려야해할점] &lt;br /&gt;1. 문제의 특성과 해결 방법에 대한 직관적 이해 - (1), (4) &lt;br /&gt;2. 코드의 가독성 - (2) &lt;br /&gt;3. 재귀호출의 안정성 - (3)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만&amp;nbsp;반복적&amp;nbsp;알고리즘이라고&amp;nbsp;다&amp;nbsp;좋은&amp;nbsp;것은&amp;nbsp;아니다.&lt;br /&gt;상황에&amp;nbsp;따라서&amp;nbsp;재귀적&amp;nbsp;알고리즘이&amp;nbsp;더&amp;nbsp;좋은&amp;nbsp;경우가&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(1)&amp;nbsp;문제의&amp;nbsp;재귀적&amp;nbsp;정의가&amp;nbsp;명확할&amp;nbsp;경우&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;문제 정의 자체가 재귀적으로 되어있어서 재귀적 알고리즘이 자연스럽고 직관적으로 표현될 수 있는 경우&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex)&amp;nbsp;트리구조탐색,&amp;nbsp;그래프&amp;nbsp;순회등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(2)&amp;nbsp;코드의&amp;nbsp;가독성이&amp;nbsp;중요한&amp;nbsp;경우&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;- 코드의 가독성을 높이고 유지보수를 용이하게 만들 수 있는 경우 &lt;br /&gt;- 문제의 본질을 더 잘 반영할 수 있어서 코드 이해하기 쉽게 만듦&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(3)&amp;nbsp;재귀&amp;nbsp;호출의&amp;nbsp;깊이가&amp;nbsp;제한적인&amp;nbsp;경우&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;깊이를 제한하거나 입력크기를 제한할 경우 재귀적 알고리즘을 코드의 가독성을 높이고 보다 효율적으로 사용할 수 있다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(4) 동적계획법에서의&amp;nbsp;재귀적&amp;nbsp;접근&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;문제를 재귀적으로 정의하고 하향식(top-down) 접근할 때가 있습니다. &lt;br /&gt;이때 동적 계획법을 이용하여 부분적으로 해결가능합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(재귀적 알고리즘의 사용 사례)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;트리구조의 순회&lt;/li&gt;
&lt;li&gt;분할정복 알고리즘(병합정렬)&lt;/li&gt;
&lt;li&gt;백트래킹 알고리즘(N-Queens 문제해결)&lt;/li&gt;
&lt;li&gt;etc&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt;&amp;nbsp;따라서&amp;nbsp;특정&amp;nbsp;문제에&amp;nbsp;대한&amp;nbsp;해결방식을&amp;nbsp;선택할&amp;nbsp;때&amp;nbsp;그&amp;nbsp;문제의&amp;nbsp;특성과&amp;nbsp;실행환경을&amp;nbsp;고려해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 점근적 표긱법: O표기&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-1. 정의를 알기 전 알아야할 사항&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-11 18.29.15.png&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;1254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dG1fwP/btsIxe20BQr/7ifsLJmkX361Rj5PD3MXKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dG1fwP/btsIxe20BQr/7ifsLJmkX361Rj5PD3MXKk/img.png&quot; data-alt=&quot;[Fig7. ]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dG1fwP/btsIxe20BQr/7ifsLJmkX361Rj5PD3MXKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdG1fwP%2FbtsIxe20BQr%2F7ifsLJmkX361Rj5PD3MXKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;450&quot; height=&quot;383&quot; data-filename=&quot;스크린샷 2024-07-11 18.29.15.png&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;1254&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[Fig7. ]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;매번 시간복잡도를 상세히 정의하면 좋지만 코드가 클수록 오래걸린다.&lt;/li&gt;
&lt;li&gt;또한 &quot;N^2+3N+5&quot;이 경우 N이 커질수록 N^2의 영향력이 커져서 3N,5의 값이 의미없게 된다.&lt;/li&gt;
&lt;li&gt;코딩테스트는 연산회수를 측정하는 시험이 아니기에 대략적으로만 알면 된다.&lt;/li&gt;
&lt;li&gt;N^2+3N+5 &amp;asymp; N^2 이라고 생각해도 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-2. 점근적 표기법이란?&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;정확한 연산횟수가 아닌, &amp;lt;b&amp;gt;연산횟수의 추이&amp;lt;/b&amp;gt;를 활용해 시간 복잡도를 표기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;표시할 때 빅요 표기를 사용하는데 &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;빅오 표기란 최악의 경우를 고려해서 점근적 표기법으로 나타내는 것을 말한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;시간 복잡도를 통해서 내가 작성한 알고리즘의 성능을 유추할 수 있다.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;ex)&amp;nbsp;N^2&amp;nbsp;+&amp;nbsp;3N&amp;nbsp;+&amp;nbsp;5&amp;nbsp;=&amp;gt;&amp;nbsp;O(N^2)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;빅오 표기법의 시간 복잡도&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Pasted image 20240711184436.png&quot; data-origin-width=&quot;2380&quot; data-origin-height=&quot;934&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5y55i/btsIwRUv2Ja/i0kVsek6pXKWryXjzKiqzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5y55i/btsIwRUv2Ja/i0kVsek6pXKWryXjzKiqzk/img.png&quot; data-alt=&quot;[Fig8. ]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5y55i/btsIwRUv2Ja/i0kVsek6pXKWryXjzKiqzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5y55i%2FbtsIwRUv2Ja%2Fi0kVsek6pXKWryXjzKiqzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;235&quot; data-filename=&quot;Pasted image 20240711184436.png&quot; data-origin-width=&quot;2380&quot; data-origin-height=&quot;934&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[Fig8. ]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;함수의 따른 시간 복잡도를 빅오표기법으로 표현한 그래프이다.&lt;/li&gt;
&lt;li&gt;입력값이 커질 수록 각 함수의 영향력 차이가 어느정도인지 유추할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;[코딩테스트에서의 활용법] &lt;br /&gt;=&amp;gt; 입력값을 기준으로 가용한 자료구조 및 알고리즘을 고려가능하다. &lt;br /&gt;&lt;br /&gt;ex) 입력값이 100만까지 가능 &lt;br /&gt;-&amp;gt; 만약 연산횟수가 N^M이라면 시간초과 / 연산횟수가 log N이면 Pass 로 예상할 수 있다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-3. 메서드의 시간 복잡도 파악&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;저장되는 메모리 공간의 특징이나 메서드에 따라서 시간 복잡도가 달라질 수 있다.&lt;/li&gt;
&lt;li&gt;따라서 이 부분은 알고리즘의 성능을 좌지우지 할 수 있기 때문에 직접 코딩을 수행하고 분석하여 파악해두는게 좋다&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex)&lt;br /&gt;-&amp;nbsp;std::set&amp;nbsp;vs&amp;nbsp;std::unordered_set&lt;br /&gt;-&amp;nbsp;set::vector&amp;nbsp;vs&amp;nbsp;std::set&lt;br /&gt;-&amp;nbsp;std::map&amp;nbsp;vs&amp;nbsp;std::unordered_map&lt;br /&gt;=&amp;gt;&amp;nbsp;c++의&amp;nbsp;경우&amp;nbsp;일부&amp;nbsp;예시를&amp;nbsp;아래&amp;nbsp;링크에서&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있다.&lt;br /&gt;(&lt;a href=&quot;https://github.com/dremdeveloper/codingtest_cpp/tree/main/performance)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/dremdeveloper/codingtest_cpp/tree/main/performance)&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;참고링크&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1) &lt;a href=&quot;https://www.desmos.com/calculator/ifg3mwmqun?lang=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.desmos.com/calculator/ifg3mwmqun?lang=ko&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 그래프 그려주는 사이트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(2) &lt;a href=&quot;https://inf.run/t92e1&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://inf.run/t92e1&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 참고한 인프런 강의&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(3) Book&amp;nbsp;-&amp;nbsp;알고리즘&amp;nbsp;문제해결전략&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(4) &lt;a href=&quot;https://chatgpt.com/share/923ae9ae-3032-4814-a7cc-751e149a935a&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://chatgpt.com/share/923ae9ae-3032-4814-a7cc-751e149a935a&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 알고리즘 예시 chatgpt&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(5) &lt;a href=&quot;https://velog.io/@jacob3015/2022.04.13-BIG-O-표기법&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@jacob3015/2022.04.13-BIG-O-표기법&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 빅오표기법 비교 그래프&lt;/p&gt;</description>
      <category>알고리즘/알고리즘 개념</category>
      <author>Greedun (lr-x-dl)</author>
      <guid isPermaLink="true">https://greedun.tistory.com/86</guid>
      <comments>https://greedun.tistory.com/86#entry86comment</comments>
      <pubDate>Fri, 12 Jul 2024 15:08:34 +0900</pubDate>
    </item>
    <item>
      <title>CTF - Pwnable_문제 환경 구성</title>
      <link>https://greedun.tistory.com/85</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. socat을 이용한 문제 구성&lt;/h2&gt;
&lt;pre id=&quot;code_1719827047595&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[필요한 파일]
1 - 문제파일(바이너리, *.py등)
2 - Dockerfile, docker-compose.yml
3 - README.md&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-1. socat이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;:다목적&amp;nbsp;소켓&amp;nbsp;터널링을&amp;nbsp;위한&amp;nbsp;유명한&amp;nbsp;유닉스&amp;nbsp;소켓&amp;nbsp;프로그램&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(socat 설치)&lt;/p&gt;
&lt;pre id=&quot;code_1719827080289&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;apt-get install socat&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-2. 문제파일 준비&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1) 입출력이 가능한 문제파일을 작성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) test.c&lt;/p&gt;
&lt;pre id=&quot;code_1719827184072&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# test.c
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

#define FLAG &quot;RD{welldone_you_found_the_flag}&quot;

void check_input(char *input) {
    if (strcmp(input, &quot;1234&quot;) == 0) {
	    printf(&quot;%s&quot;, FLAG);
        printf(&quot;Correct!\n&quot;);
    } else {
        printf(&quot;Wrong!\n&quot;);
    }
}

int main() {
    char input[100];

    printf(&quot;Enter the flag: &quot;);
    fgets(input, sizeof(input), stdin);

    // Remove newline character from input
    input[strcspn(input, &quot;\n&quot;)] = 0;

    check_input(input);

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-3. Dockerfile, docker-compose.yml 작성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(바이너리만 제공하는 경우)&lt;/p&gt;
&lt;pre id=&quot;code_1719827224244&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FROM ubuntu:22.04@sha256:b6b83d3c331794420340093eb706a6f152d9c1fa51b262d9bf34594887c2c7ac

ENV PROB test
ENV PORT 8888

RUN apt-get update -y
RUN apt-get install -y socat

RUN adduser $PROB

WORKDIR /home/$PROB

COPY ./flag ./flag
COPY ./deploy/prob ./prob

RUN chmod 644 ./flag
RUN chmod 755 ./prob

USER $PROB

EXPOSE 8888
CMD socat TCP-LISTEN:$PORT,reuseaddr,fork EXEC:./prob,stderr&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) docker-compose.yml&lt;/p&gt;
&lt;pre id=&quot;code_1719827252922&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;version: '3'
services:
  socat:
    image: socat_test
    ports:
      - &quot;38888:8888&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; docker-compose는 관리용으로써 문제제공시 compose파일은 제공하지 않는다.&lt;/p&gt;
&lt;pre id=&quot;code_1719827301446&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;실행 : docker-compose up -d
종료 : docker-compose down&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-4. README.md 작성&lt;/h3&gt;
&lt;pre id=&quot;code_1719827346834&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[나만의 README 작성 프레임]
# Title : 
# Author : 
# Desc
asdf

---

(flag)
RD{test}

(익스 원리)

(익스플로잇 코드)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-5. 환경 구축 테스트&lt;/h3&gt;
&lt;pre id=&quot;code_1719827380159&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(폴더구성)
&amp;gt; tree
.
├── Dockerfile
├── deploy
│&amp;nbsp;&amp;nbsp; └── prob
├── docker-compose.yml
└── flag

docker build -t {이미지 이름} .
docker run --rm -it -p {외부포트}:{내부포트} {이미지 이름}
nc localhost {외부포트}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;주의사항&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;(1) - 권한 에러&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1719827456966&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(base)  Greedun    &amp;gt; ~/Downloads/test
&amp;gt; docker run --rm -p 38888:8888 socat_test
2024/06/30 07:28:43 socat[9] E execvp(&quot;./prob&quot;, &quot;./prob&quot;): Permission denied
2024/06/30 07:28:43 socat[8] E waitpid(): child 9 exited with status 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 해당 에러는 flag, prob파일에 작업하려는데 올바른 권한이 없어서 생기는 에러이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; 이 에러를 해결하기 위해서는 dockerfile에서 권한을 부여하는 명령어를 작성해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;(2) - docker run시 취소 불가 상황&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(문제 원인)&lt;/p&gt;
&lt;pre id=&quot;code_1719827555789&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[chatgpt왈]
- 컨테이너가 포그라운드 프로세스로 실행되지 않거나
- 신호를 적절하게 처리하지 않는 경우&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; chatgpt왈 이런 문제로 종료가 안되는거라고 답변이 왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 다음와 같은 방법을 나열해봤다.&lt;/p&gt;
&lt;pre id=&quot;code_1719827632488&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1 - Docker 컨테이너 종료 명령 사용
2 - SIGINT 신호 전달
3 - Docker compose 사용(V)
4 - 직접 SIGINT 신호 보내기&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 하나씩 방법을 알아보고 그중 적당히 간편한 것으로 방법을 찾고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1) Docker 컨테이너 종료 명령 사용&lt;/p&gt;
&lt;pre id=&quot;code_1719851929316&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker ps
docker stop {container_id}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;(2) SIGINT 신호 전달&lt;/p&gt;
&lt;pre id=&quot;code_1719851990814&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker run 명령어로 실행할때 -it옵션으로 TTY를 할당하여 표준 입력이 연결됨
-&amp;gt; Ctrl+C신호를 전달하여 컨테이너 종료가 가능&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;(3) Docker compose 사용 - 채택&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; compose로 컨테이너를 관리시 더 쉽게 종료할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) docker-compose.yml&lt;/p&gt;
&lt;pre id=&quot;code_1719852045157&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;version: '3'
services:
  socat:
    image: socat_test
    ports:
      - &quot;38888:8888&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) docker 실행&lt;/p&gt;
&lt;pre id=&quot;code_1719852069561&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;실행 : docker-compose up -d
=&amp;gt; -d옵션 : 백그라운드으로 실행 
종료 : docker-compose down&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;(4) 직접 SIGINT 신호 보내기&lt;/p&gt;
&lt;pre id=&quot;code_1719852124127&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker kill --signal=SIGINT {container_id}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;참고링크&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(socat)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1)&amp;nbsp;&lt;a href=&quot;https://minpeter.xyz/blog/use-socat-nc-ctf-challenge&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://minpeter.xyz/blog/use-socat-nc-ctf-challenge&lt;/a&gt;&lt;br /&gt;(2)&amp;nbsp;&lt;a href=&quot;https://dhna.tistory.com/334&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://dhna.tistory.com/334&lt;/a&gt;&lt;br /&gt;=&amp;gt;&amp;nbsp;socat명령어와&amp;nbsp;관련된&amp;nbsp;옛날자료&lt;/p&gt;</description>
      <category>환경구축 &amp;amp; Tip</category>
      <category>ctf운영</category>
      <author>Greedun (lr-x-dl)</author>
      <guid isPermaLink="true">https://greedun.tistory.com/85</guid>
      <comments>https://greedun.tistory.com/85#entry85comment</comments>
      <pubDate>Tue, 2 Jul 2024 01:43:48 +0900</pubDate>
    </item>
  </channel>
</rss>