'리버싱'에 해당되는 글 12건

  1. 2011.01.03 [Reversing With Lena] lena's tutorial 17 풀이

1. 개 요
예제 문제 및 강의 내용 출처 : http://www.tuts4you.com/
이번 Lena의 17장 강의에서는 특정 프로그램의 keygen(별도의 프로그램 작성이 아닌 self-keygen)을 생성하는 방법에 대해서 설명한다.

2. 사용도구
Ollydbg :
http://www.ollydbg.de

3. 내 용
Ollydbg를 이용하여 예제가 되는 KeygenMe.exe 프로그램 로딩 후 실행(F9)해보도록 한다. [그림 1]과 같이 사용자로부터 2개의 입력값을 받는 입력창을 볼 수 있으며, 임의대로 값을 입력 후 "Check" 버튼 클릭시 특정 다이얼로그 박스가 출력되는 것을 확인할 수 있다.
                                                                          [그림 1]

[그림 2]와 같이 ollycommand를 이용하여 텍스트 입력창에서 사용자 입력값을 읽어올 때 사용하는 GetDlgItemTextA 함수에 BP를 설정하도록 한다.
[그림 2]

사용자의 입력 값을 두 번 입력받게 되므로 F9를 두 번 실행하여 [그림 3]과 같이 두 번째로 호출된 GetDlgItemTextA 함수를 호출하는 시점에서 정지하도록 한다.
[그림 3]
현재 GetDlgItemTextA가 호출된 이후에 USER23.dll에서 프로그램이 정지되어 있는 것을 확인할 수 있다. GetDlgItemTextA 호출뒤 프로그램 코드를 확인하기 위해 Atl + F9(Execute till user code)를 실행한다.

[그림 4]와 같이 Alt + F9 실행 후 4012D8에서 정지하는 것을 확인할 수 있다. 위에서 두 번의 GetDlgItemTextA를 호출하여 사용자 입력 값을 읽어오는 것을 확인할 수 있으며, 사용자 입력 값 길이가 0일 경우 MessageBoxA를 호출하여 "Give me more material hehe!!"를 출력하며, 0이 아닐 경우 lstrlenA 함수를 통해서 첫번째 입력 값의 문자열 길이 값을 얻어온다.
[그림 4]

이어서 [그림 5]와 같이 key 값을 생성하는 부분을 확인할 수 있다. 붉은 박스로 표시된 부분에서 첫번째 입력값에 맞는 시리얼 값이 생성되어 지며 생성된 값은 최종적으로 ESI 레지스터에 저장되어 401336에서 CMP 명령어에 의해 두번째 입력한 입력값과 비교되는 것을 확인할 수 있다.
[그림 5]

401336의 CMP 구문에 의해 시리얼 값의 이상유무를 비교한 뒤 40133C의 JNZ 구문에 의해 [그림 6]과 같이 GoodBoy!와 BadBoy!로 분기 여부가 결정된다.
[그림 6]

이번 Lena151의 17강 강의에서는 (self)Keygen을 생성하는 것이 목적이다. 시리얼을 생성하는 방법을 알았고 최종적으로 생성된 시리얼 값이 ESI 레지스터에 저장된다는 특성을 이용하여 inline patch를 이용하여 (self)Keygen을 만들어 보기로한다.
(inline patch에 대한 내용은 다음 포스팅 참조 : http://sinun.tistory.com/112)

시리얼 값을 생성하는 부분이 모두 실행된 뒤 ESI 레지스터에 저장된 시리얼 값을 출력하는 것을 최종 목표로 하며, 일단 빈 영역에 ESI 레지스터의 값을 특정 영역에 저장하는 명령어를 생성해준다. [그림 7]과 같이 ①번(40133C) 구문에서 시리얼 값이 틀렸을 경우 새로 추가한 부분이 401383 영역으로 분기하도록 설정한다. 빈 영역인 ② 번(401383) 부분에는 최종 생성된 시리얼이 저장된 ESI 레지스터의 값을 439000 메모리 영역에 저장하며, 시리얼 값 일치시 실행되는 401353 영역으로 분기하도록 inline patch code를 추가한다. 마지막으로 ③번 구문과 같이 MessageBoxA에서 출력대상이 되는 파라미터의 값을 생성된 시리얼 값이 저장된 439000으로 변경한다. 따라서 사용자의 첫번째 입력값에 따른 시리얼 값이 항상 메시지 박스 형태로 출력된다.
[그림 7]

확인을 위해 시리얼 값 생성 루틴이 완료된 이후 ESI 레지스터에 저장된 값을 확인해 보면 [그림 8]과 같이 11E9D8인 것을 확인할 수 있으며, little-endian인 것을 감안하여 ASCII 값으로 변경시 아래와 같은 값을 얻을 수 있다.
[그림 8]

위에서 얻어낸 값이 실제 inline patch를 통해 수정된 프로그램에서 동일하게 생성이 되는지 또한 생성된 값이 실제 시리얼 값이 맞는지 확인해 보자. [그림 9]의 왼쪽 그림과 같이 inline patch된 프로그램을 통해 시리얼 값이 메시지 박스 형태로 출력되는 것을 알 수 있으며, 출력된 시리얼 값 입력시 정상적으로 통과되는 것을 확인할 수 있다.
[그림 9]

4. 결 론
이번 Lena의 Tutorial에서는 inline patch를 이용한 self-keygen 만드는 방법을 보여주고 있다. 간단한 방법이지만 많은 것을 배울 수 있었다. 이 포스팅에 있는 기술들을 악용하여 상용 프로그램의 라이센스 인증 과정을 크랙하는 우를 범하지 않았으면 한다.

                                                                                                    +---------------------------------+
                                                                                                    | Infinite Flow..                              |
                                                                                                    | mail : geekspark@gmail.com         |
                                                                                                    | Blog : http://sinun.tistory.com       |
                                                                                                    | twitter : @unpacker                      |
                                                                                                    | CISSP                                        |
                                                                                                    +----------------------------------+
저작자 표시 비영리 변경 금지
신고
Posted by By. PHR34K

티스토리 툴바