디버깅 전 이 부분은 PEView를 잘 활용해야 한다. UPX 실행 압축된 PE File의 특징을 말하자면
- UPX0 (첫번째 섹션) 은 RawDataSize가 0이다. 나중에 압축 해제된 코드들이 들어갈 자리이다.
- UPX1 (두번째 섹션) 에는 압축된 코드와 압축해제 코드가 들어가있다.
1. notepad.exe
010073B4에서 Dos Signature와 비교함 (5A4D = Dos Signature)
010073C0에서 NT_Header Signautre와 비교함 (5045 = NT_Header Signature)
EP는 0100739D
2. 디버깅 목적
원본 코드의 EP 즉, OEP(Original Entry Point)를 notepad_upx에서 찾는것
3. UPX 파일 트레이싱
압축해제 과정은 무수히 많은 루프의 연속이다.
그렇기 때문에 Ctrl+F8(Step over 연속 반복)을 이용하여 반복문이 나올때 마다 F7로 멈춰 확인해 준다.
Loop #1
ECX(회전 수)가 36B인 루프이다.
루프 내용은 EDX에서 한 바이트씩 읽어 EDI에 쓰는 것이다.
Loop #2
디코딩 루프이다.
ESI가 가리키는 UPX1의 주소에서 차례대로 값을 읽어 EDI가 가리키는 UPX0의 주소에 값을 써줌
#Loop3
원본 코드의 CALL/JMP 명령어의 destination 주소를 복원 시켜주는 코드이다.
#Loop4
IAT를 세팅하는 루프이다.
EBX가 가리키는 원본 notepad.exe IAT영역에 API주소를 입력한다.
API이름 문자열이 모두 입력되면 IAT 복원 과정이 마무리된다.
IAT 복원 과정이 모두 마무리되면 010154BB의 JMP코드로 인해 OEP로 간다.
POPAD는 PUSHAD에 대응되는 명령어로 모든 레지스터를 원래대로 복원시킨다.
4. UPX OEP 빨리 찾는법
#1. POPAD 근처의 JMP를 찾는다.
UPX패커의 특징중 하나는 OEP코드로 가는 JMP명령어가 POPAD 이후에 나타난다.
#2. 스택에 하드웨어 브레이크 포인트
PUSHAD(모든 레지스터를 스택에 넣음) 명령어 이후 Dump창에서 스택 맨 위의 주소값으로 간다.
그다음 정확히 DFF58위치에 하드웨어 bp를 건다.
[BreakPoint -> Hardware, on access -> byte]
그다음 실행시키면 POPAD가 호출된 순간에 BP가 설정된 주소를 엑세스하고 그때 제어가 멈춘다.
그다음에 나타나는 JMP 코드를 찾으면 OEP를 쉽게 얻을 수 있다.
'Reversing > Information' 카테고리의 다른 글
CF(Carry Flag)와 OF(Overflow) 차이 (0) | 2024.03.25 |
---|---|
실행 압축 (0) | 2024.02.01 |
범용 레지스터 역할 (0) | 2024.02.01 |
PE header 구조 (0) | 2023.12.30 |
TEST 어셈블리 명령어 (0) | 2023.12.21 |