PE둥PE둥 놀면서 훑어보는 PE(3)

By conchi | December 7, 2016

PE둥PE둥 놀면서 훑어보는 PE(3)


이 글 맨 마지막에 우리 물꼬기 선원이 “다시는 이거 주제로 글 쓰나 봐라” 라고 하는데요.

물꼬기선원은 다시 이 주제로 글을 쓰게 될거예요ㅎㅎ (사악)

콘치의 32bit 피이↗둥피이↗둥피이↗ 마지막 편 지금 퍼다 날라봅니다ㅋㅋ




부제 : 3편이라 쓰고 2편 번외라 읽는다


안녕하세여. 지난시간 PE에 대해서 뭔가 자기 마음대로 설명해주고 떠난 흐물해진 물고기에여.

여름이되서 몸도 마음도 넘나 흐물흐물 해저버렸어요…는 여름 다 감.


오늘 뭐하기로했더라..


아 맞다 지난시간에 설명하다가 이해한되는거 귀찮다고 넘어가버려서 이번편에선 그거 설명해주기로 했져.


근데 넘나 귀찮은데 알아서들좀 공부 할생각은 없는건가…

네? 없다구여?


녜…


그럼 귀찮지만 와타시가 또 알려드려야 겠네여!


놀면서 공부해야하니까 뒤에 오버워치나 롤이나 와우같은거 켜놓고 오시라는^^


※ 아참 자꾸 업무요정이 저냐고 물어보시는데 저는 약빤 물고기지, 업무요정이 아닙니다.

업무요정님은 노멀하고 포멀하신 분입니다. 아마도…..ㅎ ※




지난시간에 우리가.. 뭘배웠더라.

아 PE라는걸 배웠어요!

뭐 windows에서 사용되는 실행파일들을 보고 PE라고 했었고,

구조는 상당히 괴랄했었어요.


주소들이 거꾸로 적혀있지를 않나.. 뭐 뭐라더라 리틀엔디언? 무튼 그거때문에 거꾸로 적혀있었어요.

그런데 또 웃긴게 걔들은 이유 없이 적힌것도 아니었고 다들 각자의 존재 이유가 있는 애들이었죠.

각각의 구조체에 맞게, 변수들에 맞는 데이터가 들어있었고요.


변수들의 이름은 상당히 직관적인 편이라 대충 뭐하는 놈들인지는 이름만봐도 알 수 있을것 같았어요.


BUT


직관적인 편이라는 주장은 콘치님만 그런것 같았어요.

사실, 도대체 어디가 직관적인지 말도 안해주고 다음편에 말해줄게요(귀찮귀찮) 이러면서 넘어갔었죠.




RAW, RVA, VA 이게 다 뭐야!!


RVA, Offset 뭐가뭔지 잘 모르겠어요 ㅠㅠ

지난글에서 보면 RVA 라던지.. Offset이라던지 이런 이야기가 너무 많이 나와서 혼란스러웠어요.



…요런식으로?  쓰고 제낀 정신없는 부분들을 한번에 싹 정리해봅시다.




File Offset(RAW)


파일이 실행되기 전의 주소를 우리는 File Offset 이라고 부릅니다. RAW라고도 해요.

지난시간 HxD화면에서도 계속해서 등장했었죠.



위의 그림에서 빨간 상자안에 들어있는 바로 이 부분들이 File Offset입니다.

실행되기 전의 파일에서 주소를 논할때는, 바로 이 부분을 이야기 하는 거랍니다.

파일 자체를 분석해야할 때, 이 주소를 기반으로 주로 데이터들을 주로 확인하게 되여.




Relative Virtual Address(RVA)



이는 특정한 위치로부터 얼만큼 떨어진곳에 위치하는지 알려주는 녀석들입니다.

위의 그림에서는 빨간 박스 안에 들어있는 곳에 각각의 항목들이 자리잡을거라는 의미에요.

`IMPORT Table`을 보면 특정한 위치에서 `0x000A71E8` 만큼 떨어진곳에 있다는 소리가 되겠군요.


