반응형

 

Write-up 쓴 날짜 : 2022-10-27 12:31

 

KeygenMe.exe
0.39MB
KeygenMe.Keygen.exe
0.39MB
patched_KeygenMe.exe
0.39MB

 

CrackersTool.exe
0.03MB
comdlg32.ocx
0.13MB
NonaWrite1.1.rar
0.01MB

 

주제 - Insights and practice in basic (self)keygenning

 


분석 1

 

 

프로그램을 실행하면 위와 같이 창이 뜬다.

 

 

아무것도 입력하지 않은 상태에서 Check 버튼을 누르면 위와 같이 Give me more material hehe!! 메세지 창이 뜬다.

 

 

빈칸에 한 글자씩 입력 후 Check 버튼을 누르면 위와 같이 Error detected! Remove debugger from Hard Drive 메세지 창이 뜬다.

 

 

About 버튼을 누르면 위와 같이 메세지 창이 뜬다.

 


분석 2

 

 

프로그램 내에서 어떠한 알고리즘을 이용해 시리얼 키를 생성할 것인데, 이 시리얼 키를 생성할 때 사용자가 입력한 값을 이용할 수도 있고 안 할 수도 있지만, 어쨌든 사용자가 입력한 값을 프로그램에서 읽어가게 되는데 이때 사용할만한 함수로는 GetDlgItemTextA()와 GetWindowTextA()이다.

 

해당 API 함수의 주소를 찾아가기 위해 ollydbg에서 제공하는 command bar 이라는 플러그인을 사용한다.

 

command bar 플러그인은 ollydbg 맨 하단에 보여지는데 위와 같이 bp GetDlgItemTextA 라고 입력 후 Enter를 누르면

 

Alt + b 키를 눌러 BP들을 확인했을 때 위와 같이 775E4B90 주소에 있는 mov EDI, EDI 주소에 BP가 걸린다.

 

775E4B90 주소는 user32 모듈의 주소이다.

 

 

F9 키를 눌러 실행 후 프로그램이 실행되면 아무 값이나 입력하고 Check 버튼을 누른다.

 

 

그러면 위와 같이 775E4B90 주소에서 멈추게 된다.

 

F9 키를 눌러 실행하면 한 번 더 775E4B90 주소에서 멈추게 되는데

 

그 이유는 프로그램에서 입력 하는 텍스트 박스가 2개이고, 현재 BP를 GetDlgItemTextA에 걸었기 때문이다.

 

어디 주소에서 GetDlgItemTextA API 함수를 호출했는지 보기 위해 Alt + F9 키를 눌러 user code가 나올 때까지 자동으로 진행시킨다.

 

 

Alt + F9 키를 눌렀더니 위와 같이 4012C2 주소에서 멈췄다.

 

4012BD 주소와 4012D3 주소에서 GetDlgItemTextA 함수를 호출하고 4012C2 주소와 4012D8 주소에서 반환값과 0을 비교한 뒤 0이면 4012DF 주소로 점프한다.

 

4012DF 주소에는 Give me more material hehe!! 메세지 창을 띄우는 부분으로 프로그램에 아무런 값도 입력하지 않고 Check 버튼을 눌렀을 때 실행되는 곳이다.

 

그렇다면 GetDlgItemTextA 함수를 호출 후 eax에는 입력한 값의 길이가 들어있는 것이다.

 

4012BD 주소의 GetDlgItemTextA 함수는 첫 번째 텍스트 박스의 입력한 값을 가져오는 부분이고

4012D3 주소의 GetDlgItemTextA 함수 함수는 두 번째 텍스트 박스의 입력한 값을 가져오는 부분이다.

 

두 텍스트 박스에 값이 입력되어 있으면 4012F6 주소로 점프하고, 4012F6 주소에서는 첫 번째 텍스트 박스에 입력됐던 값의 길이를 구한다.

 

 

그리고 401300 ~ 401334 주소까지는 암호화 연산이다.

 

즉, 시리얼 키를 생성하는 곳이다.

 

 

암호화 연산이 끝난 후 401336 주소에서 ESI의 값과 403138 주소에 있는 값과 비교한 뒤 같지 않으면 401353 주소로 점프하는데 401353 주소는 Error detected! 메세지 창을 띄우는 부분이다.

 

ESI의 값과 403138 주소에 있는 값과 같으면 That's right 메세지 창을 띄우는 부분으로 간다.

 

 

401336 주소에 BP를 걸고 F9 키를 눌러 실행하면 403138 주소에는 이전에 두 번째 텍스트 박스에 입력했던 bbbb가 들어있고, ESI에는 암호화 연산을 한 0686FA가 들어있다.

 

조건 분기문을 패치해도 되지만

 

키젠을 만드는 것이 목표이다.

 

시리얼 키가 생성되는 것은 사용자가 첫 번째 텍스트 박스에 입력한 값에 따라 달라지는데, 두 번째 텍스트 박스에 입력된 값과 암호화 연산이 끝난 후의 값이 같지 않으면 에러 메세지 창이 뜬다.

 

이러한 점을 바탕으로 에러 메세지 창을 띄우는 부분에 올바른 시리얼 키를 출력하도록 어셈블리어를 삽입한다.

 

 

인라인 패치 기법을 이용할 것인데

 

암호화 연산 후의 값이 담긴 ESI의 값을 저장할 공간을 데이터 영역에서 찾아주는데, 데이터 영역인 439000 주소로 가면 모두 00으로 채워져있다.

 

 

그리고 code cave를 설치할 공간을 찾아야 하는데 에러 메세지 창을 띄우는 부분에서 스크롤을 조금 내리다보면 401383 주소부터 4013B0 주소까지 00으로 채워진 것을 확인할 수 있다.

 

0x401384:
mov dword ptr ds:[439000], esi
jmp short 00401353

 

ollydbg에서 NonaWrite 플러그인을 이용해 위와 같이 작성한 후 Assemble을 누른다.

 

위의 어셈블리어는 esi 레지스터에 담긴 시리얼 값을 439000 주소에 저장하고, 401353 주소로 복귀한다.

 

 

40133C 주소의 조건 분기문에서 점프하는 주소를 401353 주소에서 401384 주소로 수정한다.

 

그리고 40135A 주소의 Text 매개변수의 명령어도 push 439000으로 수정하여 생성된 시리얼 값이 출력되도록 한다.

 

패치한 내용을 저장하고, 저장한 파일을 실행한다.

(디스어셈블리 창 -> 우클릭 -> copy to executable -> All modifications -> Copy all -> 우클릭 -> Save File)

 

 

a와 aaaa를 입력하고 Check 버튼을 누르면 위와 같이 fo 메세지 창이 뜬다.

 

 

a와 fo를 입력하면 위와 같이 that's right 메세지가 뜬다.

 

 

반응형

+ Recent posts