본문 바로가기

리버싱/리버싱기초

리버싱 예제 1 (라이센스 우회)

1. 파일다운 받고 실행




위의 폴더에서 2번째 예제를 풀어본다. 실행파일은 다음과 같다.


Exercise02.exe



우선 실행을 시키면 다음 그림과 같은 메시지박스가 뜬다.




2. ollydbg.exe 실행


평가 기간이 만료되었으니 새 라이센스를 구입하란다. 우선 어셈코드를 확인하기 위해 ollydbg.exe를 실행한다.





위의 화면은 다음과 같이 구성되어 있다.


 - 왼쪽 상단 : 어셈코드

 - 오른쪽 상단 : 레지스터 정보

 - 왼쪽 하단 : 메모리 정보

 - 오른쪽 하단 : 스택 정보



3. 문제 확인 1


코드를 천천히 내려서 문제가 발생했던 지점을 찾고 브레이크 포인트(F2)를 건다.


그리고 디버깅을 실행(F9)한다.






 00401078

 CMP EAX, -1

 EAX 값과 -1을 비교한다.

 0040107B

 JNE SHORT 0040109A 

 0이 아닐 경우 0040109A(에러 메시지박스 함수)로 점프 


EAX 값은 함수가 호출될 때의 반환 값이다. 즉 CreateFileA가 호출된 뒤의 반환값이 -1이면 

Evaluation period out of date. Purchase new license"와 같은 에러를 보여주는 것 같다.

그렇다면 언제 CreateFileA가 -1을 리턴하는지 확인해보자.(구글 검색)




천천히 읽어보니 함수가 성공하면 특정 파일에 관한 open 핸들이 반환된다고 한다.

하지만 실패할 경우 INVALID_HANDLE_VALUE가 리턴된다고 한다. 

이 값이 무엇인지 좀더 검색해보니 


#define INVALID_HANDLE_VALUE (HANDLE)-1;


라고 적혀있다. 결국 특정 파일에 관한 open 핸들을 얻지 못해서 -1을 반환했고 그 결과 이전과 같은 에러 메시지창이 출력된 것이라고 생각이 된다.



4. 문제 해결1


파일이 없거나 읽을 수 없기 때문에 -1을 반환했을 것이다. CreateFileA를 호출할 때의 인자를 확인해보았다. FileNmae=Keyfile.dat을 확인할 수 있었다. 파일핸들 API 실행 시 가장 최초의 파일을 찾는 경로는 실행 프로그램의 폴더이다. 현재 실행프로그램이 있는 폴더 내에 아무런 파일도 없으므로 Keyfile.dat 파일을 만들고 다시 프로그램을 실행시켜 보자.





실행 하고 보니 에러메세지가 바뀌었다. 앞의 문제는 해결했으나 아직 고쳐야할 것이 있는 것 같다. 



5. 문제 확인 2


다시 ollydbg.exe를 실행하자. 해당 메시지박스를 띄우는 주소를 확인해보니 004010F7임을 확인할 수 있었다.




이 주소를 호출하는 코드를 찾아보니 몇개가 있었는데 일단 첫번째는 다음과 같았다.





 004010B4

 XOR EBX,EBX

 EBX 레지스터를 초기화한다. 
 004010B6 

 XOR ESI,ESI

 ESI 레지스터를 초기화한다.

 004010B8

 CMP DWORD PTR DS:[402173], 10

 402173 주소에 있는 값 0x10을 비교한다.

 004010BF

 JL SHORT 004010F7

 작으면 004010F7(에러 메시지 함수)로 점프 



그림을 확인하면 ReadFile 함수 호출 시 402173은 pByteRead를 가리키게 된다. 

보면 값이 0인것을 알 수 있는데... 왜 0인지 검색해보자




읽어보니 hFile 파라미터를 사용할 때 읽은 바이트의 수를 가지고 있는 변수의 포인터라고 한다. 우선 ReadFile은 이 값을 실행 전, 에러 확인전에 0(NULL)으로 설정한다고 한다.


흠..읽은 바이트 수가 맞는지 확인하기 위해 Keyfile.dat에 3글자를 쓰고 다시 실행해보았다.


00402173의 메모리 값(ctrl+G)을 확인하자. 






03 00 00 00 (리틀엔디안) 인 것을 보니 확실히 이 인자는 읽은 바이트수를 나타냄이 확실했다.


6. 문제 해결 2


아까 코드를 확인해보면 0x10이랑 값을 비교했었다. 따라서 0x10글자 이상을 파일에 입력하면 된다.


Keyfile.dat에 A를 16개 입력한뒤 다시 프로그램을 실행해보았다.






다행히 위의 코드는 건너 뛰었는데 또 다른 검증이 나타났다.



7. 문제 확인 3


 004010C1

 MOV AL,BYTE PTR DS:[EBX+40211A]

 EBX+40211A 로부터 한 바이트를 읽은 뒤 AL에 넣는다.

 AX : EAX의 하위 16비트 

 AL : AX의 하위 8비트

 AH : AX의 상위 8비트

 004010C7 CMP AL,0

 이 값을 0이랑 비교하여 (문자열 끝)

 004010C9

 JE SHORT 004010D3

 004010D3 으로 점프 (루프 종료)

 004010CB CMP AL,47

 이를 0x47과 비교하여

 004010CD

 JNE SHORT 004010D0

 같지 않을 시 004010D0으로 점프

 004010CF

 INC ESI ESI 값을 1증가

 004010D0

 INC EBX

 EBX 값을 1증가

 004010D1 JMP SHORT 004010C1 다시 004010C1로 돌아감(루프)

 004010D3

 CMP ESI,8

 ESI 값을 8이랑 비교하여

 004010C6

 JL SHORT 004010F7

 0보다 작으면 004010F7(에러 메세지 박스)로 점프


코드를 보니 모든게 확인되었다.


글자수를 0x10개이상 0x47로 입력하면 해결될 것 같다.



8. 문제 해결 3


0x47을 16글자 입력한뒤 프로그램을 다시 실행시켜보았다.








잘 된다고 한다.



9. IDA Pro 를 통해 확인


코드 쫒아가기가 은근 귀찮으므로 위에 했던 코드를 IDA를 통해 확인해본다.





오른쪽 하단에 Strings window를 보자.


우리가 아까 보았던 에러 메시지문구가 보인다.


어디서 사용되는지 확인하기 위해 문구를 더블클릭한다.


그리고 마우스 오른쪽 클릭 한뒤 어디서 참조되는 지확인하자.








OK를 누르면 어디서 이 문구가 사용되었는지 알 수 있다.





코드를 보면 CreateFileA를 호출한 뒤 리턴 값이 -1이면 에러메시지 창을 띄우고 아니면 40109A로 점프를 하게 된다.






코드를 확인해보니 읽은 바이트가 16글자보다 작으면 4010F7로 점프하라고 한다.


아닐 경우 그 아래 코드를 실행하게 된다.





글자를 한글자씩 읽은 다음 글자가 0x47이면 esi를 1씩 증가시킨다.


그리고 모든 글자를 읽은 뒤 esi가 8보다 작으면 4010F7로 점프한다.


도대체 4010F7이 어디길래


확인해보면 Keyfile is not valid Sorrry 라며 에러 메시지를 출력하는 코드이다.


근데 4010F7로 보면 보기 힘드므로 이름을 지어주자.


마우스 오른쪽 클릭 한뒤 rename을 클릭하면 된다.




바꿔주면 아까 4010F7이라고 나왔던 부분이 내가 지정해준 이름으로 표시가된다.





'리버싱 > 리버싱기초' 카테고리의 다른 글

DLL(Dynamic-link library) 동적 분석 방법  (2) 2016.03.07
리버싱 예제 2 (정적분석 vs 동적분석)  (0) 2015.10.14
PE파일 데이터 암호화  (0) 2015.10.05
PE파일 구조  (0) 2015.09.23
리버싱 백그라운드(x86)  (0) 2015.09.15