都2024了,你该不会还没用过这个数据库吧?
2024-5-6 00:22:52 Author: mp.weixin.qq.com(查看原文) 阅读量:0 收藏

本文旨在保证"抽丝剥茧代码属性图CPG"系列文章的完整性,笔者认为图数据库Neo4j也是该系列中不可或缺的一部分,本文起到一个抛砖引玉的作用,后续大概率会对CPG中的Neo4j做详细的讲解,大家敬请期待~

为什么要写CPG中的Neo4j呢,在花大把时间肝完CPG中的DFG(Data Flow Graph)后,笔者闲下来再去回顾这些东西时,虽然写得很全面也很细节了, 但看起来还不是那么的直观,尤其是验证各条边的构建过程时,必须在特定代码场景下debug调试,然后从程序断点处寻找我们想要的DFG信息,想必大家在阅读过程中也是比较痛苦的。

基于上述原因,再加上CPG自身集成了图数据库Neo4j,其支持把翻译后的产物TranslationResult序列化到数据库,然后我们就可以通过Neo4j Browser直观地看到生成的图了,各节点间的关系,各节点间连接着什么边,节点都有哪些属性等等以的形式呈现,一目了然,对读者极其友好。

所以嘞,笔者打算以后的文章中若涉及到验证或者是需要看CPG的构建效果时,直接给大家上图!

大家可以先看一张图,直观地感受一下图形化展示的效果(此图不是完整的图,是笔者本地测试的一张图,主要是让大家感受下neo4j带来的便利)。

红色的边都是DFG边(neo4j browser提供的渲染,可自定义样式),另外,节点是什么类型,其有哪些属性都可以点击节点,直观地看到。

概述

Neo4j 是一款高性能的、开源的 NoSQL 图形数据库。其采用图形数据模型,将数据表示为节点关系以及节点之间的连接,并且节点及关系都可以携带属性来扩充信息,非常适合那些需要揭示复杂数据间隐含关系的应用场景。其存储的内容如下:

  • Node  节点
  • Relationship  节点间的关系
  • Property  节点属性

特点

  • 使用Cypher查询语言
  • 支持完整的ACID事务特性(原子性,一致性,隔离性和持久性)
  • 支持将查询的数据导出为JSON和XSL格式
  • 提供REST API,可以被任何编程语言访问
  • 下载地址:https://neo4j.com/deployment-center/#community
  • 解压后进入bin文件夹下,执行如下命令:
neo4j.bat console

如下效果即执行成功

  • 浏览器访问http://localhost:7474/browser/

输入默认账号neo4j,默认密码neo4j,然后再修改密码后即可正常访问。

tips:需先本地安装neo4j,并启动neo4j服务

1.gradle打包+命令行

// 克隆cpg到本地
git clone https://github.com/Fraunhofer-AISEC/cpg.git
// 进入cpg-neo4j目录
cd cpg/cpg-neo4j
//gradle 构建
gralde installDist

构建完成后,会在build/install/cpg-neo4j/bin目录下生成打包好的可执行文件

  • cpg-neo4j
  • cpg-neo4j.bat

命令行调用可执行程序:

