주기억장치보다 더 큰 메모리 영역을 제공하기 위해 우리의 컴퓨터는 가상 메모리라는 것을 사용한다.

이를 이용하여 프로세스들은 각각의 가상 주소 공간을 가지고 있다.

[그림 1]

가상적으로 주어진 주소 가상 주소(논리 주소)와 실제 메모리 상에서의 주소를 가리키는 물리 주소(실 주소)가 있다.

 

가상 주소 공간은 MMU(메모리 관리 장치)에 의해 물리 주소로 변환되며 두 주소를 매핑 시키기 위한 기술이 바로 페이징이다.

 

페이징 기법이란 컴퓨터가 메인 메모리에서의 사용을 목적으로 2차 기억장치로부터 데이터를 저장 및 검색하는 메모리 관리 기법이다.

 

이때 가상 기억 장치를 모두 같은 크기의 블록으로 편성하는데, 이 블록을 페이지라 한다.

주소 공간을 페이지 단위로 나눈 다음 실질적인 기억공간은 페이지 크기와 같은 프레임으로 나누어 사용한다.

 

페이지 : 가상 메모리를 일정한 크기로 나눈 블록 

프레임 : 물리 멤모리를 일정한 크기로 나눈 블록

 

프레임과 페이지의 크기는 같다.

 

페이지가 프레임과 매핑이 된다면, 물리 메모리에 위치한다.

그렇지 않았다면 페이지들은 외부 저장장치, 보조기억장치에 저장된다.

 

하나의 프로세스는 하나의 페이지 테이블을 갖는다. 페이지 테이블은 페이지의 정보가 담겨 있다.

페이지 번호, 페이지에 할당된 물리 메모리 즉, 프레임의 시작 주소를 값으로 가지고 있다.

 

페이지 테이블 엔트리(PTE)라는 것이 존재한다. 

이는 페이지 테이블의 레코드이다.

 

페이지 기본 주소(Page base address)

 

플래그 비트(Flag bit)

  •  접근 비트 : 페이지에 대한 접근이 있었는지를 나타낸다.
  •  변경 비트 : 페이지의 내용에 변경이 있었는지를 나타낸다.
  •  현재 비트 : 현재 페이지에 할당된 프레임이 있는지를 나타낸다.
  •  읽기/쓰기 비트 : 읽기/쓰기에 대한 권한을 표시한다.

마지막으로 동적 주소 변환이다.

 

페이징 기법에서 동적 주소 변환 과정은 알아두는것이 좋다.

 

1. 수행중인 프로세스가 가상 주소를 참조한다.

2. 페이징 기법을 통해 페이지 a가 페이지 프레임 A에 있음을 알아낸다.

3. 실 주소 = A + 오프셋을 한다.

'Basic Concepts > Reverse Engineering' 카테고리의 다른 글

IA-32(Intel Architecture 32) Register  (0) 2020.01.24
바이트 오더링  (0) 2020.01.24

레지스터란 CPU 내부에 존재하는 다목적 저장 공간이다.

 

리버싱 초급 단계에서 디버깅을 잘하려면 디버거가 디스어셈 해주는 어셈블리 명령어를 잘 알아야 한다.

어셈블리 명령어는 레지스터를 다루기에 필수불가결하다.

 

IA-32는 지원하는 기능 뿐만 아니라 레지스터의 수 또한 엄청나다.

워낙 많기에 하나하나 다 나열하기에는 무리가 따른다. 

디버깅 할때 가장 많이 보게 될 레지스터인 Basic program execution register를 다루어 보겠다.

※본인이 관심이 있고 더 알고 싶다면 Control registers, Memory management registers를 공부하는것도 좋다.

 

 

Basic program execution registers

Basic program execution register은 4개의 레지스터로 나뉘어진다.

범용 레지스터, 세그먼트 레지스터, 프로그램 상태와 컨트롤 레지스터, Instruction Pointer

 

범용 레지스터는 32비트 8개

세그먼트 레지스터는 16비트 6개

프로그램 상태와 컨트롤 레지스터는 32비트 1개

Instruction Pointer는 32비트 1개로 되어 있다.

 

범용 레지스터

General purpose register는 말 그대로 범용적으로 사용되는 레지스터이다.

IA-32에서는 32비트로 이루어 져있다.

범용 레지스터

레지스터의 각각의 이름은 32-bit에 적힌대로이다.

 

16-bit AX에서 32비트로 크기가 커지면서 앞에 Extended를 붙여 EAX가 된것이다.

EAX, EBX, ECX, EDX는 산술연산에 주로 사용된다.

EAX는 일반적으로 함수 리턴 값에 사용되며 ECX는 반복문 명령어에서 반복 카운트로 사용된다.

 

