<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Hyeon-Stone.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Mon, 27 Jun 2022 09:50:49 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. Hyeon-Stone.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/hyeon-stone" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[기본 개념]]></title>
            <link>https://velog.io/@hyeon-stone/%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90</link>
            <guid>https://velog.io/@hyeon-stone/%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90</guid>
            <pubDate>Mon, 27 Jun 2022 09:50:49 GMT</pubDate>
            <description><![CDATA[<p><span style="background-color: rgba(242,179,188,0.5)"><strong>기계어(Machine Language)</strong>: </span>
→ 컴퓨터에 명령을 내리기 위한 컴퓨터의 언어</p>
<p><span style="background-color: rgba(242,179,188,0.5)"><strong>어셈블리어(Assembly Language):</strong> </span>
→ 사람이 이해하기 쉬운 언어</p>
<p><span style="background-color: rgba(242,179,188,0.5)"><strong>어셈블러(Assembler):</strong> </span>
→ 기계어로 번역해주는 도구</p>
<p><span style="background-color: rgba(242,179,188,0.5)"><strong>컴파일러(Compiler)</strong>: </span>
→ C, C++, Go 등을 비롯해 어셈블리어 보다 이해하기 쉬운 언어들을 기계어로 번역해주는 도구 </p>
<p><span style="background-color: rgba(242,179,188,0.5)"><strong>프로그램(Program):</strong> </span>
→ 연산 장치가 수행해야 하는 동작을 정의한 일종의 문서</p>
<p><span style="background-color: rgba(242,179,188,0.5)"><strong>programmable:  </span>
→</strong> 사용자가 정의한 프로그램을 해성하여 명렁어를 처리할 수 있는 연산 장치
→ ex. 컴퓨터</p>
<p><span style="background-color: rgba(242,179,188,0.5)"><strong>바이너리(Binary):</strong>  </span>
→ 프로그램이 저장 장치에 binary 형태로 저장됨
→ 즉, 프로그램을 의미</p>
<hr>
<h2 id="컴파일러와-인터프리터"><strong>컴파일러와 인터프리터</strong></h2>
<p><span style="background-color: rgba(242,179,188,0.5)"><strong>프로그래밍 언어(Programing Language):</strong> </span>
→ 프로그램을 개발하기 위해 사용하는 언어
→ C,C++, GO와 같은 고급 언어와 어셈블리어, 기계어와 같은 저급 언어가 존재</p>
<p><span style="background-color: rgba(242,179,188,0.5)"><strong>소스코드(Source Code):</strong></span> 
→ CPU가 수행해야 할 명령들을 프로그래밍 언어로 작성한 것</p>
<p><span style="background-color: rgba(242,179,188,0.5)"><strong>컴파일 및 컴파일러(Comoplie/Compiler):</strong> </span> 
→ 소스코드를 컴퓨터가 이해할 수 있는 기계어의 형식으로 변역하는 것/
→ 컴파일 해주는 도구를 컴파일러라고 함
→ 컴파일의 정확한 의미는 Source Code를 Object Code로 번역하는 것</p>
<p><span style="background-color: rgba(242,179,188,0.5)"><strong>인터프리팅 및 인터프리터(Interpreting/Interpreter):</strong> </span> 
→ Python, Javascripts 등의 언어는 사용자의 입력 또는 사용자가 작성한 스크립트를 그때 그때 번역하여 CPU에 전달하는데, 이 동작이 통역과 비슷해 인터프리팅이라 불림
→ 이를 처리해주는 프로그램을 인터프리터라 함</p>
<hr>
<h2 id="컴파일-과정">컴파일 과정</h2>
<p>→ C언어는 일반적으로 전처리(Preprocess), 컴파일(Compile), 어셈블(Assemble), 링크(Link)의 과정을 거쳐 바이너리로 번역됨</p>
<h3 id="전처리preprocess"><strong>전처리(Preprocess)</strong></h3>
<p>→ 컴파일러가 소스 코드를 어셈블리어로 컴파일하기 전에, 필요한 형식으로 가공하는 과정</p>
<ol>
<li>주석 제거</li>
<li>매크로 치환
→ <code>#define</code> 으로 단어와 상수를 매칭해 논 것을 단어⇒상수로 바꾸는 작업</li>
<li>파일 병합
→ 여러개의 소스(.c)와 헤더(.h)를 합치는 작업</li>
</ol>
<p>→ <code>gcc</code>를 사용해 <code>-e</code>옵션을 주면 전처리 과정의 결과를 화면에 보여줌</p>
<p>→ <code>gcc -E add.c &gt; add.i</code> </p>
<pre><code class="language-c">// Name: add.h
int add(int a, int b);
// Name: add.c

#include &quot;add.h&quot;
#define HI 3
int add(int a, int b) { return a + b + HI; }  // return a+b
// Name: add.h
int add(int a, int b);</code></pre>
<pre><code># 1 &quot;add.c&quot;
# 1 &quot;&lt;built-in&gt;&quot;
# 1 &quot;&lt;command-line&gt;&quot;
# 31 &quot;&lt;command-line&gt;&quot;
# 1 &quot;/usr/include/stdc-predef.h&quot; 1 3 4
# 32 &quot;&lt;command-line&gt;&quot; 2
# 1 &quot;add.c&quot;
# 1 &quot;add.h&quot; 1
int add(int a, int b);
# 2 &quot;add.c&quot; 2
int add(int a, int b) { return a + b + 3; }</code></pre><h3 id="컴파일compile">컴파일(Compile)</h3>
<p>→ C로 작성된 소스 코드를 어셈블리어로 번역하는 것
→ 이 과정에서 소스코드의 문법을 검사하고, 오류가 있다면 컴파일을 멈추고 에러를 출력
→ gcc에서 <code>-O -O0 -O1 -O2 -O3 -Os -Ofast -Og</code>  등의 옵션으로 최적화 가능
→ <code>-S</code> 옵션으로 소스크드를 어셈블리 코드로 변환 가능</p>
<p>→ <code>gcc -S add.i -o add.S</code> </p>
<pre><code class="language-c">.file   &quot;add.c&quot;
        .intel_syntax noprefix
        .text
        .globl  add
        .type   add, @function
add:
.LFB0:
        .cfi_startproc
        push    rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        mov     rbp, rsp
        .cfi_def_cfa_register 6
        mov     DWORD PTR -4[rbp], edi
        mov     DWORD PTR -8[rbp], esi
        mov     edx, DWORD PTR -4[rbp]
        mov     eax, DWORD PTR -8[rbp]
        add     eax, edx
        add     eax, 3
        pop     rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size   add, .-add
        .ident  &quot;GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0&quot;
        .section        .note.GNU-stack,&quot;&quot;,@progbits</code></pre>
<h3 id="어셈블asemble">어셈블(Asemble)</h3>
<p>→ 컴파일로 생성된 어셈블리어 코드를 ELF 형식의 Object file(.o)로 변환하는 과정
→ 변환되고 나면 기계어로 번역되어 더 이상 해석하기 어려움
→ <code>-c</code> 옵션으로 컴파일 후 나온  <code>add.S</code> 파일을 Object file로 변환 가능</p>
<pre><code class="language-bash">file add.o
add.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
$ hexdump -C add.o
00000000  7f 45 4c 46 02 01 01 00  00 00 00 00 00 00 00 00  |.ELF............|
00000010  01 00 3e 00 01 00 00 00  00 00 00 00 00 00 00 00  |..&gt;.............|
00000020  00 00 00 00 00 00 00 00  10 02 00 00 00 00 00 00  |................|
00000030  00 00 00 00 40 00 00 00  00 00 40 00 0b 00 0a 00  |....@.....@.....|
00000040  55 48 89 e5 89 7d fc 89  75 f8 8b 55 fc 8b 45 f8  |UH...}..u..U..E.|
00000050  01 d0 5d c3 00 47 43 43  3a 20 28 55 62 75 6e 74  |..]..GCC: (Ubunt|
00000060  75 20 37 2e 35 2e 30 2d  33 75 62 75 6e 74 75 31  |u 7.5.0-3ubuntu1|
00000070  7e 31 38 2e 30 34 29 20  37 2e 35 2e 30 00 00 00  |~18.04) 7.5.0...|
00000080  14 00 00 00 00 00 00 00  01 7a 52 00 01 78 10 01  |.........zR..x..|
00000090  1b 0c 07 08 90 01 00 00  1c 00 00 00 1c 00 00 00  |................|
000000a0  00 00 00 00 14 00 00 00  00 41 0e 10 86 02 43 0d  |.........A....C.|
000000b0  06 4f 0c 07 08 00 00 00  00 00 00 00 00 00 00 00  |.O..............|
...</code></pre>
<h3 id="링크link">링크(Link)</h3>
<p>→ 어떤 목적 파일들을 연결하여 실행 가능한 바이너리로 만드는 과정</p>
<pre><code class="language-c">// Name: hello-world.c
// Compile: gcc -o hello-world hello-world.c
#include &lt;stdio.h&gt;
int main() { printf(&quot;Hello, world!&quot;); }</code></pre>
<p>→ <code>printf</code> 라는 함수가 호출이 되지만 해당 파일에 정의되어 있지 않음
→ <code>printf</code> 는 <code>libc</code> 라는 공유 라이브러리에 존재, 이는 gcc의 기본 라이브러리 경로에 있음
→ 링커는 바이너리가 <code>printf</code> 를 호출하면 libc의 함수가 실행될 수 있도록 연결해줌
→ 이 단계를 지나면 실행 가능한 프로그램이 완성</p>
<p>→ 위 어셈블 과정에서 나온 <code>add.o</code> 파일을 링크하는 명령어는 <code>gcc add.o -o add --unresolved-symbols=ignore-in-object-files</code> 이다. 
→ <code>--unresolved-symbols</code> 컴파일 옵션은 이 파일 안에 <code>main</code> 함수가 존재하지 않기 때문에 에러를 방지하기 위해 넣어준 옵션</p>
<hr>
<h2 id="디스어셈블과-디컴파일">디스어셈블과 디컴파일</h2>
<h3 id="디스어셈블disassemble">디스어셈블(Disassemble)</h3>
<p>→ 바이너리를 분석하기 위해 바이너리를 읽을 수 있어야함
→ 하지만 기계어를 이해하기 어렵기 때문에 이를 다시 어셈블리어로 번역하고자하는 기법</p>
<p>→ 즉, <code>Binary ⇒ Assemble Code ⇒ Source Code</code> 가 리버싱의 절차</p>
<h3 id="디컴파일decompile">디컴파일(Decompile)</h3>
<p>→ 규모가 크면 어셈블리 코드만으로 이해하기 힘듦
→ 어셈블리어보다 고급언어로 바이너리를 번역하는 것이 디컴파일
→ 디컴파일을 진행해주는 프로그램이 디컴파일러(Decompiler)</p>
<p>→ 최적화와 같은 과정에 의해 완벽하게 소스코드와 동일한 코드를 생성은 불가능에 가까움
→ 하지만 이 오차가 바이너리의 동작을 왜곡하지는 않기 때문에 디스어셈블러를 사용하는 것보다 압도적으로 효율적인 디컴파일러를 사용하는게 유리함</p>
<hr>
<hr>
<h1 id="static--dynamic-analysis">Static &amp; Dynamic Analysis</h1>
<h2 id="정적-분석static-analysis">정적 분석(Static Analysis)</h2>
<blockquote>
<p>외적인 관찰만을 통해 정보를 알아내는 것을 의미</p>
</blockquote>
<h3 id="장점">장점</h3>
<ol>
<li>전체 구조 파악이 쉬움
→ 프로그램이 어떤 함수로 구성되었는지
→ 함수들은 서로 어떤 호출 관계를 갖는지
→ 어떤 API를 사용하고 어떤 문자열을 포함하는 지</li>
<li>분석 환경의 제약에서 비교적 자유로움
→ apk와 같은 파일은 별도의 소프트웨어 없이는 시스템에서 실행할 수 없음</li>
<li>바이러스와 같은 악성 프로그램의 위협으로부터 안전함</li>
</ol>
<h3 id="단점">단점</h3>
<ol>
<li>난독화(Obfuscation)가 적용되면 분석이 매우 어려워짐</li>
<li>다양한 동적 요소를 고려하기 어려움
→ 인자 입력같은 경우</li>
</ol>
<h2 id="동적-분석dynamic-analysis">동적 분석(Dynamic Analysis)</h2>
<blockquote>
<p>실행을 통해 동작을 분석하는 것을 의미</p>
</blockquote>
<h3 id="장점-1">장점</h3>
<ol>
<li>코드를 자세히 분석해보지 않고도 프로그램의 개략적인 동작 파악 가능</li>
</ol>
<h3 id="단점-1">단점</h3>
<ol>
<li>분석환경을 구축하기 어려울 수 있음</li>
<li>안티 디버깅(Anti Debugging)을 사용해 디버깅을 방해하는 기법이 있음</li>
</ol>
<p>→ 어느 하나의 방법만 고수하는 것이 아닌 상황에 따라 적절한 방법을 탱해야 함</p>
<hr>
<p>[Reference : Dreamhack]</p>
]]></description>
        </item>
    </channel>
</rss>