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)



    이전 댓글 더보기
  1. 장황제 2010.01.19 18:29 신고 댓글주소 | 수정 | 삭제 | 댓글

    좋은 자료와 설명잘해주신 강의로 열심히 공부하고 있습니다!!

    정말 감사합니다~ㅋㅋ

    질문 드릴께 있는데요.

    padding의 개념이 잘 이해가 않가네여;;

    • reversecore 2010.01.21 01:56 신고 댓글주소 | 수정 | 삭제

      장황제님, 안녕하세요.

      PE 파일의 padding 개념에 대해서 궁금하시군요.


      패딩은 '기본단위' 를 맞추기 위해서 추가하는 덤 이라고 보시면 됩니다.

      이러한 '기본단위' 개념은 컴퓨터 뿐만 아니라 일상 생활에서도 많이 볼 수 있습니다.
      가령 귤을 (많이) 보관할 때는 낱개로 보관하는것이 아니고 박스에 담아서 창고에 보관하지요. 그때 박스가 바로 '기본단위' 인 것입니다. 귤이 몇개라고 하지 않고 귤박스가 몇개라고 말을 합니다.

      왜냐구요? 편하니까요. 귤박스가 아주 많아지면 보관 창고를 더 늘려야 하고, 그때는 귤이 몇박스라고 하지 않고 귤이 창고 몇개에 보관되어 있다라고 할 수 있습니다.

      이러한 '기본단위' 개념은 컴퓨터 설계에도 그대로 녹아 있어서 메모리, 하드디스크 등에도 적용되어 있습니다. (하드디스크가 섹터단위로 구분된다고 들어보셨지요?)

      마찬가지로 PE File Format 의 '섹션'에도 '기본단위(크기)' 개념이 적용되어 있습니다.

      제가 프로그래밍한 코드가 (기계어로 컴파일되어) 크기가 100 byte 밖에 안된다고 하더라도, 만약 섹션의 기본단위가 400h(1000d) byte 라면 코드 섹션의 크기는 1000d 가 되는 것입니다.

      100 byte 코드가 채워지고 남은 900 byte 의 영역에는 그냥 0 으로 채워지게 되고, 이를 padding 이라고 하는 것입니다.

      메모리도 같은 개념이 적용됩니다. (보통 파일보다는 단위 크기가 좀 더 크지요.)

      PE 파일에서 padding 은 누가 어떻게 만들까요?
      네, 당연히 개발도구(VC++, VB, etc) 에서 PE 파일 생성시 자신의 옵션에 따라서 결정됩니다. ^^


      만약 잘 이해 안되시면 다시 질문해 주세요~

      감사합니다.

  2. 장황제 2010.01.21 21:48 신고 댓글주소 | 수정 | 삭제 | 댓글

    와..읽으면서..웃음이 나옵니다..ㅋㅋ

    이해가 퐉왔습니다~;;

    정말 개념만 보면 쉬운거였네요..ㅋㅋ

    이해하기 쉽게 알려주셔서 감사합니다~

    • ReverseCore 2010.01.21 22:47 신고 댓글주소 | 수정 | 삭제

      장황제님, 안녕하세요.

      이해가 잘 되셨다니 다행입니다.

      사실 저렇게 귤을 보관하면 검색(찾기)이 편리해 집니다.
      "몇번 창고 몇번 박스내의 몇번 귤" 하면 되니까요.

      즉, 대량의 데이타를 보관할 때 묶어서 보관하면 정리도 잘되고 검색도 쉬워지는 장점이 있지요.

      감사합니다.

  3. 장황제 2010.01.30 10:45 신고 댓글주소 | 수정 | 삭제 | 댓글

    이번에는 패딩사이즈질문좀 드릴께요..ㅠ

    파일에 패딩하고 메모리에 로드되었을때의 패딩 크기가 알고싶어서요.

    저는 만약 sectionalignment에서 ox00001000이면 4096바이트의 배수가 되는거고.

    filealignment가 ox00002000 이면 8192바이트의 배수가 된다고 생각을 했는데....

    제가 잘못생각하고 있는건가요??

    • reversecore 2010.01.31 23:19 신고 댓글주소 | 수정 | 삭제

      장황제님, 안녕하세요.

      패딩크기 말씀이시죠?

      실제 코드(데이타) 의 크기를 각 alignment 에 맞게 확장시켜 주기 때문에 그때 그때 달라집니다.

      그리고 각 섹션의 크기는 장황제님 말씀대로 입니다.

      보통 file alignment 는 0x200, 0x400, 0x1000 이 많이 쓰입니다.
      Section Alignment 는 0x1000 이 많이 쓰이구요.

      감사합니다.

  4. tanosi 2010.04.06 01:02 신고 댓글주소 | 수정 | 삭제 | 댓글

    머리속에 '파밧' 하고 개념이 잘 서는 포스팅을 보고 놀랐습니다.
    출간 준비중 이라고 하시니 기대됩니다~~
    최근 나온 리버스엔지니어링 역분석 구조와 원리 라는책을 보고 PE 에서 딱 막혔는데, 다시한번 달리게 되었습니다.
    많은 도움이 되고 있습니다~~

  5. 할라 2010.04.15 22:29 신고 댓글주소 | 수정 | 삭제 | 댓글

    리버싱 입문에 들어서는 할라라고 합니다^^;;
    요즘 리버싱이 재밌어지려고 하는 찰라에
    많은걸 학습해야 하는걸 깨닫고 관련된 자료를 찾아다니는 찰나에
    이런 좋은 글을 발견했네요 ㅎㅎ
    괜찮으시면 이 글을 토대로 제가 따로 글을 올려놓고 싶은데
    괜찮나요?^^;

    아무튼 여기서 많은 걸 배워갑니다^^

    • reversecore 2010.04.15 23:42 신고 댓글주소 | 수정 | 삭제

      할라님, 안녕하세요. ^^

      저의 저작권 정책만 지켜주시면
      여기서 배우신 내용을 가지고 본인의 글을 쓰시는건
      아무런 문제가 없습니다.

      감사합니다.

  6. 할라 2010.04.19 16:39 신고 댓글주소 | 수정 | 삭제 | 댓글

    음.. 저기 VA/RVA 부분에서요
    VA와 RVA에 관계를 보시면
    RVA + ImageBase = VA라고 되어있는데요
    +가 맞나요??? -아닌가요???

    • reversecore 2010.04.19 23:01 신고 댓글주소 | 수정 | 삭제

      + 가 맞습니다.

      RVA 의 의미가 Relative Virtual Address (to ImageBase) 이거든요.

      따라서 VA = RVA + ImageBase 이고,
      RVA = VA - ImageBase 이지요.

      감사합니다.

  7. kvirus 2010.05.27 10:39 신고 댓글주소 | 수정 | 삭제 | 댓글

    책으로 출판하시는군요...
    꼭 소장하겠습니다!!!
    기대되네요 :)

  8. MyKim 2010.06.17 23:47 신고 댓글주소 | 수정 | 삭제 | 댓글

    이렇게 체계적으로 잘 정리된 내용이라니 ...
    참 좋은 내용를 제공해 주셔서 감사합니다.
    또한 박수와 격려를 보내드립니다.
    그런데 언제 책이 출간되나요 ?
    빨리 사서 공부해야 겠습니다....

    Have reverence for God, and obey his commands, because this is all that man was created for. (Ecclesia 12:13)

  9. 박두현 2010.08.09 19:02 신고 댓글주소 | 수정 | 삭제 | 댓글

    Fig2. 그림을 사용하고 싶습니다.
    프로그램 실행에 관해서 블로깅을 하고 있는데
    Fig2 그림이 너무나 필요합니다.
    물론 출처는 남기겠습니다.

    • reversecore 2010.08.10 12:43 신고 댓글주소 | 수정 | 삭제

      안녕하세요.

      가져가시기 전에 먼저 문의해 주셔서 감사합니다. ^^

      이글의 제일 처음 댓글을 보시면 showtime 님께서 동일한 문의를 주셨는데요.

      그쪽에 제가 답변 달아놓은 대로만 지켜주시면 사용하실 수 있도록 해드리겠습니다.

      감사합니다.

  10. maruhun 2010.08.11 23:55 신고 댓글주소 | 수정 | 삭제 | 댓글

    pe구조에 궁금한점있어서 문의드립니다.

    인터넷으로찾아보았지만 시원한 대답이 없어서 이렇게문의 드립니다.

    페이징 파일이란 가상메모리라고 알고있습니다. 그럼 페이지는 CPU가 엑세스하는 메모리인가요?

    그리고 공부를 하다보니깐 처음에 CPU가 메모리를 vitual address를 발생시킨다고 하는데

    cpu는 가상주소밖에 모르는건가요?

    실제 주소 번지(가상주소)=이미지 로드 시작 번지+RVA 인데

    실제 주소 번지가(가상주소)<----메모리 주소이면 실제주소는 어딘지..

    VAS,MMF,VMM 등 찾아보고 연습장에 내용이랑 찾아놓았지만 연결이 되지를 않습니다..

    간단하게 연결만 시켜주셨으면 감사하겠습니다..

    • reversecore 2010.08.15 22:48 신고 댓글주소 | 수정 | 삭제

      CPU 는 하드웨어이고 컴퓨터의 두뇌 역할이지요.
      따라서 메모리를 직접 access 할 수 있습니다.

      내부적으로 치열하게 물리메모리<->가상메모리 변환을 통해 정확한 주소에 접근할 수 있습니다.

      물리주소에 접근하는걸 궁금하시는게 아니라면...

      위의 설명은 이렇게 이해하시면 됩니다.

      PE 파일이 실행되면 프로세스가 생성되는데,
      프로세스는 4 GB 의 가상메모리를 할당 받고 그중 하위 2GB 를 유저영역으로 사용할 수 있습니다.

      이 프로세스 가상 메모리 주소를 표시할 때 VA 로 나타냅니다.

      음... 어떻게 이해가 되시는지요...

      궁금하신 내용은 또 질문 올려주세요~

      감사합니다.

  11. pe공부 2011.01.01 10:52 신고 댓글주소 | 수정 | 삭제 | 댓글

    리버스코어님 제가 PE포맷에 대해서 공부하다가 의문점이 생겨서 질문드립니다.
    ------------------------------------------------------------------------------------------------
    현재 PE파일포맷형식이 A라고 하면(현재 PE구조)
    PE파일포맷형식을 다른 형식인 B로 만들어도 되는가?(물론,프로그램이 실행해야할 필수정보는 있다.)
    WIN32 OS들은 모두 B형식을 인식할수있다고 치자

    • reversecore 2011.01.03 01:04 신고 댓글주소 | 수정 | 삭제

      안녕하세요.

      네, 말씀하신 대로 가능합니다.

      packer 류의 프로그램이 바로 정확하게 그 일을 수행하고 있지요.

      감사합니다.

  12. 금빛 star 2011.04.27 11:54 신고 댓글주소 | 수정 | 삭제 | 댓글

    좋은 자료에 감사드립니다.
    근데. 가상메모리->물리메모리변환은 누가 해주는가요? OS인가요?
    무식한넘. 감히 질문합니다요.

  13. wjsdlfdhkd 2011.05.01 20:14 신고 댓글주소 | 수정 | 삭제 | 댓글

    wjsdlfdhkd@nate.com 네이트온친추좀 해주세요 ㅠ

  14. PE 2011.05.18 11:43 신고 댓글주소 | 수정 | 삭제 | 댓글

    제가 PE관련하여 발표를 하게 되었습니다.

    ppt자료에 그림을 쓰고 싶습니다.

    사용해도 되는지 먼저 문의 드립니다.

  15. cropin 2011.05.30 01:28 신고 댓글주소 | 수정 | 삭제 | 댓글

    제가 리버싱입문한지 얼마안되서 죄송한데
    offset과 address의 차이점이 무엇인지 설명해주실수 있나요?...

    • reversecore 2011.06.03 22:22 신고 댓글주소 | 수정 | 삭제

      안녕하세요.

      둘 다 거의 같은 개념인데요... 보통 리버싱에서는 아래와 같이 사용됩니다.

      offset 은 어떤 기준점에서 떨어진 거리(변위)를 나타내며 주로 파일내의 위치를 표현할 때 사용합니다. (상대 거리를 나타낼 때 주로 사용됨)

      address 는 주로 메모리의 절대 주소를 나타낼 때 사용됩니다. (절대 주소를 나타낼 때 주로 사용됨)

      감사합니다.

  16. 금강이 2011.09.19 16:43 신고 댓글주소 | 수정 | 삭제 | 댓글

    안녕하세요 요즘은 하루하루 방문해서 조금씩 공부하고 있습니다. ㅎㅎ
    사내에서 스터디 같은걸 하는데 PE 관련 교육을 하려고 합니다. 그림2번 PPT 파일에 사용해도 될지요?

  17. 2012.02.03 11:06 신고 댓글주소 | 수정 | 삭제 | 댓글

    조금 햇갈리는게 있는데 각 널패딩은 하위주소(그림에서 윗부분)에 종속되는건가요? 그러니까 각각의 헤더 및 섹션들의 널패딩은 그 아래부분인건가요?

  18. 라마르틴 2013.02.26 17:00 신고 댓글주소 | 수정 | 삭제 | 댓글

    dllinjection 먼저 읽고 pe구조 몰라서 읽었는데 역시 깔끔합니다. 그동안 몰랐던 것들이 머릿속에서 깔끔하게 정리되는 느낌.

  19. 이정민 2014.10.27 12:20 신고 댓글주소 | 수정 | 삭제 | 댓글

    안녕하세요.
    글을 읽다가 궁금한 점이 하나 생겨서 여쭤봅니다.
    RVA 와 VA에 대해서
    DLL파일 같은 경우 이미 그 위치에 다른 파일이있다면
    재배치 과정을 통해 다른 위치로 로딩되어야 하는데
    VA주소로 되어있다면 정상적인 접근이 안된다는게 이해가 안되는데요,

    첫번째로는
    각 프로세스마다 독립된 가상메모리를 사용하는데
    어떻게 메모리 주소가 겹칠 수 있는지를 모르겠고,

    두번째로는
    RVA 주소든 VA 주소든 하나의 고유한 메모리 주소인데
    VA주소로는 왜 접근이 안되는건지 모르겠습니다.

  20. 코딩하는 경제학도 2017.02.03 08:09 댓글주소 | 수정 | 삭제 | 댓글

    관리자의 승인을 기다리고 있는 댓글입니다





티스토리 툴바