어플리케이션 후킹(Application Hooking) 설계(디자인)에 대한 설명입니다. 후킹 방법을 결정하고, 검증하는 과정을 보여드립니다. 



후킹 방법 결정 - 무엇을? 어떻게? 후킹 할 것인가?


우리의 목표는 [HxD.exe 프로그램에서 PE 파일을 열었을 때 상태바의 "Offset: XXXX" 문자열에 "RVA: YYYY" 문자열을 추가하기]  입니다.


기존 어플리케이션에 어떤 기능을 추가(혹은 수정) 하려고 마음을 먹었다면 그 다음에는 구체적인 방법에 대해 고민을 해야 합니다. 즉, 후킹 설계 과정으로 들어가야 합니다.


윈도우즈 OS의 대표적인 후킹 기법은 "메시지 후킹(Message Hooking)""API 후킹(API Hooking)" 입니다. 둘 중에서 목표 달성에 더 적합하고 구현이 편리한 방법을 사용하는 것이 좋을 것입니다.


일반적으로는 메시지 후킹 기법이 더 간단하고 더 안전하다고 볼 수 있습니다. 대신 경우에 따라(특히 GUI 관련) 더 많은 고려사항이 필요한 경우가 있습니다. 따라서 실전에서는 후킹 설계 단계에서 메시지 후킹 방법이 더 편리할지 확인해 보는 것이 좋습니다.



메시지 후킹 기법 검증


우리 목표에 메시지 후킹 기법이 잘 어울릴지 검증해 보도록 하겠습니다. 


Windows OS 는 어플리케이션 윈도우의 GUI 처리 작업을 위해 윈도우 메시지를 이용합니다. HxD.exe 의 상태바도 일종의 윈도우입니다. 프로그램 내부에서 상태바에 특정 문자열을 쓰기 위해 관련된 윈도우 메시지를 전달할 것입니다. 


* 참고 


GUI 관련 API 를 호출하면 GUI 작업 처리를 할 수 있기 때문에 마치 윈도우 메시지를 사용하지 않고도 작업이 가능한 것처럼 생각될 수도 있습니다. 그러나 실제로는 API 내부에서 윈도우 메시지를 보내는 것입니다. 일반적인 GUI 작업은 메시지 기반으로 동작한다는 것을 기억하시기 바랍니다.


HxD.exe 의 상태바에 있는 "Offset: XXXX" 문자열이 변경될 때 상태바 윈도우 프로시저(Window Procedure)에서 처리하는 윈도우 메시지들을 확인해 보겠습니다. 먼저 HxD.exe 프로그램을 실행 하신 후 적당한 PE 파일을 열어 주세요.


그리고 윈도우 메시지를 모니터링 하기 위해 Spy++ 유틸리티를 실행합니다.



<그림 3 - Spy++ 실행화면>


* 참고


윈도우 메시지 확인에 있어서 Spy++ 은 최고의 유틸리티입니다. 기본 동작 원리는 윈도우 메시지 후킹입니다. 모니터링 대상 프로세스에 DLL 을 인젝션 시켜서 사용자가 원하는 메시지를 모니터링 합니다. Spy++ 은 Microsoft Visual Studio 패키지에 포함된 유틸리티 입니다. 


Spy++의 툴바에서 "Log Messages... (Ctrl+M)" 버튼을 선택합니다. (또는 "Spy - Log Messages..." 메뉴를 선택하셔도 됩니다.)



<그림 4 - Log Messages... (Ctrl+M) 툴바 버튼>


Message Options 다이알로그가 나타납니다.



<그림 5 - Message Options 다이알로그>


Windows 탭의 Finder Tool 을 이용할 것입니다. Finder Tool 아이콘을 마우스 버튼을 누른 채로 드래그 하면 마우스 포인터가 과녁 모양으로 바뀝니다. 이 과녁 모양의 마우스 포인터를 HxD 의 상태바 윈도우에 위치시킨 후 마우스 버튼에서 손을 떼면 Spy++ 의 타겟(Target) 윈도우로 설정됩니다. (과녁 모양의 마우스 포인터 밑에 있는 윈도우는 두꺼운 검은색 테두리가 생겨서 잘 알아 볼 수 있습니다.)



<그림 6 - Finder Tool 로 상태바 설정>


이제 Spy++ 의 Message Options 다이알로그의 "Selected Object" 섹션에 지금 선택된 HxD 의 상태바 윈도우에 대한 정보들이 표시됩니다.



