반응형


PE File Format


지금까지 오랜 시간에 걸쳐 PE(Portable Executable) File Format 에 대해 살펴보았습니다.

PE 스펙을 보면 각 구조체 멤버 하나하나 자세히 기술하고 있지만
리버싱에서 주목해야 하는 멤버들만 추려서 설명드렸습니다.

특히 IAT, EAT 에 관한 내용은 실행압축(Run-Time Packer), Anti-Debugging, DLL Injection, API Hooking
매우 다양한 중/고급 리버싱 주제들의 기반 지식이 됩니다.

hex editor 와 연필, 종이만 가지고 IAT/EAT 의 주소를 하나하나 계산해서
파일/메모리 에서 실제 주소를 찾는 훈련을 많이 해보시기 바랍니다.

쉽지 않은 내용이지만 그만큼 리버싱에서 중요한 위치를 차지하고 있기 때문에
고급 리버싱을 원하는 분들께서는 반드시 습득하셔야 합니다.



PEView.exe


간단하고 사용하기 편리한 PE Viewer 프로그램(PEView.exe)을 소개해 드립니다.
(개인이 만든 무료 공개 SW 입니다.)

http://www.magma.ca/~wjr/PEview.zip

아래는 PEView.exe 의 실행 화면입니다.


PE Header 를 각 구조체 별로 보기 쉽게 표현해주고, RVA <-> File Offset 변환을 간단히 수행해줍니다.
(제가 설명드렸던 내용과 용어 사용에 있어서 약간 틀릴 수 있습니다. 둘 다 익혀두시는게 의사소통에 좋습니다.)

위와 같은 PE Viewer 를 직접 제작해 보시는 것을 추천드립니다.
저 또한 처음 PE Header 를 공부할 때 (검증을 위해) 콘솔 기반의 PE Viewer 를 만들어서 지금까지 잘 사용하고 있습니다.
직접 제작하다 보면 자신이 잘 몰랐거나 잘 못 이해하던 부분을 정확히 파악하고 제대로 공부할 수 있습니다.



PE Patch


PE 스펙은 말 그대로 권장 스펙이기 때문에 각 구조체 내부에 보면 사용되지 않는 많은 멤버들이 많이 있습니다.

또한 말 그대로 스펙만 맞추면 PE 파일이 되기 때문에 일반적인 상식을 벗어나는 PE 파일을 만들어 낼 수 있습니다.

PE Patch 란 바로 그런 PE 파일을 말합니다.
PE 스펙에 어긋나지는 않지만 굉장히 창의적인(?) PE Header 를 가진 파일들입니다.
(정확히 표현하면 PE Header 를 이리저리 꼬아 놨다고 할 수 있습니다.)

PE Patch 만 해도 따로 고급 주제로 다뤄야 할 만큼 (리버싱에 있어서) 넓고도 깊은 분야입니다.

한가지만 소개해 드리겠습니다.
지금까지 배웠던 PE Header 에 대한 상식이 사뿐히 깨지는 경험을 하실 수 있습니다.
(그러나 PE 스펙에 벗어난건 없답니다.)

아래 사이트는 tiny pe 라고 가장 작은 크기의 PE 파일을 만드는 내용입니다.

http://blogs.securiteam.com/index.php/archives/675

411 byte 크기의 (정상적인) PE 파일을 만들어 냈습니다.
IMAGE_NT_HEADERS 구조체 크기만 해도 248 byte 라는걸 생각하면 이것은 매우 작은 크기의 PE 파일입니다.

다른 사람들이 계속 도전해서 304 byte 크기의 파일까지 나타나게 됩니다.

그리고 마지막으로 어떤 다른 사람이 위 사이트를 본 후 자극을 받아서
아래와 같이 극단적이고 매우 황당한 PE 파일을 만들어 내었습니다.

http://www.phreedom.org/solar/code/tinype/

이곳에 가면 Windows XP 에서 정상 실행되는 97 byte 짜리 PE 파일을 다운 받을 수 있습니다.
(2009년 4월 현재까지 최고 기록입니다.)
또한 PE Header 와 tiny pe 제작과정에 대한 내용을 자세히 설명하고 있어서 읽어보시면 크게 도움이 되실 겁니다.
(약간의 assembly 언어에 대한 지식이 요구됩니다.)

모두 다운 받아서 하나씩 분석해 보시기 바랍니다. 분명 크게 도움이 됩니다.



Epilogue


이러한 PE patch 파일들은 저뿐만 아니라 일반적인 리버서들의 고정관념을 깨트리는 내용이며
그래서 리버싱 공부가 더 즐겁습니다.

PE Header 에 대해서 다시 한번 강조 하고 싶은 내용은 아래와 같습니다.

- PE 스펙은 그저 스펙일 뿐이다. (만들어 놓고 사용되지 않는 내용이 많다.)
- 내가 지금 알고 있는 PE Header 에 대한 지식도 잘 못된 부분이 있을 수 있다.
   (tiny pe 외에도 PE header 를 조작하는 여러 창의적인 기법들이 계속 쏟아져 나온다.)
- 항상 모르는 부분을 체크해서 보강하자.

앞으로 제 블로그에서 다양한 형태의 PE 파일들을 분석할 예정입니다.
재밌고 특이한 PE Header 조작 기법에 대해서는 그때 그때 소개해 드리도록 하겠습니다.




반응형
반응형


Introduction


