pcode-graph 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pcode_graph-1.0.0/.github/workflows/release.yml +32 -0
- pcode_graph-1.0.0/.gitignore +6 -0
- pcode_graph-1.0.0/LICENSE +21 -0
- pcode_graph-1.0.0/PKG-INFO +205 -0
- pcode_graph-1.0.0/README.md +177 -0
- pcode_graph-1.0.0/pcode_graph/__init__.py +0 -0
- pcode_graph-1.0.0/pcode_graph/__main__.py +3 -0
- pcode_graph-1.0.0/pcode_graph/analysis.py +395 -0
- pcode_graph-1.0.0/pcode_graph/arch.py +10 -0
- pcode_graph-1.0.0/pcode_graph/asm.py +60 -0
- pcode_graph-1.0.0/pcode_graph/charac.py +97 -0
- pcode_graph-1.0.0/pcode_graph/checker.py +120 -0
- pcode_graph-1.0.0/pcode_graph/cli.py +175 -0
- pcode_graph-1.0.0/pcode_graph/emulator.py +419 -0
- pcode_graph-1.0.0/pcode_graph/gnn_exporter.py +208 -0
- pcode_graph-1.0.0/pcode_graph/graph.py +234 -0
- pcode_graph-1.0.0/pcode_graph/lief_importer.py +299 -0
- pcode_graph-1.0.0/pcode_graph/log.py +36 -0
- pcode_graph-1.0.0/pcode_graph/maker.py +369 -0
- pcode_graph-1.0.0/pcode_graph/nx_exporter.py +20 -0
- pcode_graph-1.0.0/pcode_graph/pcode.py +187 -0
- pcode_graph-1.0.0/pcode_graph/registers.py +2929 -0
- pcode_graph-1.0.0/pcode_graph/simplifier.py +185 -0
- pcode_graph-1.0.0/pcode_graph/torch_utils.py +30 -0
- pcode_graph-1.0.0/pcode_graph/translator.py +235 -0
- pcode_graph-1.0.0/pcode_graph/utils.py +15 -0
- pcode_graph-1.0.0/pcode_graph/view.py +65 -0
- pcode_graph-1.0.0/pcode_graph/visitor.py +103 -0
- pcode_graph-1.0.0/pyproject.toml +48 -0
- pcode_graph-1.0.0/requirements.txt +12 -0
- pcode_graph-1.0.0/tests/__init__.py +0 -0
- pcode_graph-1.0.0/tests/analysis_test.py +395 -0
- pcode_graph-1.0.0/tests/charac_test.py +69 -0
- pcode_graph-1.0.0/tests/conftest.py +7 -0
- pcode_graph-1.0.0/tests/emulator_test.py +27 -0
- pcode_graph-1.0.0/tests/exporter_test.py +68 -0
- pcode_graph-1.0.0/tests/fixtures.py +70 -0
- pcode_graph-1.0.0/tests/helpers.py +100 -0
- pcode_graph-1.0.0/tests/maker_test.py +1156 -0
- pcode_graph-1.0.0/tests/translator_test.py +194 -0
- pcode_graph-1.0.0/tests/utils_test.py +54 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
tags: ["v*"]
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
build:
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
steps:
|
|
10
|
+
- uses: actions/checkout@v4
|
|
11
|
+
- uses: actions/setup-python@v5
|
|
12
|
+
with:
|
|
13
|
+
python-version: "3.12"
|
|
14
|
+
- run: pip install build
|
|
15
|
+
- run: python -m build
|
|
16
|
+
- uses: actions/upload-artifact@v4
|
|
17
|
+
with:
|
|
18
|
+
name: dist
|
|
19
|
+
path: dist/
|
|
20
|
+
|
|
21
|
+
publish:
|
|
22
|
+
needs: build
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
environment: pypi
|
|
25
|
+
permissions:
|
|
26
|
+
id-token: write
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/download-artifact@v4
|
|
29
|
+
with:
|
|
30
|
+
name: dist
|
|
31
|
+
path: dist/
|
|
32
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Quarkslab
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pcode_graph
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Build, display and vectorize semantic graphs from binary code
|
|
5
|
+
Project-URL: Homepage, https://github.com/quarkslab/pcode_graph
|
|
6
|
+
Project-URL: Issues, https://github.com/quarkslab/pcode_graph/issues
|
|
7
|
+
Author-email: Samuel Hangouët <samuel.hangouet@quarkslab.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Topic :: Security
|
|
13
|
+
Requires-Python: >=3.12
|
|
14
|
+
Requires-Dist: docopt
|
|
15
|
+
Requires-Dist: keystone-engine~=0.9.2
|
|
16
|
+
Requires-Dist: lief~=1.0.0
|
|
17
|
+
Requires-Dist: loguru
|
|
18
|
+
Requires-Dist: magika
|
|
19
|
+
Requires-Dist: pypcode>=4.0.0
|
|
20
|
+
Requires-Dist: pyvis
|
|
21
|
+
Provides-Extra: test
|
|
22
|
+
Requires-Dist: pytest; extra == 'test'
|
|
23
|
+
Requires-Dist: pytest-timeout; extra == 'test'
|
|
24
|
+
Provides-Extra: torch
|
|
25
|
+
Requires-Dist: torch-geometric~=2.8.0; extra == 'torch'
|
|
26
|
+
Requires-Dist: torch~=2.13.0; extra == 'torch'
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# P-Code Graph
|
|
30
|
+
|
|
31
|
+
This library helps to build, display and vectorize the Control-Data Graph (CDG) of a
|
|
32
|
+
chunk of binary code, using Ghidra P-Code representation.
|
|
33
|
+
|
|
34
|
+
## Command-line interface
|
|
35
|
+
|
|
36
|
+
A `cdg` tool is provided to play with binary of assembly files.
|
|
37
|
+
|
|
38
|
+
For example to dump the CDG of a function in markdown format:
|
|
39
|
+
|
|
40
|
+
```console
|
|
41
|
+
(venv) $ cdg mermaid test.o -f func -o graph.md
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Or to display the graph of the whole content of an assembly file in HTML:
|
|
45
|
+
|
|
46
|
+
```console
|
|
47
|
+
(venv) $ cdg html test.asm -o graph.html
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Tests
|
|
51
|
+
|
|
52
|
+
### Run tests
|
|
53
|
+
|
|
54
|
+
```console
|
|
55
|
+
$ python3.14 -m venv venv
|
|
56
|
+
$ source venv/bin/activate
|
|
57
|
+
(venv) $ pip install .[test,torch]
|
|
58
|
+
(venv) $ python -m pytest tests
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Test output
|
|
62
|
+
|
|
63
|
+
Tests using the `outdir` fixture generate their files in a dedicated output
|
|
64
|
+
directory, in which you can usually find:
|
|
65
|
+
|
|
66
|
+
- the log file
|
|
67
|
+
- the dump of P-Code operations
|
|
68
|
+
- the dump of generated graph in markdown+mermaid format
|
|
69
|
+
- a HTML file to display the related graph in a browser
|
|
70
|
+
|
|
71
|
+
You can display the dataflow graph resulting from a test in its output directory:
|
|
72
|
+
|
|
73
|
+
```console
|
|
74
|
+
$ firefox out/tests/maker_test/test_call/graph.html
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## API
|
|
78
|
+
|
|
79
|
+
### Graph representation
|
|
80
|
+
|
|
81
|
+
The `graph.py` module contains the data classes defining a CDG.
|
|
82
|
+
|
|
83
|
+
```mermaid
|
|
84
|
+
classDiagram
|
|
85
|
+
Graph *-- Node : nodes
|
|
86
|
+
Graph *-- Edge : edges
|
|
87
|
+
Graph: +list[Node] nodes
|
|
88
|
+
Graph: +list[Edge] edges
|
|
89
|
+
|
|
90
|
+
Node: +NodeKinds kind
|
|
91
|
+
Node: +int size
|
|
92
|
+
Node: +int value
|
|
93
|
+
Node: +int register_id
|
|
94
|
+
Node: +str register_name
|
|
95
|
+
Node: +OpCodes opcode
|
|
96
|
+
|
|
97
|
+
Edge: +EdgeKinds kind
|
|
98
|
+
Edge: +int source_node
|
|
99
|
+
Edge: +int destination_node
|
|
100
|
+
Edge: +Optional[int] operand_number
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Build a graph
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
We use LIEF library as a default binary loader. To build a graph from binary code:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from pcode_graph.maker import make_graph_from_binary
|
|
110
|
+
from pcode_graph.pcode import Translator
|
|
111
|
+
from pcode_graph.arch import Arch
|
|
112
|
+
from pcode_graph.lief_importer import iter_functions
|
|
113
|
+
|
|
114
|
+
translator = Translator(Arch.x86_64)
|
|
115
|
+
|
|
116
|
+
for function in iter_functions(Path("a.out")):
|
|
117
|
+
graph = make_graph_from_binary(translator,
|
|
118
|
+
function.content,
|
|
119
|
+
function.address,
|
|
120
|
+
ignore_flag_outputs=True)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Note that you can alternatively collect basic blocks (see lief_importer.py module), or use your own loader and make a graph from an arbitrary piece of binary code.
|
|
124
|
+
|
|
125
|
+
For testing purpose, you can also build it from assembly:
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
from pcode_graph.maker import make_graph_from_asm
|
|
129
|
+
from pcode_graph.asm import Assembler
|
|
130
|
+
from pcode_graph.pcode import Translator
|
|
131
|
+
from pcode_graph.arch import Arch
|
|
132
|
+
|
|
133
|
+
translator = Translator(Arch.arm_64)
|
|
134
|
+
assembler = Assembler(Arch.arm_64)
|
|
135
|
+
asm = """
|
|
136
|
+
add x0, x1, x2
|
|
137
|
+
blr x16
|
|
138
|
+
mul x1, x0, x0
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
graph = make_graph_from_asm(assembler, translator, asm)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### View the graph
|
|
145
|
+
|
|
146
|
+
You can unparse the graph into markdown using the mermaid syntax:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
with open("graph.md", "w") as f:
|
|
150
|
+
f.write(str(graph))
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The module `pcode_graph.view` wraps the `pyvis` library to display graphs in a browser:
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
from pcode_graph.view import draw_graph
|
|
157
|
+
|
|
158
|
+
draw_graph(graph, "out/graph.html", open_browser=True)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Vectorize the graph
|
|
162
|
+
|
|
163
|
+
To convert a graph to tensors, you will need the list of the registers
|
|
164
|
+
you expect your model to know, in order to convert the references to
|
|
165
|
+
these registers into tensors.
|
|
166
|
+
|
|
167
|
+
If you know in advance a list of interesting registers, the `map_registers` function will create a `dict` that maps these registers and their alias to an hot-encoded vector:
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
from pcode_graph.gnn_exporter import map_registers
|
|
171
|
+
|
|
172
|
+
reg_map = map_registers("rsp", "rax", "rbx", "rsi", "rdi")
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Then you can export your graph to a GNN as a torch_geometric Data object:
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
data = graph_to_data(graph, reg_map)
|
|
179
|
+
assert data.x is not None
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
If you want to help your GNN to deal with different architectures, a helper is provided to encode registers as a mask, depending on their role regarding the calling convention:
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
from pcode_graph.gnn_exporter import map_calling_convention_registers
|
|
186
|
+
|
|
187
|
+
reg_map = map_registers(Arch.x86_64)
|
|
188
|
+
print(reg_map)
|
|
189
|
+
{'rax': tensor([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
|
|
190
|
+
'rdx': tensor([0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
|
|
191
|
+
'rdi': tensor([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
|
|
192
|
+
'rsi': tensor([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
|
|
193
|
+
...
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Many options are provided by the `graph_to_data` function depending on how you want to export graph information into node and edges features. Look at the function documentation for more details.
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
### Converting into networkx
|
|
200
|
+
|
|
201
|
+
In case you want to apply some classical graph-theory algorithms, you can use `export_to_networkx` from `nx_exporter` module:
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
def export_to_networkx(graph: CDG, ignore_cfg: bool) -> nx.MultiDiGraph: ...
|
|
205
|
+
```
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# P-Code Graph
|
|
2
|
+
|
|
3
|
+
This library helps to build, display and vectorize the Control-Data Graph (CDG) of a
|
|
4
|
+
chunk of binary code, using Ghidra P-Code representation.
|
|
5
|
+
|
|
6
|
+
## Command-line interface
|
|
7
|
+
|
|
8
|
+
A `cdg` tool is provided to play with binary of assembly files.
|
|
9
|
+
|
|
10
|
+
For example to dump the CDG of a function in markdown format:
|
|
11
|
+
|
|
12
|
+
```console
|
|
13
|
+
(venv) $ cdg mermaid test.o -f func -o graph.md
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Or to display the graph of the whole content of an assembly file in HTML:
|
|
17
|
+
|
|
18
|
+
```console
|
|
19
|
+
(venv) $ cdg html test.asm -o graph.html
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Tests
|
|
23
|
+
|
|
24
|
+
### Run tests
|
|
25
|
+
|
|
26
|
+
```console
|
|
27
|
+
$ python3.14 -m venv venv
|
|
28
|
+
$ source venv/bin/activate
|
|
29
|
+
(venv) $ pip install .[test,torch]
|
|
30
|
+
(venv) $ python -m pytest tests
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Test output
|
|
34
|
+
|
|
35
|
+
Tests using the `outdir` fixture generate their files in a dedicated output
|
|
36
|
+
directory, in which you can usually find:
|
|
37
|
+
|
|
38
|
+
- the log file
|
|
39
|
+
- the dump of P-Code operations
|
|
40
|
+
- the dump of generated graph in markdown+mermaid format
|
|
41
|
+
- a HTML file to display the related graph in a browser
|
|
42
|
+
|
|
43
|
+
You can display the dataflow graph resulting from a test in its output directory:
|
|
44
|
+
|
|
45
|
+
```console
|
|
46
|
+
$ firefox out/tests/maker_test/test_call/graph.html
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## API
|
|
50
|
+
|
|
51
|
+
### Graph representation
|
|
52
|
+
|
|
53
|
+
The `graph.py` module contains the data classes defining a CDG.
|
|
54
|
+
|
|
55
|
+
```mermaid
|
|
56
|
+
classDiagram
|
|
57
|
+
Graph *-- Node : nodes
|
|
58
|
+
Graph *-- Edge : edges
|
|
59
|
+
Graph: +list[Node] nodes
|
|
60
|
+
Graph: +list[Edge] edges
|
|
61
|
+
|
|
62
|
+
Node: +NodeKinds kind
|
|
63
|
+
Node: +int size
|
|
64
|
+
Node: +int value
|
|
65
|
+
Node: +int register_id
|
|
66
|
+
Node: +str register_name
|
|
67
|
+
Node: +OpCodes opcode
|
|
68
|
+
|
|
69
|
+
Edge: +EdgeKinds kind
|
|
70
|
+
Edge: +int source_node
|
|
71
|
+
Edge: +int destination_node
|
|
72
|
+
Edge: +Optional[int] operand_number
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Build a graph
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
We use LIEF library as a default binary loader. To build a graph from binary code:
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
from pcode_graph.maker import make_graph_from_binary
|
|
82
|
+
from pcode_graph.pcode import Translator
|
|
83
|
+
from pcode_graph.arch import Arch
|
|
84
|
+
from pcode_graph.lief_importer import iter_functions
|
|
85
|
+
|
|
86
|
+
translator = Translator(Arch.x86_64)
|
|
87
|
+
|
|
88
|
+
for function in iter_functions(Path("a.out")):
|
|
89
|
+
graph = make_graph_from_binary(translator,
|
|
90
|
+
function.content,
|
|
91
|
+
function.address,
|
|
92
|
+
ignore_flag_outputs=True)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Note that you can alternatively collect basic blocks (see lief_importer.py module), or use your own loader and make a graph from an arbitrary piece of binary code.
|
|
96
|
+
|
|
97
|
+
For testing purpose, you can also build it from assembly:
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
from pcode_graph.maker import make_graph_from_asm
|
|
101
|
+
from pcode_graph.asm import Assembler
|
|
102
|
+
from pcode_graph.pcode import Translator
|
|
103
|
+
from pcode_graph.arch import Arch
|
|
104
|
+
|
|
105
|
+
translator = Translator(Arch.arm_64)
|
|
106
|
+
assembler = Assembler(Arch.arm_64)
|
|
107
|
+
asm = """
|
|
108
|
+
add x0, x1, x2
|
|
109
|
+
blr x16
|
|
110
|
+
mul x1, x0, x0
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
graph = make_graph_from_asm(assembler, translator, asm)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### View the graph
|
|
117
|
+
|
|
118
|
+
You can unparse the graph into markdown using the mermaid syntax:
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
with open("graph.md", "w") as f:
|
|
122
|
+
f.write(str(graph))
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The module `pcode_graph.view` wraps the `pyvis` library to display graphs in a browser:
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
from pcode_graph.view import draw_graph
|
|
129
|
+
|
|
130
|
+
draw_graph(graph, "out/graph.html", open_browser=True)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Vectorize the graph
|
|
134
|
+
|
|
135
|
+
To convert a graph to tensors, you will need the list of the registers
|
|
136
|
+
you expect your model to know, in order to convert the references to
|
|
137
|
+
these registers into tensors.
|
|
138
|
+
|
|
139
|
+
If you know in advance a list of interesting registers, the `map_registers` function will create a `dict` that maps these registers and their alias to an hot-encoded vector:
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from pcode_graph.gnn_exporter import map_registers
|
|
143
|
+
|
|
144
|
+
reg_map = map_registers("rsp", "rax", "rbx", "rsi", "rdi")
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Then you can export your graph to a GNN as a torch_geometric Data object:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
data = graph_to_data(graph, reg_map)
|
|
151
|
+
assert data.x is not None
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
If you want to help your GNN to deal with different architectures, a helper is provided to encode registers as a mask, depending on their role regarding the calling convention:
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
from pcode_graph.gnn_exporter import map_calling_convention_registers
|
|
158
|
+
|
|
159
|
+
reg_map = map_registers(Arch.x86_64)
|
|
160
|
+
print(reg_map)
|
|
161
|
+
{'rax': tensor([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
|
|
162
|
+
'rdx': tensor([0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
|
|
163
|
+
'rdi': tensor([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
|
|
164
|
+
'rsi': tensor([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
|
|
165
|
+
...
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Many options are provided by the `graph_to_data` function depending on how you want to export graph information into node and edges features. Look at the function documentation for more details.
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
### Converting into networkx
|
|
172
|
+
|
|
173
|
+
In case you want to apply some classical graph-theory algorithms, you can use `export_to_networkx` from `nx_exporter` module:
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
def export_to_networkx(graph: CDG, ignore_cfg: bool) -> nx.MultiDiGraph: ...
|
|
177
|
+
```
|
|
File without changes
|