[Computer Architecture]
1. 컴퓨터 구조
1) 컴퓨터 구조
- 컴퓨터가 효율적으로 작동할 수 있도록 하드웨어 및 소프트웨어의 기능을 고안하고 이들을 구성하는 방법
- 컴퓨터 기능 구조에 대한 설계, 명령어 집합구조, 마이크로 아키텍처, 기타 하드웨어 및 컴퓨팅 방법에 대한 설계 포함
2) 컴퓨터 기능 구조에 대한 설계
- 효율적인 연산을 위해 컴퓨터에 필요한 기능들을 고민, 설계하는 분야
- ex. 폰 노이만 구조, 하버드 구조, 수정된 하버드 구조
3) 명령어 집합구조(CPU 명령어에 대한 설계)
- CPU가 처리해야하는 명령어 설계하는 분야
- ex. ARM, MIPS, AVR, 인텔의 x86 및 x86-64 등
2. 폰 노이만 구조
1) 컴퓨터의 핵심 기능
- 연산, 제어, 저장
- 연산과 제어 -> 중앙처리장치(CPU) 사용
- 저장 -> 기억장치 사용
- 장치 간에 데이터나 제어 신호 교환 -> 버스(전자 통로) 사용
2) 중앙처리장치(CPU)
- 프로그램의 연산을 처리하고 시스템을 관리하는 컴퓨터의 두뇌
- 프로세스의 코드를 불러오고, 실행하고, 결과를 저장하는 기능을 함
- 산술논리장치 / 제어장치 / 레지스터로 구성
① 산술논리장치 : 산술/논리연산 처리
② 제어장치 : CPU 제어
③ 레지스터 : CPU에 필요한 데이터 저장
3) 기억장치
- 컴퓨터가 동하는데 필요한 데이터 저장
- 주기억장치 / 보조기억장치로 분류
① 주기억장치 : 프로그램 실행과정에서 필요한 데이터를 임시 저장 ex. 램(RAM)
② 보조기억장치 : 운영체제, 프로그램 등과 같은 데이터를 장기간 보관 ex. 하드드라이브(HDD), SSD
4) 버스
- 컴퓨터 부품 간에, 또는 컴퓨터 간에 신호를 전송하는 통로
- 데이터 버스 / 주소 버스 / 제어 버스
① 데이터 버스 : 데이터 이동
② 주소 버스 : 주소 지정
③ 제어 버스 : 읽기/쓰기 제어
- 랜선, 데이터 전송 소프트웨어, 프로토콜 등도 버스라 불림
5) 기억장치가 있는데 CPU 안에 레지스터가 필요한 이유
- CPU가 빠른 속도로 연산을 처리하기 위해 데이터의 빠른 교환이 필요
- CPU의 연산 속도가 기억장치와 데이터 교환속도보다 압도적으로 빨라, 기억장치만 사용하면 병목현상 발생
- 따라서 CPU는 교환 속도를 단축하기 위해 레지스터와 캐시라는 저장장치를 내부에 갖고 있음
3. 명령어 집합 구조
1) 명령어 집합 구조(Instruction Set Architecture, ISA)
- CPU가 해석하는 명령어의 집합
- IA-32, x86-64(x64), MIPS, AVR 등 존재
2) 인텔의 x86-64
- 고성능 프로세서 설계를 위해 사용
- 이를 기반으로 한 CPU는 전력소모 크고 발열도 상대적으로 심함
- 데스크탑, 랩탑에 적합
cf) 배터리 사용하는 드론, 공유기, 인공지능 스피커처럼 작은 임베디드 기기들은 인텔의 고성능 프로세서를 장착하기 부적합
-> 많은 임베디드 장비들은 전력 소모와 발열이 적은 ARM, MIPS, AVR의 프로세서 주로 사용
4. x86-64 아키텍처
1) x86-64 아키텍처
- x64 아키텍처 : 인텔의 64비트 CPU 아키텍처
인텔의 32비트 CPU 아키텍처인 IA-32를 64비트 환경에서 사용할 수 있도록 확장한 것
2) n 비트 아키텍처
- n은 CPU가 한번에 처리할 수 있는 데이터의 크기
- WORD : CPU가 이해할 수 있는 데이터의 단위
- WORD의 크기는 CPU가 어떻게 설계됐느냐에 따라 달라짐
ex. 일반적인 32비트 아키텍처
-> ALU는 32비트까지 계산 가능, 레지스터의 요량 및 각종 버스들의 대역폭이 32비트
이들로 구성된 CPU는 설계 상 32비트의 데이터까지만 처리 가능
3) WORD가 크면 유리한 점
- 작으면 CPU가 제공할 수 있는 가상메모리의 크기가 작음
-> 많은 메모리 자원을 소모하는 전문 소프트웨어나 고사양의 게임을 실행할 때 부족할 수 있음
- 크면 가용한 메모리 자원이 부족해서 소프트웨어의 최고 성능을 낼 수 없다거나 실행 불가능한 상황이 거의 발생하지 x
5. 범용 레지스터
1) 범용 레지스터
- 주용도는 있으나 그 외의 다양한 용도로 사용될 수 있는 레지스터
- x86-64에서 각각의 범용 레지스터는 8바이트 저장 가능, 부호없는 정수 기준 2^64-1 까지의 수 표현 가능
2) x64에서 자주 쓰이는 범용 레지스터의 종류
이름 | 주용도 |
rax (accumulator register) | 함수의 반환 값 |
rbx (base register) | x64에서는 주된 용도 없음 |
rcx (counter register) | 반복문의 반복 횟수, 각종 연산의 시행 횟수 |
rdx (data register) | x64에서는 주된 용도 없음 |
rsi (source index) | 데이터를 옮길 때 원본을 가리키는 포인터 |
rdi (destination index) | 데이터를 옮길 때 목적지를 가리키는 포인터 |
rsp (stack pointer) | 사용 중인 스택의 위치를 가리키는 포인터 |
rbp (stack base pointer) | 스택의 바닥을 가리키는 포인터 |
6. 세그먼트 레지스터
1) 세그먼트 레지스터
- x64로 아키텍처가 확장되면서 용도에 큰 변화가 생김
- x64에 존재하는 세그먼트 레지스터 : cs, ss, ds, es, fs, gs (각 레지스터의 크기는 16비트)
- cs, ds, ss 레지스터 : 코드 영역과 데이터, 스택 메모리 영역을 가리킬 때 사용
- es, fs, gs 레지스터 : 운영체제 별로 용도를 결정할 수 있도록 범용적인 용도로 제작됨
7. 플래그 레지스터
1) 플래그 레지스터
- 프로세서의 현재 상태를 저장하고 있는 레지스터
- x64에는 RFLAGS라 불리는 64비트 크기의 플래그 레지스터 존재
- 자신을 구성하고 있는 여러 비트들로 CPU의 현재 상태 표현 (마치 깃발을 올리고 내리는 것처럼)
- RFLAGS는 최대 64개의 플래그를 사용 가능하지만 실제로는 아래의 20여개의 비트만 사용
2) 자주 접하게 될 플래그
플래그 | 의미 |
CF (Carry Flag) | 부호 없는 수의 연산 결과가 비트의 범위를 넘을 경우 설정됨 |
ZF (Zero Flag) | 연산의 결과가 0일 경우 설정됨 |
SF (Sign Flag) | 연산의 결과가 음수일 경우 설정됨 |
OF (Overflow Flag) | 부호 있는 수의 연산 결과가 비트의 범위를 넘을 경우 설정됨 |
8. 명령어 포인터 레지스터
1) 명령어 포인터 레지스터
- 프로그램을 이룬 기계어 코드들 중에서 CPU가 어느 부분의 코드를 실행할 지 가리킴
- x64 아키텍처의 명령어 레지스터는 rip이며 크기는 8byte
9. 레지스터 호환
- IA-32에서 CPU의 레지스터들은 32비트 크기를 가짐
-> 명칭은 각각 eax, ebx, ecx, edx, esi, edi, esp, ebp
- 호환성을 위해 이 레지스터들은 x86-64에서도 그대로 사용 가능
- rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp가 이들의 확장된 형태, eax, ebx 등은 확장된 레지스터의 하위 32비트를 가리킴
- 마찬가지로 과거 16비트 아키텍처인 IA-16과의 호환을 위해 ax, bx, cx, dx, si, di, sp, bp는 eax, ebx, ecx, edx, esi, edi, esp ,ebp의 하위 16비트를 가리킴
- 이들 중 몇몇은 다시 상위 8비트, 하위 8비트로 나뉨
[Windows Memory Layout]
1. 메모리 레이아웃 (Memory Layout)
1) 메모리 레이아웃
- 프로세스 가상 메모리의 구성
- 가상 메모리 : 프로그램을 실행할 때 운영체제가 프로세스에 할당해주는 사용 가능한 메모리 공간
- 리버싱의 핵심은 바이너리를 분석하여 바이너리의 동작을 이해하는 것
- 바이너리의 동작은 메모리와 관련이 있기 때문에, 바이너리 동작을 이해하기 위해 그와 상호작용하는 메모리에 대한 이해가 필요
2. 프로세스 메모리 구조
1) 섹션
- 윈도우의 PE 파일 구성 = PE 헤더 + 1개 이상의 섹션
- 섹션 : 유사한 용도로 사용되는 데이터가 모여있는 영역
- ex. .text : PE의 코드
.data : PE가 실행 중에 참조하는 데이터
- 섹션에 대한 정보는 PE 헤더에 적혀있음
- PE 헤더에 저장되는 섹션과 관련된 데이터 중, 중요한 것은 다음과 같다.
① 섹션의 이름
② 섹션의 크기
③ 섹션이 로드될 주소의 오프셋
④ 섹션의 속성과 권한
- 윈도우는 PE를 실행할 때, 위의 정보를 참조하여 PE의 각 섹션들을 가상 메모리의 적절한 세그먼트에 매핑함
2) 일반적으로 사용되는 섹션
① .text
- 실행 가능한 기계 코드가 위치함
- 프로그램이 동작하려면 코드를 실행할 수 있어야 하므로, r/e 권한이 부여되지만, w 권한은 대부분 제거 (공격 위험 때문)
int main() { return 31337; }
- 정수 31337을 반환하는 main 함수가 컴파일 되면 554889e5b8697a00005dc3이라는 기계코드로 변환되는데,
이 기계 코드가 코드 세그먼트에 위치하게 됨
② .data
- 컴파일 시점에 값이 정해진 전역 변수들이 위치함
- CPU가 이 섹션의 데이터를 읽고 쓸 수 있어야 하므로, r/w 권한이 부여됨
//.data 섹션에 포함되는 여러 데이터의 유형
int data_num = 31337;
char data_rwstr[] = "writable_data"; // data
int main() { ... }
③ .rdata
- 컴파일 시점에 값이 정해진 전역 상수와 참조할 DLL 및 외부 함수들의 정보가 저장됨
- CPU가 이 섹션의 데이터를 읽을 수 있어야 하므로, r 권한이 부여되지만, w는 불가능
//.rdata 섹션에 포함되는 여러 데이터의 유형
const char data_rostr[] = "readonly_data";
char *str_ptr = "readonly"; // str_ptr은 .data, 문자열은 .rdata
int main() { ... }
- str_ptr은 "readonly"라는 문자열을 가리키고 있는데, str_ptr은 전역 변수로서 .data에 위치하지만,
"readonly"는 상수 문자열로 취급되어 .rdata에 위치함
- 과거에는 참조할 DLL과 외부 함수들의 정보를 .idata 섹션에 저장하였으나, 최근에는 대부분 .rdata에 저장함
2) 스택
- 윈도우즈 프로세스의 각 쓰레드는 자신만의 스택 공간을 가지고 있음
- 보통 지역 변수나 함수의 리턴 주소가 저장됨
- 자유롭게 읽고 쓸 수 있어야 하므로, r/w 권한이 부여
- 스택에 대해 '아래로 자란다'라는 표현을 종종 사용하는데, 이는 스택이 확장될 때, 기존 주소보다 낮은 주소로 확장되기 때문
void func() {
int choice = 0;
scanf("%d", &choice);
if (choice)
call_true();
else
call_false();
return 0;
}
- 지역변수 choice가 스택에 저장됨
3) 힙
- 힙 : 프로그램이 여러 용도로 사용하기 위해 할당받는 공간
- 모든 종류의 데이터가 저장될 수 있음
- 스택과 다른 점
① 비교적 스택보다 큰 데이터 저장 가능
② 전역적으로 접근 가능하도록 설계됨
③ 실행 중 동적으로 할당 받음
- 보통 데이터를 읽고 쓰기만 하기 때문에 r/w 권한이 부여되지만, 상황에 따라 e 권한을 가지기도 함
int main() {
int *heap_data_ptr =
malloc(sizeof(*heap_data_ptr)); // 동적 할당한 힙 영역의 주소를 가리킴
*heap_data_ptr = 31337; // 힙 영역에 값을 씀
printf("%d\n", *heap_data_ptr); // 힙 영역의 값을 사용함
return 0;
}
- heap_data_ptr에 malloc()으로 동적 할당한 영역의 주소를 대입하고, 이 영역에 값을 씀
- heap_data_ptr은 지역변수이므로 스택에 위치하며, malloc으로 할당받은 힙 세그먼트의 주소를 가리킴
'Security > Reversing' 카테고리의 다른 글
[어셈블리어 분석 실습] example 1 (0) | 2022.05.08 |
---|---|
[어셈블리어 분석 실습] 기본 내용 (0) | 2022.05.08 |
[Dreamhack Reverse Engineering] STAGE 4 (0) | 2022.05.06 |
[Dreamhack Reverse Engineering] STAGE 2 (0) | 2022.04.28 |
[Dreamhack Reverse Engineering] STAGE 1 (0) | 2022.04.28 |
댓글