▣ 실행 포맷

윈도우 실행파일 포맷인 PE(Portable Executable)의 기본적인 구조 이해

    기본 개념

-       실행파인은 재배치 될 수 있음(로드될 때마다 다른 가상 메모리 주소에 로드될 수 있음)

-       OS는 각 프로세서마다 고유한 주소 공간을 제공하지만 주소 공간에는 여러 개의 실행 바이너리들이 로드됨

-       프로그램은 자신의 주소 공간에 실행파일뿐만 아니라 DLL과 같은 추가적인 실행 모듈들을 로드함

-       기존에 사용하고 있는 주소에 다른 프로그램이 해당 주소를 사용하려고 하는 경우 다른 주소에 로딩해야 되는데 이때 재배치 작업을 수행함

 

MOV    EAX,   DWORD  PTR [pGlobalVariable]

위 코드는 전역변수에 접근하는 전형적인 코드

컴파일러와 링커가 pGlobalVariable에 대한 주소로 어떤 값을 사용해야 하는가?

→일반적으로 파일의 시작 지점으로부터의 상대주소를 생각할 수 있다. 이 주소를 사용할 경우 어느 주소로 로드되는지 걱정할 필요가 없다. 그러나위의 코드는 프로세서가 직접 실행하는 코드이다. 따라서 로더는 코드상의 모든 주소를 정확한 위치를 가리키는 절대주소로 변환한다.

 

# 재배치가 중요한 이유

-       실행모듈헤더에서는 절대주소가 사용되지 않고 코드에서만 절대주소가 사용되기 때문

-       실행 모듈 헤더에서는 항상 상대가상주소(RVA, Relative Virtual Address : 단순 offset)를 상요함

-       실행 모듈이 로드되고 가상주소를 할당받을 때 로더는 실제 가상주소를 계산함

(모듈의 Based Address + RVA = 실제 가상주소)

 

    이미지 섹션

-       실행이미지는 여러가지 섹션으로 나누어 짐

-       코드(text)섹션 : 실행모듈의 코드 포함

-       데이터섹션 : 데이터 포함

-       실행 모듈 로딩 시 메모리 관리자는 섹션 헤더의 설정 내용에 따라 각 섹션에 해당하는 메모리 페이지에 대한 접근 권한 설정함

Char   szMessage[] = “Welcome to my program!”;

위의 코드에서 컴파일러는 실행 이미지의 어딘가에 정의된 문자열을 저장해야 함

위의 문자열은 초기화된 데이터이며 따라서 해당 문자열과 그것을 가리키는 변수는 초기화된 데이터 섹션에 저당됨

 

 

    섹션 정렬

-       메모리에 로드되는 섹션의 크기는 일반적으로 페이지 크기의 배수

-       반대로 실행 이미지를 페이지 크기 단뒤로 디스크에 저장하면 실제 필요한 용량보다 훨씬 큰 용량을 차지함(디스크 낭비)

 

→ 위의 이유로 인해 PE헤더는 섹션정렬을 위한 두개의 필드가 존재함

섹션정렬 필드 : 실행 이미지를 메모리에 로드할 때 사용

파일정렬 필드 : 파일을 디스크에 저장할 때 사용

 

    동적 링크 라이브러리(DLL)

-       동적 링크 라이브러리의 개념

프로그램은 하나 이상의 실행 파일로 분리될 수 있고, 각 실행 파일은 프로그램 기능의 일부분이나 일부 기능을 수행하는 것

           장점 : 필요한 기능을 제공하는 실행 모듈만 로드해서 사용함(메모리 낭비를 줄임)

                  프로그램의 기능 변경시 해당 모듈만 변경하거나 추가하면 됨

    정적 라이브러리(.lib)

-       실행 모듈에 영구히 링크됨

-       프로그램이 빌드될 때 .lib파일안의 코드를 원래 소스코드의 일부분인 것처럼 실행 모듈에 정적으로 링크시킴

-       실행 모듈이 로드될 때 OS는 로드된 실행 모듈안에 정적라이브러리가 있다는 것을 알지 못함. 이는 같은 정정적라이브러리가 포함된 A, B프로그램이 있다면 정정라이브러리가 중복되서 로드될 것임(메모리 낭비가 발생할 수 있음)

 

    윈도우 프로그램 실행 시 DLL로드 방법

(1)   정적링크

-       실행 이미지의 임포트 테이블 안에 다른 실행모듈에 대한 정보를 포함시키는 과정

-       실행 이미지가 사용하는 모듈들도 같이 로드함

-       해당 모듈들에 대한 모든 외부 레퍼런스 정보를 올바르게 맞춤

 

(2)   동적링크

-       실행 이미지가 런타임 시에 다른 실행 모듈에 대한 로드여부를 판단함

-       런타임 시에 모듈을 직접 로드하고 로드한 모듈 이미지의 헤더를 검색해서 호출하고자 하는 함수를 찾아야만 함

  리버싱 관점에서 볼 때 정적 링크 방법은 어떤 모듈의 어떤 함수를 사용하는지 전부 할 수 있으므로 좀더 다루기 쉽다


    헤더(Header)

