'mup'에 해당되는 글 1건

  1. 2010.06.13 [Reversing] UPX manual unpacking / UPX 패킹 방식의 구조 (2)
0x03 Reversing/Reversing2010.06.13 23:26

1. 개요
대표적인 packing 알고리즘인 UPX를 이용하여 packing에 대한 개념과 Manual Unpaking을 방법을 이용하여 Unpacking하는 방법을 알아보도록 한다.  기존에 UPX를 언패킹하는 방법에 대한 자료는 많지만 세부적인 내용까지 나온 자료는 흔치 않은 듯 하다. 조금더 세부적인 사항까지 알아보도록 한다. MUP 방법은 많은 자료들이 있기 때문에 다른 자료를 참조하길 바란다.

2. 패킹된 파일의 비교
                     <원본 notepad.exe 파일의 구조>                   <upx로 패킹된 notepad.exe 파일의 구조>
PEiD를 이용하여 패킹 전후의 구조를 비교한 사진이다. 일단 섹션 테이블의 구조가 변경된 것을 볼 수 있다. 원본과는 달리 .text, .data 섹션이 없어지고 UPX0, UPX1 섹션이 생성된 것을 볼 수 있다. 패킹된 파일의 섹션 테이블의 주소를 눈여겨 봐두기 바란다.

각 파일의 Entry Point 값도 원본이 0000739D(.text 섹션)인 반면에 패킹된 파일의 경우 00015330(UPX1 섹션)인 것을 볼 수 있다. 이를 그림으로 나타내면 다음과 같다.

패킹된 notepad.exe 파일의 경우 UPX1 섹션에서 프로그램이 시작됨을 알 수 있으며, Ollydbg를 이용하여 UPX0 섹션의 값을 보면 모두 '00' 값으로 채워져 있는 빈 섹션인 것을 알 수 있다.

3. 패킹 파일의 복원
1) UPX0 섹션 초기화 루틴
Ollydbg를 이용하여 패킹된 파일을 로딩후 실제로 어떤식으로 원본 파일을 메모리에 복원하는지 살펴보자.
F8을 눌러가며 진행하다 보면 위와 같은 루프 구문을 만나게 된다. 최초 위 루프 구문을 만났을 때 EDX에는 UPX0 섹션의 주소가 저장되어 있는 것을 볼 수 있다. 또한 EDI 레지스터에는 EDX + 1의 주소값이 저장되어 있는 것을 볼 수 있다.

전체 흐름을 보면 EDX 레지스터가 가르키는 주소의 1 byte 값을 읽어와서 AL 레지스터에 저장한다. 이후 EDX 값을 1 증가시키고, AL 레지스터에 저장된 값을 EDI 레지스터가 가르키는 주소에 복사한다. 이후 EDI 레지스터 값을 1 증가시킨다. 이를 EDX 레지스터 값 만큼 반복하는 구문이다. 즉, UPX0 섹션을 처음부터 ECX 값 만큼 돌면서 '00' 값으로 초기화하는 구문인 것을 알 수 있다.

2) UPX1 섹션에 실제 구문을 복구하는 루틴
이후 진행을 하다 보면 위와 같이 실제로 UPX0 섹션에 실제로 데이터를 쓰기 시작하는 구문을 만나게 된다. 전체적인 구문을 봤을때 ESI 레지스터가 가르키는 주소에서 1 byte씩 읽어와 EDI가 가르키는 주소에 복사하는 구조이다.

최초 ESI 레지스터가 가르키는 곳에는 아래와 같은 값들이 있는 것을 볼 수 있으며 01011005 주소에서 부터 값을 읽어와 EDI 레지스터에 복사하는 것을 볼 수 있다.
                                          < ESI 레지스터가 가르키는 메모리에 저장된 값 >

EDI 레지스터가 가르키는 곳은 UPX0 섹션의 특정 주소로 0100136C부터 실제 구문(패킹되기 전 실제 구문)을 쓰기 시작하는 것을 볼 수 있다.
                                         < EDI 레지스터가 가르키는 메모리에 최초 저장된 값 >
최초에 EDI 레지스터가 가르키는 메모리의 주소에는 위와 같이 아무 값도 저장되어 있지 않는 것을 볼 수 있다. 위의 복구 구문이 모두 실행되고 난 후에는 아래와 같이 패킹되기 전 실제 구문들을 UPX0 섹션의 특정 주소에 푼 것을 볼 수 있다.
                           < 복구 구문 모두 실행 후 EDI 레지스터가 가르키는 메모리에 저장된 실제 구문 >

3) IAT(Import Address Table) 복구 구문
UPX0 섹션에 실제 코드를 복사한 뒤에 IAT를 복구해주는 구문을 만나게 된다.
EDI 레지스터가 가르키는 주소에서 특정 함수를 읽어 온뒤에 GetProcAddress 함수를 이용하여 함수의 주소를 읽어온뒤 EBX 레지스터가 가르키는 메모리 주소 공간에 저장을 하는 구문이다.

EDI 레지스터가 가르키는 메모리에 저장되어 있는 값을 보면 notepad.exe에 사용되는 함수들의 목록이 저장되어 있는 것을 알 수 있다.

GetProcAddress 함수가 호출되기 전에 스택에 Push되는 값을 보면 함수의 이름이 저장된 후 특정 값이 저장된 후 call 되는 것을 볼 수 있다. MSDN을 이용하여 GetProcAddress 함수의 구조를 보면 첫번째로 push된 값은 함수의 이름, 두번째로 push된 값은 DLL 모듈에 대한 핸들 값임을 확인할 수 있따. 리턴 값으로는 DLL의 export된 함수의 주소값을 읽어오는 것을 알 수 있다.

GetProcAddress 함수가 호출된 후에 EAX에 저장된 리턴 값(GetCurrentThreadId 함수의 주소)을 EBX 레지스터가 가르키는 주소(0100108C, UPX0섹션의 일부)에 복사하는 것을 볼 수 있으며, 이런 과정을 반복하면서 IAT를 복구하게 된다. 위 과정을 반복한 후에 UPX0섹션에 복구된 IAT 테이블을 보면 아래와 같다.

위와 같은 모든 original code 복구 과정을 마친 후에 JMP 구문을 통하여 OEP(Original Entry Point)로 JUMP하는 것을 볼 수 있다.


4. UPX 패킹 정리
전체적으로 정리해 보면 UPX로 패킹된 파일은 UPX1 섹션에 실제 코드를 복구하는 루틴이 저장되어 있으며, UPX0 섹션에 실제 코드와 IAT를 복구한 뒤에 OEP인 UPX0 섹션의 특정 구문으로 분기하여 실제 코드를 실행하는 것을 알 수 있다.

5. 결론
간단하게 생각한 UPX 패킹 방법이지만 실제로 많은 패킹 방법들이 UPX에서 사용된 방법들을 기초로 접근했을 경우 분석이 가능할 듯하다. 앞으로 더 많은 패킹 방법에 대해서 심도있는 스터디를 진행할 예정이다. To be continue..

                                                                                                    +---------------------------------+
                                                                                                    | Infinite Flow..                              |

                                                                                                    | mail : geekspark@gmail.com         |
                                                                                                    | Blog : http://sinun.tistory.com       |
                                                                                                    | twitter : @unpacker                      |
                                                                                                    | CISSP                                        |
                                                                                                    +----------------------------------+
저작자 표시 비영리 변경 금지
신고
Posted by By. PHR34K

티스토리 툴바