SlideShare a Scribd company logo
1 of 34
Portable Executable (PE) 의 구조PE 의 구조
by somma (fixbrain@gmail.com)
PE – Portable Executable
• Portable Executable
– 16 bit VxD 를 제외한 win32 실행 파일 규격
– Exe, dll, ocx, sys 등
– windows 표준 규격이므로 머신 (CPU) 에 상관없이 windows 운
영체제 하에서 모두 실행 가능한 실행 파일 포맷
RVA
• RVA – Relative Virtual Address
PE
(Exe, dll)
RVA
매핑된 PE
이미지
가상 메모리 공간
가상 주소 0x00000000
RVA
로딩 시작 주소
(ImageBase)
RVA
가상 메모리상에서의 실제 번지 ( 가상 주소 ) = ImageBase + RVA
Section
• Section ?
실행 코드 , 리소스 데이터 , 읽기 전용 데이터 등 비슷한 용도의
데이터들을 페이지 단위로 매핑하기 위한 공간
코드 영역 .text 실행코드를 담는 섹션
데이터 영역 .data, .rdata, .bss 전역 데이터 , 문자열 , VMT 등의
영역
리소스 영역 .rsrc 리소스 , 아이콘 등의 영역
IAT .idata, .didat 임포트 데이터
EAT .edata 익스포트 데이터
기준 재 배치 .reloc 기준 재 배치 영역
DOS 헤더
PE 헤더
섹션 테이블
.text
.data
.rsrc
.reloc
File offset
DOS 헤더
PE 헤더
섹션 테이블
.text
.data
.rsrc
.reloc
0x00400000
메모리 증가 방향
메모리 매핑
PE 의 로딩 방식
• Memory mapped file
– 디스크에 존재하는 파일을 직접 가상메모리 공간에 매핑
– Windows 의 IPC ( 파이프 , 메일 슬롯 , RPC, WM_COPYDATA
등 ) 구현의 근간이 되는 개념
– Pagefile.sys ?
가상 주소 공간
• 가상 주소 – Virtual Address
프로세스는 몽땅 사용할 수 있는 4GB 의 메모리를 제공받는다 .
PE 의 구조
IMAGE_DOS_HEADER
IMAGE_NT_HEADERS
• Signature
– ‘PE00’ 문자열
• IMAGE_FILE_HEADER
• IMAGE_OPTIONAL_HEADER
IMAGE_FILE_HEADER
• WORD NumberOfSections;
IMAGE_SECTION_HEADER 의 개수
• WORD SizeOfOptionalHeader;
IMAGE_FILE_HEADER 다음에 오는 IMAGE_OPTIONAL_HEADER 구조체의 바이
트수 , OBJ 인 경우 0, 실행파일인 경우 sizeof(IMAGE_OPTIONAL_HEADER) 임 .
32 비트 PE 인 경우 0xE0 (224), 64 비트 PE 의 경우 0xF0 (240)
IMAGE_OPTIONAL_HEADER
typedef struct _IMAGE_OPTIONAL_HEADER {
//
// Standard fields.
//
WORD Magic;
DWORD AddressOfEntryPoint; // 프로그램 엔트리 포인트
// WinMainCRTStartup or minaCRTStartup or
// DllMainCRTStartup
//
// NT additional fields.
//
DWORD ImageBase; // PE 가 가상 주소 공간에 매핑될 메모리상의 시작
// 주소 , 디폴트로 0x00400000 (exe),
// 0x10000000(dll)
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
DWORD NumberOfRvaAndSizes; // 바로 다음 필드인 DataDirectory[] 배열의
// 갯수 . 항상 16 이다 (0x00000010)
// 아래의 Direcotry Entries 박스
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
IMAGE_OPTIONAL_HEADER32.DataDirectory
• IMAGE_OPTIONAL_HEADER.DataDirectory[]
– 각 섹션들의 가상 주소를 위한 RVA 와 섹션의 크기정보 저장
– 각 인덱스는 미리 정해져 있다 .
IMAGE_SECTION_HEADER
• IMAGE_NT_HEADERS 구조체 다음에 오늘 구조체 배열
• 이 구조체 배열의 개수는 IMAGE_FILE_HEADER.NumberOfSections 값
• PE 를 구성하는 각 섹션들의 정보를 보관하고 있음
Export section (.edata)
• Dll 처럼 특정 함수포인터 , symbol 등을 외부로 노출하는 경우 생성
됨
• IMAGE_OPTIONAL_HEADER.IMAGE_DATA_DIRECTORY[IMAGE
_DIRECTORY_ENTRY_EXPORT] 구조체가 가리키는 곳이 export
섹션이다 .
• IMAGE_OPTIONAL_HEADER.IMAGE_DATA_DIRECTORY
[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
값이 .edata 섹션의 RVA 값이 됨
• .edata 섹션은 IMAGE_EXPORT_DIRECTORY 구조체로 이루어져
있음
IMAGE_EXPORT_DIRECTORY
• Name
– DLL 의 이름 문자열
• Base
– Export 된 함수들의 서수의 시작 번호 ( 임의의 숫자로 시작 가능 )
– 정확한 서수의 값을 계산하려면 AddressOfNameOrdinal 필드의 값에 Base 필드 값을 더해 주어야 함
• NumberOfFunctions
– AddressOfFunctions 필드가 가리키는 RVA 배열의 개수
– 서수의 끝 번호 – 시작 번호 + 1 의 값
– 불연속적인 서수를 사용하는 경우 NumberOfNames 와 다름
• NumberOfNames
– AddressOfNames 필드가 가리키는 RVA 배열의 개수
– 실제 export 된 함수의 정확한 개수를 나타내는 값임
• AddressOfFunctions
– Export 된 함수들의 함수 포인터를 가진
배열의 RVA
• AddressOfNames
– Export 된 함수들의 심볼을 가리키는
문자열 배열의 RVA
• AddressOfNameOrdinals
– WORD 타입의 배열에 대한 포인터 RVA
– WORD 타입 배열의 각 원소는 ordinal
값을 저장하고 있다 .
MyGetProcAddress() 함수 - 1
MyGetProcAddress() 함수 - 2
Import section (.idata)
• Import 섹션은 해당 PE 가 로드한 외부 모듈 / 함수에 대
한 정보를 보관하는 섹션이다 .
• IMAGE_OPTIONAL_HEADER.IMAGE_DATA_DIRECTORY[IMAGE
_DIRECTORY_ENTRY_IMPORT] 구조체가 가리키는 곳이 import
섹션이다 .
• IMAGE_OPTIONAL_HEADER.IMAGE_DATA_DIRECTORY
[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
값이 .idata 섹션의 RVA 값이 됨
• .edata 섹션은 IMAGE_IMPORT_DESCRIPTOR 구조체로
이루어져 있음
IMAGE_IMPORT_DESCRIPTOR
• OriginalFirstThunk
– IMAGE_THUNK_DATA 구조체 배열의 RVA
– 각 배열의 원소는 IMAGE_IMPORT_BY_NAME 구조체 의 RVA
• Name
– 임포트한 dll 의 이름 문자열
• FirstThunk ( 아주 중요 !)
– PE 가 디스크에 존재할
때는 OriginalFirstThunk
와 동일한 값
– 가상메모리상에서는
IAT 포인터 , 즉 실제
임포트한 함수의 주소
( 바인딩 되었다고 표현 )
IMAGE_THUNK_DATA
• 4 바이트 유니온
• ForwarderString
– 임포트한 함수가 포워딩 된 경우 ‘ dll.RtlGetWin32LastError’ 형태
의 문자열 RVA
• Ordinal
– 서수로 임포트 된 경우 해당
함수의 서수값
• AddressOfData
– 이름으로 임포트 된 경우 해당
함수의 함수 포인터
• Name or Ordinal?
– IMAGE_IMPORT_DESCRIPTOR.OrginalFirstThunk 의 최상위
비트가 설정된 경우 Ordinal 로 임포트 한 것임
IAT 바인딩 과정 - 1
• Disk 에 존재할 때의 Import section 구조
IAT 바인딩 과정 - 2
• 가상 주소 공간에 매핑된 후의 Import section
볼랜드 계열 링커가 생성한 PE 의 IAT 분석
• 볼랜드 계열 링커가 생성한 PE 는 OrginalFirstThunk 필
드가 항상 0 이다 .
• 따라서 가상 메모리 상에서 임포트 한 DLL 및 함수의 서
수 혹은 이름을 역으로 분석해 낼 수 없다 .
• ImportREC 같은 툴로 IAT 복원이 안 된다 . !!
Portable Executable (PE) 의 구조API hooking 101
by somma (fixbrain@gmail.com)
Injecting Technique -1
• Registry 를 이용한 dll 침투 기법
키에 dll 이름을 등록하면 user32.dll 이 로드되면서 이 DLL 들도 함께 로드한
다 .
• 단점
USER32.dll 을 사용하는 어플리케이션만 해당됨 ( 콘솔 APP 는 해당 안됨 )
NT, Win2K 만 해당됨
리부팅 필요
HKEY_LOCAL_MACHINESoftwareMicrosoftwindowsNTCurrentersionWindowsAppInit_DLLs
Injecting Technique -2
• SYSTEM-WIDE Windows Hook
– SetWindowsEx() 함수를 통해서 윈도우 메시지 핸들러를 통해
DLL 을 대상 프로세스 컨텍스트로 침투 시키는 방법
- 이 경우 침투된 dll 들은 서로 다른 프로세스 공간에 존재하므로
데이터 공유를 위해 IPC 메커니즘을 구현함
- 이 방법은 UnHookWindowsEx() 을 통해 dll 을 언로드
- Windows 9x 부터 최신의 windows 까지 모두 사용 가능
- 모든 프로세스의 windows message 를 처리하므로 부하를 가중
시킬 수 있음
STEP 1.
침투하고자 하는 프로세스의 핸들을 얻는다 .
STEP 2.
kernel32.dll 의 LoarLibrary() 함수의 포인터를 얻는다 .
STEP 3.
CreateRemoteThread() 를 통해서 타겟 프로세스에 스레드를 생성
한다 .
이때 lpParameter 는 “ hook.dll” 문자열의 포인터가 넘어갈 것이다
.
STEP 4.
타겟 프로세스는 LoadLibrary(“hook.dll”) 을 호출하는 것과 동일한
결과를 만든다 .
STEP 5.
hook.dll 의 Dll entry 는 타겟 프로세스의 컨텍스트 내에서 필요한
작업을 수행할 수 있다 .
Injecting Technique -3
• Injecting DLL by using CreateRemoteThread() API
– Win9x 계열에서는 사용할 수 없음
– 타겟 프로세스 공간에 스레드를 생성하는 API
생성된 스레드가 실행할 함수 포인터
LoadLibrary () 함수와 동일한 원형을 가진다 !!
Interception mechanisms - 1
• 커널 레벨 후킹
– SSDT hook
– IDT hook
– IRP handler hook
– Sysenter hook
Interception mechanisms - 2
• Window 서브 클래싱
– SetWindowLogPtr() 함수를 통해서 타겟 윈도우의 Window
procedure 를 가로채는 (?) 기법
• Proxy dll or Trojan dll
– Kernel32.dll 의 export function 을 동일하게 구현한 dll 을 타겟
프로세스에 침투 시키는 방법 -_-
• Spying by a debugger
– 디버깅 api 를 통해서 , 혹은 디버거를 통해서 타겟 프로세스에
dll 을 침투
Interception mechanisms - 3
• IAT hooking
Hook_Func01
Hook_Func01
Hook_Func01
Hook.dll
Interception mechanisms - 3
• IAT hooking - 예제
단점 및 한계 ?
Interception mechanisms - 4
• EAT hook
– 타겟 프로세스가 Import 한 DLL 들은 이미 타겟 프로세스 주소
공간에 매핑되어있는 상태
– 따라서 로드된 dll 들의 EAT 를 분석해서 주입된 hook.dll 의 주
소공간으로 바꿔치기 하면 됨
IAT 훅의 단점을 극복할 수 있다 . !!
Interception mechanisms - 5
• Inline hook
– 함수 내부의 코드를 patch 해서 특정 주소의 인스트럭션을 수행
하도록 flow 를 변경하는 기법
– IAT hook, EAT hook 의 모든 단점을 극복할 수 있는 기술
– 난이도가 높음
Interception mechanisms - 6
• Jump templates
– 한 부분만 수정해서 모든 콜에 대한 변조가 가능
– Inline hook 을 통해 구현하면 더욱 효과적 (more stealthy !)
Api_1()
Api_2()
Api_3()
.....
.
Api_x()
IDT vector
IDT vector
0x2E handler
IDT vector
IDT vector
IDT vector
Ntoskrnl 의 인터럽트 핸들러
Hook driver code

More Related Content

What's hot

Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해Nam Hyeonuk
 
Assembly 스터디 2
Assembly 스터디 2Assembly 스터디 2
Assembly 스터디 2Jinkyoung Kim
 
Linux reversing study_basic_4
Linux reversing study_basic_4Linux reversing study_basic_4
Linux reversing study_basic_4Jinkyoung Kim
 
Pwnable study basic_3
Pwnable study basic_3Pwnable study basic_3
Pwnable study basic_3Jinkyoung Kim
 
[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스종빈 오
 
Windows reversing study_basic_8
Windows reversing study_basic_8Windows reversing study_basic_8
Windows reversing study_basic_8Jinkyoung Kim
 
Pwnable study basic_2
Pwnable study basic_2Pwnable study basic_2
Pwnable study basic_2Jinkyoung Kim
 
사내스터디 발표 온라인게임서버이해 20100401
사내스터디 발표 온라인게임서버이해 20100401사내스터디 발표 온라인게임서버이해 20100401
사내스터디 발표 온라인게임서버이해 20100401guest91f89d83
 
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기흥배 최
 
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은jieun kim
 
Windows reversing study_basic_7
Windows reversing study_basic_7Windows reversing study_basic_7
Windows reversing study_basic_7Jinkyoung Kim
 
windows via c++ Ch 5. Job
windows via c++ Ch 5. Jobwindows via c++ Ch 5. Job
windows via c++ Ch 5. JobHyosung Jeon
 
Assembly 스터디 1
Assembly 스터디 1Assembly 스터디 1
Assembly 스터디 1Jinkyoung Kim
 
Windows reversing study_basic_2
Windows reversing study_basic_2Windows reversing study_basic_2
Windows reversing study_basic_2Jinkyoung Kim
 
Linux reversing study_basic_3
Linux reversing study_basic_3Linux reversing study_basic_3
Linux reversing study_basic_3Jinkyoung Kim
 
Google Protocol buffer
Google Protocol bufferGoogle Protocol buffer
Google Protocol bufferknight1128
 
Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표Kwen Won Lee
 
[D2 CAMPUS] 안드로이드 오픈소스 스터디자료 - OkHttp
[D2 CAMPUS] 안드로이드 오픈소스 스터디자료 - OkHttp[D2 CAMPUS] 안드로이드 오픈소스 스터디자료 - OkHttp
[D2 CAMPUS] 안드로이드 오픈소스 스터디자료 - OkHttpNAVER D2
 
Web hacking introduction
Web hacking introductionWeb hacking introduction
Web hacking introductionJinkyoung Kim
 

What's hot (20)

Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해
 
Assembly 스터디 2
Assembly 스터디 2Assembly 스터디 2
Assembly 스터디 2
 
Linux reversing study_basic_4
Linux reversing study_basic_4Linux reversing study_basic_4
Linux reversing study_basic_4
 
Pwnable study basic_3
Pwnable study basic_3Pwnable study basic_3
Pwnable study basic_3
 
[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스
 
Windows reversing study_basic_8
Windows reversing study_basic_8Windows reversing study_basic_8
Windows reversing study_basic_8
 
Pwnable study basic_2
Pwnable study basic_2Pwnable study basic_2
Pwnable study basic_2
 
사내스터디 발표 온라인게임서버이해 20100401
사내스터디 발표 온라인게임서버이해 20100401사내스터디 발표 온라인게임서버이해 20100401
사내스터디 발표 온라인게임서버이해 20100401
 
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
 
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
 
Windows reversing study_basic_7
Windows reversing study_basic_7Windows reversing study_basic_7
Windows reversing study_basic_7
 
windows via c++ Ch 5. Job
windows via c++ Ch 5. Jobwindows via c++ Ch 5. Job
windows via c++ Ch 5. Job
 
Assembly 스터디 1
Assembly 스터디 1Assembly 스터디 1
Assembly 스터디 1
 
Windows reversing study_basic_2
Windows reversing study_basic_2Windows reversing study_basic_2
Windows reversing study_basic_2
 
Linux reversing study_basic_3
Linux reversing study_basic_3Linux reversing study_basic_3
Linux reversing study_basic_3
 
System+os study 7
System+os study 7System+os study 7
System+os study 7
 
Google Protocol buffer
Google Protocol bufferGoogle Protocol buffer
Google Protocol buffer
 
Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표Overlapped IO와 IOCP 조사 발표
Overlapped IO와 IOCP 조사 발표
 
[D2 CAMPUS] 안드로이드 오픈소스 스터디자료 - OkHttp
[D2 CAMPUS] 안드로이드 오픈소스 스터디자료 - OkHttp[D2 CAMPUS] 안드로이드 오픈소스 스터디자료 - OkHttp
[D2 CAMPUS] 안드로이드 오픈소스 스터디자료 - OkHttp
 
Web hacking introduction
Web hacking introductionWeb hacking introduction
Web hacking introduction
 

Similar to 2006 03 15_pe & api hook

2. windows system과 file format
2. windows system과 file format2. windows system과 file format
2. windows system과 file formatYoungjun Chang
 
Windows reversing study_basic_3
Windows reversing study_basic_3Windows reversing study_basic_3
Windows reversing study_basic_3Jinkyoung Kim
 
20170623 최신OS와 멀티플랫폼 개발 전략 with RAD Studio
20170623 최신OS와 멀티플랫폼 개발 전략 with RAD Studio20170623 최신OS와 멀티플랫폼 개발 전략 with RAD Studio
20170623 최신OS와 멀티플랫폼 개발 전략 with RAD StudioDevgear
 
하둡 타입과 포맷
하둡 타입과 포맷하둡 타입과 포맷
하둡 타입과 포맷진호 박
 
나만의 엔진 개발하기
나만의 엔진 개발하기나만의 엔진 개발하기
나만의 엔진 개발하기YEONG-CHEON YOU
 
20201121 코드 삼분지계
20201121 코드 삼분지계20201121 코드 삼분지계
20201121 코드 삼분지계Chiwon Song
 
Big data analysis with R and Apache Tajo (in Korean)
Big data analysis with R and Apache Tajo (in Korean)Big data analysis with R and Apache Tajo (in Korean)
Big data analysis with R and Apache Tajo (in Korean)Gruter
 
스레드
스레드스레드
스레드xxbdxx
 
C#을 사용한 빠른 툴 개발
C#을 사용한 빠른 툴 개발C#을 사용한 빠른 툴 개발
C#을 사용한 빠른 툴 개발흥배 최
 
Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본ssuser0c2478
 
[232] 성능어디까지쥐어짜봤니 송태웅
[232] 성능어디까지쥐어짜봤니 송태웅[232] 성능어디까지쥐어짜봤니 송태웅
[232] 성능어디까지쥐어짜봤니 송태웅NAVER D2
 
[Step UP! 마이그레이션] RAD 업그레이드 마이그레이션_점검과 수행
[Step UP! 마이그레이션] RAD 업그레이드 마이그레이션_점검과 수행[Step UP! 마이그레이션] RAD 업그레이드 마이그레이션_점검과 수행
[Step UP! 마이그레이션] RAD 업그레이드 마이그레이션_점검과 수행Devgear
 
윈도우 커널 익스플로잇
윈도우 커널 익스플로잇윈도우 커널 익스플로잇
윈도우 커널 익스플로잇Seungyong Lee
 
Windows via c++ chapter6
Windows via c++   chapter6Windows via c++   chapter6
Windows via c++ chapter6Shin heemin
 
Java Class File Format
Java Class File FormatJava Class File Format
Java Class File FormatJongyoung Park
 
리눅스 커널 기초 태스크관리
리눅스 커널 기초 태스크관리리눅스 커널 기초 태스크관리
리눅스 커널 기초 태스크관리Seungyong Lee
 

Similar to 2006 03 15_pe & api hook (20)

Pe+file+format
Pe+file+formatPe+file+format
Pe+file+format
 
2. windows system과 file format
2. windows system과 file format2. windows system과 file format
2. windows system과 file format
 
Windows reversing study_basic_3
Windows reversing study_basic_3Windows reversing study_basic_3
Windows reversing study_basic_3
 
04 프로세스
04 프로세스04 프로세스
04 프로세스
 
20170623 최신OS와 멀티플랫폼 개발 전략 with RAD Studio
20170623 최신OS와 멀티플랫폼 개발 전략 with RAD Studio20170623 최신OS와 멀티플랫폼 개발 전략 with RAD Studio
20170623 최신OS와 멀티플랫폼 개발 전략 with RAD Studio
 
하둡 타입과 포맷
하둡 타입과 포맷하둡 타입과 포맷
하둡 타입과 포맷
 
나만의 엔진 개발하기
나만의 엔진 개발하기나만의 엔진 개발하기
나만의 엔진 개발하기
 
20201121 코드 삼분지계
20201121 코드 삼분지계20201121 코드 삼분지계
20201121 코드 삼분지계
 
ice_grad
ice_gradice_grad
ice_grad
 
Big data analysis with R and Apache Tajo (in Korean)
Big data analysis with R and Apache Tajo (in Korean)Big data analysis with R and Apache Tajo (in Korean)
Big data analysis with R and Apache Tajo (in Korean)
 
스레드
스레드스레드
스레드
 
C#을 사용한 빠른 툴 개발
C#을 사용한 빠른 툴 개발C#을 사용한 빠른 툴 개발
C#을 사용한 빠른 툴 개발
 
Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본
 
[232] 성능어디까지쥐어짜봤니 송태웅
[232] 성능어디까지쥐어짜봤니 송태웅[232] 성능어디까지쥐어짜봤니 송태웅
[232] 성능어디까지쥐어짜봤니 송태웅
 
[Step UP! 마이그레이션] RAD 업그레이드 마이그레이션_점검과 수행
[Step UP! 마이그레이션] RAD 업그레이드 마이그레이션_점검과 수행[Step UP! 마이그레이션] RAD 업그레이드 마이그레이션_점검과 수행
[Step UP! 마이그레이션] RAD 업그레이드 마이그레이션_점검과 수행
 
윈도우 커널 익스플로잇
윈도우 커널 익스플로잇윈도우 커널 익스플로잇
윈도우 커널 익스플로잇
 
Windows via c++ chapter6
Windows via c++   chapter6Windows via c++   chapter6
Windows via c++ chapter6
 
Java Class File Format
Java Class File FormatJava Class File Format
Java Class File Format
 
Spark sql
Spark sqlSpark sql
Spark sql
 
리눅스 커널 기초 태스크관리
리눅스 커널 기초 태스크관리리눅스 커널 기초 태스크관리
리눅스 커널 기초 태스크관리
 

2006 03 15_pe & api hook

  • 1. Portable Executable (PE) 의 구조PE 의 구조 by somma (fixbrain@gmail.com)
  • 2. PE – Portable Executable • Portable Executable – 16 bit VxD 를 제외한 win32 실행 파일 규격 – Exe, dll, ocx, sys 등 – windows 표준 규격이므로 머신 (CPU) 에 상관없이 windows 운 영체제 하에서 모두 실행 가능한 실행 파일 포맷
  • 3. RVA • RVA – Relative Virtual Address PE (Exe, dll) RVA 매핑된 PE 이미지 가상 메모리 공간 가상 주소 0x00000000 RVA 로딩 시작 주소 (ImageBase) RVA 가상 메모리상에서의 실제 번지 ( 가상 주소 ) = ImageBase + RVA
  • 4. Section • Section ? 실행 코드 , 리소스 데이터 , 읽기 전용 데이터 등 비슷한 용도의 데이터들을 페이지 단위로 매핑하기 위한 공간 코드 영역 .text 실행코드를 담는 섹션 데이터 영역 .data, .rdata, .bss 전역 데이터 , 문자열 , VMT 등의 영역 리소스 영역 .rsrc 리소스 , 아이콘 등의 영역 IAT .idata, .didat 임포트 데이터 EAT .edata 익스포트 데이터 기준 재 배치 .reloc 기준 재 배치 영역
  • 5. DOS 헤더 PE 헤더 섹션 테이블 .text .data .rsrc .reloc File offset DOS 헤더 PE 헤더 섹션 테이블 .text .data .rsrc .reloc 0x00400000 메모리 증가 방향 메모리 매핑 PE 의 로딩 방식 • Memory mapped file – 디스크에 존재하는 파일을 직접 가상메모리 공간에 매핑 – Windows 의 IPC ( 파이프 , 메일 슬롯 , RPC, WM_COPYDATA 등 ) 구현의 근간이 되는 개념 – Pagefile.sys ?
  • 6. 가상 주소 공간 • 가상 주소 – Virtual Address 프로세스는 몽땅 사용할 수 있는 4GB 의 메모리를 제공받는다 .
  • 9. IMAGE_NT_HEADERS • Signature – ‘PE00’ 문자열 • IMAGE_FILE_HEADER • IMAGE_OPTIONAL_HEADER
  • 10. IMAGE_FILE_HEADER • WORD NumberOfSections; IMAGE_SECTION_HEADER 의 개수 • WORD SizeOfOptionalHeader; IMAGE_FILE_HEADER 다음에 오는 IMAGE_OPTIONAL_HEADER 구조체의 바이 트수 , OBJ 인 경우 0, 실행파일인 경우 sizeof(IMAGE_OPTIONAL_HEADER) 임 . 32 비트 PE 인 경우 0xE0 (224), 64 비트 PE 의 경우 0xF0 (240)
  • 11. IMAGE_OPTIONAL_HEADER typedef struct _IMAGE_OPTIONAL_HEADER { // // Standard fields. // WORD Magic; DWORD AddressOfEntryPoint; // 프로그램 엔트리 포인트 // WinMainCRTStartup or minaCRTStartup or // DllMainCRTStartup // // NT additional fields. // DWORD ImageBase; // PE 가 가상 주소 공간에 매핑될 메모리상의 시작 // 주소 , 디폴트로 0x00400000 (exe), // 0x10000000(dll) DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; DWORD NumberOfRvaAndSizes; // 바로 다음 필드인 DataDirectory[] 배열의 // 갯수 . 항상 16 이다 (0x00000010) // 아래의 Direcotry Entries 박스 IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
  • 12. IMAGE_OPTIONAL_HEADER32.DataDirectory • IMAGE_OPTIONAL_HEADER.DataDirectory[] – 각 섹션들의 가상 주소를 위한 RVA 와 섹션의 크기정보 저장 – 각 인덱스는 미리 정해져 있다 .
  • 13. IMAGE_SECTION_HEADER • IMAGE_NT_HEADERS 구조체 다음에 오늘 구조체 배열 • 이 구조체 배열의 개수는 IMAGE_FILE_HEADER.NumberOfSections 값 • PE 를 구성하는 각 섹션들의 정보를 보관하고 있음
  • 14. Export section (.edata) • Dll 처럼 특정 함수포인터 , symbol 등을 외부로 노출하는 경우 생성 됨 • IMAGE_OPTIONAL_HEADER.IMAGE_DATA_DIRECTORY[IMAGE _DIRECTORY_ENTRY_EXPORT] 구조체가 가리키는 곳이 export 섹션이다 . • IMAGE_OPTIONAL_HEADER.IMAGE_DATA_DIRECTORY [IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress 값이 .edata 섹션의 RVA 값이 됨 • .edata 섹션은 IMAGE_EXPORT_DIRECTORY 구조체로 이루어져 있음
  • 15. IMAGE_EXPORT_DIRECTORY • Name – DLL 의 이름 문자열 • Base – Export 된 함수들의 서수의 시작 번호 ( 임의의 숫자로 시작 가능 ) – 정확한 서수의 값을 계산하려면 AddressOfNameOrdinal 필드의 값에 Base 필드 값을 더해 주어야 함 • NumberOfFunctions – AddressOfFunctions 필드가 가리키는 RVA 배열의 개수 – 서수의 끝 번호 – 시작 번호 + 1 의 값 – 불연속적인 서수를 사용하는 경우 NumberOfNames 와 다름 • NumberOfNames – AddressOfNames 필드가 가리키는 RVA 배열의 개수 – 실제 export 된 함수의 정확한 개수를 나타내는 값임 • AddressOfFunctions – Export 된 함수들의 함수 포인터를 가진 배열의 RVA • AddressOfNames – Export 된 함수들의 심볼을 가리키는 문자열 배열의 RVA • AddressOfNameOrdinals – WORD 타입의 배열에 대한 포인터 RVA – WORD 타입 배열의 각 원소는 ordinal 값을 저장하고 있다 .
  • 18. Import section (.idata) • Import 섹션은 해당 PE 가 로드한 외부 모듈 / 함수에 대 한 정보를 보관하는 섹션이다 . • IMAGE_OPTIONAL_HEADER.IMAGE_DATA_DIRECTORY[IMAGE _DIRECTORY_ENTRY_IMPORT] 구조체가 가리키는 곳이 import 섹션이다 . • IMAGE_OPTIONAL_HEADER.IMAGE_DATA_DIRECTORY [IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress 값이 .idata 섹션의 RVA 값이 됨 • .edata 섹션은 IMAGE_IMPORT_DESCRIPTOR 구조체로 이루어져 있음
  • 19. IMAGE_IMPORT_DESCRIPTOR • OriginalFirstThunk – IMAGE_THUNK_DATA 구조체 배열의 RVA – 각 배열의 원소는 IMAGE_IMPORT_BY_NAME 구조체 의 RVA • Name – 임포트한 dll 의 이름 문자열 • FirstThunk ( 아주 중요 !) – PE 가 디스크에 존재할 때는 OriginalFirstThunk 와 동일한 값 – 가상메모리상에서는 IAT 포인터 , 즉 실제 임포트한 함수의 주소 ( 바인딩 되었다고 표현 )
  • 20. IMAGE_THUNK_DATA • 4 바이트 유니온 • ForwarderString – 임포트한 함수가 포워딩 된 경우 ‘ dll.RtlGetWin32LastError’ 형태 의 문자열 RVA • Ordinal – 서수로 임포트 된 경우 해당 함수의 서수값 • AddressOfData – 이름으로 임포트 된 경우 해당 함수의 함수 포인터 • Name or Ordinal? – IMAGE_IMPORT_DESCRIPTOR.OrginalFirstThunk 의 최상위 비트가 설정된 경우 Ordinal 로 임포트 한 것임
  • 21. IAT 바인딩 과정 - 1 • Disk 에 존재할 때의 Import section 구조
  • 22. IAT 바인딩 과정 - 2 • 가상 주소 공간에 매핑된 후의 Import section
  • 23. 볼랜드 계열 링커가 생성한 PE 의 IAT 분석 • 볼랜드 계열 링커가 생성한 PE 는 OrginalFirstThunk 필 드가 항상 0 이다 . • 따라서 가상 메모리 상에서 임포트 한 DLL 및 함수의 서 수 혹은 이름을 역으로 분석해 낼 수 없다 . • ImportREC 같은 툴로 IAT 복원이 안 된다 . !!
  • 24. Portable Executable (PE) 의 구조API hooking 101 by somma (fixbrain@gmail.com)
  • 25. Injecting Technique -1 • Registry 를 이용한 dll 침투 기법 키에 dll 이름을 등록하면 user32.dll 이 로드되면서 이 DLL 들도 함께 로드한 다 . • 단점 USER32.dll 을 사용하는 어플리케이션만 해당됨 ( 콘솔 APP 는 해당 안됨 ) NT, Win2K 만 해당됨 리부팅 필요 HKEY_LOCAL_MACHINESoftwareMicrosoftwindowsNTCurrentersionWindowsAppInit_DLLs
  • 26. Injecting Technique -2 • SYSTEM-WIDE Windows Hook – SetWindowsEx() 함수를 통해서 윈도우 메시지 핸들러를 통해 DLL 을 대상 프로세스 컨텍스트로 침투 시키는 방법 - 이 경우 침투된 dll 들은 서로 다른 프로세스 공간에 존재하므로 데이터 공유를 위해 IPC 메커니즘을 구현함 - 이 방법은 UnHookWindowsEx() 을 통해 dll 을 언로드 - Windows 9x 부터 최신의 windows 까지 모두 사용 가능 - 모든 프로세스의 windows message 를 처리하므로 부하를 가중 시킬 수 있음
  • 27. STEP 1. 침투하고자 하는 프로세스의 핸들을 얻는다 . STEP 2. kernel32.dll 의 LoarLibrary() 함수의 포인터를 얻는다 . STEP 3. CreateRemoteThread() 를 통해서 타겟 프로세스에 스레드를 생성 한다 . 이때 lpParameter 는 “ hook.dll” 문자열의 포인터가 넘어갈 것이다 . STEP 4. 타겟 프로세스는 LoadLibrary(“hook.dll”) 을 호출하는 것과 동일한 결과를 만든다 . STEP 5. hook.dll 의 Dll entry 는 타겟 프로세스의 컨텍스트 내에서 필요한 작업을 수행할 수 있다 . Injecting Technique -3 • Injecting DLL by using CreateRemoteThread() API – Win9x 계열에서는 사용할 수 없음 – 타겟 프로세스 공간에 스레드를 생성하는 API 생성된 스레드가 실행할 함수 포인터 LoadLibrary () 함수와 동일한 원형을 가진다 !!
  • 28. Interception mechanisms - 1 • 커널 레벨 후킹 – SSDT hook – IDT hook – IRP handler hook – Sysenter hook
  • 29. Interception mechanisms - 2 • Window 서브 클래싱 – SetWindowLogPtr() 함수를 통해서 타겟 윈도우의 Window procedure 를 가로채는 (?) 기법 • Proxy dll or Trojan dll – Kernel32.dll 의 export function 을 동일하게 구현한 dll 을 타겟 프로세스에 침투 시키는 방법 -_- • Spying by a debugger – 디버깅 api 를 통해서 , 혹은 디버거를 통해서 타겟 프로세스에 dll 을 침투
  • 30. Interception mechanisms - 3 • IAT hooking Hook_Func01 Hook_Func01 Hook_Func01 Hook.dll
  • 31. Interception mechanisms - 3 • IAT hooking - 예제 단점 및 한계 ?
  • 32. Interception mechanisms - 4 • EAT hook – 타겟 프로세스가 Import 한 DLL 들은 이미 타겟 프로세스 주소 공간에 매핑되어있는 상태 – 따라서 로드된 dll 들의 EAT 를 분석해서 주입된 hook.dll 의 주 소공간으로 바꿔치기 하면 됨 IAT 훅의 단점을 극복할 수 있다 . !!
  • 33. Interception mechanisms - 5 • Inline hook – 함수 내부의 코드를 patch 해서 특정 주소의 인스트럭션을 수행 하도록 flow 를 변경하는 기법 – IAT hook, EAT hook 의 모든 단점을 극복할 수 있는 기술 – 난이도가 높음
  • 34. Interception mechanisms - 6 • Jump templates – 한 부분만 수정해서 모든 콜에 대한 변조가 가능 – Inline hook 을 통해 구현하면 더욱 효과적 (more stealthy !) Api_1() Api_2() Api_3() ..... . Api_x() IDT vector IDT vector 0x2E handler IDT vector IDT vector IDT vector Ntoskrnl 의 인터럽트 핸들러 Hook driver code