본문 바로가기

Reversing

[Dreamhack] Computer Science

컴퓨터 구조 💻

: 컴퓨터가 효율적으로 작동할 수 있도록 HW 및 SW 기능을 고안하고, 이들을 구성하는 방법

 

1) 기능 구조에 대한 설계

: 컴퓨터가 연산을 효율적으로 하기 위해 어떤 기능들이 필요한지 고민하고 설계하는 분야

ex) 폰 노이만 구조, 하버드 구조, 수정된 하버드 구조 등

 

2) 명령어 집합구조 (Instruction Set Architecture, ISA)

: CPU가 사용하는 명령어와 관련된 설계

ex) ARM, MIPS, AVR, 인텔의 x86-64 아키텍처

 

3) 마이크로 아키텍처

: 정의된 명령어 집합을 효율적으로 처리할 수 있도록 CPU의 회로를 설계하는 분야

 

 

폰 노이만 구조

 

중앙처리장치 (Central Processing Unit, CPU) - 연산과 제어

: 프로그램의 연산을 처리하고 시스템을 제어하는 컴퓨터의 두뇌. 프로세스의 코드를 불러오고, 실행하고, 결과를 저장하는 일련의 과정을 수행.

* CPU의 연산속도는 주기억장치 및 보조기억장치와의 데이터 교환속도보다 압도적으로 빠르기 때문에, 이들만 사용하면 병목현상이 발생한다. 그래서 CPU는 데이터 교환 속도를 단축하기 위해 레지스터와 캐시라는 저장 장치를 내부에 갖고 있음.

 

구성요소 ↓

  1. 산술/논리 연산을 처리하는 산술논리장치 (Arithmetic Logic Unit, ALU)
  2. CPU를 제어하는 제어장치
  3. CPU에 필요한 데이터를 저장하는 레지스터 

 

 

기억장치 - 저장

: 컴퓨터가 동작하는데 필요한 여러 데이터를 저장

주기억장치: 임시 저장, 램(Random-Access Memory, RAM)

보조기억장치: 운영체제, 프로그램 등과 같은 데이터를 장기간 보관하고자 할 때 사용됨, 하드 드라이브(Hard Disk Drive, HDD), SSD(Solid State Drive)

 

 

버스

: 장치간에 데이터나 제어 신호를 교환할 수 있는 전자 통로

데이터 버스, 주소 버스, 읽기와 쓰기를 제어하는 제어 버스, 랜선이나 데이터 전송을 목적으로 하는 소프트웨어, 프로토콜 등도 버스라고 불림.

 


 

인텔의 x86-64를 기반으로 한 CPU들은 많은 전력 소모, 발열 심함 따라서 데스크톱 또는 랩톱에 적합

임베디드 기기, 스마트폰 등은 발열 문제에 민감하고 높은 전력을 안정적으로 공급하기 어려우므로 전력 소모와 발열이 적은 ARM이나 MIPS 또는 AVR의 프로세서를 사용함

 

 

x86-64 아키텍처 (= Intel64, amd64)

: 인텔의 64비트 CPU 아키텍처로, 대다수의 개인용 컴퓨터들이 인텔의 x64 CPU를 사용하고 있음. 

 

n 비트 아키텍처

n은 CPU가 한번에 처리할 수 있는 데이터의 크기를 의미함. 컴퓨터과학에서는 이를 CPU가 이해할 수 있는 데이터의 단위라는 의미에서 WORD라고 부름. 

 

WORD가 크면 유리한 점

32비트 아키텍처의 CPU가 제공할 수 있는 가상메모리의 크기는 4기가 바이트가 최대임. 이는 전문 소프트웨어나 고사양의 게임 등을 실행할 때는 부족할 수 있음.

반면 64비트 아키텍처에서는 16777216 테라바이트의 가상메모리를 제공 가능함. 이는 완전한 사용이 불가능할 정도로 큰 크기.

 

 

레지스터

: CPU 내부의 저장장치로, CPU가 빠르게 접근하여 사용할 수 있다. 산술연산에 필요한 데이터를 저장하거나, 주소를 저장하고 참조하는 등 다양한 용도로 사용됨. 

x64 아키텍처에는 범용 레지스터, 세그먼트 레지스터, 명령어 포인터 레지스터, 플래그 레지스터가 존재한다.

 

범용 레지스터

: 주용도는 있으나 그 외 임의의 용도로도 사용될 수 있는 레지스터. 8바이트를 저장할 수 있음.

x64의 범용 레지스터) rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp 등

 

세그먼트 레지스터

: 현재는 주로 메모리 보호를 위해 사용되는 레지스터

x64 아키텍처에는 cs, ss, ds, es, fs, gs 총 6가지 세그먼트 레지스터가 존재함. 각 레지스터의 크기는 16비트

 

명령어 포인터 레지스터 (Instruction Pointer Register, IP)

: 프로그램의 코드는 기계어로 작성되어 있는데, 이 중에서 CPU가 실행해야할 코드를 가리키는 레지스터.

x64 아키텍처의 명령어 레지스터는 rip이며, 크기는 8바이트.

 

플래그 레지스터

