Lena's Reversing Tutorial 01

beanii·2023년 11월 4일

Reversing

목록 보기
1/1
post-thumbnail

🔎 OllyDbg 설치



🔎 OllyDbg 단축키


  • Run (F9) : 프로그램 실행 (Break Point까지 실행)
  • Break Pint (F2) : Break Point 설정/해제
  • Step into (F7) : 한줄씩 실행(함수 진입 O)
  • Step over (F8) : 한줄씩 실행(함수 진입 X)
  • Execute till return (Ctrl+F9) : RETN 명령어가 나올때까지 실행
  • Restart (Ctrl+F2) : 프로그램 재실행
  • Go To (Ctrl+G) : 입력한 주소로 이동

🚀 Tutorial 01


Lena's Reversing Tutorial 시리즈는 리버싱 입문을 위한 문제들이다.
총 40문제가 있다. 앞으로 1번부터 차근차근 풀어보려고 한다.
(문제 다운로드)

1번 문제인 reverseMe.exe 파일을 실행하면 다음과 같이 라이센스를 새로 구입하라는 메시지가 뜬다.
-> 1번 문제 풀이의 목적은 라이센스가 있는 척 해당 오류를 우회하여 이 메시지가 아닌 성공 메시지가 뜨도록 하는 것이다.

OllyDbg로 1번 문제를 열고, 단축키 F8를 사용해서 한줄씩 실행한다.

초반에 호출되는 GetModuleHandleA 함수나 이미지 관련 함수인 LoadIconALoadCursorA 는 문제 푸는데 있어 크게 중요하지 않기 때문에 자세한 설명은 넘어가고, 중요한 부분만 부분적으로 문제 푸는 흐름대로 정리하도록 하겠다.

주로 주목해야 될 명령어는 함수를 호출하는 CALL 이나 값을 비교하는 CMP, 주소를 이동하는 JMP(JE, JZ, JNZ) 등이다.


1. CreateFileA

우리가 봐야 할 함수는 CreateFileA 함수이다.
왜냐하면 해당 함수가 실행 된 이후 CMP와 JNZ 명령어가 있기 때문에 이 함수의 실행결과가 중요할 것이라는 예상을 할 수 있다.

CreateFileA 함수에 대해 조금 더 찾아보면, 다음과 같은 매개변수를 받아서 파일을 생성 또는 open한다는 것을 알 수 있다.

문제를 다시 보면 Keyfile.dat이라는 이름의 파일이 존재하는 경우 이 파일을 열려고 하는데, 우리는 이런 이름의 파일을 가지고 있지 않으므로 해당 함수를 오류가 발생할 것이다.

함수의 리턴값을 알아보면, 함수가 실패했을 경우 INVALID_HANDLE_VALUE가 반환된다고 한다. 이 값은 -1 (FFFFFFFF) 이다.

함수에 대한 리턴값은 EAX에 저장되는데,
실제로 함수 실행 후 EAX가 FFFFFFFF로 채워진 모습을 볼 수 있다.

여기까지가 00401073 CALL <JMP.&KERNEL32.CreateFileA> 까지에 대한 설명이다.


2. CMP, JNZ

CMP 명령어는 비교하는 두 값이 같다면 ZF(Zero Flag)에 1이 저장되고, 다르면 0이 저장된다.

JNZ 명령어는 ZF=0일 때 해당 주소 값으로 분기한다.

위의 두 가지 개념을 알고 004010780040107B 이 두 줄을 살펴보자.

EAX(함수의 리턴값)와 -1(에러 발생)을 비교해서
1) 에러가 발생하지 않은 경우(EAX가 -1이 아닌 경우)에는 ZF=0을 만족하기 때문에 40109A 주소 값으로 분기하며,
2) 에러가 발생한 경우(EAX가 -1인 경우)에는 ZF=1이기 때문에 바로 다음 줄인 40107D 주소 값으로 분기된다.

-> 문제에서는 Keyfile.dat 파일이 존재하지 않아 에러가 발생하여 EAX 값이 -1이므로 2)에 해당하여 40107D 주소 값으로 분기하게 된다.

⛔ 그러나 40107D로 이동하면 결국 ExitProcess 함수를 실행하게 되어 라이센스를 새로 구입하라는 메시지와 함께 프로그램이 끝나버린다.

🌟 즉, 우리는 40107D 이 아니라 40109A 주소로 이동하도록 강제로 바꿔야한다.

우리가 40107D로 이동했던 이유는 위에서 JNZ로 인해 ZF가 0인지 1인지 조건을 따졌기 때문이다.
그럼 조건을 따지지 않고 40109A로 가려면 어떻게 해야할까?

아래 사진과 같이 0040107B에서 JNZJMP로 바꿔주면 된다!

그럼 이제 프로그램이 끝나지 않고 40109A로 이동하게 된다.

여기까지가 0040107B JMP SHORT reverseM.0040109A(수정 후 모습)까지에 대한 설명이다.


3. CMP, JMP(JE, JNZ, JL)의 반복

이제부터는 위에서 봤던 2번 내용의 반복이다.
그러나 JNZ 뿐만 아니라 다양한 JMP 관련 명령어가 나오니 한번 정리하고 넘어가려고 한다.

명령어명령어의 의미명령어가 수행되기 위한 조건
JMPJumpx(무조건 점프)
JEJump if equalZF=1
JNZJump if not equalZF=0
JLJump if (signed) lessSF!=OF

이제 다시 40109A부터 살펴보자.

ReadFile 함수가 실행되고, 실행결과가 EAX에 담긴다.

ReadFile 함수는 앞서 CreateFileA 함수에서 참조한 Keyfile.dat 파일의 문자열을 일거오는 함수지만, 마찬가지로 해당 파일이 존재하지 않기 때문에 오류가 발생한다.
-> EAX는 0(FALSE)이 된다. (아래 사진 참고)

그 다음 줄에서 TEST EAX, EAX는 EAX의 값이 0인지 아닌지를 확인하는 명령어라고 생각하면 된다. (TEST 명령어 중에서도 특별하게 사용되는 구문임!)

TEST 명령어도 마찬가지로 ZF에 영향을 준다.
두 값이 같으면 ZF=1이 되고, 다르면 ZF=0이 된다.
-> 여기서는 EAX가 0이므로 ZF=1이 된다.


그 다음 줄인 004010B0에서는 JNZ 명령어를 이용해서 ZF 값에 따라 분기할 위치를 정하고 있다.
1) ZF=0인 경우 004010B4로 분기
2) ZF=1인 경우 바로 다음 줄인 004010B2로 분기

-> ZF=1로 2)에 해당된다.

004010B2로 분기됐으므로 이 부분을 살펴보면 JMP 명령어로 다시 004010F7로 분기한다.

⛔ 그러나 004010F7로 이동하면 다음 사진과 같이 또다른 에러 메시지와 함께 프로그램이 종료되므로 우리가 원하는 방향이 아니다.

🌟 위에서 2)로 가면 무조건 004010F7로 이동하게 되므로 우린 또다시 2)가 아닌 1)로 가도록 바꿔줘야 한다.

004010B0에서 JNZJMP로 바꿔준다!

그러면 이제 1)의 경우가 되어 004010B4로 분기한다.

이후에는 XOR연산과 CMP명령어의 결과를 통해 결국 004010BF에 있는 JL 명령어가 실행된다.

⛔ 그런데 JL로 분기되는 지점인 004010F7은 위에서 봤듯이 에러 메시지와 함께 프로그램이 끝나는 부분이므로 여기로 가면 안된다.

🌟 다시 조금 거슬러 올라가서 방금 JL명령어가 실행된 004010BF 값을 실행되지 않도록 수정하면 된다.
(참고: JL을 JGE(jump greater or equal)로 바꾸는 방법도 있다.)

다음 사진과 같이 실행을 원하지 않는 주소 값에서 마우스 오른쪽 클릭 - Binary - Fill with NOPs 메뉴를 클릭하면 해당 주소 값이 전부 NOP으로 처리되어 실행되지 않게 된다.
(주석처리와 비슷하다고 생각하면 될 것 같다.)

이제 다시 F8를 계속 누르다보면 004010C9에서 004010D3 이동하고 다음 줄인 004010D6에서 다시 004010BF로 이동하려고 한다.
(정확한 흐름 알기 위해서는 F8 누르면서 레지스터, 플래그 값 변화 이해하기)

아까 위에서 봤듯이 004010BF로 가면 안되기 때문에 마찬가지로 004010D6은 NOP 처리를 해준다.

이제 남은 줄인 004010D8로 가면 JMP 명령문으로 인해 00401205 주소 값으로 분기된다.

00401205를 살펴보면 성공 메시지를 출력하고 있음을 알 수 있다.


4. 저장

마우스 우클릭 - Copy to executable - All modifications로 패치한 부분 포함해서 전체 파일을 저장한다.

새로 생성된 창에서 마우스 우클릭 - Save file로 새로운 실행파일을 저장한다.

방금 저장한 실행파일을 실행해보면 다음과 같이 성공 메시지가 나온다!!


📚 참고자료


https://bob3rdnewbie.tistory.com/105
https://cha4ser.tistory.com/entry/%EB%A0%88%EB%82%98-%ED%8A%9C%ED%86%A0%EB%A6%AC%EC%96%BC-1-%EB%9D%BC%EC%9D%B4%EC%84%BC%EC%8A%A4-%EB%A3%A8%ED%8B%B4-%EC%A7%80%EB%82%98%EA%B0%80%EA%B8%B0

0개의 댓글