Windows 운영체제의 PE(Portable Executable) File Format 에 대해서 아주 상세히 공부해 보도록 하겠습니다.

PE format 을 공부하면서 Windows 운영체제의 가장 핵심적인 부분인
Process, Memory, DLL 등에 대한 내용을 같이 정리할 수 있습니다.



PE(Portable Executable) File Format


PE 파일의 종류는 아래와 같습니다.

  • 실행 파일 계열 : EXE, SCR
  • 라이브러리 계열 : DLL, OCX
  • 드라이버 계열 : SYS
  • 오브젝트 파일 계열 : OBJ

엄밀히 얘기하면 OBJ(오브젝트) 파일을 제외한 모든 파일들은 실행 가능한 파일 입니다.

DLL, SYS 파일등은 쉘(Explorer.exe) 에서 직접 실행 할 수는 없지만,
다른 형태의 방법(디버거, 서비스, 기타)을 이용하여 실행이 가능한 파일들입니다.

* PE 공식 스펙 에는 컴파일 결과물인 OBJ(오브젝트) 파일도 PE 파일로 간주합니다.
  하지만 OBJ 파일 자체로는 어떠한 형태의 실행도 불가능하므로 리버싱에서 관심을 가질 필요는 없습니다.


간단한 설명을 위해서 노트패드(notepad.exe) 파일을 hex editor 를 이용해서 열어보겠습니다.


<Fig. 1>

<Fig. 1> 은 notepad.exe 파일의 시작 부분이며, PE 파일의 헤더 (PE header) 부분입니다.

바로 이 PE header 에 notepad.exe 파일이 실행되기 위해 필요한 모든 정보가 적혀있습니다.

어떻게 메모리에 적재되고, 어디서부터 실행되어야 하며, 실행에 필요한 DLL 들은 어떤것들이 있고,
필요한 stack/heap 메모리의 크기를 얼마로 할지 등등...


수 많은 정보들이 PE header 에 구조체 형식으로 저장되어 있습니다.

즉, PE File Format 을 공부한다는 것은 PE header 구조체를 공부한다는 것과 같은 말입니다.



Basic Structure


일반적인 PE 파일의 기본 구조입니다. (notepad.exe)


<Fig. 2>

<Fig. 2> 는 notepad.exe 파일이 메모리에 적재(loading 또는 mapping)될 때의 모습을 나타낸 그림입니다.
많은 내용을 함축하고 있는데요, 하나씩 살펴보겠습니다.


  • DOS header 부터 Section header 까지를 PE Header, 그 밑의 Section 들을 합쳐서 PE Body 라고 합니다.

  • 파일에서는 offset 으로, 메모리에서는 VA(Virtual Address) 로 위치를 표현합니다.

  • 파일이 메모리에 로딩되면 모양이 달라집니다. (Section 의 크기, 위치 등)

  • 파일의 내용은 보통 코드(".text" 섹션), 데이타(".data" 섹션), 리소스(".rsrc") 섹션에 나뉘어서 저장됩니다.
    반드시 그런것은 아니며 개발도구(VB/VC++/Delphi/etc)와 빌드 옵션에 따라서
    섹션의 이름, 크기, 개수, 저장내용 등은 틀려집니다. 중요한 것은 섹션이 나뉘어서 저장 된다는 것입니다.

  • Section Header 에 각 Section 에 대한 파일/메모리에서의 크기, 위치, 속성 등이 정의 되어 있습니다.

  • PE Header 의 끝부분과 각 Section 들의 끝에는 NULL padding 이라고 불리우는 영역이 존재합니다.
    컴퓨터에서 파일, 메모리, 네트워크 패킷 등을 처리할 때 효율을 높이기 위해 최소 기본 단위 개념을 사용하는데,
    PE 파일에도 같은 개념이 적용된 것입니다.

  • 파일/메모리에서 섹션의 시작위치는 각 파일/메모리의 최소 기본 단위의 배수에 해당하는 위치여야 하고,
    빈 공간은 NULL 로 채워버립니다. (<Fig. 2> 를 보면 각 섹션의 시작이 이쁘게 딱딱 끊어지는 걸 볼 수 있습니다.)



VA & RVA



VA (Virtual Address) 는 프로세스 가상 메모리의 절대 주소를 말하며,
RVA (Relative Virtual Address) 는 어느 기준위치(ImageBase) 에서부터의 상대 주소를 말합니다.

VA 와 RVA 의 관계는 아래 식과 같습니다.

RVA + ImageBase = VA

PE header 내의 많은 정보는 RVA 형태로 된 것들이 많습니다.
그 이유는 PE 파일(주로 DLL)이 프로세스 가상 메모리의 특정 위치에 로딩되는 순간
이미 그 위치에 다른 PE 파일(DLL) 이 로딩 되어 있을 수 있습니다.

그럴때는 재배치(Relocation) 과정을 통해서 비어 있는 다른 위치에 로딩되어야 하는데,
만약 PE header 정보들이 VA (Virtual Address - 절대주소) 로 되어 있다면 정상적인 엑세스가 이루어지지 않을것입니다.

정보들이 RVA (Relative Virtual Address - 상대주소) 로 되어 있으면 Relocation 이 발생해도
기준위치에 대한 상대주소는 변하지 않기 때문에 아무런 문제없이 원하는 정보에 엑세스 할 수 있을 것입니다.




이어지는 강좌에서 PE Header 구조체를 하나씩 상세히 살펴보도록 하겠습니다.



(continue)



반응형

+ Recent posts