Skip to content

Commit 3ab5d0c

Browse files
committed
RegisterValue class now has __eq__ method, documentation, and fix for uninitialized type property
1 parent 4280e92 commit 3ab5d0c

1 file changed

Lines changed: 62 additions & 79 deletions

File tree

python/function.py

Lines changed: 62 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import threading
2323
import traceback
2424
import ctypes
25+
import numbers
2526

2627
# Binary Ninja components
2728
import binaryninja
@@ -73,6 +74,11 @@ def __init__(self, arch = None, value = None, confidence = types.max_confidence)
7374
self._is_constant = False
7475
if value is None:
7576
self._type = RegisterValueType.UndeterminedValue
77+
self._value = None
78+
self._arch = None
79+
self._reg = None
80+
self._is_constant = False
81+
self._offset = None
7682
else:
7783
self._type = RegisterValueType(value.state)
7884
if value.state == RegisterValueType.EntryValue:
@@ -92,34 +98,48 @@ def __init__(self, arch = None, value = None, confidence = types.max_confidence)
9298

9399
def __repr__(self):
94100
if self._type == RegisterValueType.EntryValue:
95-
return "<entry %s>" % self.reg
101+
return "<entry %s>" % self._reg
96102
if self._type == RegisterValueType.ConstantValue:
97-
return "<const %#x>" % self.value
103+
return "<const %#x>" % self._value
98104
if self._type == RegisterValueType.ConstantPointerValue:
99-
return "<const ptr %#x>" % self.value
105+
return "<const ptr %#x>" % self._value
100106
if self._type == RegisterValueType.StackFrameOffset:
101-
return "<stack frame offset %#x>" % self.offset
107+
return "<stack frame offset %#x>" % self._offset
102108
if self._type == RegisterValueType.ReturnAddressValue:
103109
return "<return address>"
104110
if self._type == RegisterValueType.ImportedAddressValue:
105-
return "<imported address from entry %#x>" % self.value
111+
return "<imported address from entry %#x>" % self._value
106112
return "<undetermined>"
107113

114+
def __eq__(self, other):
115+
if self._type in [RegisterValueType.ConstantValue, RegisterValueType.ConstantPointerValue, ImportedAddressValue, ReturnAddressValue] and isinstance(other, numbers.Integral):
116+
return self._value == other
117+
elif self._type in [RegisterValueType.ConstantValue, RegisterValueType.ConstantPointerValue, ImportedAddressValue, ReturnAddressValue] and hasattr(other, 'type') and other.type == self._type:
118+
return self._value == other.value
119+
elif self._type == RegisterValueType.EntryValue and hasattr(other, "type") and other.type == self._type:
120+
return self._reg == other.reg
121+
elif self._type == RegisterValueType.StackFrameOffset and hasattr(other, 'type') and other.type == self._type:
122+
return self._offset == other.offset
123+
elif self._type == RegisterValueType.StackFrameOffset and isinstance(other, numbers.Integral):
124+
return self._offset == other
125+
else:
126+
raise TypeError("'%s' is not valid for comparison to '%s'" % (other, self))
127+
108128
def _to_api_object(self):
109129
result = core.BNRegisterValue()
110-
result.state = self._type
111-
result.value = 0
130+
result.type = self._type
131+
result._value = 0
112132
if self._type == RegisterValueType.EntryValue:
113-
if self.arch is not None:
114-
result.value = self.arch.get_reg_index(self.reg)
133+
if self._arch is not None:
134+
result._value = self._arch.get_reg_index(self._reg)
115135
else:
116-
result.value = self.reg
136+
result._value = self._reg
117137
elif (self._type == RegisterValueType.ConstantValue) or (self._type == RegisterValueType.ConstantPointerValue):
118-
result.value = self.value
138+
result._value = self._value
119139
elif self._type == RegisterValueType.StackFrameOffset:
120-
result.value = self.offset
140+
result._value = self._offset
121141
elif self._type == RegisterValueType.ImportedAddressValue:
122-
result.value = self.value
142+
result._value = self._value
123143
return result
124144

125145
@classmethod
@@ -129,127 +149,82 @@ def undetermined(self):
129149
@classmethod
130150
def entry_value(self, arch, reg):
131151
result = RegisterValue()
132-
result.type = RegisterValueType.EntryValue
133-
result.arch = arch
134-
result.reg = reg
152+
result._type = RegisterValueType.EntryValue
153+
result._arch = arch
154+
result._reg = reg
135155
return result
136156

