<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>HACK THE WORLD</title>
    <link>https://juntheworld.tistory.com/</link>
    <description>HACK THE WORLD : 안녕하세요 이준학입니다.</description>
    <language>ko</language>
    <pubDate>Tue, 14 Apr 2026 12:54:18 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>JUNFUTURE</managingEditor>
    <image>
      <title>HACK THE WORLD</title>
      <url>https://tistory1.daumcdn.net/tistory/3942596/attach/65c48c22d38246029604dcd7b8f738a2</url>
      <link>https://juntheworld.tistory.com</link>
    </image>
    <item>
      <title>C++ Demangling (함수, 변수이름 심볼 인코딩 복원하기)</title>
      <link>https://juntheworld.tistory.com/262</link>
      <description>&lt;p data-end=&quot;147&quot; data-start=&quot;64&quot; data-ke-size=&quot;size16&quot;&gt;Demangling은 C++ 컴파일러가 함수나 변수 이름을 링크용 심볼로 인코딩한 것을 사람이 읽을 수 있는 원래 이름으로 복원하는 과정이다.&lt;/p&gt;
&lt;p data-end=&quot;147&quot; data-start=&quot;64&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;355&quot; data-start=&quot;149&quot; data-ke-size=&quot;size16&quot;&gt;C++은 함수 오버로딩, 네임스페이스, 클래스, 템플릿 같은 정보까지 심볼에 담아야 하므로, 예를 들어&lt;br /&gt;MyApp::Renderer::instance() 같은 이름이 바이너리에서는&lt;br /&gt;__ZN5MyApp8Renderer8instanceEv 처럼 mangling된다.&lt;/p&gt;
&lt;p data-end=&quot;355&quot; data-start=&quot;149&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;355&quot; data-start=&quot;149&quot; data-ke-size=&quot;size16&quot;&gt;이 인코딩된 이름을 다시 원래 C++ 형태로 푸는 작업이 demangling이다.&lt;/p&gt;
&lt;p data-end=&quot;364&quot; data-start=&quot;357&quot; data-ke-size=&quot;size16&quot;&gt;직접 해보면:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1775796621435&quot; class=&quot;excel&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;echo &quot;__ZZN5MyApp8Renderer8instanceEvE6object&quot; | c++filt
=&amp;gt; MyApp::Renderer::instance()::object&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;495&quot; data-start=&quot;489&quot; data-ke-size=&quot;size16&quot;&gt;해석해보면:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;751&quot; data-start=&quot;497&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;531&quot; data-start=&quot;497&quot; data-section-id=&quot;1rhe9gq&quot;&gt;_ZN &amp;rarr; namespace / class 스코프 시작&lt;/li&gt;
&lt;li data-end=&quot;567&quot; data-start=&quot;532&quot; data-section-id=&quot;11g9ob5&quot;&gt;5MyApp &amp;rarr; &quot;MyApp&quot; (숫자는 문자열 길이)&lt;/li&gt;
&lt;li data-end=&quot;596&quot; data-start=&quot;568&quot; data-section-id=&quot;qvowea&quot;&gt;8Renderer &amp;rarr; &quot;Renderer&quot;&lt;/li&gt;
&lt;li data-end=&quot;642&quot; data-start=&quot;597&quot; data-section-id=&quot;qzivbj&quot;&gt;8instanceEv &amp;rarr; instance() (v는 void 인자)&lt;/li&gt;
&lt;li data-end=&quot;695&quot; data-start=&quot;643&quot; data-section-id=&quot;1b5qe15&quot;&gt;_ZZ...E6object &amp;rarr; 함수 내부의 static local 변수 object&lt;/li&gt;
&lt;li data-end=&quot;751&quot; data-start=&quot;696&quot; data-section-id=&quot;1jwwi96&quot;&gt;_ZGV... &amp;rarr; 해당 static 변수의 초기화 여부를 관리하는 guard variable&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;839&quot; data-start=&quot;753&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;839&quot; data-start=&quot;753&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;즉, demangling은 디스어셈블리나 심볼 분석 중 보이는 난독화된 C++ 심볼을 원래의 함수/변수 선언 형태에 가깝게 복원하는 작업이라고 보면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;839&quot; data-start=&quot;753&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;839&quot; data-start=&quot;753&quot; data-ke-size=&quot;size16&quot;&gt;아 신기하다 진짜&lt;/p&gt;</description>
      <author>JUNFUTURE</author>
      <guid isPermaLink="true">https://juntheworld.tistory.com/262</guid>
      <comments>https://juntheworld.tistory.com/262#entry262comment</comments>
      <pubDate>Fri, 10 Apr 2026 13:50:48 +0900</pubDate>
    </item>
    <item>
      <title>진짜 어카노</title>
      <link>https://juntheworld.tistory.com/259</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://red.anthropic.com/2026/mythos-preview/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://red.anthropic.com/2026/mythos-preview/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1775610014747&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Claude Mythos Preview \ red.anthropic.com&quot; data-og-description=&quot;April 7, 2026 Nicholas Carlini, Newton Cheng, Keane Lucas, Michael Moore, Milad Nasr, Vinay Prabhushankar, Winnie Xiao Evyatar Ben Asher, Hakeem Angulu, Jackie Bow, Keir Bradwell, Ben Buchanan, Daniel Freeman, Alex Gaynor, Xinyang Ge, Logan Graham, Hasnain&quot; data-og-host=&quot;red.anthropic.com&quot; data-og-source-url=&quot;https://red.anthropic.com/2026/mythos-preview/&quot; data-og-url=&quot;https://red.anthropic.com/2026/mythos-preview/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fwfrr/dJMb9lMckPB/mXEQvOLMoQV4d6WmcXco8K/img.png?width=3840&amp;amp;height=2160&amp;amp;face=0_0_3840_2160&quot;&gt;&lt;a href=&quot;https://red.anthropic.com/2026/mythos-preview/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://red.anthropic.com/2026/mythos-preview/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fwfrr/dJMb9lMckPB/mXEQvOLMoQV4d6WmcXco8K/img.png?width=3840&amp;amp;height=2160&amp;amp;face=0_0_3840_2160');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Claude Mythos Preview \ red.anthropic.com&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;April 7, 2026 Nicholas Carlini, Newton Cheng, Keane Lucas, Michael Moore, Milad Nasr, Vinay Prabhushankar, Winnie Xiao Evyatar Ben Asher, Hakeem Angulu, Jackie Bow, Keir Bradwell, Ben Buchanan, Daniel Freeman, Alex Gaynor, Xinyang Ge, Logan Graham, Hasnain&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;red.anthropic.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;진짜 어카노?&lt;/p&gt;</description>
      <category>공부/이모저모</category>
      <author>JUNFUTURE</author>
      <guid isPermaLink="true">https://juntheworld.tistory.com/259</guid>
      <comments>https://juntheworld.tistory.com/259#entry259comment</comments>
      <pubDate>Wed, 8 Apr 2026 10:00:32 +0900</pubDate>
    </item>
    <item>
      <title>Javascript worker와 blob(동적 코드 주입)</title>
      <link>https://juntheworld.tistory.com/254</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;들어가며&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 코드를 이해해보자&lt;/p&gt;
&lt;pre id=&quot;code_1774920773949&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 1. 워커에서 실행될 코드를 문자열로 정의 (템플릿 리터럴 활용)
const workerCode = `
  self.onmessage = function(e) {
    console.log('[Worker] Received data from main thread:', e.data);
    
    // 무거운 연산을 시뮬레이션 (메인 스레드 방해 없음)
    const result = e.data * e.data;
    
    // 결과를 다시 메인 스레드로 전송
    self.postMessage(result);
  };
`;

// 2. 문자열을 Blob 객체로 변환 (타입은 반드시 javascript)
const blob = new Blob([workerCode], { type: 'application/javascript' });

