Content
# VEH Debugger for VSCode
**한국어** | [English](README.en.md)
Windows 프로세스를 VEH(Vectored Exception Handler)로 디버깅하는 인-프로세스 디버거. 브레이크포인트, 하드웨어 워치포인트, 메모리/레지스터 조회, 포인터 체인과 런타임 call 추적 — **모든 디버깅 연산을 호출 가능한 headless primitive로 노출한다.** GUI를 조작할 필요 없이 AI 에이전트는 이걸 MCP 함수로 직접 호출하고, 사람은 같은 엔진을 VSCode의 DAP로 쓴다.
## 왜 VEH인가
Windows Debug API를 쓰지 않는다. `DebugActiveProcess` / `NtSetInformationThread` 대신 타겟 안에서 VEH로 예외를 잡으므로 `PEB.BeingDebugged`가 0으로 유지된다. Themida, VMProtect의 PEB/NtQuery 기반 안티디버그 체크에 디버거가 보이지 않는다. (VEH 등록 자체를 스캔하는 EAC류 커널 안티치트는 예외.)
in-process라는 점에서 하나 더. Windows Debug API 디버거는 프로세스당 하나만 붙지만, VEH는 **x64dbg가 이미 붙은 프로세스에도 동시에** 붙는다. 커널/유저 디버거로 분석하면서 워치포인트만 VEH로 병행할 수 있다.
## 제어 경로: DAP와 MCP
같은 디버깅 엔진을 두 프로토콜로 노출한다.
- **DAP**: VSCode 디버그 패널에서 직접. 소스 BP, 스텝, 디스어셈블리, 레지스터 편집.
- **MCP**: Claude, Cursor, Codex 등이 39개 도구를 직접 호출. GUI를 거치지 않고 디버깅 연산을 함수처럼 조합·자동화한다 — 에이전트가 디버거를 '조종'하는 게 아니라 primitive로 '프로그래밍'한다.
## 실전 시나리오
자연어 요청이 실제로 어떤 도구 시퀀스로 풀리는지.
**모듈 로드 시점에 내부로 BP**
Game.dll이 로드되는 순간 정지시키고, 그 안 오프셋에 BP를 건다.
```
veh_set_module_breakpoint(module="Game.dll") # 로드 시점에 정지
veh_continue(wait=true)
veh_set_breakpoint(address="Game.dll+0x1234")
veh_continue(wait=true)
veh_registers(threadId=...)
```
언패킹 후에야 나타나는 모듈, 지연 로드 DLL을 로드 시점에 잡는다. `module+RVA` 주소라 ASLR 베이스 계산이 없다.
**이 값에 쓰는 코드 찾기 (Find What Writes)**
감시 주소에 쓰기가 일어난 명령을 찾는다.
```
veh_set_data_breakpoint(address="0x...", type="write", size=4, condition="value != 0")
veh_continue(wait=true)
veh_registers(threadId=...) # 쓴 명령의 RIP
veh_disassemble(address=<위 RIP 값>)
```
DR0~DR3 하드웨어 워치포인트라 코드에 INT3를 심지 않아 무결성 검사에 안 걸린다. `value != 0`으로 0-write 노이즈를 건너뛴다.
**N스텝 동안 레지스터 변화 추적**
특정 지점부터 100스텝 동안 EAX 값이 바뀌는 지점만 모은다.
```
veh_trace_register(threadId=..., register="eax", max_steps=100)
```
스텝 루프가 타겟 DLL 안에서 돌아 스텝마다 IPC 왕복이 없다. 값이 바뀐 스텝만 반환한다.
**포인터 체인 한 번에 풀기**
base에서 오프셋을 차례로 따라가 최종 값을 읽는다.
```
veh_read_pointer_chain(base="game.exe+0x1F00", offsets=[0x10, 0x8, 0x34], size=4)
```
각 홉을 역참조(x86/x64 포인터 크기 자동)해 홉마다 주소와 최종 값을 반환한다. 홉당 왕복하던 걸 1콜로. HP/좌표/엔티티 포인터 추적.
**난독화된 import 일괄 해석**
thunk 주소들이 실제로 어느 API로 가는지 한 번에 푼다.
```
veh_resolve_imports(threadId=..., addresses=[...], follow_exceptions=true, system_only=true)
```
각 thunk에서 DLL 안까지 스텝으로 따라가 실제 API를 알아낸다(최대 2000). 예외 기반 난독화도 `follow_exceptions`로 추적. IAT가 밀린 바이너리의 import 복원.
**패킹된 바이너리의 런타임 call 타겟 수집**
콜사이트들이 실행 중 실제로 어디로 도달하는지 5초간 모은다.
```
veh_trace_calls(addresses=[...], duration_sec=5, resolve=true, system_only=true)
```
콜/점프가 런타임에 도달하는 주소 + API 이름을 수집한다. `resolve=true`는 thunk/트램폴린을 끝까지 따라간다. 패킹 바이너리의 IAT 재구성용.
---
## 특징
- **VEH 기반**: Windows Debug API 대신 VEH를 사용하여 안티디버그 우회에 유리
- **DAP 전체 지원**: VSCode, MCP debug 도구 등 모든 DAP 호환 클라이언트에서 사용 가능
- **MCP 도구 서버**: AI 에이전트(Claude, Codex 등)가 직접 디버거를 제어하는 39개 도구 제공
- **TCP 모드**: `--tcp --port=PORT`로 원격 디버깅/MCP 연동 지원
- **원격 접속**: `--remote` / `--bind=0.0.0.0`으로 VM/네트워크 너머 디버깅
- **32/64비트 지원**: x86/x64 프로세스 모두 디버깅 (32비트 타겟은 별도 32비트 DLL 빌드 + WoW64 인젝션)
- **소프트웨어 브레이크포인트**: INT3 (0xCC) 패치 (ReadMemory에서 원본 바이트 마스킹)
- **조건부 브레이크포인트**: 조건식 만족 시에만 정지 (예: `RAX==0x1234`, `*0x7FF600!=0`)
- **힐 카운트 브레이크포인트**: N번째 히트에서만 정지
- **로그 포인트**: 정지 없이 Debug Console에 로깅 (예: `RAX={RAX}, ptr={*0x7FF600}`)
- **하드웨어 브레이크포인트**: DR0~DR3 (메모리 읽기/쓰기 감시 = Find What Writes/Accesses)
- **PDB 심볼 지원**: 소스 파일/줄 번호 매핑, 함수 이름으로 브레이크포인트
- **PDB 기반 O(1) StepOver**: `SymGetLineFromAddrW64`로 다음 소스 줄 주소를 계산 — O(n) 싱글스텝 대신 임시 BP 하나
- **레지스터 편집**: Variables 패널에서 레지스터 값 더블클릭 수정
- **디스어셈블리**: Zydis x86/x64 디스어셈블러 (기본) + 내장 경량 디코더 (폴백)
- **메모리 읽기/쓰기**: DAP readMemory/writeMemory 지원
- **detach/재부착**: detach 후에도 DLL 파이프 서버 유지 — 타겟 재시작 없이 재부착 가능
- **MT(정적 CRT) 빌드**: DLL 인젝션 시 vcruntime 의존성 없음
## 아키텍처
```
VSCode / DAP Client Claude / AI Agent
↕ DAP (stdin/stdout or TCP) ↕ MCP (stdin/stdout, JSON-RPC 2.0)
veh-debug-adapter.exe veh-mcp-server.exe
↕ Named Pipe IPC ↕ Named Pipe IPC
└──────── veh-debugger.dll (타겟 프로세스 내부) ────────┘
```
### 컴포넌트 설명
| 컴포넌트 | 역할 |
|---------|------|
| `veh-debugger.dll` (`vcruntime_net.dll`) | 타겟 프로세스에 인젝션. VEH 핸들러 등록, 브레이크포인트 관리, 스레드/스택/메모리 조회 |
| `veh-debug-adapter.exe` | DAP 프로토콜 서버. DLL 인젝션, Named Pipe 통신, JSON-RPC 처리 |
| `veh-mcp-server.exe` | MCP 도구 서버. AI 에이전트가 39개 도구로 디버거 직접 제어 |
| VSCode Extension | launch.json 스키마 정의, 어댑터 경로 설정 (최소 래퍼) |
## 빌드
### 요구사항
- Windows 10+ x64
- CMake 3.20+
- Visual Studio 2022 (MSVC)
- Node.js 18+ (VSCode 익스텐션용, 선택)
### C++ 빌드 (64비트)
```bash
cmake -B build -G "Visual Studio 17 2022" -A x64
cmake --build build --config Release
```
출력물:
- `build/bin/Release/veh-debug-adapter.exe` — DAP 어댑터
- `build/bin/Release/veh-mcp-server.exe` — MCP 도구 서버
- `build/bin/Release/vcruntime_net.dll` — VEH 디버거 DLL (위장 이름)
### C++ 빌드 (32비트 DLL)
32비트 프로세스 디버깅 시 필요:
```bash
cmake -B build32 -G "Visual Studio 17 2022" -A Win32
cmake --build build32 --config Release --target veh-debugger
# 출력: build32/bin/Release/vcruntime_net32.dll
# build/bin/Release/ 에 복사하여 사용
copy build32\bin\Release\vcruntime_net32.dll build\bin\Release\
```
### VSCode 익스텐션 빌드
```bash
cd extension
npm install
npm run compile
```
## 사용법
### 1. VSCode에서 사용 (stdio 모드)
`.vscode/launch.json`에 추가:
**프로세스 실행 (Launch)**
```json
{
"type": "veh",
"request": "launch",
"name": "VEH Debug - Launch",
"program": "C:/path/to/target.exe",
"args": ["arg1", "arg2"],
"stopOnEntry": true
}
```
- `program`: 디버깅할 실행 파일 경로
- `args`: 실행 인자 (선택)
- `stopOnEntry`: 진입점에서 정지 여부
- `runAsInvoker`: UAC 권한 상승 프롬프트 없이 현재 권한으로 실행 (기본: false)
**실행 중인 프로세스에 붙기 (Attach)**
```json
{
"type": "veh",
"request": "attach",
"name": "VEH Debug - Attach",
"processId": 1234
}
```
- `processId`: 대상 프로세스 PID (작업 관리자에서 확인)
### 2. TCP 모드 (로컬)
어댑터를 별도 프로세스로 실행한 뒤 DAP 클라이언트에서 TCP로 연결:
```bash
veh-debug-adapter.exe --tcp --port=4711
```
기본적으로 `127.0.0.1`에만 바인딩되어 로컬에서만 접속 가능.
### 3. TCP 원격 모드 (VM/네트워크)
VM 내부나 원격 머신에서 실행하고 호스트/외부에서 접속:
```bash
# 대상 머신에서 실행 (0.0.0.0 바인딩)
veh-debug-adapter.exe --tcp --port=4711 --remote
# 또는
veh-debug-adapter.exe --tcp --port=4711 --bind=0.0.0.0
```
외부에서 DAP 클라이언트로 `<대상머신IP>:4711`에 연결.
**보안 주의**: `--remote`는 모든 네트워크 인터페이스에 바인딩합니다. 신뢰할 수 있는 네트워크에서만 사용하거나 방화벽으로 접근을 제한하세요.
> TCP로 열어둔 어댑터에는 DAP를 지원하는 클라이언트라면 무엇이든 붙을 수 있습니다. 예를 들어 agent-tool의 `debug` 도구로 `debug(operation: "launch", address: "localhost:4711", ...)` 처럼 연결합니다.
### 4. MCP 도구 서버 (AI 에이전트 직접 제어)
DAP 프로토콜을 모르는 AI 에이전트가 함수 호출처럼 디버거를 제어할 수 있는 별도 MCP 서버.
**자동 설치 (권장)**
```bash
# 모든 에이전트에 한 번에 설치
veh-mcp-server.exe --install
# 특정 에이전트만 설치
veh-mcp-server.exe --install claude-code
veh-mcp-server.exe --install cursor
# 제거
veh-mcp-server.exe --uninstall
```
지원 에이전트: `claude-code`, `claude-desktop`, `cursor`, `windsurf`, `codex`
자기 자신의 절대경로를 자동 감지하여 각 에이전트의 설정 파일에 등록합니다.
| 에이전트 | 설정 파일 | 형식 |
|---------|----------|------|
| Claude Code | `~/.claude/settings.json` | JSON (`mcpServers`) |
| Claude Desktop | `%APPDATA%/Claude/claude_desktop_config.json` | JSON (`mcpServers`) |
| Cursor | `~/.cursor/mcp.json` | JSON (`mcpServers`) |
| Windsurf | `~/.codeium/windsurf/mcp_config.json` | JSON (`mcpServers`) |
| Codex CLI | `~/.codex/config.toml` | TOML (`mcp_servers`) |
**수동 설치** (설정 파일 직접 편집)
Claude Code / Claude Desktop / Cursor / Windsurf (JSON 형식):
```json
{
"mcpServers": {
"veh-debugger": {
"command": "C:/path/to/veh-mcp-server.exe",
"args": ["--log=veh-mcp.log"]
}
}
}
```
Codex CLI (TOML 형식):
```toml
[mcp_servers.veh-debugger]
command = "C:/path/to/veh-mcp-server.exe"
args = ["--log=veh-mcp.log"]
enabled = true
```
설정 후 에이전트/IDE를 재시작하면 활성화됩니다.
**MCP 도구 목록 (39개)**
| 도구 | 인자 | 설명 |
|------|------|------|
| `veh_attach` | `pid` | 프로세스에 DLL 인젝션 + 파이프 연결 |
| `veh_launch` | `program, args?, stopOnEntry?, cwd?, env?` | 프로세스 생성 + 인젝션. `cwd`로 타겟 작업 디렉토리 지정(생략 시 디버거 cwd 상속). `env`로 타겟에 환경변수 전달 (`{"KEY":"VAL"}` 또는 `["KEY=VALUE"]`, 부모 환경 위에 덮어씀) |
| `veh_detach` | - | 디버거 분리 (타겟은 계속 실행) |
| `veh_terminate` | `exitCode?` | 타겟을 **내부에서** 강제 종료 (주입된 DLL이 자기 프로세스에 `TerminateProcess` 호출). 외부 `taskkill`/`OpenProcess`를 막는 자기보호 타겟(deny-DACL/상위 무결성)도 확실히 종료 -- 프로세스 자기 핸들은 항상 종료 권한 보유. 종료 후 자동 detach. `WM_CLOSE->detach->taskkill` 수순 대체 |
| `veh_set_breakpoint` | `address, condition?, hitCondition?, logMessage?, action?` | 소프트웨어 BP. `action`으로 히트 시 자동 실행 (veh_batch 형식) |
| `veh_remove_breakpoint` | `id` | 소프트웨어 BP 제거 |
| `veh_set_source_breakpoint` | `source, line, condition?, hitCondition?, logMessage?` | 소스 파일+줄번호 BP (PDB 필요; 미로드 모듈은 `pending` 후 모듈 로드 시 자동 바인딩) |
| `veh_set_function_breakpoint` | `name, condition?, hitCondition?, logMessage?` | 함수명 BP (PDB 필요; 미로드 모듈은 `pending` 후 자동 바인딩) |
| `veh_list_breakpoints` | - | 활성 SW/HW BP 목록 조회 |
| `veh_set_data_breakpoint` | `address, type, size, condition?, hitCondition?` | HW BP (write/readwrite/execute). `condition`의 `value` 토큰=감시 주소 현재값 (예: `value != 0`으로 0-write 노이즈 필터), `hitCondition:"5"`=5번째 hit에서만 정지 |
| `veh_remove_data_breakpoint` | `id` | HW BP 제거 |
| `veh_set_module_breakpoint` | `module, enabled?, clear?` | 모듈(DLL) 로드 시 정지. 이름 부분일치(대소문자 무시, 예: `"D2Common"`). 매핑 직후 로더 스레드 정지(LdrRegisterDllNotification, INT3/패치 없음) -> 내부 함수에 BP 설치나 덤프 가능. 모던 Windows에선 DllMain 실행 후 발화. `enabled:false`로 패턴 제거, `clear:true`로 전체 제거 |
| `veh_continue` | `threadId?, wait?, timeout?, pass_exception?, ignore_exceptions?` | 실행 계속. `ignore_exceptions=[0x80000003]`으로 특정 예외만 SEH 전달 |
| `veh_step_in` | `threadId` | Step Into |
| `veh_step_over` | `threadId` | Step Over |
| `veh_step_out` | `threadId` | Step Out |
| `veh_pause` | `threadId?` | 일시정지 |
| `veh_threads` | - | 스레드 목록 |
| `veh_stack_trace` | `threadId, maxFrames?` | 스택 트레이스. PDB 없는 모듈은 PE export 테이블을 직접 파싱해 정확한 함수명 제공 (DbgHelp의 부정확한 `OrdinalNNNNN` 라벨 대신) |
| `veh_enum_locals` | `threadId, instructionAddress?, frameBase?` | 정지된 스레드의 스택 프레임에서 지역변수/파라미터 열거 (이름/타입/주소/값). 생략 시 최상위 프레임 자동 감지 (PDB 필요) |
| `veh_registers` | `threadId` | 레지스터 조회 |
| `veh_set_register` | `threadId, name, value` | 레지스터 값 변경 |
| `veh_evaluate` | `expression, threadId` | 레지스터/메모리/포인터/세그먼트 평가 (`[reg+offset]`, `gs:[0x60]` 등) |
| `veh_read_memory` | `address, size` | 메모리 읽기 (hex) |
| `veh_read_pointer_chain` | `base, offsets[], derefFinal?, size?` | 다단계 포인터 체인을 1콜로 추적 (N번 왕복 대신). 각 홉마다 `*(cur+offset)` 역참조 (x86/x64 포인터 크기 자동 판정), 각 홉과 최종 주소 반환. `derefFinal:false`면 마지막 오프셋은 역참조 없이 주소만 반환, `size>0`이면 최종 주소에서 바이트도 읽음 |
| `veh_write_memory` | `address, data` 또는 `patches` | 메모리 쓰기. 배치: `patches=[{address,data},...]` |
| `veh_dump_memory` | `address, size, output_path` | 메모리를 바이너리 파일로 덤프 (최대 64MB) |
| `veh_allocate_memory` | `size?, protection?` | 타겟 프로세스에 메모리 할당 (VirtualAlloc) |
| `veh_free_memory` | `address` | 할당된 메모리 해제 (VirtualFree) |
| `veh_execute_shellcode` | `shellcode, timeout_ms?` | 셸코드 실행 (RWX 할당+복사+스레드 생성+대기+해제) |
| `veh_modules` | - | 모듈 목록 |
| `veh_disassemble` | `address, count?` | 디스어셈블리 (Zydis) |
| `veh_exception_info` | - | 마지막 예외 정보 조회 |
| `veh_trace_register` | `threadId, register, mode?, value?, max_steps?` | 레지스터 변화 추적 (DLL 내부 스텝 루프, IPC 오버헤드 0) |
| `veh_trace_memory` | `address, size?, timeout_ms?` | 메모리 쓰기 추적 (임시 HW BP로 빠르게 감지) |
| `veh_resolve_imports` | `threadId, addresses, max_steps?, follow_exceptions?, system_only?, target_modules?` | 난독화 import 일괄 해석 (thunk -> DLL 스텝 추적, 최대 2000개) |
| `veh_batch` | `steps` | 다중 명령 일괄 실행 (`$N`/`$last`/`$prev` 결과 참조, if/loop/for_each 제어 흐름) |
| `veh_trace_callers` | `address, duration_sec?` | 함수 호출자 프로파일링 (자동 resume -> N초간 caller 수집 -> 자동 pause). 유니크 caller별 히트 카운트 반환. x64: RtlVirtualUnwind (정확). x86: [ESP] (함수 진입점에서만 정확) |
| `veh_trace_calls` | `addresses, duration_sec?, resolve?, system_only?` | call/jmp 명령이 런타임에 어디로 가는지 모니터링. 콜 사이트에 BP 설치 후 N초간 실행, 실제 타겟 주소 + API 이름 수집. `resolve=true`: thunk/trampoline을 자연스러운 call 컨텍스트에서 따라가 최종 API까지 추적 (예외 기반 난독화 대응). `system_only=true`: 시스템 DLL 타겟만 반환. 패킹된 바이너리의 IAT 복원용. |
> **Non-stop 조회 (타겟 정지 불필요)**: `veh_read_memory` / `veh_read_pointer_chain` / `veh_write_memory` / `veh_dump_memory` / `veh_disassemble` / `veh_modules` 는 타겟이 **실행 중에도** 동작합니다 (DLL 내 전용 파이프 스레드가 처리 -- 다른 스레드를 멈추지 않음). GUI를 조작하면서 라이브 값을 읽을 때 BP를 걸거나 detach/attach를 왕복할 필요가 없습니다. 반대로 `veh_registers` / `veh_stack_trace` / `veh_enum_locals` / `veh_step_*` 는 스레드 컨텍스트가 필요하므로 BP 히트나 `veh_pause`로 정지된 상태에서만 동작합니다.
> **Tip**: 주소 인자는 hex (`"0x401000"`), 10진수 (`4198400`), **모듈+RVA** (`"crackme.exe+0x1000"`) 모두 허용합니다. 모듈+RVA는 ASLR 계산 없이 사용 가능합니다.
### 커맨드라인 옵션
**veh-mcp-server.exe**
| 옵션 | 설명 |
|------|------|
| `--install [AGENT]` | AI 에이전트 설정에 MCP 서버 등록 (전체 또는 특정) |
| `--uninstall [AGENT]` | AI 에이전트 설정에서 MCP 서버 제거 |
| `--log=FILE` | 로그 파일 경로 |
| `--log-level=LEVEL` | 로그 레벨: debug, info, warn, error |
| `--help` | 도움말 출력 |
**veh-debug-adapter.exe**
| 옵션 | 설명 |
|------|------|
| `--tcp` | TCP 전송 모드 (기본: stdin/stdout) |
| `--port=PORT` | TCP 포트 번호 (기본: 4711) |
| `--remote` | 0.0.0.0에 바인딩 (원격 접속 허용) |
| `--bind=0.0.0.0` | `--remote`와 동일 |
| `--log=FILE` | 로그 파일 경로 |
| `--log-level=LEVEL` | 로그 레벨: debug, info, warn, error (기본: info) |
| `--help` | 도움말 출력 |
## 기능 상세
### 브레이크포인트
**소프트웨어 브레이크포인트 (INT3)**
- `setBreakpoints` — 소스 파일:줄 번호 기반 (PDB 필요)
- `setFunctionBreakpoints` — 함수 이름 기반 (PDB 필요)
- `setInstructionBreakpoints` — 주소 기반 (PDB 불필요)
**하드웨어 브레이크포인트 (DR0~DR3)**
- `setDataBreakpoints` — 메모리 주소 읽기/쓰기 감시
- 치트엔진의 "Find out what writes/accesses to this address"와 동일 원리
- 최대 4개 동시 감시 (CPU 하드웨어 제한)
- 감시 크기: 1/2/4/8 바이트
### PDB 심볼 지원
타겟 프로세스의 PDB 파일이 있으면:
- 소스 파일명 + 줄 번호로 브레이크포인트 설정
- 함수 이름으로 브레이크포인트 설정
- 스택 트레이스에서 함수명/소스 파일/줄 번호 표시
PDB 없이도 주소 기반 디버깅은 가능.
### 싱글스텝
| 명령 | 동작 |
|------|------|
| `next` (F10) | Step Over — 한 줄/명령어 실행 (호출 건너뜀) |
| `stepIn` (F11) | Step Into — 함수 내부로 진입 |
| `stepOut` (Shift+F11) | Step Out — 현재 함수 완료까지 실행 |
### 프로세스 실행 디버깅 (Launch)
Windows 디버거의 "실행하며 디버깅" 기능과 동일. DAP(`launch` 요청)와 MCP(`veh_launch`) 모두 지원.
동작 순서:
1. `CreateProcess` + `CREATE_SUSPENDED` — 프로세스를 정지 상태로 생성
2. DLL 인젝션 — VEH 핸들러 등록, Named Pipe 서버 시작
3. `stopOnEntry=true`이면 진입점에서 정지 유지, `false`이면 `ResumeThread`로 실행 계속
이미 실행 중인 프로세스에는 `attach` / `veh_attach`로 연결.
### DLL 인젝션
4가지 인젝션 방식 지원 (자동 선택):
1. **CreateRemoteThread** — 기본 방식
2. **NtCreateThreadEx** — 보호된 프로세스 대응
3. **Thread Hijacking** — 기존 스레드 하이재킹
4. **QueueUserAPC** — APC 큐 방식
### 메모리 & 디스어셈블리
- `readMemory` / `writeMemory` — 임의 메모리 읽기/쓰기
- `disassemble` — x86/x64 디스어셈블리
- **Zydis 백엔드** (기본): 완전한 오퍼랜드 표시 (`mov rax, qword ptr [rbp-0x10]`)
- **Simple 백엔드** (폴백): 니모닉만 (`mov`, `call` — 외부 의존성 없음)
- `IDisassembler` 인터페이스로 추상화, `CreateDisassembler()` 팩토리로 생성
- `evaluate` — 메모리 주소 표현식 평가
## DAP 지원 명령 전체 목록
| 카테고리 | 명령 |
|---------|------|
| 라이프사이클 | initialize, launch, attach, disconnect, terminate |
| 브레이크포인트 | setBreakpoints, setFunctionBreakpoints, setExceptionBreakpoints, setInstructionBreakpoints, setDataBreakpoints, dataBreakpointInfo |
| 실행 제어 | configurationDone, continue, next, stepIn, stepOut, pause |
| 상태 조회 | threads, stackTrace, scopes, variables, evaluate |
| 메모리/디스어셈블리 | readMemory, writeMemory, disassemble |
| 기타 | modules, loadedSources, exceptionInfo, completions, source, cancel, gotoTargets |
## 문제 해결
### DLL 인젝션 실패
- 관리자 권한으로 VSCode/어댑터 실행
- 타겟 프로세스의 비트 수(32/64) 확인 — DLL 비트가 일치해야 함
- 안티바이러스가 인젝션을 차단하는지 확인
### 파이프 연결 타임아웃
- 기본 타임아웃은 7초. 느린 시스템에서는 DLL 로드에 시간이 걸릴 수 있음
- 로그 파일로 진행 상황 확인: `--log=debug.log --log-level=debug`
### 브레이크포인트가 안 걸림
- PDB 파일이 타겟 EXE와 같은 디렉토리에 있는지 확인
- PDB 없이는 주소 기반 BP(`setInstructionBreakpoints`)만 가능
- 하드웨어 BP는 최대 4개 제한
### 원격 접속이 안 됨
- `--remote` 또는 `--bind=0.0.0.0` 옵션을 사용했는지 확인
- 방화벽에서 해당 포트가 열려있는지 확인
- VM의 네트워크 어댑터가 브릿지 모드인지 확인
## 의존성
| 라이브러리 | 용도 | 라이선스 |
|-----------|------|---------|
| [nlohmann/json](https://github.com/nlohmann/json) | JSON 파싱 (header-only) | MIT |
| [Zydis v4.1](https://github.com/zyantific/zydis) | x86/x64 디스어셈블리 (third_party에 포함) | MIT |
## 라이선스
MIT License
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
everything-claude-code
Complete Claude Code configuration collection - agents, skills, hooks,...
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
cc-switch
All-in-One Assistant for Claude Code, Codex & Gemini CLI across platforms.
servers
Model Context Protocol Servers
servers
Model Context Protocol Servers
Time
A Model Context Protocol server for time and timezone conversions.