137157
@classmethod
138158
def constant(self, value):
139159
result = RegisterValue()
140-
result.type = RegisterValueType.ConstantValue
141-
result.value = value
142-
result.is_constant = True
160+
result._type = RegisterValueType.ConstantValue
161+
result._value = value
162+
result._is_constant = True
143163
return result
144164

145165
@classmethod
146166
def constant_ptr(self, value):
147167
result = RegisterValue()
148-
result.type = RegisterValueType.ConstantPointerValue
149-
result.value = value
150-
result.is_constant = True
168+
result._type = RegisterValueType.ConstantPointerValue
169+
result._value = value
170+
result._is_constant = True
151171
return result
152172

153173
@classmethod
154174
def stack_frame_offset(self, offset):
155175
result = RegisterValue()
156-
result.type = RegisterValueType.StackFrameOffset
157-
result.offset = offset
176+
result._type = RegisterValueType.StackFrameOffset
177+
result._offset = offset
158178
return result
159179

160180
@classmethod
161181
def imported_address(self, value):
162182
result = RegisterValue()
163-
result.type = RegisterValueType.ImportedAddressValue
164-
result.value = value
183+
result._type = RegisterValueType.ImportedAddressValue
184+
result._value = value
165185
return result
166186

167187
@classmethod
168188
def return_address(self):
169189
result = RegisterValue()
170-
result.type = RegisterValueType.ReturnAddressValue
190+
result._type = RegisterValueType.ReturnAddressValue
171191
return result
172192

173193
@property
174194
def is_constant(self):
175-
""" """
195+
"""Boolean for whether the RegisterValue is known to be constant (read-only)"""
176196
return self._is_constant
177197

178-
@is_constant.setter
179-
def is_constant(self, value):
180-
""" """
181-
self._is_constant = value
182-
183198
@property
184199
def type(self):
185-
""" """
200+
""":class:`~enums.RegisterValueType` (read-only)"""
186201
return self._type
187202

188-
@type.setter
189-
def type(self, value):
190-
""" """
191-
self._type = value
192-
193-
@property
194-
def state(self):
195-
""" """
196-
return self._state
197-
198-
@state.setter
199-
def state(self, value):
200-
""" """
201-
self._state = value
202-
203203
@property
204204
def arch(self):
205-
""" """
205+
"""Architecture where it exists, None otherwise (read-only)"""
206206
return self._arch
207207

208-
@arch.setter
209-
def arch(self, value):
210-
""" """
211-
self._arch = value
212-
213208
@property
214209
def reg(self):
215-
""" """
210+
"""Register where the Architecture exists, None otherwise (read-only)"""
216211
return self._reg
217212

218-
@reg.setter
219-
def reg(self, value):
220-
""" """
221-
self._reg = value
222-
223213
@property
224214
def value(self):
225-
""" """
215+
"""Value where it exists, None otherwise (read-only)"""
226216
return self._value
227217

228-
@value.setter
229-
def value(self, value):
230-
""" """
231-
self._value = value
232-
233218
@property
234219
def offset(self):
235-
""" """
220+
"""Offset where it exists, None otherwise (read-only)"""
236221
return self._offset
237222

238-
@offset.setter
239-
def offset(self, value):
240-
""" """
241-
self._offset = value
242-
243223
@property
244224
def confidence(self):
245-
""" """
225+
"""Confidence where it exists, None otherwise (read-only)"""
246226
return self._confidence
247227

248-
@confidence.setter
249-
def confidence(self, value):
250-
""" """
251-
self._confidence = value
252-
253228

254229
class ValueRange(object):
255230
def __init__(self, start, end, step):
@@ -441,6 +416,14 @@ def values(self, value):
441416
""" """
442417
self._values = value
443418

419+
def __eq__(self, other):
420+
if self.type in [RegisterValueType.ConstantValue, RegisterValueType.ConstantValue] and isinstance(other, numbers.Integral):
421+
return self.value == other
422+
if self.type in [RegisterValueType.ConstantValue, RegisterValueType.ConstantValue] and hasattr(other, 'type') and other.type == self.type:
423+
return self.value == other.value
424+
else:
425+
return self == other
426+
444427

445428
class StackVariableReference(object):
446429
def __init__(self, src_operand, t, name, var, ref_ofs, size):

0 commit comments

Comments
 (0)