EBP, ESI, EDI, ESP는 메모리 주소를 저장하는 포인터로 사용된다.

ESP는 스택 메모리 주소를 가리킨다.

EBP는 함수가 호출되었을때 그순간의 ESP를 저장하고 있다 함수가 리턴되기 직전에 값을 돌려준다.

(이것을 Stack Frame기법이라고 하며 stack pointer와 base pointer는 굉장히 중요하기에 추후에 따로 다루도록 하겠다.)

ESIEDI는 메모리 복사에 사용된다.

 

세그먼트 레지스터

세그먼트(Segment)란 IA-32의 메모리 관리 모델에서 나오는 용어이다.

IA-32 보호 모드에서 세그먼트는 메모리를 조각내어 각 조각마다 시작주소, 범위, 접근 권한 등을 부여해서 메모리를 보호하는 기법이다. 

세그먼트 레지스터는 총 6개가 존재한다.  

CS Code Segment (16비트)

SS Stack Segment (16비트)

DS Data Segment (16비트)

ES Extra(Data) Segment (16비트)

FS Data Segment (16비트)

GS Data Segment (16비트)

 

ES, FS, GS 세그먼트는 추가적인 데이터 세그먼트 이다. 마지막으로 FS 레지스터는 애플리케이션 디버깅에도 자주 등장하게 되는데 SEH, PEB등의 주소를 계산할 때 사용된다. 이는 추후 포스팅에서 다루도록 하겠다.

 

프로그램 상태와 컨트롤 레지스터

플래그 레지스터의 이름은 EFLAGS이며 32비트 크기이다.

EFLAGS Register

EFLAGS 레지스터는  각 비트마다 의미를 가진다. 각 비트는  1 또는 0의 값을 가진다.(True or False)

 

저 많은 걸 한번에 다 외우려 하지 말고 우선적으로 사용되는 ZF, OF, CF만 다루어 보도록 하자.

 

Zero Flag(ZF)

연산 명령 후에 결과값이 0이 되면 ZF가 1(True)로 세팅 된다.

 

Oerflow Flag(OF)

부호 있는 수(signed integer, 실수)의 오버플로가 발생했을 때 1로 세팅 된다. MSB가 변경되었을 때 1로 세팅된다.

 

Carry Flag(CF)

부호 없는 수(unsigned integer, 정수)의 오버플로가 발생했을 때 1로 세팅된다.

 

 

Instruction Pointer

CPU가 처리할 명령어의 주소를 나타내는 레지스터이며, 크기는 32비트이다. CPU는 EIP에 저장된 메모리 주소의 명령어를 하나 처리하고 난 후 자동으로 그 명령어 길이만큼 EIP를 증가시킨다.

 

 

사진참조 http://www.intel.co.kr/content/www/kr/ko/architecture-and-technology/64-ia-32-architectures-software-developer-manual-325462.html

'Basic Concepts > Reverse Engineering' 카테고리의 다른 글

가상메모리와 페이징  (0) 2020.02.01
바이트 오더링  (0) 2020.01.24

바이트 오더링은 데이터를 저장하는 방식을 말하며 디버깅을 할때 필요한 기본 개념이다.

이 방식은 크게 빅 엔디언(Big Endian)과 리틀 엔디언(Little Endian) 두 방식이 있다.

 

 

더보기

 

BYTE                 b          = 0x12;

WORD              w          = 0x1234;

DWORD           dw         = 0x12345678;

char                str[ ]       = "abcde";

 

 

엔디언 방식에 따라서 데이터를 저장하는 방식이 달라진다.

TYPE Name SIZE Big Endian Little Endian
BYTE b 1 [12] [12]
WORD w 2 [12][34] [34][12]
DWORD dw 4 [12][34][56][78] [78][56][34][12]
char [] str 6 [61][62][63][64][65][00] [61][62][63][64][65][00]

※ [61]은 'a'를 ASCII 문자로 나타낸것이다. 문자열의 마지막은 NULL로 끝나야 한다.

 

빅 엔디언 방식은 순착적인 반면 리틀 엔디언 방식은 역순으로 나타난다.(바이트 자체는 정상적인 순서로 저장된다.)

2바이트 혹은 4바이트와 같이 멀티 바이트인 경우에 바이트가 역순으로 저장되는 것이다.

str 문자열은 char 배열이기 때문에 바이트를 하나씩 연속해서 저장한다. 따라서 Endian 형식과 상관이 없다. 

'Basic Concepts > Reverse Engineering' 카테고리의 다른 글

가상메모리와 페이징  (0) 2020.02.01
IA-32(Intel Architecture 32) Register  (0) 2020.01.24

+ Recent posts