ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Lenas Reversing for Newbies] 15
    Wargame/Lenas Reversing 2021. 2. 26. 21:41

    1. 프로그램 실행

    첨부된 프로그램을 실행하면 다음과 같은 창이 나타난다.

     

    실행화면 1

     

    Windows 10에서는 글자가 잘리는데 XP에서 실행하면 "I'm the starting nag. Remove me"라는 문자열이 보인다. 잠시 기다리면 다음과 같은 창이 나타난다.

     

    실행화면 2

    이번 문제의 목표가 나타나 있다. Exit 버튼을 눌러보자.

     

    실행화면 3

    위와 같은 창이 나타난 후 잠시 뒤에 프로그램이 종료된다. 이번 실습의 목표는 메인 창(실행화면 2) 앞 뒤로 나타나는 nag window가 나타나지 않게끔 패치하는 것이다.

     

    2. Debugging(with OllyDbg)

    파일을 열고, F9로 실행한 후, 앞의 nag window가 나타나자마자 OllyDbg로 pause를 한 후 call stack을 살펴보자.

     

    디버깅

    파란색 체크 표시한 부분에서 ReverseM 모듈에서 함수가 호출되었음을 확인할 수 있다. 해당 부분으로 이동해보자.

     

    디버깅

    아래쪽 체크표시 부분이 call stack에 기록된 부분인데 위쪽 체크표시한 부분에 conditional jump 가 있는 것을 확인할 수 있다. 해당 부분에 BP를 설정하고 프로그램을 다시 실행시켜보자.

     

    디버깅

    위와 같이 BP에 적중하고 점프가 일어나지 않는 것을 확인할 수 있다. 위 지점부터 F8로 한 줄씩 트레이싱하다 보면 0042039A 주소의 CALL <JMP.&MFC42.#2514> 명령을 실행한 후 nag 창이 나타나는 것을 확인할 수 있다. F9를 눌러 프로그램을 실행시키면 마찬가지로 BP에 적중하고, 0042039A 주소의 명령어가 실행된 후 메인 윈도우가 나타난다. Exit 버튼을 눌러 프로그램을 종료할 때도 마찬가지이다. 00420379 주소의 conditional jump 명령어를 무조건 점프하도록 패치할 경우 메인윈도우가 나타나지 않게 되는 문제점이 발생한다.

     

    해당 지점을 지나칠 때마다 언제 지났는지에 대한 조건을 data 영역의 변수에 설정한 후, 해당 변수를 참조하여 점프할지 말지를 결정하도록 하는 방법을 생각해볼 수 있다. Lenas 강의에서는 variable pointer를 이용한 inline patching 방법이라고 기술하고 있다. 00420379 주소에 BP를 설정한 후, F9를 눌렀을 때, 프로세스가 종료되기까지 총 3번 지나쳐간다. 

     

    첫 번째 - nag window 생성 직전

    두 번째 - 메인 window 생성 직전

    세 번째 - nag window 생성 직전

     

    두 번째의 경우 conditional jump 명령어에서 점프를 하지 않게 함으로써 메인 window가 나타나야 하지만, 나머지 경우 점프를 하게끔 코드를 수정해야 한다. 우선 몇 번째로 BP를 지나치는지를 참조할 변수를 설정하기 위해서 data section의 끝부분에 적당한 지점을 찾아 주소를 기억하자.

     

    디버깅

    위와 같이 00445E80 주소의 BYTE에 BP 지점을 지날 때마다 INC 명령어를 통해 값을 증가시키면서 2가 아닌 경우 점프하도록 코드를 작성하면 된다. 그전에 00445E80이 프로그램 실행 도중 사용되는 공간인지 검증하기 위해 hardware BP를 설정하고 프로그램이 종료할 때까지 실행해보자.

     

    검증이 끝났으면 다시 BP를 설정했던 지점으로 돌아가 보자.

     

    디버깅

    BP를 설정한 conditional jump 명령어는 2byte를 차지하므로 INC 명령어, 비교를 위한 CMP 명령어 등을 작성하기에는 부족해 보인다. code cave를 활용한 inline patching 방법을 적용해보자. code cave를 작성할 부분을 .text 섹션 끝부분에서 찾아보자.

     

    디버깅

    00437D65에 코드를 작성해보겠다. 우선은 앞서 BP를 설정한 00420379의 conditional jump 명령어를 jmp 00437D65로 수정한 후, 다음과 같이 코드를 작성하자.

     

    코드 작성

    한 줄씩 의미를 해석하면 다음과 같다.

     

    INC BYTE PTR DS:[445E80]

    => 몇 번째 해당 지점을 지나는지 counter 변수 증가

    CMP BYTE PTR DS:[445E80], 2

    => 2번째 지나는 것인지 판단

    JNZ ReverseM.004203BA

    => 2번째가 아니라면 앞서 언급한 윈도우 생성 관련 함수들이 호출되지 않아야 하므로, 기존 conditional jump 명령어에 의해 점프하는 곳으로 점프

    LEA ECX, DWORD PTR SS:[ESP+4C]

    => (코드를 패치하면서 잘린 뒷 명령어를 그대로 복사)

    JMP ReverseM.0042037F

    => code cave 내부의 모든 코드 수행 후 원래 위치로 복귀

     

    이때 counter 변수는 기존에 hardware BP를 통해 검증한 data section의 빈 공간을 가리킨다. 이와 같이 패치하고 파일을 저장한 후 실행하면, 앞 뒤로 nag window가 사라진 것을 확인할 수 있다.

     

    3. Comment

    Lenas Reversing 14 문제의 연장이라고 보면 될 듯하다. 특정 조건을 설정하기 위해 data section 영역을 활용하는 점과, 해당 지점을 활용해도 되는지를 hardware BP를 통해 검증하는 과정까지 배울 수 있었다.

     

    반응형

    'Wargame > Lenas Reversing' 카테고리의 다른 글

    [Lenas Reversing for Newbies] 16  (0) 2021.03.08
    [Lenas Reversing for Newbies] 14  (0) 2021.02.23
    [Lenas Reversing for Newbies] 13  (0) 2021.02.20
    [Lenas Reversing for Newbies] 12  (0) 2021.02.18
    [Lenas Reversing for Newbies] 11  (0) 2021.02.09

    댓글

Designed by Tistory.