python-lancelot 0.9.9__cp313-cp313-win_arm64.whl
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.
- lancelot/__init__.py +14 -0
- lancelot/_lib.cp313-win_arm64.pyd +0 -0
- lancelot/be2utils/__init__.py +340 -0
- lancelot/be2utils/binexport2_pb2.py +73 -0
- lancelot/be2utils/binexport2_pb2.pyi +1128 -0
- python_lancelot-0.9.9.dist-info/METADATA +50 -0
- python_lancelot-0.9.9.dist-info/RECORD +9 -0
- python_lancelot-0.9.9.dist-info/WHEEL +4 -0
- python_lancelot-0.9.9.dist-info/licenses/LICENSE.txt +202 -0
lancelot/__init__.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from ._lib import binexport2_from_bytes as _binexport2_bytes_from_bytes
|
|
2
|
+
from .be2utils.binexport2_pb2 import BinExport2
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def get_binexport2_bytes_from_bytes(buf: bytes, sig_paths=None, function_hints=None) -> bytes:
|
|
6
|
+
"""Get the Lancelot workspace as a BinExport2-encoded buffer"""
|
|
7
|
+
return _binexport2_bytes_from_bytes(buf, sig_paths=sig_paths, function_hints=function_hints)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_binexport2_from_bytes(buf: bytes, sig_paths=None, function_hints=None) -> BinExport2:
|
|
11
|
+
"""Get the Lancelot workspace as a BinExport2 instance"""
|
|
12
|
+
be2: BinExport2 = BinExport2()
|
|
13
|
+
be2.ParseFromString(get_binexport2_bytes_from_bytes(buf, sig_paths=sig_paths, function_hints=function_hints))
|
|
14
|
+
return be2
|
|
Binary file
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Proto files generated via protobuf v24.4:
|
|
3
|
+
|
|
4
|
+
protoc --python_out=. --mypy_out=. binexport2.proto
|
|
5
|
+
|
|
6
|
+
from BinExport2 at 6916731d5f6693c4a4f0a052501fd3bd92cfd08b
|
|
7
|
+
https://github.com/google/binexport/blob/6916731/binexport2.proto
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import io
|
|
11
|
+
import logging
|
|
12
|
+
from collections.abc import Iterator
|
|
13
|
+
from collections import defaultdict
|
|
14
|
+
from dataclasses import dataclass
|
|
15
|
+
|
|
16
|
+
from pefile import PE
|
|
17
|
+
from elftools.elf.elffile import ELFFile
|
|
18
|
+
from lancelot.be2utils.binexport2_pb2 import BinExport2
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def is_vertex_type(vertex: BinExport2.CallGraph.Vertex, type_: BinExport2.CallGraph.Vertex.Type.ValueType) -> bool:
|
|
24
|
+
return vertex.HasField("type") and vertex.type == type_
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def is_thunk_vertex(vertex: BinExport2.CallGraph.Vertex) -> bool:
|
|
28
|
+
return is_vertex_type(vertex, BinExport2.CallGraph.Vertex.Type.THUNK)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
THUNK_CHAIN_DEPTH_DELTA = 5
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class BinExport2Index:
|
|
35
|
+
def __init__(self, be2: BinExport2):
|
|
36
|
+
self.be2: BinExport2 = be2
|
|
37
|
+
|
|
38
|
+
self.callers_by_vertex_index: dict[int, list[int]] = defaultdict(list)
|
|
39
|
+
self.callees_by_vertex_index: dict[int, list[int]] = defaultdict(list)
|
|
40
|
+
|
|
41
|
+
# note: flow graph != call graph (vertex)
|
|
42
|
+
self.flow_graph_index_by_address: dict[int, int] = {}
|
|
43
|
+
self.flow_graph_address_by_index: dict[int, int] = {}
|
|
44
|
+
|
|
45
|
+
# edges that come from the given basic block
|
|
46
|
+
self.source_edges_by_basic_block_index: dict[int, list[BinExport2.FlowGraph.Edge]] = defaultdict(list)
|
|
47
|
+
# edges that end up at the given basic block
|
|
48
|
+
self.target_edges_by_basic_block_index: dict[int, list[BinExport2.FlowGraph.Edge]] = defaultdict(list)
|
|
49
|
+
|
|
50
|
+
self.vertex_index_by_address: dict[int, int] = {}
|
|
51
|
+
|
|
52
|
+
self.data_reference_index_by_source_instruction_index: dict[int, list[int]] = defaultdict(list)
|
|
53
|
+
self.data_reference_index_by_target_address: dict[int, list[int]] = defaultdict(list)
|
|
54
|
+
self.string_reference_index_by_source_instruction_index: dict[int, list[int]] = defaultdict(list)
|
|
55
|
+
|
|
56
|
+
self.insn_address_by_index: dict[int, int] = {}
|
|
57
|
+
self.insn_index_by_address: dict[int, int] = {}
|
|
58
|
+
self.insn_by_address: dict[int, BinExport2.Instruction] = {}
|
|
59
|
+
|
|
60
|
+
# from thunk address to target function address
|
|
61
|
+
self.thunks: dict[int, int] = {}
|
|
62
|
+
|
|
63
|
+
# must index instructions first
|
|
64
|
+
self._index_insn_addresses()
|
|
65
|
+
self._index_vertex_edges()
|
|
66
|
+
self._index_flow_graph_nodes()
|
|
67
|
+
self._index_flow_graph_edges()
|
|
68
|
+
self._index_call_graph_vertices()
|
|
69
|
+
self._index_data_references()
|
|
70
|
+
self._index_string_references()
|
|
71
|
+
self._index_thunks()
|
|
72
|
+
|
|
73
|
+
def get_insn_address(self, insn_index: int) -> int:
|
|
74
|
+
assert insn_index in self.insn_address_by_index, f"insn must be indexed, missing {insn_index}"
|
|
75
|
+
return self.insn_address_by_index[insn_index]
|
|
76
|
+
|
|
77
|
+
def get_basic_block_address(self, basic_block_index: int) -> int:
|
|
78
|
+
basic_block: BinExport2.BasicBlock = self.be2.basic_block[basic_block_index]
|
|
79
|
+
first_instruction_index: int = next(self.instruction_indices(basic_block))
|
|
80
|
+
return self.get_insn_address(first_instruction_index)
|
|
81
|
+
|
|
82
|
+
def _index_vertex_edges(self):
|
|
83
|
+
for edge in self.be2.call_graph.edge:
|
|
84
|
+
self.callers_by_vertex_index[edge.target_vertex_index].append(edge.source_vertex_index)
|
|
85
|
+
self.callees_by_vertex_index[edge.source_vertex_index].append(edge.target_vertex_index)
|
|
86
|
+
|
|
87
|
+
def _index_flow_graph_nodes(self):
|
|
88
|
+
for flow_graph_index, flow_graph in enumerate(self.be2.flow_graph):
|
|
89
|
+
function_address: int = self.get_basic_block_address(flow_graph.entry_basic_block_index)
|
|
90
|
+
self.flow_graph_index_by_address[function_address] = flow_graph_index
|
|
91
|
+
self.flow_graph_address_by_index[flow_graph_index] = function_address
|
|
92
|
+
|
|
93
|
+
def _index_flow_graph_edges(self):
|
|
94
|
+
for flow_graph in self.be2.flow_graph:
|
|
95
|
+
for edge in flow_graph.edge:
|
|
96
|
+
if not edge.HasField("source_basic_block_index") or not edge.HasField("target_basic_block_index"):
|
|
97
|
+
continue
|
|
98
|
+
|
|
99
|
+
self.source_edges_by_basic_block_index[edge.source_basic_block_index].append(edge)
|
|
100
|
+
self.target_edges_by_basic_block_index[edge.target_basic_block_index].append(edge)
|
|
101
|
+
|
|
102
|
+
def _index_call_graph_vertices(self):
|
|
103
|
+
for vertex_index, vertex in enumerate(self.be2.call_graph.vertex):
|
|
104
|
+
if not vertex.HasField("address"):
|
|
105
|
+
continue
|
|
106
|
+
|
|
107
|
+
vertex_address: int = vertex.address
|
|
108
|
+
self.vertex_index_by_address[vertex_address] = vertex_index
|
|
109
|
+
|
|
110
|
+
def _index_data_references(self):
|
|
111
|
+
for data_reference_index, data_reference in enumerate(self.be2.data_reference):
|
|
112
|
+
self.data_reference_index_by_source_instruction_index[data_reference.instruction_index].append(
|
|
113
|
+
data_reference_index
|
|
114
|
+
)
|
|
115
|
+
self.data_reference_index_by_target_address[data_reference.address].append(data_reference_index)
|
|
116
|
+
|
|
117
|
+
def _index_string_references(self):
|
|
118
|
+
for string_reference_index, string_reference in enumerate(self.be2.string_reference):
|
|
119
|
+
self.string_reference_index_by_source_instruction_index[string_reference.instruction_index].append(
|
|
120
|
+
string_reference_index
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
def _index_insn_addresses(self):
|
|
124
|
+
# see https://github.com/google/binexport/blob/39f6445c232bb5caf5c4a2a996de91dfa20c48e8/binexport.cc#L45
|
|
125
|
+
if len(self.be2.instruction) == 0:
|
|
126
|
+
return
|
|
127
|
+
|
|
128
|
+
assert self.be2.instruction[0].HasField("address"), "first insn must have explicit address"
|
|
129
|
+
|
|
130
|
+
addr: int = 0
|
|
131
|
+
next_addr: int = 0
|
|
132
|
+
for idx, insn in enumerate(self.be2.instruction):
|
|
133
|
+
if insn.HasField("address"):
|
|
134
|
+
addr = insn.address
|
|
135
|
+
next_addr = addr + len(insn.raw_bytes)
|
|
136
|
+
else:
|
|
137
|
+
addr = next_addr
|
|
138
|
+
next_addr += len(insn.raw_bytes)
|
|
139
|
+
self.insn_address_by_index[idx] = addr
|
|
140
|
+
self.insn_index_by_address[addr] = idx
|
|
141
|
+
self.insn_by_address[addr] = insn
|
|
142
|
+
|
|
143
|
+
def _index_thunks(self):
|
|
144
|
+
for addr, vertex_idx in self.vertex_index_by_address.items():
|
|
145
|
+
vertex: BinExport2.CallGraph.Vertex = self.be2.call_graph.vertex[vertex_idx]
|
|
146
|
+
|
|
147
|
+
if not is_thunk_vertex(vertex):
|
|
148
|
+
continue
|
|
149
|
+
|
|
150
|
+
curr_vertex_idx: int = vertex_idx
|
|
151
|
+
for _ in range(THUNK_CHAIN_DEPTH_DELTA):
|
|
152
|
+
thunk_callees: list[int] = self.callees_by_vertex_index[curr_vertex_idx]
|
|
153
|
+
# if this doesn't hold, then it doesn't seem like this is a thunk,
|
|
154
|
+
# because either, len is:
|
|
155
|
+
# 0 and the thunk doesn't point to anything, such as `jmp eax`, or
|
|
156
|
+
# >1 and the thunk may end up at many functions.
|
|
157
|
+
|
|
158
|
+
if not thunk_callees:
|
|
159
|
+
# maybe we have an indirect jump, like `jmp eax`
|
|
160
|
+
# that we can't actually resolve here.
|
|
161
|
+
break
|
|
162
|
+
|
|
163
|
+
assert len(thunk_callees) == 1, f"thunk @ {hex(addr)} failed"
|
|
164
|
+
|
|
165
|
+
thunked_vertex_idx: int = thunk_callees[0]
|
|
166
|
+
thunked_vertex: BinExport2.CallGraph.Vertex = self.be2.call_graph.vertex[thunked_vertex_idx]
|
|
167
|
+
|
|
168
|
+
if not is_thunk_vertex(thunked_vertex):
|
|
169
|
+
assert thunked_vertex.HasField("address")
|
|
170
|
+
|
|
171
|
+
self.thunks[addr] = thunked_vertex.address
|
|
172
|
+
break
|
|
173
|
+
|
|
174
|
+
curr_vertex_idx = thunked_vertex_idx
|
|
175
|
+
|
|
176
|
+
@staticmethod
|
|
177
|
+
def instruction_indices(basic_block: BinExport2.BasicBlock) -> Iterator[int]:
|
|
178
|
+
"""
|
|
179
|
+
For a given basic block, enumerate the instruction indices.
|
|
180
|
+
"""
|
|
181
|
+
for index_range in basic_block.instruction_index:
|
|
182
|
+
if not index_range.HasField("end_index"):
|
|
183
|
+
yield index_range.begin_index
|
|
184
|
+
continue
|
|
185
|
+
else:
|
|
186
|
+
yield from range(index_range.begin_index, index_range.end_index)
|
|
187
|
+
|
|
188
|
+
def basic_block_instructions(
|
|
189
|
+
self, basic_block: BinExport2.BasicBlock
|
|
190
|
+
) -> Iterator[tuple[int, BinExport2.Instruction, int]]:
|
|
191
|
+
"""
|
|
192
|
+
For a given basic block, enumerate the instruction indices,
|
|
193
|
+
the instruction instances, and their addresses.
|
|
194
|
+
"""
|
|
195
|
+
for instruction_index in self.instruction_indices(basic_block):
|
|
196
|
+
instruction: BinExport2.Instruction = self.be2.instruction[instruction_index]
|
|
197
|
+
instruction_address: int = self.get_insn_address(instruction_index)
|
|
198
|
+
|
|
199
|
+
yield instruction_index, instruction, instruction_address
|
|
200
|
+
|
|
201
|
+
def get_function_name_by_vertex(self, vertex_index: int) -> str:
|
|
202
|
+
vertex: BinExport2.CallGraph.Vertex = self.be2.call_graph.vertex[vertex_index]
|
|
203
|
+
name: str = f"sub_{vertex.address:x}"
|
|
204
|
+
|
|
205
|
+
if is_thunk_vertex(vertex):
|
|
206
|
+
if target := self.thunks.get(vertex.address):
|
|
207
|
+
target_name = self.get_function_name_by_address(target)
|
|
208
|
+
name = f"j_{target_name}"
|
|
209
|
+
|
|
210
|
+
if vertex.HasField("mangled_name") and not vertex.mangled_name.startswith("sub_"):
|
|
211
|
+
name = vertex.mangled_name
|
|
212
|
+
|
|
213
|
+
if vertex.HasField("demangled_name") and not vertex.demangled_name.startswith("sub_"):
|
|
214
|
+
name = vertex.demangled_name
|
|
215
|
+
|
|
216
|
+
if vertex.HasField("library_index"):
|
|
217
|
+
library: BinExport2.Library = self.be2.library[vertex.library_index]
|
|
218
|
+
if library.HasField("name"):
|
|
219
|
+
name = f"{library.name}!{name}"
|
|
220
|
+
|
|
221
|
+
return name
|
|
222
|
+
|
|
223
|
+
def get_function_name_by_address(self, address: int) -> str:
|
|
224
|
+
if address not in self.vertex_index_by_address:
|
|
225
|
+
return ""
|
|
226
|
+
|
|
227
|
+
vertex_index: int = self.vertex_index_by_address[address]
|
|
228
|
+
return self.get_function_name_by_vertex(vertex_index)
|
|
229
|
+
|
|
230
|
+
def get_instruction_by_address(self, address: int) -> BinExport2.Instruction:
|
|
231
|
+
assert address in self.insn_by_address, f"address must be indexed, missing {address:x}"
|
|
232
|
+
return self.insn_by_address[address]
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def find_be2_base_address(be2: BinExport2):
|
|
236
|
+
sections_with_perms: Iterator[BinExport2.Section] = filter(lambda s: s.flag_r or s.flag_w or s.flag_x, be2.section)
|
|
237
|
+
# assume the lowest address is the base address.
|
|
238
|
+
# this works as long as BinExport doesn't record other
|
|
239
|
+
# libraries mapped into memory.
|
|
240
|
+
return min(s.address for s in sections_with_perms)
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
@dataclass
|
|
244
|
+
class MemoryRegion:
|
|
245
|
+
# location of the bytes, potentially relative to a base address
|
|
246
|
+
address: int
|
|
247
|
+
buf: bytes
|
|
248
|
+
|
|
249
|
+
@property
|
|
250
|
+
def end(self) -> int:
|
|
251
|
+
return self.address + len(self.buf)
|
|
252
|
+
|
|
253
|
+
def contains(self, address: int) -> bool:
|
|
254
|
+
# note: address must be relative to any base address
|
|
255
|
+
return self.address <= address < self.end
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class ReadMemoryError(ValueError): ...
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
class AddressNotMappedError(ReadMemoryError): ...
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
@dataclass
|
|
265
|
+
class AddressSpace:
|
|
266
|
+
"""
|
|
267
|
+
Simple accessor to mapped executable files.
|
|
268
|
+
|
|
269
|
+
BinExport2 doesn't capture file bytes, but it does reference
|
|
270
|
+
bytes by virtual addresses. This class makes it easy to read
|
|
271
|
+
the data at those references.
|
|
272
|
+
|
|
273
|
+
Addresses are relative to the `base_address` field here,
|
|
274
|
+
so provide RVAs (not VAs). Use `find_be2_base_address` to
|
|
275
|
+
when working with BinExport2 instances to map a VA to an RVA.
|
|
276
|
+
"""
|
|
277
|
+
|
|
278
|
+
base_address: int
|
|
279
|
+
memory_regions: tuple[MemoryRegion, ...]
|
|
280
|
+
|
|
281
|
+
def read_memory(self, address: int, length: int) -> bytes:
|
|
282
|
+
rva: int = address - self.base_address
|
|
283
|
+
for region in self.memory_regions:
|
|
284
|
+
if region.contains(rva):
|
|
285
|
+
offset: int = rva - region.address
|
|
286
|
+
return region.buf[offset : offset + length]
|
|
287
|
+
|
|
288
|
+
raise AddressNotMappedError(address)
|
|
289
|
+
|
|
290
|
+
@classmethod
|
|
291
|
+
def from_pe(cls, pe: PE, base_address: int):
|
|
292
|
+
regions: list[MemoryRegion] = []
|
|
293
|
+
for section in pe.sections:
|
|
294
|
+
address: int = section.VirtualAddress
|
|
295
|
+
size: int = section.Misc_VirtualSize
|
|
296
|
+
buf: bytes = section.get_data()
|
|
297
|
+
|
|
298
|
+
if len(buf) != size:
|
|
299
|
+
# pad the section with NULLs
|
|
300
|
+
# assume page alignment is already handled.
|
|
301
|
+
# might need more hardening here.
|
|
302
|
+
buf += b"\x00" * (size - len(buf))
|
|
303
|
+
|
|
304
|
+
regions.append(MemoryRegion(address, buf))
|
|
305
|
+
|
|
306
|
+
return cls(base_address, tuple(regions))
|
|
307
|
+
|
|
308
|
+
@classmethod
|
|
309
|
+
def from_elf(cls, elf: ELFFile, base_address: int):
|
|
310
|
+
regions: list[MemoryRegion] = []
|
|
311
|
+
|
|
312
|
+
# ELF segments are for runtime data,
|
|
313
|
+
# ELF sections are for link-time data.
|
|
314
|
+
for segment in elf.iter_segments():
|
|
315
|
+
# assume p_align is consistent with addresses here.
|
|
316
|
+
# otherwise, should harden this loader.
|
|
317
|
+
segment_rva: int = segment.header.p_vaddr
|
|
318
|
+
segment_size: int = segment.header.p_memsz
|
|
319
|
+
segment_data: bytes = segment.data()
|
|
320
|
+
|
|
321
|
+
if len(segment_data) < segment_size:
|
|
322
|
+
# pad the section with NULLs
|
|
323
|
+
# assume page alignment is already handled.
|
|
324
|
+
# might need more hardening here.
|
|
325
|
+
segment_data += b"\x00" * (segment_size - len(segment_data))
|
|
326
|
+
|
|
327
|
+
regions.append(MemoryRegion(segment_rva, segment_data))
|
|
328
|
+
|
|
329
|
+
return cls(base_address, tuple(regions))
|
|
330
|
+
|
|
331
|
+
@classmethod
|
|
332
|
+
def from_buf(cls, buf: bytes, base_address: int):
|
|
333
|
+
if buf.startswith(b"MZ"):
|
|
334
|
+
pe: PE = PE(data=buf)
|
|
335
|
+
return cls.from_pe(pe, base_address)
|
|
336
|
+
elif buf.startswith(b"\x7fELF"):
|
|
337
|
+
elf: ELFFile = ELFFile(io.BytesIO(buf))
|
|
338
|
+
return cls.from_elf(elf, base_address)
|
|
339
|
+
else:
|
|
340
|
+
raise NotImplementedError("file format address space")
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# source: binexport2.proto
|
|
4
|
+
"""Generated protocol buffer code."""
|
|
5
|
+
from google.protobuf import descriptor as _descriptor
|
|
6
|
+
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
7
|
+
from google.protobuf import symbol_database as _symbol_database
|
|
8
|
+
from google.protobuf.internal import builder as _builder
|
|
9
|
+
|
|
10
|
+
# @@protoc_insertion_point(imports)
|
|
11
|
+
|
|
12
|
+
_sym_db = _symbol_database.Default()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(
|
|
16
|
+
b'\n\x10\x62inexport2.proto"\xa5\x17\n\nBinExport2\x12*\n\x10meta_information\x18\x01 \x01(\x0b\x32\x10.BinExport2.Meta\x12*\n\nexpression\x18\x02 \x03(\x0b\x32\x16.BinExport2.Expression\x12$\n\x07operand\x18\x03 \x03(\x0b\x32\x13.BinExport2.Operand\x12&\n\x08mnemonic\x18\x04 \x03(\x0b\x32\x14.BinExport2.Mnemonic\x12,\n\x0binstruction\x18\x05 \x03(\x0b\x32\x17.BinExport2.Instruction\x12+\n\x0b\x62\x61sic_block\x18\x06 \x03(\x0b\x32\x16.BinExport2.BasicBlock\x12)\n\nflow_graph\x18\x07 \x03(\x0b\x32\x15.BinExport2.FlowGraph\x12)\n\ncall_graph\x18\x08 \x01(\x0b\x32\x15.BinExport2.CallGraph\x12\x14\n\x0cstring_table\x18\t \x03(\t\x12\x32\n\x0f\x61\x64\x64ress_comment\x18\n \x03(\x0b\x32\x15.BinExport2.ReferenceB\x02\x18\x01\x12$\n\x07\x63omment\x18\x11 \x03(\x0b\x32\x13.BinExport2.Comment\x12/\n\x10string_reference\x18\x0b \x03(\x0b\x32\x15.BinExport2.Reference\x12\x36\n\x17\x65xpression_substitution\x18\x0c \x03(\x0b\x32\x15.BinExport2.Reference\x12$\n\x07section\x18\r \x03(\x0b\x32\x13.BinExport2.Section\x12$\n\x07library\x18\x0e \x03(\x0b\x32\x13.BinExport2.Library\x12\x31\n\x0e\x64\x61ta_reference\x18\x0f \x03(\x0b\x32\x19.BinExport2.DataReference\x12"\n\x06module\x18\x10 \x03(\x0b\x32\x12.BinExport2.Module\x1aj\n\x04Meta\x12\x17\n\x0f\x65xecutable_name\x18\x01 \x01(\t\x12\x15\n\rexecutable_id\x18\x02 \x01(\t\x12\x19\n\x11\x61rchitecture_name\x18\x03 \x01(\t\x12\x11\n\ttimestamp\x18\x04 \x01(\x03J\x04\x08\x05\x10\x06\x1a\x9c\x03\n\tCallGraph\x12,\n\x06vertex\x18\x01 \x03(\x0b\x32\x1c.BinExport2.CallGraph.Vertex\x12(\n\x04\x65\x64ge\x18\x02 \x03(\x0b\x32\x1a.BinExport2.CallGraph.Edge\x1a\xf4\x01\n\x06Vertex\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\x04\x12\x37\n\x04type\x18\x02 \x01(\x0e\x32!.BinExport2.CallGraph.Vertex.Type:\x06NORMAL\x12\x14\n\x0cmangled_name\x18\x03 \x01(\t\x12\x16\n\x0e\x64\x65mangled_name\x18\x04 \x01(\t\x12\x15\n\rlibrary_index\x18\x05 \x01(\x05\x12\x14\n\x0cmodule_index\x18\x06 \x01(\x05"E\n\x04Type\x12\n\n\x06NORMAL\x10\x00\x12\x0b\n\x07LIBRARY\x10\x01\x12\x0c\n\x08IMPORTED\x10\x02\x12\t\n\x05THUNK\x10\x03\x12\x0b\n\x07INVALID\x10\x04\x1a@\n\x04\x45\x64ge\x12\x1b\n\x13source_vertex_index\x18\x01 \x01(\x05\x12\x1b\n\x13target_vertex_index\x18\x02 \x01(\x05\x1a\x90\x02\n\nExpression\x12\x38\n\x04type\x18\x01 \x01(\x0e\x32\x1b.BinExport2.Expression.Type:\rIMMEDIATE_INT\x12\x0e\n\x06symbol\x18\x02 \x01(\t\x12\x11\n\timmediate\x18\x03 \x01(\x04\x12\x14\n\x0cparent_index\x18\x04 \x01(\x05\x12\x15\n\ris_relocation\x18\x05 \x01(\x08"x\n\x04Type\x12\n\n\x06SYMBOL\x10\x01\x12\x11\n\rIMMEDIATE_INT\x10\x02\x12\x13\n\x0fIMMEDIATE_FLOAT\x10\x03\x12\x0c\n\x08OPERATOR\x10\x04\x12\x0c\n\x08REGISTER\x10\x05\x12\x0f\n\x0bSIZE_PREFIX\x10\x06\x12\x0f\n\x0b\x44\x45REFERENCE\x10\x07\x1a#\n\x07Operand\x12\x18\n\x10\x65xpression_index\x18\x01 \x03(\x05\x1a\x18\n\x08Mnemonic\x12\x0c\n\x04name\x18\x01 \x01(\t\x1a\x8f\x01\n\x0bInstruction\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\x04\x12\x13\n\x0b\x63\x61ll_target\x18\x02 \x03(\x04\x12\x19\n\x0emnemonic_index\x18\x03 \x01(\x05:\x01\x30\x12\x15\n\roperand_index\x18\x04 \x03(\x05\x12\x11\n\traw_bytes\x18\x05 \x01(\x0c\x12\x15\n\rcomment_index\x18\x06 \x03(\x05\x1a\x80\x01\n\nBasicBlock\x12<\n\x11instruction_index\x18\x01 \x03(\x0b\x32!.BinExport2.BasicBlock.IndexRange\x1a\x34\n\nIndexRange\x12\x13\n\x0b\x62\x65gin_index\x18\x01 \x01(\x05\x12\x11\n\tend_index\x18\x02 \x01(\x05\x1a\xe9\x02\n\tFlowGraph\x12\x19\n\x11\x62\x61sic_block_index\x18\x01 \x03(\x05\x12\x1f\n\x17\x65ntry_basic_block_index\x18\x03 \x01(\x05\x12(\n\x04\x65\x64ge\x18\x02 \x03(\x0b\x32\x1a.BinExport2.FlowGraph.Edge\x1a\xf5\x01\n\x04\x45\x64ge\x12 \n\x18source_basic_block_index\x18\x01 \x01(\x05\x12 \n\x18target_basic_block_index\x18\x02 \x01(\x05\x12<\n\x04type\x18\x03 \x01(\x0e\x32\x1f.BinExport2.FlowGraph.Edge.Type:\rUNCONDITIONAL\x12\x1b\n\x0cis_back_edge\x18\x04 \x01(\x08:\x05\x66\x61lse"N\n\x04Type\x12\x12\n\x0e\x43ONDITION_TRUE\x10\x01\x12\x13\n\x0f\x43ONDITION_FALSE\x10\x02\x12\x11\n\rUNCONDITIONAL\x10\x03\x12\n\n\x06SWITCH\x10\x04\x1a\x8d\x01\n\tReference\x12\x19\n\x11instruction_index\x18\x01 \x01(\x05\x12$\n\x19instruction_operand_index\x18\x02 \x01(\x05:\x01\x30\x12#\n\x18operand_expression_index\x18\x03 \x01(\x05:\x01\x30\x12\x1a\n\x12string_table_index\x18\x04 \x01(\x05\x1a;\n\rDataReference\x12\x19\n\x11instruction_index\x18\x01 \x01(\x05\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\x04\x1a\xd4\x02\n\x07\x43omment\x12\x19\n\x11instruction_index\x18\x01 \x01(\x05\x12$\n\x19instruction_operand_index\x18\x02 \x01(\x05:\x01\x30\x12#\n\x18operand_expression_index\x18\x03 \x01(\x05:\x01\x30\x12\x1a\n\x12string_table_index\x18\x04 \x01(\x05\x12\x12\n\nrepeatable\x18\x05 \x01(\x08\x12/\n\x04type\x18\x06 \x01(\x0e\x32\x18.BinExport2.Comment.Type:\x07\x44\x45\x46\x41ULT"\x81\x01\n\x04Type\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08\x41NTERIOR\x10\x01\x12\r\n\tPOSTERIOR\x10\x02\x12\x0c\n\x08\x46UNCTION\x10\x03\x12\x08\n\x04\x45NUM\x10\x04\x12\x0c\n\x08LOCATION\x10\x05\x12\x14\n\x10GLOBAL_REFERENCE\x10\x06\x12\x13\n\x0fLOCAL_REFERENCE\x10\x07\x1aX\n\x07Section\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\x04\x12\x0c\n\x04size\x18\x02 \x01(\x04\x12\x0e\n\x06\x66lag_r\x18\x03 \x01(\x08\x12\x0e\n\x06\x66lag_w\x18\x04 \x01(\x08\x12\x0e\n\x06\x66lag_x\x18\x05 \x01(\x08\x1a\x43\n\x07Library\x12\x11\n\tis_static\x18\x01 \x01(\x08\x12\x17\n\x0cload_address\x18\x02 \x01(\x04:\x01\x30\x12\x0c\n\x04name\x18\x03 \x01(\t\x1a\x16\n\x06Module\x12\x0c\n\x04name\x18\x01 \x01(\t*\x0b\x08\x80\xc2\xd7/\x10\x80\x80\x80\x80\x02\x42)\n\x1c\x63om.google.security.zynamicsB\tBinExport'
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
|
20
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "binexport2_pb2", globals())
|
|
21
|
+
if _descriptor._USE_C_DESCRIPTORS == False:
|
|
22
|
+
|
|
23
|
+
DESCRIPTOR._options = None
|
|
24
|
+
DESCRIPTOR._serialized_options = b"\n\034com.google.security.zynamicsB\tBinExport"
|
|
25
|
+
_BINEXPORT2.fields_by_name["address_comment"]._options = None
|
|
26
|
+
_BINEXPORT2.fields_by_name["address_comment"]._serialized_options = b"\030\001"
|
|
27
|
+
_BINEXPORT2._serialized_start = 21
|
|
28
|
+
_BINEXPORT2._serialized_end = 3002
|
|
29
|
+
_BINEXPORT2_META._serialized_start = 758
|
|
30
|
+
_BINEXPORT2_META._serialized_end = 864
|
|
31
|
+
_BINEXPORT2_CALLGRAPH._serialized_start = 867
|
|
32
|
+
_BINEXPORT2_CALLGRAPH._serialized_end = 1279
|
|
33
|
+
_BINEXPORT2_CALLGRAPH_VERTEX._serialized_start = 969
|
|
34
|
+
_BINEXPORT2_CALLGRAPH_VERTEX._serialized_end = 1213
|
|
35
|
+
_BINEXPORT2_CALLGRAPH_VERTEX_TYPE._serialized_start = 1144
|
|
36
|
+
_BINEXPORT2_CALLGRAPH_VERTEX_TYPE._serialized_end = 1213
|
|
37
|
+
_BINEXPORT2_CALLGRAPH_EDGE._serialized_start = 1215
|
|
38
|
+
_BINEXPORT2_CALLGRAPH_EDGE._serialized_end = 1279
|
|
39
|
+
_BINEXPORT2_EXPRESSION._serialized_start = 1282
|
|
40
|
+
_BINEXPORT2_EXPRESSION._serialized_end = 1554
|
|
41
|
+
_BINEXPORT2_EXPRESSION_TYPE._serialized_start = 1434
|
|
42
|
+
_BINEXPORT2_EXPRESSION_TYPE._serialized_end = 1554
|
|
43
|
+
_BINEXPORT2_OPERAND._serialized_start = 1556
|
|
44
|
+
_BINEXPORT2_OPERAND._serialized_end = 1591
|
|
45
|
+
_BINEXPORT2_MNEMONIC._serialized_start = 1593
|
|
46
|
+
_BINEXPORT2_MNEMONIC._serialized_end = 1617
|
|
47
|
+
_BINEXPORT2_INSTRUCTION._serialized_start = 1620
|
|
48
|
+
_BINEXPORT2_INSTRUCTION._serialized_end = 1763
|
|
49
|
+
_BINEXPORT2_BASICBLOCK._serialized_start = 1766
|
|
50
|
+
_BINEXPORT2_BASICBLOCK._serialized_end = 1894
|
|
51
|
+
_BINEXPORT2_BASICBLOCK_INDEXRANGE._serialized_start = 1842
|
|
52
|
+
_BINEXPORT2_BASICBLOCK_INDEXRANGE._serialized_end = 1894
|
|
53
|
+
_BINEXPORT2_FLOWGRAPH._serialized_start = 1897
|
|
54
|
+
_BINEXPORT2_FLOWGRAPH._serialized_end = 2258
|
|
55
|
+
_BINEXPORT2_FLOWGRAPH_EDGE._serialized_start = 2013
|
|
56
|
+
_BINEXPORT2_FLOWGRAPH_EDGE._serialized_end = 2258
|
|
57
|
+
_BINEXPORT2_FLOWGRAPH_EDGE_TYPE._serialized_start = 2180
|
|
58
|
+
_BINEXPORT2_FLOWGRAPH_EDGE_TYPE._serialized_end = 2258
|
|
59
|
+
_BINEXPORT2_REFERENCE._serialized_start = 2261
|
|
60
|
+
_BINEXPORT2_REFERENCE._serialized_end = 2402
|
|
61
|
+
_BINEXPORT2_DATAREFERENCE._serialized_start = 2404
|
|
62
|
+
_BINEXPORT2_DATAREFERENCE._serialized_end = 2463
|
|
63
|
+
_BINEXPORT2_COMMENT._serialized_start = 2466
|
|
64
|
+
_BINEXPORT2_COMMENT._serialized_end = 2806
|
|
65
|
+
_BINEXPORT2_COMMENT_TYPE._serialized_start = 2677
|
|
66
|
+
_BINEXPORT2_COMMENT_TYPE._serialized_end = 2806
|
|
67
|
+
_BINEXPORT2_SECTION._serialized_start = 2808
|
|
68
|
+
_BINEXPORT2_SECTION._serialized_end = 2896
|
|
69
|
+
_BINEXPORT2_LIBRARY._serialized_start = 2898
|
|
70
|
+
_BINEXPORT2_LIBRARY._serialized_end = 2965
|
|
71
|
+
_BINEXPORT2_MODULE._serialized_start = 2967
|
|
72
|
+
_BINEXPORT2_MODULE._serialized_end = 2989
|
|
73
|
+
# @@protoc_insertion_point(module_scope)
|