실행 압축

먼저 압축을 3가지 방식으로 나눠봅니다.

 

#1. 비손실 압축

- 압축된 파일을 100% 원래대로 복원할 수 있다. (무결성 보장)

 

#2. 손실 압축

- 원래대로 복원할 수 없다.

- jpg, mp4 등에 사용되며 의도적인 손상을 주어서 압축률을 높임 (사람은 식별안됌)

 

#3. 실행 압축

- PE 파일을 대상으로 하는 압축

- 파일 내부에 압축해제 코드를 포함하고 있어, 실행되는 순간에 메모리에서 압축을 해제 후 실행시키는 기술.

- PE 파일을 실행 압축 파일로 만들어 주는 유틸을 '패커'라고 함.

 

* 패커의 사용 목적 : 크기를 줄일 수도 있지만 파일 내부의 코드와 리소스를 보호.

 

PE 프로텍터 : 단순히 압축을 목적이 아닌 안티 리버싱을 위해 다양한 기법들로 코드및 리소스를 보호함

 

notepad.exe를 UPX 패커를 이용해 패킹을 진행해보자 !

 

[UPX 다운로드]

내가 쓸 notepad_upx.exe

notepad_upx.exe
0.05MB

PE Viewer로 비교해보자!

notepad.exe와 notepad_upx.exe

 

음... 뭔가가 변화가 있는것 같다. UPX의 첫번째 섹션을 열어보면,

 

Virtual Size의 값은 1만인데 Raw Data Size값이 0이다.

이게 무슨 일이냐면 압축된 원본코드와 해제코드는 지금 섹션2에 존재합니다. 그런데 실행하게 될경우 이게 섹션 1에 해제 되어지는 것입니더.

 

그럼 디버깅!

 

notepad_upx.exe 디버깅

목표 : 코드를 하나씩 트레이싱 하면서 원본 코드를 찾아보za

 

먼저 원본코드의 구조를 확인하기 위해 원본파일인 notepad.exe를 열어보자.

 

먼저 010073B2의 주소에서 GetModuleHandleA() 함수를 호출해서 notepad.exe의 ImageBase를 구한다.

그 후에 010073B4와 010073C0에서 각각 MZ와 PE 시그니처를 비교합니다. 

 

이제 notepad_upx.exe를 열어보자!

 

짜짱!

01015330이 EP 주소입니다. 여기는 2번째 섹션의 끝부분 주소입니다. 실제 원본코드는 이 주소 위로 존재합니다.

하나씩 살펴볼까요 ~

 

먼저 PUSHAD를 통해 EAX~EDI 레지스터 값을 스택에 저장하고,

ESI, EDI레지스터를 각각 두 번째와 첫 번째 섹션의 시작주소로 설정합니다. (0101100, 01001000)

- 이렇게 esi와 edi가 동시에 세팅되면 esi -> edi 로 메모리 복사가 일어날 거라 추측.

esi에서 데이터를 읽어서 압축을 해제한 후 edi에 저장.

 

그럼 트레이싱을 시작하자 트레이싱 단축키! (* 루프를 만나면 루프를 확인하고 넘어간다)

- 총 4개의 루프를 만날 예정

[Ctrl + F8]을 누르면 정신없이 트레이싱이 시작되다가 어떤 짧은 루프(#1) 안에 갖히게된다 그부분에서 [F12]를 눌러서 해당 루프를 자세히 봐야한다

.

 

루프를 돌려보면 ECX는 회전마다 1씩감소하고 EDX와 EDI는 1씩 증가하는걸 볼 수있다. EDX에서 한바이트를 읽어서 EDI에 쓰고 있는 중이다. (ctrl+F8을 돌려 살펴보라!)

 

010153E6에 Bp를 걸고 루프를 탈출한 뒤 다시 트레이싱을 실행해보자.

그러다보면 2번째 커다란 루프를 만날 수 있다.

 

#2. decoding 루프.

-> 압축 해제 루프

두 번째 섹션 주소에서 차례대로 값을 읽어 첫 번째 섹션으로 값을 옮겨 써주는 작업 중...

ESI가 가르키는 두 번째 섹션(UPX1)의 주소에서 차례대로 값을 읽어서 적절한 연산을 거쳐 압축을 해제하며 EDI가 가리키는 첫 번째 섹션(UPX0)에 주소에 값을 써주는 과정입니다.

 

...

...

 

* AL(EAX)에는 압축해제된 데이터, EDI는 첫 번째 섹션의 주소

 

=> al은 1바이트라 inc 1씩 증가시켜 다음 주소를 가르키고 eax는 4바이트라서 add로 4바이트 증가시킨 경우이다.

뭔지 몰랐다능 ... 까묵

NULl이었던 UPX0 영역(01007000)에 데이터가 채워진 모습

그렇게 두 번째 루프를 지나기 위해 01015402에 BP를 걸고 다음 트레이싱을 진행합니다.

바로 밑에서 세 번째 루프를 발견할 수 있습니다.

이 부분은 원본 코드의 CALL/JMP 명령어의 주소를 복원시켜주는 코드라고 합니다. 그냥 알고 넘어가면 대나...

jne는 not equal, cmp 비교시 같지않으면 ZF는 0을 반환합니다.

 

이제 IAT 셋팅만 하면 UPX 압축해제 코드가 끝이나게 됩니다. 다시 트레이싱을 해봅시다.

마지막 루프 입니다! 이 부분이 IAT를 셋팅하는 루프입니다. 01015436 주소에서 EDI=01014000으로 세팅되며, 이곳은 두번째 섹션(UPX1) 영역입니다. 이곳에 원본 notepad.exe에서 사용되는 API 이름 문자열이 저장되어 있습니다.

 

 

 

'Reversing' 카테고리의 다른 글

리버싱 9  (0) 2019.04.10
리버싱 8  (0) 2019.04.09
리버싱 6  (2) 2019.04.04
PE file(3)  (0) 2019.04.03
PE File(2)  (0) 2019.04.03

+ Recent posts