'Reversing'에 해당되는 글 9건

  1. 2012.11.18 UPX MUP 1
  2. 2012.11.12 RVA & RAW
  3. 2012.11.11 PE File Format 0x06
  4. 2012.11.07 PE File Format 0x05
Reversing/Packer2012. 11. 18. 17:25

UPX MUP (Manual Unpacking)


UPX MUP를 해보겠습니다.


0x01. Packing


MUP 대상 program은 reversing 입문자 용 문제인 abex' crackme 1 입니다.

Packing 전의 등록정보를 확인해 보겠습니다.

크기가 8.00KB인 것을 확인할 수 있습니다.


이제 해당 program을 UPX로 packing 한 후 등록정보를 확인해 보겠습니다.

크기가 6.50KB로 줄어들었습니다.

이처럼 UPX는 파일 크기를 줄여주는 packer의 목적에 충실합니다.



0x02. PE File Format


Packing 전후의 PE 구조를 비교해 보겠습니다.

왼쪽이 packing 하지 않은 program이고

오른쪽이 packing 한 program입니다.

Section의 수가 줄어들고 section 명에 UPX라고 적혀있습니다.

Packing된 program의 각 section의 header를 확인해 보겠습니다.


UPX0 section의 header입니다.

UPX0 section의 0ffset은 0x00000400입니다.

살펴보면 특이한 부분이 있습니다.

Virtual Size는 0x00006000인데 반해

Size of Raw Data는 0x00000000입니다.

일단은 넘어갑니다.


UPX1 section의 header입니다.

UPX1 section의 offset은 0x00000400입니다.

UPX0 section의 offset과 동일합니다.

이유는 UPX0의 offset이 0x00000400이지만 크기가 0인 관계로

바로 다음에 오는 UPX1 section이 같은 offset을 갖게 된 것입니다.


UPX0 section은 disk 상에서는 크기가 0으로 아무것도 없지만

Memory에 mapping 될 때는 크기가 0x00006000으로 바뀝니다.

이는 program이 실행될 때 UPX1에 저장된 packing된 code들이

UPX0에 unpacking되어 저장되기 때문입니다.


실제로 UPX0 section과 UPX1 section의 offset인 0x00000400을 가보면

Packing된 code들이 있는것을 확인할 수 있습니다.



0x03. Manual Unpacking


UPX MUP는 매우 간단합니다.

Debugger를 통해 packing된 파일을 열어보겠습니다.


제일 먼저 PUSHAD가 보입니다.


UPX로 packing된 program의 흐름을 간단히 설명하겠습니다.

먼저 PUSHAD를 통해 register 값을 stack에 저장합니다.

그리고 unpacking routine이 끝나면 POPAD를 통해 register를 복구하고

Unpacking된 정상 program이 실행됩니다.


Register가 복구되는 시점을 활용해 한번에 OEP로 갈 수 있습니다.


PUSHAD 이전의 register 상태입니다.


PUSHAD를 실행합니다.


Stack에 PUSHAD를 실행하기 이전의 register 값들이 들어가는 것을 확인할 수 있습니다.


ESP를 따라가 hardware break point를 걸어줍니다.

Register의 크기는 DWORD이므로 DWORD로 걸어줍니다.


실행합니다.


위와 같은 위치에서 멈추는 것을 확인할 수 있습니다.

정지한 위치의 위를 보면 POPAD 명령이 보입니다.

JMP 명령을 따라갑니다.


OEP에 도착했습니다.

Dump를 뜨고 IAT를 복구해주면 unpacking된 프로그램이 완성됩니다.


'Reversing > Packer' 카테고리의 다른 글

UPX  (0) 2012.10.31
Posted by slimV
Reversing/PE File Format2012. 11. 12. 17:39

RVA & RAW



0x01. RVA (Relative Virtual Address)


VA (Virtual Address)memory에 mapping된 절대 주소를 뜻합니다.

RVA는 이름 그대로 어느 기준(ImageBase)으로부터의 상대 주소를 뜻합니다.


VA와 RVA의 관계는 다음과 같습니다.

RVA + ImageBase = VA


PE header 내의 많은 정보들이 RVA 형태로 되어있습니다.

RVA를 사용하는 이유는 relocation 때문입니다.

Dll 같은 경우 memory에 mapping하려는 주소에 이미 다른 library가 있는 경우

Relocation을 통해 빈 공간에 mapping하게 됩니다.


0x02. RAW


RAWdisk상의 file에서 주소를 뜻합니다.

File상에서의 offset이라고도 부릅니다.


0x03. RVA to RAW


PE file이 memory에 load 될 때 RVA와 offset을 mapping할 수 있습니다.

RVA를 통해 offset을 구할 때 사용하는 비례식과 값들은 다음과 같습니다.


RAW - PointerToRawData = RVA - VirtualAddress

RAW = RVA - VirtualAddress + PointerToRawData


RAW : File 상에서의 offset

RVA : Memory 상에서의 RVA

VirtualAddress : Offset을 찾으려는 RVA가 속해있는 section의 RVA

PointerToRawData : Offset을 찾으려는 RVA가 속해있는 section의 offset


0x04. Practice


PEview를 이용해 직접 offset과 RVA를 변환 해 보겠습니다.

PEview로 열어볼 파일은 reversing 입문자 용 문제인 abex' crackme 1 입니다.


해당 프로그램에서 load 하는 dll중 하나인

KERNEL32.dll의 이름을 가리키고 있는 RVA를 offset으로 변환하겠습니다.


계산식을 하나씩 채워나가도록 하겠습니다.

RAW = RVA - VirtualAddress + PointerToRawData


