Chapter 3. Memory & Assembly Language
1. Memory
- Program이 실행되는 동안 Data가 저장되는 공간
- 운영체제에 의해 할당되는 Memory 공간
‧ Code Area : 실행할 Program의 Code가 저장되는 공간으로 CPU는 코드영역에 저장된 명령문을 하나씩 꺼내 실행한다.
‧ Data Area : 전역변수와 정적 변수가 할당되는 영역으로 Program 시작과 동시에 할당되어 종료 시까지 남아있는 특징의 변수가 저장되는 공간이다.
‧ Heap Area : Programer가 원하는 시점에 Memory 공간에 할당 및 소멸을 하기 위한 공간이다.
‧ Stack Area : 지역변수와 매개변수가 할당 되는 공간으로 함수를 빠져나가면 소멸되는 변수를 저장하는 공간이다.
- Program 실행 시 할당되는 Memory 영역
‧ Buffer 영역은 밑 부분부터 Memory 값이 쌓이는 Stack 구조(FILO 구조)이며 Buffer 영역은 Program이 실행되고 있는 동안만 Stack Area에 할당된다.
‧ Buffer 영역이 할당된 바로 밑 부분엔 SFP(Stack Frame Pointer) 즉, Stack의 시작 주소가 저장되며 바로 밑 부분에는 Return 값의 주소가 저장된다.
‧ 실행을 마친 Program은 RET에 있는 주소에 있는 Code를 실행하며 이 Code는 값일 수도 다른 명령 Code일 수도 있다.
- Stack
‧ 임시저장장소 또는 Buffer라고도 하며 Program이 실행되는 Runtime에 Memory의 Stack Area에 생성된다.
‧ Thread 단위로 Memory에 할당된다.
‧ Stack(Buffer)의 위치는 Memory상에 Random으로 생성된다.
‧ 시작위치는 대체로 비슷하거나 같은 위치에 생성되지만 해제된 Program을 재 시작해 Stack을 재할당한다고해서 같은 위치에서 생성되는 것을 보장할 순 없다.
‧ Stack(Buffer)의 용도
◦ 지역 변수 저장(주목적)
◦ 함수의 전달 인자 저장
◦ 함수 호출 관련 정보
◦ 임시 Data Backup
◦ 운영체제가 필요할 때 사용
2. Assembly Language
- 기계어와 1 대 1 대응이 되는 Programming의 저급 언어
- 기계어 형식
· OPCODE : 명령 Code
· OPERAND : 인자 값
- 주로 사용되는 기계어 명령어
· MOV
◦ Data를 복사하는 명령어
◦ 'Source OPERAND'의 내용을 'Destination OPERAND'에 복사
◦ C Language 유사 명령어
▹ int i = 10;
‧ ADD/SUB/MUL/DIV
◦ 더하기/빼기/곱하기/나누기 명령어
◦ 'Source OPERAND'의 내용을 'Destination OPERAND'와 연산 후 'Destination OPERAND'에 저장
· INC/DEC
◦ 단일증가/감소 명령어
· AND/OR/XOR
◦ 논리연산 명령어
◦ 'Source OPERAND'의 내용을 'Destination OPERAND'와 논리 연산 후 'Destination OPERAND'에 저장
· LEA
◦ MOV와 비슷한 복사를 수행하는 명령어로 값이 아닌 주소를 복사하는 명령어
◦ MOV와 LEA 비교
▹ MOV는 값(Value)을, LEA는 주소(Address)를 복사한다.
· Stack(Buffer) 관련 기계어
◦ PUSH
▹ Stack(Buffer)에 Data 저장하는 명령어
▹ 먼저 ESP를 감소시키고 32Bit(4Byte) 값을 Stack(Buffer)에 복사
◦ POP
▹ Stack(Buffer)에 있는 Data를 복사해 'Destination OPERAND'에 저장하는 명령어
▹ ESP가 가리킨 Memory에 저장된 내용을 'Destination OPERAND'에 저장 후 ESP 값을 증가시킨다.
· EIP 값을 변경하는 명령어
◦ JMP
▹ 분기문(Ex, for, while, switch etc.) 사용 시 사용하는 명령어
◦ CALL
▹ 함수 호출시 사용하는 명령어
◦ RETN
▹ 함수 Return 시 사용하는 명령어
▹ Buffer의 반환 값을 EIP에 저장한다.
▹ POP EIP와 같은 명령어
◦ JMP & CALL 비교
▹ EIP Backup
▸ CALL : EIP 값을 변경하기 전에 Stack(Buffer)에 Backup
▸ JMP : EIP 값을 변경하기 전에 Stack(Buffer)에 Backup 하지 않고 바로 변경
▹ 조건 분기문
▸ CALL : 조건 분기 가능한 명령어 형태가 존재하지 않는다.
▸ JMP : 조건 분기 가능한 명령어 형태가 존재한다.
- Function Prologue & Epilogue
· Function Prologue
◦ 함수가 사용할 Stack Area를 확보하는 Code
◦ Stack Frame을 사용하는 경우 함수는 항상 Stack Frame Pointer를 설정하는 기계어 Code로 시작된다.
◦ Code의 예
▹ PUSH EBP : 함수를 호출한 것의 Stack Frame Pointer를 Backup하는 Code
▹ MOV EBP, ESP : 함수를 호출 당한 측(Callee)의 Stack Frame 기준점을 설정하는 Code
▹ SUB EBP, [Num] : 지역 변수를 위한 공간을 확보하는 Code
· Function Epilogue
◦ 함수가 사용한 Stack Area를 해제하는 Code
◦ Stack Frame을 사용하는 경우 함수는 끝 부분에 Stack Frame Pointer를 원래대로 복원하는 Code가 위치한다.
◦ Code의 예
▹ MOV ESP, EBP : 지역변수의 공간을 해제하는 Code로 지역변수가 존재할 시만 위치
▹ POP EBP : 미리 저장한 호출하는 측의 EBP(SFP)를 원래대로 복원하는 Code
- Assembly Language의 Register로의 Data 저장 순서
· Endian
◦ 1Byte 이상의 Data를 Register에 저장할 때 사용되는 저장 순서를 정의
◦ 단위 : byte
◦ 방식
▹ Little Endian
▸ Data를 높은 주소에서 낮은 주소로 Byte 단위로 저장하는 방식
▸ 일반적인 CPU(Intel, AMD)에서 사용하는 방식
▸ 저장 예시
▹ Big Endian
▸ Data를 낮은 주소에서 높은 주소로 Byte 단위로 저장하는 방식
▸ 저장 예시
'Reversing > Theory' 카테고리의 다른 글
Chapter 6. PE header I - PE Format (0) | 2015.08.16 |
---|---|
Chapter 5. Calling Convention (0) | 2015.08.16 |
Chapter 4. Stack (0) | 2015.08.16 |
Chapter 2. Register & Byte Ordering (0) | 2015.08.16 |
Chapter 1. About Reverse Engineering (0) | 2015.08.16 |