feat: Introduce Kunlun agent tool, add Docker and sandbox environment checks, and update agent services and frontend dialogs.

This commit is contained in:
lintsinghua 2025-12-15 02:00:34 +08:00
parent 39a57b9c58
commit 2df1b39e08
23 changed files with 3580 additions and 917 deletions

View File

@ -234,9 +234,17 @@ async def _execute_agent_task(task_id: str):
from app.services.agent.event_manager import EventManager, AgentEventEmitter
from app.services.llm.service import LLMService
from app.services.agent.core import agent_registry
from app.services.agent.tools import SandboxManager
from app.core.config import settings
import time
# 🔥 在任务最开始就初始化 Docker 沙箱管理器
# 这样可以确保整个任务生命周期内使用同一个管理器,并且尽早发现 Docker 问题
logger.info(f"🚀 Starting execution for task {task_id}")
sandbox_manager = SandboxManager()
await sandbox_manager.initialize()
logger.info(f"🐳 Global Sandbox Manager initialized (Available: {sandbox_manager.is_available})")
async with async_session_factory() as db:
orchestrator = None
start_time = time.time()
@ -275,11 +283,12 @@ async def _execute_agent_task(task_id: str):
# 创建 LLM 服务
llm_service = LLMService(user_config=user_config)
# 初始化工具集 - 传递排除模式和目标文件
# 初始化工具集 - 传递排除模式和目标文件以及预初始化的 sandbox_manager
tools = await _initialize_tools(
project_root,
llm_service,
user_config,
sandbox_manager=sandbox_manager,
exclude_patterns=task.exclude_patterns,
target_files=task.target_files,
)
@ -535,6 +544,7 @@ async def _initialize_tools(
project_root: str,
llm_service,
user_config: Optional[Dict[str, Any]],
sandbox_manager: Any, # 传递预初始化的 SandboxManager
exclude_patterns: Optional[List[str]] = None,
target_files: Optional[List[str]] = None,
) -> Dict[str, Dict[str, Any]]:
@ -544,6 +554,7 @@ async def _initialize_tools(
project_root: 项目根目录
llm_service: LLM 服务
user_config: 用户配置
sandbox_manager: 沙箱管理器
exclude_patterns: 排除模式列表
target_files: 目标文件列表
"""
@ -551,6 +562,7 @@ async def _initialize_tools(
FileReadTool, FileSearchTool, ListFilesTool,
PatternMatchTool, CodeAnalysisTool, DataFlowAnalysisTool,
SemgrepTool, BanditTool, GitleaksTool,
NpmAuditTool, SafetyTool, TruffleHogTool, OSVScannerTool, # 🔥 Added missing tools
ThinkTool, ReflectTool,
CreateVulnerabilityReportTool,
VulnerabilityValidationTool,
@ -572,6 +584,14 @@ async def _initialize_tools(
# Recon 工具
recon_tools = {
**base_tools,
# 🔥 外部侦察工具 (Recon 阶段也需要使用这些工具来收集初步信息)
"semgrep_scan": SemgrepTool(project_root, sandbox_manager),
"bandit_scan": BanditTool(project_root, sandbox_manager),
"gitleaks_scan": GitleaksTool(project_root, sandbox_manager),
"npm_audit": NpmAuditTool(project_root, sandbox_manager),
"safety_scan": SafetyTool(project_root, sandbox_manager),
"trufflehog_scan": TruffleHogTool(project_root, sandbox_manager),
"osv_scan": OSVScannerTool(project_root, sandbox_manager),
}
# Analysis 工具
@ -587,10 +607,14 @@ async def _initialize_tools(
"pattern_match": PatternMatchTool(project_root),
# 数据流分析
"dataflow_analysis": DataFlowAnalysisTool(llm_service),
# 外部安全工具
"semgrep_scan": SemgrepTool(project_root),
"bandit_scan": BanditTool(project_root),
"gitleaks_scan": GitleaksTool(project_root),
# 外部安全工具 (传入共享的 sandbox_manager)
"semgrep_scan": SemgrepTool(project_root, sandbox_manager),
"bandit_scan": BanditTool(project_root, sandbox_manager),
"gitleaks_scan": GitleaksTool(project_root, sandbox_manager),
"npm_audit": NpmAuditTool(project_root, sandbox_manager),
"safety_scan": SafetyTool(project_root, sandbox_manager),
"trufflehog_scan": TruffleHogTool(project_root, sandbox_manager),
"osv_scan": OSVScannerTool(project_root, sandbox_manager),
# 安全知识查询
"query_security_knowledge": SecurityKnowledgeQueryTool(),
"get_vulnerability_knowledge": GetVulnerabilityKnowledgeTool(),
@ -599,7 +623,7 @@ async def _initialize_tools(
# Verification 工具
# 🔥 导入沙箱工具
from app.services.agent.tools import (
SandboxTool, SandboxHttpTool, VulnerabilityVerifyTool, SandboxManager,
SandboxTool, SandboxHttpTool, VulnerabilityVerifyTool,
# 多语言代码测试工具
PhpTestTool, PythonTestTool, JavaScriptTestTool, JavaTestTool,
GoTestTool, RubyTestTool, ShellTestTool, UniversalCodeTestTool,
@ -609,11 +633,6 @@ async def _initialize_tools(
UniversalVulnTestTool,
)
# 🔥 初始化沙箱管理器
sandbox_manager = SandboxManager()
await sandbox_manager.initialize()
logger.info(f"✅ Sandbox initialized (available: {sandbox_manager.is_available})")
verification_tools = {
**base_tools,
# 🔥 沙箱验证工具

View File

@ -34,44 +34,111 @@ ANALYSIS_SYSTEM_PROMPT = """你是 DeepAudit 的漏洞分析 Agent一个**自
4. 判断是否是真实漏洞
5. 动态调整分析方向
## 你可以使用的工具
## ⚠️ 核心原则:优先使用外部专业工具!
### 🚀 智能扫描工具(推荐优先使用)
- **smart_scan**: 智能批量安全扫描 首选工具
**外部工具优先级最高** 必须首先使用外部安全工具进行扫描它们有
- 经过验证的专业规则库
- 更低的误报率
- 更全面的漏洞检测能力
## 🔧 工具优先级(必须按此顺序使用)
### 第一优先级:外部专业安全工具 ⭐⭐⭐ 【必须首先使用!】
- **semgrep_scan**: 全语言静态分析 - **每次分析必用**
参数: target_path (str), rules (str: "auto" "p/security-audit")
示例: {"target_path": ".", "rules": "auto"}
- **bandit_scan**: Python 安全扫描 - **Python项目必用**
参数: target_path (str), severity (str)
示例: {"target_path": ".", "severity": "medium"}
- **gitleaks_scan**: 密钥泄露检测 - **每次分析必用**
参数: target_path (str)
示例: {"target_path": "."}
- **safety_scan**: Python 依赖漏洞 - ** requirements.txt 时必用**
参数: requirements_file (str)
示例: {"requirements_file": "requirements.txt"}
- **npm_audit**: Node.js 依赖漏洞 - ** package.json 时必用**
参数: target_path (str)
示例: {"target_path": "."}
- **kunlun_scan**: 深度代码审计Kunlun-M
参数: target_path (str), language (str: "php"|"javascript")
示例: {"target_path": ".", "language": "php"}
### 第二优先级:智能扫描工具 ⭐⭐
- **smart_scan**: 智能批量安全扫描
参数: target (str), quick_mode (bool), focus_vulnerabilities (list)
示例: {"target": ".", "quick_mode": true}
- **quick_audit**: 快速文件审计
参数: file_path (str), deep_analysis (bool)
示例: {"file_path": "app/views.py", "deep_analysis": true}
### 文件操作
- **read_file**: 读取文件内容
### 第三优先级:内置分析工具 ⭐
- **pattern_match**: 危险模式匹配外部工具不可用时的备选
参数: scan_file (str) code (str), pattern_types (list)
示例: {"scan_file": "app/models.py", "pattern_types": ["sql_injection"]}
- **dataflow_analysis**: 数据流追踪
参数: source_code (str), variable_name (str)
### 辅助工具
- **read_file**: 读取文件内容验证发现
参数: file_path (str), start_line (int), end_line (int)
- **list_files**: 列出目录文件
参数: directory (str), pattern (str)
- **search_code**: 代码关键字搜索
参数: keyword (str), max_results (int)
### 深度分析
- **pattern_match**: 危险模式匹配支持直接扫描文件
参数: scan_file (str) code (str), pattern_types (list)
示例: {"scan_file": "app/models.py", "pattern_types": ["sql_injection"]}
- **dataflow_analysis**: 数据流追踪
参数: source_code (str), variable_name (str)
### 外部静态分析工具
- **semgrep_scan**: Semgrep 静态分析
参数: target_path (str), rules (str)
- **bandit_scan**: Python 安全扫描
参数: target_path (str)
- **gitleaks_scan**: Git 密钥泄露扫描
参数: target_path (str)
### 安全知识查询
- **query_security_knowledge**: 查询安全知识库
- **get_vulnerability_knowledge**: 获取漏洞知识
## 📋 推荐分析流程(严格按此执行!)
### 第一步外部工具全面扫描60%时间)⚡ 最重要!
根据项目技术栈**必须首先**执行以下外部工具
```
# 所有项目必做
Action: semgrep_scan
Action Input: {"target_path": ".", "rules": "auto"}
Action: gitleaks_scan
Action Input: {"target_path": "."}
# Python 项目必做
Action: bandit_scan
Action Input: {"target_path": ".", "severity": "medium"}
Action: safety_scan
Action Input: {"requirements_file": "requirements.txt"}
# Node.js 项目必做
Action: npm_audit
Action Input: {"target_path": "."}
```
### 第二步分析外部工具结果25%时间)
对外部工具发现的问题进行深入分析
- 使用 `read_file` 查看完整代码上下文
- 使用 `dataflow_analysis` 追踪数据流
- 验证是否为真实漏洞排除误报
### 第三步补充扫描10%时间)
如果外部工具覆盖不足使用内置工具补充
- `smart_scan` 综合扫描
- `pattern_match` 模式匹配
### 第四步汇总报告5%时间)
整理所有发现输出 Final Answer
## ⚠️ 重要提醒
1. **不要跳过外部工具** 即使内置工具可能更快外部工具的检测能力更强
2. **Docker依赖**外部工具需要Docker环境如果返回"Docker不可用"再使用内置工具
3. **并行执行**可以连续调用多个外部工具
## 工作方式
每一步你需要输出
@ -111,21 +178,6 @@ Final Answer: [JSON 格式的漏洞报告]
}
```
## ⭐ 推荐分析策略
1. **第一步智能扫描**
使用 smart_scan 快速获取项目安全概览
示例: {"target": ".", "quick_mode": true}
2. **第二步重点审计**
smart_scan 发现的高风险文件使用 quick_audit 深入分析
示例: {"file_path": "发现的高风险文件", "deep_analysis": true}
3. **第三步验证分析**
使用 read_file 查看完整上下文 dataflow_analysis 追踪数据流
4. **第四步汇总报告**
整理所有发现输出 Final Answer
## 重点关注的漏洞类型
- SQL 注入 (query, execute, raw SQL)
- XSS (innerHTML, document.write, v-html)
@ -136,12 +188,12 @@ Final Answer: [JSON 格式的漏洞报告]
- 不安全的反序列化 (pickle, yaml.load, eval)
## 重要原则
1. **质量优先** - 宁可深入分析几个真实漏洞不要浅尝辄止报告大量误报
2. **上下文分析** - 看到可疑代码要读取上下文理解完整逻辑
3. **自主判断** - 不要机械相信工具输出要用你的专业知识判断
4. **持续探索** - 发现一个问题后思考是否有相关问题
1. **外部工具优先** - 首先使用 semgrepbandit 等专业工具
2. **质量优先** - 宁可深入分析几个真实漏洞不要浅尝辄止报告大量误报
3. **上下文分析** - 看到可疑代码要读取上下文理解完整逻辑
4. **自主判断** - 不要机械相信工具输出要用你的专业知识判断
现在开始你的安全分析"""
现在开始你的安全分析首先使用外部工具进行全面扫描"""
@dataclass

View File

@ -125,6 +125,11 @@ class AgentConfig(BaseSettings):
default=True,
description="Enable OSV scanner"
)
# Kunlun-M (MIT License - https://github.com/LoRexxar/Kunlun-M)
kunlun_enabled: bool = Field(
default=True,
description="Enable Kunlun-M static code analyzer"
)
# External Tool Timeouts
semgrep_timeout_seconds: int = Field(
@ -139,6 +144,10 @@ class AgentConfig(BaseSettings):
default=60,
description="Timeout for Gitleaks scanner"
)
kunlun_timeout_seconds: int = Field(
default=600,
description="Timeout for Kunlun-M scanner (10 minutes for deep analysis)"
)
# ============ Rate Limiting ============
rate_limit_enabled: bool = Field(

View File

@ -204,6 +204,8 @@ class AgentRunner:
CommandInjectionTestTool, SqlInjectionTestTool, XssTestTool,
PathTraversalTestTool, SstiTestTool, DeserializationTestTool,
UniversalVulnTestTool,
# Kunlun-M 静态代码分析工具 (MIT License)
KunlunMTool, KunlunRuleListTool, KunlunPluginTool,
)
# 🔥 导入知识查询工具
from app.services.agent.knowledge import (
@ -214,7 +216,34 @@ class AgentRunner:
# 🔥 获取排除模式和目标文件
exclude_patterns = self.task.exclude_patterns or []
target_files = self.task.target_files or None
# ============ 🔥 提前初始化 SandboxManager供所有外部工具共享============
self.sandbox_manager = None
try:
from app.services.agent.tools.sandbox_tool import SandboxConfig
sandbox_config = SandboxConfig(
image=settings.SANDBOX_IMAGE,
memory_limit=settings.SANDBOX_MEMORY_LIMIT,
cpu_limit=settings.SANDBOX_CPU_LIMIT,
timeout=settings.SANDBOX_TIMEOUT,
network_mode=settings.SANDBOX_NETWORK_MODE,
)
self.sandbox_manager = SandboxManager(config=sandbox_config)
# 🔥 必须调用 initialize() 来连接 Docker
await self.sandbox_manager.initialize()
logger.info(f"✅ SandboxManager initialized early (Docker available: {self.sandbox_manager.is_available})")
except Exception as e:
logger.warning(f"❌ Early Sandbox Manager initialization failed: {e}")
import traceback
logger.warning(f"Traceback: {traceback.format_exc()}")
# 尝试创建默认管理器作为后备
try:
self.sandbox_manager = SandboxManager()
await self.sandbox_manager.initialize()
logger.info(f"⚠️ Created fallback SandboxManager (Docker available: {self.sandbox_manager.is_available})")
except Exception as e2:
logger.error(f"❌ Failed to create fallback SandboxManager: {e2}")
# ============ 基础工具(所有 Agent 共享)============
base_tools = {
"read_file": FileReadTool(self.project_root, exclude_patterns, target_files),
@ -225,11 +254,18 @@ class AgentRunner:
# ============ Recon Agent 专属工具 ============
# 职责:信息收集、项目结构分析、技术栈识别
# 🔥 新增外部工具也可用于Recon阶段的快速扫描
self.recon_tools = {
**base_tools,
"search_code": FileSearchTool(self.project_root, exclude_patterns, target_files),
# 🔥 新增:反思工具
"reflect": ReflectTool(),
# 🔥 外部安全工具(共享 SandboxManager 实例)
"semgrep_scan": SemgrepTool(self.project_root, self.sandbox_manager),
"bandit_scan": BanditTool(self.project_root, self.sandbox_manager),
"gitleaks_scan": GitleaksTool(self.project_root, self.sandbox_manager),
"safety_scan": SafetyTool(self.project_root, self.sandbox_manager),
"npm_audit": NpmAuditTool(self.project_root, self.sandbox_manager),
}
# RAG 工具Recon 用于语义搜索)
@ -246,14 +282,18 @@ class AgentRunner:
# TODO: code_analysis 工具暂时禁用,因为 LLM 调用经常失败
# "code_analysis": CodeAnalysisTool(self.llm_service),
"dataflow_analysis": DataFlowAnalysisTool(self.llm_service),
# 外部静态分析工具
"semgrep_scan": SemgrepTool(self.project_root),
"bandit_scan": BanditTool(self.project_root),
"gitleaks_scan": GitleaksTool(self.project_root),
"trufflehog_scan": TruffleHogTool(self.project_root),
"npm_audit": NpmAuditTool(self.project_root),
"safety_scan": SafetyTool(self.project_root),
"osv_scan": OSVScannerTool(self.project_root),
# 🔥 外部静态分析工具(共享 SandboxManager 实例)
"semgrep_scan": SemgrepTool(self.project_root, self.sandbox_manager),
"bandit_scan": BanditTool(self.project_root, self.sandbox_manager),
"gitleaks_scan": GitleaksTool(self.project_root, self.sandbox_manager),
"trufflehog_scan": TruffleHogTool(self.project_root, self.sandbox_manager),
"npm_audit": NpmAuditTool(self.project_root, self.sandbox_manager),
"safety_scan": SafetyTool(self.project_root, self.sandbox_manager),
"osv_scan": OSVScannerTool(self.project_root, self.sandbox_manager),
# 🔥 Kunlun-M 静态代码分析工具 (MIT License - https://github.com/LoRexxar/Kunlun-M)
"kunlun_scan": KunlunMTool(self.project_root),
"kunlun_list_rules": KunlunRuleListTool(self.project_root),
"kunlun_plugin": KunlunPluginTool(self.project_root),
# 🔥 新增:反思工具
"reflect": ReflectTool(),
# 🔥 新增安全知识查询工具基于RAG
@ -276,35 +316,8 @@ class AgentRunner:
# 🔥 新增:反思工具
"reflect": ReflectTool(),
}
# 沙箱工具(仅 Verification Agent 可用)
self.sandbox_manager = None
try:
from app.services.agent.tools.sandbox_tool import SandboxConfig
sandbox_config = SandboxConfig(
image=settings.SANDBOX_IMAGE,
memory_limit=settings.SANDBOX_MEMORY_LIMIT,
cpu_limit=settings.SANDBOX_CPU_LIMIT,
timeout=settings.SANDBOX_TIMEOUT,
network_mode=settings.SANDBOX_NETWORK_MODE,
)
self.sandbox_manager = SandboxManager(config=sandbox_config)
# 🔥 必须调用 initialize() 来连接 Docker
await self.sandbox_manager.initialize()
except Exception as e:
logger.warning(f"❌ Sandbox Manager initialization failed: {e}")
import traceback
logger.warning(f"Traceback: {traceback.format_exc()}")
# 尝试创建默认管理器作为后备
try:
self.sandbox_manager = SandboxManager()
# 🔥 同样需要调用 initialize()
await self.sandbox_manager.initialize()
logger.info("⚠️ Created fallback SandboxManager (Docker might be unavailable)")
except Exception as e2:
logger.error(f"❌ Failed to create fallback SandboxManager: {e2}")
# 始终注册沙箱工具,即使 Docker 不可用(工具内部会检查
# 🔥 注册沙箱工具(使用提前初始化的 SandboxManager
if self.sandbox_manager:
# 🔥 沙箱核心工具
self.verification_tools["sandbox_exec"] = SandboxTool(self.sandbox_manager)

View File

@ -102,26 +102,104 @@ TOOL_USAGE_GUIDE = """
<tool_usage_guide>
## 工具使用指南
### 分析流程
### ⚠️ 核心原则:优先使用外部专业工具
1. **初始侦察** - 了解项目结构
- 使用 list_files 了解目录布局
- 识别主要入口点和配置文件
- 确定技术栈和框架
**外部工具优先级最高** 外部安全工具SemgrepBanditGitleaksKunlun-M 是经过业界验证的专业工具具有
- 更全面的规则库和漏洞检测能力
- 更低的误报率
- 更专业的安全分析算法
- 持续更新的安全规则
2. **智能扫描** - 快速发现热点
- smart_scan: 综合扫描发现高风险区域
- pattern_match: 识别危险代码模式
- semgrep_scan/bandit_scan: 静态分析
**必须优先调用外部工具而非依赖内置的模式匹配**
3. **深度分析** - 验证发现
- read_file: 读取完整上下文
- dataflow_analysis: 追踪数据流
- search_code: 搜索相关代码
### 🔧 工具优先级(从高到低)
4. **知识查询** - 获取专业知识
- query_security_knowledge: 搜索安全知识库
- get_vulnerability_knowledge: 获取特定漏洞信息
#### 第一优先级:外部专业安全工具 ⭐⭐⭐
| 工具 | 用途 | 何时使用 |
|------|------|---------|
| `semgrep_scan` | 多语言静态分析 | **每次分析必用**支持30+语言OWASP规则 |
| `bandit_scan` | Python安全扫描 | Python项目**必用**检测注入/反序列化等 |
| `gitleaks_scan` | 密钥泄露检测 | **每次分析必用**检测150+种密钥类型 |
| `kunlun_scan` | 深度代码审计 | 大型项目推荐支持PHP/Java/JS深度分析 |
| `npm_audit` | Node.js依赖漏洞 | package.json项目**必用** |
| `safety_scan` | Python依赖漏洞 | requirements.txt项目**必用** |
| `osv_scan` | 开源漏洞扫描 | 多语言依赖检查 |
| `trufflehog_scan` | 深度密钥扫描 | 需要验证密钥有效性时使用 |
#### 第二优先级:智能扫描工具 ⭐⭐
| 工具 | 用途 |
|------|------|
| `smart_scan` | 综合智能扫描快速定位高风险区域 |
| `quick_audit` | 快速审计模式 |
#### 第三优先级:内置分析工具 ⭐
| 工具 | 用途 |
|------|------|
| `pattern_match` | 正则模式匹配外部工具不可用时的备选 |
| `dataflow_analysis` | 数据流追踪验证 |
| `code_analysis` | 代码结构分析 |
#### 辅助工具
| 工具 | 用途 |
|------|------|
| `list_files` | 了解项目结构 |
| `read_file` | 读取文件内容验证发现 |
| `search_code` | 搜索相关代码 |
| `query_security_knowledge` | 查询安全知识库 |
### 📋 推荐分析流程
#### 第一步快速侦察5%时间)
```
Action: list_files
Action Input: {"path": "."}
```
了解项目结构技术栈入口点
#### 第二步外部工具全面扫描60%时间)⚡重点!
**根据技术栈选择对应工具并行执行多个扫描**
```
# 通用项目(必做)
Action: semgrep_scan
Action Input: {"target_path": ".", "rules": "p/security-audit"}
Action: gitleaks_scan
Action Input: {"target_path": "."}
# Python项目必做
Action: bandit_scan
Action Input: {"target_path": ".", "severity": "medium"}
Action: safety_scan
Action Input: {"requirements_file": "requirements.txt"}
# Node.js项目必做
Action: npm_audit
Action Input: {"target_path": "."}
# 大型项目(推荐)
Action: kunlun_scan
Action Input: {"target_path": ".", "rules": "all"}
```
#### 第三步深度分析25%时间)
对外部工具发现的问题进行深入分析
- 使用 `read_file` 查看完整上下文
- 使用 `dataflow_analysis` 追踪数据流
- 验证是否为真实漏洞
#### 第四步验证和报告10%时间)
- 确认漏洞可利用性
- 评估影响范围
- 生成修复建议
### ⚠️ 重要提醒
1. **不要跳过外部工具** 即使内置模式匹配可能更快外部工具的检测能力更强
2. **并行执行**可以同时调用多个不相关的外部工具以提高效率
3. **Docker依赖**外部工具需要Docker环境如果Docker不可用再回退到内置工具
4. **结果整合**综合多个工具的结果交叉验证提高准确性
### 工具调用格式
@ -268,22 +346,43 @@ ANALYSIS_SYSTEM_PROMPT = f"""你是 DeepAudit 的漏洞分析 Agent一个专
## 分析策略
### 第一步:快速扫描
使用 smart_scan pattern_match 快速识别高风险区域
### ⚠️ 核心原则:外部工具优先!
### 第二步:深度分析
对可疑代码进行上下文分析
- 读取相关文件
- 追踪数据流
- 理解业务逻辑
**必须首先使用外部专业安全工具进行扫描** 这些工具有经过验证的规则库和更低的误报率
### 第三步:验证判断
- 确认是否为真实漏洞
- 评估可利用性
- 确定置信度
### 第一步:外部工具全面扫描(最重要!)⭐⭐⭐
**根据项目技术栈选择并执行以下工具**
### 第四步:报告发现
输出结构化的漏洞报告
**所有项目必做**
- `semgrep_scan`: 使用规则 "p/security-audit" "p/owasp-top-ten" 进行全面扫描
- `gitleaks_scan`: 检测密钥泄露
**Python项目必做**
- `bandit_scan`: Python专用安全扫描
- `safety_scan`: 依赖漏洞检查
**Node.js项目必做**
- `npm_audit`: 依赖漏洞检查
**大型项目推荐**
- `kunlun_scan`: Kunlun-M深度代码审计
- `osv_scan`: 开源漏洞扫描
### 第二步:分析外部工具结果
对外部工具发现的问题进行深入分析
- 使用 `read_file` 查看完整代码上下文
- 使用 `dataflow_analysis` 追踪数据流
- 理解业务逻辑排除误报
### 第三步:补充扫描(仅在需要时)
如果外部工具覆盖不足使用内置工具补充
- `smart_scan`: 综合智能扫描
- `pattern_match`: 正则模式匹配
### 第四步:验证和报告
- 确认漏洞可利用性
- 评估实际影响
- 输出结构化的漏洞报告
## 输出格式
@ -330,25 +429,31 @@ VERIFICATION_SYSTEM_PROMPT = f"""你是 DeepAudit 的验证 Agent负责验证
## 验证方法
### 1. 上下文验证
### 1. 外部工具交叉验证 ⭐⭐⭐(推荐!)
使用不同的外部工具验证发现
- 使用 `semgrep_scan` 配合特定规则验证
- 使用 `bandit_scan` 交叉确认 Python 漏洞
- 如果多个工具都报告同一问题置信度更高
### 2. 上下文验证
- 检查完整的代码上下文
- 理解数据处理逻辑
- 验证安全控制是否存在
### 2. 数据流验证
### 3. 数据流验证
- 追踪从输入到输出的完整路径
- 识别中间的验证和过滤
- 确认是否存在有效的安全控制
### 3. 配置验证
### 4. 配置验证
- 检查安全配置
- 验证框架安全特性
- 评估防护措施
### 4. 模式验证
- 对比已知漏洞模式
- 检查类似代码位置
- 评估误报可能性
### 5. 沙箱验证(高置信度漏洞)
- 使用 `sandbox_execute` 或漏洞专用测试工具
- 构造 PoC 验证可利用性
- 记录验证结果
## 输出格式
@ -359,6 +464,7 @@ Final Answer: {{
"original_finding": {{...}},
"is_verified": true/false,
"verification_method": "使用的验证方法",
"cross_tool_results": {{"semgrep": "...", "bandit": "..."}},
"evidence": "验证证据",
"final_severity": "最终严重程度",
"final_confidence": 0.95,
@ -380,15 +486,21 @@ RECON_SYSTEM_PROMPT = f"""你是 DeepAudit 的侦察 Agent负责收集和分
1. 分析项目结构和技术栈
2. 识别关键入口点
3. 发现配置文件和敏感区域
4. 提供初步风险评估
4. **推荐需要使用的外部安全工具**
5. 提供初步风险评估
## 侦察目标
### 1. 技术栈识别
### 1. 技术栈识别(用于选择外部工具)
- 编程语言和版本
- Web框架Django, Flask, FastAPI, Express等
- 数据库类型
- 前端框架
- **根据技术栈推荐外部工具**
- Python项目 bandit_scan, safety_scan
- Node.js项目 npm_audit
- 所有项目 semgrep_scan, gitleaks_scan
- 大型项目 kunlun_scan, osv_scan
### 2. 入口点发现
- HTTP路由和API端点
@ -433,6 +545,11 @@ Final Answer: {{
"frameworks": [...],
"databases": [...]
}},
"recommended_tools": {{
"must_use": ["semgrep_scan", "gitleaks_scan", ...],
"recommended": ["kunlun_scan", ...],
"reason": "基于项目技术栈的推荐理由"
}},
"entry_points": [
{{"type": "...", "file": "...", "line": ..., "method": "..."}}
],
@ -448,6 +565,12 @@ Final Answer: {{
## ⚠️ 重要输出要求
### recommended_tools 格式要求(新增!)
**必须**根据项目技术栈推荐外部工具
- `must_use`: 必须使用的工具列表
- `recommended`: 推荐使用的工具列表
- `reason`: 推荐理由
### high_risk_areas 格式要求
每个高风险区域**必须**包含具体的文件路径格式为
- `"app.py:36 - SECRET_KEY 硬编码"`

View File

@ -79,6 +79,9 @@ from .agent_tools import (
# 🔥 新增:智能扫描工具
from .smart_scan_tool import SmartScanTool, QuickAuditTool
# 🔥 新增Kunlun-M 静态代码分析工具 (MIT License)
from .kunlun_tool import KunlunMTool, KunlunRuleListTool, KunlunPluginTool
__all__ = [
# 基础
"AgentTool",
@ -156,4 +159,9 @@ __all__ = [
# 🔥 智能扫描工具
"SmartScanTool",
"QuickAuditTool",
# 🔥 Kunlun-M 工具 (MIT License - https://github.com/LoRexxar/Kunlun-M)
"KunlunMTool",
"KunlunRuleListTool",
"KunlunPluginTool",
]

View File

@ -25,8 +25,8 @@ class SemgrepInput(BaseModel):
"""Semgrep 扫描输入"""
target_path: str = Field(description="要扫描的目录或文件路径(相对于项目根目录)")
rules: Optional[str] = Field(
default="auto",
description="规则集: auto, p/security-audit, p/owasp-top-ten, p/r2c-security-audit, 或自定义规则文件路径"
default="p/security-audit",
description="规则集: p/security-audit, p/owasp-top-ten, p/r2c-security-audit, 或自定义规则文件路径"
)
severity: Optional[str] = Field(
default=None,
@ -51,7 +51,6 @@ class SemgrepTool(AgentTool):
"""
AVAILABLE_RULESETS = [
"auto",
"p/security-audit",
"p/owasp-top-ten",
"p/r2c-security-audit",
@ -68,11 +67,13 @@ class SemgrepTool(AgentTool):
"p/command-injection",
]
def __init__(self, project_root: str):
def __init__(self, project_root: str, sandbox_manager: Optional["SandboxManager"] = None):
super().__init__()
self.project_root = project_root
self.sandbox_manager = SandboxManager()
# 🔥 将相对路径转换为绝对路径Docker 需要绝对路径
self.project_root = os.path.abspath(project_root)
# 🔥 使用共享的 SandboxManager 实例,避免重复初始化
self.sandbox_manager = sandbox_manager or SandboxManager()
@property
def name(self) -> str:
return "semgrep_scan"
@ -103,7 +104,7 @@ Semgrep 是业界领先的静态分析工具,支持 30+ 种编程语言。
async def _execute(
self,
target_path: str = ".",
rules: str = "auto",
rules: str = "p/security-audit",
severity: Optional[str] = None,
max_results: int = 50,
**kwargs
@ -112,7 +113,7 @@ Semgrep 是业界领先的静态分析工具,支持 30+ 种编程语言。
# 确保 Docker 可用
await self.sandbox_manager.initialize()
if not self.sandbox_manager.is_available:
return ToolResult(success=False, error="Docker 沙箱不可用,无法执行 Semgrep")
return ToolResult(success=False, error=f"Semgrep unavailable: {self.sandbox_manager.get_diagnosis()}")
# 构建命令 (相对于 /workspace)
# 注意: target_path 是相对于 project_root 的
@ -121,7 +122,8 @@ Semgrep 是业界领先的静态分析工具,支持 30+ 种编程语言。
cmd = ["semgrep", "--json", "--quiet"]
if rules == "auto":
cmd.extend(["--config", "auto"])
# 🔥 Fallback if user explicitly requests 'auto', but prefer security-audit
cmd.extend(["--config", "p/security-audit"])
elif rules.startswith("p/"):
cmd.extend(["--config", rules])
else:
@ -139,7 +141,8 @@ Semgrep 是业界领先的静态分析工具,支持 30+ 种编程语言。
result = await self.sandbox_manager.execute_tool_command(
command=cmd_str,
host_workdir=self.project_root,
timeout=300
timeout=300,
network_mode="bridge" # 🔥 Semgrep 需要网络来下载规则
)
if not result["success"] and result["exit_code"] != 1: # 1 means findings were found
@ -230,11 +233,13 @@ class BanditTool(AgentTool):
- 不安全的反序列化
"""
def __init__(self, project_root: str):
def __init__(self, project_root: str, sandbox_manager: Optional["SandboxManager"] = None):
super().__init__()
self.project_root = project_root
self.sandbox_manager = SandboxManager()
# 🔥 将相对路径转换为绝对路径Docker 需要绝对路径
self.project_root = os.path.abspath(project_root)
# 🔥 使用共享的 SandboxManager 实例,避免重复初始化
self.sandbox_manager = sandbox_manager or SandboxManager()
@property
def name(self) -> str:
return "bandit_scan"
@ -271,10 +276,10 @@ Bandit 是 Python 专用的安全分析工具,由 OpenStack 安全团队开发
# 确保 Docker 可用
await self.sandbox_manager.initialize()
if not self.sandbox_manager.is_available:
return ToolResult(success=False, error="Docker 沙箱不可用")
return ToolResult(success=False, error=f"Bandit unavailable: {self.sandbox_manager.get_diagnosis()}")
safe_target_path = target_path if not target_path.startswith("/") else target_path.lstrip("/")
# 构建命令
severity_map = {"low": "l", "medium": "m", "high": "h"}
confidence_map = {"low": "l", "medium": "m", "high": "h"}
@ -360,11 +365,13 @@ class GitleaksTool(AgentTool):
- JWT secrets
"""
def __init__(self, project_root: str):
def __init__(self, project_root: str, sandbox_manager: Optional["SandboxManager"] = None):
super().__init__()
self.project_root = project_root
self.sandbox_manager = SandboxManager()
# 🔥 将相对路径转换为绝对路径Docker 需要绝对路径
self.project_root = os.path.abspath(project_root)
# 🔥 使用共享的 SandboxManager 实例,避免重复初始化
self.sandbox_manager = sandbox_manager or SandboxManager()
@property
def name(self) -> str:
return "gitleaks_scan"
@ -402,30 +409,36 @@ Gitleaks 是专业的密钥检测工具,支持 150+ 种密钥类型。
# 确保 Docker 可用
await self.sandbox_manager.initialize()
if not self.sandbox_manager.is_available:
return ToolResult(success=False, error="Docker 沙箱不可用")
return ToolResult(success=False, error=f"Gitleaks unavailable: {self.sandbox_manager.get_diagnosis()}")
safe_target_path = target_path if not target_path.startswith("/") else target_path.lstrip("/")
# 构建命令 using . as source because we are mounted to /workspace
# But if user specified a subdirectory, we append it.
# Actually gitleaks detects pwd by default if source is .
cmd = ["gitleaks", "detect", "--source", safe_target_path, "-f", "json"]
# 🔥 修复:新版 gitleaks 需要使用 --report-path 输出到文件
# 使用 /tmp 目录tmpfs 可写)
cmd = [
"gitleaks", "detect",
"--source", safe_target_path,
"--report-format", "json",
"--report-path", "/tmp/gitleaks-report.json",
"--exit-code", "0" # 🔥 不要因为发现密钥而返回非零退出码
]
if no_git:
cmd.append("--no-git")
cmd_str = " ".join(cmd)
# 执行 gitleaks 并读取报告文件
cmd_str = " ".join(cmd) + " && cat /tmp/gitleaks-report.json"
try:
result = await self.sandbox_manager.execute_tool_command(
command=cmd_str,
host_workdir=self.project_root,
timeout=120
timeout=180 # 🔥 增加超时时间
)
# Gitleaks returns 1 if secrets found
if result['exit_code'] not in [0, 1]:
return ToolResult(success=False, error=f"Gitleaks 执行失败: {result['stderr'][:300]}")
if result['exit_code'] != 0:
# 🔥 修复:错误信息可能在 error 或 stderr 中
error_msg = result.get('error') or result.get('stderr', '')[:300] or '未知错误'
return ToolResult(success=False, error=f"Gitleaks 执行失败: {error_msg}")
stdout = result['stdout']
@ -502,11 +515,13 @@ class NpmAuditTool(AgentTool):
扫描 Node.js 项目的依赖漏洞基于 npm 官方漏洞数据库
"""
def __init__(self, project_root: str):
def __init__(self, project_root: str, sandbox_manager: Optional["SandboxManager"] = None):
super().__init__()
self.project_root = project_root
self.sandbox_manager = SandboxManager()
# 🔥 将相对路径转换为绝对路径Docker 需要绝对路径
self.project_root = os.path.abspath(project_root)
# 🔥 使用共享的 SandboxManager 实例,避免重复初始化
self.sandbox_manager = sandbox_manager or SandboxManager()
@property
def name(self) -> str:
return "npm_audit"
@ -536,7 +551,7 @@ class NpmAuditTool(AgentTool):
# 确保 Docker 可用
await self.sandbox_manager.initialize()
if not self.sandbox_manager.is_available:
return ToolResult(success=False, error="Docker 沙箱不可用")
return ToolResult(success=False, error=f"npm audit unavailable: {self.sandbox_manager.get_diagnosis()}")
# 这里的 target_path 是相对于 project_root 的
# 防止空路径
@ -645,11 +660,13 @@ class SafetyTool(AgentTool):
检查 Python 依赖中的已知安全漏洞
"""
def __init__(self, project_root: str):
def __init__(self, project_root: str, sandbox_manager: Optional["SandboxManager"] = None):
super().__init__()
self.project_root = project_root
self.sandbox_manager = SandboxManager()
# 🔥 将相对路径转换为绝对路径Docker 需要绝对路径
self.project_root = os.path.abspath(project_root)
# 🔥 使用共享的 SandboxManager 实例,避免重复初始化
self.sandbox_manager = sandbox_manager or SandboxManager()
@property
def name(self) -> str:
return "safety_scan"
@ -677,7 +694,7 @@ class SafetyTool(AgentTool):
# 确保 Docker 可用
await self.sandbox_manager.initialize()
if not self.sandbox_manager.is_available:
return ToolResult(success=False, error="Docker 沙箱不可用")
return ToolResult(success=False, error=f"Safety unavailable: {self.sandbox_manager.get_diagnosis()}")
full_path = os.path.join(self.project_root, requirements_file)
if not os.path.exists(full_path):
@ -768,11 +785,13 @@ class TruffleHogTool(AgentTool):
并可以验证密钥是否仍然有效
"""
def __init__(self, project_root: str):
def __init__(self, project_root: str, sandbox_manager: Optional["SandboxManager"] = None):
super().__init__()
self.project_root = project_root
self.sandbox_manager = SandboxManager()
# 🔥 将相对路径转换为绝对路径Docker 需要绝对路径
self.project_root = os.path.abspath(project_root)
# 🔥 使用共享的 SandboxManager 实例,避免重复初始化
self.sandbox_manager = sandbox_manager or SandboxManager()
@property
def name(self) -> str:
return "trufflehog_scan"
@ -804,10 +823,10 @@ TruffleHog 可以扫描代码和 Git 历史,并验证密钥是否有效。
# 确保 Docker 可用
await self.sandbox_manager.initialize()
if not self.sandbox_manager.is_available:
return ToolResult(success=False, error="Docker 沙箱不可用")
return ToolResult(success=False, error=f"TruffleHog unavailable: {self.sandbox_manager.get_diagnosis()}")
safe_target_path = target_path if not target_path.startswith("/") else target_path.lstrip("/")
cmd = ["trufflehog", "filesystem", safe_target_path, "--json"]
if only_verified:
cmd.append("--only-verified")
@ -879,11 +898,13 @@ class OSVScannerTool(AgentTool):
支持多种包管理器和锁文件
"""
def __init__(self, project_root: str):
def __init__(self, project_root: str, sandbox_manager: Optional["SandboxManager"] = None):
super().__init__()
self.project_root = project_root
self.sandbox_manager = SandboxManager()
# 🔥 将相对路径转换为绝对路径Docker 需要绝对路径
self.project_root = os.path.abspath(project_root)
# 🔥 使用共享的 SandboxManager 实例,避免重复初始化
self.sandbox_manager = sandbox_manager or SandboxManager()
@property
def name(self) -> str:
return "osv_scan"
@ -920,10 +941,10 @@ Google 开源的漏洞扫描工具,使用 OSV (Open Source Vulnerabilities)
# 确保 Docker 可用
await self.sandbox_manager.initialize()
if not self.sandbox_manager.is_available:
return ToolResult(success=False, error="Docker 沙箱不可用")
return ToolResult(success=False, error=f"OSV-Scanner unavailable: {self.sandbox_manager.get_diagnosis()}")
safe_target_path = target_path if not target_path.startswith("/") else target_path.lstrip("/")
# OSV-Scanner
cmd = ["osv-scanner", "--json", "-r", safe_target_path]
cmd_str = " ".join(cmd)

View File

@ -0,0 +1,723 @@
"""
Kunlun-M 静态代码分析工具集成
Kunlun-M (昆仑镜) 是一款开源的静态代码安全审计工具
支持 PHPJavaScript 等语言的语义分析和漏洞检测
MIT License
Copyright (c) 2017 Feei. <feei@feei.cn> All rights reserved
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
原始项目: https://github.com/LoRexxar/Kunlun-M
"""
import asyncio
import json
import logging
import os
import sys
import tempfile
import subprocess
from typing import Optional, List, Dict, Any
from pydantic import BaseModel, Field
from pathlib import Path
from .base import AgentTool, ToolResult
logger = logging.getLogger(__name__)
# Kunlun-M 安装路径(相对于项目根目录)
KUNLUN_M_PATH = os.path.join(
os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))))),
"Kunlun-M-master"
)
class KunlunScanInput(BaseModel):
"""Kunlun-M 扫描输入"""
target_path: str = Field(
description="要扫描的目录或文件路径(相对于项目根目录)"
)
language: Optional[str] = Field(
default=None,
description="指定扫描语言: php, javascript, solidity, chromeext。不指定则自动检测"
)
rules: Optional[str] = Field(
default=None,
description="指定规则ID多个规则用逗号分隔如: 1000,1001,1002"
)
tamper: Optional[str] = Field(
default=None,
description="指定 tamper 名称,用于自定义修复函数检测"
)
include_unconfirmed: bool = Field(
default=False,
description="是否包含未确认的漏洞(疑似漏洞)"
)
max_results: int = Field(
default=50,
description="最大返回结果数"
)
class KunlunRuleListInput(BaseModel):
"""Kunlun-M 规则列表输入"""
language: Optional[str] = Field(
default=None,
description="按语言过滤规则: php, javascript, solidity, chromeext"
)
class KunlunMTool(AgentTool):
"""
Kunlun-M (昆仑镜) 静态代码安全审计工具
特点
- 语义分析深度AST分析减少误报
- 多语言支持PHPJavaScript 语义分析SolidityChrome Extension 基础扫描
- 函数回溯支持污点追踪和数据流分析
- 丰富的规则库覆盖 OWASP Top 10 等常见漏洞
支持的漏洞类型
- SQL 注入
- XSS 跨站脚本
- 命令注入
- 代码执行
- 文件包含
- 文件上传
- 反序列化
- SSRF
- XXE
- 等等...
使用场景
- PHP 代码深度安全审计
- JavaScript 代码安全扫描
- 智能合约安全检查
- Chrome 扩展安全审计
原始项目: https://github.com/LoRexxar/Kunlun-M
License: MIT
"""
SUPPORTED_LANGUAGES = ["php", "javascript", "solidity", "chromeext"]
def __init__(self, project_root: str):
super().__init__()
self.project_root = project_root
self.kunlun_path = KUNLUN_M_PATH
self._initialized = False
self._db_initialized = False
@property
def name(self) -> str:
return "kunlun_scan"
@property
def description(self) -> str:
return """使用 Kunlun-M (昆仑镜) 进行静态代码安全审计。
Kunlun-M 是一款专注于代码安全审计的工具特别擅长 PHP JavaScript 的语义分析
支持的语言
- php: PHP 语义分析最完善
- javascript: JavaScript 语义分析
- solidity: 智能合约基础扫描
- chromeext: Chrome 扩展安全检查
主要功能
- 深度 AST 语义分析
- 污点追踪和函数回溯
- 自定义规则和 tamper 支持
- 支持识别常见安全漏洞
使用场景
- PHP/JS 代码进行深度安全审计
- 检测 SQL 注入XSS命令注入等漏洞
- 分析代码中的危险函数调用
- 追踪用户输入的传播路径"""
@property
def args_schema(self):
return KunlunScanInput
async def _ensure_initialized(self) -> bool:
"""确保 Kunlun-M 已初始化"""
if self._initialized:
return True
# 检查 Kunlun-M 是否存在
if not os.path.exists(self.kunlun_path):
logger.error(f"Kunlun-M not found at {self.kunlun_path}")
return False
kunlun_py = os.path.join(self.kunlun_path, "kunlun.py")
if not os.path.exists(kunlun_py):
logger.error(f"kunlun.py not found at {kunlun_py}")
return False
# 检查数据库是否已初始化
db_path = os.path.join(self.kunlun_path, "db.sqlite3")
if not os.path.exists(db_path):
logger.info("Kunlun-M database not found, initializing...")
try:
await self._initialize_database()
except Exception as e:
logger.error(f"Failed to initialize Kunlun-M database: {e}")
return False
self._initialized = True
return True
async def _initialize_database(self):
"""初始化 Kunlun-M 数据库"""
# 复制 settings.py
settings_bak = os.path.join(self.kunlun_path, "Kunlun_M", "settings.py.bak")
settings_py = os.path.join(self.kunlun_path, "Kunlun_M", "settings.py")
if os.path.exists(settings_bak) and not os.path.exists(settings_py):
import shutil
shutil.copy(settings_bak, settings_py)
# 运行初始化命令
init_cmd = [
sys.executable,
os.path.join(self.kunlun_path, "kunlun.py"),
"init", "initialize"
]
process = await asyncio.create_subprocess_exec(
*init_cmd,
cwd=self.kunlun_path,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
env={**os.environ, "DJANGO_SETTINGS_MODULE": "Kunlun_M.settings"}
)
stdout, stderr = await asyncio.wait_for(process.communicate(), timeout=120)
if process.returncode != 0:
raise Exception(f"Database init failed: {stderr.decode()}")
# 加载规则
load_cmd = [
sys.executable,
os.path.join(self.kunlun_path, "kunlun.py"),
"config", "load"
]
process = await asyncio.create_subprocess_exec(
*load_cmd,
cwd=self.kunlun_path,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
env={**os.environ, "DJANGO_SETTINGS_MODULE": "Kunlun_M.settings"}
)
stdout, stderr = await asyncio.wait_for(process.communicate(), timeout=120)
self._db_initialized = True
logger.info("Kunlun-M database initialized successfully")
async def _execute(
self,
target_path: str = ".",
language: Optional[str] = None,
rules: Optional[str] = None,
tamper: Optional[str] = None,
include_unconfirmed: bool = False,
max_results: int = 50,
**kwargs
) -> ToolResult:
"""执行 Kunlun-M 扫描"""
# 确保初始化
if not await self._ensure_initialized():
return ToolResult(
success=False,
error="Kunlun-M 未正确安装或初始化失败。请确保 Kunlun-M-master 目录存在且依赖已安装。"
)
# 构建完整目标路径
if target_path.startswith("/"):
full_target = target_path
else:
full_target = os.path.join(self.project_root, target_path)
if not os.path.exists(full_target):
return ToolResult(
success=False,
error=f"目标路径不存在: {target_path}"
)
# 构建扫描命令
cmd = [
sys.executable,
os.path.join(self.kunlun_path, "kunlun.py"),
"scan",
"-t", full_target,
"-o", "json" # JSON 输出格式
]
# 添加语言参数
if language:
if language.lower() not in self.SUPPORTED_LANGUAGES:
return ToolResult(
success=False,
error=f"不支持的语言: {language}。支持: {', '.join(self.SUPPORTED_LANGUAGES)}"
)
cmd.extend(["-l", language.lower()])
# 添加规则参数
if rules:
cmd.extend(["-r", rules])
# 添加 tamper 参数
if tamper:
cmd.extend(["-tp", tamper])
# 包含未确认漏洞
if include_unconfirmed:
cmd.append("-uc")
try:
# 创建临时输出文件
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
output_file = f.name
# 修改命令使用输出文件
cmd.extend(["-o", output_file])
logger.debug(f"Running Kunlun-M: {' '.join(cmd)}")
# 执行扫描
process = await asyncio.create_subprocess_exec(
*cmd,
cwd=self.kunlun_path,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
env={**os.environ, "DJANGO_SETTINGS_MODULE": "Kunlun_M.settings"}
)
stdout, stderr = await asyncio.wait_for(
process.communicate(),
timeout=600 # 10 分钟超时
)
stdout_text = stdout.decode('utf-8', errors='ignore')
stderr_text = stderr.decode('utf-8', errors='ignore')
# 解析结果
findings = await self._parse_results(stdout_text, stderr_text, output_file)
# 清理临时文件
try:
os.unlink(output_file)
except:
pass
if not findings:
return ToolResult(
success=True,
data="🛡️ Kunlun-M 扫描完成,未发现安全问题",
metadata={
"findings_count": 0,
"target": target_path,
"language": language
}
)
# 格式化输出
output = self._format_findings(findings[:max_results], target_path)
return ToolResult(
success=True,
data=output,
metadata={
"findings_count": len(findings),
"target": target_path,
"language": language,
"findings": findings[:10] # 只在 metadata 中保存前10个
}
)
except asyncio.TimeoutError:
return ToolResult(
success=False,
error="Kunlun-M 扫描超时10分钟"
)
except Exception as e:
logger.error(f"Kunlun-M scan error: {e}", exc_info=True)
return ToolResult(
success=False,
error=f"扫描执行失败: {str(e)}"
)
async def _parse_results(
self,
stdout: str,
stderr: str,
output_file: str
) -> List[Dict[str, Any]]:
"""解析 Kunlun-M 扫描结果"""
findings = []
# 尝试从输出文件读取 JSON
try:
if os.path.exists(output_file):
with open(output_file, 'r', encoding='utf-8') as f:
data = json.load(f)
if isinstance(data, list):
findings.extend(data)
elif isinstance(data, dict) and 'vulnerabilities' in data:
findings.extend(data['vulnerabilities'])
except Exception as e:
logger.debug(f"Failed to parse output file: {e}")
# 如果没有 JSON 输出,尝试从 stdout 解析
if not findings and stdout:
# 尝试提取 JSON 部分
try:
json_start = stdout.find('[')
json_end = stdout.rfind(']') + 1
if json_start >= 0 and json_end > json_start:
json_str = stdout[json_start:json_end]
findings = json.loads(json_str)
except:
pass
# 尝试解析表格格式输出
if not findings:
findings = self._parse_table_output(stdout)
return findings
def _parse_table_output(self, output: str) -> List[Dict[str, Any]]:
"""解析 Kunlun-M 表格格式输出"""
findings = []
lines = output.split('\n')
for line in lines:
# 匹配漏洞行格式: | index | CVI-xxxx | rule_name | language | file:line | ...
if '|' in line and 'CVI' in line:
parts = [p.strip() for p in line.split('|') if p.strip()]
if len(parts) >= 6:
try:
finding = {
"id": parts[1], # CVI-xxxx
"rule_name": parts[2],
"language": parts[3],
"location": parts[4],
"author": parts[5] if len(parts) > 5 else "",
"code": parts[6] if len(parts) > 6 else "",
"analysis": parts[7] if len(parts) > 7 else "",
}
findings.append(finding)
except:
pass
return findings
def _format_findings(self, findings: List[Dict[str, Any]], target: str) -> str:
"""格式化漏洞发现"""
output_parts = [
f"🔍 Kunlun-M 扫描结果",
f"目标: {target}",
f"发现 {len(findings)} 个潜在安全问题:\n"
]
severity_icons = {
"CRITICAL": "🔴",
"HIGH": "🟠",
"MEDIUM": "🟡",
"LOW": "🟢",
"INFO": ""
}
for i, finding in enumerate(findings, 1):
# 获取严重程度
severity = finding.get("severity", "MEDIUM")
if isinstance(severity, int):
if severity >= 9:
severity = "CRITICAL"
elif severity >= 6:
severity = "HIGH"
elif severity >= 3:
severity = "MEDIUM"
else:
severity = "LOW"
icon = severity_icons.get(severity.upper(), "")
output_parts.append(f"\n{icon} [{i}] {finding.get('rule_name', 'Unknown')}")
output_parts.append(f" ID: {finding.get('id', 'N/A')}")
output_parts.append(f" 语言: {finding.get('language', 'N/A')}")
location = finding.get('location') or finding.get('file_path', '')
line_number = finding.get('line_number', '')
if location:
if line_number:
output_parts.append(f" 位置: {location}:{line_number}")
else:
output_parts.append(f" 位置: {location}")
code = finding.get('code') or finding.get('code_content', '')
if code:
code_preview = code[:100].strip().replace('\n', ' ')
output_parts.append(f" 代码: {code_preview}")
analysis = finding.get('analysis', '')
if analysis:
output_parts.append(f" 分析: {analysis}")
return "\n".join(output_parts)
class KunlunRuleListTool(AgentTool):
"""
查看 Kunlun-M 可用的扫描规则
可以按语言过滤规则了解支持检测的漏洞类型
"""
def __init__(self, project_root: str):
super().__init__()
self.project_root = project_root
self.kunlun_path = KUNLUN_M_PATH
@property
def name(self) -> str:
return "kunlun_list_rules"
@property
def description(self) -> str:
return """查看 Kunlun-M 可用的扫描规则。
可以按语言过滤
- php: PHP 规则
- javascript: JavaScript 规则
- solidity: 智能合约规则
- chromeext: Chrome 扩展规则
返回规则ID名称描述等信息帮助选择合适的规则进行扫描"""
@property
def args_schema(self):
return KunlunRuleListInput
async def _execute(
self,
language: Optional[str] = None,
**kwargs
) -> ToolResult:
"""列出可用规则"""
if not os.path.exists(self.kunlun_path):
return ToolResult(
success=False,
error="Kunlun-M 未安装"
)
# 构建命令
cmd = [
sys.executable,
os.path.join(self.kunlun_path, "kunlun.py"),
"show", "rule"
]
if language:
cmd.extend(["-k", language.lower()])
try:
process = await asyncio.create_subprocess_exec(
*cmd,
cwd=self.kunlun_path,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
env={**os.environ, "DJANGO_SETTINGS_MODULE": "Kunlun_M.settings"}
)
stdout, stderr = await asyncio.wait_for(
process.communicate(),
timeout=60
)
output = stdout.decode('utf-8', errors='ignore')
if not output.strip():
return ToolResult(
success=True,
data="未找到匹配的规则" if language else "规则列表为空,请先运行初始化",
metadata={"language": language}
)
return ToolResult(
success=True,
data=f"📋 Kunlun-M 规则列表{f' ({language})' if language else ''}:\n\n{output}",
metadata={"language": language}
)
except asyncio.TimeoutError:
return ToolResult(
success=False,
error="获取规则列表超时"
)
except Exception as e:
return ToolResult(
success=False,
error=f"获取规则列表失败: {str(e)}"
)
class KunlunPluginInput(BaseModel):
"""Kunlun-M 插件输入"""
plugin_name: str = Field(
description="插件名称: php_unserialize_chain_tools (PHP反序列化链分析), entrance_finder (入口点发现)"
)
target_path: str = Field(
description="要分析的目标路径(相对于项目根目录)"
)
depth: int = Field(
default=3,
description="分析深度(仅对 entrance_finder 有效)"
)
class KunlunPluginTool(AgentTool):
"""
Kunlun-M 插件工具
提供额外的分析功能
- php_unserialize_chain_tools: 自动化寻找 PHP 反序列化链
- entrance_finder: 发现 PHP 代码中的入口点/路由
"""
AVAILABLE_PLUGINS = {
"php_unserialize_chain_tools": "PHP 反序列化链分析工具,用于发现潜在的反序列化攻击链",
"entrance_finder": "入口点发现工具,帮助找到 PHP 代码中的入口页面和路由",
}
def __init__(self, project_root: str):
super().__init__()
self.project_root = project_root
self.kunlun_path = KUNLUN_M_PATH
@property
def name(self) -> str:
return "kunlun_plugin"
@property
def description(self) -> str:
return """运行 Kunlun-M 插件进行专项分析。
可用插件
- php_unserialize_chain_tools: 自动分析 PHP 反序列化链寻找 POP
- entrance_finder: 发现 PHP 入口点和路由
使用场景
- 分析 PHP 框架的反序列化漏洞利用链
- 快速定位大型 PHP 项目的入口文件"""
@property
def args_schema(self):
return KunlunPluginInput
async def _execute(
self,
plugin_name: str,
target_path: str = ".",
depth: int = 3,
**kwargs
) -> ToolResult:
"""执行插件"""
if plugin_name not in self.AVAILABLE_PLUGINS:
return ToolResult(
success=False,
error=f"未知插件: {plugin_name}。可用插件: {', '.join(self.AVAILABLE_PLUGINS.keys())}"
)
if not os.path.exists(self.kunlun_path):
return ToolResult(
success=False,
error="Kunlun-M 未安装"
)
# 构建完整目标路径
if target_path.startswith("/"):
full_target = target_path
else:
full_target = os.path.join(self.project_root, target_path)
if not os.path.exists(full_target):
return ToolResult(
success=False,
error=f"目标路径不存在: {target_path}"
)
# 构建命令
cmd = [
sys.executable,
os.path.join(self.kunlun_path, "kunlun.py"),
"plugin", plugin_name,
"-t", full_target
]
if plugin_name == "entrance_finder":
cmd.extend(["-l", str(depth)])
try:
process = await asyncio.create_subprocess_exec(
*cmd,
cwd=self.kunlun_path,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
env={**os.environ, "DJANGO_SETTINGS_MODULE": "Kunlun_M.settings"}
)
stdout, stderr = await asyncio.wait_for(
process.communicate(),
timeout=300 # 5 分钟超时
)
output = stdout.decode('utf-8', errors='ignore')
if not output.strip():
return ToolResult(
success=True,
data=f"插件 {plugin_name} 执行完成,未发现结果",
metadata={"plugin": plugin_name, "target": target_path}
)
return ToolResult(
success=True,
data=f"🔌 Kunlun-M 插件 [{plugin_name}] 分析结果:\n\n{output}",
metadata={"plugin": plugin_name, "target": target_path}
)
except asyncio.TimeoutError:
return ToolResult(
success=False,
error=f"插件 {plugin_name} 执行超时"
)
except Exception as e:
return ToolResult(
success=False,
error=f"插件执行失败: {str(e)}"
)

View File

@ -40,6 +40,7 @@ class SandboxManager:
self.config = config or SandboxConfig()
self._docker_client = None
self._initialized = False
self._init_error = None
async def initialize(self):
"""初始化 Docker 客户端"""
@ -49,25 +50,34 @@ class SandboxManager:
try:
import docker
logger.info("🔄 Attempting to connect to Docker...")
logger.info(f"🔄 Attempting to connect to Docker... (lib: {docker.__file__})")
self._docker_client = docker.from_env()
# 测试连接
self._docker_client.ping()
self._initialized = True
self._init_error = None
logger.info("✅ Docker sandbox manager initialized successfully")
except ImportError as e:
logger.error(f"❌ Docker library not installed: {e}")
self._docker_client = None
self._init_error = f"ImportError: {e}"
except Exception as e:
logger.warning(f"❌ Docker not available: {e}")
import traceback
logger.warning(f"Docker connection traceback: {traceback.format_exc()}")
self._docker_client = None
self._init_error = f"{type(e).__name__}: {str(e)}"
@property
def is_available(self) -> bool:
"""检查 Docker 是否可用"""
return self._docker_client is not None
def get_diagnosis(self) -> str:
"""获取诊断信息"""
if self.is_available:
return "Docker Service Available"
return f"Docker Service Unavailable. Error: {self._init_error or 'Not initialized'}"
async def execute_command(
self,
@ -211,12 +221,20 @@ class SandboxManager:
}
timeout = timeout or self.config.timeout
try:
# 🔥 清除代理环境变量的方式:在命令前添加 unset
# 因为设置空字符串会导致工具尝试解析空 URI 而出错
unset_proxy_prefix = "unset HTTP_PROXY HTTPS_PROXY http_proxy https_proxy; "
wrapped_command = unset_proxy_prefix + command
# 用户传入的环境变量
container_env = env or {}
# 准备容器配置
container_config = {
"image": self.config.image,
"command": ["sh", "-c", command],
"command": ["sh", "-c", wrapped_command],
"detach": True,
"mem_limit": self.config.memory_limit,
"cpu_period": 100000,
@ -228,10 +246,11 @@ class SandboxManager:
host_workdir: {"bind": "/workspace", "mode": "ro"}, # 只读挂载项目代码
},
"tmpfs": {
"/home/sandbox": "rw,size=100m,mode=1777"
"/home/sandbox": "rw,size=100m,mode=1777",
"/tmp": "rw,size=100m,mode=1777" # 🔥 添加 /tmp 目录供工具写入临时文件
},
"working_dir": "/workspace",
"environment": env or {},
"environment": container_env, # 🔥 用户传入的环境变量
"cap_drop": ["ALL"],
"security_opt": ["no-new-privileges:true"],
}

View File

@ -0,0 +1,16 @@
import sys
try:
import docker
print(f"Docker module: {docker.__file__}")
client = docker.from_env()
print("Client created")
client.ping()
print("Docker is available and ping successful")
print(f"Docker version: {client.version()}")
except ImportError:
print("Docker library not installed")
except Exception as e:
print(f"Docker unavailable: {e}")
import traceback
traceback.print_exc()

31
backend/check_sandbox.py Normal file
View File

@ -0,0 +1,31 @@
import asyncio
import logging
import sys
import os
# Add backend to path
sys.path.append(os.getcwd())
# Configure logging
logging.basicConfig(level=logging.INFO)
from app.services.agent.tools.sandbox_tool import SandboxManager
async def main():
print("Checking SandboxManager...")
mgr = SandboxManager()
await mgr.initialize()
print(f"Is available: {mgr.is_available}")
print(f"Diagnosis: {mgr.get_diagnosis()}")
if mgr.is_available:
print("Docker client created successfully.")
try:
ver = mgr._docker_client.version()
print(f"Docker version: {ver}")
except Exception as e:
print(f"Error getting version: {e}")
if __name__ == "__main__":
asyncio.run(main())

View File

@ -1,28 +1,211 @@
[project]
name = "deepaudit-backend"
version = "2.0.0-beta.7"
description = "DeepAudit Backend API"
requires-python = ">=3.13"
dependencies = [
"fastapi>=0.100.0",
"uvicorn[standard]",
"sqlalchemy>=2.0.0",
"asyncpg",
"alembic",
"pydantic>=2.0.0",
"pydantic-settings",
"passlib[bcrypt]",
"python-jose[cryptography]",
"python-multipart",
"httpx",
"email-validator",
"greenlet",
"bcrypt<5.0.0",
"litellm>=1.0.0",
"reportlab>=4.0.0",
"weasyprint>=66.0",
"jinja2>=3.1.6",
"json-repair>=0.30.0",
"bandit>=1.9.2",
"safety>=3.7.0",
version = "3.0.0"
description = "DeepAudit Backend API - AI-Powered Code Security Audit Platform"
requires-python = ">=3.11,<3.13"
readme = "README.md"
license = { text = "MIT" }
authors = [
{ name = "DeepAudit Team" }
]
keywords = ["security", "audit", "code-review", "vulnerability", "ai", "llm"]
dependencies = [
# ============ Web Framework ============
"fastapi>=0.100.0",
"uvicorn[standard]>=0.23.0",
"sse-starlette>=1.8.2",
# ============ Database ============
"sqlalchemy>=2.0.0",
"asyncpg>=0.29.0",
"alembic>=1.13.0",
"greenlet>=3.0.0",
# ============ Data Validation ============
"pydantic>=2.0.0",
"pydantic-settings>=2.0.0",
"email-validator>=2.1.0",
# ============ Authentication ============
"passlib[bcrypt]>=1.7.4",
"python-jose[cryptography]>=3.3.0",
"python-multipart>=0.0.6",
"bcrypt>=4.0.0,<5.0.0",
# ============ HTTP Client ============
"httpx>=0.25.0",
# ============ LLM Integration ============
"litellm>=1.0.0",
"tiktoken>=0.5.2",
# ============ Report Generation ============
"reportlab>=4.0.0",
"weasyprint>=60.0",
"jinja2>=3.1.6",
# ============ Utilities ============
"json-repair>=0.30.0",
"aiofiles>=23.2.1",
# ============ LangChain & LangGraph ============
"langchain>=0.1.0",
"langchain-community>=0.0.20",
"langchain-openai>=0.0.5",
"langgraph>=0.0.40",
# ============ Vector Database ============
"chromadb>=0.4.22",
# ============ Code Parsing ============
"tree-sitter>=0.21.0",
"tree-sitter-languages>=1.10.0",
"pygments>=2.17.0",
# ============ Docker Sandbox ============
"docker>=7.0.0",
# ============ Security Tools ============
"bandit>=1.7.0",
"safety>=2.3.0",
"pip-audit>=2.6.0",
# ============ Kunlun-M Dependencies (MIT License) ============
# https://github.com/LoRexxar/Kunlun-M
"pyjsparser>=2.7.1",
"phply>=1.2.6",
"esprima>=4.0.1",
"jsbeautifier>=1.14.0",
"colorlog>=6.0.0",
"portalocker>=2.0.0",
"prettytable>=3.0.0",
"rarfile>=4.0",
"beautifulsoup4>=4.12.0",
"django>=4.2.0",
]
[project.optional-dependencies]
# MySQL support for Kunlun-M web mode
mysql = ["mysqlclient>=2.2.0"]
# Development tools
dev = [
"pytest>=7.4.0",
"pytest-asyncio>=0.21.0",
"pytest-cov>=4.1.0",
"black>=23.0.0",
"ruff>=0.1.0",
"mypy>=1.5.0",
"pre-commit>=3.5.0",
]
# Documentation
docs = [
"mkdocs>=1.5.0",
"mkdocs-material>=9.4.0",
"mkdocstrings[python]>=0.23.0",
]
[project.urls]
Homepage = "https://github.com/your-org/deepaudit"
Documentation = "https://docs.deepaudit.io"
Repository = "https://github.com/your-org/deepaudit"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["app"]
# ============ Tool Configurations ============
[tool.black]
line-length = 100
target-version = ["py311", "py312", "py313"]
exclude = '''
/(
\.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| _build
| buck-out
| build
| dist
| migrations
)/
'''
[tool.ruff]
line-length = 100
target-version = "py311"
exclude = [
".git",
".hg",
".mypy_cache",
".tox",
".venv",
"_build",
"buck-out",
"build",
"dist",
"migrations",
]
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # Pyflakes
"I", # isort
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"UP", # pyupgrade
]
ignore = [
"E501", # line too long (handled by black)
"B008", # do not perform function calls in argument defaults
"C901", # too complex
]
[tool.mypy]
python_version = "3.11"
warn_return_any = true
warn_unused_ignores = true
disallow_untyped_defs = true
exclude = [
"migrations/",
".venv/",
]
[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
addopts = "-v --tb=short"
[tool.coverage.run]
source = ["app"]
omit = ["*/migrations/*", "*/tests/*"]
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"def __repr__",
"raise NotImplementedError",
"if TYPE_CHECKING:",
]
# ============ UV Configuration ============
[tool.uv]
dev-dependencies = [
"pytest>=7.4.0",
"pytest-asyncio>=0.21.0",
"pytest-cov>=4.1.0",
"black>=23.0.0",
"ruff>=0.1.0",
"mypy>=1.5.0",
]

View File

@ -1,9 +1,13 @@
# This file was autogenerated by uv via the following command:
# uv pip compile requirements.txt -o requirements-lock.txt
# uv pip compile requirements.txt -o requirements-lock.txt --python-version 3.12
aiofiles==25.1.0
# via -r requirements.txt
aiohappyeyeballs==2.6.1
# via aiohttp
aiohttp==3.13.2
# via litellm
# via
# langchain-community
# litellm
aiosignal==1.4.0
# via aiohttp
alembic==1.17.2
@ -16,8 +20,11 @@ anyio==4.11.0
# via
# httpx
# openai
# sse-starlette
# starlette
# watchfiles
asgiref==3.11.0
# via django
asyncpg==0.31.0
# via -r requirements.txt
attrs==25.4.0
@ -25,16 +32,34 @@ attrs==25.4.0
# aiohttp
# jsonschema
# referencing
authlib==1.6.6
# via safety
backoff==2.2.1
# via posthog
bandit==1.9.2
# via -r requirements.txt
bcrypt==4.3.0
# via
# -r requirements.txt
# chromadb
# passlib
beautifulsoup4==4.14.3
# via -r requirements.txt
boolean-py==5.0
# via license-expression
brotli==1.2.0
# via fonttools
build==1.3.0
# via chromadb
cachecontrol==0.14.4
# via pip-audit
cachetools==6.2.3
# via google-auth
certifi==2025.11.12
# via
# httpcore
# httpx
# kubernetes
# requests
cffi==2.0.0
# via
@ -44,29 +69,67 @@ charset-normalizer==3.4.4
# via
# reportlab
# requests
chromadb==1.3.7
# via -r requirements.txt
click==8.3.1
# via
# litellm
# nltk
# safety
# typer
# typer-slim
# uvicorn
coloredlogs==15.0.1
# via onnxruntime
colorlog==6.10.1
# via -r requirements.txt
cryptography==46.0.3
# via python-jose
# via
# authlib
# python-jose
cssselect2==0.8.0
# via weasyprint
cyclonedx-python-lib==11.6.0
# via pip-audit
dataclasses-json==0.6.7
# via langchain-community
defusedxml==0.7.1
# via py-serializable
distro==1.9.0
# via openai
# via
# openai
# posthog
django==6.0
# via -r requirements.txt
dnspython==2.8.0
# via email-validator
docker==7.1.0
# via -r requirements.txt
dparse==0.6.4
# via
# safety
# safety-schemas
durationpy==0.10
# via kubernetes
ecdsa==0.19.1
# via python-jose
editorconfig==0.17.1
# via jsbeautifier
email-validator==2.3.0
# via -r requirements.txt
esprima==4.0.1
# via -r requirements.txt
fastapi==0.122.0
# via -r requirements.txt
fastuuid==0.14.0
# via litellm
filelock==3.20.0
# via huggingface-hub
# via
# cachecontrol
# huggingface-hub
# safety
flatbuffers==25.9.23
# via onnxruntime
fonttools==4.61.0
# via weasyprint
frozenlist==1.8.0
@ -75,10 +138,17 @@ frozenlist==1.8.0
# aiosignal
fsspec==2025.12.0
# via huggingface-hub
google-auth==2.43.0
# via kubernetes
googleapis-common-protos==1.72.0
# via opentelemetry-exporter-otlp-proto-grpc
greenlet==3.3.0
# via -r requirements.txt
grpcio==1.67.1
# via litellm
# via
# chromadb
# litellm
# opentelemetry-exporter-otlp-proto-grpc
h11==0.16.0
# via
# httpcore
@ -92,11 +162,19 @@ httptools==0.7.1
httpx==0.28.1
# via
# -r requirements.txt
# chromadb
# huggingface-hub
# langgraph-sdk
# langsmith
# litellm
# openai
# safety
httpx-sse==0.4.3
# via langchain-community
huggingface-hub==1.2.1
# via tokenizers
humanfriendly==10.0
# via coloredlogs
idna==3.11
# via
# anyio
@ -105,66 +183,251 @@ idna==3.11
# requests
# yarl
importlib-metadata==8.7.0
# via litellm
# via
# litellm
# opentelemetry-api
importlib-resources==6.5.2
# via chromadb
jinja2==3.1.6
# via
# -r requirements.txt
# litellm
# safety
jiter==0.12.0
# via openai
joblib==1.5.2
# via nltk
jsbeautifier==1.15.4
# via -r requirements.txt
json-repair==0.54.2
# via -r requirements.txt
jsonpatch==1.33
# via langchain-core
jsonpointer==3.0.0
# via jsonpatch
jsonschema==4.25.1
# via litellm
# via
# chromadb
# litellm
jsonschema-specifications==2025.9.1
# via jsonschema
kubernetes==34.1.0
# via chromadb
langchain==1.1.3
# via -r requirements.txt
langchain-classic==1.0.0
# via langchain-community
langchain-community==0.4.1
# via -r requirements.txt
langchain-core==1.2.0
# via
# langchain
# langchain-classic
# langchain-community
# langchain-openai
# langchain-text-splitters
# langgraph
# langgraph-checkpoint
# langgraph-prebuilt
langchain-openai==1.1.3
# via -r requirements.txt
langchain-text-splitters==1.1.0
# via langchain-classic
langgraph==1.0.5
# via
# -r requirements.txt
# langchain
langgraph-checkpoint==3.0.1
# via
# langgraph
# langgraph-prebuilt
langgraph-prebuilt==1.0.5
# via langgraph
langgraph-sdk==0.3.0
# via langgraph
langsmith==0.4.59
# via
# langchain-classic
# langchain-community
# langchain-core
license-expression==30.4.4
# via cyclonedx-python-lib
litellm==1.80.8
# via -r requirements.txt
mako==1.3.10
# via alembic
markdown-it-py==4.0.0
# via rich
markupsafe==3.0.3
# via
# jinja2
# mako
marshmallow==3.26.1
# via
# dataclasses-json
# safety
mdurl==0.1.2
# via markdown-it-py
mmh3==5.2.0
# via chromadb
mpmath==1.3.0
# via sympy
msgpack==1.1.2
# via cachecontrol
multidict==6.7.0
# via
# aiohttp
# yarl
mypy-extensions==1.1.0
# via typing-inspect
nltk==3.9.2
# via safety
numpy==2.3.5
# via
# chromadb
# langchain-community
# onnxruntime
oauthlib==3.3.1
# via requests-oauthlib
onnxruntime==1.23.2
# via chromadb
openai==2.9.0
# via litellm
# via
# langchain-openai
# litellm
opentelemetry-api==1.39.1
# via
# chromadb
# opentelemetry-exporter-otlp-proto-grpc
# opentelemetry-sdk
# opentelemetry-semantic-conventions
opentelemetry-exporter-otlp-proto-common==1.39.1
# via opentelemetry-exporter-otlp-proto-grpc
opentelemetry-exporter-otlp-proto-grpc==1.39.1
# via chromadb
opentelemetry-proto==1.39.1
# via
# opentelemetry-exporter-otlp-proto-common
# opentelemetry-exporter-otlp-proto-grpc
opentelemetry-sdk==1.39.1
# via
# chromadb
# opentelemetry-exporter-otlp-proto-grpc
opentelemetry-semantic-conventions==0.60b1
# via opentelemetry-sdk
orjson==3.11.5
# via
# chromadb
# langgraph-sdk
# langsmith
ormsgpack==1.12.1
# via langgraph-checkpoint
overrides==7.7.0
# via chromadb
packageurl-python==0.17.6
# via cyclonedx-python-lib
packaging==25.0
# via huggingface-hub
# via
# build
# dparse
# huggingface-hub
# langchain-core
# langsmith
# marshmallow
# onnxruntime
# pip-audit
# pip-requirements-parser
# safety
# safety-schemas
passlib==1.7.4
# via -r requirements.txt
phply==1.2.6
# via -r requirements.txt
pillow==12.0.0
# via
# reportlab
# weasyprint
pip==25.3
# via pip-api
pip-api==0.0.34
# via pip-audit
pip-audit==2.10.0
# via -r requirements.txt
pip-requirements-parser==32.0.1
# via pip-audit
platformdirs==4.5.1
# via pip-audit
ply==3.11
# via phply
portalocker==3.2.0
# via -r requirements.txt
posthog==5.4.0
# via chromadb
prettytable==3.17.0
# via -r requirements.txt
propcache==0.4.1
# via
# aiohttp
# yarl
protobuf==6.33.2
# via
# googleapis-common-protos
# onnxruntime
# opentelemetry-proto
py-serializable==2.1.0
# via cyclonedx-python-lib
pyasn1==0.6.1
# via
# pyasn1-modules
# python-jose
# rsa
pyasn1-modules==0.4.2
# via google-auth
pybase64==1.4.3
# via chromadb
pycparser==2.23
# via cffi
pydantic==2.12.4
# via
# -r requirements.txt
# chromadb
# fastapi
# langchain
# langchain-classic
# langchain-core
# langgraph
# langsmith
# litellm
# openai
# pydantic-settings
# safety
# safety-schemas
pydantic-core==2.41.5
# via pydantic
pydantic-settings==2.12.0
# via -r requirements.txt
# via
# -r requirements.txt
# langchain-community
pydyf==0.12.1
# via weasyprint
pygments==2.19.2
# via
# -r requirements.txt
# rich
pyjsparser==2.7.1
# via -r requirements.txt
pyparsing==3.2.5
# via pip-requirements-parser
pyphen==0.17.2
# via weasyprint
pypika==0.48.9
# via chromadb
pyproject-hooks==1.2.0
# via build
python-dateutil==2.9.0.post0
# via
# kubernetes
# posthog
python-dotenv==1.2.1
# via
# litellm
@ -176,40 +439,114 @@ python-multipart==0.0.20
# via -r requirements.txt
pyyaml==6.0.3
# via
# bandit
# chromadb
# huggingface-hub
# kubernetes
# langchain-classic
# langchain-community
# langchain-core
# uvicorn
rarfile==4.2
# via -r requirements.txt
referencing==0.37.0
# via
# jsonschema
# jsonschema-specifications
regex==2025.11.3
# via tiktoken
# via
# nltk
# tiktoken
reportlab==4.4.5
# via -r requirements.txt
requests==2.32.5
# via tiktoken
# via
# cachecontrol
# docker
# kubernetes
# langchain-classic
# langchain-community
# langsmith
# pip-audit
# posthog
# requests-oauthlib
# requests-toolbelt
# safety
# tiktoken
requests-oauthlib==2.0.0
# via kubernetes
requests-toolbelt==1.0.0
# via langsmith
rich==14.2.0
# via
# bandit
# chromadb
# pip-audit
# typer
rpds-py==0.30.0
# via
# jsonschema
# referencing
rsa==4.9.1
# via python-jose
# via
# google-auth
# python-jose
ruamel-yaml==0.18.16
# via
# safety
# safety-schemas
ruamel-yaml-clib==0.2.15
# via ruamel-yaml
safety==3.7.0
# via -r requirements.txt
safety-schemas==0.0.16
# via safety
shellingham==1.5.4
# via huggingface-hub
# via
# huggingface-hub
# typer
six==1.17.0
# via ecdsa
# via
# ecdsa
# jsbeautifier
# kubernetes
# posthog
# python-dateutil
sniffio==1.3.1
# via
# anyio
# openai
sortedcontainers==2.4.0
# via cyclonedx-python-lib
soupsieve==2.8
# via beautifulsoup4
sqlalchemy==2.0.44
# via
# -r requirements.txt
# alembic
# langchain-classic
# langchain-community
sqlparse==0.5.4
# via django
sse-starlette==3.0.3
# via -r requirements.txt
starlette==0.50.0
# via fastapi
stevedore==5.6.0
# via bandit
sympy==1.14.0
# via onnxruntime
tenacity==9.1.2
# via
# chromadb
# langchain-community
# langchain-core
# safety
tiktoken==0.12.0
# via litellm
# via
# -r requirements.txt
# langchain-openai
# litellm
tinycss2==1.5.1
# via
# cssselect2
@ -217,36 +554,85 @@ tinycss2==1.5.1
tinyhtml5==2.0.0
# via weasyprint
tokenizers==0.22.1
# via litellm
# via
# chromadb
# litellm
tomli==2.3.0
# via pip-audit
tomli-w==1.2.0
# via pip-audit
tomlkit==0.13.3
# via safety
tqdm==4.67.1
# via
# chromadb
# huggingface-hub
# nltk
# openai
tree-sitter==0.25.2
# via
# -r requirements.txt
# tree-sitter-languages
tree-sitter-languages==1.10.2
# via -r requirements.txt
typer==0.20.0
# via
# chromadb
# safety
typer-slim==0.20.0
# via huggingface-hub
typing-extensions==4.15.0
# via
# aiosignal
# alembic
# anyio
# beautifulsoup4
# chromadb
# cyclonedx-python-lib
# fastapi
# huggingface-hub
# langchain-core
# openai
# opentelemetry-api
# opentelemetry-exporter-otlp-proto-grpc
# opentelemetry-sdk
# opentelemetry-semantic-conventions
# pydantic
# pydantic-core
# referencing
# safety
# safety-schemas
# sqlalchemy
# starlette
# typer
# typer-slim
# typing-inspect
# typing-inspection
typing-inspect==0.9.0
# via dataclasses-json
typing-inspection==0.4.2
# via
# pydantic
# pydantic-settings
urllib3==2.6.0
# via requests
urllib3==2.3.0
# via
# docker
# kubernetes
# requests
uuid-utils==0.12.0
# via
# langchain-core
# langsmith
uvicorn==0.38.0
# via -r requirements.txt
# via
# -r requirements.txt
# chromadb
uvloop==0.22.1
# via uvicorn
watchfiles==1.1.1
# via uvicorn
wcwidth==0.2.14
# via prettytable
weasyprint==67.0
# via -r requirements.txt
webencodings==0.5.1
@ -254,11 +640,17 @@ webencodings==0.5.1
# cssselect2
# tinycss2
# tinyhtml5
websocket-client==1.9.0
# via kubernetes
websockets==15.0.1
# via uvicorn
xxhash==3.6.0
# via langgraph
yarl==1.22.0
# via aiohttp
zipp==3.23.0
# via importlib-metadata
zopfli==0.4.0
# via fonttools
zstandard==0.25.0
# via langsmith

View File

@ -65,3 +65,29 @@ safety>=2.3.0
# 依赖漏洞扫描
pip-audit>=2.6.0
# ============ Kunlun-M 依赖 (MIT License) ============
# https://github.com/LoRexxar/Kunlun-M
# Kunlun-M 是静态代码安全审计工具,支持 PHP/JS 语义分析
# PHP/JS 解析器
pyjsparser>=2.7.1
phply>=1.2.6
esprima>=4.0.1
jsbeautifier>=1.14.0
# 工具库
colorlog>=6.0.0
portalocker>=2.0.0
prettytable>=3.0.0
rarfile>=4.0
# HTML 解析
beautifulsoup4>=4.12.0
# Django (Kunlun-M 数据库)
django>=4.2.0
# MySQL 客户端 (可选,用于 Kunlun-M Web 模式)
# 如需 MySQL 支持,请安装: pip install mysqlclient
# 注意: mysqlclient 需要系统级 MySQL 开发库

View File

@ -449,7 +449,7 @@ export default function FileSelectionDialog({
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="!max-w-[1000px] !w-[95vw] max-h-[85vh] flex flex-col cyber-card p-0 bg-[#0c0c12]">
<DialogContent className="!max-w-[1000px] !w-[95vw] max-h-[85vh] flex flex-col cyber-card p-0 bg-[#0c0c12] !fixed">
<DialogHeader className="cyber-card-header flex-shrink-0">
<div className="flex items-center gap-3">
<FolderOpen className="w-5 h-5 text-primary" />
@ -464,7 +464,7 @@ export default function FileSelectionDialog({
)}
</DialogHeader>
<div className="p-5 flex-1 flex flex-col min-h-0 space-y-3">
<div className="p-5 flex-1 flex flex-col min-h-0 space-y-3 overflow-y-auto">
{/* 工具栏 */}
<div className="flex items-center gap-2 flex-wrap">
{/* 搜索框 */}

View File

@ -60,91 +60,49 @@ export default function ExportReportDialog({
}
};
const formats = [
{
value: "json" as ExportFormat,
label: "JSON 格式",
description: "结构化数据,适合程序处理和集成",
icon: FileJson,
color: "text-amber-400",
bgColor: "bg-amber-500/20",
borderColor: "border-amber-500/30"
},
{
value: "pdf" as ExportFormat,
label: "PDF 格式",
description: "专业报告,适合打印和分享",
icon: FileText,
color: "text-rose-400",
bgColor: "bg-rose-500/20",
borderColor: "border-rose-500/30"
}
];
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-[600px] cyber-card p-0 bg-[#0c0c12]">
<DialogHeader className="cyber-card-header">
<div className="flex items-center gap-3">
<DialogContent className="sm:max-w-[600px] bg-[#0c0c12] border-gray-700">
<DialogHeader>
<DialogTitle className="flex items-center gap-3 text-lg font-bold uppercase tracking-wider text-white">
<Download className="w-5 h-5 text-primary" />
<DialogTitle className="text-lg font-bold uppercase tracking-wider text-white">
</DialogTitle>
</div>
</DialogTitle>
<DialogDescription className="text-gray-400 font-mono text-xs">
</DialogDescription>
</DialogHeader>
<DialogDescription className="px-6 pt-4 text-gray-400 font-mono text-xs">
</DialogDescription>
<div className="p-6">
<div className="py-4">
<RadioGroup
value={selectedFormat}
onValueChange={(value) => setSelectedFormat(value as ExportFormat)}
className="space-y-4"
>
{formats.map((format) => {
const Icon = format.icon;
const isSelected = selectedFormat === format.value;
return (
<div key={format.value} className="relative">
<RadioGroupItem
value={format.value}
id={format.value}
className="peer sr-only"
/>
<Label
htmlFor={format.value}
className={`flex items-start space-x-4 p-4 border cursor-pointer transition-all rounded font-mono ${isSelected
? "border-primary bg-primary/10"
: "border-gray-700 bg-gray-900/30 hover:bg-gray-800/50 hover:border-gray-600"
}`}
>
<div
className={`w-12 h-12 flex items-center justify-center rounded ${isSelected ? "bg-primary/20 border border-primary/50" : format.bgColor + " border " + format.borderColor
}`}
>
<Icon className={`w-6 h-6 ${isSelected ? "text-primary" : format.color}`} />
</div>
<div className="flex-1">
<div className="flex items-center justify-between mb-1">
<h4 className={`font-bold uppercase ${isSelected ? "text-primary" : "text-gray-200"}`}>
{format.label}
</h4>
{isSelected && (
<div className="w-3 h-3 bg-primary rounded-full shadow-[0_0_10px_rgba(255,107,44,0.5)]" />
)}
</div>
<p className="text-xs text-gray-500">{format.description}</p>
</div>
</Label>
<div className="flex items-center space-x-3 p-4 border border-gray-700 rounded bg-gray-900/30 cursor-pointer hover:bg-gray-800/50">
<RadioGroupItem value="json" id="json" />
<Label htmlFor="json" className="flex items-center gap-3 cursor-pointer flex-1">
<FileJson className="w-5 h-5 text-amber-400" />
<div>
<div className="font-bold text-gray-200">JSON </div>
<div className="text-xs text-gray-500"></div>
</div>
);
})}
</Label>
</div>
<div className="flex items-center space-x-3 p-4 border border-gray-700 rounded bg-gray-900/30 cursor-pointer hover:bg-gray-800/50">
<RadioGroupItem value="pdf" id="pdf" />
<Label htmlFor="pdf" className="flex items-center gap-3 cursor-pointer flex-1">
<FileText className="w-5 h-5 text-rose-400" />
<div>
<div className="font-bold text-gray-200">PDF </div>
<div className="text-xs text-gray-500"></div>
</div>
</Label>
</div>
</RadioGroup>
{/* 报告预览信息 */}
<div className="mt-6 cyber-card p-0">
<div className="mt-6 border border-gray-700 rounded bg-gray-900/30">
<div className="px-4 py-2 border-b border-gray-800 bg-gray-900/50 flex items-center gap-2">
<Terminal className="w-3 h-3 text-primary" />
<h4 className="font-bold text-gray-300 uppercase text-xs"></h4>
@ -180,19 +138,17 @@ export default function ExportReportDialog({
</div>
</div>
<DialogFooter className="p-4 border-t border-gray-800 bg-gray-900/50 flex justify-end gap-3">
<DialogFooter className="border-t border-gray-800 pt-4">
<Button
variant="outline"
onClick={() => onOpenChange(false)}
disabled={isExporting}
className="cyber-btn-outline h-10"
>
</Button>
<Button
onClick={handleExport}
disabled={isExporting}
className="cyber-btn-primary h-10 font-bold uppercase"
>
{isExporting ? (
<>

View File

@ -68,105 +68,54 @@ export default function InstantExportDialog({
}
};
const formats = [
{
value: "json" as ExportFormat,
label: "JSON 格式",
description: "结构化数据,适合程序处理和集成",
icon: FileJson,
color: "text-amber-400",
bgColor: "bg-amber-500/20",
borderColor: "border-amber-500/30",
disabled: false
},
{
value: "pdf" as ExportFormat,
label: "PDF 格式",
description: analysisId ? "专业报告,适合打印和分享" : "需要先保存到历史记录",
icon: FileText,
color: "text-rose-400",
bgColor: "bg-rose-500/20",
borderColor: "border-rose-500/30",
disabled: !analysisId
}
];
const isPdfDisabled = !analysisId;
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-[600px] cyber-card p-0 bg-[#0c0c12]">
<DialogHeader className="cyber-card-header">
<div className="flex items-center gap-3">
<DialogContent className="sm:max-w-[600px] bg-[#0c0c12] border-gray-700">
<DialogHeader>
<DialogTitle className="flex items-center gap-3 text-lg font-bold uppercase tracking-wider text-white">
<Download className="w-5 h-5 text-primary" />
<DialogTitle className="text-lg font-bold uppercase tracking-wider text-white">
</DialogTitle>
</div>
</DialogTitle>
<DialogDescription className="text-gray-400 font-mono text-xs">
</DialogDescription>
</DialogHeader>
<DialogDescription className="px-6 pt-4 text-gray-400 font-mono text-xs">
</DialogDescription>
<div className="p-6">
<div className="py-4">
<RadioGroup
value={selectedFormat}
onValueChange={(value) => setSelectedFormat(value as ExportFormat)}
className="space-y-4"
>
{formats.map((format) => {
const Icon = format.icon;
const isSelected = selectedFormat === format.value;
return (
<div key={format.value} className="relative">
<RadioGroupItem
value={format.value}
id={format.value}
className="peer sr-only"
disabled={format.disabled}
/>
<Label
htmlFor={format.value}
className={`flex items-start space-x-4 p-4 border cursor-pointer transition-all rounded font-mono ${
format.disabled
? "border-gray-800 bg-gray-900/20 cursor-not-allowed opacity-50"
: isSelected
? "border-primary bg-primary/10"
: "border-gray-700 bg-gray-900/30 hover:bg-gray-800/50 hover:border-gray-600"
}`}
>
<div
className={`w-12 h-12 flex items-center justify-center rounded ${
format.disabled
? "bg-gray-800 border border-gray-700"
: isSelected
? "bg-primary/20 border border-primary/50"
: format.bgColor + " border " + format.borderColor
}`}
>
<Icon className={`w-6 h-6 ${format.disabled ? "text-gray-600" : isSelected ? "text-primary" : format.color}`} />
</div>
<div className="flex-1">
<div className="flex items-center justify-between mb-1">
<h4 className={`font-bold uppercase ${format.disabled ? "text-gray-600" : isSelected ? "text-primary" : "text-gray-200"}`}>
{format.label}
</h4>
{isSelected && !format.disabled && (
<div className="w-3 h-3 bg-primary rounded-full shadow-[0_0_10px_rgba(255,107,44,0.5)]" />
)}
</div>
<p className={`text-xs ${format.disabled ? "text-gray-600" : "text-gray-500"}`}>
{format.disabled && <AlertTriangle className="w-3 h-3 inline mr-1 text-amber-500" />}
{format.description}
</p>
</div>
</Label>
<div className="flex items-center space-x-3 p-4 border border-gray-700 rounded bg-gray-900/30 cursor-pointer hover:bg-gray-800/50">
<RadioGroupItem value="json" id="json" />
<Label htmlFor="json" className="flex items-center gap-3 cursor-pointer flex-1">
<FileJson className="w-5 h-5 text-amber-400" />
<div>
<div className="font-bold text-gray-200">JSON </div>
<div className="text-xs text-gray-500"></div>
</div>
);
})}
</Label>
</div>
<div className={`flex items-center space-x-3 p-4 border border-gray-700 rounded bg-gray-900/30 ${isPdfDisabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer hover:bg-gray-800/50'}`}>
<RadioGroupItem value="pdf" id="pdf" disabled={isPdfDisabled} />
<Label htmlFor="pdf" className={`flex items-center gap-3 flex-1 ${isPdfDisabled ? 'cursor-not-allowed' : 'cursor-pointer'}`}>
<FileText className="w-5 h-5 text-rose-400" />
<div>
<div className="font-bold text-gray-200">PDF </div>
<div className="text-xs text-gray-500">
{isPdfDisabled && <AlertTriangle className="w-3 h-3 inline mr-1 text-amber-500" />}
{isPdfDisabled ? "需要先保存到历史记录" : "专业报告,适合打印和分享"}
</div>
</div>
</Label>
</div>
</RadioGroup>
{/* 报告预览信息 */}
<div className="mt-6 cyber-card p-0">
<div className="mt-6 border border-gray-700 rounded bg-gray-900/30">
<div className="px-4 py-2 border-b border-gray-800 bg-gray-900/50 flex items-center gap-2">
<Terminal className="w-3 h-3 text-primary" />
<h4 className="font-bold text-gray-300 uppercase text-xs"></h4>
@ -192,19 +141,17 @@ export default function InstantExportDialog({
</div>
</div>
<DialogFooter className="p-4 border-t border-gray-800 bg-gray-900/50 flex justify-end gap-3">
<DialogFooter className="border-t border-gray-800 pt-4">
<Button
variant="outline"
onClick={() => onOpenChange(false)}
disabled={isExporting}
className="cyber-btn-outline h-10"
>
</Button>
<Button
onClick={handleExport}
disabled={isExporting || (selectedFormat === "pdf" && !analysisId)}
className="cyber-btn-primary h-10 font-bold uppercase"
>
{isExporting ? (
<>

View File

@ -1,135 +1,122 @@
"use client";
"use client"
import * as React from "react";
import * as DialogPrimitive from "@radix-ui/react-dialog";
import { XIcon } from "lucide-react";
import * as React from "react"
import * as DialogPrimitive from "@radix-ui/react-dialog"
import { X } from "lucide-react"
import { cn } from "@/shared/utils/utils";
import { cn } from "@/shared/utils/utils"
function Dialog({
...props
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
return <DialogPrimitive.Root data-slot="dialog" {...props} />;
}
const Dialog = DialogPrimitive.Root
function DialogTrigger({
...props
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
}
const DialogTrigger = DialogPrimitive.Trigger
function DialogPortal({
...props
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
}
const DialogPortal = DialogPrimitive.Portal
function DialogClose({
...props
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
}
const DialogClose = DialogPrimitive.Close
function DialogOverlay({
className,
...props
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
return (
<DialogPrimitive.Overlay
data-slot="dialog-overlay"
const DialogOverlay = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Overlay
ref={ref}
className={cn(
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props}
/>
))
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
>(({ className, children, ...props }, ref) => (
<DialogPortal>
<DialogOverlay />
<DialogPrimitive.Content
ref={ref}
className={cn(
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
className
)}
{...props}
/>
);
}
>
{children}
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
</DialogPrimitive.Content>
</DialogPortal>
))
DialogContent.displayName = DialogPrimitive.Content.displayName
function DialogContent({
className,
children,
...props
}: React.ComponentProps<typeof DialogPrimitive.Content>) {
return (
<DialogPortal data-slot="dialog-portal">
<DialogOverlay />
<DialogPrimitive.Content
data-slot="dialog-content"
className={cn(
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
className
)}
{...props}
>
{children}
<DialogPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4">
<XIcon />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
</DialogPrimitive.Content>
</DialogPortal>
);
}
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="dialog-header"
className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
{...props}
/>
);
}
function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="dialog-footer"
className={cn(
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
className
)}
{...props}
/>
);
}
function DialogTitle({
const DialogHeader = ({
className,
...props
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
return (
<DialogPrimitive.Title
data-slot="dialog-title"
className={cn("text-lg leading-none font-semibold", className)}
{...props}
/>
);
}
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col space-y-1.5 text-center sm:text-left",
className
)}
{...props}
/>
)
DialogHeader.displayName = "DialogHeader"
function DialogDescription({
const DialogFooter = ({
className,
...props
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
return (
<DialogPrimitive.Description
data-slot="dialog-description"
className={cn("text-muted-foreground text-sm", className)}
{...props}
/>
);
}
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className
)}
{...props}
/>
)
DialogFooter.displayName = "DialogFooter"
const DialogTitle = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Title
ref={ref}
className={cn(
"text-lg font-semibold leading-none tracking-tight",
className
)}
{...props}
/>
))
DialogTitle.displayName = DialogPrimitive.Title.displayName
const DialogDescription = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
DialogDescription.displayName = DialogPrimitive.Description.displayName
export {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogOverlay,
DialogPortal,
DialogTitle,
DialogOverlay,
DialogClose,
DialogTrigger,
};
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
}

File diff suppressed because it is too large Load Diff

View File

@ -423,7 +423,7 @@ export default function Projects() {
</Button>
</DialogTrigger>
<DialogContent className="max-w-2xl max-h-[85vh] overflow-y-auto cyber-card border-gray-700 bg-[#0c0c12] p-0">
<DialogContent className="max-w-2xl max-h-[85vh] !overflow-y-auto cyber-card border-gray-700 bg-[#0c0c12] p-0 !fixed">
{/* Terminal Header */}
<div className="flex items-center gap-2 px-4 py-3 bg-[#0a0a0f] border-b border-gray-800/50">
<div className="flex items-center gap-1.5">
@ -934,7 +934,7 @@ export default function Projects() {
{/* Edit Dialog */}
<Dialog open={showEditDialog} onOpenChange={setShowEditDialog}>
<DialogContent className="max-w-2xl cyber-card border-gray-700 bg-[#0c0c12] p-0">
<DialogContent className="max-w-2xl cyber-card border-gray-700 bg-[#0c0c12] p-0 !fixed">
{/* Terminal Header */}
<div className="flex items-center gap-2 px-4 py-3 bg-[#0a0a0f] border-b border-gray-800/50">
<div className="flex items-center gap-1.5">
@ -1185,7 +1185,7 @@ export default function Projects() {
{/* Delete Dialog */}
<AlertDialog open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
<AlertDialogContent className="cyber-card border-gray-700 bg-[#0c0c12] p-0">
<AlertDialogContent className="cyber-card border-gray-700 bg-[#0c0c12] p-0 !fixed">
{/* Terminal Header */}
<div className="flex items-center gap-2 px-4 py-3 bg-rose-500/10 border-b border-rose-500/30">
<div className="flex items-center gap-1.5">

View File

@ -401,7 +401,7 @@ export default function PromptManager() {
{/* Test Dialog */}
<Dialog open={showTestDialog} onOpenChange={setShowTestDialog}>
<DialogContent className="!max-w-6xl w-[90vw] max-h-[90vh] overflow-y-auto cyber-card p-0 bg-[#0c0c12]">
<DialogContent className="!max-w-6xl w-[90vw] max-h-[90vh] !overflow-y-auto cyber-card p-0 bg-[#0c0c12] !fixed">
<DialogHeader className="cyber-card-header">
<Sparkles className="w-5 h-5 text-violet-400" />
<DialogTitle className="text-lg font-bold uppercase tracking-wider text-white">

View File

@ -262,7 +262,7 @@ export default function RecycleBin() {
{/* Restore Dialog */}
<AlertDialog open={showRestoreDialog} onOpenChange={setShowRestoreDialog}>
<AlertDialogContent className="cyber-card p-0 bg-[#0c0c12] max-w-md">
<AlertDialogContent className="cyber-card p-0 bg-[#0c0c12] max-w-md !fixed">
<AlertDialogHeader className="cyber-card-header">
<RotateCcw className="w-5 h-5 text-emerald-400" />
<AlertDialogTitle className="text-lg font-bold uppercase tracking-wider text-white">
@ -288,7 +288,7 @@ export default function RecycleBin() {
{/* Permanent Delete Dialog */}
<AlertDialog open={showPermanentDeleteDialog} onOpenChange={setShowPermanentDeleteDialog}>
<AlertDialogContent className="cyber-card p-0 bg-[#0c0c12] max-w-md">
<AlertDialogContent className="cyber-card p-0 bg-[#0c0c12] max-w-md !fixed">
<AlertDialogHeader className="p-4 border-b border-rose-500/30 bg-rose-500/10 flex flex-row items-center gap-2">
<AlertTriangle className="w-5 h-5 text-rose-400" />
<AlertDialogTitle className="text-lg font-bold uppercase tracking-wider text-rose-400">

102
tools.txt Normal file
View File

@ -0,0 +1,102 @@
代码阅读IDE 集成开发环境IDE、Integrated Development Environment主要用于提供应用程序开发的环境、通常包括编辑器、编译器、调试器等。Chocolat C++、PHP、Ruby、Haskell https://chocolatapp.com/ Mac OS X Mac系统上一款强大的文本编辑器
Eclipse-aptana PHP、Javascript、AJAX、Adobe AIR、Apple iPhone、Ruby on Rails http://www.aptana.com/ Windows、Mac OS X 一个非常强大、开源、JavaScript-focused的AJAX开发IDE
netbeans PHP、C、C++、JavaScript、Ruby、Groovy、Grails https://netbeans.org/index_zh_CN.html Windows、Mac OS X 、 Linux 开放源代码的Java IDE
Coda HTML、PHP、JavaScript、CSS https://www.panic.com/coda/ Mac OS X 界面漂亮、操作简单的网页开发工具
Editplus HTML、、PHP、Java、 C、C++、CSS、ASP、Perl、JavaScript、 VBScript、Python、 Ruby on Rails https://www.editplus.com/ Windows 小巧但是功能强大的可处理文本、HTML和程序语言的Windows编辑器
Anjuta C、C++ http://anjuta.org/ Linux 一个建立在GNU/Linux下为C、C++提供编译的集成开发环境
kDevelop C、 C++、 Python、 QML、JavaScript and PHP https://www.kdevelop.org/ Windows、Mac OS X 、 Linux 一个自由、开放源代码 的 IDE集成开发环境
Ultimate C、C++ https://www.ultimatepp.org/ Windows、 Linux 一个C ++跨平台快速应用程序开发框架
C-Free C、C++ http://www.programarts.com/cfree_en/download.htm Windows 一款C/C++集成开发环境IDE
visual-mingw C、C++ http://visual-mingw.sourceforge.net/ Windows 一个可自由使用和自由发布的Windows特定头文件和使用GNU工具集导入库的集合
Eclipse CDT C、C++ http://www.eclipse.org/cdt/ Windows、Mac OS X Eclipse的CDT搭建标准的C/C++开发环境
espresso HTML、XML、 CSS、JavaScript https://espresso.en.softonic.com/mac Windows、Mac OS X 强大的HTML、XML、CSS和JavaScript的Web开发工具
visual-web-developer-express C#、Visual Basic、F#、C++、HTML、JavaScript、TypeScript、Python 等 https://www.visualstudio.com/zh-hans/vs/visual-studio-express/?rr=http%3A%2F%2Fwww.csdn.net%2Farticle%2F2012-02-15%2F311835 Windows、Mac OS X 一款非常好用且功能强大的web应用程序开发工具
IntelliJ IDEA Java http://www.jetbrains.com/webstorm/ Windows、Mac OS X 、 Linux 业界被公认为最好的java开发工具之一
Codelite C、C++、PHP 、Node.js https://codelite.org/ Windows、 Linux 一个功能强大的开源、C/C++编程语言的跨平台ID
Zend Studio PHP http://www.zend.com/en/products/studio Windows、Mac OS X 、 Linux Zend Technologies公司开发的PHP语言集成开发环境(IDE)
GNU Emacs All http://www.gnu.org/software/emacs/download.html Windows、Mac OS X 著名的集成开发环境和文本编辑器
E-TextEditor All https://e-texteditor.en.softonic.com/download Windows 一款新概念的窗口本文编辑软件
Notepad++ All https://notepad-plus-plus.org/ Windows Windows操作系统下的一套文本编辑器
Bbedit All http://www.barebones.com/products/bbedit/ Mac OS X 一款适用于Mac操作系统的软件
TextMate All http://macromates.com/ Mac OS X Mac下的著名的文本编辑器软件
textpad All https://www.textpad.com/ Windows 一个强大的替代 Windows 记事本 Notepad 的文本编辑器
SUBLIME TEXT All http://www.sublimetext.com/ Windows、Mac OS X 、 Linux 一个代码编辑器、也是HTML和散文先进的文本编辑器
skEdit All https://skedit.en.softonic.com/mac Mac OS X Mac HTML和文本编辑器
ATOM All https://atom.io/ Windows、Mac OS X 、 Linux github专门为程序员推出的一个跨平台文本编辑器
GEANY C、CPP、Java、Python、PHP、 HTML、 DocBook、 Perl、 LateX 和 Bash脚本 http://www.geany.org/ Windows、Mac OS X 、 Linux 一个小巧的使用GTK+2开发的跨平台的开源集成开发环境
JEDIT All http://www.jedit.org/ Windows、Mac OS X 、 Linux 一个用Java语言开发的文本编辑器
VIM All http://www.vim.org/ Windows、Mac OS X 、 Linux 一个类似于Vi的著名的功能强大、高度可定制的文本编辑器
PSPAD All http://www.pspad.com/en/ Windows 功能非常强大的代码浏览器
komodo-ide Python、Perl、PHP 、Ruby https://www.activestate.com/komodo-ide Windows、Mac OS X 、 Linux 一个独特的特性是常规表达式调试器
商业代码审计工具 在源代码的静态安全审计中、使用自动化工具代替人工漏洞挖掘、可以显著提高审计工作的效率。学会利用自动化代码审计工具、是每一个代码审计人员必备的能力。Fortify SCA Java、JSP、ASP.NET、C#、VB.NET、C、C++、COBOL、ColdFusion https://www.fortify.com Windows、Mac OS X 、 Linux 是一个静态的、白盒的软件源代码安全测试工具
Checkmarx CxSuite JAVA、ASP.NETC#、VB.NET、JavaScript、Jscript、C、C++、APEX等语言 http://www.dumasoftware.com/corporate01.asp Windows、Mac OS X 、 Linux 一个独特的源代码分析解决方案
360代码卫士 C、C++、C#、Objective-C、Java、JSP、JavaScript、PHP、Python、Cobol等 http://b.360.cn/codesafe/intro.html Windows、Mac OS X 、 Linux 360企业安全集团基于多年源代码安全实践经验开发的新一代源代码安全检测系统
RIPS PHP https://sourceforge.net/projects/rips-scanner/ Windows、Mac OS X 、 Linux PHP代码审计系统
VCGVisualCodeGrepper C、C++、C#、VB、PHP、Java、PL、SQL http://downloads.informer.com/visualcodegrepper/ Windows、Mac OS X 、 Linux 免费代码安全审计工具
blackduckprotex、Codecenter、和Export All https://www.blackducksoftware.com/ Windows、Mac OS X 、 Linux 是一款对源代码进行扫描、审计和代码管理的软件工具。
代码扫描工具 静态源代码检查工具,能对源代码进行全面的分析 Coverity Prevent C、C++、C#、JAVA http://www.coverity.com/index.html Windows、Mac OS X 、 Linux 开发测试领域的领导者
Rational Purify C、C++、Java http://www-01.ibm.com/software/awdtools/purify/ Windows 是一个面向VC, VB或者Java开发的测试Visual C/C++ 和Java 代码中与内存有关的错误,确保整个应用程序的质量和可靠性
pc-lint C、C++ http://www.gimpel.com/html/pcl.htm Windows GIMPEL SOFTWARE公司开发的C/C++软件代码静态分析工具
Cppcheck C、C++ http://cppcheck.sourceforge.net/ Windows、Mac OS X 一种C/C++代码缺陷静态检查工具
Klocwork Insight C、C++ 、Java http://www.klocwork.com/products/insight.asp Windows、 Linux 使用高度的解析手法Truepath™让到现在为止的调试和测试方法很难检测出来的错误在早期可以检出使软件的信赖性提高并提高测试的效率
PolySpace Client/Server C、C++ http://www.mathworks.cn/ Windows、Mac OS X 可以识别 C 和 C++ 代码中的运行时错误、并发问题、安全漏洞和其他缺陷
cqual C、C++ http://www.cs.umd.edu/~jfoster/cqual/ Windows、Mac OS X 、 Linux 一种基于类型的分析工具它为指定和检查C程序的属性提供了一种轻量级的实用机制
ITS4 C\C++ http://www.cigital.com/its4/ Windows 一个静态检测源代码的工具,它是基于词法分析的
flawfinder C、C++ http://www.dwheeler.com/flawfinder/ Windows、Mac OS X 、 Linux 应用在代码是否有漏洞,是否存在被攻击的可能。
Splint C http://www.splint.org/ Windows 应用在分析代码是否符合编程规范
MOPS C http://www.cs.berkeley.edu/~daw/mops/ Unix 是在C程序中查找安全漏洞并验证是否符合防御性编程规则的工具
BLAST C http://mtc.epfl.ch/software-tools/blast/ Windows、 Linux C程序的软件模型检查器
Frama-C C http://frama-c.cea.fr/ Windows、Mac OS X 、 Linux 一个用来分析 C 代码的工具,它收集了很多静态统计技术
FindBugs Java http://findbugs.sourceforge.net/ Windows、Mac OS X 、 Linux 一个静态分析工具,它检查类或者 JAR 文件
Checkstyle Java http://checkstyle.sourceforge.net/ Windows、Mac OS X 、 Linux SourceForge下的一个项目提供了一个帮助JAVA开发人员遵守某些编码规范的工具
Eclipse-Jtest Java http://www.parasoft.com/jsp/cn/support.jsp Windows、Mac OS X 、 Linux 一款优秀的 Java 代码优化和测试工具
PMD Java http://pmd.sourceforge.net/ Windows、Mac OS X 、 Linux 一种开源分析Java代码错误的工具
QJ-Pro Java http://qjpro.sourceforge.net/ Windows、Mac OS X 、 Linux 一个全面的软件检测工具
Jint Java http://artho.com/jlint/ Windows 通过进行数据流分析和构建锁图来检查您的Java代码并发现错误
Hammurapi Java http://www.hammurapi.biz/hammurapi-biz/ef/xmenu/hammurapi-group/index.html Windows、Mac OS X 、 Linux 一个开源的代码审查/评审(review)工具
Dependency Finder Java http://depfind.sourceforge.net/ Windows、Mac OS X 、 Linux 一个java依赖分析工具
Classycle Java http://classycle.sourceforge.net/ Windows 可以分析静态类和Java应用程序或库的包依赖性生成XML报表
JDepend Java http://www.clarkware.com/software/JDepend.html Windows、Mac OS X 、 Linux 一个开放源代码的可以用来评价Java程序质量的优秀工具
LAPSE Java http://www.owasp.org/index.php/Category:OWASP_LAPSE_Project Windows、Mac OS X 、 Linux 向开发人员和审计人员提供一种用于检测Java EE应用程序中的漏洞的工具
JSLint JavaScript http://www.jslint.com/ Windows、Mac OS X 、 Linux 基于Web的验证JavaScript错误代码的工具
J3Unit JavaScript http://j3unit.sourceforge.net/ Windows、Mac OS X 、 Linux 一个面向对象的JavaScript单元测试框架
JSHint JavaScript http://jshint.com/ Windows、Mac OS X 、 Linux JSLint的一个更加灵活可配置的一个版本
JSCS JavaScript http://jscs.info/ Windows、Mac OS X 、 Linux 一个代码风格检查器
ESLint JavaScript http://eslint.org/ Windows、Mac OS X 、 Linux 易于拓展的,具有大量的自定义规则,并且很容易通过插件的形式来安装
Regular Expression Tool JavaScript http://erik.eae.net/playground/regexp/regexp.html Windows、Mac OS X 、 Linux 一款在线工具,用来测试您的正则表达式代码是否正确
JSLitmus JavaScript http://broofa.com/Tools/JSLitmus/ Windows、Mac OS X 、 Linux 是款轻量级的工具用来测试JavaScript执行性能情况采用直观的API
JavaScript Regular Expression Tester JavaScript http://broofa.com/Tools/JSLitmus/ Windows、Mac OS X 、 Linux 是在浏览器中使用JavaScript来测试JavaScript正则表达式的
Exakat PHP https://www.exakat.io/ Mac OS X 提供从PHP 5.2到PHP 7.2-dev的实时PHP静态分析器
PHPSecurityScanner PHP https://sourceforge.net/projects/securityscanner/ Linux 扫描PHP代码中是否有存在漏洞
PHPMD PHP https://phpmd.org/ Windows、Mac OS X 、 Linux 探测PHP源代码中一些潜在的问题
PHPStan PHP https://packagist.org/packages/phpstan/phpstan Windows、Mac OS X 、 Linux 一款 PHP 静态分析工具,它专注于在代码中发现错误而不实际运行它
PhpSecInfo PHP http://phpsec.org/projects/phpsecinfo/ Windows、Mac OS X 、 Linux 相当于phpinfo函数它报告有关PHP环境的安全信息
StyleCop C# http://stylecop.codeplex.com/releases/view/79972 Windows 微软的一个开源的静态代码分析工具,检查c#代码一致性和编码风格
FxCop C# https://msdn.microsoft.com/library/bb429476 Windows 微软的代码分析工具,以微软内部使用的.NET编码规范为参照找出源代码中潜在的设计和编写缺陷
PyChecker Python http://pychecker.sourceforge.net/ Linux Python代码的静态分析工具
Pylint Python https://www.pylint.org/ Windows、Mac OS X 、 Linux 一个高阶的Python代码分析工具
Bandit Python https://wiki.openstack.org/wiki/Security/Projects/Bandit Windows、Mac OS X 、 Linux 一款Python源码分析框架可用于Python代码的安全性分析
反编译工具 高级语言源程序经过编译变成可执行文件反编译就是逆过程。jd-gui Java http://jd.benow.ca/ Windows、Mac OS X 、 Linux 一个用 C++ 开发的 Java 反编译工具
Eclips-Jadclipse Java http://sourceforge.net/projects/jadclipse/ Windows、Mac OS X 、 Linux Jad的Eclipse插件是一款非常实用而且方便地Java反编译插件
jad Java http://varaneckas.com/jad/ Windows、Mac OS X 、 Linux 一款使用非常广泛地Java反编译工具
jdec Java http://jdec.sourceforge.net/ Windows、Mac OS X 、 Linux 一个Java反编译器
uuDeJava Java http://www.uuware.com/uudejava_cn.htm Windows、Mac OS X 、 Linux Java Class文件的反编译工具
Minjava Java https://code.google.com/p/minjava/ Windows、Mac OS X 、 Linux 一个 Java 反向工程软件
Java Decompiler Java http://jd.benow.ca/ Windows、Mac OS X 、 Linux 一个Java反编译器
Reflector C# http://www.red-gate.com/products/dotnet-development/reflector/ Windows、Mac OS X 可将·NET程序集中的中间语言反编译成C#或者Visual Basic代码
ILSpy C# http://ilspy.NET/ Windows、Mac OS X 一个开源的.net反编译软件使用十分方便
dnSpy C# https://github.com/0xd4d/dnSpy/blame/master/dnSpy.sln Windows、Mac OS X .net反编译工具
JetBrains dotPeek C# http://www.jetbrains.com/decompiler/ Windows .NET反编译工具
Telerik JustDecompile C# http://www.telerik.com/products/decompiler.aspx Windows 一款非常实用的.net反编译工具
Retargetable Decompiler C、pyhton https://retdec.com/ Windows 一个可重定位的反编译器
Easy Python Decompiler pyhton https://sourceforge.net/projects/easypythondecompiler/files/?source=navbar Windows python字节码反编译器反编译pycpyo文件
uncompyle2 pyhton2.7 https://github.com/Mysterie/uncompyle2 Windows Python 2.7的反编译工具
exescope C++ http://www.softpedia.com/get/Programming/File-Editors/eXeScope.shtml Windows 能在没有资源文件的情况下分析,显示不同的信息,重写可执行文件的资源
C、C++通过编译把文本形式源代码翻译为机器语言形式的目标文件的再通过链接把目标文件、操作系统的启动代码和用到的库文件进行组织形成最终生成可执行代码。OllyDBG C、C++ http://www.ollydbg.de/ Windows 一个新的动态追踪工具
c32asm C、C++ http://www.c32asm.com/ Windows 具有反汇编模式和十六进制编辑模式能跟踪exe文件的断点也可直接修改软件内部代码。
W32Dasm C、C++ http://www.softpedia.com/get/Programming/Debuggers-Decompilers-Dissasemblers/WDASM.shtml Windows 一个静态反汇编工具,也是破解人常用的工具之一
Hex Rays Ida C、C++ https://www.hex-rays.com/ Windows、Mac OS X 、 Linux 一款调试工具的模拟器,可以更好的反汇编和更有深层分析