-       PE파일은 DOS헤더로 시작함

-       하위 호환을 위한 부분으로 DOS시스템에서 PE파일이 실행될 때 에러처리를 하기 위함

(ex: “This program connot be run in DOS mode”라는 메시지가 나타나는 경우가 있는데, DOS상에서 PE실행 이미지를 실행 시킬 수 없다는 의미 → 이 메시지를 출력하기 위해서 PE실행 이미지에는 작은 16bit DOS 프로그램을 포함)

-       헤더 안의 모든 포인터는 절대주소가 아닌 RAV값임

-       유용한 정보들은 PE헤더 안의 추가적인 데이터 구조체 배열인 DataDirectory 구조체 안에 포함됨

 

(1)   DOS 헤더

-       e_lfanew : 실제 PE 헤더를 가리키는 포인터

 

(2)   PE헤더

-       DOS헤더가 확장된 것임

 

    임포트와 익스포트

-       실행 이미지의 동적링크를 가능하게 해주는 메커니즘

-       컴파일러와 링커는 임포트하는 함수의 실제 주소를 알지 못함 → 실행 시에만 알 수 있음

(임포트 테이블 : 실행 이미지가 사용하는 각 모듈목록과 그 모듈에서 사용하는 함수 목록의 정보가 저장되어 있음)

-       모듈이 모드될 때 로더는 임포트 테이블에 명시된 모든 모듈을 로드 함

-       로드한 각 모듈의 함수 목록에 있는 함수들의 주소를 산출

-       함수 주소는 임포트한 모듈의 익스포트 테이블을 통해 산출

(익스포트 테이블 : 해당 모듈이 익스포트하는 모든 함수의 이름과 RVA를 가지고 있음)

 

    디렉토리

-       데이터 구조체

이름

설명

관련 구조체

export table

모듈의 모든 익스포트 함수 이름과 RVA를 포함

IMAGE_EXPORT_DIRECTORY

import table

·임포트하는 모듈과 함수 이름을 포함함

·함수별로 함수 이름 문자열(또는 서수)과 함수의 임포트 어드레스 테이블 엔트리를 가리키는 RVA를 포함

·모듈이 로드될 때 임포트한 함수의 실제 주소를 전달받는 시작점이 됨

IMAGE_IMPORT_DESCRIPTOR

resource table

·실행 모듈의 리소스 디렉토리 포인터

·리소스 디렉토리는 문자열, 대화상자 레이아웃, 메뉴와 같은 다양한 사용자 인터페이스 요소와 정적인 요소를 정의함

IMAGE_RESOURCE_DIRECTORY

Base Relocation table

모듈이 빌드되면서 설정된 로드 주소가 아닌 다른 주소로 로드되어야 할 때 재배치되어야 하는 주소들의 목록

IMAGE_BASE_RELOCATION

Debugging Information

·실행 모듈을 위한 디버깅 정보

·일반적으로 실질적인 디버깅 정보를 담고 있는 외부 심볼 파일에 대한 링크 정보를 제공함

IMAGE_DEBUG_DIRECTORY

Thread Local Storage table

·쓰레드 로컬 변수를 포함할 수 있는 실행 모듈의 쓰레드 로컬 섹션에 대한 포인터

·이 기능은 로더가 실행 모듈을 로드할 때 사용함

IMAGE_TLS_DIRECTORY

Load Configuration table

·LOCK prefix테이블(단일 프로세서 시스템이나 멀티 프로세스 시스템에 맞게 실행 모듈이 로드될 때 실행 모듈 이미지를 변경 가능)과 같은 다양한 이미지 설정 요소를 포함

·모듈의 예외 핸들러 목록 포함(악의적인 코드가 예외 핸들러를 설치하는 것을 방지하기 위함)

IMAGE_LOAD_CONFIG_DIRECTORY

Bound Import table

·바운드 임포트 엔트리 정보를 담고 있는 추가적인 임포트 테이블

·임포트한 실행 모듈의 실제 주소가 포함되어 있다는 것을 의미함(그 주소가 여전이 유효한지 확인하기 위함)

IMAGE_BOUND_IMPORT_DESCIPTOR

Import Address table(IAT)

·임포트된 각 함수의 목록을 포함

·실행 모듈이 로드될 때 각 임포트 함수의 엔트리가 해당 함수에 대한 실제 주소로 초기화 됨

32bit 포인터 목록

Delay Import Descriptor

·임포트한 함수를 처음 호출할 때 해당 함수의 실제 주소가 매핑되는 지연 임포트 로딩 메커니즘을 구현하기 위해 사용됨

·이 메커니즘은 OS가 제공하는 것이 아니라 C런타임 라이브러리에 의해서 구현됨

ImgDelayDescr

 [ PE파일 포맷의 디렉토리]

 


+ Recent posts