Skip to content

Instantly share code, notes, and snippets.

@PierceLBrooks
Last active November 25, 2025 20:08
Show Gist options
  • Select an option

  • Save PierceLBrooks/dc12b8748b61ac3cc10bb069feeb6fbc to your computer and use it in GitHub Desktop.

Select an option

Save PierceLBrooks/dc12b8748b61ac3cc10bb069feeb6fbc to your computer and use it in GitHub Desktop.
# Author: Pierce Brooks
import os
import sys
import copy
import json
import platform
import subprocess
def run(binaries):
if (sys.flags.debug):
print("RUN")
past = []
sboms = []
components = {}
dependencies = {}
references = {}
mapping = {}
environment = None
if (platform.system().strip().lower() == "linux"):
environment = {}
try:
command = []
command.append("ldconfig")
command.append("-p")
output = subprocess.check_output(command).decode()
lines = output.split("\n")
for line in lines:
line = line.strip()
if not (" => " in line):
continue
line = line.split(" => ")
left = line[0].strip()
if (left in environment):
continue
right = line[len(line)-1].strip()
if not (os.path.exists(right)):
continue
environment[left] = right
except:
pass
elif (platform.system().strip().lower() == "windows"):
environment = os.environ.copy()
rpath = ""
if (platform.system().strip().lower() == "linux"):
rpath += "$ORIGIN"
else:
rpath += "@rpath"
origin = os.path.join(os.getcwd(), os.path.basename(binaries[0])+".sbom.cdx.json")
while ((len(binaries) > 0) or (len(sboms) > 0)):
if (sys.flags.debug):
print("WHILE")
if (len(binaries) > 0):
if (sys.flags.debug):
print(json.dumps(binaries))
binary = binaries[0]
if not (binary in past):
past.append(binary)
if (len(binaries) == 1):
binaries = []
else:
binaries = binaries[1:]
if (sys.flags.debug):
print(binary)
if not (os.path.exists(binary)):
continue
sbom = os.path.join(os.getcwd(), os.path.basename(binary)+".sbom.cdx.json")
mapping[sbom] = binary
dependencies[binary] = []
if (os.path.exists(sbom)):
sboms.append(sbom)
continue
command = []
command.append("blint")
command.append("sbom")
command.append("-i")
command.append(binary)
command.append("-o")
command.append(sbom)
if (sys.flags.debug):
print(str(command))
subprocess.check_output(command)
if not (os.path.exists(sbom)):
continue
sboms.append(sbom)
continue
sbom = sboms[0]
if (len(sboms) == 1):
sboms = []
else:
sboms = sboms[1:]
if (sys.flags.debug):
print(sbom)
if not (os.path.exists(sbom)):
continue
descriptor = open(sbom, "r")
content = descriptor.read()
descriptor.close()
data = json.loads(content)
if (sys.flags.debug):
for key in data:
print(key)
dep = []
if ("components" in data):
for i in range(len(data["components"])):
comp = copy.deepcopy(data["components"][i])
ref = None
name = None
source = None
if ("properties" in comp):
for prop in comp["properties"]:
if (("name" in prop) and ("value" in prop)):
if (prop["name"] == "internal:libPath"):
name = prop["value"]
elif (prop["name"] == "internal:srcFile"):
source = prop["value"]
if ((name == None) and ("name" in comp) and not (environment == None)):
if (platform.system().strip().lower() == "linux"):
for key in environment:
if (comp["name"] in key):
name = environment[key]
break
if ((name == None) and not (source == None)):
if ((os.path.exists(source)) and (os.path.isdir(os.path.dirname(source))) and not (os.path.isdir(source))):
source = os.path.dirname(source)
try:
command = []
command.append("objdump")
command.append("-x")
command.append(mapping[sbom])
output = subprocess.check_output(command).decode()
lines = output.split("\n")
for line in lines:
line = line.strip().replace("\t", " ")
if not (" " in line):
continue
line = line.split(" ")
if not (("RPATH" in line[0].upper()) or ("RUNPATH" in line[0].upper())):
continue
line = line[len(line)-1].strip()
if (rpath in line):
for root, folders, files in os.walk(source):
for library in files:
if (library == comp["name"]):
name = os.path.join(root, library)
break
break
if not (name == None):
break
except:
pass
else:
for key in environment:
if (key.strip().lower() == "path"):
paths = environment[key].split(";")
if not (source == None):
if ((os.path.exists(source)) and (os.path.isdir(os.path.dirname(source)))):
paths.append(os.path.dirname(source))
for path in paths:
if not (os.path.isdir(path)):
continue
for root, folders, files in os.walk(path):
for library in files:
if (os.path.exists(os.path.join(root, library))):
if (library == comp["name"]):
name = os.path.join(root, library)
break
break
if not (name == None):
break
break
if ("bom-ref" in comp):
ref = comp["bom-ref"]
if not ((name == None) or (ref == None)):
if not (ref in dep):
dep.append(ref)
if ((rpath in name) and not (source == None)):
if (sys.flags.debug):
print(source)
if ((os.path.exists(source)) and (os.path.isdir(os.path.dirname(source))) and not (os.path.isdir(source))):
source = os.path.dirname(source)
name = name.replace(rpath, source)
if not (ref in references):
if not (name in past):
binaries.append(name)
references[ref] = name
if ("properties" in comp):
for prop in comp["properties"]:
if (("name" in prop) and ("value" in prop)):
if (prop["name"] == "internal:libPath"):
prop["value"] = name
name = None
break
if not (name == None):
comp["properties"].append({"name": "internal:libPath", "value": name})
if not (ref == None):
if not (ref in components):
component = json.dumps(comp)
components[ref] = component
for dependency in dep:
if (dependency in dependencies[mapping[sbom]]):
continue
dependencies[mapping[sbom]].append(dependency)
if not (os.path.exists(origin)):
return -1
descriptor = open(origin, "r")
content = descriptor.read()
descriptor.close()
data = json.loads(content)
data["components"] = []
for component in components:
data["components"].append(json.loads(components[component]))
if ("dependencies" in data):
for i in range(len(data["dependencies"])):
dependency = data["dependencies"][i]
if (("ref" in dependency) and ("dependsOn" in dependency)):
ref = dependency["ref"]
if (ref in references):
ref = references[ref]
if (ref in dependencies):
for dep in dependencies[ref]:
if not (dep in dependency["dependsOn"]):
data["dependencies"][i]["dependsOn"].append(dep)
descriptor = open(origin, "w")
descriptor.write(json.dumps(data))
descriptor.close()
return 0
def launch(arguments):
if (sys.flags.debug):
print("LAUNCH")
if (len(arguments) < 2):
return False
result = run(arguments[1:])
print(str(result))
if not (result == 0):
return False
return True
if (__name__ == "__main__"):
print(str(launch(sys.argv)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment