
Google의 Gemma 4 E4B 로컬 AI 모델을 사용하여 Ghidra로 Windows 크랙미를 리버스 엔지니어링하는 방법에 대한 단계별 튜토리얼. 로컬 추론 설정 및 자동 함수/변수 이름 변경을 포함합니다.
저는 Google이 출시한 새로운 Gemma E4B 오픈 가중치 로컬 모델을 가지고 놀던 중, 로컬 오프라인 리버스 엔지니어링 시나리오에서 놀라운 성공을 거두는 것을 보았습니다. 이 튜토리얼을 작성하여 로컬 AI가 이제 많은 기본적인 리버싱 작업에 충분히 좋다는 사실을 알리고, 앞으로 상황이 빠르게 개선될 것이라는 점을 전파하고자 합니다.
새로운 바이너리를 리버싱할 때 가장 지루한 부분 중 하나는 처음에 중요한 함수와 변수에 대한 통찰력이 전혀 없을 때입니다. 리버서들이 시작하기 위해 사용하는 많은 트릭이 있으며, 문자열 참조 확인, 바이너리 디핑, 또는 유사 함수 매칭 등이 있습니다.
AI는 이 부분에서 매우 도움이 되며, 저는 개인적으로 OpenAI API를 사용하여 바이너리를 마크업하거나 디컴파일러 출력을 정리하는 데 큰 성공을 거두었습니다. 그러나 이러한 API를 사용하는 데는 몇 가지 단점이 있습니다:
비용 - 디컴파일 및 디스어셈블리는 엄청난 양의 토큰을 생성합니다. API는 토큰당 요금을 부과하므로 더 큰 바이너리를 분석하는 데 상당한 비용이 들 수 있습니다. 매주 업데이트되는 많은 바이너리를 가진 대규모 대상을 다루는 경우 이러한 비용은 빠르게 누적되며, 취미 리버스 엔지니어에게는 부담스럽습니다.
개인정보 - 원격 API를 사용할 때 AI 호스트는 사용자가 무엇을 하고 있는지 파악할 수 있습니다. 이는 일부 전문적인 시나리오에서는 사용이 불가능합니다.
제어 - 원격 API에 의존할 때 어떤 모델이 제공되는지, 또는 모델의 품질이 어떤지에 대해 제어할 수 없습니다. 중요한 작업에 의존하는 경우, 필요할 때 속도가 느려지거나 다운되거나 출력 품질이 쓸모없을 정도로 저하될 때 문제가 될 수 있습니다.
자체 로컬 AI 모델을 실행하면 이러한 문제점 중 일부를 해결할 수 있습니다:
비용 - 호스팅 서비스에 의존하는 것보다 로컬 모델을 실행하는 것이 훨씬 저렴할 수 있습니다. 로컬 모델이 좋은 제공업체의 모델보다 작고 느릴 수 있지만, 충분히 좋고 합리적인 시간 내에 실행된다면, 특히 단순한 작업을 위해 많은 양의 데이터를 처리하는 경우 자체 모델을 실행하여 비용을 절약하는 것이 합리적일 수 있습니다.
개인정보 - 모델을 로컬에서 실행하면 네트워크 호출이 발생하지 않으며 개인정보를 완전히 통제할 수 있습니다. 아무도 사용자가 자신의 기기에서 모델을 무엇에 사용하는지 볼 수 없습니다.
제어 - 오픈 가중치 모델의 장점은 아무도 당신에게서 그것을 빼앗을 수 없다는 것입니다. OpenAI나 Anthropic은 언젠가 가격 인상이나 API를 명시적으로 제거함으로써 SotA 모델을 사용할 수 없게 만들 수 있습니다. 그러나 오픈 가중치 모델을 사용하면 좋든 나쁘든 자신의 운명을 통제할 수 있습니다.
하지만 로컬 AI 모델에는 단점이 있습니다:
크기 - 모델이 클수록 더 똑똑합니다. 그러나 대부분의 큰 모델은 일반 소비자 하드웨어에 맞지 않습니다. 따라서 로컬 모델을 실행한다면 SotA(State-of-the-Art) 모델보다 10배에서 100배 작은 모델을 실행할 가능성이 높습니다. 이러한 크기 감소는 모델의 지능 감소로 직접 이어져 ChatGPT/Codex 또는 Claude와 같은 SotA 모델에서 사람들이 당연하게 여기는 많은 작업에 부적합하게 만듭니다.
속도 - 로컬 모델은 AI API를 사용할 때보다 기기에서 더 느리게 실행될 가능성이 높습니다. 이는 다시 소비자 하드웨어의 한계와 API 제공자가 수행할 수 있는 기법들이 일반적으로 사용자에게는 제공되지 않기 때문입니다.
구성 - 로컬 모델을 실행하는 것은 리퍼브 노트북에 Linux를 설치하려는 것과 Apple 매장에 가서 새 Macbook Air를 사는 것의 차이와 같습니다. Codex와 Claude Code 경험은 AI의 Apple 스토어 경험입니다. 로컬 AI 모델 경험은 페도라를 쓴 차고에서 이상한 컴퓨터를 두드리며 작동시키려는 사람입니다. 최소한 다음 사항을 고려해야 합니다:
쉬운 여정이 아니며, 많은 사람들이 포기하고 로컬 AI 모델이 작업에 적합하지 않다고 가정합니다. 왜냐하면 그들은 자신의 작업에 맞는 하드웨어/모델/설정/프롬프트/하네스의 올바른 조합을 찾지 못했기 때문입니다. 많은 경우 그들이 옳지만, 이 튜토리얼이 적어도 로컬 모델이 얼마나 발전했는지, 리버스 엔지니어링에 어떻게 도움이 될 수 있는지 조명하고, 사람들이 로컬 AI에 도전하도록 영감을 주기를 바랍니다.
(압축 비밀번호는 crackmes.one입니다). 원본 링크가 다운될 경우를 대비해 리포지토리 내 대체 링크도 호스팅했습니다.
디스어셈블리 및 디컴파일을 위해 Ghidra 12.04를 사용합니다. 이를 사용하려면 OpenJDK 21을 설치해야 합니다: https://github.com/nationalsecurityagency/ghidra
이 튜토리얼을 작업하는 동안 Claude Code로 AI를 사용하여 함수와 변수 이름을 바꾸는 Ghidra 플러그인을 바이브 코딩했습니다. 플러그인은 여기에서 다운로드할 수 있습니다: https://github.com/markoglasgow/Ghidra_FastAIRenamer_Plugin
설치하려면 zip 파일 ghidra_12.0.4_PUBLIC_20260427_FastAIRenamerPlugin.zip을 ${GHIDRA_HOME}\Extensions\Ghidra로 이동한 다음 ${GHIDRA_HOME}\ghidraRun.bat를 실행하여 Ghidra를 실행하세요. 플러그인을 활성화하려면 초기 Ghidra 화면의 상단 메뉴에서 File -> Install Extensions을 선택한 다음 플러그인 브라우저에서 FastAIRenamerPlugin 옆의 체크박스를 선택하고 Ok를 클릭하세요. Ghidra가 재시작하라는 메시지를 표시하므로 즉시 재시작하세요.
플러그인을 구성하려면 다음에 Ghidra가 시작될 때 상단 메뉴에서 Tools -> Run Tool -> CodeBrowser로 이동하세요. Ghidra가 "새 확장이 감지되었습니다. 구성하시겠습니까?"라고 말할 것입니다. 예를 클릭한 다음 다시 FastAIRenamerPlugin 옆의 체크박스를 선택하고 Ok를 클릭하세요. CodeBrowser가 열리면 상단 메뉴에서 Window -> Fast AI Renamer를 클릭한 다음 Config 버튼을 클릭하세요. 여기에서 AI 모델을 구성할 수 있습니다. 완료되면 플러그인 창과 빈 CodeBrowser 창을 닫으세요.
참고: 플러그인 로딩에 문제가 있으면 Ghidra에서 개발자 모드를 활성화해야 할 수 있습니다 (File -> Configure -> Developer 옆 체크박스).
참고: 플러그인이 로드되었는지 확인하려면 CodeBrowser로 이동하여 File -> Configure -> Ghidra Core -> 파란색 구성 버튼 클릭 -> "FastAIRenamer"로 필터링 -> 이름 옆의 체크박스가 선택되어 있는지 확인하면 됩니다.
참고: 플러그인을 제거하려면 먼저 CodeBrowser를 열고 File -> Configure -> Ghidra Core -> 파란색 구성 버튼 클릭 -> "FastAIRenamer"로 필터링 -> 체크 해제 -> ok. CodeBrowser를 닫은 다음 초기 Ghidra 창에서 File -> Install Extensions -> "FastAIRenamer" 체크 해제. 마지막으로 Ghidra를 닫고 ${GHIDRA_HOME}\Extensions\Ghidra에서 ghidra_12.0.4_PUBLIC_20260427_FastAIRenamerPlugin.zip을 삭제하세요. 확장이 삭제되었는지 확인하려면 다음에 Ghidra를 실행할 때 초기 창에서 Help -> Runtime Information -> Extension Points -> "FastAIRenamer"로 필터링하여 아무것도 표시되지 않는지 확인하세요. 휴.
마지막으로, 필요할 때 크랙미에 대한 솔루션을 바이브 코딩할 수 있도록 Visual Studio 또는 다른 C++ 개발 환경이 설정되어 있는지 확인하세요.
사람들의 로컬 AI 설정은 하드웨어와 사용 가능한 $$$에 따라 크게 다릅니다. 제 경우:
저는 개인적으로 Nvidia GTX 3080을 사용 중이며, Cuda 13.2가 설치되어 있습니다. Cuda 버전은 Windows 터미널에서 nvcc --version을 실행하여 확인할 수 있습니다.
저는 bartowski의 bartowski 양자화 모델을 실행하고 있습니다. 미신일 수도 있지만, 분석 작업의 경우 가능한 한 양자화를 최소화하여 실행하려고 하며, 가능하면 완전히 피하려고 합니다.
저는 추론 서버로 llama.cpp를 사용하고 있으며, 특정 버전은 llama-b8893-bin-win-cuda-13.1-x64입니다.
다음 CLI 설정으로 llama.cpp를 실행하고 있습니다:```
..\llama-b8893-bin-win-cuda-13.1-x64\llama-server.exe ^
--port 8090 ^
--threads 12 ^
--n-gpu-layers 256 ^
--no-mmap ^
--model "google_gemma-4-E4B-it-Q8_0.gguf" ^
--ctx-size 32768 ^
--temp 1.0 ^
--top-k 64 ^
--top-p 0.95 ^
--offline
이는 `75 tokens/sec`를 산출하며, 로컬 AI에서 꽤 빠른 속도입니다.
## 하드웨어가 없으세요? 문제없습니다
하드웨어를 사용할 수 없거나 설정에 어려움이 있지만, 이 튜토리얼을 따라가고 싶다면 OpenRouter 로그인을 받아 무료 API 중 하나를 사용할 수 있습니다:
https://openrouter.ai/models/?q=free
Google은 현재 (한정된 기간 동안) `Gemma 4 31B`와 `Gemma 4 26B-A4B`를 무료로 제공하고 있습니다:
https://openrouter.ai/google/gemma-4-31b-it:free
https://openrouter.ai/google/gemma-4-26b-a4b-it:free
... 다만 이러한 무료 API는 느리고 신뢰할 수 없으며, 보내는 모든 데이터가 내부 분석에 기록되어 다음 학습 실행에 사용될 가능성이 높다는 점을 명심하세요. 그래도 이 튜토리얼의 목적상, 이 API를 사용하면 따라갈 수 있을 것입니다.
Ghidra 플러그인이 OpenRouter 로그인을 사용하도록 구성하려면 플러그인 설정을 열고 다음을 입력하십시오:```
Base URL: https://openrouter.ai/api/
API Key: <your OpenRouter API Key>
Model Name: qwen/qwen3-235b-a22b-2507
이 예제는 qwen3 모델에 대해 플러그인을 실행합니다 여기
압축을 풀고 crackmepls.exe를 실행하면 표준 로그인 화면이 나타납니다. 임의의 비밀번호를 입력하면 'Access Denied' 메시지가 표시됩니다:```
User: marko
Pass: 123
Access denied
`ghidraRun.bat`을 실행하여 Ghidra를 엽니다. 툴바에서 `File -> New Project`를 선택하고, `Non-Shared Project`를 선택한 상태로 두고 `Next >>`를 클릭한 다음, 빈 프로젝트 디렉터리를 선택하고 프로젝트 이름을 지정합니다. 그런 다음 `Finish`를 클릭합니다.
다음으로, `File -> Import File`을 클릭한 다음 `crackmepls.exe`를 선택하여 프로젝트에 추가합니다. Ghidra가 파일에 대한 세부 정보를 팝업으로 표시하며, 파일이 `windows`용 `x86:LE:64:default:windows`용 `Portable Executable (PE)` 파일임을 알려줍니다. 아무것도 변경하지 않고 `OK`를 클릭하여 수락합니다. 잠시 지연된 후 파일에 대한 추가 세부 정보가 다시 팝업되며, 다시 `OK`를 클릭하여 수락합니다. 마지막으로 프로젝트에서 `crackmepls.exe`를 더블 클릭하여 Code Browser를 열고 디스어셈블을 시작합니다.