Files
Eduardo' Vela" Nava (sirdarckcat) 4bd1568850 Add files via upload
2024-12-21 17:15:38 +01:00

107 lines
3.1 KiB
Python

import sqlite3
from collections import defaultdict
def find_paths_to_function_recursive(db_file, function, max_depth=100):
"""
Finds paths to $function recursively, finding edges
by target message and filtering by rule_id.
"""
conn = sqlite3.connect(db_file)
cursor = conn.cursor()
cursor.execute("SELECT id, message, uri, startLine FROM locations")
locations = cursor.fetchall()
# Create a dictionary to map location ID to (message, uri, startLine)
location_map = defaultdict(set)
for id, message, uri, startLine in locations:
location_map[(message, uri, startLine)].add(id)
# Find IDs corresponding to $function
function_keys = [
key for key, value in location_map.items() if key[0] == function
][0:1000]
def preprocess_edges(cursor):
cursor.execute(
"""
SELECT e.source_location_id, e.target_location_id
FROM edges AS e
WHERE e.rule_id = 'callgraph-all'
"""
)
edges = {}
for source_id, target_id in cursor.fetchall():
if target_id not in edges:
edges[target_id] = []
edges[target_id].append(source_id)
return edges
edges = preprocess_edges(cursor)
def find_edge_source(target_key):
target_ids = location_map.get(target_key)
if target_ids:
for target_id in target_ids:
source_ids = edges.get(target_id)
if source_ids:
return source_ids
return None
paths = [] # To store all unique paths
seen_paths = set() # To keep track of visited paths
def dfs_recursive(node_key, path, visited, depth):
visited.add(node_key)
path.append(node_key)
neighbors = find_edge_source(node_key)
if neighbors is not None:
for neighbor_id in neighbors:
for key, ids in location_map.items():
if neighbor_id in ids:
neighbor_key = key
break
if (
neighbor_key
and depth < max_depth
and neighbor_key not in visited
):
dfs_recursive(
neighbor_key, path.copy(), visited.copy(), depth + 1
)
else:
path_tuple = tuple(path)
if path_tuple not in seen_paths:
seen_paths.add(path_tuple)
paths.append(path.copy())
path.pop()
visited.remove(node_key)
for start_key in function_keys:
dfs_recursive(start_key, [], set(), 0)
named_paths = []
for path in paths:
named_paths.append(path.copy())
conn.close()
return named_paths
if __name__ == "__main__":
db_file = "codeql_data-6.1.db"
paths = find_paths_to_function_recursive(db_file, "___sys_recvmsg")
for path in paths:
# Format the path
formatted_path = " -> ".join(
[f"{node[0]} ({node[1]}:{node[2]})" for node in path]
)
print(formatted_path)
print()