./build/install/cpg-neo4j/bin/cpg-neo4j  [--infer-nodes] [--load-includes] [--no-default-passes]
[--no-neo4j] [--no-purge-db] [--print-benchmark]
[--use-unity-build] [--benchmark-json=<benchmarkJson>]
[--custom-pass-list=<customPasses>]
[--export-json=<exportJsonFile>] [--host=<host>]
[--includes-file=<includesFile>]
[--password=<neo4jPassword>] [--port=<port>]
[--save-depth=<depth>] [--top-level=<topLevel>]
[--user=<neo4jUsername>] ([<files>...] | -S=<String=String>
[-S=<String=String>]... |
--json-compilation-database=<jsonCompilationDatabase> |
--list-passes)
[<files>...] The paths to analyze. If module support is
enabled, the paths will be looked at if they
contain modules
--benchmark-json=<benchmarkJson>
Save benchmark results to json file
--custom-pass-list=<customPasses>
Add custom list of passes (includes
--no-default-passes) which is passed as a
comma-separated list; give either pass name if
pass is in list, or its FQDN (e.g.
--custom-pass-list=DFGPass,CallResolver)
--export-json=<exportJsonFile>
Export cpg as json
--host=<host> Set the host of the neo4j Database (default:
localhost).
--includes-file=<includesFile>
Load includes from file
--infer-nodes Create inferred nodes for missing declarations
--json-compilation-database=<jsonCompilationDatabase>
The path to an optional a JSON compilation database
--list-passes Prints the list available passes
--load-includes Enable TranslationConfiguration option loadIncludes
--no-default-passes Do not register default passes [used for debugging]
--no-neo4j Do not push cpg into neo4j [used for debugging]
--no-purge-db Do no purge neo4j database before pushing the cpg
--password=<neo4jPassword>
Neo4j password (default: password
--port=<port> Set the port of the neo4j Database (default: 7687).
--print-benchmark Print benchmark result as markdown table
-S, --softwareComponents=<String=String>
Maps the names of software components to their
respective files. The files are separated by
commas (No whitespace!).
Example: -S App1=./file1.c,./file2.c -S App2=.
/Main.java,./Class.java
--save-depth=<depth> Performance optimisation: Limit recursion depth
form neo4j OGM when leaving the AST. -1
(default) means no limit is used.
--top-level=<topLevel> Set top level directory of project structure.
Default: Largest common path of all source files
--use-unity-build Enable unity build mode for C++ (requires
--load-includes)
--user=<neo4jUsername> Neo4j user name (default: neo4j)

我们需要注意以下参数:

  • --host   neo4j服务器(默认localhost
  • --port  服务器端口(默认7687
  • --user  neo4j用户名(默认 neo4j
  • --password  neo4j密码(默认 password
  • --export-json  是否输出json格式的结果
  • --no-neo4j  不将结果push至neo4j数据库

使用示例:(其余参数默认即可)

 .\cpg-neo4j D:\Example.java --password yourPassword

有如下响应证明TranslationResult已成功push至neo4j

然后,就可以访问http://localhost:7474/browser查看CPG翻译后的代码属性图了

2.code调用

@Test
@Throws(InterruptedException::class)
fun myNeo4jTest() {
    val cmd = CommandLine(Application::class.java)
    cmd.parseArgs("Example.java")
    val application = cmd.getCommand<Application>()
    val translationConfiguration = application.setupTranslationConfiguration()
    val translationResult = TranslationManager.builder().config(translationConfiguration).build().analyze().get()
    application.pushToNeo4j(translationResult)
}

当然,你也可以参考CPG的测试代码进行修改:cpg-neo4j/src/test/kotlin/de/fraunhofer/aisec/cpg_vis_neo4j/Neo4JTest.kt

代码属性图CPG系列文章(白盒/静态代码分析方向):超万字的详细讲解,文章理论与实践相结合,示例代码可拿来即用通俗易懂,这样的文章你爱了吗! 

  • 社群大佬云集,可与各领域大咖面对面交流技术

  • 定期做优质技术分享提升自己的技术能力

  • 自我提升,不仅限于技术,还有圈子

  • 与笔者交个朋友

点击公众号底部菜单栏“点击进群”,扫码加笔者好友(备注"进群")

能够看到这篇文章,就是我们的缘分,坚持输出优质内容是笔者一直在做的事情。若文章对你有帮助,感谢点个免费的 点赞在看的鼓励是我最大的动力

关注我,交个朋友~


文章来源: https://mp.weixin.qq.com/s?__biz=MzkxNzY3MjE1NA==&mid=2247484382&idx=1&sn=0a9979dcf7de46831cdf79b012feedf1&chksm=c1bc5a6bf6cbd37df9604850ef281840a4035dbb42d74884e223b4b59c6a6dd0abcef07cd7a1&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh