본문 바로가기

Reverse Engineering

리버싱을 위한 기초 지식 - 진수변환과 CPU 레지스터

1. 진수 변환 :

2진수, 10진수 16진수의 뜻과 자유롭게 변환하는 법을 소개한다.

10진수를 기준으로 해서 2진수와 16진수를 설명하겠다.

2진수는 0과 1로만 이루어져 있어서 1 다음이 한 자리 올림을 한 10이 된다. 2진수가 영어로 binary이기 때문에 뒤에 b를 붙인다.

16진수는 1부터 9, 그리고 A부터 F까지 순차적으로 사용하고, 10진수로 16이 되면 그때 자릿수를 올려 10이 된다. 16진수를 표현할 때는 영어로 hexadecimal이기 떄문에 뒤에 h를 붙인다.
그리고 구분을 더 편하게 하기위해서 앞부분에는 0을 붙인다.

 10진수  2진수   16진수  10진수  2진수  16진수
 1  1  1  10  1010  A
 2  10  2  11  1011  B
 3  11  3  12  1100  C
 4  100  4  13  1101  D
 5  101  5  14  1110  E
 6  110  6  15  1111  F
 7  111  7  16  10000  10
 8  1000  8  17  10001  11
 9  1001  9  18  10010  12

이러한 진법 계산은 윈도우 계산기를 이용하면 편리하다.
윈도우 실행(Win키+R) calc.exe 혹은 cmd 창에서 calc.exe 혹은 보조프로그램에서 계산기를 실행하고 공학용 옵션을 활성화시켜준다.


계산기의 공학용 옵션을 켜면 Hex(16진수), Dec(10진수), Oct(8진수), Bin(2진수) 버튼이 나타난다.
변환하는 방법은 Dec를 선택한 상태에서 숫자를 십진수로 적고, 변환하고 싶은 진수버튼을 누르면 변환이 되어 표시된다. 각 진수간의 변환도 가능하다.



2. CPU 레지스터 :

CPU(Central Processing Unit)는 메모리로부터 명령어를 가져와서(fetch) 어떤 명령어인지 해석하고(decode) 실행하는(execute) 동작을 한다.

레지스터는 CPU 내부에 존재는 작은 고속의 메모리이다. 레지스터의 종류로는 범용 레지스터, 세그먼트 레지스터, 상태 플래그 레지스터, 명령 포인터 레지스터 등이 있다.
다음은 올리디버거에 나타나는 레지스터 정보이다.



범용 레지스터

EAX(Extended Accumulator Register)
곱셈과 나눗셈 명령에서 자동으로 사용되고 함수의 리턴값이 저장되는 용도로 사용된다.

EBX(Extended Base Register)
ESI나 EDI와 결합하여 인덱스에 사용된다.

ECX(Extended Counter Register)
반복 명령어 사용시 카운터로 사용된다. ECX 레지스터에 반복할 횟수를 지정해 놓고 반복 작업을 수행한다.

EDX(Extended data Register)
EAX와 같이 쓰이며 부호 확장 명령 등에 쓰인다.

ESI(Extended Source Index)
데이터 복사나 조작시 Source Data의 주소가 저장된다. ESI 레지스터가 가리키는 주소의 데이터를 EDI 레지스터가 가리키는 주소로 복사하는 용도로 많이 사용된다.

EDI(Extended Destination Index)
복사 작업시 Destination의 주소가 저장된다. 주로 ESI 레지스터가 가리키는 주소의 데이터가 복사된다.

ESP(Extended Stack Pointer)
하나의 스택 프레임의 끝 지점 주소가 저장된다. PUSH, POP 명령어에 따라서 ESP의 값이 4byte씩 변한다.

EBP(Extended Base Pointer)
하나의 스택 프레임의 시작 지점 주소가 저장된다. 현재 사용되는 스택 프레임이 소멸되지 않는 동안 EBP의 값은 변하지 않는다. 현재의 스택 프레임이 소멸되면 이전에 사용되던 스택
프레임을 가리키게 된다.


명령 포인터 레지스터

EIP(Extended Instruction Pointer)
다음에 실행해야 할 명령어가 존재하는 메모리 주소가 저장된다. 현재 명령어를 실행 완료한 후에 EIP 레지스터에 저장되어 있는 주소에 위치한 명령어를 실행하게 된다. 실행 전 EIP 레지스터는 다음 실행해야 할 명령어가 존재하는 주소의 값이 저장된다.


세그먼트 레지스터

CS(Code Segment)
실행 가능한 명령어가 존재하는 세그먼트의 오프셋이 저장된다.

DS(Data Segment)
프로그램에서 사용되는 데이터가 존재하는 세그먼트의 오프셋이 저장된다.

SS(Stack Segment)
스택이 존재하는 세그먼트의 오프셋이 저장된다.


플래그 레지스터

CF(Carry Flag)
부호 없는 연산 결과가 용량보다 클 때 세트(1)된다.

ZF(Zero Flag)
연산 결과가 0일 때 세트(1)된다. 연산 결과가 0이 아닐 때 해제(0)된다.

OF(Overflow Flag)
부호 있는 연산 결과가 용량보다 클 때 세트(1)된다.

SF(Sign Flag)
연산 결과가 음수가 되었을 때 세트(1)된다. 연산 결과가 양수가 되었을 때 해제(0)된다.

DF(Direction Flag)
문자열 처리에서 연속되는 문자열의 처리 방향에 따라 세트된다.


부동 소수점 데이터 레지스터

ST(0), ST(1), ST(2), ST(3), ST(4), ST(5), ST(6), ST(7)
범용 레지스터는 레지스터 이름 첫 글자가 'E'인 것을 알 수 있다. '확장되었다(Extended)'
라는 의미로 32bit 컴퓨터 환경이 되면서 16bit 레지스터인 AX, BX, CX, DX 등의 레지스터를 32bit로 확장한 것이라고 보면 된다. EAX, EBX, ECX, EDX 레지스터는 32bit, 16bit, 8bit로
사용할 수 있다.

 32bit  16bit  High 8bit  Low 8bit
 EAX  AX  AH  AL
 EBX  BX  BH  BL
 ECX  CX  CH  CL
 EDX  DX  DH  DL

ESI, EDI, EBP, ESP 레지스터는 32bit, 16bit로 사용이 가능하다.

 32bit  16bit
 ESI  SI
 EDI  DI
 EBP  BP
 ESP  SP