<그림 7 - HxD 의 상태바 윈도우 정보>


각 정보들이 나타내는 의미는 <표 1>과 같습니다.


 항목

 의미

 

 Window

 윈도우 핸들

 001B0362

 Text

 윈도우 텍스트

 Offset: 0

 Class

 윈도우 클래스 이름

 TXmStatusBar

 Style

 윈도우 스타일

 54000100

 Rect

 윈도우 위치와 크기

 (15, 663)-(589, 684) 574x21

 Thread ID

 윈도우를 생성한 스레드 ID

 00000150

 Process ID

 윈도우가 속한 프로세스 ID

 00000F30


<표 1 - Selected Object 항목들의 의미>


* 참고


Spy++ 에서 보여주는 상태바 윈도우의 정보는 나중에 메시지 후킹을 구현할 때 좋은 참고자료가 됩니다.


윈도우 클래스 이름이 "TXmStatusBar" 인 걸로 봐서 윈도우 기본 상태바(StatusBar)를 서브클래싱(SubClassing) 한 것으로 추정됩니다. 그렇다면 기본 동작은 윈도우 기본 상태바와 비슷할 것이라고 예상해 봅니다.


Message Options 다이알로그의 [확인] 버튼을 선택하면 이제부터 Spy++ 은 HxD 의 상태바 메시지를 모니터링하기 시작 합니다. 시험 삼아서 마우스 포인터를 상태바 위에서 이리저리 이동해 보시기 바랍니다. Spy++ 화면에 마우스 관련 메시지가 많이 나타날 것입니다.



<그림 8 - 마우스 이동 메시지>


Spy++ 의 메시지 캡쳐 옵션을 디폴트인 'ALL' 로 설정하였기 때문에 상태바로 전달되는 모든 메시지가 표시되는 것입니다. 우리가 진짜 궁금한 내용은 상태바에 문자열이 써지는 순간에 어떤 메시지를 받느냐 하는 것입니다. 


Spy++ 툴바의 'Clear Log (Del)' 버튼을 선택하여 지금까지 쌓인 로그를 지워버립니다. 그리고 HxD.exe 의 메인 화면 내의 아무 부분을 마우스로 클릭하시기 바랍니다. 마우스가 선택한 파일의 옵셋을 상태바에 출력하기 위해 메시지가 전달될 것입니다.



<그림 9 - 문자열 출력 메시지>


HxD 메인 윈도우에서 마우스 클릭을 한번 하면 정확히 9개의 메시지 로그가 출력됩니다. (제가 보기 편하게 들여쓰기를 하였습니다.)


<00001> 001B0362 S message:0x040A [User-defined:WM_USER+10] wParam:00000000 lParam:0012FA84

<00002> 001B0362 R message:0x040A [User-defined:WM_USER+10] lResult:00000001


<00003> 001B0362 P WM_PAINT hdc:00000000


<00004> 001B0362 S message:0x0401 [User-defined:WM_USER+1] wParam:00000000 lParam:01A06768

<00005> 001B0362 S   WM_PAINT hdc:00000000

<00006> 001B0362 S     WM_ERASEBKGND hdc:33010BC2

<00007> 001B0362 R     WM_ERASEBKGND fErased:True

<00008> 001B0362 R   WM_PAINT

<00009> 001B0362 R message:0x0401 [User-defined:WM_USER+1] lResult:00000001


1번 로그의 메시지는 WM_USER(0x400)+A 이고 그 때의 lParam 값은 0012FA84 입니다. lParam 값이 마치 스택의 주소를 가리키는 것으로 추정됩니다. 그리고 4번 로그의 메시지는 WM_USER(0x400)+1 이고 lParam 값은 01A06768 입니다. 이 값 또한 메모리 주소를 표시한다고 추정해 볼 수 있겠습니다. 


마우스(또는 키보드)를 이용하여 HxD 메인 윈도우의 커서를 다른 옵셋으로 이동시키면 기본적으로 이와 동일한 9 개의 메시지 로그가 기록됩니다. 그리고 4 번째 로그의 lParam 값은 계속 바뀌는 것을 알 수 있습니다. (아마 동적 할당 메모리로 추정됩니다.)


