김승현
KISA Academy - 리버스 코드 엔지니어링 중급 (4~12강) 본문
4강 [이론] PE 파일의 개괄적 구조와 실행전후 변화
PE(PE-COFF) 파일이란?
윈도우 운영체제에서 사용하는 실행파일의 포멧
ex) EXE/DLL/SYS 등
일부 영역을 제외하곤 실행 전후로 모습이 거의 유사함
PE파일
Header와 여러 개의 Section으로 이루어져 있음.
header에서 집중해서 봐야 할 부분
- ImageBase
- 해당 PE파일이 메모리에서 매핑되는 시작 주소
- AddressOfEntryPoiont
- PE파일이 매핑된 후 가장 먼저 실행될 코드의 위치
---- 보통 Header를 읽으면 위의 정보와 section 개수와 위치값, 이름, protection을 얻을 수 있음(section table)
---- 보통의 r 권한만 있음
필수적인 Section
- .text Section
- 보통 컴파일된 기계어 코드가 포함됨
- 코드니까 보통 r x 권한이 있음
- .data Section
- 보통 전역변수들이 포함됨 - 식별가능한 문자열들이 잘 발견됨
- (strings 같은 함수에서 이 부분의 문자열이 나오는 경우가 많음)
- 보통 r w 권한이 있음
- 보통 전역변수들이 포함됨 - 식별가능한 문자열들이 잘 발견됨
- .idata Section(i는 import)
- 보통 EXE파일 내 위치함
- DLL이름, API이름으로 되어 있음 보통
- 실행파일의 기능을 엿볼 수 있는 Section( [ex] internetConnect이런 이름이 있으면 연결 하는 구나를 할 수 있음)
- r권한이 있고 바인딩하는 과정도 있을 때가 있어서 w권한도 있을 때 있음
section과 header 각각 사이엔 padding 공간이 포함되어 있음 0000 이런 거로 채워짐
예시 - a.exe
page 단위로(*page: 최소한의 접근 통제 단위 ) 배치됨. 이에 각 protection의 단위는 page.
페이지에 적제 했는데 만약 공간이 남으면 해당 부분은 padding 영역이 됨.
5강 [이론] PE 파일의 주요 자료구조 분석 - DOS 헤더와 DOS Stub 코드
DOS Header란?
- 구버전 OS인 MS-DOM와의 호환을 위해 존재하는 헤더, 주로 DOS Stub 영역의 코드를 실행하는 데 사용
최근엔 거의 참조하지 않지만 호환을 위해 꼭 알아야 하는 영역!
PE 파일은 DOS 헤더로 시작함. 디스크 상에선 파일의 첫 부분임 (매직코드 MZ가 DOS 그거 2bytes)
e_lfanew는 PE헤더의 위치를 가짐 요즘 대부분의 윈도우 로더는 e_magic과 elfanew만을 참조함...
로더라는 프로그램이 메모리에 올라가면,
로더는 MZ라는 문자열을 찾음 (이미지 도스 헤더에 있는),
그 후 점프를 해서 e_lfanew로 이동하고 PE Header(PE)로 이동함. 정상적인 PE_COFF 형식을 갖춘 지 확인하는 느낌
e_cblp, e_cp와 같은 헤더의 변수들은 시작할 때 셋 되어야 할 레지스터 값들이라고 함 이 값 올라가며 DOS Stub Code가 같이 올라감 stub code엔 처음엔 기계어 코드가 있고 This program cannot be run in ... 이런 문자열이 후반부에 존재함 화면에 저 문자열을 출력해주는 코드임
결국 DOS 영역은 dos 환겨에선 실행할 수 없다는 걸 알려주기 위해 존재하는 영역이라고 생각하면 좋음
6강 [실습] PE 파일의 주요 자료구조 분석 - DOS 헤더와 DOS Stub 코드 분석 실습
7강 [이론] PE 파일의 주요 자료구조 분석 - PE 헤더
IMAGE_NT_HEADER란?
실행파일을 가상주소공간에 매핑시키고 코드를 실행하는 데 필요한 주요 정보를 담음
IMAGE_NT_HEADER는 PE 포멧 파일의 중요한 자료구조 중 하나.
PE헤더는 PE_COFF에서
DOS Header, DOS Stub Code 다음으로 오는 것으로 IMAGE_NT_HEADER이다. 이 위치는
DOS Header 젤 마지막에 IMAGE_DOS_HEADER.e_lfanew를 보면 알 수 있음
그 위치 첫 시작의 시그니처를 확인 하면 여기가 맞구나라는 걸 알 수 있음
pe헤더의 구조
- Signature (PE)
- IMAGE_FILE_HEADER
- 어떤 아키텍쳐가 대상인지, 언제 빌드가 됐는지 등에 대한 정보를 담음
- IMAGE_OPTIONAL_HEADER
- 중요한 정보를 담음 가상주소공간 어디에 적제될지, 어디서 코드를 시작하면 되는지에 대한 정보를 담음
- 코드 시작방식 등을 공부하고 싶다면 이 영역을 공부해야함
- 주요 멤버
- ImageBase
- 가상 주소 공간의 위치
- AddressOfEntryPoint
- 메모리에 로드된 후 가장 먼저 실행될 코드의 위치
- FileAlignment
- 주소 시작 위치 지정 결정
- SectionAlignment
- 메모리 상에서 각 섹션의 정렬 단위
- ImageBase
Virtual address - 매핑될 메모리의 주소
Offset - 이격
AddressOfEntryPoint, FileAlignment, SectionAlignment 모두 오프셋 값으로 표현함
값이 50이면 MZ로부터 50만큼 떨어져 있다는 것을 나타
ImageBase는 위와 다르게 절댓값으로 표현됨
실행파일이 더블클릭되면
가상주소공간에 올라가고 분석되기 시작, mz가 제대로 되어 있다면 IMAGE_DOS_HEADER.e_lfanew를 읽고
PE헤더를 읽음 PE 시그니처가 있는지 확인한 후 여러 일(시그니처부터 쭉..)을 하고 ImageBase값 확인 ImageBase 위치 가상주소공간에 매핑함 그 이후 쭉 메모리에 매핑 저장될 때 분리되어 다르게가 아니라 거의 비슷하게 매핑됨
로더 프로그램 자기 일이 끝난 후 코드를 실행해야 겠다는 시점이 존재 이 값은 AddressOfEntryPoint에 존재(x 권한 넘김)
파일 내 젤 먼저 실행되는 코드의 위치를 알고 싶으면
ImageBase + AddressOfEntryPoint 위치로 이동해야함
-> AddressOfEntryPoint는 offset이기 때문.
8강 [실습] PE 파일의 주요 자료구조 분석 - PE 헤더 분석 실습
stud_PE 프로그램 사용
- 시각화가 잘 되어 있기 때문
시작 주소와 ImageBase의 위치가 동일함
SectionAlignment가 00001000이면 header부터 section1, section2, section3 이렇게 있으면 블럭 단위가 1000으로 나뉜다는 느낌 (사진에선 단위가 1000인 것) 단위는 페이지임!
.text가 1000보다 커서 2개의 페이지를 잡아먹는다고 보면 됨 (추가적으로 남은 건 padding)
00403000엔 다음 Section이 들어감.
이런 매핑 방법은 protection 때문
9강 [이론] PE 파일의 주요 자료구조 분석 - 섹션테이블
섹션 테이블이란?
로더가 각 섹션을 메모리에 로드 하기 전 참조하는 테이블 => 로더를 위해 존재하는 테이블이라 볼 수 있
동일한 자료구조가 배열처럼 나열되어 있음(테이블)
PE Header 뒤에 나옴(DOS Header, DOS Stub Code, PE Header, Section Table, Section#1~ ...)
section에는 컴파일러마다 다르지만 보통 .text, .data ,,, etc
섹션 테이블의 각 엔트리들은 하나의 섹션들을 담당함( 섹션과 1ㄷ1 대응, PE Header에 S.T의 엔트리 개수가 나타남 )
Section Table의 멤버
- 섹션의 이름 (.text, .data, .idata ...등의 이름이 보임 )
- PointerToRawData : 파일 상에서 해당 섹션의 위치 ( base )
- 만약 400이라면 파일의 시작 지점부터 정확히 400만큼 떨어진 위치에 첫 번째 섹션이 존재한다는 뜻
- 파일 내부에서 Section의 주소 블로그펌
- 만약 400이라면 파일의 시작 지점부터 정확히 400만큼 떨어진 위치에 첫 번째 섹션이 존재한다는 뜻
- VirtualAddress : 메모리에 올라갔을 때의 위치 ( offset )
- 메모리에 올라간 파일의 시작 위치에서부터 1000만큼 떨어진 위치에 첫 번째 섹션을 매핑
- 파일이 실행될 때 메모리에 올라오는 Section의 주소 (Image Base로부터의 Offset) 블로그펌
- 메모리에 올라간 파일의 시작 위치에서부터 1000만큼 떨어진 위치에 첫 번째 섹션을 매핑
섹션테이블의 역할
- 섹션이 해당 파일 어디에 있고 이를 어디에 적제해야 하는지 알려줌
- Protection을 알려줌 (R, W, X) - Characteristics 멤버에서
10강 [실습] PE 파일의 주요 자료구조 분석 - 섹션테이블 분석 실습
분석 도구
CFF Explorer
Section Table 값 확인을 위해 Nav에서 Section Header 클릭
행: 한 섹션에 대한 자료구조들
열: 각 자료구조에 대한 섹션의 값
파일 상에서 위치가 궁금하면 Raw Address
가상 메모리에서 궁금할 땐 Virtual Address
어디에 적제된지 알고 싶으면 Virtual Address + ImageBase 값을 해야 함 만약 ImageBase가 00400000이라
.text는, 00401000
.data는, 00403000
*ImageBase란 해당 실행 파일이 매핑될 가상 주소 공간의 주솟값
protaction값은 권한이며 마이크로소프트 공식 홈페이지에서 flag값의 권한을 찾아볼 수 있음
IMAGE_SCN_MEM_EXECUTE : 0x20000000
IMAGE_SCN_MEM_READ : 0X400000000
IMAGE_SCN_MEM_WRITE : 0X800000000
-> 0x600000000이라면 실행과 읽기 권한을 포함했다는 뜻 ( 2 + 4 )
위의 0x60500060은 .text Section인데 여긴 기계어 코드의 영역임. 코드기에 읽고 그 코드를 실행하기에 RX가 포함됨E
E(Excute)와 R(Read)권한이 실제로 있는 것을 확인 가능함
11강 [이론] PE 파일의 주요 자료구조 분석 - 임포트 매커니즘
EXE 확장자를 가진 PE-COFF 파일은 가상주소 공간에서 매핑되어도 DLL내 API를 호출하지 않고는 혼자 일 할 수 없음
그렇기에 PE-COFF 포맷에는 실행 과정에서 참조해야 하는 DLL과 API들을 구조화하여 유지하는데 이를 Import Table이라고 함
PEE-COFF파일은 import를 IMAGE_IMPORT_DESCRIPTOR를 통해 체계화하고 구조화하고 있음
IMAGE_IMPORT_DESCRIPTOR는 PE-COFF파일의 헤더 중 OPTIONAL_HEADER에 포함되어 있음
정확히는, OPTIONAL_HEADER의 IMAGE_DIRECTORY_ENTRY_IMPORT를 통해 이동 가능함
임포트 테이블은 section에 존재. 일반적으로 .idata에 존재하는 경우가 多 (idata의 i가 import의 i)
이 섹션을 분석하면 함수명이나 이런 문자열을 자주 얻을 수 있음
IMAGE_IMPORT_DESCRIPTOR라는 자료구조는 하나의 실행 파일 내에 여러 개 존재할 수 있음 = 배열
끝은 NULL 이들이 모여 import table을 이룸
DLL이나 API의 주소 값들은 빌드하는 단계에서 알 수 없음. 가상주소 공간 상의 위치는 랜덤함
-> 보안 상의 목적으로 ( 공격자에 의해서 특정 코드를 실행하거나 정보 참조를 막기 위함)
-> ASLR( Address Space Layout Randomization )
바인딩
DLL내 API주소를 찾고 그 주소를 자료구조에 Overwriting하는 과정 Loader에 의해 실행
프로그램 실행 중 필요에 따라 동적으로 binding이 이루어질 수 있음( Dynamic Binding)
IMAGE_IMPORT_DESCRIPTOR엔 총 다섯 개의 멤버가 있음
- OriginalFirstThunk
- TimeDateStamp
- ForwarderChain
- Name
- 참조하는 DLL의 이름이 들어 있음
- FirstThunk
- 포인터 값임. 함수의 주소 값이 들어 있음 IAT( Import Address Table)의 시작 주소 값을 가짐
4번째 멤버인 Name에서 xxx.dll이 있으면 5번째 멤버의 IAT를 참조하여 얻은 주소는 xxx.dll의 함수의 시작 주소임
-> IAT에는 바인딩 이후 함수들의 주소들이 입력됨
12강 [실습] PE 파일의 주요 자료구조 분석 - 임포트 매커니즘 분석 실습
분석 도구
CFF Explorer
navigator에서 Data Directory 클릭
-> import와 관련된 멤버들 확인 가능. 해당 자료 구조에서는 Offset, Size, Value, Section을 볼 수 있음
Import Directory RVA의 Value는 메모리 상에서의 Offset임.
-> ImageBase의 값에 7000을 더해야지 Import Directory의 주소를 알 수 있음
각 IMAGE_IMPORT_DESCRITOR들
파란색은 첫 IMAGE_IMPORT_DESCRITOR의 Name, 초록색은 FirstThunk이다. 각 주소는 00407520, 00407104로 가기
KERNEL32.dll과 관련된 것임을 알 수 있음
해당 파일은 KERNEL32.dll, ntdll.dll, msvcrt.dll 3개의 라이브러리를 참조하 IMAGE_IMPORT_DESCRIPTOR는 2개임을 알 수 있음
'교육 > KisaGym' 카테고리의 다른 글
KISA Academy - 리버스 코드 엔지니어링 중급 (24~26강) (0) | 2024.07.13 |
---|---|
KISA Academy - 리버스 코드 엔지니어링 중급 (21~23강) (0) | 2024.07.12 |
KISA Academy - 리버스 코드 엔지니어링 중급 (16~20강) (1) | 2024.07.12 |
KISA Academy - 리버스 코드 엔지니어링 중급 (13~15강) (0) | 2024.07.11 |
KISA Academy - 리버스 코드 엔지니어링 중급 (1~3강) (0) | 2024.07.04 |