Crack me #2 알고리즘 알아내기

- x32dbg로 abex' crack me 씨리얼 생성 알고리즘을 파악해보자.

 

먼저 abex' crack me #2를 디버거로 오픈한다.

 

저번장에서 우린이미 프로그램을 크랙했었다. 이제 시리얼 생성 알고리즘을 파악할 시간이다.

 

1. Serial 생성 알고리즘 찾기

프로그램의 check 버튼을 누르면 시리얼과 일치하는지를 검사하도록 되어있다.

전에 봤던 조건분기문은 분명히 [Check] 버튼의 이벤트로 발생하는 event handler? 일 것이다.

그렇다면 함수의 시작 부분부터 쭉~ 보다보면 다음과 같은 코드를 볼 수 있다.

 

* (ID는 ReverseCore로 입력했다)

호호

위의 push, mov는 전형적인 스택프레임을 구성할때 보이는 모습이고, 이부분이 함수의 시작임을 직관적으로(?) ㅇㅇ

따라서 이부분이 함수의 시작임을 알 수 있음.

그래서 여기에 캠프차리고 디버깅을 시작함.

[F8]막 눌러보면서 변화를 살펴보자!

 

몇번의 시행착오를 겪다보면 다음과 같은 코드를 만나게됨

AX값이 0이면 바로밑의 jmp문을 수행

에러문구를 보니 Name에 4글자가 안되면 AX가 0이 안되나보다! 아무튼 4글자 이상의 Name을 넣고 점프를 해보면!

다음과 같은 곳으로 뛰게된다.

짜잔!

mov, push는 스택프레임을 생성할 때 보이는 전형적인 패턴임을 알고간다.

루프문의 구조는 다음과 같다.

 

MOV EBX, 4								; 4개만 돌림
...
CALL DWORD PTR DS:[&~__vbaVarForInit]		
TEST EAX,EAX								; if(EAX==0) [loop start] 0되면 루프나감 ^^
JE abexcme2-.004032A5						
...
CALL dWORD PTR DS:[&~__vbaVarForNext]		
JMP abexcme2-00403197							; loop end
MOV EAX, DWORD PTR SS;[EBP+8]

여기가 원하는 알고리즘을 생성하는 부분이다.

그렇다면 이제 암호화 방법에 대해서 알아보자! 밑으로 내리다보면 다음의 부분이있다.

첫번째 PUSH(004031F6)에서 Name에서 가져온 유니코드값을 넣는다. ('R')

이후에 그 유니코드를 ASCII 변환을 한다 (004031F7)

 

0040323D까지 실행한후에 스택을 살펴보자.

ECX : 0018F3C4

EAX : 0018F384

EDX : 0018F40C

 

[CPU 범용 레지스터 까묵;;]

 

[보안] CPU 범용 레지스터

CPU 범용 레지스터 (EAX,EBX,ECX,EDX,EBP,ESI,EDI,ESP) - CPU 범용 레지스터란 범용적으로 사용되는(?) 레지스터 입니다. 모든 레지스터들은 각각 4byte(32bit)의 크기를 가진다고 하네요! 8개의 레지스터에서 상..

kyumoonhan.tistory.com

그럼 이제 각 메모리주소를 살펴본다.

ECX
EAX
EDX

다음을보면 ECX에서 18F3CC는 결과저장용 버퍼이다.

EAX의 18F38C에 암호화키 (64),

EDX에서 18F414는 Name에서 문자열의 첫 ASII키 값(내가입력한 'R' 52) 이다.

 

이 후에 밑의 함수를 실행시키면 ECX 레지스터가 가리키는 버퍼에 암호화된 값이 저장된다.

52 + 64 = B6 이겠죠?
ECX 결과값을 보니 정답!

계산결과 B6은 보다시피 원본값('R')에 64를 더해서 생성한 값임을 알 수 있었다!

이후에 아래의 부분을 이용해 'B6'값을 유니코드로 변경한다.

마지막 함수 호출시 변환

함수 호출직후 EAX가 가르키는 버퍼(0018F3C4)를 살펴보자

B6이 성공적으로 들어감!

