Skip to content

Commit

Permalink
add end node filter and relationship filter
Browse files Browse the repository at this point in the history
  • Loading branch information
waderwu committed Dec 27, 2023
1 parent 45f0539 commit 1ec1500
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 20 deletions.
24 changes: 19 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,36 @@

## Chinese

### 简介
### Introduction

实现了自定义procedure

- `bytecodedl.findOnePath`
- `findOnePath(@Name("start") Node start, @Name("end") Node end, @Name("maxLength") Long maxLength @Name("callProperty") String callProperty)`
- `findOnePath(@Name("start") Node start, @Name("end") Node end, @Name("maxLength") long maxLength, @Name(value = "relationshipType", defaultValue = "Call") String relationType, @Name(value = "callProperty", defaultValue = "insn") String callProperty)`
- `bytecodedl.biFindOnePath`
- `biFindOnePath(@Name("start") Node start, @Name("end") Node end, @Name("maxLength") Long maxLength @Name("callProperty") String callProperty)`
- `biFindOnePath(@Name("start") Node start, @Name("end") Node end, @Name("maxLength") long maxLength, @Name(value = "relationshipType", defaultValue = "Call") String relationType, @Name(value = "callProperty", defaultValue = "insn") String callProperty)`

其中各个参数的意义

- start: 开始节点
- end: 结束节点
- maxLength: path 最大长度
- relationshipType: 边的类型 默认是Call
- callProperty: 边的属性名称 默认是insn 值的格式为`<org.apache.logging.log4j.core.appender.ScriptAppenderSelector$Builder: org.apache.logging.log4j.core.Appender build()>/org.apache.logging.log4j.Logger.error/0`,会根据这个值计算multi dispatch

功能包括:
- 从start到end找到长度小于maxlength任意一条路径就返回 -> 速度较快
- 然后找到该路径第一个存在multi dispatch的边,同时返回所有的dispatch结果 -> 方便排查virtual invoke存在多个callee的情况
- 过滤掉属性is_deleted为1的边

### Build

`./mvnw clean package -DskipTests`

### 安装
### Install

- 手动安装
-[releases](https://github.com/BytecodeDL/bytecodedl-pathfinder-neo4j-procedure/releases/)下载最新的jar, 然后放到neo4j的`/var/lib/neo4j/plugins`目录
- 然后在`/var/lib/neo4j/conf/neo4j.conf`增加一行`dbms.security.procedures.unrestricted=bytecodedl.*`
- docker
-
- `docker pull wuxxxxx/neo4j-server:5.12.0-bytecodedl-pathfinder-1.0.0`
6 changes: 0 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,6 @@
<scope>provided</scope>
</dependency>

<!-- <dependency>-->
<!-- <groupId>org.neo4j</groupId>-->
<!-- <artifactId>neo4j-graph-algo</artifactId>-->
<!-- <version>5.12.0</version>-->
<!-- </dependency>-->

<!-- Test Dependencies -->
<dependency>
<!-- This is used for a utility that lets us start Neo4j with
Expand Down
36 changes: 36 additions & 0 deletions src/main/java/com/bytecodedl/pathfinder/FindAnyOneEvaluator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.bytecodedl.pathfinder;

import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Path;
import org.neo4j.graphdb.traversal.Evaluation;
import org.neo4j.graphdb.traversal.Evaluator;


/**
* @author [email protected]
* @date 2023/12/16 16:40
*/
public class FindAnyOneEvaluator implements Evaluator {
private Node endNode;
private long maxLength;

public FindAnyOneEvaluator(Node endNode, long maxLength){
this.endNode = endNode;
this.maxLength = maxLength;
}

@Override
public Evaluation evaluate(Path path) {
if (path.length() > this.maxLength){
return Evaluation.EXCLUDE_AND_PRUNE;
}

Node pathEndNode = path.endNode();
if (pathEndNode.equals(endNode)){
return Evaluation.INCLUDE_AND_PRUNE;
}

return Evaluation.EXCLUDE_AND_CONTINUE;
}
}

18 changes: 9 additions & 9 deletions src/main/java/com/bytecodedl/pathfinder/FindAnyOnePath.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
package com.bytecodedl.pathfinder;

import org.neo4j.graphalgo.GraphAlgoFactory;
import org.neo4j.graphalgo.PathFinder;
import org.neo4j.graphalgo.WeightedPath;
import org.neo4j.graphalgo.impl.util.PathImpl;
import org.neo4j.graphdb.*;
import org.neo4j.graphdb.traversal.*;
import org.neo4j.logging.Log;
import org.neo4j.procedure.*;

import java.nio.DoubleBuffer;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
Expand All @@ -31,11 +27,15 @@ public class FindAnyOnePath {

@Procedure(name = "bytecodedl.findOnePath", mode = Mode.READ)
@Description("find one path from start to end under maxlength, also show first multi dispatch")
public Stream<PathRecord> findOnePath(@Name("start") Node start, @Name("end") Node end, @Name("maxLength") long maxLength, @Name("callProperty") String callProperty){
public Stream<PathRecord> findOnePath(@Name("start") Node start, @Name("end") Node end, @Name("maxLength") long maxLength, @Name(value = "relationshipType", defaultValue = "Call") String relationType, @Name(value = "callProperty", defaultValue = "insn") String callProperty){
final Traverser traverser = tx.traversalDescription()
.breadthFirst()
.evaluator(Evaluators.toDepth((int)maxLength))
.expand(PathExpanders.forTypeAndDirection(RelationshipType.withName("Call"), Direction.OUTGOING ))
.evaluator(new FindAnyOneEvaluator(end, maxLength))
.expand(
PathExpanderBuilder.empty()
.add(RelationshipType.withName(relationType), Direction.OUTGOING)
// filter non delete relation
.addRelationshipFilter(relationship -> relationship.getProperty("is_deleted", "0").equals("0")).build())
.uniqueness(Uniqueness.NODE_GLOBAL)
.traverse(start);

Expand All @@ -44,9 +44,9 @@ public Stream<PathRecord> findOnePath(@Name("start") Node start, @Name("end") No

@Procedure(name = "bytecodedl.biFindOnePath", mode = Mode.READ)
@Description("find one path from start to end between minlength and maxlength, also show first multi dispatch")
public Stream<PathRecord> biFindOnePath(@Name("start") Node start, @Name("end") Node end, @Name("maxLength") long maxLength, @Name("callProperty") String callProperty){
public Stream<PathRecord> biFindOnePath(@Name("start") Node start, @Name("end") Node end, @Name("maxLength") long maxLength, @Name(value = "relationshipType", defaultValue = "Call") String relationType, @Name(value = "callProperty", defaultValue = "insn") String callProperty){
TraversalDescription base = tx.traversalDescription().depthFirst().uniqueness(Uniqueness.RELATIONSHIP_GLOBAL);
PathExpander expander = PathExpanders.forTypeAndDirection(RelationshipType.withName("Call"), Direction.OUTGOING );
PathExpander expander = PathExpanderBuilder.empty().add(RelationshipType.withName(relationType), Direction.OUTGOING).addRelationshipFilter(relationship -> relationship.getProperty("is_deleted", "0").equals("0")).build();
int maxDepth = (int) maxLength;

final Traverser traverser = tx.bidirectionalTraversalDescription()
Expand Down

0 comments on commit 1ec1500

Please sign in to comment.