실행압축 (Packing)
실행되는 순간 메모리에서 압축을 해제하고 실행을 시키는 기술이기에,
어딘가에 압축 해제 루틴이 담겨있어서, 이런 루틴을 지난 후에 실행시킨다는 게 특징이다.
이런 패킹을 사용하는 목적은 아래라고 생각합니다.
1. 파일 자체의 크기를 줄이기 위함
2. 내부 코드와 리소스등을 사용자가 보지 못하게 방해하는 것.
3. 분석을 하지 않게 귀차니즘을 넘겨주기 위해
이라고 볼 수 있습니다.
UPX Packing
먼저 보기 전에 UPX 패킹이 이루어지고 난 뒤에 PE가 어떻게 변경되는지 보도록 하겠습니다.
앗, 딱 봐도 IMAGE_SECTION_HEADER, SECTION 들이 UPX0, UPX1 들로 압축된 것을 볼 수 있습니다.
또 UPX0 SECTION의 RawDataSize를 보면 0으로 되있는 것을 볼 수 있으므로,
파일 내에 존재하지 않는 것을 볼 수 있습니다.
하지만 UPX0 SECTION의 Virtual Size를 보면 알 수 있습니다.
실제 파일에서의 사이즈는 0으로 되어있는데 메모리에서의 사이즈는 큰 것을 볼 수 있습니다.
그렇다면 이유는 압축 해제 코드와 압축된 원본 코드들은 UPX1 SECTION에 존재하다는 것을 예상할 수 있습니다.
그렇다면 파일이 실행이 되면 원본코드는 UPX0 섹션에 해제시킨다는 것을 예상할 수 있겠네요 (웃음)
Analyze
PUSHAD
POPAD
PUSHAD 명령어의 반대로 스택에 넣은 CPU 레지스터 값들을 CPU 레지스터로 복귀시키는 명령어입니다.
처음 실행될 때에 PUSHAD로 CPU 레지스터 들의 값들을 스택에 집어넣는 것을 볼 수 있습니다.
스택에 들어간 것을 볼 수 있습니다.
EAX~EDI의 값들이 순서대로 스택에 들어간 것을 볼 수 있습니다.
그 후에 ESI에 UPX1 시작 주소를 넘겨주어 세팅을 합니다.
EDI에는 0x001CE000(UPX1) + 0xFFFFFFFFFFFE3000 = 0x1B1000(UPX0)
(이 뒤에서 주소가 갑자기 바뀌는데... 디버거가 한번 팅겨서 주소가 달라진 것이니 착각하지마시길 바랍니다!)
아무튼 UPX0의 주소를 스택에 넣고 이제 점프합니다.
EBX에 [UPX1] 주소에 담긴 값을 저장합니다.
그리고 ESI, EDI 레지스터에는 위의 사진과 같이 세팅이 되어있는데.
0x41e000과 0x401000은 UPX1(.data) 주소와 0x401000(.text)주소입니다.
맞는 것을 볼 수 있습니다.
[EDX]에서 값을 가져와서 AL에 쳐박고
EDI(UPX0)에 복사함을 알 수 있습니다.
FFF2만큼 UPX0에 0으로 초기화하는 부분임을 알 수 있습니다.
이 뒤의 0x40370F주소 이후에 IMAGE_SECTION_HEADER를 채우게 됩니다.
ESI가 가르키는 곳에 있는 값을 EDI에 값들을 복사하는 것을 볼 수 있습니다.
그리고 EDX의 값을 가져와서 EDI에 쑤컹쑤컹하는 것을 볼 수 있습니다.
그리고 이 부분이 압축 해제 루프입니다.
그 뒤로는 IAT 세팅입니다.
퍄퍄 이 곳에서 하나하나 이동시키는 것을 볼 수 있습니다!
그 뒤에 스택에 EAX~EBP까지 PUSH한 후 POPAD를 하는 모습입니다.
POPAD를 한 후의 CPU 레지스터의 상태입니다.
모든 압축 해제 과정이 끝나게 되면 OEP로 점프를 하게 됩니다.
넵!
실제로 패킹 안한 프로그램을 열어보면 같음을 확인할 수 있습니다.
그렇다면 하나의 꼼수를 알아내자면 UPX 패킹일 경우에는 그저 POPAD를 찾아서 그 뒤에 있는 JMP 주소가 oep라는 것을 알 수 있습니다. (웃음)
'0x30 Study > 0x31 Reverse Lab' 카테고리의 다른 글
[Reverse Lab 스터디] Ada Cracked(0) (1) | 2016.08.10 |
---|---|
[Reverse Lab 스터디] DLL Injection (0) | 2016.08.10 |