← 목록으로

크랙미(Crackme) 실습 방법론

[Rev] 리버싱 · 작성: 2026-07-19 19:34:18 · 수정: 2026-07-21 23:32:17 · 조회 12

크랙미(Crackme)를 마주하고 무작정 디버거부터 켜면 방향 없이 헤매기 쉽다. 이 글은 지금까지 다룬 정적/동적 분석, 어셈블리 읽기 기법을 하나의 문제 해결 순서로 엮는다.

1단계: 정적 분석으로 지도 그리기

정적 분석 글에서 다룬 순서 그대로 시작한다.

  1. checksec/file로 아키텍처와 보호 기법 확인 — 크랙미는 대개 익스플로잇이 목적이 아니라 로직 분석이 목적이라 카나리/NX보다는 스트리핑 여부가 더 중요한 정보다
  2. strings로 "Correct!", "Wrong password" 같은 성공/실패 메시지 문자열을 먼저 찾는다 — 이 문자열이 코드のどこ에서 참조되는지가 인증 로직의 위치를 알려주는 가장 빠른 단서다
  3. Ghidra/IDA로 그 문자열을 참조하는 함수를 역추적(Cross-reference, XREF) — "이 문자열을 누가 쓰는가"를 따라가면 곧바로 check_password() 같은 핵심 함수에 도달한다

2단계: 어셈블리에서 비교 로직 찾기

어셈블리어 읽기 기초 글에서 다룬 cmp+jcc 패턴을 그 함수 안에서 찾는다.

call  transform_input      ; 사용자 입력을 어떤 알고리즘으로 변환
cmp   eax, 0x1337           ; 변환 결과를 정답과 비교
jne   print_fail
call  print_success

여기서 두 갈래로 나뉜다 — **정답이 하드코딩된 상수와의 단순 비교(위 예시)**라면 그 상수만 읽으면 끝나지만, 입력값 자체를 어떤 알고리즘(해시, XOR, 커스텀 변환)으로 가공한 뒤 비교하는 경우가 대부분이라, transform_input 안으로 더 들어가야 한다.

3단계: 동적 분석으로 가설 검증

동적 분석 글에서 다룬 대로 transform_input 호출 직후에 브레이크포인트를 걸고, 실제 입력값이 어떻게 변환되는지 레지스터/메모리 값을 직접 관찰한다. 정적으로 어셈블리만 봐서는 루프의 반복 횟수나 실제 중간값을 파악하기 어려운 경우가 많아서, 이 단계에서 "가설(아마 이런 알고리즘일 것이다)"을 실제 실행으로 확인하는 과정이 필수다.

4단계: 두 가지 해결 전략 — 패치 vs 키젠

패치(Patch): 검사 자체를 무력화

jne(0x75)를 je(0x74)로 바꾸거나, 그냥 nop(0x90)으로 덮어써서 분기 자체를 무의미하게 만드는 방식이다. 가장 빠르지만, "어떤 입력을 넣어도 통과하는" 바이너리를 만드는 것이지 "정답을 알아내는 것"은 아니다 — 크랙미의 의도(알고리즘을 역산해서 정답을 찾는 것)와는 다른 접근이라는 걸 인지하고 써야 한다.

키젠(Keygen): 알고리즘을 그대로 재구현

transform_input의 로직을 완전히 이해한 뒤, **그 알고리즘을 파이썬 등으로 그대로 재구현해서 역산(정답을 만족하는 입력값을 계산)**하는 방식이다. 해시 함수처럼 일방향이면 역산이 불가능하고 브루트포스가 필요할 수도 있고, 단순 XOR/치환이면 역함수를 그대로 짜면 된다. 진짜 리버싱 실력을 요구하는 건 이쪽이다.

여기서 끝나지 않는다

크랙미를 "정답을 맞히는 게임"이 아니라 **"문자열 → 비교 로직 → 변환 알고리즘"으로 이어지는 역추적 경로를 순서대로 좁혀가는 작업"**으로 이해하면, 왜 리버싱 실력이 결국 정적/동적 분석을 얼마나 유기적으로 오가며 가설을 세우고 검증하는지에 달려있는지가 같은 논리로 설명된다.

리버싱 카테고리의 글 (9/11)

  1. 리버싱이란 무엇인가: 정적 분석 기초
  2. 어셈블리어 읽기 기초 (x86-64)
  3. 동적 분석: 디버거로 실행 흐름 추적하기
  4. 안티 디버깅 / 안티 리버싱 기법과 우회
  5. 패킹과 언패킹: 실행 파일을 압축/암호화해서 숨기기
  6. Frida로 동적 계측/후킹하기
  7. 안드로이드 앱 리버싱: APK 분석 기초
  8. iOS 앱 리버싱 기초
  9. 크랙미(Crackme) 실습 방법론
  10. PE 포맷 내부 구조: Windows 실행 파일 뜯어보기
  11. 코드 난독화 해제: Control Flow Flattening 분석하기
← iOS 앱 리버싱 기초 PE 포맷 내부 구조: Windows 실행 파일 뜯어보기 →