// 3. Blob을 가리키는 고유한 URL 생성
const blobURL = URL.createObjectURL(blob);
console.log('[Main] Created Blob URL:', blobURL);

// 4. 생성된 URL을 사용하여 워커 인스턴스 생성
const myWorker = new Worker(blobURL);

// 5. 워커로부터 오는 메시지를 처리할 핸들러 등록
myWorker.onmessage = function(e) {
  console.log('[Main] Worker computed result:', e.data);
  
  // 6. 사용이 끝난 URL은 메모리 해제를 위해 폐기 (중요!)
  URL.revokeObjectURL(blobURL);
  console.log('[Main] Blob URL has been released from memory.');
};

// 7. 워커에게 작업 지시 (데이터 전송)
console.log('[Main] Sending 10 to the worker.');
myWorker.postMessage(10);&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;Worker&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;worker는 js 파일을 받아서 실행해준다. 정확히 말하면 worker는 &quot;Worker Thread&quot;의 개념이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;woker가 등장하게된 배경은 브라우저의 main thread와 분리되어 서로 다른 context에서 데이터를 주고받으며 js를 실행하기위함&lt;/b&gt;&lt;/u&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;브라우저의 main thread는 UI를 담당한다. window, document(DOM) 접근을 관리하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;worker thread는 이외에 백그라운드 연산(당연히 다른 .js 코드 실행을 뜻한다)을 수행한다.&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;이때 둘 thread 간의 통신이 필요할텐데, 오직 message를 이용해서만 통신을 하고 이때 아래와 같은 핸들러들을 이용해서 통신하는 것이다.&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;Worker - Main thread 통신 규격 (Event driven)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보낼 때 : postMessage(data)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #1f1f1f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;받을 때 : onmessage 이벤트 핸들러&lt;/p&gt;
&lt;pre id=&quot;code_1774921303102&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const myWorker = new Worker('worker.js');

// 1. 워커가 나에게 보낸 메시지를 받을 준비
myWorker.onmessage = function(event) {
    console.log(&quot;워커가 보낸 답장:&quot;, event.data);
};

