11. 크랙미 두 번째
본문 바로가기
Reversing & Cheat Engine

11. 크랙미 두 번째

by boosting 2024. 2. 25.
728x90

 

CrackMe#4.exe
0.18MB

쉬운 거부터 꾸준히 연습하자

 

처음부터 어려운 거 해봐야 벽만 크게 느끼고 돌아설 가능성이 높습니다.

그러므로 비교적 쉬운 거부터 확실하게 다루고 넘어가야 어려운 거에서도

자그마한 성과라도 낼 확률이 높아집니다.

 

패킹된 프로그램

 

패킹이라 함은 간단히 말해서 실행하는 과정을 압축하는 과정입니다.

즉 Ollydbg 같은 정적의 프로그램으로 실행도 시키지 않은 채로 내용 보는 걸 방지하는 정도죠.

 

크랙미

 

이번엔 이런 파일을 구해왔는데 이전 글의 파일과는 달리 기본적인 패킹은 되어있네요.

패킹된 방식을 봐서는 UPX로 패킹이 진행된 프로그램인 거 같은데 저희는 직접 실행을

한 상태로 보는 거라 언패킹의 과정은 굳이 없어도 됩니다.

 

그리고 UPX는 패킹을 풀어주는 언패커가 있어서 그렇지, 실제로 게임이나 다른 프로그램을

보실 때엔 사실상 언패커가 없다고 봐야 하기 때문에 Ollydbg를 쓰기는 힘듭니다.

물론 이렇게 분석할 프로그램을 실행한 후 메모리 전체를 Dump 떠서 볼 수는 있겠습니다만

프로그램의 크기가 크면 그마저도 쉽지는 않죠.

 

우선 이 프로그램에서 Name과 Serial 둘 다 뭐 아무거나 써보고 Check를 눌러봅시다.

 

크랙미

 

이름이 6글자 이상 길이가 되어야 한다고 하네요.

우선 뭐 그건 모르겠고 이 문구를 확인했으니 문구를 한 번 스캔해 봅시다.

 

크랙미

 

우선 나오는 걸 확인할 수 있었고 이것을 메모리뷰로 잠깐 열어보겠습니다.

주변에 다른 문구들이 있을 확률이 높아요.

 

크랙미

 

주변에 바로 Congratz! You cracked the CFF CrackMe #4 !... 문구가 있는 걸 확인했습니다.

우선 저게 성공했다는 문구를 표기하는 거일 거고 저 문구를 사용하는 곳 근처에 성공 조건이

붙어 있겠죠. 그러면 Congratz에서 C 에다가 클릭을 하고 우클릭하고 맨 밑에를 보죠.

 

크랙미

 

이 문구의 첫 시작 주소를 테이블 리스트에 추가하겠다는 건데 눌러줍니다.

그리고 00457F38라는 주소가 있을 텐데 이 주소를 복사 후 취소를 누릅니다.

그리고 어셈블리 스캔을 진행해 줍니다.

 

어셈블리 스캔을 모른다면 밑의 글 천천히 읽어주시면 있습니다.

 

 

8. API 함수를 통한 리버싱 & 크랙

API는 함수라고 생각하자. 기존 글에서 함수라는 말은 많이 봤을 겁니다. 명령어들의 집합 정도라고 설명을 드렸었죠. 컴퓨터의 운영체제가 돌아가는 데에도 당연히 이 수많은 함수들이 사용이

poppintip.co.kr

 

크랙미

 

문구를 어셈블리 스캔 했을 때 다음과 같은 주소가 나왔습니다.

그러면 이 함수가 클리어를 했든, 클리어를 못했든 특정 조건에 맞게 메시지 박스를 출력하는 곳이겠죠.

살짝 위로 올리다 보면 저희가 처음 봤든 무슨 6 Chars long... 인가 그 문구도 보이네요.

 

크랙미

 

