리버스 엔지니어링은 항상 사이버보안에서 가장 지적으로 까다로운 분야 중 하나였습니다. 분석가들은 어셈블리 명령어를 관찰하고, 데이터 구조를 정신적으로 재구성하고, 스트립된 바이너리를 통해 실행 경로를 추적하는 데 수 시간을 보냅니다. 인지적 부담은 엄청나며, 숙련된 리버스 엔지니어에 대한 수요는 공급을 훨씬 초과합니다.
바로 이 격차가 대규모 언어 모델이 자리를 잡고 있는 곳입니다. 지난 2년 동안 AI 지원 리버스 엔지니어링은 호기심에서 합법적인 전력 배수기로 발전했습니다. 몇 분 만에 수천 개의 함수를 이름 변경하는 Ghidra 플러그인, 자연어로 셸코드를 설명하는 Binary Ninja 통합, 메모리 손상 패턴에 대해 추론하는 자동화된 취약점 스캐너가 모두 오늘날 제공되고 있습니다. 이것은 추측적 기술이 아닙니다. 현역 분석가들이 의존하는 프로덕션 도구입니다.
이 가이드는 AI 증강 리버스 엔지니어링의 현재 상태, 중요한 도구들, 분석 파이프라인에 통합하기 위한 실용적 워크플로우, 그리고 신뢰하기 전에 이해해야 할 한계를 다룹니다.
AI와 리버스 엔지니어링의 교차점
리버스 엔지니어링은 근본적으로 패턴 인식과 번역 문제입니다. 기계 코드를 가져와서 점점 더 추상적인 표현으로 끌어올리고, 궁극적으로 개발자의 원래 의도를 재구성합니다. LLM은 정확히 이런 종류의 구조화된 번역에 탁월합니다.
현재 도구를 이끄는 핵심 통찰은 디컴파일된 C 의사코드가 범용 LLM이 효과적으로 추론할 수 있을 만큼 자연어에 충분히 가깝다는 것입니다. Ghidra나 IDA Pro가 디컴파일러 출력을 생성할 때, 그 출력은 구문적으로 유효한 C입니다. 수십억 줄의 소스 코드로 훈련된 LLM은 함수 목적을 추론하고, 의미 있는 변수 이름을 제안하고, 일반적인 라이브러리 패턴을 식별하고, 의심스러운 구문을 표시할 수 있습니다.
세 가지 AI 지원 범주가 등장했습니다:
- 시맨틱 강화 — 디컴파일된 코드의 동작 분석을 기반으로 함수, 변수, 타입 이름 변경
- 설명과 요약 — 코드 블록이 수행하는 작업에 대한 자연어 설명 생성
- 취약점 탐지 — 버퍼 오버플로우, use-after-free, 포맷 스트링 버그 및 기타 악용 가능한 조건과 관련된 패턴 식별
각 범주는 서로 다른 신뢰성 프로파일을 가지고 있습니다. 시맨틱 강화는 잘 알려진 라이브러리 코드에 대해 놀라울 정도로 정확합니다. 설명 품질은 모델 능력에 따라 달라집니다. 취약점 탐지는 가장 신뢰성이 낮지만 가장 활발하게 연구되고 있습니다.
AI 지원 디컴파일: Ghidra 플러그인
Ghidra의 개방형 아키텍처와 Python/Java 스크립팅 지원은 이를 AI 리버스 엔지니어링 실험의 주요 플랫폼으로 만들었습니다. 여러 플러그인이 일상적 도구로 성숙했습니다.
GhidrAssist
GhidrAssist는 Ghidra를 LLM API(OpenAI, Anthropic 또는 Ollama를 통한 로컬 모델)에 직접 연결하고 현재 선택된 함수의 컨텍스트 분석을 제공합니다. 디컴파일된 출력과 교차 참조 및 문자열 데이터를 모델에 보내고 구조화된 분석을 반환합니다.
설치는 간단합니다:
git clone https://github.com/unkmc/GhidrAssist.git
cp -r GhidrAssist $GHIDRA_INSTALL_DIR/Extensions/Ghidra/
API 키를 구성한 후 모든 함수를 마우스 오른쪽 버튼으로 클릭하고 "Explain Function" 또는 "Suggest Names"를 선택할 수 있습니다. 플러그인은 호출 규약, 가져온 심볼, 교차 참조에 대한 컨텍스트와 함께 디컴파일된 C를 보냅니다.
GhidrAssist를 특히 효과적으로 만드는 것은 컨텍스트 윈도우 관리입니다. 바이너리의 전체 디컴파일을 프롬프트에 덤프하는 대신, 대상 함수, 즉시 호출자와 피호출자, 관련 문자열 참조를 포함하는 집중된 쿼리를 구성합니다. 이 집중된 접근 방식은 순진한 프롬프팅보다 훨씬 더 나은 결과를 생성합니다.
GEPETTO
GEPETTO(GPT Explanation of ProcEdures To Transform Operations)는 최초의 프로덕션 품질 Ghidra AI 플러그인 중 하나였습니다. 함수 설명과 이름 변경에 특화됩니다:
import ghidra_bridge
b = ghidra_bridge.GhidraBridge()
current_function = b.currentProgram.getFunctionManager().getFunctionContaining(b.currentAddress)
decomp = b.DecompInterface()
decomp.openProgram(b.currentProgram)
results = decomp.decompileFunction(current_function, 60, None)
c_code = results.getDecompiledFunction().getC()
prompt = f"""Analyze this decompiled C function. Suggest:
1. A descriptive function name
2. Parameter names and likely types
3. A one-paragraph explanation of its purpose
```c
{c_code}
```"""
GEPETTO는 배치 처리에 탁월합니다. 바이너리의 전체 함수 목록에서 실행하여 FUN_00401000 레이블의 바다를 decrypt_config_buffer나 parse_c2_response 같은 의미 있는 이름으로 변환하는 첫 번째 이름 변경 패스를 얻을 수 있습니다. 일반적인 패턴(파일 I/O, 네트워크 작업, 암호화 루틴)에 대한 정확도는 일반적으로 80%를 초과합니다.
VulChatGPT
VulChatGPT는 취약점 식별에 특화된 GEPETTO 개념을 확장합니다. 일반적인 취약점 패턴에 대해 디컴파일된 함수를 분석하고 구조화된 보고서를 생성합니다:
vulnerability_prompt = """
Analyze this decompiled function for security vulnerabilities.
Focus on:
- Buffer overflow conditions (unchecked memcpy, strcpy, sprintf)
- Integer overflow/underflow in size calculations
- Use-after-free patterns
- Format string vulnerabilities
- Race conditions in shared resource access
- Unvalidated input used in sensitive operations
"""
여기서의 가치는 LLM이 숙련된 분석가가 놓칠 취약점을 잡는다는 것이 아닙니다. 오히려 트리아지를 가속화합니다. 2,000개의 함수가 있는 바이너리를 분석할 때, 가장 의심스러운 50개의 함수를 표시하는 자동화된 첫 번째 패스는 수일간의 수동 검토를 절약합니다.
Binary Ninja의 Sidekick과 AI 분석
Binary Ninja는 AI 지원에 대해 더 통합된 접근 방식을 취했습니다. 타사 플러그인에 의존하는 대신 Vector 35는 AI 기능을 플랫폼에 직접 구축했습니다.
Sidekick은 Binary Ninja 내에서 컨텍스트를 인식하는 대화형 채팅 인터페이스를 제공합니다. 어떤 함수를 보고 있는지, 현재 선택이 무엇인지, 어떤 분석이 이미 수행되었는지를 알고 있습니다.
from binaryninja import BinaryViewType
bv = BinaryViewType.get_view_of_file("/path/to/binary")
for func in bv.functions:
if func.name.startswith("sub_"):
analysis = bv.query_sidekick(f"Analyze function at {hex(func.start)} and suggest a name")
if analysis.confidence > 0.8:
func.name = analysis.suggested_name
Binary Ninja의 타입 전파 엔진은 AI 컨텍스트에 직접 피드되므로 모델은 원시 디컴파일된 코드뿐만 아니라 복구된 타입, 구조체, enum 값도 봅니다.
IDA Pro AI 통합
상용 리버스 엔지니어링에서 IDA Pro의 지배적 위치는 상당한 AI 통합 노력을 끌어들였습니다.
BinaryAI
BinaryAI는 임베딩 기반 유사도 검색을 사용하여 알려진 오픈소스 코드 데이터베이스에 대해 함수를 매칭합니다. LLM에게 함수가 무엇을 하는지 추측하도록 요청하는 대신, BinaryAI는 함수의 제어 흐름 그래프와 데이터 흐름 패턴의 벡터 임베딩을 계산한 다음 인덱싱된 코퍼스에서 유사한 함수를 검색합니다.
import binaryai as bai
import idautils, idc
client = bai.Client(token="your_api_token")
func_addr = idc.get_screen_ea()
func_bytes = idc.get_bytes(func_addr, idc.get_func_attr(func_addr, idc.FUNCATTR_END) - func_addr)
results = client.search_function(func_bytes)
for match in results[:5]:
print(f"Match: {match.name} from {match.source} (confidence: {match.score:.2f})")
이 접근 방식은 LLM 기반 분석을 보완합니다. BinaryAI는 정적으로 링크된 라이브러리 함수(zlib, OpenSSL, SQLite) 식별에 탁월하고, LLM은 사용자 정의 애플리케이션 로직을 이해하는 데 더 뛰어납니다.
자동화된 함수 명명 및 타입 복구
함수 명명은 AI가 리버스 엔지니어링에서 가장 즉각적이고 실질적인 가치를 제공하는 곳입니다. 워크플로우는 간단하지만 강력합니다:
- 함수를 의사코드로 디컴파일
- 의사코드와 컨텍스트(문자열, 임포트, 교차 참조)를 LLM에 전송
- 제안된 이름과 매개변수 타입에 대한 응답 파싱
- 제안 사항을 적용하고 호출 그래프를 통해 타입 전파
전파 단계가 중요합니다. FUN_00405a20이 실제로 aes_cbc_encrypt임을 올바르게 식별하면, 매개변수(키 버퍼, IV, 평문, 길이)에 대한 타입 정보가 모든 호출자에게 전파되어 전체 바이너리의 가독성을 극적으로 향상시킵니다.
from ghidra.program.model.data import StructureDataType, PointerDataType
from ghidra.program.model.symbol import SourceType
def apply_crypto_types(func, analysis_result):
dtm = currentProgram.getDataTypeManager()
if analysis_result.get("struct_type"):
struct = StructureDataType(analysis_result["struct_name"], 0)
for field in analysis_result["fields"]:
struct.add(dtm.getDataType(field["type"]), field["size"], field["name"], field["comment"])
dtm.addDataType(struct, None)
func.setName(analysis_result["name"], SourceType.USER_DEFINED)
바이너리에서의 LLM 기반 취약점 탐지
컴파일된 코드의 취약점 탐지는 전통적으로 패턴 매칭(Flawfinder, RATS) 또는 무거운 형식적 방법(심볼릭 실행, 추상 해석)에 의존해왔습니다. LLM은 중간 지대를 제공합니다: 구문적 패턴 매칭과 형식적 검증 사이의 수준에서 코드 의미론에 대해 추론할 수 있습니다.
핵심 한계는 오탐률입니다. LLM은 잠재적 문제를 과도하게 표시하는 경향이 있으며, 특히 코드의 다른 곳에서 경계 검사로 인해 실제로 안전한 포인터 산술 주변에서 그렇습니다. LLM 취약점 보고서를 항상 수동 조사를 위한 단서로 취급하고, 확인된 발견으로 취급하지 마세요.
Capstone, Unicorn, Keystone 도구킷
AI가 등장하기 전에 Capstone/Unicorn/Keystone 스위트는 프로그래밍 방식의 바이너리 분석을 위한 기반을 확립했습니다. 이 도구들은 여전히 필수적인 빌딩 블록이며 LLM 지원 워크플로우와 잘 결합됩니다.
Capstone은 다중 아키텍처를 지원하는 디스어셈블리 프레임워크입니다:
from capstone import Cs, CS_ARCH_X86, CS_MODE_64
CODE = b"\x55\x48\x89\xe5\x48\x83\xec\x10\x89\x7d\xfc\x8b\x45\xfc\x83\xc0\x01"
md = Cs(CS_ARCH_X86, CS_MODE_64)
for insn in md.disasm(CODE, 0x1000):
print(f"0x{insn.address:x}:\t{insn.mnemonic}\t{insn.op_str}")
Unicorn은 동적 분석을 위한 CPU 에뮬레이션을 제공합니다. Keystone은 어셈블리를 처리하여 사이클을 완성합니다.
이 도구들을 LLM과 결합하는 힘은 자동화된 분석 파이프라인 구축에 있습니다. Capstone으로 디스어셈블하고, 출력을 시맨틱 분석을 위해 LLM에 보내고, LLM의 제안을 사용하여 Unicorn 에뮬레이션 경로를 안내하고, Keystone을 사용하여 테스트 페이로드를 생성할 수 있습니다.
PyGhidra: Python 우선 리버스 엔지니어링 파이프라인
PyGhidra(이전의 pyhidra)는 GUI를 실행하지 않고 Ghidra의 분석 엔진을 Python 라이브러리로 실행할 수 있게 합니다. 이는 자동화된 파이프라인 구축에 변혁적입니다:
import pyghidra
with pyghidra.open_program("/path/to/malware.bin") as flat_api:
program = flat_api.getCurrentProgram()
func_manager = program.getFunctionManager()
results = {}
for func in func_manager.getFunctions(True):
decomp = flat_api.DecompInterface()
decomp.openProgram(program)
decomp_result = decomp.decompileFunction(func, 120, None)
if decomp_result.depiledFunction():
c_code = decomp_result.getDecompiledFunction().getC()
analysis = analyze_with_llm(c_code)
results[func.getName()] = analysis
generate_analysis_report(results, "/path/to/report.json")
PyGhidra는 CI/CD 스타일 바이너리 분석을 가능하게 합니다. 새로운 맬웨어 샘플을 자동으로 처리하고, AI 강화 분석 보고서를 생성하고, 고우선순위 항목을 인간 검토를 위해 표시하는 파이프라인을 설정할 수 있습니다.
윤리적 고려사항과 한계
AI 지원 리버스 엔지니어링은 실무자들이 해결해야 할 중요한 질문을 제기합니다.
정확도와 과신. LLM은 그럴듯하게 들리지만 완전히 틀릴 수 있는 분석을 생성합니다. 모델에게 AES-128 암호화처럼 보이는 함수가 실제로는 우연히 유사한 구조를 가진 사용자 정의 XOR 암호일 수 있습니다. 검증 없이 AI 분석을 절대 신뢰하지 마세요. 가설 생성기로 취급하되 오라클로 취급하지 마세요.
지적 재산. AI를 사용하여 독점 소프트웨어를 리버스 엔지니어링하면 관할권에 따라 다른 법적 문제가 발생합니다. 미국의 DMCA에는 보안 연구와 상호 운용성에 대한 면제가 있지만 경계가 항상 명확하지는 않습니다.
모델 데이터 유출. 디컴파일된 코드를 클라우드 LLM API에 보낼 때, 그 코드는 기록되거나, 학습에 사용되거나, 소환장의 대상이 될 수 있습니다. 민감한 대상(국가 맬웨어, 기밀 바이너리, NDA 하의 고객 업무)의 경우 로컬 모델만 사용하세요.
적대적 견고성. 맬웨어 작성자들은 이미 AI 분석을 혼란시키는 기술을 탐구하고 있습니다. 군비 경쟁을 예상하세요.
기술 퇴화. AI 분석에 대한 과도한 의존은 근본적인 리버스 엔지니어링 기술을 침식시킬 수 있습니다. AI를 학습의 대체가 아닌 가속기로 사용하세요.
미래: 자율 바이너리 분석 에이전트
다음 프론티어는 다단계 바이너리 분석을 자율적으로 수행할 수 있는 에이전틱 시스템입니다. 개별 함수에 대한 개별 질문에 답변하는 대신, 이러한 시스템은 바이너리를 탐색하고, 가설을 형성하고 테스트하며, 포괄적인 분석 보고서를 생성할 것입니다.
agent:
planning_model: claude-sonnet
analysis_model: claude-sonnet
tools:
- ghidra_decompile
- ghidra_xrefs
- ghidra_strings
- unicorn_emulate
- capstone_disasm
- yara_scan
workflow:
- step: initial_triage
actions: [identify_packer, check_imports, extract_strings]
- step: function_analysis
actions: [identify_interesting_functions, analyze_top_50]
- step: vulnerability_scan
actions: [check_memory_safety, check_crypto_usage]
- step: report_generation
actions: [compile_findings, assign_severity, generate_report]
제한 요소는 모델 능력이 아니라 도구 통합 신뢰성입니다. LLM이 Ghidra API를 올바르게 호출하고, 결과를 해석하고, 다음 단계를 결정하게 하려면 에이전트 루프의 신중한 엔지니어링이 필요합니다.
내년 안에 상용 플랫폼이 에이전트 기반 분석을 핵심 기능으로 제공할 것으로 예상됩니다. AI 능력과 기본적인 리버스 엔지니어링 기초를 모두 이해하는 분석가들이 이러한 도구를 가장 효과적으로 사용할 것입니다. 기술은 전문성을 증폭합니다. 대체하지 않습니다.
오늘 시작하기
지금 바로 리버스 엔지니어링 워크플로우에 AI를 통합하고 싶다면 여기서 시작하세요:
GhidrAssist를 설치하고 선호하는 LLM 제공자로 구성하세요. 이미 수동으로 분석한 바이너리에서 사용하여 출력에 대한 신뢰를 보정하세요.
민감한 작업을 위해 Ollama로 로컬 모델을 설정하세요. Q4_K_M 양자화의 Llama 3 70B는 48GB RAM 머신에서 좋은 분석 품질을 제공합니다.
함수를 배치 처리하고 JSON 보고서를 생성하는 PyGhidra 스크립트를 구축하세요.
검증 습관을 확립하세요. 수락하는 모든 AI 제안에 대해 실제 코드와 대조하여 30초를 투자하세요.
메트릭을 추적하세요. 수락 대 거부한 AI 제안 수와 수락한 제안이 더 깊은 분석에서 틀린 것으로 판명되는 빈도를 측정하세요.
도구는 여기 있습니다. 모델은 유용할 만큼 충분히 능력이 있습니다. 이를 훈련된 워크플로우에 사려 깊게 통합하는 분석가들은 AI를 완전히 무시하거나 맹목적으로 신뢰하는 사람들보다 상당한 이점을 갖게 될 것입니다.