아니 볼게 얼마나 많은데 얼만큼 떨어진 위치까지 알아야 하는 부분인가여???

라고 생각하시는 분들이 많이 있겠져??

무슨소린지 잘 모르겠져??

요 부분은 다음항목인 VA(Virtual Address)와 엮어서 다시 설명하도록 할게엽.




Virtual Address(VA)


얘들은 메모리의 어딘가에 올라가는 주소이기 때문에 오프셋의 주소범위와 전혀 다른 차원의 주소를 가지기도 합니다.

위키피디아의 요 글을 보시면 제가 말하려는 개념을 이해하기 조금 더 편하실거예요.


우리가 사용하는 windows에서도 위의 글에 나와있는 Memory mapped file을 사용하기 때문에,

파일을 실행하게 되면 프로세스의 어딘가에 존재하는 가상의 메모리 주소공간에 실행한 파일이 올라가게 됩니다.


이러한 과정을 매핑(mapping)이라고 하지요.


요렇게 매핑을 통해 가상 메모리 주소 공간 어딘가에 자리를 잡게되는데

매핑되는 위치는 바로 지난시간 PE Header 볼 때 나왔던

NT Header 중에서 IMAGE_OPTIONAL_HEADER32구조체 안에있는 ImageBase를 의미합니다.


Image Base에 대한 설명을 다시한번 떠올려 보시져!


얘는 메모리에서 PE파일이 어디에 로딩이 되는지 메모리에 로딩되는 시작 주소를 알려주는 부분이에요.

넘나 중요합니다 완전 중요합니다. 별다섯개


ㅇㅇㅋ 설명이 딱 맞아 떨어지네여 낄낄


VA는 요 주소(Image Base)를 기준으로 만들어지는 주소에요.

실제 메모리에서는 바로 이 주소를 보고 이 위치에 있는 명령을 실행시킨답니다.


“그럼 이 위치는 어떻게 만들죠? 이 위치에 대한 내용이 있나요????? 어떻게 확인하져???

PE Header에는 VA라는 말보단 RVA에 대한 내용이 더 많았던것 같은디유!!!!”


라고 물으신다면 대답해드리는게 인지상정!


예, 지난시간 본것처럼 PE헤더에서 나오는 거의 모든 주소값은 모두 RVA를 의미합니다.

Image Base로부터 얼마나 떨어져있는지 거리를 의미하는거죠.


VA(실제 메모리에 로딩되는 주소)를 구하고자 한다면 Image Base주소와 RVA주소를 더하면 됩니다.

그럼 끝이에요 딩딩! 넘나 간단한것!!


그러면 바로


“VA를 미리 좀 적어주지 왜 PE Header안에는 RVA에 대한 내용밖에 없나여?”


라는 궁금증이 생기시는 분들이 있을거에여.


이는 PE가 메모리에 로딩될때 발생하는 특수한 경우 때문이에여.


  1. `VA= 0x123` 이라고 설정을 해뒀는데 해당 위치에 이미 다른 프로그램이 로딩되어 있으면…??….
    ????? 그럼 주소 하나에 두개의 명령이 올라가나요?????
    그..그럴순 없다능.. 후에 올라가는 프로그램이 갈곳을 잃고 혼돈의 카오스에 빠져 프로그램에 문제가 생길거에여.

  2. 특정 버전 이상의 windows OS에서는 ASLR(Address Space Layout Randomization)의 영향을 받아 계속해서 주소값이 바뀝니다.
    이런경우에 VA를 이용하게되면… 바뀌는 시작 주소값을 어떻게 예측할것인가여….


ㅇㅇ 이러한 경우들을 대비해 PE Header에서의 대부분의 주소는 RVA로 표현됩니다.

Image Base가 바뀌어도 우리는 Image Base로부터 요만큼 떨어진 위치에 있어요 !! 하고 알려 줄 수 있기 때문이죠.


이렇게되면 동일한 Image Base의 위치에 영향을 받지 않게 됩니다.

