본문 바로가기

Reversing/Theory

Chapter 3. Memory & Assembly Language

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