Example
This example assumes you have already created the BGraph for android-10.0.0_r1
and the file is available in graphs/android-10.0.0_r1.bgraph
.
First query: dependencies of a source file
The patch for the CVE-2020-0471 modifies the file packet_fragmenter.cc
( commit: ca6b0a). We are interested in the different targets (e.g. binaries and libraries) where we can find the content of this file in AOSP.
% bgraph query graphs/android-10.0.0_r1.bgraph --src 'packet_fragmenter.cc'
Dependencies for source file
packet_fragmenter.cc
╷ ╷
Target │ Type │ Distance
══════════════╪═══════════════════╪══════════
libbt-hci │ cc_library_static │ 1
libbt-stack │ cc_library_static │ 2
libbluetooth │ cc_library_shared │ 2
╵ ╵
Warning
The example assumes you have already created the bgraph
for android-10.0.0_r1
.
Second query: let's find sources of library
% bgraph query graphs/android-10.0.0_r1.bgraph --target libbluetooth-types-header
Sources for the target libbluetooth-types-header
╷
Filename │ File type
═════════════════════════════════════════════════════════════════════════════════════════╪═══════════
/tmp/bgraph_6p4534y2/android-10.0.0_r1/system/bt/types/class_of_device.h │ .h
/tmp/bgraph_6p4534y2/android-10.0.0_r1/system/bt/types/test/bluetooth/uuid_unittest.cc │ .cc
/tmp/bgraph_6p4534y2/android-10.0.0_r1/system/bt/types/bluetooth/uuid.h │ .h
/tmp/bgraph_6p4534y2/android-10.0.0_r1/system/bt/types/raw_address.cc │ .cc
/tmp/bgraph_6p4534y2/android-10.0.0_r1/system/bt/types/BUILD.gn │ .gn
/tmp/bgraph_6p4534y2/android-10.0.0_r1/system/bt/types/test/raw_address_unittest.cc │ .cc
/tmp/bgraph_6p4534y2/android-10.0.0_r1/system/bt/types/Android.bp │ .bp
/tmp/bgraph_6p4534y2/android-10.0.0_r1/system/bt/types/bluetooth/uuid.cc │ .cc
/tmp/bgraph_6p4534y2/android-10.0.0_r1/system/bt/types/test/class_of_device_unittest.cc │ .cc
/tmp/bgraph_6p4534y2/android-10.0.0_r1/system/bt/types/raw_address.h │ .h
/tmp/bgraph_6p4534y2/android-10.0.0_r1/system/bt/types/class_of_device.cc │ .cc
╵
Note
This type of requests can leads to huge number of results and are not really suited for a command line usage.
For example, the result for the target query of libbluetooth
yields to more than 5700 lines of results.
Use as a library
BGraph
is also a library and can be used like one.
Note
All the examples can be runned as-if assuming you are at the root directory of the project and a bgraph for android-10.0.0_r1
is found in graphs/
.
Example
import bgraph
# Load the graph
graph = bgraph.viewer.load_graph("graphs/android-10.0.0_r1.bgraph")
# Query to find the source dependencies of libbluetooth
sources = bgraph.viewer.find_sources(graph, "libbluetooth")
for source in filter(lambda x: 'zlib' in x, sources):
print(f"Zlib file: {source}")
Format results
import bgraph
from bgraph.types import QueryType, OutChoice
# Load the graph
graph = bgraph.viewer.load_graph("graphs/android-10.0.0_r1.bgraph")
sources = bgraph.viewer.find_sources(graph, "libbluetooth")
bgraph.viewer.format_result(
graph, sources, query=QueryType.TARGET, query_value="libbluetooth", out_choice=OutChoice.DOT
)
Iterative process
In this example, we are looking for the first target using Parcel.cpp
. This will illustrate both the radius
argument of the find_target
method and what to do when multiple files matches the name we are looking for.
import bgraph
graph = bgraph.viewer.load_graph("graphs/android-10.0.0_r1.bgraph")
# Will raise an exception : TooManyNodes - refine the search
bgraph.viewer.find_target(graph, "Parcel.cpp", radius=1)
# Indeed, there are many sources files having "Parcel.cpp" in their name
graph_srcs = [node for node in graph if bgraph.viewer.get_node_type(node) == "source"]
potential_results = [node for node in graph_srcs if "Parcel.cpp" in node]
print(f"Found {len(potential_results)}/{len(graph_srcs)} matching nodes")
# In this case, it is possible to use a more precise path:
file, target = bgraph.viewer.find_target(graph, "libs/binder/Parcel.cpp", radius=1)
print(f"{file} is used in {target}")
# file in this case will be the absolute path to the Parcel.cpp found.