이를 PE Relocation이라 합니댜. 퍕퍕


더 자세히 알고 싶으시다면 검색창에 PE Relocation이라 검색해보세여.

생각하는 그이상의 방대한 자료들이 여러분을 기다릴것이에요.




 IAT? EAT? 그건 또 뭐래여?


지난시간에 잠깐 설명하다가 말아버린 IAT와 EAT입니다.


- 내가 이 프로그램에서 어떤 함수를 사용하는지 모아둔 것과(IAT)

- 내가 라이브러리가 되어서 다른 프로그램들에게 제공하는 함수들을 모아둔것에 대한 내용이 담겨있는 부분입니다(EAT)


뭐 이런식으로 설명하고 호로록 넘어가버렸었던것 같네요.


IAT(Import Address Table)


이녀석은 지난번에 살짝 설명했듯이 내가 이 프로그램에서 어떤 함수(API)를 사용할거시다!!!!

하고 사용할 함수의 주소를 잔뜩 적어둔 테이블이에요.

요 주소들을 따라가보면 어떤 API가 쓰이는지, 그 API는 어떤 DLL을 사용하는지까지 나온답니다.

(이 주소들도 RVA값으로 되어있습니다)


exe같은 실행파일들을 파헤칠때 중요하게 보는 부분이에요.


어떤 API들이 사용되는지 확인하고, 아니! 이런동작을 하는 API들이 주로 사용되는군!!

그럼 넌 이런 역할을 하는 프로그램이니? 하고 추측할 수 있거든요.


아니 그럼 이건 도대체 왜있는거져????

맨날 추측이나 당하고 분석을 제대로 해보지 않아도 뭐하는놈인지 얼추 파악이 되버리쟈나여!!!!


왜긴여… 메모리를 효율적으로 쓰고, 파일의 크기를 쬐끔이나마 줄여보자는 설계자의 빅픽쳐죠


위에서 말했지만 주소(address)들이 기술되어 있는 테이블입니다.

그리고 해당 API를 제공하는 DLL에 대한 정보도 함께 들어있죠.


해당 DLL에서 내가 쓰고싶은 API가 존재하는 주소로 가서 땡겨(?)오겠다, 이런의미가 됩니다.


그러면 굳이 해당 실행파일 안에 내가 사용하고자 하는 함수에 대한 모든 정보가 없어도

주소만 가지고 DLL로 넘어가 해당 주소에 있는 함수에 대한 정보를 샥샥 가져다가 쓰기만 하면 되니까

용량이 클 필요도, 메모리를 잔뜩 잡아먹을 필요도 없다 이거져


오키?


넘나 천재적인것.


이와 반대되는 개념이 바로


EAT(Export Address Table)


입니다.


DLL처럼 본인이 라이브러리와 같은 기능을 하는 프로그램들을 살펴보면 EAT부분에 뭐라뭐라 많은 내용들이 기술되어있는걸 볼 수 있어요.


왜냐하면!

말그대로 나는 너희에게 이러한 API를 제공하노라 엣헴

하고 있는 셈이거든요.



우리의 conchiCrack.exe는 다른 누군가에게 API를 제공하고 있지 않으므로

EXPORT Table에 대한 내용이 없네영ㅋㅋ




흠냥흠냥 이로써 우리는 PE 포맷을 이해하는데 필요한 지식을 쬐끔 더 습득했져영 뿌우!


그러면 이제 한번 맞나 안 맞나 내가 잘 공부했나 못했나 어디한번

실습을 통해서 알아보도록 하져!!!!(고약)


사용한 프로그램은 콘치의 리버싱 튜토리얼 마지막 편에서 사용했던 바이너리 입니다!


미션 : IMPORT Table의 RVA를 이용하여 실제 실행된 프로그램에서 API를 찾아봅시당!!

※ 편의를 위하여 툴을 이용하여 IMPORT Table의 RVA를 찾았습니당. 퍕퍕※





네 그렇다고 합니다.