RVA는 offset을 찾으려는 값을 넣으면 됩니다.

KERNEL32.dll의 RVA0x00003064 입니다.


RAW = 0x00003064 - VirtualAddress + PointerToRawData


VirtualAddress는 RVA가 속해있는 section의 RVA 입니다.

0x00003064는 .idata section에 속해있습니다.

.idata section의 RVA0x00003000 입니다.


RAW = 0x00003064 - 0x00003000 + PointerToRawData


PointerToRawData는 RVA가 속해있는 section의 offset 입니다.

.idata section의 offset0x00000A00 입니다.


RAW = 0x00003064 - 0x00003000 + 0x00000A00


계산하면 RAW0x00000A64 입니다.

Disk 상에서 0x00000A64를 찾아가봅니다.


KERNEL32.dll string이 있는 것을 확인할 수 있습니다.


'Reversing > PE File Format' 카테고리의 다른 글

PE File Format 0x06  (0) 2012.11.11
PE File Format 0x05  (0) 2012.11.07
PE File Format 0x04  (0) 2012.10.31
PE File Format 0x03  (0) 2012.10.29
PE File Format 0x02  (0) 2012.10.29
Posted by slimV
Reversing/PE File Format2012. 11. 11. 23:03

PE File Format 0x06



0x01. EAT (Export Address Table)


Windows에서 제공하는 WinNT.h의 _IMAGE_EXPORT_DIRECTORY 구조체입니다.


EAT는 library에서 제공하는 함수를 다른 프로그램에서 불러 쓸 수 있도록 해줍니다.

EAT를 통해 library가 export 하는 함수의 시작 주소를 구할 수 있습니다.

EAT는 PE header에서 Optional header의 Data directory[0]을 따라가면 찾을 수 있습니다.

EAT에서 중요한 부분을 하나씩 살펴보도록 하겠습니다.


NumberOfFunctions // 실제 export 함수의 개수를 나타냅니다.

NumberOfNames /* Export 함수 중에서 이름을 가지는 함수의 개수를 나타냅니다.

 NumberOfFunctions보다 작거나 같습니다. */

AddressOfFunctions /* Export 함수 주소 배열을 가리키고 있습니다.

  배열의 원소 개수는 NumberOfFunctions와 동일합니다. */

AddressOfNames /* 함수 이름 주소 배열을 가리키고 있습니다.

   배열의 원소 개수는 NumberOfFunctions와 동일합니다. */

AddressOfNameOrdinals /* Ordinal 주소 배열을 가리키고 있습니다.

   배열의 원소 개수는 NumberOfFunctions와 동일합니다. */


0x02. Get APIs' Address


EAT가 export 된 함수들을 가리키고 있는 것을 그림으로 나타낸 것입니다.


Export된 함수들의 각 정보를 가진 RVA list들을 가리키고 있는 것을 확인할 수 있습니다.


'Reversing > PE File Format' 카테고리의 다른 글

RVA & RAW  (0) 2012.11.12
PE File Format 0x05  (0) 2012.11.07
PE File Format 0x04  (0) 2012.10.31
PE File Format 0x03  (0) 2012.10.29
PE File Format 0x02  (0) 2012.10.29
Posted by slimV
Reversing/PE File Format2012. 11. 7. 01:12

PE File Format 0x05



0x01. IAT (Import Address Table)


Windows에서 제공하는 WinNT.h의 _IMAGE_IMPORT_DESCRIPTOR 구조체입니다.

   


IAT는 Process가 어떤 library에서 어떤 함수를 가져와 사용하는지에 대한 정보를 가지고 있습니다.

일반적으로는 여러개의 library를 import 하기 때문에

Library 개수만큼 위의 구조체가 배열로 저장되어 있습니다.

구조체 배열의 마지막은 null로 끝납니다.

IAT에서 중요한 부분은 OriginalFirstThunk, Name, FirstThunk 입니다.


OriginalFirstThunk /* INT(Import Name Table)의 주소를 가리키고 있습니다.

     상황에 따라 함수의 주소를 가리키기도 하고

     Ordinal 값으로 사용되기도 하고

     Forwarder로 사용되기도 합니다.

     저장된 주소는 RVA 형식입니다.

     INT의 각 원소는 IMAGE_IMPORT_BY_NAME 구조체 포인터입니다. */

Name /* Library의 이름 문자열의 주소를 가리키고 있습니다.

  저장된 주소는 RVA 형식입니다. */

FirstThunk /* IAT(Import Address Table)의 주소를 가리키고 있습니다.

    저장된 주소는 RVA 형식입니다. */


0x02. IAT Address Mapping


IAT가 어떤 식으로 입력이 되는지를 알아보도록 하겠습니다.


IID의 Name을 이용해 해당 library를 로드합니다.


IID의 OriginalFirstThunk를 이용해 INT의 주소를 얻습니다.

해당 INT에서 IMAGE_IMPORT_BY_NAME의 주소를 얻습니다.

IMAGE_IMPORT_BY_NAME의 Hint 또는 Name을 이용해 해당 함수의 주소를 얻습니다.


IID의 FirstThunk를 이용해 IAT의 주소를 얻습니다.

해당 IAT에 위의 과정에서 얻어온 함수의 주소를 입력합니다.


위의 과정을 INT가 null일 때까지 반복합니다.


'Reversing > PE File Format' 카테고리의 다른 글

RVA & RAW  (0) 2012.11.12
PE File Format 0x06  (0) 2012.11.11
PE File Format 0x04  (0) 2012.10.31
PE File Format 0x03  (0) 2012.10.29
PE File Format 0x02  (0) 2012.10.29
Posted by slimV