// 2. 워커에게 메시지 던지기
myWorker.postMessage(&quot;안녕 워커!&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;worker를 생성하는 쪽(main thread)에서는 반드시 위와 같은 코드가 필요할 것이다.&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;생성되는 worker의 코드는 아래와 같은 패턴이 있을 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1774921351472&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 3. 메인이 보낸 메시지를 받을 준비 (자신을 가리키는 self 사용)
self.onmessage = function(event) {
    const receivedData = event.data;
    console.log(&quot;메인이 보낸 내용:&quot;, receivedData);

    // 4. 메인에게 다시 답장 던지기
    const reply = &quot;받았다: &quot; + receivedData;
    self.postMessage(reply); 
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;worker 코드 내부에 self??&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(TBD)&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;Blob (Binary large object)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리 내부에 존재하는 바이너리 데이터다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;MIME 타입&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C도 많이 해봤으면 알듯이 메모리에 저장된 데이터를 어떻게 해석할까?의 문제를 해결해주는게 바로 MIME 타입이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니까... 이런식으로 blob을 정의 한다는 건 쌩짜로 바이너리 데이터 넣는거니까 이걸 브라우저에서 뭐 어떤 데이터 인지 알아야 이걸 처리(렌더링) 할테니까, 타입을 알려주는게 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래에서 workerCode는 위에서 봤던 self.onmessage로 시작하는 코드 일 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1774921932765&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const blob = new Blob([workerCode], { type: 'application/javascript' });&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;MIME 타입(Multipurpose Internet Mail Extensions)은&amp;nbsp;파일의 성격과 형식을 나타내는 식별자로,&amp;nbsp;type/subtype&amp;nbsp;구조(text/html,&amp;nbsp;image/png&amp;nbsp;등)로 웹에서 데이터 형식을 정의합니다. 주로 HTTP 헤더(Content-Type)를 통해 서버가 브라우저에게 파일 종류를 알리고, 브라우저는 이에 따라 파일을 랜더링하거나 다운로드한다.&lt;br /&gt;
&lt;pre id=&quot;code_1774922325911&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;text/html: HTML 문서
image/png: PNG 이미지
application/json: JSON 데이터
application/javascript: 자바스크립트 파일​&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;URL.createObjectURL(blob)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;blob:https://현재도메인/무작위-UUID&lt;/i&gt; 형태의 가짜 주소를 생성하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 주소가 현재 내 컴퓨터 RAM의 특정 지점(Blob 데이터가 있는 곳 - 주소, URL)을 가리키도록 연결&lt;/p&gt;
&lt;pre id=&quot;code_1774922289152&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const blobURL = URL.createObjectURL(blob);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Blob을 이용한 동적 js 코드 주입&lt;/h2&gt;
&lt;pre id=&quot;code_1774921670330&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 정적으로 코드 주입(code injection)
const myWorker = new Worker('worker.js');&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1774921688047&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 동적으로 코드 주입(code injection)
const workerCode = `
  self.onmessage = function(e) {
    console.log('[Worker] Received data from main thread:', e.data);
    
    // 무거운 연산을 시뮬레이션 (메인 스레드 방해 없음)
    const result = e.data * e.data;
    
    // 결과를 다시 메인 스레드로 전송
    self.postMessage(result);
  };
`;

const blob = new Blob([workerCode], { type: 'application/javascript' });
const blobURL = URL.createObjectURL(blob);
const myWorker = new Worker(blobURL);&lt;/code&gt;&lt;/pre&gt;</description>
      <author>JUNFUTURE</author>
      <guid isPermaLink="true">https://juntheworld.tistory.com/254</guid>
      <comments>https://juntheworld.tistory.com/254#entry254comment</comments>
      <pubDate>Tue, 31 Mar 2026 11:00:31 +0900</pubDate>
    </item>
    <item>
      <title>MacOS(ARM, M1,M2..) 에서 UTM을 이용해 Ubuntu VM실행하기</title>
      <link>https://juntheworld.tistory.com/250</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. UTM 설치&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;QEMU 기반 VM을 GUI로 감싼 툴이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무료이고 이게 압도적으로 편하다는 설이 많다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. ubuntu server for arm iso 설치&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ubuntu server를 설치한 뒤&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 명령어를 치면 ubuntu desktop처럼 사용할 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1773882081066&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ sudo apt update
$ sudo apt install ubuntu-desktop
$ sudo reboot&lt;/code&gt;&lt;/pre&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. boot from next volume&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후에 boot from next volume으로 접속하면 우분투 접속이 된다.&lt;/p&gt;</description>
      <category>공부/이모저모</category>
      <author>JUNFUTURE</author>
      <guid isPermaLink="true">https://juntheworld.tistory.com/250</guid>
      <comments>https://juntheworld.tistory.com/250#entry250comment</comments>
      <pubDate>Thu, 19 Mar 2026 10:01:27 +0900</pubDate>
    </item>
    <item>
      <title>Javascript의 객체와 prototype inheritance(프로토타입 기반 상속)</title>
      <link>https://juntheworld.tistory.com/247</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;들어가며&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;javascript 는 프로토타입 기반 객체지향 프로그래밍 언어이다.&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;h2 data-ke-size=&quot;size26&quot;&gt;Prototype의 의미&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중복으로 사용되는 곳이 너무 많아 정리한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 일반 공학에서의 prototype : 최종 제품을 만들기 전에 만든 초기 시험 모델(시제품)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. C언어에서의 함수 prototype : 함수를 정의하기 전에 컴파일러에게 함수의 이름, 반환형, 매개변수 타입을 미리 알려주는 선언 &lt;br /&gt;&lt;b&gt;3. javascript의 prototype : 객체가 다른 객체의 속성과 메서드를 상속받기 위해 연결하는 상위 객체 참조&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;이 글에서는 3번만 얘기할거니까 헷갈리지 말자&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;h2 data-ke-size=&quot;size26&quot;&gt;Javascript의 객체&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체라 함은 메모리에 저장되는 일련의 데이터 덩어리라고 생각하면된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트는 모든 것이 객체(object)라는 설계철학을 가지고있다.&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트에서 모든 인스턴스들(함수, 배열, 문자열 인스턴스들) 은 생성되는 순간, 부모의 객체 메모리 주소 값을 자신의 내부 포인터인 [[Prototype]]에 저장한다.&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;따라서 자바스크립트의 모든 객체 인스턴스들은 Object.prototype을 조상으로 갖는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 구조(prototype chain)로 구성되어있는 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1772690826443&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;obj
 └── [[Prototype]] &amp;rarr; parent
                          └── [[Prototype]] &amp;rarr; Object.prototype&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;408&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csArl4/dJMb996BeWA/g9SWm41Fan4N2ssBCwH2d1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csArl4/dJMb996BeWA/g9SWm41Fan4N2ssBCwH2d1/img.png&quot; data-alt=&quot;진짜다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csArl4/dJMb996BeWA/g9SWm41Fan4N2ssBCwH2d1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsArl4%2FdJMb996BeWA%2Fg9SWm41Fan4N2ssBCwH2d1%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;537&quot; height=&quot;408&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;408&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;진짜다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;여기서 __proto__는 객체의 내부 prototype ( [[Prototype]] )에 접근하는 getter/setter &lt;br /&gt;obj.__proto__ 는 실제로 obj.[[Prototype]] &lt;br /&gt;&lt;br /&gt;여기서 .constructor는 해당 prototype을 만든 생성자 함수. (어떤 객체가 어떤 생성자에서 왔는가?)&lt;br /&gt;String.prototype.constructor === String&lt;br /&gt;Array.prototype.constructor === Array&lt;br /&gt;Function.prototype.constructor === Function&lt;br /&gt;Object.prototype.constructor === Object&lt;br /&gt;&lt;br /&gt;생성자 함수? -&amp;gt; 객체를 만들기 위한 함수&lt;/blockquote&gt;
&lt;pre id=&quot;code_1772690939011&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function Dog(name) {
  this.name = name;
}

const d = new Dog(&quot;puppy&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 Dog이 생성자 함수다.&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 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;Javascript의 객체 생성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전통적인 클래스 기반 언어(C++, Java)는 인스턴스를 만들 때 새로운 메모리 덩어리를 찍어내지만, 자바스크립트는 복사하지 않고 클래스간 연결만 한다.&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 style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;[[Prototype]] 포인터에 저장하는 것&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;직접 객체 생성하기 (new없이)&lt;/h3&gt;
&lt;pre id=&quot;code_1772691934186&quot; class=&quot;qml&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const parent = { gold: 100 };
const child = Object.create(parent); // child -&amp;gt; parent 연결&lt;/code&gt;&lt;/pre&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;parent 객체 생성: &lt;/b&gt;메모리 주소 0x111에 생성. 내부에 gold: 100이 저장&lt;/li&gt;
&lt;li&gt;&lt;b&gt;child 객체 생성: &lt;/b&gt;메모리 주소 0x222에 생성. 내부 데이터는 비어있음&lt;/li&gt;
&lt;li&gt;&lt;b&gt;연결 &lt;/b&gt;: Object.create()는 새 객체를 만들면서 그 객체(child)의 [[Prototype]]을 원하는 객체(parent)로 직접 지정하는 함수 child 객체의 헤더 영역에 있는 [[Prototype]] 필드에 0x111이라는 주소가 기록됨&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1772692111740&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;child
├─ own properties: (없음)
└─ [[Prototype]] ──&amp;gt; parent
                    ├─ gold: 100
                    └─ [[Prototype]] &amp;rarr; Object.prototype
                    
child.__proto__ === parent&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 형태로&amp;nbsp; 객체가 생성되며 ECMAScript spec(자바스크립트 표준) 에서 Object.create(proto)의 동작은 아래의 알고리즘이다.&lt;/p&gt;
&lt;pre id=&quot;code_1772692164699&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. 새로운 빈 객체 O 생성
2. O.[[Prototype]] = proto
3. O 반환&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;Javascript Delegation&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 어떤 데이터나 함수를 가지고 있지 않을 때, 내 메모리에 저장된 주소를 타고 상위 객체(prototype에 연결되어있는 객체)의 메모리 영역으로 이동해서 그 데이터를 빌려오는 것이다.&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;아까 Object.create로 객체를 생성했을때를 생각해보자.&lt;/p&gt;
&lt;pre id=&quot;code_1772692314229&quot; class=&quot;angelscript&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;1. child 객체(0x222) 자체에서 gold 찾기
2. 없으면 child.[[Prototype]] &amp;rarr; parent
3. parent (0x111)에서 gold 발견 &amp;rarr; 100 반환&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;new의 동작&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이런식으로 new 를 이용하면 prototype을 연결하는 것 뿐만 아니라, constructor를 실행한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 69.186%; height: 92px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignCenter&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 24.7825%; text-align: center;&quot;&gt;&lt;b&gt;방식&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 34.1176%; text-align: center;&quot;&gt;&lt;b&gt;prototype 연결&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 41.6426%; text-align: center;&quot;&gt;&lt;b&gt;constructor 실행&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 24.7825%; text-align: center;&quot;&gt;new&lt;/td&gt;
&lt;td style=&quot;width: 34.1176%; text-align: center;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;width: 41.6426%; text-align: center;&quot;&gt;O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 24.7825%; text-align: center;&quot;&gt;Object.create()&lt;/td&gt;
&lt;td style=&quot;width: 34.1176%; text-align: center;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;width: 41.6426%; text-align: center;&quot;&gt;X&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1772691482260&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const d = new Dog(&quot;puppy&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;javascript에서 new를 이용해 객체를 생성하면 엔진 내부에서 아래와 같은 순서로 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 생성 -&amp;gt; prototype 연결 -&amp;gt; constructor 실행 -&amp;gt; 객체 반환&lt;/p&gt;
&lt;pre id=&quot;code_1772691552290&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//1. 빈 객체 생성
{}

//2. prototype 연결
obj.[[Prototype]] = Dog.prototype

//3. constructor 실행
Dog.call(obj, &quot;puppy&quot;)

//4. 객체 반환
return obj&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실상 아래와 같은 함수가 동작하는 거다&lt;/p&gt;
&lt;pre id=&quot;code_1772691569851&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function fakeNew(constructor, ...args) {

  const obj = Object.create(constructor.prototype);

  constructor.apply(obj, args);

  return obj;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정을 거쳐서 최종적으로 아래 구조를 갖는 객체가 탄생한다.&lt;/p&gt;
&lt;pre id=&quot;code_1772691641715&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;d
 ├─ name: &quot;puppy&quot;
 └─ [[Prototype]] &amp;rarr; Dog.prototype&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 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Prototype 상속&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트에서 상속이란 (prototype 기반 상속) 특정 인스턴스의 [[Prototype]] 포인터를 상위 객체를 가리키게 설정하는 것을 의미한다.&lt;/p&gt;
&lt;pre id=&quot;code_1772688096011&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Dog extends Animal {}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1772688107499&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Dog.prototype.__proto__ = Animal.prototype&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;span style=&quot;background-color: #ffffff;&quot;&gt;자바 스크립트에도 class라는 키워드는 있지만 이건 그냥 &lt;span style=&quot;color: #2c2b28; text-align: start;&quot;&gt;&lt;a style=&quot;background-color: #ffffff;&quot; href=&quot;https://blog.naver.com/magnking/220956399657&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Syntactic Sugar&lt;/a&gt;(사람 눈에만 예뻐보이는 문법) 라고 한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #2c2b28; text-align: start;&quot;&gt;굳이 Syntactic Sugar라고 말하는 이유는 C++이나 자바 같은 prototype기반 언어가 아닌 경우 class를 선언하는 것은 실제로 해당 타입을 만드는 개념이다.&lt;/span&gt;&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 style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #2c2b28; text-align: start;&quot;&gt;즉, C++과 JAVA와 같은 프로그래밍 언어의 상속은 class와 class 간의 type hierarchy의 개념이고&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #2c2b28; text-align: start;&quot;&gt;Javascript 에서의 상속은 object와 object 간의 prototype delegation의 개념이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1772690991617&quot; class=&quot;lua&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;┌──────────────┐
│ 배열 arr1    │  ┐
├──────────────┤  │
│ length: 0    │  │ arr1 객체
│ [[Prototype]]:──┼─&amp;rarr; 같은 메모리 주소 가리킴
└──────────────┘  │
                  │
┌──────────────┐  │
│ 배열 arr2    │  │
├──────────────┤  │
│ length: 0    │  │ arr2 객체
│ [[Prototype]]:──┼─&amp;rarr; (같은 Array.prototype)
└──────────────┘  │
                  │
        &amp;darr; 모두 가리키는 곳
┌────────────────────┐
│ Array.prototype    │  (하나만 메모리 존재)
├────────────────────┤
│ push: function     │
│ pop: function      │
│ slice: function    │
│ ...배열 메서드들   │
└────────────────────┘&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;pre id=&quot;code_1772693485004&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Object.prototype.toTest = function () { return 'test1' }
console.log( &quot;abc&quot;.toTest() );
// &quot;test1&quot;

function fn () {}
fn.prototype.name = 'test2'
var newFn = new fn();
console.log(newFn.name)
// &quot;test2&quot;
console.log(newFn.toTest());
// &quot;test1&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처 :&amp;nbsp;&lt;a href=&quot;https://velog.io/@huurray/Javascript%EB%8A%94-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85-%EA%B8%B0%EB%B0%98-%EC%96%B8%EC%96%B4%EC%9D%B4%EB%8B%A4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Javascript는 프로토타입 기반 언어이다&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;왜 이러는 거???&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 식으로 특정한 객체가 반복되어 인스턴스로 생성되면 딱 한번만 생성하고 이후부터는 생성된 객체를 복사해서 쓰자 라는 관점으로 접근하는 것이 프로토타입 패턴&lt;/p&gt;
&lt;pre id=&quot;code_1772693004115&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 이건 너무 객체 생성 비용이 높으니까...
Player evan = new Player();
Player john = new Player();
Player wilson = new Player();

// 이런 방법으로 접근해보는 것은 어떨까?
Player player = new Player();
Player evan = player.clone();
Player john = player.clone();
Player wilson = player.clone();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처 : &lt;a href=&quot;https://evan-moon.github.io/2019/10/23/js-prototype/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://evan-moon.github.io/2019/10/23/js-prototype/&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;h2 data-ke-size=&quot;size26&quot;&gt;참고&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://evan-moon.github.io/2019/10/23/js-prototype/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://evan-moon.github.io/2019/10/23/js-prototype/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@huurray/Javascript%EB%8A%94-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85-%EA%B8%B0%EB%B0%98-%EC%96%B8%EC%96%B4%EC%9D%B4%EB%8B%A4&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@huurray/Javascript%EB%8A%94-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85-%EA%B8%B0%EB%B0%98-%EC%96%B8%EC%96%B4%EC%9D%B4%EB%8B%A4&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>공부/JUN STUDY</category>
      <author>JUNFUTURE</author>
      <guid isPermaLink="true">https://juntheworld.tistory.com/247</guid>
      <comments>https://juntheworld.tistory.com/247#entry247comment</comments>
      <pubDate>Thu, 5 Mar 2026 15:45:05 +0900</pubDate>
    </item>
    <item>
      <title>JavaScript Object Property Lookup이란 (자바 스크립트 객체가 property를 찾는 순서)</title>
      <link>https://juntheworld.tistory.com/245</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;420&quot; data-origin-height=&quot;221&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGDRwv/dJMcadHSKAY/CaZsKGBDY2FV1XCkVHyAyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGDRwv/dJMcadHSKAY/CaZsKGBDY2FV1XCkVHyAyk/img.png&quot; data-alt=&quot;ㅇㄱ ㅈㅉㅇㅇ???&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGDRwv/dJMcadHSKAY/CaZsKGBDY2FV1XCkVHyAyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGDRwv%2FdJMcadHSKAY%2FCaZsKGBDY2FV1XCkVHyAyk%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;420&quot; height=&quot;221&quot; data-origin-width=&quot;420&quot; data-origin-height=&quot;221&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ㅇㄱ ㅈㅉㅇㅇ???&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;Javascript를 보면 위와 같은 충격적인 상황을 마주할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;이것이 가능한 이유는 JavaScript는 모든 것이 객체이고 객체의 property를 찾을때 자바스크립트 엔진은 spec에 근거한 lookup 과정을 거치기 때문이다.&lt;/p&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;배열의 arr[index] 접근도 일반 객체의 property lookup과 같은 규칙을 따르기 때문이다. property lookup이라 함은 특정한 객체의 property를 찾는 과정을 의미하는데, 자바스크립트의 특정 객체 인스턴스의 property를 탐색하는 순서가 있다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1772693749092&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. obj 자체에 property 있는지 확인
2. 없으면 obj.[[Prototype]] 로 이동
3. 거기서 property 찾기
4. 계속 반복
5. 끝까지 없으면 undefined&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;이게 property를 찾는 순서인데, 이 과정을 property lookup이라고 부른다.&lt;/p&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;173&quot; data-start=&quot;0&quot; data-ke-size=&quot;size20&quot;&gt;Prototype-based Inheritance&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Prototype이랑 property랑 단어가 비슷해서 헷갈리지 집중해서 보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;javascript는 prototype-based inheritance를 디자인 패턴으로 채택했다.&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;a href=&quot;https://juntheworld.tistory.com/247&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://juntheworld.tistory.com/247&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1772694364531&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Javascript의 객체와 prototype inheritance(프로토타입 기반 상속)&quot; data-og-description=&quot;들어가며javascript 는 프로토타입 기반 객체지향 프로그래밍 언어이다.프로토타입이 뭘까? Prototype의 의미중복으로 사용되는 곳이 너무 많아 정리한다1. 일반 공학에서의 prototype : 최종 제품을 만&quot; data-og-host=&quot;juntheworld.tistory.com&quot; data-og-source-url=&quot;https://juntheworld.tistory.com/247&quot; data-og-url=&quot;https://juntheworld.tistory.com/247&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cqHhxw/dJMb8XR3pXp/g0uYAzb9XxsjK7lNmFc730/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bB36O3/dJMb8Wexqt0/awXmGuQ2H8Tcriuzg60cBK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/yr917/dJMb8UHMXkj/p7vmsHgSPLPL9HgDOkXpwk/img.jpg?width=1440&amp;amp;height=1439&amp;amp;face=0_0_1440_1439&quot;&gt;&lt;a href=&quot;https://juntheworld.tistory.com/247&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://juntheworld.tistory.com/247&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cqHhxw/dJMb8XR3pXp/g0uYAzb9XxsjK7lNmFc730/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bB36O3/dJMb8Wexqt0/awXmGuQ2H8Tcriuzg60cBK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/yr917/dJMb8UHMXkj/p7vmsHgSPLPL9HgDOkXpwk/img.jpg?width=1440&amp;amp;height=1439&amp;amp;face=0_0_1440_1439');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Javascript의 객체와 prototype inheritance(프로토타입 기반 상속)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;들어가며javascript 는 프로토타입 기반 객체지향 프로그래밍 언어이다.프로토타입이 뭘까? Prototype의 의미중복으로 사용되는 곳이 너무 많아 정리한다1. 일반 공학에서의 prototype : 최종 제품을 만&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;juntheworld.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;자바스크립트의 모든 객체(배열 포함)는 내부적으로 다른 객체를 가리키는 [[Prototype]]이라는 포인터를 가지고 배열의 경우, 그 [[Prototype]]이 Array.prototype 이다.&lt;/p&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1772694461315&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;┌──────────────┐
│ 배열 arr1    │  ┐
├──────────────┤  │
│ length: 0    │  │ arr1 객체
│ [[Prototype]]:──┼─&amp;rarr; 같은 메모리 주소 가리킴
└──────────────┘  │
                  │
┌──────────────┐  │
│ 배열 arr2    │  │
├──────────────┤  │
│ length: 0    │  │ arr2 객체
│ [[Prototype]]:──┼─&amp;rarr; (같은 Array.prototype)
└──────────────┘  │
                  │
        &amp;darr; 모두 가리키는 곳
┌────────────────────┐
│ Array.prototype    │  (하나만 메모리 존재)
├────────────────────┤
│ push: function     │
│ pop: function      │
│ slice: function    │
│ ...배열 메서드들   │
└────────────────────┘&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;173&quot; data-start=&quot;0&quot; data-ke-size=&quot;size20&quot;&gt;Property&amp;nbsp;Lookup&lt;/h4&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;이걸 생각하고 위의 코드를 다시 보면&lt;/p&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;arr[0] &amp;rarr; 없음 &amp;rarr; Array.prototype[0] &amp;rarr; 있음(999 가져옴)&lt;/p&gt;
&lt;p data-end=&quot;173&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;이런 식으로 동작한 것이다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1772693955019&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;arr
├─ elements: []
├─ length: 0
└─ [[Prototype]]: ──┐
                    &amp;darr;
         Array.prototype
         ├─ '0': 999  &amp;larr; 이걸 찾음!
         ├─ 'length': (함수)
         ├─ 'push': (함수)
         └─ [[Prototype]]: Object.prototype&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;property를 찾는 obj에 never assigned element (arr[0]) 가 있어도(즉, property가 없어도)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;javascript는 spec 상으로 prototype chain을 찾아보게 설계되어있다.&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>공부/JUN STUDY</category>
      <author>JUNFUTURE</author>
      <guid isPermaLink="true">https://juntheworld.tistory.com/245</guid>
      <comments>https://juntheworld.tistory.com/245#entry245comment</comments>
      <pubDate>Wed, 4 Mar 2026 18:05:52 +0900</pubDate>
    </item>
    <item>
      <title>리눅스 권한 이제는 좀 이해하기 (Owner, Group, Other과 프로세스 권한 ruid, euid, suid 까지)</title>
      <link>https://juntheworld.tistory.com/244</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스 권한을 이해할때 크게&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0. 권한은 파일(리눅스에서는 디렉터리도 파일이다)에 부여된다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 어떤 권한이 있는가 (rwx)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 누구에게 그 권한이 있는가 (owner, group, other)&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번 rwx는 표현법만 익히면 되는거니 그냥 넘어가고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;owner, group, other 개념을 확실히 익혀보자.&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-origin-width=&quot;800&quot; data-origin-height=&quot;696&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cweT38/dJMcaiWIsSg/uieWZ6kENAJOlix3dIV6yK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cweT38/dJMcaiWIsSg/uieWZ6kENAJOlix3dIV6yK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cweT38/dJMcaiWIsSg/uieWZ6kENAJOlix3dIV6yK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcweT38%2FdJMcaiWIsSg%2FuieWZ6kENAJOlix3dIV6yK%2Fimg.jpg&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;800&quot; height=&quot;696&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;696&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;바로 예제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 파일들이 있다고 했을때 (ls -l로 확인가능하다)&lt;/p&gt;
&lt;pre id=&quot;code_1772583837268&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-r-------- 1 pwned pwned      69 flag-4a366de5f9250ee00973d579cd8a9e87
-r-sr-x--- 1 pwned pwn   17552 flag_reader-2b6cfa9d53f87254b7c90bbd12d17ab6
-rwxr-xr-x 1 root  root     30 run.sh
-rw-r--r-- 1 root  root    534 runner.py
drwxr-xr-x 4 pwn   pwn    4096 x64.release
-rw-r--r-- 1 root  root 59528158 x64.release.zip&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;flag 파일의 경우 owner 에게만 r 권한이 있다. (400)&lt;/p&gt;
&lt;pre id=&quot;code_1772583970972&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-r--------&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1772583978619&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;- r-- --- ---
│ │   │   │
│ │   │   └ other
│ │   └ group
│ └ owner
└ file type&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그다음 숫자&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1772584024844&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1 pwned pwned      69 flag-4a366de5f9250ee00973d579cd8a9e87&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은 hard link 갯수 이다 (ln file file2) 했을때 쌓인다.&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;그다음에 pwned pwned가 &lt;b&gt;순서대로&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;owner / group이 누군지를&lt;/b&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;owner? group? other?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;owner -&amp;gt; 파일을 만들거나 소유권을 가진 user&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;group -&amp;gt; 유저들을 묶은 그룹 : 그룹 권한이 적용됨. 리눅스에서 유저는 owner가 될 자격을 가진 개인이면서 group에 속할 수 있는 개인이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;other -&amp;gt; owner도 아니고 group도 아닌 모든 user (외부 프로세스에서 접속한 사람 등등)&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;Local Privilege Escalation&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 이 글을 쓰게 된 것이 LPE를 이해하기 위함인데,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 아래와 같이 RCE를 성공한 상황을 가정해보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;739&quot; data-origin-height=&quot;222&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bR3QXV/dJMcahcsOBG/V5AuAadg3S28yvEeB2FlH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bR3QXV/dJMcahcsOBG/V5AuAadg3S28yvEeB2FlH0/img.png&quot; data-alt=&quot;RCE 직후 cat flag를 하면 permission deny가 떴다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bR3QXV/dJMcahcsOBG/V5AuAadg3S28yvEeB2FlH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbR3QXV%2FdJMcahcsOBG%2FV5AuAadg3S28yvEeB2FlH0%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;739&quot; height=&quot;222&quot; data-origin-width=&quot;739&quot; data-origin-height=&quot;222&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;RCE 직후 cat flag를 하면 permission deny가 떴다.&lt;/figcaption&gt;
&lt;/figure&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;지금 ctf 문제에서는 문제 바이너리를 프로세스로 실행하는 유저는 pwn이고 flag 파일 만들어둔 주체(owner)는 pwned고 ./flag reader로 pwned 권한을 얻어서 읽는것이다.&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;위 디렉터리에서 flag_reader는 아래와 같은 코드로 표현할 수 있는데&lt;/p&gt;
&lt;pre id=&quot;code_1772585895523&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

int main(int argc, char **argv, char **envp)
{
    uid_t euid1;
    uid_t euid2;

    euid1 = geteuid();
    euid2 = geteuid();

    setreuid(euid2, euid1);

    system(&quot;/bin/bash&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;이제 이 코드를 하나하나 이해하면 LPE를 이해할 수 있을거다.&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;geteuid() 를 이용해 현재 프로세스의 effective UID를 가져온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;질문 1. effective UID가 뭔가???&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;setreuid()는 프로세스가 가지는 UID 값 read uid와 effective uid를 동시에 변경한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;질문 2. 프로세스가 UID를 가진다?&lt;br /&gt;질문 3. read uid와 effective uid가 뭔가?&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;setreuid()는 현재 프로세스가 사용하는 UID credential(ruid,euid)을 바꿔서 프로세스의 권한 컨텍스트를 변경하는 함수다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;질문 4. UID credentail이 뭔가??&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;UID(UserID) credentail - 프로세스가 가지는 권한&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스에서 커널이 권한을 체크할때 &quot;유저의 권한&quot;을 보는 것이 아니라 &quot;프로세스에 붙어있는 UID credentail&quot;을 본다.&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;예를 들어 cat flag 명령을 RCE 이후에 특정 프로세스 권한을 이용해 연 쉘에서 수행한다고해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 아래와 같이 커널 syscall을 이용해서 파일을 읽는다(파일을 읽는다는게 syscall 필요하니까)&lt;/p&gt;
&lt;pre id=&quot;code_1772586422588&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cat &amp;rarr; open(&quot;flag&quot;)
      &amp;rarr; syscall open()
      &amp;rarr; kernel&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_1772586483363&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;process = current
euid = process-&amp;gt;cred-&amp;gt;euid # 현재 프로세스 uid
inode_owner = file-&amp;gt;inode-&amp;gt;uid # 열려는 파일의 uid

if (euid == inode_owner) # 둘이 같음?? 
    owner permission 적용&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;왜???????? &lt;span style=&quot;color: #f3c000;&quot;&gt;유저 권한 매번 확인하면 되는거 아니냐?&lt;/span&gt; - UNIX의 설계철학이다. &quot;process delegation&quot; 권한 모델.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;권한은 &amp;ldquo;프로세스 실행 시점에 결정&amp;rdquo;된다. 유저의 권한은 프로세스 생성 시점에 위임 (delegation) 되는 설계철학.&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;ruid/euid/suid 이야기는 이미 프로그램이 실행된 이후의 프로세스 credential 상태를 말하는 것이고, 거기까지 오려면 그 이전 단계에서 반드시 유저가 파일을 +x 할 수 있는 권한 체크가 통과되어야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1772586944683&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;process
 └ credentials
      ├ ruid  (real uid) # 이 프로세스를 실행한 실제 사용자
      ├ euid  (effective uid) # 커널이 권한 체크할 때 사용하는 uid
      └ suid  (saved uid) # 이전 privilege를 복구하기 위해 저장하는 uid&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;suid???? - 이전 권한을 복구하기 위해 저장??????&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;pre id=&quot;code_1772587184163&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. config file 읽기
2. user input 처리
3. privileged 작업&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_1772587262339&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-rwsr-xr-x root root program&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1772587227338&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 권한을 내려놓음 (drop privilege)
seteuid(ruid);

ruid = user
euid = user
suid = root

# 다시 올림
seteuid(suid);

ruid = user
euid = root
suid = root

# suid가 없으면 
seteuid(user)
# root 권한 영구적으로 잃음&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(suid 얘기 끝)&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; LPE를 하고 싶으면 실행중인 프로그램의 uid를 바꿔주면 된다.&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;처음 RCE를 했을때 Permission Deny가 되는 원리는&lt;/p&gt;
&lt;pre id=&quot;code_1772586795548&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# RCE로 shell 따기 성공
/bin/sh
uid=1000(pwn)

# 현재 프로세스(/bin/sh의 uid - RCE성공한 프로세스의 uid 상속)
ruid = 1000
euid = 1000

# 커널 명령 수행
cat flag

# 커널 딴 체크 -&amp;gt; 파일 권한이랑 안맞음
process.euid = 1000
flag owner = 1001

Permission denied&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;setuid를 실행하면 해당 프로세스의 euid를 바꿔버려서 아래와 같이 되어버리는 것&lt;/p&gt;
&lt;pre id=&quot;code_1772586857323&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./flag_reader

ruid = 1000 (pwn)
euid = 1001 (pwned) # 이게 바뀜

# 커널 체크 성공!
process.euid = 1001
flag owner = 1001&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;flag_reader의 권한은&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;-r-sr-x--- 1 pwned pwn 17552 May 4 2023 flag_reader-2b6cfa9d53f87254b7c90bbd12d17ab6&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 data-ke-size=&quot;size16&quot;&gt;여기서 owner의 s 권한이 바로 setuid buit 인데 -&amp;gt; 이 비트가 있으면 프로세스의 euid를 파일 owner의 UID로 바꾼다.&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_1772587674827&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1 execute permission 체크 -&amp;gt; +x 권한 있음?
2 setuid bit 처리 =? +s 권한 있음? 있으면 실행 후 euid 권한 owner로 변경
3 프로세스 시작&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;따라서 flag_reader를 실행하면 프로세스의 uid가 아래와 같이 세팅된다.&lt;/p&gt;
&lt;pre id=&quot;code_1772587729363&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ruid = pwn
euid = pwned
suid = pwned&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;아래가 이제 euid를 가져와서 ruid랑 euid 둘 다 지금 euid로 바꿔버리겠다 (setreuid)라는 명령어인데, 그 이유는 bash 보안 로직 내부에 setuid 환경을 감지 (ruid != euid) 인 경우 privilege drop을 시도하는 경우가 있기 때문이라고 한다. (충분히 상식적인 보안로직)&lt;/p&gt;
&lt;pre id=&quot;code_1772587752139&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    uid_t euid1;
    uid_t euid2;

    euid1 = geteuid();
    euid2 = geteuid();

    setreuid(euid2, euid1);&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_1772587898091&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ruid = pwn
euid = pwned
suid = pwned&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;h4 data-ke-size=&quot;size20&quot;&gt;참고.. setreuid 의 존재 이유에 대해&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스 권한(privilege)은 euid로 확인한다면서 프로세스 내부에서 ruid까지 바꿔버리는 setreuid 이런 함수를 만든 이유가 뭘까?&lt;/p&gt;
&lt;pre id=&quot;code_1772588154603&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ruid = identity
euid = privilege&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;ruid가 identity 역할로 프로세스가 identity를 바꿀 필요가 있다는 뜻인데.. 어쩌피 프로세스의 privilege는 euid로 검사하는데, 프로세스가 직접 함수 호출을 이용해서 identity를 변환해야되는 이유가 뭐냐는 말이다.&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;user에게 아예 ownership을 넘기는 경우가 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;identity 까지 넘겨버리는.. 예를들면 로그인과 웹서버, 그리고 UNIX에 일부 시스템 콜 kill ptrace 같은 경우에 ruid도 검증을 한다고 한다. 이럴때는 ruid와 euid까지 넘겨버리는 것.&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;</description>
      <category>공부/이모저모</category>
      <author>JUNFUTURE</author>
      <guid isPermaLink="true">https://juntheworld.tistory.com/244</guid>
      <comments>https://juntheworld.tistory.com/244#entry244comment</comments>
      <pubDate>Wed, 4 Mar 2026 10:31:53 +0900</pubDate>
    </item>
    <item>
      <title>Type Casting과 Type Punning의 차이</title>
      <link>https://juntheworld.tistory.com/243</link>
      <description>&lt;h2 data-path-to-node=&quot;3&quot; data-ke-size=&quot;size26&quot;&gt;Cast (형변환): &quot;데이터의 의미를 유지하며 형태를 바꿈&quot;&lt;/h2&gt;
&lt;p data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;Cast는 데이터를 다른 타입으로 바꾸되, 그 값(Value)의 의미가 유지되도록 비트를 재구성하는 과정&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;5&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;동작: 컴퓨터가 CPU 연산을 통해 비트 패턴을 새로 만듬&lt;/li&gt;
&lt;li&gt;예시: 정수 1을 실수 1.0으로 캐스팅할 때.
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;5,1,1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정수 1: 0x00000001&lt;/li&gt;
&lt;li&gt;실수 1.0: 0x3f800000 (IEEE 754 방식)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 비트 패턴이 완전히 달라졌지만, 인간이 읽는 '값'은 여전히 1&lt;/p&gt;
&lt;h2 data-path-to-node=&quot;6&quot; data-ke-size=&quot;size26&quot;&gt;Punning (타입 퍼닝): &quot;비트는 그대로 두고 해석만 바꿈&quot;&lt;/h2&gt;
&lt;p data-path-to-node=&quot;7&quot; data-ke-size=&quot;size16&quot;&gt;Punning은 메모리에 저장된 비트 패턴을 단 1비트도 건드리지 않고, 그것을 바라보는 타입만 바꿔서 읽는 기법&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;8&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;동작: 추가적인 CPU 연산(번역) 없이, 메모리 주소에 있는 값을 그대로 가져와 다른 타입으로 우깁니다.&lt;/li&gt;
&lt;li&gt;예시: 정수 1065353216 (0x3f800000)이 들어있는 메모리를 실수 타입으로 퍼닝할 때.
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;8,1,1&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메모리: 0x3f800000&lt;/li&gt;
&lt;li&gt;결과: 1.0이라는 실수&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 메모리 내부 비트 패턴은 똑같지만, 해석된 '값'은 완전히 달라짐&lt;/p&gt;</description>
      <category>Master Piece of jun/컴퓨터구조</category>
      <author>JUNFUTURE</author>
      <guid isPermaLink="true">https://juntheworld.tistory.com/243</guid>
      <comments>https://juntheworld.tistory.com/243#entry243comment</comments>
      <pubDate>Wed, 25 Feb 2026 11:04:57 +0900</pubDate>
    </item>
    <item>
      <title>VMware 에서 Ubuntu 디스크 용량 늘린 후에 적용하는법</title>
      <link>https://juntheworld.tistory.com/242</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;Vmware나 Naver Cloud 등에서 Disk 크기를 조정한다&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;749&quot; data-origin-height=&quot;459&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zfNNE/dJMcah4x6Q0/FVpLc2LOVBrJNFAiUdiJBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zfNNE/dJMcah4x6Q0/FVpLc2LOVBrJNFAiUdiJBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zfNNE/dJMcah4x6Q0/FVpLc2LOVBrJNFAiUdiJBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzfNNE%2FdJMcah4x6Q0%2FFVpLc2LOVBrJNFAiUdiJBK%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;749&quot; height=&quot;459&quot; data-origin-width=&quot;749&quot; data-origin-height=&quot;459&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Ubuntu Disk 용량 늘리기 -&amp;gt; Ubuntu 내부 Disk Setting 이용하면 가능!&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kysf.tistory.com/20&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kysf.tistory.com/20&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1771920371481&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Ubuntu 디스크 용량 늘리는 방법&quot; data-og-description=&quot;STEP 1. VMware 설정에서 용량 확장1) 수정하고자 하는 machine의 설정 페이지에 들어간다.&amp;quot;Edit virtual machine settings&amp;quot;&amp;nbsp;2) 현재 할당된 Hard Disk의 용량을 확인후, Expand 버튼을 클릭한다.&amp;nbsp;3) 늘리고자 하는 크&quot; data-og-host=&quot;kysf.tistory.com&quot; data-og-source-url=&quot;https://kysf.tistory.com/20&quot; data-og-url=&quot;https://kysf.tistory.com/20&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bV1tqF/dJMb8YpSpI8/d5ubK06ZKRJ0h7vkZ0JaF0/img.png?width=800&amp;amp;height=394&amp;amp;face=0_0_800_394,https://scrap.kakaocdn.net/dn/bWwLn1/dJMb83kpUYW/rZ7ce7ZZPjAT1mSMkHBy40/img.png?width=800&amp;amp;height=394&amp;amp;face=0_0_800_394,https://scrap.kakaocdn.net/dn/pYeXO/dJMb86nUxaK/a85FCbilp81jX3WMcBhi21/img.png?width=1920&amp;amp;height=947&amp;amp;face=0_0_1920_947&quot;&gt;&lt;a href=&quot;https://kysf.tistory.com/20&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://kysf.tistory.com/20&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bV1tqF/dJMb8YpSpI8/d5ubK06ZKRJ0h7vkZ0JaF0/img.png?width=800&amp;amp;height=394&amp;amp;face=0_0_800_394,https://scrap.kakaocdn.net/dn/bWwLn1/dJMb83kpUYW/rZ7ce7ZZPjAT1mSMkHBy40/img.png?width=800&amp;amp;height=394&amp;amp;face=0_0_800_394,https://scrap.kakaocdn.net/dn/pYeXO/dJMb86nUxaK/a85FCbilp81jX3WMcBhi21/img.png?width=1920&amp;amp;height=947&amp;amp;face=0_0_1920_947');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Ubuntu 디스크 용량 늘리는 방법&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;STEP 1. VMware 설정에서 용량 확장1) 수정하고자 하는 machine의 설정 페이지에 들어간다.&quot;Edit virtual machine settings&quot;&amp;nbsp;2) 현재 할당된 Hard Disk의 용량을 확인후, Expand 버튼을 클릭한다.&amp;nbsp;3) 늘리고자 하는 크&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;kysf.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;895&quot; data-origin-height=&quot;594&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zyUqg/dJMcagq1A1Y/arfiGG6Lg4xWtIFeQVbxT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zyUqg/dJMcagq1A1Y/arfiGG6Lg4xWtIFeQVbxT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zyUqg/dJMcagq1A1Y/arfiGG6Lg4xWtIFeQVbxT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzyUqg%2FdJMcagq1A1Y%2FarfiGG6Lg4xWtIFeQVbxT1%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;895&quot; height=&quot;594&quot; data-origin-width=&quot;895&quot; data-origin-height=&quot;594&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;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;890&quot; data-origin-height=&quot;441&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EjhEO/dJMcajuuE9O/4ncfjPt3WekyMaKAKZphv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EjhEO/dJMcajuuE9O/4ncfjPt3WekyMaKAKZphv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EjhEO/dJMcajuuE9O/4ncfjPt3WekyMaKAKZphv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEjhEO%2FdJMcajuuE9O%2F4ncfjPt3WekyMaKAKZphv0%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;890&quot; height=&quot;441&quot; data-origin-width=&quot;890&quot; data-origin-height=&quot;441&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>공부/이모저모</category>
      <author>JUNFUTURE</author>
      <guid isPermaLink="true">https://juntheworld.tistory.com/242</guid>
      <comments>https://juntheworld.tistory.com/242#entry242comment</comments>
      <pubDate>Tue, 24 Feb 2026 17:09:05 +0900</pubDate>
    </item>
    <item>
      <title>V8(d8) 빌드 및 gdb를 이용한 디버깅 방법</title>
      <link>https://juntheworld.tistory.com/240</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;타겟 빌드&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;V8 빌드 도구(depot_tools) 다운&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ninja나 관련된 모든 빌드 도구들이 depot_tools에 들어있다.&lt;/p&gt;
&lt;pre id=&quot;code_1771807147813&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH=$PATH:$(pwd)/depot_tools&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;V8 소스코드 다운&lt;/h3&gt;
&lt;pre id=&quot;code_1771807230310&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fetch v8
cd v8
# 특정 CVE가 수정되기 전의 특정 커밋으로 이동 (예: 2024년 3월 중순)
git checkout 28877c5520
gclient sync&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;819&quot; data-origin-height=&quot;132&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDf5Vo/dJMcaioP7a4/iUM5cjYu3wkhszsKHLJHCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDf5Vo/dJMcaioP7a4/iUM5cjYu3wkhszsKHLJHCK/img.png&quot; data-alt=&quot;예를 들어) CVE-2024-2887의 경우 패치전 (취약버전)이 28877c5520 커밋&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDf5Vo/dJMcaioP7a4/iUM5cjYu3wkhszsKHLJHCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDf5Vo%2FdJMcaioP7a4%2FiUM5cjYu3wkhszsKHLJHCK%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;819&quot; height=&quot;132&quot; data-origin-width=&quot;819&quot; data-origin-height=&quot;132&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;예를 들어) CVE-2024-2887의 경우 패치전 (취약버전)이 28877c5520 커밋&lt;/figcaption&gt;
&lt;/figure&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;h3 data-ke-size=&quot;size23&quot;&gt;V8 빌드 (d8 쉘 생성)&lt;/h3&gt;
&lt;pre id=&quot;code_1771807319366&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./tools/dev/gm.py x64.debug
./tools/dev/gm.py x64.release&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;V8 실행&lt;/h3&gt;
&lt;pre id=&quot;code_1771807461302&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./out.gn/x64.release/d8 *.js
# 혹은
./out/x64.release/d8 *.js&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;834&quot; data-origin-height=&quot;240&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QeVCK/dJMcagLklNB/Xu337eJn42mPQN3DzUEJOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QeVCK/dJMcagLklNB/Xu337eJn42mPQN3DzUEJOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QeVCK/dJMcagLklNB/Xu337eJn42mPQN3DzUEJOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQeVCK%2FdJMcagLklNB%2FXu337eJn42mPQN3DzUEJOk%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;834&quot; height=&quot;240&quot; data-origin-width=&quot;834&quot; data-origin-height=&quot;240&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;V8 디버깅&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;v8을 디버깅한다는 것은 v8의 쉘 역할을 해주는 d8 바이너리를 이용해서 .js 코드의 동작을 해석하는 브라우저 엔진의 동작을 분석한다는 뜻이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;645&quot; data-origin-height=&quot;65&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cWQE3A/dJMcaaqNAlS/UkhenA3ekMKPmLzf7o52bk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cWQE3A/dJMcaaqNAlS/UkhenA3ekMKPmLzf7o52bk/img.png&quot; data-alt=&quot;d8은 리눅스 바이너리(ELF)다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cWQE3A/dJMcaaqNAlS/UkhenA3ekMKPmLzf7o52bk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcWQE3A%2FdJMcaaqNAlS%2FUkhenA3ekMKPmLzf7o52bk%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;645&quot; height=&quot;65&quot; data-origin-width=&quot;645&quot; data-origin-height=&quot;65&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;d8은 리눅스 바이너리(ELF)다&lt;/figcaption&gt;
&lt;/figure&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;d8은 리눅스 바이너리이기 때문에 gdb를 이용해서 디버깅이 당연히 가능하다. 근데 이제 .js 파일을 인자로 받아서. 따라서 gdb를 실행할때 인자로 .js 파일을 넘겨주어여야 한다는 것만 생각하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1771808001045&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gdb &amp;lt;d8 바이너리&amp;gt;
# 이 시점에 브레이크 포인트 걸기
r --allow-natives-syntax &amp;lt;.js파일&amp;gt;&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;660&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MEViT/dJMcafyS5mn/00dSI7TWDiyasbNExQPAKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MEViT/dJMcafyS5mn/00dSI7TWDiyasbNExQPAKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MEViT/dJMcafyS5mn/00dSI7TWDiyasbNExQPAKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMEViT%2FdJMcafyS5mn%2F00dSI7TWDiyasbNExQPAKK%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;537&quot; height=&quot;660&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;660&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;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;트러블 슈팅&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;python3 /home/jun/CVE-2024-2887/v8/build/config/linux/pkg-config.py -s ../../build/linux/debian_bullseye_amd64-sysroot -a x64 glib-2.0 gmodule-2.0 gobject-2.0 gthread-2.0&lt;/h3&gt;
&lt;pre id=&quot;code_1771807382630&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;➜&amp;nbsp; v8 git:(afe6883a2a5) ./tools/dev/gm.py x64.debug
# mkdir -p /home/jun/CVE-2024-2887/v8/out/x64.debug
# echo &amp;gt; /home/jun/CVE-2024-2887/v8/out/x64.debug/args.gn &amp;lt;&amp;lt; EOF
is_component_build = true
is_debug = true
symbol_level = 2
target_cpu = &quot;x64&quot;
v8_enable_sandbox = true
v8_enable_backtrace = true
v8_enable_fast_mksnapshot = true
v8_enable_slow_dchecks = true
v8_optimized_debug = false
EOF
# gn gen out/x64.debug
ERROR at //build/config/linux/pkg_config.gni:152:19: Script returned non-zero exit code.
&amp;nbsp; &amp;nbsp; &amp;nbsp; pkgresult = exec_script(pkg_config_script, _script_args, &quot;json&quot;)
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ^----------
Current dir: /home/jun/CVE-2024-2887/v8/out/x64.debug/
Command: python3 /home/jun/CVE-2024-2887/v8/build/config/linux/pkg-config.py -s ../../build/linux/debian_bullseye_amd64-sysroot -a x64 glib-2.0 gmodule-2.0 gobject-2.0 gthread-2.0
Returned 1.
stderr:

Traceback (most recent call last):
&amp;nbsp; File &quot;/home/jun/CVE-2024-2887/v8/build/config/linux/pkg-config.py&quot;, line 252, in &amp;lt;module&amp;gt;
&amp;nbsp; &amp;nbsp; sys.exit(main())
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;^^^^^^
&amp;nbsp; File &quot;/home/jun/CVE-2024-2887/v8/build/config/linux/pkg-config.py&quot;, line 142, in main
&amp;nbsp; &amp;nbsp; prefix = GetPkgConfigPrefixToStrip(options, args)
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
&amp;nbsp; File &quot;/home/jun/CVE-2024-2887/v8/build/config/linux/pkg-config.py&quot;, line 80, in GetPkgConfigPrefixToStrip
&amp;nbsp; &amp;nbsp; prefix = subprocess.check_output([options.pkg_config,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
&amp;nbsp; File &quot;/home/jun/CVE-2024-2887/depot_tools/bootstrap-2@3.11.8.chromium.35_bin/python3/lib/python3.11/subprocess.py&quot;, line 466, in check_output
&amp;nbsp; &amp;nbsp; return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
&amp;nbsp; File &quot;/home/jun/CVE-2024-2887/depot_tools/bootstrap-2@3.11.8.chromium.35_bin/python3/lib/python3.11/subprocess.py&quot;, line 548, in run
&amp;nbsp; &amp;nbsp; with Popen(*popenargs, **kwargs) as process:
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;^^^^^^^^^^^^^^^^^^^^^^^^^^^
&amp;nbsp; File &quot;/home/jun/CVE-2024-2887/depot_tools/bootstrap-2@3.11.8.chromium.35_bin/python3/lib/python3.11/subprocess.py&quot;, line 1026, in __init__
&amp;nbsp; &amp;nbsp; self._execute_child(args, executable, preexec_fn, close_fds,
&amp;nbsp; File &quot;/home/jun/CVE-2024-2887/depot_tools/bootstrap-2@3.11.8.chromium.35_bin/python3/lib/python3.11/subprocess.py&quot;, line 1953, in _execute_child
&amp;nbsp; &amp;nbsp; raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'pkg-config'

See //build/config/linux/BUILD.gn:58:3: whence it was called.
&amp;nbsp; pkg_config(&quot;glib&quot;) {
&amp;nbsp; ^-------------------
See //build/config/compiler/BUILD.gn:354:18: which caused the file to be included.
&amp;nbsp; &amp;nbsp; configs += [ &quot;//build/config/linux:compiler&quot; ]
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;^------------------------------&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;해결&lt;/h4&gt;
&lt;pre id=&quot;code_1771807366846&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install -y pkg-config libglib2.0-dev&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;Code TurboFan 최적화 안되어있을때&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 먼저 d8 실행시켜두고 gdb붙이기&lt;/p&gt;
&lt;pre id=&quot;code_1772079604551&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 실행
./x64.release/d8 --allow-natives-syntax ./ex.js

# 프로세스 id 찾기
ps aux | grep d8

# gdb 붙기
sudo gdb -p 82223&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Configuration</category>
      <category>D8</category>
      <category>V8</category>
      <category>V8디버깅</category>
      <category>V8빌드</category>
      <author>JUNFUTURE</author>
      <guid isPermaLink="true">https://juntheworld.tistory.com/240</guid>
      <comments>https://juntheworld.tistory.com/240#entry240comment</comments>
      <pubDate>Mon, 23 Feb 2026 09:54:35 +0900</pubDate>
    </item>
  </channel>
</rss>