ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 20 인라인 패치 실습
    리버싱 엔지니어링/리버싱 핵심 원리 2022. 3. 30. 01:42

     인라인 패치 

    : 인라인 코드 패치(Inline Code Patch) 혹은 줄여서 인라인 패치(Inline Patch)라고 함

     

    • 원하는 코드를 직접 수정하기 어려울 때 간단히 코드 케이브(Code Cave)라고 하는 패치 코드를 삽입한 후 프로그램을 패치하는 기법
    • 주로 대상 프로그램이 실행 압축(또는 암호화)되어 있어 파일을 직접 수정하기 어려운 경우 많이 사용되는 기법

     

    인라인 코드 패치

    • Before : 전형적인 실행 압축(또는 암호화) 코드
      • EP 코드는 암호화된 OEP 코드를 복호화한 후 OEP 코드로 점프
      • 패치를 원하는 코드가 암호화된 OEP영역에 존재한다면, 그냥 패치시키기는 어려움 (엉뚱하게 복호화되기 때문)
    • After : 코드 케이브라고 하는 별도의 패치 코드를 설치하여, EP 코드의 복호화 과정 이후 JMP 명령어를 수정하여 코드 케이브가 실행되도록 함
      • 코드 케이브 내에 패치코드 실행 후 OEP로 이동 
      • 실행될 때마다 매번 프로세스 메모리의 코드를 패치하기 때문에 인라인 코드 패치라고 부름

     

    코드 패치와 인라인 패치의 차이점

      코드 패치(Before) 인라인 패치(After)
    대상 파일 파일 & 메모리
    횟수 1 파일에는 1번,
    메모리는 실행될 때마다
    방법 Direct(원하는 위치에 직접 패치) Indirect(코드 케이브를 미리 설치한 후 메모리에서 원하는 영역이 복화화되었을 때 패치)

     

     실습 - Patchme 

    : ap0x라는 리버서가 제작한 patchme 예시

     

    1. 실행

    • 표시 문자열 변경이 필요하다는 메시지 박스가 나타남

     

    2. 1번 메시지 박스 [확인]버튼

    • 다이얼로그 표시
    • 자신을 unpack하라는 문자열

     

    위 두개의 문자열을 변경하는 간단한 patchme 파일. 하지만, 문자열이 암호화되어 쉽게 바꿀 수 없음

     

     디버깅 ( 코드 흐름 살펴보기) 

    : OllyDbg 사용 

     

    1. EP 코드

    EP 코드

    • 401007 주소 이후로 암호화된 코드가 보임
    • 'Search for > All referenced text strings' 선택

    • 모든 문자열이 암호화 되어있음

    401001 주소의 CALL 명령의 함수(4010E9)를 따라 들어가 진행하면,

    • 위와 같은 복호화 루프 발견
    • 4010A3 주소의 XOR BYTE PTR DS:[EBX], 44 명령을 사용해 특정 영역에 XOR 명령으로 복호화 진행
      • 영역 : 4010F5~401248
        • EBX : 4010F5, ECX : 154
        • 4010F5~4010F5+154-1(401248)

    4010B0 주소의 CALL 함수(4010BD)를 따라가면,

    • 또 다른 2개의 복호화 루프 발견
    • 4010C8 주소의 XOR 명령에 의해 401007~401085 영역이 복호화
      • EBX : 401007, ECX : 7F
      • 401007~401007+7F-1(401085) 
    • 4010DB 주소의 XOR 명령에 의해 4010F5~401248 영역이 복호화
      • 복호화 되는 영역이 4010A3 주소와 동일한 영역 -> 이중 암호화
    • 4010DB 함수 호출이 완료되면,

     

    CALL 401039 명령을 만나게 되어 따라 들어가면,

    • 주소 401046에 있는 Checksum 계산 루프
      • 401041 주소의 MOV EDX,0 명령으로 EDX에 0을 대입(초기화)
      • 401046 주소의 ADD 명령으로 특정 주소 영역(4010F5~401248)에서 4바이트 단위로 순차적으로 값을 읽어들여 EDX 레지스터에 덧셈 연산으로 누적
      • 루프 종료 후 EDX 레지스터에 저장된 값이 Checksum 값
        • Checksum 계산 영역은 이중으로 암호화된 영역
        • 패치하려는 문자열이 존재할 것으로 예상됨
    • 401062~401068 주소의 CMP/JE 명령은 이렇게 계산한 Checksum 값이 31EB8DB0와 같다면, 401083 주소의 JMP 명령어에 의해 OEP(40121E)로 이동
      • 값이 다르면 에러메시지를 출력하고 프로그램이 종료됨

     

    OEP

    • 제대로된 코드가 나오지 않는다면 [Ctrl+a]

    • 다이얼로그를 실행시키는 코드
    • DlgProc : Dialog Box Procedure 주소 -> 4010F5
    • DlgProc 코드로 이동

    • 패치해야하는 문자열들 발견 (40110A, 401123)
    • 패치하려는 문자열은 이중으로 암호화 -> 인라인 패치 방법을 사용해 해결

     

     코드 구조 

    • [EP Code]는 [Decoding Code]를 호출하는 역할, 실제 [Decoding Code]에서 디코딩 작업이 이루어짐
    • [B] - [A] - [B] 순서로 디코딩(XOR), 암호가 해제된 [A] 영역 코드를 실행
    • [A] 영역 코드 내에서 [B] 영역의 Checksum을 구해 [B] 영역의 변경 여부를 판별
    • [C] 영역을 디코딩(XOR)한 다음 마지막으로 OEP(40121E)로 점프

     

     인라인 패치 실습 

     

    작업 순서

    ① 파일의 적절한 위치에 문자열을 패치시키는 코드 삽입

    ② [A]영역의 JMP OEP 명령을 JMP Patch Code로 수정 ([A] 영역 암호화 고려)

     

     패치 코드를 어디에 설치할까?

    1. 파일의 빈 영역에 설치

    2. 마지막 섹션을 확장한 후 설치

    3. 새로운 섹션을 추가한 후 설치

    → 보통 크기가 작은 경우 1번, 나머지 경우는 2 또는 3번 방법 사용

     

    1번 방법으로 시도

    1. PEView로 예제 파일의 첫번째 섹션(.text) 헤더 살펴보기

    • 파일 모습과 메모리에 로딩되었을 때의 모습

    • 첫번째 섹션의 Size of Raw Data는 400, Virtual Size는 280
      • 280 크기만 메모리에 로딩, 나머지 영역(680~800)은 쓰이지 않는 영역 = 빈 영역

     

    2. 빈 영역(Null-Padding 영역) Hex Editor로 확인

    • 이 곳에 패치 코드(코드 케이브) 설치

     

     패치 코드 만들기 

    디버깅하여 OEP로 이동

    • Assemble[Space] 명령과 Edit[Ctrl+E] 명령을 이용해 위와 같이 편집
    • "You must patch this NAG !!!" -> "ReverseCore"
    • "You must unpack me !!!" -> "Unpacked"
    • 변경 내용 저장 (Copy to executable > All modifications)

     

     패치 코드 실행 

    : 패치 코드(코드 케이브)가 실행되도록 파일을 직접 수정해야함

     

    401083 주소에 JMP OEP(0040121E) 명령어가 존재

    1. JMP Code Cave(401280)로  변경

    • 401083은 원래 암호화되어 있는 영역
      • [A] 영역에 속하며 XOR 7로 암호화 되어있음
      • 파일에서 암호화된 모습

    • 위 두 사진을 비교하면 'EE 91 06'이 XOR 7 복호화를 통해 'E9 96 01'로 바뀌는 것을 알 수 있음

    2. 명령어 수정

     

    3. 복호화 코드 수정

    • E9 XOR 7 = EE
    • F8 XOR 7 = FF
    • 01 XOR 7 = 06

     결과 확인 

    : 패치된 파일 실행

     

    댓글

Designed by Tistory.