agencies

Joern을 이용한 CPG node edge 생성하기 (deepdfa) 1.1.1072 version 본문

Ⅲ. 정보보안

Joern을 이용한 CPG node edge 생성하기 (deepdfa) 1.1.1072 version

agencies 2024. 10. 7. 20:05

https://github.com/ISU-PAAL/DeepDFA

 

GitHub - ISU-PAAL/DeepDFA: Replication package for "Dataflow Analysis-Inspired Deep Learning for Efficient Vulnerability Detecti

Replication package for "Dataflow Analysis-Inspired Deep Learning for Efficient Vulnerability Detection", ICSE 2024. - ISU-PAAL/DeepDFA

github.com

https://figshare.com/articles/dataset/Dataflow_Analysis-Inspired_Deep_Learning_for_Efficient_Vulnerability_Detection/21225413

 

Dataflow Analysis-Inspired Deep Learning for Efficient Vulnerability Detection

Data package for "Dataflow Analysis-Inspired Deep Learning for Efficient Vulnerability Detection", published in ICSE 2024, with updates from Artifact Evaluation.Paper link: https://www.computer.org/csdl/proceedings-article/icse/2024/021700a166/1RLIWqviwEMS

figshare.com

https://arxiv.org/pdf/2212.08108

 


 

※ 논문에 존재하는 before 파일 중 일부

100016.c
0.00MB
100016.c.cpg.bin
0.02MB
100016.c.edges.json
0.00MB
100016.c.nodes.json
0.00MB

 

 

 

우리는 c 파일로 cpg 파일을 생성하고

생성된 cpg 파일로 nodes 와 edges를 생성해야 합니다.


 

본 실습은 colab 환경에서 진행되었습니다.

 

!wget https://github.com/joernio/joern/releases/download/v1.1.1072/joern-cli.zip
!unzip joern-cli.zip -d joern-cli
%cd joern-cli/joern-cli

 

joern 1.1.1072 버전 설치

 

!./joern-parse /content/100016.c

 

cpg 생성하기

 

생성된 cpg.bin 파일은 위의 경로에 존재한다.

 

서로 내용이 거의 동일하다

 

 

 

이제 노드를 생성하기 위해

colab 터미널에서 joern 을 실행한다.

(이것도 joern 스크립트로 진행할 수 있으나 지금은 테스트 중이기때문에 터미널 환경에서 진행했다)

 

 

 

joern> 에 아래의 명령을 입력한다.

importCpg(”cpg.bin”)
cpg.all.l

 

생성된 노드를 before 파일의 nodes 와 비교를 해본다.

 

 

내용이 똑같다 (순서만 다르다)

 

 

 

 

 

이제 엣지를 생성해보자

%%writefile script3.sc
import java.io.PrintWriter
import scala.jdk.CollectionConverters._
importCpg("cpg.bin")

// 결과를 JSON 파일로 출력할 준비
val writer = new PrintWriter("/content/cpg_edges.json")
writer.print("[")

// 모든 에지 추출
val edges = cpg.graph.edges.l

edges.foreach { edge =>
    val inNodeId = edge.inNode.id // inNode ID 추출
    val outNodeId = edge.outNode.id // outNode ID 추출
    val edgeType = edge.label // 에지의 타입 (예: REACHING_DEF, AST 등)

    // VARIABLE 속성에서 값 추출
    val extraDataValue = if (edge.propertyKeys.contains("VARIABLE")) {
        edge.property("VARIABLE").toString
    } else {
        "null"
    }

    // 에지 정보를 JSON 형식으로 출력
    if (extraDataValue != "null") {
        writer.print(s"""[$inNodeId,$outNodeId,"$edgeType","$extraDataValue"],""")
    } else {
        writer.print(s"""[$inNodeId,$outNodeId,"$edgeType",null],""")
    }
}

// JSON 형식의 배열 닫기
writer.print("]")
writer.close()

 

이번꺼는 joern 스크립트로 작성되었다.

 

 

생성된 스크립트는

!./joern --script script3.sc

명령으로 실행할 수 있다.

 

 

 

순서만 다르지 내용은 똑같다.

 

 

 

 


4.0.151 버전에서 cpg 를 만들려면 이렇다. (최신버전)

test 폴더에는 .c만 있고

output 폴더에 생성한 .cpg 를 넣고 싶을때

 

import os
import subprocess

# c2cpg.sh 실행 파일 경로
c2cpg = "/content/set_up/joern-cli/joern-cli/c2cpg.sh"

# 입력 폴더와 출력 폴더 경로
folder_path = "test"  # C 소스 코드가 들어 있는 디렉토리
output_folder = "output"  # CPG 파일을 저장할 디렉토리

# 출력 폴더가 없으면 생성
if not os.path.exists(output_folder):
    os.makedirs(output_folder)

# 입력 폴더 내 .c 파일을 처리
for filename in os.listdir(folder_path):
    if filename.endswith(".c"):  # .c 파일만 처리
        input_file = os.path.abspath(os.path.join(folder_path, filename))  # 입력 파일 절대 경로
        output_file = os.path.abspath(os.path.join(output_folder, f"{filename}.cpg.bin"))  # 출력 파일 경로

        print(f"Processing file: {input_file}")
        
        # c2cpg.sh 명령 실행
        command = [c2cpg, "-o", output_file, input_file]
        try:
            subprocess.run(command, check=True)
            print(f"Successfully processed: {input_file}")
        except subprocess.CalledProcessError as e:
            print(f"Error processing file: {input_file}")
            print(f"Error message: {e}")