일단 디버깅을 안 걸어도 eax는 글자 숫자를 의미하는걸 대충 알 수 있습니다.

6글자에 맞춰서 이름을 입력하게 되면 저 문구는 안 보이지만 다른 문구가 눈에 띄게 됩니다.

 

크랙미

 

네가 입력한 시리얼은 유효하지 않다는 말인 거 같네요.

뭐 사실 이 조건문을 nop (아무것도 하지 않겠다는 명령어)으로 바꿔 버려도 크랙 자체는 끝날 겁니다.

하지만 이렇게 끝내면 반쪽짜리 공부니까 뭔 시리얼 번호를 써야 올바르게 통과되는지까지 한 번 봅시다.

그러면 이 조건문 위를 살짝 올려다 뭐 어떤 조건들에 의해 건드려지는지 봅시다.

 

크랙미

뭔가 보면 애매한 거 같습니다.

jne 위에 보통 cmp가 있어야 할 텐데.. 왜 없지..? 이렇게 생각을 할 만도 하거든요.

그러면 우선 jne 위에 있는 call 함수 안을 좀 봐야겠죠.

 

크랙미

 

이렇게 디버깅을 걸어서 메시지박스를 띄우면 걸릴 겁니다.

그러면 여기서 F7을 누르면 call 함수 안으로 들어가 줍니다.

그러면 찬찬히 뜯어보면 밑의 순서대로 진행이 됩니다.

 

CrackMe#4.exe+3B9E - 8B 57 FC              - mov edx,[edi-04]
CrackMe#4.exe+3BA1 - 29 D0                 - sub eax,edx
CrackMe#4.exe+3BA3 - 77 02                 - ja CrackMe#4.exe+3BA7

 

CrackMe#4.exe+3BA7 - 52                    - push edx
CrackMe#4.exe+3BA8 - C1 EA 02              - shr edx,02 { 2 }
CrackMe#4.exe+3BAB - 74 26                 - je CrackMe#4.exe+3BD3

 

CrackMe#4.exe+3BD3 - 5A                    - pop edx
CrackMe#4.exe+3BD4 - 83 E2 03              - and edx,03 { 3 }
CrackMe#4.exe+3BD7 - 74 22                 - je CrackMe#4.exe+3BFB
CrackMe#4.exe+3BD9 - 8B 0E                 - mov ecx,[esi]
CrackMe#4.exe+3BDB - 8B 1F                 - mov ebx,[edi]
CrackMe#4.exe+3BDD - 38 D9                 - cmp cl,bl
CrackMe#4.exe+3BDF - 75 41                 - jne CrackMe#4.exe+3C22
CrackMe#4.exe+3BE1 - 4A                    - dec edx
CrackMe#4.exe+3BE2 - 74 17                 - je CrackMe#4.exe+3BFB
CrackMe#4.exe+3BE4 - 38 FD                 - cmp ch,bh
CrackMe#4.exe+3BE6 - 75 3A                 - jne CrackMe#4.exe+3C22

 

CrackMe#4.exe+3C22 - 5F                    - pop edi
CrackMe#4.exe+3C23 - 5E                    - pop esi
CrackMe#4.exe+3C24 - 5B                    - pop ebx
CrackMe#4.exe+3C25 - C3                    - ret 

 

대충 보면 edx 가지고 장난질을 치고 있는 걸 확인할 수 있습니다.

그러면 jne 조건문에서 edx가 0인지 아닌지를 검사하는 거로 볼 수 있겠네요.

edx 중점으로 보면 된다는 걸 기억하고 아까 jne 조건문에서 조금 더 위를 올려서 보죠.

 

