20장 인라인 패치 실습
인라인 패치 (inline patch)
- 원하는 코드를 직접 수정하기 어려울 때 간단히 코드 케이브 (code cave) 라고 하는 패치 코드는 삽입한 후 실행해 프로그램을 패치시키는 기법
- 실행 압축되거나 암호화되어 파일을 직접 수정하기 어려운 경우, 파일을 패치할 때 자주 사용된다.
- 패치하기 원하는 코드가 암호화된 OEP영역에 존재하면 패치시키기 어렵다
- → 파일 내 코드 케이브라고 한느 별도의 패치코드를 설치한 후 EP 코드의 복호화 과정 이후 JMP 명령어를 수정해 코드 케이브가 실행되도록 한다
- 코드 케이브 내에 패치 코드를 실행 후 (이미 OEP코드가 복호화 되었기 때문에 그대로 수정 가능) OEP로 가면됨
- 즉, 실행될 때마다 (별도의 패치코드를 실행해) 매번 프로세스 메모리의 코드를 패치함
코드 패치 | 인라인 패치 | |
대상 | 파일 | 파일 & 메모리 |
횟수 | 1번 | 파일에는 1번만, 메모리는 실행될 때마다 |
방법 | Direct (원하는 위치에 직접 패치) | Indirect (코드 케이브를 미리 설치한 후 메모리에서 원하는 영역이 복호화되었을 때 패치) |
실습 - Patchme
EP 코드
- 복호화 루프1 (0x44로 0x154번 4010F5~401248을 XOR명령으로 복호화)
- 복호화 루프2 (0x7로 0x7F번 401007~401085을 XOR 명령으로 복호화)
- 복호화 루프3 (0x11로 0x154번 4010F5~401248을 XOR 명령으로 복호화)
- CheckSum 계산 루프를 보면 4010F5~401248에서 4바이트단위로 순차적으로 값을 읽어 add연산으로 누적시킨다.
- Checksum : 특정 영역의 코드/데이터가 변조되지 않았음을 검증하는 용도로 많이사용한다.
- CheckSum 값이 31EB8DB0 과 같다면 (코드가 변조되지않았다면), OEP로 jump한다
- 다르다면 에러메세지 출력하고 프로그램이 종료된다.
- Checksum : 특정 영역의 코드/데이터가 변조되지 않았음을 검증하는 용도로 많이사용한다.
- 40123E 주소를 보면 다이얼로그를 실행시키는 코드가 함수 명령이 있다. 그리고 40122C 주소를 보면 DIgProc 주소가 4010F5라는 것을 알 수 있다.
40110A, 401123을 패치해야함을 알 수 있다.
코드 구조
- A,B,C영역은 암호화된 코드이며, EP code와 decoding code 영역에는 암호화를 해제하는 복호화 코드가 존재
//대략적인 코드 흐름
[EP Code] // 단순히 Decoding Code 호출 역할
[Decoding Code] // 디코딩 작업
XOR [B] with 44 // [B] - [A] - [B] 순서로 XOR
XOR [A} with 7
XOR [C] with 11
[A] // 암호화 해제된 [A] 영역 코드 실행
Checksum [B] // 변경 여부 판단
XOR [C] with 17
JMP OEP // OEP 로 점프
인라인 패치 실습
- 이중으로 암호화된 [B] 영역을 패치시켜야하고, checksum을 따로 구해야하므로 수정이 어려움
- → 인라인 패치 해보자.
1. 파일의 적절한 위치에 문자열을 패치하는 코드 삽입
2. [A]의 JMP OEP 명령을 JMP Patch Code로 수정
3. JMP PatchCode를 만나면(이미 모든코드는 복호화가 되어있고 Checksum을 통과했기 떄문에) 패치코드에서 문자열을 변경한 후 OEP로 JMP하면 됨.
패치코드 위치?
- 파일의 빈 영역에 설치 (크기 작을 때)
- 마지막 섹션 확장한 후 설치 (크기 클 때, 권장)
- 새로운 섹션 추가한 후 설치 (크기가 클 때)
- 첫번째 섹션의 size of raw data는 400이고, virrtual size는 280이다.
- 크기는 400이지만, 여기서는 280크기만 메모리에 로딩된다
- 680~800 쓰이지않음 (NULL Padding)
- 크기는 400이지만, 여기서는 280크기만 메모리에 로딩된다
- 빈영역의 file offset : 680~800
- VA 로 변환 : 401280~401400
- Assemble 의 space , Edit의Ctrl+E 로 편집해준다.
- Copy to executable - All modifications 명령으로 저장
패치코드 실행하기
- JMP OEP를 JMP CodeCave(401280)으로 변경
- JMP 명령문의 instruction : E9 F8010000
- 그대로 쓰는게 아니라 복호화를 고려해 xor7 수행 후 써야함
- E9 → EE
- F8 → FF
- 01 → 06
- 그대로 쓰는게 아니라 복호화를 고려해 xor7 수행 후 써야함
- JMP 명령문의 instruction : E9 F8010000
'Rev' 카테고리의 다른 글
dungeon-in-1983 (0) | 2025.01.03 |
---|---|
리버싱 핵심원리 21장 ~ 23장 (0) | 2024.11.04 |
리버싱 핵심원리 16장 (0) | 2024.09.28 |
리버싱 핵심원리 2부 (0) | 2024.09.23 |
KnockOn Bootcamp ROP (0) | 2024.09.18 |