야금야금

Reversing #3_Crackme2 본문

SWING/Reversing

Reversing #3_Crackme2

hyk0425 2021. 3. 28. 12:37

[Crackme #2]

crackme #1에서는 프로그램의 작동 원리를 파악하여 우리가 원하는 방향으로 동작하도록 파일의 명령어 자체를 수정하여 패치(크랙)하였다.

crackme #2에서는 한 단계 나아가서 전형적인 크랙의 형태인 시리얼 키(serial key)를 알아내는 과정을 파악한다.

 

프로그램 설명 : NameSerial 값을 입력한다. 입력받은 Name값마다 일치하는 Serial값이 존재하고 해당 값이 아닌 다른 값이 입력되면 잘못된 값이라는 창이 뜬다.

목표 : 입력받은 Name문자열에 맞는 Serial값을 알아내고 Name문자열을 기반으로 Serial을 생성하는 알고리즘을 파악한다.

 

우선, 해당 프로그램의 EP코드를 확인해 보자 본 프로그램은 Visual Basic(이하 VB)으로 제작되었으며 VB파일은 VB전용 엔진을 사용한다. VB프로그램은Windows 운영체제의 구동 방식으로 동작하기 때문에 main() 또는 WinMain()에 사용자 코드가 존재하는 것이 아니라 각 event handler에 디버깅을 원하는 사용자 코드가 존재한다. 본 프로그램의 경우 Check버튼을 눌렀을 때의 결과값을 수정하는 것이므로 해당 버튼에 사용자 코드가 존재할 것이라고 추측할 수 있다.

 

└crackme #2의 startup 코드

3줄의 코드가 VB파일의 startup코드이다. EP코드에서 처음 하는 일은 VB엔진의 메인 함수(ThunderRTMain)를 호출하는 것이다. 40123D 주소의 CALL 명령어는 ThunderRTMain()함수 호출이다. 해당 코드의 내부로 들어가보면 직접 이동하는 것이 아니라 중간 주소의 JMP명령을 통해서 가는 방식을 사용한다. 이 방식은 VC++, VB컴파일러에서 많이 사용하는 간접호출 기법이다. (이는 특정한 이점때문이 아니라 MSVBVM을 사용하기 때문에 모듈 특성상 어쩔 수 없이 사용하는 것이다)

 

프로그램의 특성을 살펴보았으니 이제 본격적인 크랙을 진행해보도록 하자.

└임의의 Name문자열과 Serial값 입력
└오류 메시지

위와 같이 임의의 NameSerial을 입력하였다. 입력한 Name에 해당하는 Serial값이 아니므로 오류 메시지 박스가 출력되었다. 오류 메시지 박스의 문자열을 사용하여 패치해야 할 코드를 찾아보도록 하자

문자열 검색 기능을 활용하여 알맞지 않은 시리얼 키를 입력하였을 때의 메시지 박스 문자열을 검색한 후 해당 주소로 이동한다.

 

└오류 메시지 박스의 문자열 검색 및 주소 확인

본 프로그램은 crackme #1과 마찬가지로 상황에 따라 두 개의 메시지 박스 중 하나를 출력한다. 따라서 JE명령어가 수행 될 것이라고 예측할 수 있다. 다음과 같은 추론을 바탕으로 해당 문자열 출력 코드의 윗부분을 살펴보면 Congratulation 문자열과 함께 JE명령어의 존재를 확인할 수 있다. JE명령어는 리턴 값을 비교하여 참 거짓 코드로 분기하는 명령어이므로 JE명령어 위의 두 개의 PUSH명령어는 비교 함수의 파라미터, 즉 비교 문자열이 될 것이다. 이를 확인하기 위해 브레이크 포인트(f2)를 이용하여 403329 주소까지 디버깅을 진행한다.

 

위의 00403321LEA EDX,[LOCAL.17]LEA EAX,[LOCAL.13]은 스택 내의 주소를 말하는데, 이것이 바로 함수에서 선언된 로컬 객체의 주소이다.

 

└ LOCAL.17의 주소를 확인하기 위해 해당 코드를 더블클릭 하면 보이는 Assemble창

EDX의 주소를 확인해보면 위와 같은 주소를 볼 수 있다. EBP란 베이스 포인터 레지스터이다. 즉 [EBP-44]주소가 의미하는 것은 스택 내의 주소이고 이것이 바로 함수에서 선언된 로컬 객체의 주소이다. EBP주소는 Register Window에서 확인할 수 있다.

 

Dump Window에서 해당 주소를 살펴보면 다음과 같다.

VB문자열은 C++String클래스와 마찬가지로 가변 길이 문자열 타입을 사용한다. 따라서 위와 같은 16바이트 크기의 데이터가 나타난다. 박스로 표시한 부분을 제외하고 나머지 부분은 모두 같은 것을 확인할 수 있다. 이를 통해 해당 부분이 메모리 주소임을 예측할 수 있다. 따라서 Dump Window 메모리 창의 보기 형식을 ASCII dump형태로 변경하여 해당 문자열을 확인하면 다음과 같다.

 

EDX(Address 0019F298)에는 실제 Serial값이, EAX(Address 0019F2A8)에는 사용자가 입력한 Serial값이 들어있는 것을 주석으로 확인할 수 있다. 해당 문자열의 Value주소로 찾아간 후 보기 형식을 다시 16바이트의 Hex로 변경하면 다음과 같은 실제 문자열을 확인할 수 있다.

위에서 확인한 실제 Serial값을 입력했던 Name과 함께 입력한 후 실행하면 다음과 같이 성공 메시지 박스가 출력된다.

└위에서 확인한 값으로 문자열 입력
└성공 메시지

다른 Name문자열을 입력하고 본 과정을 다시 진행해보면 Name마다 다른 Serial키가 생성되는 것을 확인할 수 있다.

 

[뉴스스터디] 리버싱_v.01.02.pdf
0.83MB

'SWING > Reversing' 카테고리의 다른 글

Reversing #4_Lena's Reversing for Newbies  (0) 2021.03.28
Reversing #2_Crackme1  (0) 2021.03.28
Reversing #1_Hello World  (0) 2021.03.28