본문 바로가기

리버스엔지니어링

레지스터 정리

리버싱을 하기 위해서는 먼저 어셈블리어를 배워야 하는데 IA-32플랫폼에서 쓰이는 어셈블리어에서 많이 쓰는 레지스터에 대해서 설명드리겠습니다.

레지스터는 알기 쉽게 c언어에서 변수를 선언한다고 보시면 됩니다.
하지만 c언어와의 차이점은 c언어는 자신이 원할때 변수를 맘대로 생성시킬 수 있는 반면에 어셈블리어는 이미 몇개의 레지스터의 갯수로 정해져있다는 점입

니다.

다음 그림은 Basic program execution registers 그룹에 포함된 전체 레지스터 정리 그림입니다.



가장 위는 범용레지스터, 왼쪽아래의 EIP는 Instruction pointer, 그 아래의 EFLAGS는 프로그램 상태와 컨트롤 레지스터, 그 오른쪽은 세그먼트 레지스터입니다.

1)범용레지스터
범용레지스터는 이름 그대로 범용적으로 사용할 수 있는 레지스터들입니다.
C언어에 비유해서 설명하자면 변수 갯수가 이미 8개가 주어져 있다고 생각하시면 됩니다.

각각의 레지스터에 대해서 설명하자면
EAX : Accumulator for operands and result data(오퍼랜드와 결과를 저장하는 공간)
EBX : Pointer to data in the DS Segment(DS세그먼트의 데이터를 가리키는 곳)
ECX : Counter for string and loop operation(문자열과 루프구문을 count하는 곳)
EDX : I/O pointer (입출력 관련)

범용적으로 쓰인다고 말하긴 했지만 보통은 이름의 뜻에 맞게 쓰는것이 예의입니다.
예를들어 EAX같은 경우는 연산결과,주소값,상수들을 주로 저장하고, ECX는 루프구문이 나올때 몇 번 루프하는지를 체크합니다.

예) MOV EAX 16
     ADD EAX 32
     SUB EAX 4
이런식으로 EAX는 연산을 하는데 쓰입니다. EBX와 EDX같은 경우는 보통 범용적으로 쓰입니다.
ECX같은 경우는 어셈블리어 강의를 할때 좀더 예를 들어 설명드리겠습니다.

이 레지스터들의 크기는 32bit입니다.
중간에 보면 EAX레지스터가 AX레지스터로 반으로 쪼개지고
AX레지스터는 또다시 AH와AL로 나누어지게 되는데
이것은 8비트 컴퓨터일때 8비트 크기의 AH와 AL레지스터가 있었고
16비트로 넘어오면서 통합되어서 AX레지스터로 존재하다가
32비트 시대가 왔을때 확장됬다는 뜻인 Extention을 맨 앞에 붙여 EAX레지스터가 된것입니다.
실제로 위 그림의 레지스터들의 크기를 보면 E가 맨 앞에 붙은 레지스터들은 32bit크기지만
세그먼트레지스터들은 다른 레지스터의 반쪽(16비트)입니다.

나머지 4개의 레지스터에 대해 설명드리면
EBP : pointer to data on the stack
ESP : stack pointer
ESI : source pointer for string operation
EDI : destination pointer for string operation

EBP는 BP즉 베이스포인트라고 생각하시면 됩니다.
ESP란 애가 함수 속을 살펴보러 갈때 EBP를 입구에 세워둬서 ESP가 길을 잃어버리지 않게 합니다.
이러한 기법을 전문용어로 Stack Frame이라고 합니다.

예) PUSH EBP
     MOV EBP ESP
이런식으로 ESP의 값을 미리 EBP에 전달시키고 ESP를 이리저리 굴리면서 계산을 합니다.

2) 세그먼트 레지스터
메모리를 보호하기 위한 레지스터입니다.
DOS에서 Windows로 넘어오면서 멀티테스킹 기술이 추가되었는데요, 이러면서 프로그램끼리 서로 서로 주소를 침범시키는 것을 방지시키기 위해서 페이징,SDT 등 등의 기술을 쓰는데 그 기법을 쓰거나, 메모리의 값을 참조할때 쓰는 레지스터입니다. 더욱 자세한 설명은 시스템공부가 되있는 상태에서 들어야 이해가 잘 될것입니다.

3) 프로그램 상태와 컨트롤 레지스터
EFLAGS : Flag register


실제로는 이정도의 갯수가 있지만 실제로 중요하게 사용하는 것에 대해서만 설명드리겠습니다.
Flag라는것은 깃발이라는 뜻인데 어떤 특정한 상황이 발생됬을 때 깃발을 흔들어 상황을 정리하는것을 생각하시면 됩니다.
중요한 flag들로는
ZF(Zero Flag) : 연산의 결과값이 0이 될 경우 ZF가 1로 됩니다.
OF(Overflow Flag) : 부호 있는수의 오버플로우가 발생됬을 경우 OF가 1로 됩니다.
CF(Carry Flag) : 부호 없는수의 오버플로우가 발생됬을 경우 CF가 1로 됩니다.

위의 그림을 읽는 방법은 32비트중에 각각의 1비트마다 이름이 있는 플래그들의 비트가 존재한다고 보면 됩니다.
4) Instruction pointer
EIP : Instruction pointer
이 값은 건들일수 없으며 한 명령이 실행될때 마다 CPU자체에서 EIP를 증가시켜 다음 명령을 찾아가는데 쓰입니다.



레지스터 설명같은경우는 굉장히 어렵지만 이 레지스터들을 다 알고 있으면 로우레벨 관점에서 프로그램의 흐름을 정확히 이해 할 수 있습니다.

'리버스엔지니어링' 카테고리의 다른 글

간단한 리버싱 워게임-1  (0) 2014.04.11
reversing.kr 44위 달성!  (0) 2014.01.27
PE 구조 정리-2  (0) 2013.07.21
PE 구조 정리-1  (0) 2013.07.16