이렇게 4번을 돌리겠죠? 끝으로 생성된 문자열을 붙여주는 코드가 뒤에 있다.

 

문자열 붙이기

- vbaVarCat() : 문자열 이어붙이기

함수 호출시 : old(ECX) + add(EDX) = NEW serial(EAX) ^오^

 

이런식으로 알고리즘이 짜여져있다.

그렇게 마지막 루프를 실행하게 되면

 

Serial = old("B6C9DA") + add("C9") = "B6C9DAC9"

이렇게 암호화 알고리즘을 풀었다.

(Reve의 아스키값에 64씩 더헀네)

 

정리

1. Name 문자열을 앞에서 한 문자씩 4회 읽는다.

2. Ascii로 변환한다.

3. 변환된거에 64를 더한다.

4. 다시 유니코드로 변환한다.

5. 변환된 문자를 연결시킨다.

 

 

 

 

 

'Reversing' 카테고리의 다른 글

PE File(2)  (0) 2019.04.03
PE File(1)  (0) 2019.04.02
리버싱 4  (0) 2019.03.29
리버싱 3 Stackframe  (0) 2019.03.28
리버싱 2  (0) 2019.03.27

 앙 규문띠 

 

 

abex' crack me 2

오늘은 !!! 금요일이라 뭔가 바빴다...

 

그래도 리버싱 공부는 해야지 앞에 해답을 설명하고 뒤에 [나뭇잎 버전]으로 자세하게 공부해보겠다

 

abex' crack me 2... (언제 고수되죠?) 시작!

 

먼저 crack me 2.exe를 무작정 실행 해보았다.

 

abexcm2-voiees.exe
0.02MB

띠용!

 

Name이랑 Serial을 입력하란다. 그래서 입력해보았더니,

 

역시나 시리얼이 틀렸다고 나온다. 

아무생각없이 디버깅을 해야되겠지 ?

 

이 넓은 공간에서 무엇을 해야한단 말인가

 

일단 내가 생각했던건 먼저 메세지박스가 뜨는부분이 있을테고 거기에 위의 오류메세지인 Nope ~ 어쩌구가 있을것이라고 생각했다. -> 고렇다면... nope를 검색해보자!

 

나왔다! 따블클릭으로 들어가보자!

그랬더니 다음과 같이 해당 opcode로 이동되었다.

 

여기서 생각해봐야 할 부분이 오류를 출력하는 부분이 있다면 True를 출력하는 부분도 있을거 같다.

마우스 휠을 올려보자.

 

시리얼이 풀렸을 때의 문구가 나오는 부분을 찾게되었다!

여기서 주목해야할 부분은 위쪽 부분이다.

 

위의 부분에서 JE 조건 분기문이 생긴다 조건값에 따라서 점프하거나 바로밑으로 실행된다.

즉 조건 분기문의 위쪽부분에서 시리얼 넘버의 참거짓이 판별되는 무언가(?)가 있을것 같은 예감이..

 

그리하여 403329 call부분에 BP를 걸고 프로그램을 다시 실행시킨다. (call을 실행해보면 입력창이 뜬다.)

이후에 name과 serial을 입력한다.

 

그 다음[Check]를 누르고 스택값을 확인한다.

 

0018F42C 메...모

0018F42C의 주소로 이동하여 스택값을 확인해볼까?

 

내가 입력했던 abcd 패스워드가 그대로 스택으로 들어간걸 확인할 수 있다.

그 위에 시리얼 넘버로 추정되는 CFDDD9D1 가 문제의 해답인 것 같다.

다시 프로그램을 실행하고.... 해당 시리얼을 넣으면 !

 

키야 ~~~ 취한다!

crack me 2번 클리어!

 

나뭇잎 버전... 작성하자... 꼮..

[바로가기]

 

'Reversing' 카테고리의 다른 글

PE File(1)  (0) 2019.04.02
리버싱 5  (0) 2019.04.02
리버싱 3 Stackframe  (0) 2019.03.28
리버싱 2  (0) 2019.03.27
리버싱 1  (1) 2019.03.26

+ Recent posts