CrackMe#4.exe+57DC9 - A1 44B84500           - mov eax,[CrackMe#4.exe+5B844] { (00C3B1CC) }
CrackMe#4.exe+57DCE - E8 FDFBFAFF           - call CrackMe#4.exe+79D0
CrackMe#4.exe+57DD3 - 6B C0 02              - imul eax,eax,02
CrackMe#4.exe+57DD6 - 73 05                 - jae CrackMe#4.exe+57DDD
CrackMe#4.exe+57DD8 - E8 AFADFAFF           - call CrackMe#4.exe+2B8C
CrackMe#4.exe+57DDD - 33 D2                 - xor edx,edx
CrackMe#4.exe+57DDF - 52                    - push edx
CrackMe#4.exe+57DE0 - 50                    - push eax
CrackMe#4.exe+57DE1 - A1 40B84500           - mov eax,[CrackMe#4.exe+5B840] { (1374) }
CrackMe#4.exe+57DE6 - 99                    - cdq 
CrackMe#4.exe+57DE7 - 03 04 24              - add eax,[esp]
CrackMe#4.exe+57DEA - 13 54 24 04           - adc edx,[esp+04]
CrackMe#4.exe+57DEE - 71 05                 - jno CrackMe#4.exe+57DF5
CrackMe#4.exe+57DF0 - E8 97ADFAFF           - call CrackMe#4.exe+2B8C
CrackMe#4.exe+57DF5 - 83 C4 08              - add esp,08 { 8 }
CrackMe#4.exe+57DF8 - 50                    - push eax
CrackMe#4.exe+57DF9 - C1 F8 1F              - sar eax,1F { 31 }
CrackMe#4.exe+57DFC - 3B C2                 - cmp eax,edx
CrackMe#4.exe+57DFE - 58                    - pop eax
CrackMe#4.exe+57DFF - 74 05                 - je CrackMe#4.exe+57E06
CrackMe#4.exe+57E01 - E8 7EADFAFF           - call CrackMe#4.exe+2B84
CrackMe#4.exe+57E06 - A3 40B84500           - mov [CrackMe#4.exe+5B840],eax { (1374) }
CrackMe#4.exe+57E0B - 8D 55 E4              - lea edx,[ebp-1C] 
CrackMe#4.exe+57E0E - A1 40B84500           - mov eax,[CrackMe#4.exe+5B840] { (1374) }
CrackMe#4.exe+57E13 - E8 2CF9FAFF           - call CrackMe#4.exe+7744
CrackMe#4.exe+57E18 - 8B 45 E4              - mov eax,[ebp-1C]
CrackMe#4.exe+57E1B - 50                    - push eax
CrackMe#4.exe+57E1C - 8D 55 FC              - lea edx,[ebp-04] 
CrackMe#4.exe+57E1F - 8B 83 DC020000        - mov eax,[ebx+000002DC]
CrackMe#4.exe+57E25 - E8 B6C0FCFF           - call CrackMe#4.exe+23EE0 < 여기 체크
CrackMe#4.exe+57E2A - 8B 55 FC              - mov edx,[ebp-04]
CrackMe#4.exe+57E2D - 58                    - pop eax
CrackMe#4.exe+57E2E - E8 51BDFAFF           - call CrackMe#4.exe+3B84 // 조건에 맞는 시리얼인지 검사
CrackMe#4.exe+57E33 - 75 1A                 - jne CrackMe#4.exe+57E4F // Congratz 조건 , edx로 구분

 

위에서 여기 체크라고 써놨습니다. 말 그대로 여기 체크해 보면 답 나올 겁니다.

 

크랙미

 

우선 이 edx에 담겨있는 값이 0019F838인데 밑에 보면 00C3B1E4 라는 주소가 담겨 있습니다.

이 주소를 가보면 제가 썼던 Name 이 나와 있습니다.

 

크랙미

 

이 정도 보니까 Name에 6글자 이상으로 뭘 쓰냐에 따라 시리얼번호가 달라지는 거 같네요?

제가 썼던 qwerqwer 주변 메모리뷰를 쭉 보시면 1374라는 숫자가 보이실 겁니다.

