본문 바로가기

REVERSING

[SWING] Reversing 05

 

UPX 실행 압축된 노트패트 디버깅

 

UPX 실행 압축된 notepad_upx.exe를 디버깅하여 실행압축에 대한 개념을 이해하는 것이 목표이다. 즉, 코드를 트레이싱하면서 원본 notepad.exe 코드를 찾아내는 것이라고 할 수 있다.

 

https://github.com/upx/upx/releases

 

위의 링크에서 upx-3.96-win64.zip 을 다운받는다.

 

 

 

 

코드 트레이싱 명령

 

 

 

위의 것이 원본 EP 코드이고 아래의 것이 실행 압축된 메모장의 EP 코드이다.

 

 

 

Notepad_upx.exe를 디버거로 열어보면 위와 같이 UPX EP 코드가 나타난다. 

 

UPX 파일 트레이싱을 해볼 것인데, 이때 루프(Loop)를 만나면 그 역할을 살펴본 후 탈출한다 라는 방대한 코드에 대한 원칙이 있다고 한다. 압축 해제 과정은 무수히 많은 루프의 연속임으로, 적절히 루프를 탈출할 줄 알아야 한다. 방대한 코드를 트레이싱 할 때는 일반적인 Step Into(F7)을 사용하지 않고, 디버거에서 별도로 제공되는 명령을 사용한다.

 

Animate Into(Ctrl+F7) : Step Into 명령 반복 (화면 표시 O)

Animate Over(Ctrl+F8): Step Over 명령 반복 (화면 표시 O)

Trace Into(Ctrl+F11): Step Into 명령 반복 (화면 표시 X)

Trace Over(Ctrl+F12): Step Over 명령 반복 (화면 표시 X)

 

애니메이트 명령어와 트레이스 명령어로 나뉘는데, 애니메이트 명령어는 트레이싱 과정이 화면이 표시되기 때문에 속도가 느리다는 점이 있다. 트레이스 명령어는 미리 설정한 트레이스 조건에서 자동으로 멈출 수 있고, 로그를 남길 수도 있다는 장점이 있다. 이번 UPX 파일 트레이싱에서는 Animate Over(Ctrl+F8)을 사용할 것이다.

 

 

EP 코드에서 Animate Over(Ctrl+F8)을 누르면 트레이싱이 시작되면서, 커서가 계속 루프를 돌 것 이다. 조금 진행하다 보면 짧은 루프가 나타나는데, Step Into(F7)을 눌러 트레이스를 멈추고 해당 루프를 살펴보자.

 

 

첫번째 루프문

 

위에 보이는 사진의 범위를 계속해서 반복한다. 루프의 내용을 보면, EDX(01001000)에서 한 바이트를 읽어 EDI에 쓰는 것이다. EDI가 가리키는 01001000의 주소는 첫 번째 섹션(UPX0)의 시작 주소이며, 메모리에서만 존재하는 섹션이다.

 

 

이러한 루프를 빠져 나오기 위해서 반복문의 마지막줄 아래에 Break Point(F2)를 설정해주고, 실행명령(F9)를 이용해 탈출한다.

 

 

두번째 루프문

 

 

 

두번째 루프문은 이전보다 꽤 길다. 두번째 루프가 본격적인 디코딩 루프, 또는 압축해제 루프라고 할 수 있다. ESI가 가리키는 두번째 섹션의 주소에서 차례대로 값을 읽어서 적절한 연산을 거쳐 압축을 해제하여, EDI가 가리키는 첫번째 섹션의 주소에 값을 써주는 형식으로 돌아가고 있다. 위에서 AL(EAX)에는 압축 해제된 데이터가 있고, EDI는 첫번째 섹션의 주소를 가리키고 있다.

 

세번째 루프문

 

 

또다시 Ctrl+F8을 사용해 트레이싱을 시작하면 위와 같은 세번째 루프를 만날 수 있다. 이 루프는 원본 코드의 CALL/JMP 명령어의 destination 주소를 복원시켜주는 코드이다. 반복되는 구간은 010153FA 부터 01015401 까지인듯 하다. 0105426주소에 BP를 걸어주고 탈출하면 된다.

 

네번째 루프문

 

 

반복되는 구간은 위와 같지만 중요한 구간은 아래와 같다.

 

 

더 내려가다 보면 위와 같은 네번째 루프가 나타난다. 이 부분이 바로 IAT를 세팅하는 루프이다. 일반적인 실행 압축 파일은 원본 파일의 코드, 데이터 ,리소스의 압축 해제 과정이 끝나면 IAT를 세팅하고 OEP로 간다. 01015426 주소에서 EDI 01014000으로 세팅되고, 이곳이 두번째 섹션영역이다.

 

 

마지막에 0100739D는 처음에 UPX 실행 압축하기 전의 PUSH 70 의 코드와 같다.

 

 

UPX OEP를 빨리 찾는 방법

1. POPAD 명령어 이후의 JMP 명령어에 BP 설치

UPX 패커의 특징 중 하나는 EP 코드가 PUSHAD/POPAD 명령어로 둘러싸여 있다는 것이다. 여기서 PUSHAD 8개의 범용 레지스터의 값을 스택에 저장하는 명령어이고, POPAD PUSHAD 명령에 의해서 스택에 저자된 값을 다시 각 레지스터들에게 입력하는 명령어이다. OEP코드로 가는 JMP 명령어가 POPAD 명령어 바로 이후에 나타나기에,  JMP명령어에 BP를 설치하고 실행하면 바로 OEP로 갈 수 있다.


2. 
스택에 하드웨어 브레이크포인트 설치

이 방법도 PUSHAD/POPAD의 특성을 이용하는 것이다. 하드웨어 BP CPU에서 지원하는 브레이크 포인터로, 4개까지 설치 가능하며, 일반적인 BP와는 다르게 BP 설치된 명령어가 실행된 이후에 제어가 멈추게 된다.

 

 

'REVERSING' 카테고리의 다른 글

[SWING] Reversing 07  (0) 2023.04.02
[SWING] Reversing 06  (0) 2023.03.26
[SWING] Reversing 04  (0) 2022.08.22
[SWING] Reversing 03  (0) 2022.08.13
[SWING] Reversing 02  (0) 2022.08.06