따라서 상태바 윈도우는 사용자 정의 메시지인 WM_USER+1 또는 WM_USER+A 메시지를 받아서 lParam 이 가리키는 주소의 문자열을 상태바 윈도우에 쓴다고 추정해 볼 수 있겠습니다. 그 중에서도 4번 로그 메시지 WM_USER+1 을 받은 직후 WM_PAINT 와 WM_ERASEBKGND 메시지가 연속해서 나타나는 걸로 봐서는 WM_USER+1 메시지가 상태바 윈도우에 실제 값을 쓰라는 명령으로 보입니다.


디버거를 이용하여 lParam 이 가리키는 주소를 확인해보면 앞에서 추론한 내용이 맞는지 알 수 있겠지요.


* 참고


WM_PAINT 는 윈도우를 다시 그릴 때 발생되고, WM_ERASEBKGND 는 윈도우 배경을 지울 때 발생됩니다. WM_USER (0x400) 이후부터는 사용자 정의 메시지로서 프로그래머가 마음대로 지정해서 사용할 수 있습니다. 물론 메시지를 받는 윈도우 프로시저에서 사용자 정의 메시지를 잘 처리할 수 있도록 구현해야 합니다. 해당 메시지에 대한 더 자세한 설명은 MSDN 을 참고하시기 바랍니다.



디버깅


OllyDbg 를 실행하여 HxD.exe 프로세스에 Attach 시킵니다. 디버거는 ntdll.dll 메모리 영역의 System Break Point 위치에서 멈춥니다. 디버거를 실행[F9] 시켜 줍니다. 


윈도우 메시지를 디버깅 할 때는 주의사항이 있습니다. 그건 바로 디버기 프로세스(HxD.exe)의 윈도우를 가리면 안된다는 것입니다. 즉 OllyDbg 나 Spy++ 윈도우에 의해 HxD 윈도우가 가려졌다가 나타났다가 하게 되면 불필요한 로그가 Spy++ 에 쌓이게 됩니다. (물론 Spy++ 옵션을 고쳐서 모니터링 메시지를 필요한 것 만으로 제한해도 됩니다.) 


작업 편의상 각 윈도우들을 독립적으로 배치 시켜 주시기 바랍니다.



<그림 10 - 윈도우 배치>


다시 Spy++ 의 로그를 깨끗이 지우신 다음 마우스로 HxD 메인 윈도우 아무 곳이나 선택해 주세요. 제 경우에 Spy++ 의 WM_USER+1 로그의 lParam 주소는 01A0BA28 입니다. 



<그림 11 - 새로운 lParam 값>


이 주소를 OllyDbg 의 메모리 윈도우에서 검색해 보겠습니다.



<그림 12 - OllyDbg 에서 확인한 lParam 내용>


HxD 의 상태바에 나타난 것과 동일한 문자열이 ASCII 형태로 표시되어 있습니다. (이 경우에는 운좋게 예상과 잘 맞아서 쉽게 발견할 수 있었습니다.) 이 WM_USER+1 메시지를 후킹해서 lParam 이 가리키는 문자열("Offset: XXXX")을 읽은 후 RAW -> RVA 변환하여 표시해 주면 목표를 완수 할 수 있을 것 같습니다.


결론적으로 메시지 후킹 방법은 우리 목표에 잘 들어맞는 방법입니다. 다음 포스트에서 실제 메시지 후킹을 구현해 보도록 하겠습니다.


* 참고


사실 제가 처음 떠올렸던 아이디어는 단순한 마우스 메시지 후킹이었습니다. HxD.exe 상태바의 문자열이 바뀌려면 먼저 마우스로 커서 위치를 바꿔줘야 했으니 마우스 훅 프로시저에서 상태바의 문자열을 읽고 쓸 수 있지 않을까 하고 말이죠. 그러나 조금 더 생각해보니 좋은 아이디어가 아니라서 접었습니다. 이유는 키보드로도 커서 위치를 바꿀 수 있으니 키보드 메시지도 후킹 해야 할 테고, 상태바 윈도우가 다시 그려져야 하는 모든 상황(윈도우 이동, 윈도우가 가려졌다가 다시 나타나기, HxD 에서 다른 파일 열기, 기타)을 고려했을 때 후킹해야 할 메시지가 많아 질 것 같았기 때문입니다. 

따라서 덮어놓고 후킹을 시도하기보다는 먼저 차분히 생각을 정리해보고, 아이디어를 검증하는 단계가 매우 중요하다고 볼 수 있겠습니다.