일단 이게 시리얼 번호로 의심이 되는데 qwerqwer 이 아닌 다른 걸로 변경해 보겠습니다.

 

크랙미

 

1188로 변경이 되었습니다.

이러면 이게 시리얼 번호가 맞나 보네요. bbbbbb에 1188로 시리얼번호를 써보죠.

 

크랙미

 

크랙 성공했다고 문구가 뜹니다.

근데 살짝 위를 보면 사실 디버깅 자체가 필요가 없긴 합니다.

 

CrackMe#4.exe+57E06 - A3 40B84500           - mov [CrackMe#4.exe+5B840],eax { (1188) }
CrackMe#4.exe+57E0B - 8D 55 E4              - lea edx,[ebp-1C]
CrackMe#4.exe+57E0E - A1 40B84500           - mov eax,[CrackMe#4.exe+5B840] { (1188) }

 

이름이 bbbbbb 일 때 기준인데 1188이라고 대놓고 알려주고 있죠.

그러면 이 시리얼 번호가 어떻게 해서 만들어지는지까지 보면 좋을 거 같습니다.

 

2차 해결

우선 그러면 시리얼 번호가 담기는 주소인 CrackMe#4.exe+5B840 에다가

Data BreakPoint를 걸어서 확인을 해보도록 하죠.

 

크랙미

 

0으로 초기화 돼있는 걸로 봐선 여기서 시작하는 모양입니다.

근데 여기는 Name이 6개인지 아닌지를 검사하는 곳이기에 좀 밑을 봐야 할 거 같습니다.

실질적으로 시작은 CarckMe#4.exe+57C70 이 구간부터 시작한다 봐야겠네요.

 

1번째 단어 : a

 

CrackMe#4.exe+57C87 - 3B 50 FC              - cmp edx,[eax-04] < eax-4는 6, edx는 0, 6은 글자
CrackMe#4.exe+57C8A - 72 05                 - jb CrackMe#4.exe+57C91 < 낮지 않으니 점프
CrackMe#4.exe+57C8C - E8 F3AEFAFF           - call CrackMe#4.exe+2B84
CrackMe#4.exe+57C91 - 42                    - inc edx
CrackMe#4.exe+57C92 - 0FB6 44 10 FF         - movzx eax,byte ptr [eax+edx-01] < edx를 증가시키고 다시 뻄
CrackMe#4.exe+57C97 - 6B F0 02              - imul esi,eax,02 < 2를 곱하고 그걸 esi에 넣기

 

여기서 eax는 현재 제가 닉네임을 abcdef로 설정해 놨기 때문에 a가 들어갑니다.

즉 a = 61이고 그러면 eax에 61이 들어간다는 뜻이죠. 그러면 61x2=C2 고 esi에는 C2가 들어갑니다.

그다음 봐야 할 곳이 여기인데요.

 

2번째 단어 : b

 

CrackMe#4.exe+57CC2 - 42                    - inc edx
CrackMe#4.exe+57CC3 - 0FB6 44 10 FF         - movzx eax,byte ptr [eax+edx-01]
CrackMe#4.exe+57CC8 - 6B C0 02              - imul eax,eax,02
CrackMe#4.exe+57CCB - 71 05                 - jno CrackMe#4.exe+57CD2
CrackMe#4.exe+57CCD - E8 BAAEFAFF           - call CrackMe#4.exe+2B8C
CrackMe#4.exe+57CD2 - 03 F0                 - add esi,eax

 

구조상으론 위랑 별반 다를 거 없죠?

그런데 한 가지가 추가됐습니다. 바로 add esi, eax가 생겼네요.

즉 1번째 단어였던 a가 저 식에 의해 esi가 C2인 상태에서 2번째 단어식을 보는 겁니다.

그러면 b = 62이고 eax에는 62x2=C4 고 기존의 esi인 C2+C4=186이 들어갑니다.

이런 식으로 6개를 반복합니다.

 

