AppThreat/atom

GitHub: AppThreat/atom

atom 是一种应用程序中间表示工具,将多语言源码转化为优化的图网络结构,支持数据流分析、程序切片和可达性查询,服务于安全分析、供应链追踪和代码摘要等场景。

Stars: 95 | Forks: 9

# atom (⚛) atom 是一种用于应用程序的新型中间表示,也是一个由 [chen](https://github.com/AppThreat/chen) 库支持的独立工具。这种中间表示(一个包含节点和链接的网络)针对应用程序分析和机器学习中常用的操作(包括[切片](./specification/docs/slices.md)和向量化)进行了优化。 我们的愿景是让 atom 能够适用于多种用例,例如: - **供应链分析:** 生成外部库使用的证据,包括从数据源到数据汇的数据流。atom 被 [OWASP cdxgen](https://github.com/CycloneDX/cdxgen) 使用,以提高生成的 CycloneDX 文档的精确性和全面性。 - **漏洞分析:** 通过受影响的符号、调用路径和数据流的证据来描述漏洞。实现大规模的变体分析和[可达性分析](https://github.com/AppThreat/atom/blob/main/specification/docs/slices.md#reachables-slice)。 - **漏洞利用预测:** 利用漏洞、库和应用程序的精确表示来预测漏洞利用。 - **威胁模型和攻击向量生成:** 大规模地为应用程序生成精确的威胁模型和攻击向量。 - **应用程序上下文检测:** 生成可用于摘要生成和风险画像创建的上下文(例如,服务、端点和数据属性)。 - **应用程序的思维导图:** 作为一种开发人员工具,自动对大型和复杂的应用程序进行摘要。 以及其他更多用例。 [![SBOM](https://img.shields.io/badge/SBOM-with_%E2%9D%A4%EF%B8%8F_by_cdxgen-FF753D)](https://github.com/cdxgen/cdxgen) ![npm](https://img.shields.io/npm/dw/@appthreat/atom) ![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/AppThreat/atom/total?color=FF753D) ## 支持的语言 - C/C++ - H (仅限 C/C++ Header 和预处理过的 .i 文件) - Java (需要编译) - Jar - Android APK 和拆分包 (.apkm, .apks, .xapk)。需要 Android SDK。设置环境变量 `ANDROID_HOME` 或使用容器镜像。 - JavaScript - Flow - TypeScript - Python (支持 3.x 到 3.13) - PHP (需要 PHP >= 7.4。支持 PHP 7.0 到 8.4,对 PHP 5.x 的支持有限) - Ruby (需要 Ruby 4.0.x。支持 Ruby 1.8 - 4.0.x 语法) - Scala (WIP) ## 安装说明 atom 包含一个带有 Node.js 包装模块的 scala 核心。目前它作为 npm 包分发。 ``` npm install -g @appthreat/atom @appthreat/atom-parsetools atom --help ``` 安装 cdxgen npm 包以生成软件物料清单 (SBOM),这是进行 reachables 切片所必需的。 ``` npm install -g @cyclonedx/cdxgen --omit=optional ``` ## 容器使用 ``` docker run --rm -v /tmp:/tmp -v $HOME:$HOME -v $(pwd):/app:rw -t ghcr.io/appthreat/atom atom --help # podman run --rm -v /tmp:/tmp -v $HOME:$HOME -v $(pwd):/app:rw -t ghcr.io/appthreat/atom atom --help ``` Java 项目的示例。 ``` docker run --rm -v /tmp:/tmp -v $HOME:$HOME -v $(pwd):/app:rw -t ghcr.io/appthreat/atom atom -l java -o /app/app.atom /app # podman run --rm -v /tmp:/tmp -v $HOME:$HOME -v $(pwd):/app:rw -t ghcr.io/appthreat/atom atom -l java -o /app/app.atom /app ``` ## atom native-image (仅供高级用户使用) ``` curl -LO https://github.com/AppThreat/atom/releases/latest/download/atom-amd64 chmod +x atom-amd64 ./atom-amd64 --help ``` 在 Windows 上 ``` curl -LO https://github.com/AppThreat/atom/releases/latest/download/atom.exe .\atom.exe --help ``` 注意:诸如 astgen、rbastgen、phpastgen 等命令并未捆绑在此 native image 中。请安装 npm 包 `@appthreat/atom-parsetools` 来获取这些命令。 ``` npm install -g @appthreat/atom-parsetools which astgen which phpastgen ``` ## CLI 用法 ``` Usage: atom [parsedeps|data-flow|usages|reachables|export|algorithms] [options] [input] input source file or directory -o, --output output filename. Default app.⚛ or app.atom in windows -s, --slice-outfile export intra-procedural slices as json -l, --language source language --frontend-args Advanced frontend configuration (key=value). E.g. --frontend-args defines=DEBUG,cpp-standard=c++17 --with-data-deps generate the atom with data-dependencies - defaults to `false` --remove-atom do not persist the atom file - defaults to `false` --reuse-atom reuse existing atom file - defaults to `false` -x, --export-atom export the atom file with data-dependencies to graphml - defaults to `false` --export-dir export directory. Default: atom-exports --file-filter the name of the source file to generate slices from. Uses regex. --method-name-filter filters in slices that go through specific methods by names. Uses regex. --method-parameter-filter filters in slices that go through methods with specific types on the method parameters. Uses regex. --method-annotation-filter filters in slices that go through methods with specific annotations on the methods. Uses regex. --max-num-def maximum number of definitions in per-method data flow calculation - defaults to 2000 --legacy-dataflow use the classic data-flow engine and disable mini-graph fragment caching and method flow summaries. By default atom uses the faster, lower-allocation Flux engine with fragment caching and summary-guided pruning enabled. --validation-config path to a JSON file declaring validators/sanitisers (chennai.json schema). Reachable flows passing through a declared sanitiser are dropped for its categories. Command: parsedeps Extract dependencies from the build file and imports Command: data-flow [options] Extract backward data-flow slices --slice-depth the max depth to traverse the DDG for the data-flow slice - defaults to 7. --sink-filter filters on the sink's `code` property. Uses regex. Command: usages [options] Extract local variable and parameter usages --min-num-calls the minimum number of calls required for a usage slice - defaults to 1. --include-source includes method source code in the slices - defaults to false. --extract-endpoints extract http endpoints and convert to openapi format using atom-tools - defaults to false. Command: reachables [options] Extract reachable data-flow slices based on automated framework tags --source-tag source tag - defaults to framework-input. Comma-separated values allowed. --sink-tag sink tag - defaults to framework-output. Comma-separated values allowed. --include-crypto includes crypto library flows - defaults to false. Command: export [options] Export the atom to a graph format (dot, graphml, gexf, graphson, neo4jcsv, gnn) --format export format: dot, graphml, gexf, graphson, neo4jcsv or gnn --scope export scope: whole or methods. Default: whole --out output directory. Default: atom-exports Command: algorithms [options] Run a graph algorithm over the atom and write the result as JSON --type algorithm: scc, toposort, dominators, paths or centrality --source source method full-name pattern for the paths algorithm. Uses regex. --target target method full-name pattern for the paths algorithm. Uses regex. --max-depth maximum path depth for the paths algorithm --config path to a JSON config file for the export and algorithms commands --help display this help message ``` ## export 和 algorithms 命令 `export` 和 `algorithms` 命令作用于 `.atom` 文件。如果使用 `-o` 指定的文件已经存在,则会被重用;否则 atom 会首先从输入构建它,因此无需记住单独的构建步骤。 `export` 会以多种格式之一写入图。使用 `--scope whole` 导出整个 atom,或者使用 `--scope methods` 为每个方法写入一个文件(除了 neo4jcsv 之外,每种格式都支持按方法作用域)。`gnn` 格式将并行的 id、label 和 edge 数组以 JSON 格式写入,适用于机器学习流水线。 ``` atom export -l python --format graphml --scope whole -o app.atom --out exports app.py atom export -l python --format gnn --scope methods -o app.atom --out gnn-out app.py ``` `algorithms` 运行图算法并将结果以 JSON 格式写入切片输出文件: - `centrality` 根据 PageRank 和入度对调用图中的方法进行排名。 - `scc` 报告强连通分量,这可以标记调用图中的递归。 - `toposort` 返回方法的被调用者先于调用者的顺序。递归方法会被分阶段分组(每个都标记为递归),这样即使调用图包含循环,排序也能正常工作。 - `dominators` 写入每个方法的控制流支配树。 - `paths` 查找通过正则表达式选择的源方法和目标方法之间的路径。 ``` atom algorithms -l python --type centrality -o app.atom -s centrality.json app.py atom algorithms -l python --type paths --source '.*main$' --target '.*helper$' -o app.atom -s paths.json app.py ``` 可以通过 `--config `(一个 JSON 文件)提供冗长或可重复的参数。命令行标志会覆盖文件中的值。例如,一个 algorithms 配置文件: ``` { "type": "paths", "source": ".*main$", "target": ".*helper$", "maxDepth": 20, "out": "paths.json" } ``` ## 数据流引擎 atom 默认使用 **Flux** 引擎 (*Flow-Lattice Update eXecutor*) 计算数据依赖关系——这是一个低分配的到达定值求解器,它能生成与经典引擎相同的 `REACHING_DEF` 边,同时在处理大型(例如打包/转译过的 JavaScript)方法时占用更少的内存和 GC 时间。默认情况下也会启用按文件的迷你图(片段)AST 缓存,因此未更改的文件会从 `.chen` 缓存中恢复,而不是重新解析。 传递 `--legacy-dataflow` 以回退到经典引擎并禁用片段缓存(这对于 A/B 比较或故障排除很有用)。还可以通过 `-Dchen.cache.disabled=true` 系统属性独立控制缓存。 ### 存储压缩 (`-Dodb.storage.compression`) 在大型代码库中,图会溢出堆内存,未使用的节点会被转储到磁盘;转储/保存路径在单线程上运行,因此它使用的压缩器会主导生成和切片时间。通过系统属性选择它(无需重新构建): ``` atom ... -Dodb.storage.compression=none|lzf|deflate ``` - `deflate` (**默认**) — 最慢但生成的 `.atom` 最小;之所以设为默认,是因为在大型代码库中 atom 文件的大小最为重要。 - `lzf` — 快速压缩;最适合溢出堆内存的大型图,在这些图中 DEFLATE 占用了大量的生成/切片时间。 - `none` — 无压缩;转储最快,生成的 `.atom` 最大。 压缩器是按块记录的,因此使用任何模式写入的 atom 在任何其他模式下仍然可读(一个 `lzf` atom 在 `deflate` 默认模式下也能正常加载)。给 JVM 更多的堆内存 (`-Xmx`) 也会减少转储——最省事的办法就是根本不发生溢出。 ## 方法流摘要 `reachables` 命令在运行反向查询之前,会为每个方法构建一个与上下文无关的流摘要。摘要记录了方法的哪些参数会到达其返回值或输出参数。reachables 引擎使用这些摘要来跳过那些经证明不会携带污点的跨调用工作,例如探索被调用者从未写入的参数,或者深入其返回值不可能携带污点的被调用者。这种修剪只会移除空的工作,因此报告的流与不使用摘要运行的结果完全相同。 方法流摘要属于默认的 Flux 包的一部分——没有单独的标志。只要使用了 Flux 引擎(默认情况),它们就会被启用,并且只有在指定 `--legacy-dataflow` 时才会被关闭,这也会同时恢复到经典的数据流引擎。 摘要通过两种方式持久化:作为每个 `METHOD` 节点上的 CPG 原生 `flow-summary` 标签(这样它们就会随 atom 序列化,并在重用/缓存 atom 时被免费重用),以及作为位于 atom 旁边的 `flowsummary-.json` 伴随文件,用于不带标签的运行。当任何方法体发生改变时,指纹也会随之改变。与其他缓存一样,可以通过 `-Dchen.cache.disabled=true` 关闭摘要缓存。 ``` atom reachables -o app.atom -s reachables.json -l java . ``` ## 验证器和净化器 经过真正的验证或净化例程的可达流通常不是真正的发现。你可以在 JSON 文件中声明此类例程,并使用 `--validation-config` 传递。atom 会将每一个对已声明方法的调用标记为净化器,并丢弃经过它们的可达流,其作用范围仅限于该净化器覆盖的数据汇类别。 该文件使用与 `chennai.json` 相同的 schema。`sanitizers` 和 `validators` 的处理方式完全相同;`categories` 是可选的,如果省略,净化器将覆盖每一个流: ``` { "sanitizers": [ { "name": "owasp-encode", "methods": ["org\\.owasp\\.encoder\\.Encode\\..*"], "categories": ["http"] }, { "name": "sql-escape", "methods": [".*escapeSql.*"], "categories": ["sql"] } ], "validators": [{ "name": "bean-validation", "methods": [".*\\.validate"] }] } ``` `methods` 条目会与每个调用的方法全名进行匹配(如果包含正则表达式字符,则被视为正则表达式;否则视为精确匹配)。`categories` 会与流的数据汇上的标签进行匹配,因此为 `http` 声明的 HTML 编码器不会抑制 SQL 注入流。 ``` atom reachables --validation-config validators.json -o app.atom -s reachables.json -l java . ``` 这些声明也可以嵌入到项目的 `chennai.json` 中,而不是在命令行上传递。对于编程式使用,数据流引擎在流迭代器上暴露了 `passesThrough` / `doesNotPassThrough` 方法,接受一个简单的节点谓词。 ## 调用示例 ### 生成 atom ``` # 编译 java 项目 atom -o app.atom -l java . ``` ``` atom -o app.atom -l jar ``` ``` export ANDROID_HOME= atom -o app.atom -l apk ``` 也支持拆分包。`.apkm`、`.apks` 或 `.xapk` 文件会自动解压,并分析包含 dalvik 字节码的 apk。 ``` export ANDROID_HOME= atom -o app.atom -l apk ``` 在对 Android apk 进行切片时,atom 会在代码属性图上运行 chen 的 Android 标记阶段。这些阶段会为可达切片中的流附加语义标签,包括个人身份信息(如 `pii-email` 和 `pii-device-id`)、受监管的数据(如 `pci-dss`、`gdpr` 和 `phi-medical`)、机密信息、标记为 `tracker` 的第三方追踪器,以及标记为 `service-egress`、`service-ingress` 和 `on-device-ai` 的网络方向。atom-tools 会使用这些标签来归属可达服务,并丰富由 blint 生成的 CycloneDX SBOM。 ### 为 Java 项目创建 reachables 切片。 ``` cd cdxgen -t java --deep -o bom.json . atom reachables -o app.atom -s reachables.json -l java . ``` 传递参数 `--reuse-atom` 可基于现有的 atom 文件进行切片。 ``` atom reachables --reuse-atom -o app.atom -s reachables.json -l java . ``` 基于容器调用的示例。 ``` docker run --rm -v /tmp:/tmp -v $HOME:$HOME -v $(pwd):/app:rw -t ghcr.io/appthreat/atom atom reachables -l java -o /app/app.atom -s /app/reachables.slices.json /app # podman run --rm -v /tmp:/tmp -v $HOME:$HOME -v $(pwd):/app:rw -t ghcr.io/appthreat/atom atom reachables -l java -o /app/app.atom -s /app/reachables.slices.json /app ``` ### 为 Java 项目创建 usages 切片。 ``` atom usages -o app.atom --slice-outfile usages.json -l java . ``` 使用基于容器调用的 Ruby 4 项目示例。 ``` docker run --rm -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/appthreat/atom atom usages -l ruby -o /app/app.atom -s /app/usages.slices.json /app # podman run --rm -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/appthreat/atom atom usages -l ruby -o /app/app.atom -s /app/usages.slices.json /app ``` 如果在 arm64 架构上遇到 Java 或 Ruby 构建问题,请传递参数 `--platform=linux/amd64`。 ``` docker run --rm --platform=linux/amd64 -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/appthreat/atom atom usages -l ruby -o /app/app.atom -s /app/usages.slices.json /app # podman run --rm --platform=linux/amd64 -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/appthreat/atom atom usages -l ruby -o /app/app.atom -s /app/usages.slices.json /app ``` 对于 Ruby 4,提供了一个基于 alpine 的版本。 ``` docker run --rm -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/appthreat/atom-alpine-ruby atom usages --extract-endpoints -l ruby -o /app/app.atom -s /app/usages.slices.json /app # podman run --rm -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/appthreat/atom-alpine-ruby atom usages --extract-endpoints -l ruby -o /app/app.atom -s /app/usages.slices.json /app ``` Alpine 也提供了 Ruby 3 的变体。 ``` docker run --rm -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/appthreat/atom-alpine-ruby3 atom usages --extract-endpoints -l ruby -o /app/app.atom -s /app/usages.slices.json /app # podman run --rm -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/appthreat/atom-alpine-ruby3 atom usages --extract-endpoints -l ruby -o /app/app.atom -s /app/usages.slices.json /app ``` ### 为 Java 项目创建 data-flow 切片。 了解更多关于[切片](./specification/docs/slices.md)的信息,或查看一些[示例](https://github.com/AppThreat/atom-samples) ### 使用 atom-tools 提取 openapi 格式的 HTTP 端点 atom 可以自动调用 [atom-tools](https://github.com/AppThreat/atom-tools) 的 `convert` 命令,从 usages 切片中提取 http 端点。传递参数 `--extract-endpoints` 来启用此功能。 ``` pip install atom-tools atom usages --extract-endpoints -o app.atom --slice-outfile usages.json -l java . ``` 会创建一个包含端点信息的 `openapi.json` 文件。使用环境变量 `ATOM_TOOLS_OPENAPI_FILENAME` 自定义文件名。 ``` ATOM_TOOLS_OPENAPI_FILENAME=openapi.json atom usages --extract-endpoints -o app.atom --slice-outfile usages.json -l ruby . ``` 基于容器的调用: ``` docker run --rm -v /tmp:/tmp -e ATOM_TOOLS_OPENAPI_FILENAME=openapi.json -v $(pwd):/app:rw -t ghcr.io/appthreat/atom atom usages --extract-endpoints -l ruby -o /app/app.atom -s /app/usages.slices.json /app # podman run --rm -v /tmp:/tmp -e ATOM_TOOLS_OPENAPI_FILENAME=openapi.json -v $(pwd):/app:rw -t ghcr.io/appthreat/atom atom usages --extract-endpoints -l ruby -o /app/app.atom -s /app/usages.slices.json /app ``` ### 将 atom 导出为 graphml 或 dot 格式 可以将 atom 中的每个方法及其数据依赖关系导出为 graphml 或 dot 格式。只需传递 `--export` 即可启用此功能。 ``` atom -o app.atom -l java --export-atom --export-dir ``` 生成的 graphml 文件可以导入到 [Neo4j](https://neo4j.com/labs/apoc/4.1/import/graphml/) 或 NetworkX 中进行进一步分析。使用参数 `--export-format` 指定为 dot 格式。 ``` atom -o app.atom -l java --export-atom --export-format dot --export-dir ``` 在 dot 格式下,像 ast、cdg 和 cfg 这样的独立表示也会被导出。 要在导出的文件中计算并包含数据依赖图 (DDG) 信息,请传递 `--with-data-deps` ``` atom -o app.atom -l java --export-atom --export-dir --with-data-deps ``` ## 环境变量 | 变量 | 描述 | | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | **CHEN_IGNORE_DIRS** | 所有语言前端都要忽略的目录列表(以逗号分隔)。 | | **CHEN_IGNORE_TEST_DIRS** | 设置为 true 可为所有语言前端忽略常见的测试目录(`test`、`tests`、`mocks`)。 | | **CHEN_C_IGNORE_DIRS** | 为 C/C++ 和 Header 前端额外指定的忽略目录列表(以逗号分隔)。 | | **CHEN_CPP_IGNORE_DIRS** | 为 C++ 前端额外指定的忽略目录列表(以逗号分隔)。 | | **CHEN_JAVA_IGNORE_DIRS** | 为 Java 源码前端额外指定的忽略目录列表(以逗号分隔)。 | | **CHEN_JIMPLE_IGNORE_DIRS** | 为 Jimple/JAR/Android/APK/DEX 前端忽略的目录列表(以逗号分隔)。 | | **CHEN_SCALA_IGNORE_DIRS** | 为 Scala 前端忽略的目录列表(以逗号分隔)。 | | **CHEN_JAVASCRIPT_IGNORE_DIRS** | 为 JavaScript、TypeScript 和 Flow 前端忽略的目录列表(以逗号分隔)。 | | **CHEN_JS_IGNORE_DIRS** | JavaScript、TypeScript 和 Flow 忽略目录的别名。 | | **CHEN_TYPESCRIPT_IGNORE_DIRS** | TypeScript 和 Flow 忽略目录的别名。 | | **CHEN_PYTHON_IGNORE_DIRS** | 为 Python 忽略的目录列表(以逗号分隔)。如果未设置,atom 会使用 Python 默认的忽略目录。 | | **CHEN_PHP_IGNORE_DIRS** | 为 PHP 前端额外指定的忽略目录列表(以逗号分隔)。 | | **CHEN_RUBY_IGNORE_DIRS** | 为 Ruby 前端额外指定的忽略目录列表(以逗号分隔)。 | | **CHEN_DELOMBOK_MODE** | Java 前端的 Delombok 模式(`no-delombok`、`default`、`types-only`、`run-delombok`)。 | | **CHEN_INCLUDE_PATH** | C 前端的包含目录。用 `:` 或 `;` 分隔路径。 | | **CHEN_ASTGEN_OUT** | 现有的 astgen 输出目录。通过重用现有的 AST json 数据,提高 JavaScript、TypeScript 和 Flow 在重复调用时的性能。 | | **ATOM_TOOLS_OPENAPI_FORMAT** | atom-tools 的 OpenAPI 格式。默认:`openapi3.1.0`;备选:`openapi3.0.1`。 | | **ATOM_TOOLS_WORK_DIR** | atom-tools 的工作目录。默认为 atom 输入路径。 | | **ATOM_SCALASEM_WORK_DIR** | scalasem 的工作目录。默认为 atom 输入路径。 | | **ATOM_SCALASEM_SLICES_FILE** | 切片文件名。默认为 `semantics.slices.json`。 | | **ATOM_JVM_ARGS** | 覆盖由 atom Node.js 包装器构建的 JVM 参数,包括堆内存值。 | | **ATOM_JAVA_HOME** | atom 要使用的 Java 21 或更高版本。 | | **PHP_CMD** | 覆盖 PHP 前端使用的 PHP 命令。 | | **PHP_PARSER_BIN** | 覆盖 PHP 前端使用的 php-parse 命令。 | | **SCALA_CMD** | 覆盖 scala 命令。 | | **SCALAC_CMD** | 覆盖 scala 前端使用的 scalac 命令。 | | **ASTGEN_IGNORE_DIRS** | JavaScript astgen 预处理命令要忽略的目录列表(以逗号分隔)。 | | **ASTGEN_IGNORE_FILE_PATTERN** | JavaScript astgen 预处理命令要忽略的文件模式。 | | **ASTGEN_INCLUDE_NODE_MODULES_BUNDLES** | 同时包含来自 node_modules 目录的源代码。这会使流变得更加完整,但代价是增加内存使用量。 | | **JAVA_CMD** | 覆盖 java 命令。 | | **RUBY_CMD** | 覆盖 Ruby 命令。 | ## atom 规范 atom 使用的中间表示基于同样的开源许可 (MIT) 提供。规范支持 [protobuf](./specification/atom.proto)、[markdown](./specification/docs/spec.md) 和 [html](./specification/docs/spec.html) 格式。 当前规范版本为 1.0.0 ## 生成 atom 文件 atom 文件 (app.⚛ 或 app.atom) 是包含序列化 protobuf 数据的 zip 文件。推荐使用 atom cli 来生成这些文件。也可以使用 [proto 规范](./specification/atom.proto) 从头开始编写生成器工具。我们为感兴趣的用户提供了一个 [Python](./specification/samples/python-atomgen/README.md) 示例。我们还提供了其他语言的 proto 绑定,可以在[这里](./specification/bindings/)找到。 在 python 中生成 atom 的示例代码片段。 ``` # 创建一个具有 fullname property 的 method methodFullName = atom.CpgStructNodeProperty( name=atom.NodePropertyName.FULL_NAME, value=atom.PropertyValue("main") ) # 创建一个带有 fullname property 的 method node method = atom.CpgStructNode( key=1, type=atom.NodeType.METHOD, property=[methodFullName] ) # 创建一个包含单个 node 的 atom atom_struct = atom.CpgStruct(node=[method]) # 通过将这些数据序列化到 zip 文件中来创建一个 atom (app.atom) with ZipFile("app.atom", "w") as zip_file: zip_file.writestr("cpg.proto", bytes(atom_struct)) ``` ## 许可证 MIT ## 结合 chennai 使用 atom [chennai](https://github.com/AppThreat/chen) 是处理 atom 的推荐查询接口。 ``` chennai> importAtom("/home/almalinux/work/sandbox/apollo/app.atom") ``` ## atom 工具 查看 [atom-tools](https://github.com/AppThreat/atom-tools),获取一些涉及 atom 切片的项目灵感。 ## devenv 设置 按照官方[说明](https://devenv.sh/getting-started/)安装 devenv。 ``` devenv shell ``` 特定语言的配置: ``` # Ruby 环境 devenv --option config.profile:string ruby shell # php 环境 devenv --option config.profile:string php shell ``` ## 高级配置 对于复杂的项目,特别是用 C 或 C++ 编写的项目,你可能需要将细粒度的配置选项传递给底层的语言前端。你可以通过使用 `--frontend-args` 标志来实现。 此标志接受以逗号分隔的 `key=value` 键值对列表。 ### 用法 ``` --frontend-args key1=value1,key2=value2,key3=value3 ``` ### 支持的参数 (C/C++) 当 `--language` 设置为 `c`、`cpp` 或 `c++` 时,支持以下参数。 | Key | Type | Description | Example | | :--------------------- | :------ | :------------------------------------------------------------------------------ | :---------------------------- | | `defines` | List | 逗号分隔的预处理器定义。 | `defines=DEBUG,VERSION=2` | | `includes` | List | 额外的 Header 包含路径。 | `includes=/opt/local/include` | | `cpp-standard` | String | 要使用的 C++ 标准版本。 | `cpp-standard=c++17` | | `function-bodies` | Boolean | 是否提取函数体。 | `function-bodies=false` | | `parse-inactive-code` | Boolean | 解析处于禁用状态预处理器块内的代码(例如,`#if 0` 内部)。 | `parse-inactive-code=true` | | `with-image-locations` | Boolean | 创建镜像位置(解释名称是如何进入翻译单元的)。 | `with-image-locations=true` | | `enable-ast-cache` | Boolean | 将解析后的 AST 缓存到磁盘,以加速未更改文件的后续运行。 | `enable-ast-cache=true` | | `ast-cache-dir` | String | 存储 AST 缓存文件的目录。默认为输入目录下的 `ast_out`。 | `ast-cache-dir=/tmp/cache` | | `only-ast-cache` | Boolean | 仅生成 AST 缓存文件并退出。对于大型项目可避免 OOM。 | `only-ast-cache=true` | ### 示例 **1. 设置 C++ 标准和定义** 使用 C++17 为 C++ 项目生成 atom。 ``` java -jar atom.jar \ --language c++ \ --frontend-args cpp-standard=c++17 \ ./my-cpp-project ``` **2. 处理自定义包含路径** 如果你的项目依赖于位于源码树之外的 Header: ``` java -jar atom.jar \ --language c \ --frontend-args includes=/usr/local/include,/opt/mylib/include \ ./src ``` **3. 解析非活动代码** 包含隐藏在预处理器指令后面的代码(例如在 Linux 上运行时的 `#ifdef WINDOWS`): ``` java -jar atom.jar \ --language c \ --frontend-args parse-inactive-code=true \ ./src ``` **4. 大型项目:两阶段生成(内存优化)** 对于非常庞大的 C/C++ 代码库,一次性生成完整的图可能会消耗过多内存。你可以使用 AST 缓存将过程分为两个阶段。 _阶段 1:仅生成 AST 缓存_ 这会逐个解析文件并将其 AST 保存到磁盘(默认为 `./src/ast_out`),从而保持较低的内存使用量。 ``` java -jar atom.jar \ --language c \ --frontend-args only-ast-cache=true,ast-cache-dir=/tmp/cache \ ./src ``` _阶段 2:从缓存生成 atom_ 在启用缓存的情况下再次运行该命令。它将从磁盘加载预计算的 AST,从而显著加快图的创建速度。 ``` java -jar atom.jar \ --language c \ --frontend-args enable-ast-cache=true,ast-cache-dir=/tmp/cache \ ./src ``` ## 故障排除 ### 大型 JS/TS 项目的 atom 文件不完整 对于大型的 JavaScript 项目(尤其是 flow 项目),astgen 可能需要大量的堆内存。使用环境变量 `NODE_OPTIONS` 来增加可用内存。 ``` export NODE_OPTIONS="--expose-gc --max-old-space-size=16288" ``` 对于像 React 19 这样的大型项目,astgen 需要超过 80 GB 的堆内存!请使用环境变量 `CHEN_ASTGEN_OUT` 让 atom 和 chen 重用任何包含 astgen 生成的 json 和 typemap 文件的现有目录。 为了进一步提高准确性,可以通过设置 `ASTGEN_INCLUDE_NODE_MODULES_BUNDLES` 来包含 `node_modules` 目录中的源代码。 ``` export ASTGEN_INCLUDE_NODE_MODULES_BUNDLES=true export ASTGEN_IGNORE_DIRS="" ```
标签:DNS重绑定攻击, MITM代理, 暗色界面, 请求拦截, 通知系统