리버싱 기초지식
리버싱 공부전 기초지식
-들어가기전에 '리버싱 입문'이라는 책을 공부한 것임을 밝힌다.
프로그램 실행구조
-윈도우에서 실행파일을 PE파일이라 부른다.
-기본적으로 HDD(하드디스크)에 저장한다
-PE파일은 header와 body로 구성한다고 본다.
-OS 로더가 헤더를 분석해서 바디에 있는 코드와 데이터를 '메모리'에 배치한다.
ㄴ 메모리에 로딩시: 메모리에서 코드 영역,데이터 영역에 들어감
ㄴ프로그램 실행시:스택영역,히프영역에 쌓임
레지스터
프로그램의 명령어는 CPU의 연산장치, 제어장치가 실행한다
따라서 필요 데이터는 모두 레지스터에 있어야 실행이 가능하다.
레지스터: CPU에 있는 고속 기억 장치
주로 사용되는 것들만 소개하겠다.
*범용 레지스터(a,b,c,d 순으로 있다고 외우면 쉽다)
1)EAX-누산기:주로 산술연산에서 사용되고, 함수의 결과값을 저장
2)EBX-베이스레지스터 : 특정주소 저장하고 인덱스에 사용
3)ECX-카운트 레지스터 : 반복적으로 실행하는 명령어를 사용할 때 반복카운터를 저장
4)EDX-데이터 레지스터 : 자료저장, 부호확장명령 등에 사용
*인덱스 레지스터
5)ESI:출발지 주소에 대한 값 저장
6)EDI:목적지 주소에 대한 값 저장
*포인터 레지스터
7)EBP-베이스 포인터 : 스택 내의 변수값을 읽는 데 사용
8)ESP-스택 포인터 : 스택의 가장 끝 주소를 가리킴
9)EIP-명령 포인터 : 다음 명령어의 오프셋을 저장, CS레지스터와 합쳐져 다음에 수행될 명령의 주소 형성
ㄴ CS(실행될 기계 명령어가 저장된 메모리 주소지정)
스택
-LIFO(last in first out) 방식으로 동작
-PUSH,POP이라는 두가지 동작을 한다.
-PUSH를하면 스택의 주소는 작아지고 POP하면 4바이트씩 커짐
-맨 아래 EBP의 주소가 제일 크다.
-프로그램에서 스택은 함수로 인자전달한다.
-함수 호출 시 인자를 스택으로 PUSH하고,종료시 복귀 주소를 스택에서 POP
스택프레임
-서브루틴(함수)만의 스택영역
-함수 호출 시 생성되고, 동작 종료 복귀시 소멸된다
0-1.필요인자를 먼저스택으로 PUSH
0-2.복귀주소를 스택으로 PUSH
1. EBP레지스터 내용 백업
2. EBP레지스터 백업 위치를 함수의 EBP에 집어넣음=>프레임포인터로 사용
PE파일
기계어(운영체제가 이해할 수 있게 컴파일된 언어)로 된 파일.
-PE Header ->공통으로 가짐 /Section Header /Section Data 로 구성.
-PE Header,Section Header를 PE헤더라 통칭하기도 함.
-헤더와 데이터(바디)부분으로 나뉨
*IMAGE_OPTIONAL_HEADER
(안에 있는 것 중 중요한 항목)
(1)Image Base:메모리에 PE파일이 저장되는 시작주소
(2)Adress of Entry Point:프로그램 실행에 대한 제어권이 커널영역에서 코드영역으로 처음넘어오는 주소인 엔트리포인트를 가리킴
(3)Base of Code:코드영역이 시작되는 주소(RVA)
메모리에 로딩시, Image Base (시작주소) + RVA(상대주소) 합산된 주소( = VA )에 저장됨
주소지정방법
헤더 정보로 데이터 위치를 찾을 수 있다
이때 사용하는 주소 형식 3가지
1)pFile : PE파일 내부에서의 오프셋 값 ->물리적으로 HDD에 저장되었을 때 의미있는 값
2)RVA : 메모리에 로드 됐을 때 저장되는 상대주소(특정값을 기준으로 얼마나 떨어져있는지)
3)VA : 가상 메모리상에서 저장되는 실제주소
->2,3은 메모리에 로드됐을 때 의미 있는 값
IAT
-실행파일 안에 어떤 라이브러리의 어떤 함수를 가져다 쓰는지 기록해놓은 정보
-PE파일에서 메모리로 로딩시,
로더는 IAT에 기록된 API 이름을 참조해서 실제 주소를 찾고, API를 가르키는 주소를 적는다