본문 바로가기

2. Reversing (리버싱)/1) Write UP

[2022.11.19] R4 활동일지 - 4강 LENA 17보충

 

레나 강의 제 17강 문제.

 

아이디와 일련번호를 입력하고 CHECK 버튼을 누르면 일련번호가 맞는지 확인하는 문제

일련번호가 미리 저장된 것이 아니라 입력된 아이디 값을 가지고 프로그램에서 일련번호를 직접 생성하는 것

아이디와 일련번호를 입력할 경우 오류 메시지가 뜬다

 

오류 메시지를 통해 분석 시작 위치를 찾아보면, 0040135A 근처에서 확인할 수가 있다.

코드 영역 위쪽으로 올라가보면 004012FB에서 lstrlen 함수를 확인할 수 있다. 이 함수는 문자열을 입력받아 길이를 구해 EAX에 결과를 담아주는 함수다. 프로그램에서는 EAX에 담겨 있는 문자열 길이를 다시 ECX로 옮겨서 뒤에 오는 반복문에서 반복 횟수를 지정하는 변수로 사용하고 있다.

반복문의 역할은 일련번호를 생성하는 것이기에, 메모리 403038에 들어 있는 문자열을 다양한 연산을 반복적으로 수행하면서 일련번호로 바꾸는 기능을 수행한다.

최종적으로 생성된 일련번호는 ESI 레지스터에 담긴다.

ESI 레지스터에 저장된 일련번호와 사용자가 입력한 일련번호가 같은지 확인한다. 사용자가 입력한 값은 주소 430138에 저장되어 있다.

 

주소 004012f6에 BP를 설정하고 프로그램을 실행해 보았다. lena152를 입력하고 f8을 이용해 00401304까지 실행하면, lstrn 함수에 들어가는 문자열은 아이디로 입력한 lena152임을 확인할 수 있다.

함수 실행 결과가 저장되는 ECX 레지스터에는 문자열의 길이와 같은 7이 저장되어 있다.

(가독성을 위해 작성자는 00401384부터 코드 삽입을 하고 00401384로 점프하게 했다)

 

이제 일련번호를 확인하기 위해 코드를 삽입해보면,

주소 0040133C에 있는 명령어 JNE SHORT 00401353을 케이브 코드가 들어가는 주소 00401383으로 점프하는 코드 JMP SHORT 00401383(코드 영역 하단의 사용하지 않는 맨 처음 부분)으로 교체한 후, 케이브 코드의 첫 부분에 MOV DWORD PTR DS:[403148], ESI를 입력한다. 이는 ESI 레지스터에 들어 있는 문자열을 메모리 주소 403148에 4바이트만큼 복사하는 동작을 한다.

메모리 주소 403148에는 ESI 레지스터에 있는 데이터가 들어가는데, 이 데이터는 프로그램에서 생성된 일련번호다.

프로그램을 실행해서 아이디와 일련번호를 집어넣으면 헥사 덤프 영역에 일련번호가 들어가고, 오른쪽에 있는 ACSII 영역에 알아볼 수 있는 형태로 변환되어 들어가게 된다.

두 번째 케이브 코드인 JNE SHORT 00401353은 프로그램에서 생성된 일련변호와 사용자가 입력한 일련번호를 비교해서 틀리면 주소 00401353으로 점프하는 코드다.

두 개의 일련번호가 일치하면 주소 0040133E로 점프한다.

 

[edit] - [copy all modifications to executable] 메뉴를 사용해서 별도의 프로그램으로 저장한 후 실행시켜 보면,

주소 00401353까지 실행했을 때 주소 00403148에는 프로그램에서 생성된 일련번호가 들어 있다.

실행해 보면 프로그램 내에서 ASCII 일련번호를 확인할 수 있다!

KeygenMe.Keygen.exe
0.39MB

첨부된 패치 파일을 실행시켜 보면, 아이디 입력 시 일련번호를 메시지로 띄워주게 된다.