Tabby 分析 Java 程序
Tabby 分析 Java 程序
Neo4j 环境配置 V5
下载最新版 Neo4j
可以从官网下载相应的包, Download
下载 APOC 插件
Neo4j v5 版本 apoc 插件改成了两个部分 apoc-core
和 apoc-extend
,可自行在以下两个库下载
- apoc-core https://github.com/neo4j/apoc
- apoc-extended https://github.com/neo4j-contrib/neo4j-apoc-procedures
关于 apoc 插件的版本选择方法:Neo4j 数据库版本的前两位对应 apoc 插件的版本 比如 Neo4j 数据库版本为 v5.3.0,则选择 apoc 插件 v5.3.x 版本
新建 Neo4j 图数据库
在 Desktop 处新建一个新的 Project 和一个本地数据库,初始化的时候需要设置密码。
新建成功后将会得到一个默认名为 neo4j 的数据库,下面连接使用这个数据库。
配置新建的图数据库
首先修改当前数据库的配置文件 neo4j.conf。
# 注释下面的配置,允许从本地任意位置载入csv文件
#server.directories.import=import
# 允许 apoc 扩展
dbms.security.procedures.unrestricted=jwt.security.*,apoc.*
# 修改内存相关配置
# 可以通过官方的neo4j-admin来推荐配置内存大小,https://neo4j.com/docs/operations-manual/current/tools/neo4j-admin/neo4j-admin-memrec/
dbms.memory.heap.initial_size=1G
dbms.memory.heap.max_size=4G
dbms.memory.pagecache.size=4G
然后同一个目录下 新建 apoc.conf 文件。
apoc.import.file.enabled=true
apoc.import.file.use_neo4j_config=false
最后,配置一下 apoc 和 tabby 插件,打开 plugins 目录将对应的 jar 复制到该数据库的 plugins 目录。
上述步骤做完之后,重启数据库
检查配置是否完成
启动图数据库并打开 Neo4j Brower。
看到如下窗口和信息即说明数据库没有问题。
查询 CALL apoc.help('all')
验证 apoc 插件是否正常。
图数据库索引配置(必做项)
为了加快导入/删除的速度,这里提前对节点进行索引建立。
CREATE CONSTRAINT c1 IF NOT EXISTS FOR (c:Class) REQUIRE c.ID IS UNIQUE;
CREATE CONSTRAINT c2 IF NOT EXISTS FOR (c:Class) REQUIRE c.NAME IS UNIQUE;
CREATE CONSTRAINT c3 IF NOT EXISTS FOR (m:Method) REQUIRE m.ID IS UNIQUE;
CREATE CONSTRAINT c4 IF NOT EXISTS FOR (m:Method) REQUIRE m.SIGNATURE IS UNIQUE;
CREATE INDEX index1 IF NOT EXISTS FOR (m:Method) ON (m.NAME);
CREATE INDEX index2 IF NOT EXISTS FOR (m:Method) ON (m.CLASSNAME);
CREATE INDEX index3 IF NOT EXISTS FOR (m:Method) ON (m.NAME, m.CLASSNAME);
CREATE INDEX index4 IF NOT EXISTS FOR (m:Method) ON (m.NAME, m.NAME0);
CREATE INDEX index5 IF NOT EXISTS FOR (m:Method) ON (m.SIGNATURE);
CREATE INDEX index6 IF NOT EXISTS FOR (m:Method) ON (m.NAME0);
CREATE INDEX index7 IF NOT EXISTS FOR (m:Method) ON (m.NAME0, m.CLASSNAME);
:schema //查看表库
:sysinfo //查看数据库信息
如果经过很多的导入/删除操作,图数据库占用了很多的硬盘存储,那么可以将原有的图数据库删除,重新按照上面的步骤新建图数据库。 删除所有约束。
DROP CONSTRAINT c1;
DROP CONSTRAINT c2;
DROP CONSTRAINT c3;
DROP CONSTRAINT c4;
DROP INDEX index1;
DROP INDEX index2;
DROP INDEX index3;
DROP INDEX index4;
DROP INDEX index5;
DROP INDEX index6;
DROP INDEX index7;
分析 Demo JAR 文件
配置 Tabby
在 tabby 下新建文件夹 cases,放入我们要分析的 JAR 文件。这里我们以 Xstrem 反序列化的环境作为例子。
接下来编辑 Tabby 的配置文件 /tabby/conf/settings.properties
。
# need to modify
tabby.build.enable = true
tabby.load.enable = true
tabby.build.target = cases/xstream-sample-1.4.15.jar
tabby.build.libraries = libs
tabby.build.mode = gadget
tabby.output.directory = ./output/dev
# debug
tabby.debug.details = false
# jdk settings
tabby.build.isJDKProcess = false
tabby.build.withAllJDK = false
tabby.build.excludeJDK = false
tabby.build.isJDKOnly = false
# dealing fatjar
tabby.build.checkFatJar = true
# pointed-to analysis
tabby.build.isFullCallGraphCreate = false
tabby.build.thread.timeout = 2
tabby.build.isNeedToCreateIgnoreList = false
# db settings
tabby.cache.isDockerImportPath = false
tabby.neo4j.username = neo4j
tabby.neo4j.password = xyw647584
tabby.neo4j.url = bolt://127.0.0.1:7687
参数字段的具体说明在[Tabby 配置文件介绍](https://github.com/wh1t3p1g/tabby/blob/master/doc/Tabby 配置文件介绍.md)。我们此处只需要修改密码和目标参数,即 tabby.build.target
和 tabby.neo4j.password
。
运行 Tabby
运行方式
java -Xmx20g -jar tabby.jar
或使用项目里的 run.sh
文件 内存大小根据实际情况进行调整。
运行的输出大概如下,没有报错说明没有问题。
C:\Users\Administrator\Desktop\tabby>java -Xmx35g -jar tabby.jar
___________ __ _______ _______ ___ ___
(" _ ") /""\ | _ "\ | _ "\|" \/" |
)__/ \\__/ / \ (. |_) :)(. |_) :)\ \ /
\\_ / /' /\ \ |: \/ |: \/ \\ \/
|. | // __' \ (| _ \\ (| _ \\ / /
\: | / / \\ \ |: |_) :)|: |_) :)/ /
\__|(___/ \___)(_______/ (_______/|___/
v1.2.0
Happy Hunting Bugs! XD
https://github.com/wh1t3p1g/tabby
2023-07-14 14:43:57.537 INFO 17188 --- [ main] tabby.App : Starting App using Java 1.8.0_102 on WIN-HOST-200 with PID 17188 (C:\Users\Administrator\Desktop\tabby\tabby.jar started by Administrator in C:\Users\Administrator\Desktop\tabby)
2023-07-14 14:43:57.543 INFO 17188 --- [ main] tabby.App : The following 1 profile is active: "default"
2023-07-14 14:44:02.820 INFO 17188 --- [ main] tabby.core.container.RulesContainer : load 57 rules success!
2023-07-14 14:44:04.944 INFO 17188 --- [ main] tabby.App : Started App in 8.514 seconds (JVM running for 10.018)
2023-07-14 14:44:04.980 INFO 17188 --- [bby-collector-1] tabby.core.container.DataContainer : Clean old tabby.core.data in Neo4j.
2023-07-14 14:44:05.340 INFO 17188 --- [ main] tabby.core.Analyser : Get 2 JDK dependencies
2023-07-14 14:44:05.343 INFO 17188 --- [ main] tabby.core.Analyser : Try to collect all targets
2023-07-14 14:44:05.864 INFO 17188 --- [ main] tabby.core.Analyser : Load basic classes
2023-07-14 14:44:06.494 INFO 17188 --- [bby-collector-1] tabby.core.container.DataContainer : Clean old tabby.core.data in Neo4j. DONE!
2023-07-14 14:44:07.995 INFO 17188 --- [ main] tabby.core.Analyser : Load dynamic classes
2023-07-14 14:44:07.995 INFO 17188 --- [ main] tabby.core.Analyser : Total analyse 39 targets.
2023-07-14 14:44:08.002 INFO 17188 --- [ main] tabby.core.Analyser : Target 39, Dependencies 41
2023-07-14 14:44:08.002 INFO 17188 --- [ main] tabby.core.scanner.ClassInfoScanner : Start to collect 39 targets' class information.
2023-07-14 14:44:15.787 INFO 17188 --- [ main] tabby.core.scanner.ClassInfoScanner : Total 10400 classes.
2023-07-14 14:44:15.805 INFO 17188 --- [ main] tabby.core.scanner.ClassInfoScanner : Build 10400 classes' edges.
2023-07-14 14:44:15.808 INFO 17188 --- [ main] tabby.core.scanner.ClassInfoScanner : Build 0/10400 classes.
2023-07-14 14:44:33.487 INFO 17188 --- [ main] tabby.core.scanner.ClassInfoScanner : Build 10000/10400 classes.
2023-07-14 14:44:33.801 INFO 17188 --- [ main] tabby.core.scanner.ClassInfoScanner : Build 10400/10400 classes.
2023-07-14 14:44:33.801 INFO 17188 --- [ main] tabby.core.scanner.ClassInfoScanner : Start to save remained data to graphdb.
2023-07-14 14:44:40.292 INFO 17188 --- [ main] tabby.core.scanner.ClassInfoScanner : Graphdb saved.
2023-07-14 14:44:40.309 INFO 17188 --- [ main] tabby.core.scanner.CallGraphScanner : Build call graph. START!
2023-07-14 14:47:28.849 INFO 17188 --- [ main] tabby.util.TickTock : Status: 5.0%, Remain: 77096
2023-07-14 14:48:27.926 INFO 17188 --- [ main] tabby.util.TickTock : Status: 10.0%, Remain: 73039
2023-07-14 14:48:51.205 INFO 17188 --- [ main] tabby.util.TickTock : Status: 15.0%, Remain: 68982
2023-07-14 14:49:18.355 INFO 17188 --- [ main] tabby.util.TickTock : Status: 20.0%, Remain: 64925
2023-07-14 14:49:33.021 INFO 17188 --- [ main] tabby.util.TickTock : Status: 25.0%, Remain: 60868
2023-07-14 14:49:49.118 INFO 17188 --- [ main] tabby.util.TickTock : Status: 30.0%, Remain: 56811
2023-07-14 14:49:59.110 INFO 17188 --- [ main] tabby.util.TickTock : Status: 35.0%, Remain: 52754
2023-07-14 14:50:13.855 INFO 17188 --- [ main] tabby.util.TickTock : Status: 40.0%, Remain: 48697
2023-07-14 14:50:22.646 INFO 17188 --- [ main] tabby.util.TickTock : Status: 45.0%, Remain: 44640
2023-07-14 14:50:30.322 INFO 17188 --- [ main] tabby.util.TickTock : Status: 50.0%, Remain: 40583
2023-07-14 14:50:38.200 INFO 17188 --- [ main] tabby.util.TickTock : Status: 55.0%, Remain: 36526
2023-07-14 14:50:45.485 INFO 17188 --- [ main] tabby.util.TickTock : Status: 60.0%, Remain: 32469
2023-07-14 14:50:51.392 INFO 17188 --- [ main] tabby.util.TickTock : Status: 65.0%, Remain: 28412
2023-07-14 14:50:57.594 INFO 17188 --- [ main] tabby.util.TickTock : Status: 70.0%, Remain: 24355
2023-07-14 14:51:02.794 INFO 17188 --- [ main] tabby.util.TickTock : Status: 75.0%, Remain: 20298
2023-07-14 14:51:07.769 INFO 17188 --- [ main] tabby.util.TickTock : Status: 80.0%, Remain: 16241
2023-07-14 14:51:12.145 INFO 17188 --- [ main] tabby.util.TickTock : Status: 85.0%, Remain: 12184
2023-07-14 14:51:16.599 INFO 17188 --- [ main] tabby.util.TickTock : Status: 90.0%, Remain: 8127
2023-07-14 14:51:20.591 INFO 17188 --- [ main] tabby.util.TickTock : Status: 95.0%, Remain: 4070
2023-07-14 14:51:27.575 INFO 17188 --- [ main] tabby.util.TickTock : Status: 100.0%, Remain: 13
2023-07-14 14:51:27.582 INFO 17188 --- [ main] tabby.util.TickTock : Status: 100.0%, Remain: 0
2023-07-14 14:51:27.582 INFO 17188 --- [ main] tabby.util.TickTock : Wait for all tasks to complete. Timeout: 120s
2023-07-14 14:51:27.585 INFO 17188 --- [ main] tabby.util.TickTock : All tasks completed.
2023-07-14 14:51:27.589 INFO 17188 --- [ main] tabby.core.scanner.CallGraphScanner : Build call graph. DONE!
2023-07-14 14:51:27.592 INFO 17188 --- [ main] tabby.core.scanner.CallGraphScanner : Save remained data to graphdb. START!
2023-07-14 14:51:48.359 INFO 17188 --- [ main] tabby.core.scanner.CallGraphScanner : Save remained data to graphdb. DONE!
2023-07-14 14:51:48.359 INFO 17188 --- [ main] tabby.core.Analyser : Total cost 7 min 40 seconds.
2023-07-14 14:51:48.379 INFO 17188 --- [ main] tabby.core.container.DataContainer : Total 121218, classes: 13897, methods: 107321
2023-07-14 14:51:48.586 INFO 17188 --- [ main] t.d.c.service.RelationshipsService : Total 297613, has count: 107321, call count: 149771, extend count: 4289, alias count: 29395, interfaces count: 6837
2023-07-14 14:51:48.586 INFO 17188 --- [ main] tabby.core.container.DataContainer : Save cache to CSV.
2023-07-14 14:51:54.126 INFO 17188 --- [ main] tabby.core.container.DataContainer : Save cache to CSV. DONE!
2023-07-14 14:51:54.126 INFO 17188 --- [ main] tabby.core.Analyser : Start to save cache.
2023-07-14 14:51:54.133 INFO 17188 --- [ main] tabby.core.container.DataContainer : Save methods to Neo4j.
2023-07-14 14:53:03.690 INFO 17188 --- [ main] tabby.core.container.DataContainer : Save classes to Neo4j.
2023-07-14 14:53:04.902 INFO 17188 --- [ main] tabby.core.container.DataContainer : Save relation to Neo4j.
2023-07-14 14:53:04.902 INFO 17188 --- [ main] tabby.dal.neo4j.service.ClassService : Save Extend relationship
2023-07-14 14:53:06.468 INFO 17188 --- [ main] tabby.dal.neo4j.service.ClassService : Save Interface relationship
2023-07-14 14:53:07.743 INFO 17188 --- [ main] tabby.dal.neo4j.service.ClassService : Save Has relationship
2023-07-14 14:53:18.720 INFO 17188 --- [ main] tabby.dal.neo4j.service.ClassService : Save Call relationship
2023-07-14 14:53:35.496 INFO 17188 --- [ main] tabby.dal.neo4j.service.ClassService : Save Alias relationship
2023-07-14 14:53:38.346 INFO 17188 --- [ main] tabby.core.Analyser : Cost 1 min 44 seconds.
2023-07-14 14:53:38.346 INFO 17188 --- [ main] tabby.App : Done. Bye!
进入数据库之后查看数据保存是否完成。
查询
Demo
我们查询几个类看看。
MATCH (n:Class)
RETURN n
LIMIT 10
结果之一如下,可以观察其中的字段。
{
"identity": 107324,
"labels": [
"Class"
],
"properties": {
"HAS_INTERFACES": false,
"IS_STRUTS_ACTION": false,
"HAS_DEFAULT_CONSTRUCTOR": true,
"HAS_SUPER_CLASS": true,
"INTERFACES": "[]",
"IS_INTERFACE": false,
"ID": "e0efd3dfa9f74c9aa133e585e9314157",
"IS_ABSTRACT": false,
"IS_SERIALIZABLE": false,
"SUPER_CLASS": "org.apache.catalina.valves.ValveBase",
"NAME": "org.apache.catalina.valves.ErrorReportValve"
},
"elementId": "107324"
}
假如想查询 fastjson jar包里面的类呢。
MATCH (n:Class)
WHERE n.NAME STARTS WITH 'com.alibaba.fastjson'
RETURN n
LIMIT 10
getDataSourceName:825, BaseRowSet (javax.sql.rowset)
connect:624, JdbcRowSetImpl (com.sun.rowset)
getDatabaseMetaData:4004, JdbcRowSetImpl (com.sun.rowset) < ======================== 进入JdbcRowSetImpl类
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
get:343, Accessor$GetterSetterReflection (com.sun.xml.internal.bind.v2.runtime.reflect) < ======================== 4
serializeURIs:402, ClassBeanInfoImpl (com.sun.xml.internal.bind.v2.runtime)
childAsXsiType:662, XMLSerializer (com.sun.xml.internal.bind.v2.runtime)
write:256, MarshallerImpl (com.sun.xml.internal.bind.v2.runtime)
marshal:89, BridgeImpl (com.sun.xml.internal.bind.v2.runtime)
marshal:130, Bridge (com.sun.xml.internal.bind.api)
marshal:161, BridgeWrapper (com.sun.xml.internal.ws.db.glassfish)
writeTo:109, JAXBAttachment (com.sun.xml.internal.ws.message) < ======================== 3 第一次出现JdbcRowSetImpl对象
asInputStream:99, JAXBAttachment (com.sun.xml.internal.ws.message)
getInputStream:125, JAXBAttachment (com.sun.xml.internal.ws.message)
getMessage:366, XMLMessage$XMLMultiPart (com.sun.xml.internal.ws.encoding.xml)
getAttachments:465, XMLMessage$XMLMultiPart (com.sun.xml.internal.ws.encoding.xml)
getAttachments:103, MessageWrapper (com.sun.xml.internal.ws.api.message)
get:111, ResponseContext (com.sun.xml.internal.ws.client) < ======================== 2
compareIndices:2492, DataTransferer$IndexedComparator (sun.awt.datatransfer)
compare:2971, DataTransferer$IndexOrderComparator (sun.awt.datatransfer) < ======================== POC的第二个类
siftDownUsingComparator:721, PriorityQueue (java.util)
siftDown:687, PriorityQueue (java.util)
heapify:736, PriorityQueue (java.util)
readObject:796, PriorityQueue (java.util) < ======================== 1 进入PriorityQueue类的 readObject 方法 CC2?
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
callReadObject:132, SerializationMembers (com.thoughtworks.xstream.core.util) < ======================== 准备进入PriorityQueue类的 readObject 方法
doUnmarshal:443, SerializableConverter (com.thoughtworks.xstream.converters.reflection)
unmarshal:277, AbstractReflectionConverter (com.thoughtworks.xstream.converters.reflection) < ======================== 第一次出现PriorityQueue对象 result
convert:72, TreeUnmarshaller (com.thoughtworks.xstream.core)
convert:72, AbstractReferenceUnmarshaller (com.thoughtworks.xstream.core)
convertAnother:66, TreeUnmarshaller (com.thoughtworks.xstream.core)
convertAnother:50, TreeUnmarshaller (com.thoughtworks.xstream.core)
start:134, TreeUnmarshaller (com.thoughtworks.xstream.core) < ======================== 第一次出现PriorityQueue Class对象
unmarshal:32, AbstractTreeMarshallingStrategy (com.thoughtworks.xstream.core)
unmarshal:1409, XStream (com.thoughtworks.xstream)
unmarshal:1388, XStream (com.thoughtworks.xstream)
fromXML:1273, XStream (com.thoughtworks.xstream)
fromXML:1264, XStream (com.thoughtworks.xstream)
read:20, HelloController (org.vulhub.xstreamsample)
第一段
match (source:Method {NAME:"fromXML",CLASSNAME:"com.thoughtworks.xstream.XStream"})
match (sink:Method {NAME:"unmarshal",CLASSNAME:"com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy"})
with source, collect(sink) as sinks
call tabby.algo.findPath(source, sinks, 8, false, false) YIELD path
return path
第二段
match (source:Method {NAME:"start",CLASSNAME:"com.thoughtworks.xstream.core.TreeUnmarshaller"})
match (sink:Method {NAME:"convert",CLASSNAME:"com.thoughtworks.xstream.core.TreeUnmarshaller"})
with source, collect(sink) as sinks
call tabby.algo.findPath(source, sinks, 10, false, false) YIELD path
return path
第三段
match (source:Method {NAME:"unmarshal",CLASSNAME:"com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter"})
match (sink:Method {NAME:"callReadObject",CLASSNAME:"com.thoughtworks.xstream.core.util.SerializationMembers"})
with source, collect(sink) as sinks
call tabby.algo.findPath(source, sinks, 8, false, false) YIELD path
return path