ReverseCore

    이전 댓글 더보기
  1. Lr라 2013.03.04 14:48 신고 댓글주소 | 수정 | 삭제 | 댓글

    어렵군요..ㅎㅎ;;
    그냥 이정도 자료로도 저에겐 벅찹니다..

    • reversecore 2013.03.04 20:17 신고 댓글주소 | 수정 | 삭제

      ^^ 네, 처음 접하시면 분명히 어려운게 사실이지요.

      뭐든지 그렇지만 자꾸 보면 할만해져요~

      리버서들이 천재도 아니고 그냥 평범한 사람들이거든요. 그런데요 자꾸 보다보면 괜찮아요~ ^^

      감사합니다.

  2. supras shoes 2013.04.27 02:40 신고 댓글주소 | 수정 | 삭제 | 댓글

    내가 성공을 했다면 오직 천사와 같은 어머니의 덕이다.Topics related articles:


    http://azza.tistory.com/116 新建文章 11

    http://color114.tistory.com/68 新建文章 6

    http://mycite.tistory.com/78 新建文章 2

    http://bfhopestore.tistory.com/206 新建文章 5

  3. lunettes carrera 2013.04.28 04:22 신고 댓글주소 | 수정 | 삭제 | 댓글

    희미한 달빛이 샘물 위에 떠있으면, http://noq.botasugger.com/ botas ugg online,나는 너를 생각한다.

  4. nike free run shoes 2013.04.29 06:27 신고 댓글주소 | 수정 | 삭제 | 댓글

    노동은 생활의 꽃이요, 삶의 보람이요, 마음의 기쁨이다.Topics related articles:


    http://sma14u.tistory.com/70 新建文章 3

    http://ianbuffet.tistory.com/44?nil_openapi=search 新建文章 12

    http://eshita.tistory.com/120 新建文章 2

    http://starspalace.tistory.com/53 新建文章 6

  5. 현빈지배인 2015.04.25 16:40 댓글주소 | 수정 | 삭제 | 댓글

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

  6. TM이태임 2015.05.19 01:00 댓글주소 | 수정 | 삭제 | 댓글

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

  7. TM이태임 2015.05.19 04:07 댓글주소 | 수정 | 삭제 | 댓글

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

  8. TM이태임 2015.05.20 01:25 댓글주소 | 수정 | 삭제 | 댓글

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

  9. TM이태임 2015.05.20 23:38 댓글주소 | 수정 | 삭제 | 댓글

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

  10. 하대표 2015.06.08 05:49 댓글주소 | 수정 | 삭제 | 댓글

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

  11. 하대표 2015.06.08 08:34 댓글주소 | 수정 | 삭제 | 댓글

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

  12. 하대표 2015.06.08 21:22 댓글주소 | 수정 | 삭제 | 댓글

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

  13. 하대표 2015.06.08 23:23 댓글주소 | 수정 | 삭제 | 댓글

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

  14. 하대표 2015.06.10 17:33 댓글주소 | 수정 | 삭제 | 댓글

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

  15. 하대표 2015.06.10 21:01 댓글주소 | 수정 | 삭제 | 댓글

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

  16. 하대표 2015.06.11 16:48 댓글주소 | 수정 | 삭제 | 댓글

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

  17. 하대표 2015.06.11 20:15 댓글주소 | 수정 | 삭제 | 댓글

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

  18. 하대표 2015.06.12 22:03 댓글주소 | 수정 | 삭제 | 댓글

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

  19. 하대표 2015.06.13 01:34 댓글주소 | 수정 | 삭제 | 댓글

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

  20. 하대표 2015.06.15 21:24 댓글주소 | 수정 | 삭제 | 댓글

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


HxD.exe 기능 추가!

tool 2012.06.14 00:35

리버싱 기술을 조금 응용하면 다른 응용프로그램의 기능을 추가/변경시킬 수 있습니다. 


제가 애용하는 헥스 에디터 HxD.exe 에 필요한 기능을 살짝 추가하였습니다.



HxD.exe



DLL InjectionAPI Hooking 기술을 이용하여 HxD.exe 프로그램에 새로운 기능을 추가하였습니다.



제가 추가시킨 기능은 PE 파일 Offset 의 RVA 값을 계산해서 출력해 주는 것입니다. (위 그림 참고)


키보드나 마우스를 이용하여 커서 위치를 이동하면 Offset 값이 변함에 따라서 자동으로 그에 맞는 RVA 값이 계산되어 표시됩니다.



사용방법



