본문 바로가기

Reversing/Simples Creckme

Simples Crackme 10

Simples Crackme 10
 - Question

  · 알맞은 Serial을 찾는 문제이다

  · Serial이 맞으면 'Rigth number !!!'이라는 Message를, 맞지 않으면 'Wrong C0d3'이라는 Message를 출력한다.


 - Solution

  · OllyDbg를 이용해 실행해보면 'IsDebuggerPresent'라는 함수와 CMPJNZ를 이용해 Debug를 할 수 없도록 만들어 놓았다.
  · 함수 설명
  ◦ IsDebuggerPresent
   ▹ Process가 Debugger에 의해 실행되면 0이 아닌 값을 반환
   ▹ Process가 Debugger에 의해 실행되지 않으면 0을 반환
  · 현재 Program이 Debugger(OllyDbg)에 의해 실행되어 IsDebuggerPresent가 0이 아닌 값을 EAX에 반환해 CMP 명령어로 0과 비교하면 같지 않아 연산결과가 0이되며 JNZ 즉, 연산결과가 0이 아니라면 이동을 하기 때문에 Process가 실행되지 않고 바로 종료된다.
  · 따라서 이 Process를 Debugging 하기 위해서는 CMP 명령어를 NOP로 변경하거나 JNZ가 실행되기 직전에 Zero Flag를 1로 바꿔줘야 한다.(필자는 여기서 CMP 명령어를 NOP로 바꿔주겠다.)

  · Process의 내용을 살펴보면 'DialogBoxParamA'라는 함수로 문자열을 입력받은 후 다른 함수 영역으로 입력받은 문자열과 비교 문자열을 생성해 비교한 후 결과까지 출력하는 영역으로 이동 시켜준다는 것을 파악할 수 있다.
  · Serial 생성 및 비교영역

  ◦ 위 영역의 역할을 하나하나 나눠보면 Serial 기초조건Serial 생성 1, Serial 생성 2Serial 생성 3Serial 비교성공 & 실패 Routine으로 나눌 수 있다.
  ◦ Serial 기초조건

   ▹ Serial의 기초조건으로 'lstrlenA' 함수를 이용해 입력한 Serial의 글자 수를 가져와 CMP 명령어로 0x0E(10진수 14)와 비교하는 것을 볼 수 있다.
   ▹ 즉, 글자 수가 14개여야만 이후 명령을 실행하고 14개가 아니라면 바로 실패 Routine으로 이동시킨다.
  ◦ Serial 생성

   ▹ 입력한 Serial과 비교하기위한 Serial을 생성하는 구간이다.
   ▹ 처음에 'lstrcpyA' 함수를 이용해 'VaZoNeZ'라는 문자열을 String1에 복사한다.
   ▹ 다음으로 두 문자열 String1, String2를 붙인다.(VaZoNeZVaZoNeZ)

   ▹ 'GetUserNameA' 함수를 이용해 Serial을 생성할 때 사용할 사용자 이름을 가져온다.

   ▹ Serial을 생성하는 구간이다.
   ▹ Serial 생성 순서
    ▸  1) 사용자 이름에서 첫 번째 글자하나를 EAX에 저장한다.
    ▸  2) 위에서 생성한 Serial(VaZoNeZVaZoNeZ)을 첫 번째 글자를 가져온다.
    ▸  3) TEST 명령어는 인자 두 개를 AND 연산을 해 연산 결과가 0이면 Zero Flag를 1로 만들고 연산 결과가 0이 아니면 Zero Flag를 0으로 만드는데 여기서 EDX 값이 0이 아니므로 AND 연산 결과도 0이 아니기 때문에 Zero Flag는 0이 된다.
    ▸  4) TEST 명령어의 결과로 Zero Flag가 0이 아니면 Serial 생성 구간을 종료한다.
    ▸  5) 사용자 이름의 첫 번째 글자(AL)과 생성한 Serial의 첫 번째 글자(DL)을 더한 후 DL에 저장한다.
    ▸  6) DL에 저장된 값을 5와 Xor 연산한다.
    ▸  7) DL에 저장된 값과 위에서 생성한 Serial(VaZoNeZVaZoNeZ)의 주소 맨 마지막 자리 두 글자를 더해 DL에 저장한다.
    ▸  8) DL에 저장된 값에서 0x1E를 뺀 후 DL에 저장한다.
    ▸  9) DL에 저장된 값을 기존에 생성되어 있던 Serial(VaZoNeZVaZoNeZ)에 첫 번째 글자의 자리에 저장한다.
    ▸  10) 두 번째 글자를 연산하기위해 기존에 생성되어 있던 Serial(VaZoNeZVaZoNeZ)의 주소 값을 1 증가시킨다.
    ▸  11) 다음 글자를 연산하기위해 다시 두 번째 연산 단계로 이동한다.
   ▹  마지막에 연산을 마칠 때는 마지막 글자 뒤의 Dump 부분은 NULL(00)이고 00으로 TEST 연산을 하면 Zero Flag가 1이 되어 Serial 생성 구간을 종료한다.
  ◦  Serial 비교

   ▹  입력한 Serial과 생성된 Serial을 한 글자씩 14번(0x0E) 비교하는데 한 글자라도 맞지 않으면 3, 4번째 줄을 통해 실패 Routine으로 이동하고 모두 같으면 비교구간 바로 밑에 있는 성공 Routine으로 이동한다.


 - Answer
  · Serial +5)E'5-2<0L.<4
    ※ Serial 생성 설명에도 언급되어 있듯이 위 Serial은 사용자 이름에 영향을 받아 사용자의 이름에 따라 Serial이 달라진다.
 

'Reversing > Simples Creckme' 카테고리의 다른 글

Simples Crackme 12  (0) 2015.08.16
Simples Crackme 11  (0) 2015.08.16
Simples Crackme 9  (0) 2015.08.16
Simples Crackme 8  (0) 2015.08.16
Simples Crackme 7  (0) 2015.08.16