악성코드 분석을 위한 리버스 엔지니어링 - PE 구조
위의 파일에서 직접 PE파일과 비교해서 찾아보면 더욱 더 좋다.
PE파일 포맷이란?
PE 포맷(Portable Executable)은 윈도우 운영 체제에서 사용되는 실행 파일, DLL, object 코드, FON 폰트 파일 등을
위한 파일 형식이다. PE 포맷은 윈도우 로더가 실행 가능한 코드를 관리하는데 필요한 정보를 캡슐화한 데이터 구조체이다.
이것은 링킹을 위한 동적 라이브러리 참조, API 익스포트와 임포트 테이블, 자원 관리 데이터 그리고 TLS 데이터를 포함한다.
윈도우 NT 운영체제에서, PE 포맷은 EXE, DLL, SYS (디바이스 드라이버), 그리고 다른 파일 종류들에서 쓰인다.
통일 확장 펌웨어 인터페이스 (EFI) 설명서는 PE가 EFI 환경에서 표준 실행 파일 형식이라고 언급한다.
윈도우 NT 운영 체제에서, PE는 현재 IA-32, IA-64, x86-64 (AMD64/Intel64), 그리고
ARM instruction set architectures (ISAs)를 지원한다. 윈도우 2000 이전에서, 윈도우 NT는 (그리고 PE) MIPS, Alpha,
그리고 파워PC ISAs를 지원했다. PE가 윈도우 CE에서 사용되므로 이것은 MIPS, ARM (Thumb 포함), 그리고
SuperH ISA의 변형들을 지원하고 있다.
PE파일을 왜 만들었는가?
마이크로소프트에서 PE파일을 만듬
PE파일의 종류
종류
|
확장자
|
실행파일
|
Exe,scr
|
라이브러리 파일
|
Dll, ocx,cpl,drv
|
오브젝트 파일
|
Obj
|
드라이버 파일
|
Sys,vxd
|
PE파일 포맷 구조
대표적으로 PE파일 구조를 보게해주는 툴인 PEView가 있다.
IMAGE_DOS_HEADER
- PE 파일 포맷을 만들 때 그 당시에 쓰던 도스 파일에 대한 하위 호환성을 고려
- 중요한 멤버는 첫 번째 e_magic(DOS Signature)와 마지막 멤버인 e_lfanew(NT Header의시작주소) 두 가지임
- e_magic은 DOS 시절 실행 파일을 설계한 Mark Zbikowaski의 이니셜로 만든 것
- e_lfanew는 NT Header의 시작 주소를 나타냄
- DOS Header의 e_magic, e_lfanew값 중 하나라도 변경된다면 프로그램이 실행되지 않음
4D 5A : DOS Signature
E0 00 00 00 : NT시작 주소를 나타냄
MS-DOS Stub Program
- DOS Stub의 존재 여부는 옵션이며 크기도 일정치 않음
- 있어도 되고 없어도 되는 부분
- 크기가 정해져 있는 것이 아니라 DOS stub에 악성코드를 심기도 함
- DOS Stub에는 어셈블리어 코드와 This program cannot be run in dos mode라는
문자열이 있음
- DOS 모드에서 해당 파일을 실행하면 위의 문자열을 출력하고 종료
IMAGE_NT_HEADERS
- NT Header 구조체
- DOS Header의 마지막 멤버가 가르키는 주소에서 시작함
- 3개의 멤버로 구성되어 있음
Signature – File Header – Optional Header
•File Header 주요
멤버
1. Machine
CPU별
고유한 값, Intel x86 = 0x014c, intel x64=0x0200의
값
2. NumberOfSections
섹션의
개수를 나타냄
3. SizeOfOptionalHeader
Optional Header의
크기를 나타냄
4. Characteristics
파일의
속성을 나타냄 // 실행이
가능한지 또는 DLL 파일인지
등의 정보가 있음
•Optional Header의 주요 멤버
Magic넘버는 32비트면 10B, 64비트면 20B를 가짐
EP의 RVA(Relatvie Virtual Address)값을 가지고 있음
프로세스의 시작 위치 주소값(RVA)
PE파일이 로딩되는 시작 주소임
파일을 메모리에 로딩 후 EIP레지스터의 값 = ImageBase+AddressOfEntryPoint
메모리에서의 기준주소
메모리에서 섹션의 최소단위
파일에서 섹션의 최소단위
PE파일이 메모리에 로딩되었을 때의 크기
PE헤더의 전체 크기
GUI,CUI버전인지 드라이브파일인지나타냄
1= 드리이버, 2=GUI, 3=CUI
DataDirectory배열의 개수를 나타냄
IMAGE_DATA_DIRECTORY구조체의 배열, 각 항목은 정해진 값을 가지고 각 항목 table이 어디에 위치해 있는지
RVA값과 크기를 나타냄
0B 01 : Magic
89 36 00 00 : AddressOfEntryPoint
00 00 00 01 : ImageBase
00 10 00 00 : SectionAlignment
00 02 00 00 : FileAlignment
00 00 03 00 : SizeOfImage
00 04 00 00 : SizeOfHeader
02 00 : Subsystem
10 00 00 00 : NumberOfRvaAndSizes
Image Base + AddressOfEntryPoint = EIP
실행시 위의 주소로 그대로 EIP가 찍히진 않는다.
OptionalHeader에 DllCharacteristics이 ASLR과 관련되어 있기때문이다.
OptionalHeader에서 DllCharacteristics값을 바꿔 ASLR을 사용안하는 방법과
Section Header에 가서 NumberOfRelocations을 조정하면 고정된 위치로 나온다고 함.
SECTION
메모리에서 섹션이 차지하는 크기
메모리에서 섹션의 시작 주소(RVA)
파일에서 섹션이 차지하는 크기
파일에서 섹션의 시작위치
섹션의 속성(Bit OR)
8C A6 00 00 : VirtualSize
00 10 00 00 : VirtualAddress
00 A8 00 00 : SizeOfRawData
00 04 00 00 : PointerToRawData
20 00 00 60 : Characteristics
.text 섹션
|
컴파일된 코드, 코드, 실행, 읽기 속성, 컴파일 후의 결과가 저장되는 섹션
|
.data섹션
|
읽기/쓰기가 가능하고 초기화된 전역변수, 상수가 존재한느 섹션
|
.rdata섹션
|
읽기만 가능하고 문자열 상수나 const로 선언된 변수처럼 읽기만 가능한 읽기 전용 섹션
|
.idata섹션
|
읽기/쓰기모두 가능하고 IAT와 관련된 정보가 들어가있는 섹션
|
.edata섹션
|
읽기만 가능하고 EAT와 관련된 정보가 들어 있는 섹션
|
.bss섹션
|
읽기/쓰기가 가능하고 초기화 되지 않은 전역 변수
|
.rsrc섹션
|
읽기만 가능하고 리소스가(아이콘 등)이 저장되는 섹션
|
BOUND IMPORT Directory Table, BOUND IMPORT DLL Names
.exe(바이너리파일)은 라이브러리를 가지고 있다. 일일이 코딩하기 귀찮으니까 가져다 쓰는 것이다.
리눅스는 .so가 윈도우는 .dll이 비슷한 역할을 한다.
A.exe와 B.exe가 있고 .dll이 있으면 A와 B에서 .dll을 다 쓸 수 있다.
.dll에서는 쓸 수 있는 함수들이 있을 것이다. 그 함수들을 일부분만 쓰게 해놓지 않는 경우가 대부분이다.
.dll도 실행파일이다. A.exe에서 .dll이 쓰는 함수를 받아온다. 그리고 .dll을 한개만 쓰는게 아니라 여러개의 .dll을 사용할 수 있다.
Directory Table에 있는 함수를 전부 쓰는 것이 아니다. 확장성을 위해서 놔둔 것이다.
A.exe에서 직접 .dll에 있는 함수를 쓸 수 없으니 포인터 형태로 가지고 온다.
A.exe가 .dll을 읽어올 수 있는 구조체를 불러와서 .dll의 함수 주소를 가져오는 것을 IAT라고 한다.
.dll에 있으니까 그 안에 어떤 함수를 쓰는지 확인해야한다. 특정 .dll을 쓴다고 악성코드라고 단정지을순 없다.
.dll에 있는 어떤 함수를 쓰는지 파악해야 그 파일의 성질을 알 수 있다.
IAT는 dll의 정보를 가지고 있는게 아니라 .dll을 향하는 어드레스를 리스트로 가지고 있는 것이다.
.dll은 A.exe와 B.exe등 여러 곳에서 사용할 수 있다. 이때 어느 바이너리에서 연동되어 사용되는지 알 필요가 있다.
그래서 EAT가 필요하다. EAT는 구조체 형식이다.
IMPORT_DESCRIPTOR검색해서 OriginalFirstThunk 이것을 꼭 기억해두자
IAT
ex) Kernel32.dll
'Reversing' 카테고리의 다른 글
파일에 있는 String을 가져오는 툴 Bintext (0) | 2017.08.23 |
---|---|
PE구조 요약 툴 CFF Explorer (0) | 2017.08.23 |
OllyDBG를 이용한 지뢰찾기 지뢰위치 확인 (0) | 2017.08.22 |
OllyDBG를 이용한 지뢰찾기 시간흐름 변경 (0) | 2017.08.22 |
악성코드 분석을 위한 리버스 엔지니어링 - 기본지식2 (0) | 2017.08.22 |
최근댓글