HxD.exe  - Hex Editor

hxdhook.dll  - hooking dll

InjDll32.exe  - Injector

PEInfo.dll  - File Offset <->RVA converter



1. HxD.exe 실행


2. HxD 에서 아무 PE 파일을 오픈


3. InjDll32.exe 를 이용하여 HxD.exe 프로세스에 hxdhook.dll 을 인젝션





HxD.exe 프로세스에 hxdhook.dll 이 정상적으로 인젝션 되었다면 이제부터 프로그램 하단의 Status Bar 에 Offset 과 RVA 가 동시에 표시될 것입니다. 


크게 유용하다고 볼 수 는 없지만 리버싱 기술을 응용하여 기존 프로그램에 새로운 기능을 추가하는 방법을 잘 보여주는 예제라고 생각합니다. 필요하신 분께서는 자유롭게 가져다 쓰실 수 있습니다.



* 블로그에 리버싱 기술 응용편을 올리기 위해 준비한 간단한 시연입니다. 자세한 동작 원리, 후킹 과정, 모듈 개발 과정 등은 따로 포스팅 하도록 하겠습니다.



ReverseCore



'tool' 카테고리의 다른 글

PEView.exe  (48) 2013.01.27
HxD.exe 기능 추가!  (13) 2012.06.14
리버싱 현업에서 사용되는 디버거(Debugger)들  (31) 2010.09.29
InjDll.exe – DLL Injection/Ejection 전용 도구  (101) 2010.03.15
Process Explorer - 최고의 작업 관리자  (1) 2009.05.03
www.virustotal.com  (3) 2009.03.20
www.google.com  (2) 2009.03.06
  1. rgs 2012.06.14 19:13 신고 댓글주소 | 수정 | 삭제 | 댓글

    와 제가 댔글 처음인건가요 ?
    주인장님
    블로그 다시 시작하시는군요
    매일 들려보는 사람입니다.
    블로그 정말 재밋어요
    계속 열심히 해주세요

  2. 카이섹이 좋아 2012.06.14 20:33 신고 댓글주소 | 수정 | 삭제 | 댓글

    리버스 코어님 ㅠ ㅠ 언제 책이.....

  3. 감염오리 2012.06.15 00:44 신고 댓글주소 | 수정 | 삭제 | 댓글

    드디어!!! 포스팅 재개인가요^^

  4. 마리오 2012.06.15 10:25 신고 댓글주소 | 수정 | 삭제 | 댓글

    오호 포스팅 되었군요ㅎ
    책출판될거보다 포스팅된게 더 반가워요ㅎ

  5. db_click 2012.06.16 10:27 신고 댓글주소 | 수정 | 삭제 | 댓글

    항상 포스팅 감사히 보고 있습니다.

  6. 안녕하세요 2012.06.20 09:52 신고 댓글주소 | 수정 | 삭제 | 댓글

    책이 나오기만을 학수고대하고 있습니다.
    책 나오면 바로 살게요! ^^

  7. reversecore 2012.06.23 00:52 신고 댓글주소 | 수정 | 삭제 | 댓글

    관심 감사드립니다. ^^~

  8. Lr라 2013.03.04 14:47 신고 댓글주소 | 수정 | 삭제 | 댓글

    항상 포스팅 하신글 잘보고있습니다.
    음...~~~ 저걸 이용해서 헥스 만큼 바이트 채우고 시작되는 부분에 call로
    때려서 영역에서 불러와서 인라인 어셈으로 자동인젝션되도록 만들어야겟습니다 ㅎㅎ
    잘쓰겠습니다 ㅎㅎ

  9. absolujin 2013.05.02 15:22 신고 댓글주소 | 수정 | 삭제 | 댓글

    전 이렇게 batch 파일 만들어서 사용하고 있어요.
    잘쓸께요. 감사합니다.
    --------------------------------------------------------------
    @echo off
    start Hxd.exe
    start InjDll32.exe HxD.exe -i hxdhook.dll

  10. yO Kang 2014.03.13 02:12 신고 댓글주소 | 수정 | 삭제 | 댓글

    똑같이 했는데, 저는 "The token does not have the specified privilege" 이런 문구뜨면서 안되네요..
    뭐가 문제일까요?

  11. RBWSN 2016.02.25 06:36 댓글주소 | 수정 | 삭제 | 댓글

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




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 댓글주소 | 수정 | 삭제 | 댓글

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





티스토리 툴바