Be myself :: UPX압축 디버깅

달력

32024  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

UPX압축 디버깅

Reversing 2014. 5. 9. 13:41

1 개념

UPX실행 압축된 파일을 뜯어보면서 OEP까지 가는게 목표이다. 한번 읽어보고 직접 실습하면서 연습하자.

2 분석

어떤식으로 압축 알고리즘이 되어 있는지 살피기 위해 일단, PE구조를 살펴 보았다.

IMAGE_SECTION_HEADER UPX0의 구조이다. 여기서 주목할 점은 파일에서의 사이즈가 0이라는 점이다. 하지만 Virtual Size를 보면 10000값을 가진다. 이것이 의미하는 것은 다른 섹션에서 압축해제 알고리즘을 가지고 있어 그 섹션에서 먼저 EP가 실행이 되고 압축해제가 완료되면 원래의 UPX0섹션에서 OEP를 가진다는 것을 유추할 수 있다. 자, 그럼 이제 올리디버거로 이 파일을 까보자.

빠르게 훑어보면 코드섹션에 많은 데이터가 압축되거나 암호화되어 있고, 그 결과로 분석된 코드가 정상적이지 않을 수 있다는 말을 뱉어낸다. 그냥 '예'를 눌러준다.

처음 명령어를 살펴 보면, 먼저, EAX~EDI 레지스터 들을 스택에 push한 다음, ESI와 EDI값을 설정한다. 그 중 ESI와 EDI에 어떤 값이 들어가는지 살펴 보면 1011000값과 1001000값이 들어 있다. 이 값은 각각 아까 PEview에서 보았듯이 UPX1섹션과 UPX0섹션의 시작 값 이였다. 그렇다면 아까 우리가 예상 했듯이 UPX1에서 압축해제 알고리즘이 끝나면 UPX0에 압축해제된 내용이 존재하고, 원래의 OEP로 찾아 갈 수 있을 것 같다.

계속 트레이싱 하다 보면, 다음과 같은 루프를 만날 수 있다.

ECX의 수만큼, EDX의 하위 1바이트 값을 AL에 넣고, AL값을 EDI값(UPX0위치)에 넣는 루틴이다. 값은 NULL을 넣으니, UPX0의 공간을 확보하는 루틴이라 보아도 좋을 것 같다.

그 이후 EDI에 값을 넣는 루틴을 3가지 정도 발견 할 수 있다.

  (첫째)

(둘째)

(셋째)

EAX에 압축해제된 데이터가 존재하고 이 값을 EDI(UPX0)에 넣는 과정이다.

그 다음 만나는 루프는 다음과 같다.

UPX0에서 E8과 E9(CALL, JMP명령어)부분을 찾아 어떤 연산을 수행하는데, 잘은 모르겠지만 점프할 주소를 원래대로 복원시키는 작업인 것 같다. 계속 트레이싱 해보자.

뭔가 많이 본 함수가 보이지 않나? LoadLibraryA-> GetProcAddress가 반복된다. 앞에서 살 펴 본 IAT에 함수 시작값을 입력하는 순서에 나왔었다. 즉 이 반복루틴은 INT에 함수의 시작점을 입력하는 루틴이다. 여기까지 보면 의문스러운 점이 한두가지가 아닐 것이다. 일단 INT에 함수의 시작점을 쓴다는데, 그럼 LoadLibraryA의 시작주소는 어떻게 메모리에 올라가 있는 것인가? GetProcAddress는 또 어떠한가. 그래서 PE Viewer로 찾아보았다.

IMPORT Directory Table이 .rsrc섹션에 존재하고 있었다! 그렇다면 중요한 라이브러리의 함수들은 rsrc섹션에 이미 다 로드 되어 있고, 나머지 함수들이 UPX0섹션의 INT영역에 API주소가 입력되어 진다는 것이다.

자 이제 끝났다. 조금 더 트레이싱 하다보면, 다음과 같은 화면을 볼 수 있다.

JMP로 OEP에 가는 것을 볼 수 있다. 100739D는 UPX0의 영역이다.

'Reversing' 카테고리의 다른 글

인라인 패치  (0) 2014.05.11
Upack 분석중 정리  (0) 2014.05.10
IAT와 EAT  (0) 2014.05.08
PE구조  (0) 2014.05.08
기본 레지스터  (0) 2014.05.04
Posted by flack3r
|