: CPU의 현재 상태를 저장하고 있는 레지스터.

x64 아키텍처에서는 RFLAGS라고 불리는 64비트 크기의 플래그 레지스터가 존재함. 최대 64개의 플래그를 사용할 수 있지만, 실제로는 20여개의 비트만 사용함.

플래그 레지스터의 여러 플래그 비트들 중 주로 접하게 될 것) CF(Carry Flag), ZF(Zero Flag), SF(Sign Flag), OF(Overflow Flag)

ex) a=3, b=5일 때, a에서 b를 빼는 연산을 하면 연산 결과가 음수이므로 SF가 설정됨. 그러면 CPU는 SF를 통해 a가 b보다 작았음을 알 수 있음.

 

레지스터 호환

 

 

리뷰 퀴즈

 


 

[ Windows Memory Layout ]

프로그램을 실행 -> 운영체제가 프로세스에게 사용 가능한 메모리 공간(가상 메모리)을 할당해줌 

메모리 레이아웃: 프로세스 가상 메모리 구성 

리버싱은 바이너리 역분석으로 동작 이해하는 것. 바이너리는 메모리와 관련.

=> 즉, 메모리에 대한 이해가 필요

 

[ PE 파일 (Portable Executable ]

: 윈도우 OS에서 사용되는 실행 파일 형식

- PE 헤더와 1개 이상의 섹션으로 구성됨.

- .text(PE 코드 존재), .data(PE가 실행 중에 참조하는 데이터), .rdata 섹션이 일반적으로 사용됨.

 

PE 헤더

- 섹션에 대한 정보가 적혀 있음

ㄴ 섹션의 이름, 섹션의 크기, 섹션이 로드될 주소의 오프셋, 섹션의 속성과 권한 등

- 윈도우는 PE를 실행할 때, 이 정보를 참조하여 PE의 각 섹션들을 가상 메모리의 적절한 세그먼트에 매핑함.

 

[ 섹션 ]

: 유사한 용도로 사용되는 데이터가 모여있는 영역

 

.text

- 실행 가능한 기계 코드가 위치하는 영역

- 코드를 실행해야 하므로 이 세그먼트에는 읽기 권한과 실행 권한이 부여됨.

- 반면 쓰기 권한이 있으면 공격자가 악성 코드를 삽입하기 쉬워지므로 쓰기 권한은 제거함.

 

.data 

- 컴파일 시점에 값이 정해진 전역 변수들이 위치함

- CPU가 이 섹션의 데이터를 읽고 쓸 수 있어야 하므로, 읽기/쓰기 권한이 부여됨.

 

.rdata

- 컴파일 시점에 값이 정해진 전역 상수와 참조할 DLL 및 외부 함수들의 정보가 저장됨

- 읽기 권한만 부여됨.

- str_ptr은 "readonly"라는 문자열을 가리키고 있는데, str_ptr은 전역 변수로서 .data에 위치하지만, "readonly"는 상수 문자열로 취급되어 .rdata에 위치함 

 

 

윈도우의 가상 메모리 공간에는 섹션만 로드되는 것이 아닌, 스택과 힙도 가상 메모리 공간에 적재됨.

 

[ 스택 ]

- 윈도우즈 프로세스의 각 스레드는 자신만의 스택 공간을 가지고 있음.

- 보통 지역 변수나 함수의 리턴 주소가 저장됨.

- 낮은 주소로 확장되며, 읽기/쓰기 권한이 부여됨.

 

[ 힙 ]

- 프로그램이 여러 용도로 사용하기 위해 할당받는 공간으로, 모든 종류의 데이터가 저장될 수 있음

- 스택보다 큰 데이터 저장 가능, 전역적으로 접근이 가능하도록 설계, 실행중 동적으로 할당받음

- 읽기/쓰기 권한만을 가지나 상황에 따라 실행 권한을 가지는 경우도 있음

 

[ 정리 ]

섹션 역할 일반적인 권한 사용 예
.text 실행 가능한 코드가 저장된 영역 읽기, 실행 main() 등의 함수 코드
.data 초기화된 전역 변수가 위치하는 영역 읽기와 쓰기 초기화된 전역 변수, 전역 상수
.rdata 초기화된 전역 상수나 임포트 데이터가 위치하는 영역 읽기 전용 전역 상수, 임포트 데이터
스택 일시적으로 저장하고 사용하는 임시 영역 읽기, 쓰기 지역 변수, 함수의 인자 등
자유롭게 사용할 수 있는 영역 읽기, 쓰기 malloc(), calloc() 등으로 할당 받은 메모리

 

https://dreamhack.io/lecture/roadmaps/4

 

Reverse Engineering

리버스 엔지니어링을 공부하기 위한 로드맵입니다.

dreamhack.io

'Reversing' 카테고리의 다른 글

VMware Pro / Windows XP 설치  (0) 2022.04.09
crackme #1 / 리틀 엔디안 / PEview  (0) 2022.03.26
Visual Studio 2019 / Immunity Debugger / 문자열 패치  (0) 2022.03.11
[Dreamhack] x86 Assembly  (0) 2022.03.05
[Dreamhack] Binary & Analysis  (0) 2022.02.25