그러면 제가 abcdef를 썼기 때문에

이 식을 다 반복했을 경우 esi에는 C2+C4+C6+C8+CA+CC = 4AA 가 들어갈 겁니다.

확인을 한 번 해보죠.

 

크랙미

 

보시면 6개의 연산이 끝난 후 esi에는 4AA가 들어가 있는 상태입니다.

그다음 이 esi에 담긴걸 CrackMe#4.exe+5B840 에다가 넣어둡니다.

이후 어셈을 보면 다음과 같습니다.

 

CrackMe#4.exe+57DC9 - A1 44B84500           - mov eax,[CrackMe#4.exe+5B844] { (00C3B1CC) }
CrackMe#4.exe+57DCE - E8 FDFBFAFF           - call CrackMe#4.exe+79D0
CrackMe#4.exe+57DD3 - 6B C0 02              - imul eax,eax,02
CrackMe#4.exe+57DD6 - 73 05                 - jae CrackMe#4.exe+57DDD
CrackMe#4.exe+57DD8 - E8 AFADFAFF           - call CrackMe#4.exe+2B8C
CrackMe#4.exe+57DDD - 33 D2                 - xor edx,edx
CrackMe#4.exe+57DDF - 52                    - push edx
CrackMe#4.exe+57DE0 - 50                    - push eax
CrackMe#4.exe+57DE1 - A1 40B84500           - mov eax,[CrackMe#4.exe+5B840] { (1194) }

 

다시 eax에 무언가를 넣는데, 00C3B1CC를 가면 제가 설정해 놓은 abcdef 가 보이네요.

그리고 밑의 call 함수를 진행하면 eax에 6이 반환됩니다.

6인 걸로 보아 글자수일 거고 6x2=C가 됩니다.

그리고 밑에 push edx와 push eax로 스택을 2번 밀어내고 eax에 아까 4AA를 넣습니다.

이 4AA와 글자수 6개 x2를 한 C를 더합니다. 그러면 4B6이 되죠.

이렇게 되면 abcdef에 대한 시리얼 넘버가 완성이 됩니다. 즉 1206이죠.

 

크랙미

 

보시면 abcdef와 1206으로 크랙에 성공했음을 알 수 있습니다.

그러면 이 식에 대입해서 a1b2c3d4의 시리얼 번호를 한 번 계산해 봄으로써 식이 맞는지

검증해 보도록 합시다.

 

a1b2c3d4 = 61 31 62 32 63 33 64 34

C2+62+C4+64+C6+66, 6글자까지만 계산이 되므로 64와 34는 버려지고 8글자라 8x2=10

그러면 C2+62+C4+64+C6+66+10=388, 10진수로 하면 904

맞는지 확인해 보죠. 디버깅 같은 건 따로 안 했습니다. 순수 로직으로만 계산 한 겁니다.

 

크랙미

 

네 맞네요.

이렇게 이 프로그램의 시리얼 넘버 만드는 로직까지 분석이 다 됐습니다.

크랙 자체에만 목표를 두는 경우면 크게 분석할 일이 없겠지만 로직까지 이해를 해보고자 하면

생각보다 시간이 많이 걸릴 거예요.

 

리버싱 공부를 하실 때는 천천히 시간을 들여서 최대한 로직까지 이해해보는 과정을

겪으면 실력 향상에 크게 도움이 됩니다. 

 

근데 당장에 적당한 수준의 프로그램 구하는 게 힘들어서 저도 시간을 좀 써야 할 거 같습니다..

 

 

12. 크랙미 세 번째

연습은 꾸준히 여태 올린 글들을 정독 하면서 꾸준히 해오셨으면 이번 문제도 크게 어려울 건 없어보입니다. 이번엔 2010년때 파도콘의 예선 문제였던걸 한 번 풀어보도록 하죠. * 파도콘이란? 한

poppintip.co.kr

 

728x90