@ 01_리버싱 선수 지식
- 역공학 분석 : 실행 파일을 역으로 분석하는 행위
- 정상적인 리버싱 : 프로그램 분석, 업데이트, 패치, 악성 코드 분석
- 악의적인 리버싱 : 프로그램 크랙, 무단 사용, 시리얼 키 우회, 악성 코드 제작/유포
1. 실행 파일(Excutable File)
- 명령어에 의해서 특정 작업을 수행할 수 있도록 생성된 파일(Code, Data 포함되어 있음)
- 각각의 운영체제마다 실행 파일 형식은 다음과 같다.
Windows PE(Portable Exectable)
Linux ELF(Excutable & Linkable Format)
MAC Mach-O(Mach Object File Format)
2. 프로그램 & 프로세스 & 프로세서 & 쓰레드
- 프로그램 : 작업을 수행하기 위해서 명령어/데이터들이 포함되어 있는 실행 파일
- 프로세스 : 작업을 수행하기 위해서 메모리에 올라간 프로그램 단위 (Ex : 일꾼)
- 프로세서 : 메모리에 올라간 프로세스를 처리하는 CPU
- 쓰레드 : 생성된 프로세스에서 처리 및 흐름 과정을 담당하는 프로세스 안에 또 다른 프로세스 (Ex : 일꾼의 손 개수)
3. PE 파일
- Windows에서 사용하는 실행 파일 형식
- 원본 디렉토리 뿐만 아니라 다른 디렉토리로 이동해도 실행이 가능한 특징을 갖고 있다.
- 별도의 프로그램 설치 및 관계된 파일이 없어도 윈도우에서 실행 가능
- PE 파일 이해 중요성
프로세스 적재을 위한 정보 분석
API 호출을 위한 IAT 분석
코드 사이즈/섹션 위치 분석
패킹/언패킹 유무 분석
악성 코드 분석
4. 가상 메모리
- 프로세스와 메모리 공간을 관리하기 위해서 운영체제가 사용하는 논리적인 메모리이다.
- 모든 프로세스는 자신만의 가상 메모리를 갖고 있으며, 32bit/64bit 프로세스 각각 4G/8G 공간이 할당된다.
- 운영 체제 규칙에 의해서 실제 물리 메모리 주소와 가상 주소를 매핑한 이후 해당 영역을 사용한다.
- 이때, 서로 다른 프로세스의 가상 주소가 물리 메모리 주소로 매핑될때 중첩 및 침범되지 않는다.
A 프로그램을 실행하면 A를 위한 가상 메모리가 생성되고 가상 메모리를 사용한다.
가상 메모리에 데이터가 저장되면 실제 메모리에도 데이터가 저장되는 주소는 다르다 따라서 매핑을 해서 써야한다.
5. 메모리 주소
1) 절대 주소
- 메모리 관리자 입장에서 보는 물리 주소를 의미한다.
- 즉, 메모리 레지스터가 사용하는 주소이며, 컴퓨터에 장착된 메모리(램)의 실제 주소이다.
2) 상대 주소
- 사용자 프로세스 입장에서 보는 가상 주소를 의미한다.
- 사용자 영역이 시작되는 번지를 0번지로하여 사용한다.
3) 메모리 관리자(재배치 레지스터)
- 실제 메모리 내의 절대 주소를 상대 주소로 변환하는 작업을 처리한다.
물리 주소
0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9
|- 사용중--| |- 사용중--|
가상 주소
0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9
0x2 0x3 0x4 0x7 0x8 0x9
4) 경계 레지스터
- 메모리를 사용할때는 다음과 같이 운영체제 영역과 사용자 프로그램 영역으로 구분된다.
- 이때, 사용자 영역이 운영체제 영역으로 침범하지 않도록 경계 레지스터가 경계 지점의 주소를 저장하여 검사한다.
- 만약, 사용자 영역이 운영 체제 영역을 침범한다면 해당 프로세스를 종료한다.
[낮은 주소]
─────────
운영체제 영역
───────── <--- 경계 레지스터 : 사용자 프로그램의 주소들이 현재 기준보다 높은 주소인지를 검사한다.
사용자 프로그램 영역
─────────
[높은 주소]
6. Image Base & RVA & VA
1) Image Base
- PE 파일이 메모리에 로드되는 가상 주소이다.
- 이 영역은 PE 파일마다 예약된 범위가 있다.
2) RVA
- Relative Virtual Address
- PE 파일이 가상 주소 공간 내에 로드된 이후, 이미지의 시작 주소에 대한 상대 주소이다.
- 즉, PE 파일이 메모리에 로드된 이후, Image Base 기준으로 계산된 특정 위치를 의미한다.
- PE 파일 시작 주소에서 어느정도 떨어져 있는지를 측정할 수 있다.
- RVA = VA - ImageBase 주소
3) VA
- Virtual Address
- 가상 메모리 주소 공간에 프로세스의 절대 주소이다.
- 즉, PE 파일이 메모리에 로드된 이후, 0번지(0x0000000) 부터 계산된 특정 위치를 의미한다.
- VA = ImageBase 주소 + RVA 주소
메모리
┌──────┐ -------------------- 0
파일 │ │ │
┌──────┐ ├──────┤ -------------------- 5 (Image Base)
│PE 파일 │ │ │ │ │
│ │ │ PE 파일 │ RVA VA
└──────┘ │ │ │ │
│ │ │ │
├──────┤ --------------------
└──────┘
이미지 베이스, RVA, VA
PE파일을 실행하면 가상메모리에 로드되는데 0x000000에 올라가지않는다.(운영체제영역, 사용자 영역때문)
PE파일 마다 올라가는 곳이 정해져있다. 이 곳을 이미지 베이스라고 한다.
내가 뭔가 확인하고자 하는 곳을 0x00000000 부터 확인하면 va
이미지 베이스부터 확인하면 rva이다.
Ex1) VA가 8일때 RVA 주소는 어떻게 되는가? 3
Ex2) RVA 7일때, VA는 주소는 어떻게 되는가? 12
EX3)
Image Base 1000000, Base of Code 1000(RVA)이다.
Base of Code는 SECTION text가 메모리에 올라갈때 Image Base 기준으로 부터 상대주소이다. RVA를 확인해보면 1000인걸 확인할 수 있다.
VA 값은 RVA(1000) + Image Base(1000000)를 더한 값이다.
7. ASLR
- Address space layout randomization
- 메모리 보호 기법
- 프로그램이 메모리에 로드되는 주소(Image base)를 랜덤으로 변경하는 기능이다.
8. API
- Application Programming Interface
- 운영체제, 프로그램 언어가 응용 프로그램에서 사용할 수 있도록 기능을 제공하는 인터페이스(함수)이다.
- MSDN 문서 참조
- Ex) 구글 검색 -> createfile msdn 검색
9. 컴파일
- 모든 헤더와 소스 파일 내용을 합쳐서 하나의 기계어 코드를 생성하는 기능을 수행한다.
- 또한, 소스 코드에 오류가 있는지를 검사한다.
- 컴파일 과정
───────── 컴파일링 ───────────>
[컴파일러] [링커]
소스 코드 > Object Code > 실행 파일
(1010101011...)
<───────── 리버싱 ───────────
10. DLL
- Dynamic Linked Library
- 프로그램들이 동시에 사용할 수 있는 코드, 데이터, 함수를 포함한 라이브러리이다.
- DLL을 사용하면 디스크/메모리에 로드되는 중복된 코드를 최소화, 리소스 사용 최소화, 다른 프로그램 성능을 향상시킬 수 있다.
11. Static Linking & Dynamic Linking
1) Static Linking
- 컴파일 진행시 함수가 링커에 의해서 실행 파일에 연결되는 방식이다.
- 실행 파일에 함수의 코드가 복사되므로 파일 크기가 증가된다.
- 실행 파일에 함수 코드가 포함되기 때문에 완전한 단독 실행 파일로 생성된다.
- 그렇기 때문에 컴파일이 끝나면 라이브러리 파일이 필요없다.
- 사실상 프로그램 안에 함수를 정의한 것과 똑같다.
IE A 기능, B 기능, C 기능, D 기능
Chrome A 기능, B 기능, C 기능, D 기능
Firefox A 기능, B 기능, C 기능, D 기능
2) Dynamic Linking
- 프로그램 실행시 함수가 연결된다.
- 컴파일 진행시 호출할 함수의 정보만 포함하고 실제 함수 코드 정보는 포함되지 않는다.
- 그렇기 때문에 파일 크기가 증가되지 않는다.
- 단, 실행 파일에서 사용할 함수를 갖고 있는 라이브러리 파일이 꼭 있어야 한다.
IE
Chrome A 기능, B 기능, C 기능, D 기능
Firefox
12. DLL 로드 방식(Dynamic Linking 해당)
1) 명시적 링킹
- 프로그램에서 필요한 시점에 DLL/함수 정보를 로드하고 사용한 이후 해제한다.
- 다음과 같은 3개의 함수를 이용하여 DLL를 로드한다.
LoadLibrary() 필요한 DLL을 프로세스 가상 메모리에 매핑/로드하는 함수(DLL 불러옴)
GetProcAddress() DLL 함수의 포인터/주소를 획득하는 함수(DLL로부터 함수를 불러옴)
FreeLibrary() 프로세스 가상 메모리에서 DLL를 반환/언로드하는 함수(DLL 해제함)
- LoadLibrary 함수를 이용하여 프로세스 메모리 공간에 동적으로 DLL을 로드한다.
- 그리고 GetProcAddress() 함수를 이용하여 DLL에서 사용하고자 하는 함수의 포인터/주소를 획득한다.
- 획득한 함수 포인터/주소로 원하는 함수를 호출하고, 사용 이후에는 FreeLibrary() 함수를 이용하여 DLL를 언로드한다.
2) 암시적 링킹
- 실행 파일 자체에서 사용할 DLL과 함수 정보를 포함한 이후 프로그램 실행시 로드한다.
- 즉, 프로그램이 시작되면서 해당 DLL를 바로 로드하는 방식이다.
- PE 로더가 PE 파일 안에 있는 함수 내용/목록을 확인하여 DLL 파일을 메모리에 로드한다.
'레나 튜토리얼' 카테고리의 다른 글
Ollydbg 패치 (0) | 2022.07.30 |
---|---|
Ollydbg 설명 (0) | 2022.07.30 |
32_패킹&언패킹 (0) | 2022.07.28 |
MOV, LEA, ADD, SUB, IMUL, IDIV (0) | 2022.07.28 |
02_PE 파일 분석(PE 헤더) (0) | 2022.07.26 |