agencies

joern으로 생성한 노드를 before 형식에 맞게 정렬 본문

Ⅲ. 정보보안

joern으로 생성한 노드를 before 형식에 맞게 정렬

agencies 2024. 10. 8. 17:05

 

위 파일은 실제 big-vul 에 있는 파일 중 135192 노드 부분이다.

 

우리가 node를 생성하면 아래와 같이 나온다.

 

내용은 일치하나 형식이 다르다 ...그래서 알맞게 수정을 조금 해줘야 한다.

(GPT도움을 무척 받아 만든 파일)

import re

# cpg_node_test.json 파일 읽기
input_file = 'cpg_node_test.json'
output_file = 'transformed_cpg_node_test.json'

with open(input_file, 'r') as f:
    data = f.read()

# 스칼라 구문을 파이썬에서 사용할 수 있도록 변환 (정규 표현식 사용)
data = re.sub(r'(\d+)L', r'\1', data)  # 1L -> 1로 변환
data = re.sub(r'None', 'null', data)  # None -> null로 변환
data = re.sub(r'ArraySeq\((.*?)\)', r'[\1]', data)  # ArraySeq -> 리스트로 변환
data = re.sub(r'List\((.*?)\)', r'[\1]', data)  # List -> 리스트로 변환

# 모든 key -> value 구문을 key: value 구문으로 변환 (order, version 등 포함)
def replace_key_value(match):
    key = match.group(1)
    value = match.group(2).strip()
    # null 값을 건너뛰고, 나머지는 key: value 형식으로 변환
    if value != 'null':  # null 값을 가진 항목 제거
        return f'"{key}": {value}'

# order -> 값, version -> 값을 처리하는 정규 표현식
data = re.sub(r'(order|version)\s*->\s*(-?\d+|"[^"]*")', r'"\1": \2', data)

# key -> value 구문을 처리 (null 값은 건너뛰기)
data = re.sub(r'(\w+)\s*->\s*(.*?)(,|\))', lambda m: replace_key_value(m), data)

# """을 "로 변환
data = data.replace('"""', '"')

# 노드 타입 이름을 정규 표현식을 사용하여 JSON 형식으로 변환 및 _label 추가
node_types = ['MetaData', 'NamespaceBlock', 'TypeDecl', 'Method', 'Block', 'Unknown', 'MethodReturn', 'Namespace', 'File', 'Type']

# 각 노드 타입에 대해 _label을 추가하는 정규 표현식 적용
for node_type in node_types:
    data = re.sub(rf'{node_type}\(', rf'{{"_label":"{node_type.upper()}",', data)

# 닫는 괄호 처리
data = re.sub(r'\),', r'}},', data)
data = re.sub(r'\)$', r'}}', data)

# 중복된 }}를 }로 변환
data = re.sub(r'}}+', '}', data)

# 불필요한 빈 콤마 제거
data = re.sub(r',\s*}', '}', data)

# 맨 앞 문자열과 끝에서 4글자 제거 후 추가
data = data.replace("res1: List[StoredNode] = List(", "")
data = data.replace("Some(value = ", "")


data = '[' + data[:-4] + ']'

# 변환된 데이터를 확인 후 저장
with open(output_file, 'w') as f:
    f.write(data)

print("ok")

 

 

실행하면~

 

 

이제 조금 더 가공을 하면 될 것 같다.


 

쉼표가 없어서 추가수정을 했다...

import re

# cpg_node_test.json 파일 읽기
input_file = 'cpg_node_test.json'
output_file = 'transformed_cpg_node_test.json'

with open(input_file, 'r') as f:
    data = f.read()

# 스칼라 구문을 파이썬에서 사용할 수 있도록 변환 (정규 표현식 사용)
data = re.sub(r'(\d+)L', r'\1', data)  # 1L -> 1로 변환
data = re.sub(r'None', 'null', data)  # None -> null로 변환
data = re.sub(r'ArraySeq\((.*?)\)', r'[\1]', data)  # ArraySeq -> 리스트로 변환
data = re.sub(r'List\((.*?)\)', r'[\1]', data)  # List -> 리스트로 변환

# 모든 key -> value 구문을 key: value 구문으로 변환 (order, version 등 포함)
def replace_key_value(match):
    key = match.group(1)
    value = match.group(2).strip()
    if value != 'null':  # null 값을 가진 항목 제거
        return f'"{key}": {value},'  # 쉼표 추가

# order -> 값, version -> 값을 처리하는 정규 표현식
data = re.sub(r'(order|version|typeFullName)\s*->\s*(-?\d+|"[^"]*")', r'"\1": \2,', data)

# key -> value 구문을 처리 (null 값은 건너뛰기)
data = re.sub(r'(\w+)\s*->\s*(.*?)(,|\))', lambda m: replace_key_value(m), data)

# 누락된 쉼표 추가: "}{"를 "} , {"로 변경
data = re.sub(r'}\s*{', '}, {', data)

# """을 "로 변환
data = data.replace('"""', '"')

# 노드 타입 이름을 정규 표현식을 사용하여 JSON 형식으로 변환 및 _label 추가
node_types = ['MetaData', 'NamespaceBlock', 'TypeDecl', 'Method', 'Block', 'Unknown', 'MethodReturn', 'Namespace', 'File', 'Type']

# 각 노드 타입에 대해 _label을 추가하는 정규 표현식 적용
for node_type in node_types:
    data = re.sub(rf'{node_type}\(', rf'{{"_label":"{node_type.upper()}",', data)

# 닫는 괄호 처리
data = re.sub(r'\),', r'}},', data)
data = re.sub(r'\)$', r'}}', data)

# 중복된 }}를 }로 변환
data = re.sub(r'}}+', '}', data)

data = re.sub(r',,', ',', data)

# 불필요한 빈 콤마 제거
data = re.sub(r',\s*}', '}', data)

# 맨 앞 문자열과 끝에서 4글자 제거 후 추가
data = data.replace("res1: List[StoredNode] = List(", "")
data = data.replace("Some(value = ", "")

data = '[' + data[:-7] + '}]'

# 변환된 데이터를 확인 후 저장
with open(output_file, 'w') as f:
    f.write(data)

print("ok")