위의 사진을 보고있자니 `RVA = 0x000A71E8`이라고 하네요.

요말인 즉슨, Image Base로부터 0x000A71E8만큼 떨어진곳에 IMPORT Table가 존재한다 이런 소리가 되는군요!!!

꺄륵!!!!

그럼 Image Base를 확인해보도록 합시다.



그렇다고 합니다.


그럼 어서어서 프로그램을 디버거로 확인해봅시다 ^0^ !!!!


VA = RVA 와 ImageAddress를 더한곳에 있다고 했으니

분명 0x000A71E8 + 0x00400000 되는곳에 IMPORT Table가 존재하겠졍!!!


넘나 쉬운것 !!!…



…은 ASLR이 걸려있습니다.


분명히 Image Base는 0x00400000이랬는데….

그림을 보아하니 0x002F0000가 Image Base라네요.



이런식이기 때문에 RVA를 사용할 수 밖에 없어여 ㅜㅜ..


VA를 바로 적어두면 Image Base가 바뀌면 답이 없거든여

우리는 놀면서 배운사람들이니 빠르게 IMPORT Table의 VA를 구해봅시다.


0x002F0000(Image Base) + 0x000A71E8(IMPORT Table RVA) = 0x3971E8


입니댱 헤헤!



해당위치로 가보면 아주 수상한 RVA값 같이 생긴녀석이 낭낭하게 자리잡고 있네여.

근데 요기 IMPORT Table맞나여? 생각했던것 보다 뭐가 너무없는데 ‘ㅅ’.. 긁적긁적

저 수상한 RVA값이 있는곳에 이 프로그램에서 사용되는 유일한 함수인 MessageBoxW가 있다면

제가 이부분을 IMPORT Table로 인정해주도록 하져(????)


이녀석(IAT)은 지난번에 살짝 설명했듯이 내가 이 프로그램에서 어떤 함수(API)를 사용할거시다!!!! 하고 사용할 함수의 주소(RVA)를 잔뜩 적어둔 테이블이에요.

(라고 설명했지만 눈에 보이는 간지나는 것이 없다며 제 기능을 부정하려는 하는 물고기를 보고 계십니다)


흠흠

해당 위치에 있는 RVA스러운 녀석의 VA를 구해봅시다.


0x002F0000(Image Base) + 0x000A740C(문제적 RVA) = 0x39740C





어맛! (개놀란척)


`MessageBoxW` 이 성공적으로 나와줬네요 ㄷㄷ….


하 이거이거 전부다 RVA로 되어있으니.. 계산하는 방법을 모르면 메모리 어디에 올라가있는지 알 수가 없겠군요.


그러나


제가 아주 그냥 호로록 다 설명해드렸으니 이제 여러분도 잘 할수 있겠져? ^^?!!



와타시가 아주 큰일을 해낸듯 합니다.(응?)




어땠나여? 32bit PE시리즈는 이렇게 끝입니다. 홋홋 !!


어디 PE시리즈 재밌었나여?

이거 보고나니까 아 PE별거 아니네 싶지 않나여 ‘0’?!


제가 이 글은 처음 PE를 시작하는, 주변에서 “PE개극혐 개노잼 개어려움” 이런 말만 듣고

공포에 질려 오들오들 떨며 ‘내가 감히 어떻게 PE를 공부해’라고 하며 포기하는 분들을 위해

피둥피둥 놀면서도 공부할 수 있다며 구라치고

최대한 쉽게 알려드려 노력하며 써봤어여.


어디 조금 쉬웠나요?

맞아여 PE는 이렇게 쉽게 시작할 수 있는거에여.

(입술에 침을 바르지 않으며)


해보니까 별거 아니져? ㅎㅎ… 할 수 있을거 같져 ㅎㅎ…

해보시라는 ㅎㅎ!!

(그리고 내탓은 하지마시라는)


따라오느라 고생 많으셨습니다. 다들 열공합시댱!! ‘0’!!




결론



다시는 이거 주제로 글쓰나봐라

뿅!


comments powered by Disqus