반응형

Crack me by hackereh@!.exe
0.05MB

 

 

 

Crackme 4번을 실행하면 위와 같이 나오는데 역시 serial 값을 알아내는 것이다.

 

Enter your serial here! 이라는 값이 기본적으로 입력되어 있는데

 

이대로 Check 버튼을 눌러보면 아래와 같이 serial 값이 맞지 않다는 의미의 메세지가 뜬다.

 

 


 

 

Crack me by hackereh@!의 EP 코드이다.

 

 

스크롤을 조금 내려보면 위와 같이 serial을 입력하라라는 문구가 보인다.

 

 

문자열 찾기 기능을 이용하면 위와 같이 나열되어 있는데

 

“Yup, You did it! now make a tutorial:)!” 문구가 지정된 serial 값을 입력했을 때 출력되는 문구인 것 같으므로 해당 주소로 이동해보자.

 

 

4011F8 주소에 “Yup, You did it! now make a tutorial:)!”가 보이고 그 밑에는 401207 주소에 “Please enter 1 or more chars!” 라는 문자열이 있다.

 

문구를 보니 입력값이 최소 1글자 이상은 되어야 하는 것 같다.

 

그리고 그 밑에는 API 함수들을 확인할 수 있다.

 

 

스크롤을 조금 위로 올리면 위와 같이 4011E2 주소에 “Badboy, try it harder u can” 이라는 문구가 보인다.

 

해당 문구는 잘못된 serial 값을 입력했을 때 봤었다.

 

위의 부분을 해석해보면 입력된 serial 값에 따라 4011DB 주소, 4011F1 주소, 401207 주소로 jmp 하여 상황에 맞는 문구를 띄우고 4011D0 주소로 jmp 하여 eax의 값을 0으로 만들고 레지스터들을 원래 값으로 돌린 뒤 함수가 종료된다.

 

 

스크롤을 조금 더 올려보면 위와 같은 부분이 있다.

 

401197에 BP를 설정하고 F9를 눌러 실행하면 동작을 확인할 수 있다.

 

al의 값이 0인지 확인하여 0이면 ZF 플래그가 1로 설정되기 때문에 je 명령이 실행되므로 401207 주소로 jmp 하는데 401207 주소에는 “Please enter 1 or more chars!” 문자열을 띄우는 부분이다.

 

즉, al은 eax 레지스터의 1byte(8bit)를 의미하는 레지스터이기 때문에 al에는 우리가 입력한 serial 문자열 값에서 한 문자가 담기게 될 것이고 이때 al의 값이 0이면 1문자 이상 입력해달라고 문구를 출력해주는 것이다.

 

al에 값이 담겨있다면, 401187 주소의 je 명령은 pass 하고, ecx 레지스터에 eax의 값을 담은 뒤 ebx 레지스터와 eax 레지스터를 0으로 초기화 한 다음 edi 레지스터에 403138 주소에 있는 값을 넣고, edi 레지스터의 값에서 1byte의 크기만큼 읽어 eax에 담겠다는 것이다.

 

즉, 403138 주소에는 우리가 입력한 serial 값이 들어있을 것이고 이 입력한 문자열의 주소를 edi에 담아 한 글자 한 글자 eax에 담는다는 로직이다.

 

eax에 한 글자 한 글자 담기면 한 글자는 1byte씩이니 al로 접근한다.

  1. and al, AD는 결국 and edi, AD 라는 의미이고, 이는 입력한 문자열 중 가장 첫 번째 문자와 AD를 and 연산한다.
  2. and al, 9A는 결국 and [edi+1], 9A 라는 의미이고, 이는 입력한 문자열 중 두 번째 문자와 9A를 and 연산한다.
  3. and al, 97는 결국 and [edi+2], 97 이라는 의미이고, 이는 입력한 문자열 중 세 번째 문자와 97를 and 연산한다.
  4. and al, BF는 결국 and [edi+3], BF 이라는 의미이고, 이는 입력한 문자열 중 네 번째 문자와 BF를 and 연산한다.
  5. and al, 5FC5는 결국 and [edi+4], 5FC5 이라는 의미이고, 이는 입력한 문자열 중 다섯 번째 문자와 5FC5를 and 연산한다.
  6. and al, D6은 결국 and [edi+5], D6 이라는 의미이고, 이는 입력한 문자열 중 여섯 번째 문자와 D6을 and 연산한다.

 

1 ~ 6번 모두 and 연산 후 jne 명령으로 4011DB 주소로 jmp 한다.

 

그리고 마지막에 cmp 명령으로 ecx의 값과 6을 비교하여 jne 명령으로 4011DB 주소로 jump 하는데

이는 입력한 serial 문자열이 총 6글자라는 의미이고, 4011DB 주소에는 “Badboy, try it harder u can” 문구를 띄워주는 부분이다.

 

여기서 잠깐 정리하자면, 입력한 serial 값이 1글자 이상이여야 하고, 6글자이어야 하며 위의 1~ 6번 AND 연산을 통과해야 “Yup, You did it! now make a tutorial:)!” 문구를 띄워주는 부분으로 간다.

 

 

and 연산 부분을 자세히 보면 총 6번의 and 연산이 이루어지는데 6번의 and 연산이 모두 통과하면 4011F1 주소로 jump하고 이는 “Yup, You did it! now make a tutorial:)!” 문구를 띄워주는 부분이다.

 

jcc 명령은 이전 명령의 연산 결과에 따라 실행 여부가 결정된다.

 

je 명령은 jump if equal의 약자로 이전 명령의 연산 결과가 0이여서 ZF 플래그가 1로 세팅되면 실행된다.

 

반면, jne 명령은 jump if not equal의 약자로 이전 명령의 연산 결과가 0이 아니여서 ZF 플래그가 0으로 세팅되면 점프된다.

 

그렇다면 위의 부분에서 and 연산을 통과하기 위해서는 각 비교 값들과 연산한 결과가 0이여서 ZF가 1로 세팅되어야 jne 명령이 실행되지 않고 다음 and 연산으로 넘어간다.

 

AND 연산은 모두 1일 때만 1이고, 둘 중 하나라도 0이면 0이다.

 

그렇다면 AD와 AND 연산한 결과가 0이 되게 하려면 AD의 2진수를 NOT 연산하여 비트 반전한 뒤 해당 이진수와 AD를 AND 연산하면 결과가 0일 것이다.

 

다른 것들도 위와 같이 하면 아래와 같다.

 

비교 값 비교 값을 이진수로 표현 비교 값의 이진수를 NOT 연산한 결과 16진수 값
AD 1010 1101 0101 0010 52
9A 1001 1010 0110 0101 65
97 1001 0111 0110 1000 68
BF 1011 1111 0100 0000 40
5FC5 101 1111 1100 0101 1010 0000 0011 1010 A03A
D6 1101 0110 0010 1001 29

 

위의 16진수 값들에 해당하는 문자들을 ASCII 표에서 찾으면 아래와 같다.

 

52 = R

65 = e

68 = h

40 = @

3A = :

29 = )

 

 

 


위에서는 Reh@:) 라는 serial 값이 나왔지만 Beh@:)을 입력해도 성공 메세지가 보인다.

 

1010 1101 = AD

and

0100 0010 = B

---------------

0000 0000

 

반응형

'전쟁 > crackme' 카테고리의 다른 글

Crackme #10  (0) 2022.06.23
Crackme #9  (0) 2022.06.23
Crackme #7  (0) 2022.06.22
crackme #6(ReWrit's Crackme#1)  (0) 2022.06.21
abex' crackme #5  (0) 2022.06.14

+ Recent posts