728x90
  • Music_Player 

이 예제는 파일을 다운받아서 먼저 Readme 를 열어서 읽어 보니까 mp3 플레이어가 1분으로 제한되어 있는 것을 1분 이상으로 실행하도록 만드는 예제로 다운받은 파일에 MP3 Player 실행파일을 실행해서 아무 음원이나 넣었을 때, 1이 되었을 때 "1분 미리듣기만 가능합니다" 라는 메세지 창이 뜨게 된다.

 

 

 

디버거를 통해 메세지가 출력되는 곳을 찾아 jl문을 jmp 문으로 변경하는 것으로 1분이 지났을 때도 메세지가 출력되지 않겠금 하였다.

 

하지만 런 타임 에러...

런 타임 에러가 뜨는 이유는 프로그램을 잘못 짜거나, 특수한 상황을 고려하지 못한 경우가 발생하면 뜨게 된다. 수정한 부분 주변을 살펴 보았다.

 

 

살펴보니까  jge 부분에서 매 초가 지날 때마다 걸리는 예외 상황이 있었다. 비교 결과값이 0이거나 큰 경우에 에러 메세지를 내는 부분으로 넘어가는 것으로 보여 이러한 부분을 건너뛰게끔 jmp 명령어로 바꿔주었다.

 

jmp music_player.4046BF

 

다시 실행하니 1분이 지나서도 재생이 되는 것을 확인 할 수 있었다.

 

http://reversing.kr/challenge.php

 

Reversing.Kr

Copyright © 2012-2022 Gogil All Right Reserved.

reversing.kr

 

728x90

OEP 


OEP는 Orignal Entry Point로 EP는 엔트리 포인트이다.

엔트리 포인트는 운영체제가 사용자 프로그램으로 최초로 제어를 넘기는 지점으로 실행 코드가 최초로 실행되는 지점이다. 이런 OEP 를 찾는 방법은 여러 가지가 있다. 이러한 방법들에 대해 복습 겸 자세히 알아보고자 한다.

 

1. EP 값 찾기 

우선적으로 EP 값을 찾아야 한다. EP의 값은 AddresssOfEntryPoint 값과 ImageBase 값을 더하면 된다.

AddresssOfEntryPoint + ImageBase = EP

EP의 주소값을 찾아내면 그 주소에 EP를 설정한다.

 

2. 디코딩 루프

모든 패커에는 디코딩 루프(Decoding Loop)가 존재한다. 압축/해제 알고리즘 자체가 낳은 조건 분기와 루프로 구성되어 있다는 걸 알고 있다면 디코딩 루프가 왜 그리 복잡해 보이는지 이해할 수 있다.

이러한 디코딩 루프를 디버깅 할 때는 조건 분기를 적절히 건너 뛰어가며 루프를 탈출해야 한다. 경우에 따라서는 한 눈에 루프가 보이지 않을 수도 있다. 레지스터의 변화를 잘 포착하는 것이 중요하다.

 

 

3.  IAT 새팅

일반적인 패커에서는 디코딩 루프가 끝나면 원본 파일에 맞게 IAT를 새롭게 구성한다.

UPack이 임포트 하는 2개의 함수 LoadLibraryA와 GetProcAddress를 이용하여 루프를 돌면서 원본 notepad의 IAT를 구성한다. notepad에서 임포트 하는 함수들의 실제 메모리 주소를 얻어서 원본 IAT 영역에 쓰는 것이다.

 

 

OEP 지점을 찾는 데 있어서 몇 가지 팁이 되는 요소들이 있다.

 

먼저 일반적으로 Decode 루틴 진입 전에 PUSHAD 를 해서 기존의 레지스터들을 백업한다. 그 다음은 POPAD 를 이용해서 레지스터들을 복구한다. 이러한 점을 이용해서 Hardware Breakpoint 로 해당 Stack 에 접근 시도하는 부분을 찾은 다음에 근처에 JMP 명령, Call 명령, 또는  PUSH 주소 RET 형태의 명령들을 유심히 살펴보자.

 

두번째는 IAT 에 LoadLibrary, GetProcAddress, VirtualProtect 정도의 함수만 있다. ASProtect 의 경우에는 OEP 로 점프하는 부분 근처에서 GetSystemTime 함수를 호출하는데 이 함수에 BP 를 걸어서 실행하면 2번의 호출 후에 OEP 로 점프하는 부분이 있다.

 

마지막으로 OEP 에는 원래의 Code 가 실행될텐데, Stub Code 가 등장하고 main 또는 WinMain 함수가 호출된다. Stub Code GetVersion(Ex), GetCommandLine(A/W) 함수를 호출하는데 해당 함수를 호출하는 부분에서 OEP 를 찾아본다.

 



+ Recent posts