1515
1616BINDIFF_BINARY = None
1717BINDIFF_PATH_ENV = "BINDIFF_PATH"
18- BIN_NAMES = [' bindiff' , ' bindiff.exe' , ' differ' ]
18+ BIN_NAMES = [" bindiff" , " bindiff.exe" , " differ" ]
1919
2020
2121def _check_bin_names (path : Path ) -> bool :
@@ -48,7 +48,7 @@ def _check_environ() -> bool:
4848def _check_default_path () -> bool :
4949 """
5050 Check if BinDiff is installed at its default location
51-
51+
5252 :return: bool
5353 """
5454 return _check_bin_names (Path ("/opt/zynamics/BinDiff/bin" ))
@@ -78,7 +78,12 @@ class BinDiff(BindiffFile):
7878 additional attributes and method to the class.
7979 """
8080
81- def __init__ (self , primary : Union [ProgramBinExport , str ], secondary : Union [ProgramBinExport , str ], diff_file : str ):
81+ def __init__ (
82+ self ,
83+ primary : Union [ProgramBinExport , str ],
84+ secondary : Union [ProgramBinExport , str ],
85+ diff_file : str ,
86+ ):
8287 """
8388 :param primary: first program diffed
8489 :param secondary: second program diffed
@@ -94,7 +99,7 @@ def __init__(self, primary: Union[ProgramBinExport, str], secondary: Union[Progr
9499 def primary_unmatched_function (self ) -> list [FunctionBinExport ]:
95100 """
96101 Return a list of the unmatched functions in the primary program.
97-
102+
98103 :return: list of unmatched functions in primary
99104 """
100105 funs = []
@@ -106,7 +111,7 @@ def primary_unmatched_function(self) -> list[FunctionBinExport]:
106111 def secondary_unmatched_function (self ) -> list [FunctionBinExport ]:
107112 """
108113 Return a list of the unmatched functions in the secondary program.
109-
114+
110115 :return: list of unmatched functions in secondary
111116 """
112117 funs = []
@@ -115,7 +120,9 @@ def secondary_unmatched_function(self) -> list[FunctionBinExport]:
115120 funs .append (fun )
116121 return funs
117122
118- def iter_function_matches (self ) -> list [tuple [FunctionBinExport , FunctionBinExport , FunctionMatch ]]:
123+ def iter_function_matches (
124+ self ,
125+ ) -> list [tuple [FunctionBinExport , FunctionBinExport , FunctionMatch ]]:
119126 """
120127 Return a list of all the matched functions. Each element of the list is a tuple containing
121128 the function in the primary program, the matched function in the secondary program and the
@@ -124,50 +131,58 @@ def iter_function_matches(self) -> list[tuple[FunctionBinExport, FunctionBinExpo
124131 :return: list of tuple, each containing the primary function, the secondary function and
125132 the FunctionMatch object
126133 """
127- return [(self .primary [match .address1 ], self .secondary [match .address2 ], match ) \
128- for match in self .primary_functions_match .values ()]
134+ return [
135+ (self .primary [match .address1 ], self .secondary [match .address2 ], match )
136+ for match in self .primary_functions_match .values ()
137+ ]
129138
130- def _unmatched_bbs (self , function : FunctionBinExport , map : dict [int , dict [int , BasicBlockMatch ]]) -> list [BasicBlockBinExport ]:
139+ def _unmatched_bbs (
140+ self , function : FunctionBinExport , map : dict [int , dict [int , BasicBlockMatch ]]
141+ ) -> list [BasicBlockBinExport ]:
131142 bbs = []
132143 for bb_addr , bb in function .items ():
133144 if maps := map .get (bb_addr ):
134- if function .addr not in maps : # The block has been match but in another function thus unmatched here
145+ # The block has been match but in another function thus unmatched here
146+ if function .addr not in maps :
135147 bbs .append (bb )
136148 else :
137149 bbs .append (bb )
138150 return bbs
139151
140- def primary_unmatched_basic_block (self , function : FunctionBinExport ) -> list [BasicBlockBinExport ]:
152+ def primary_unmatched_basic_block (
153+ self , function : FunctionBinExport
154+ ) -> list [BasicBlockBinExport ]:
141155 """
142156 Return a list of the unmatched basic blocks in the provided function.
143157 The function must be part of the primary program.
144-
158+
145159 :param function: A function of the primary program
146160 :return: list of unmatched basic blocks
147161 """
148162 return self ._unmatched_bbs (function , self .primary_basicblock_match )
149163
150- def secondary_unmatched_basic_block (self , function : FunctionBinExport ) -> list [BasicBlockBinExport ]:
164+ def secondary_unmatched_basic_block (
165+ self , function : FunctionBinExport
166+ ) -> list [BasicBlockBinExport ]:
151167 """
152168 Return a list of the unmatched basic blocks in the provided function.
153169 The function must be part of the secondary program.
154-
170+
155171 :param function: A function of the secondary program
156172 :return: list of unmatched basic blocks
157173 """
158174 return self ._unmatched_bbs (function , self .secondary_basicblock_match )
159175
160- def iter_basicblock_matches (self ,
161- function1 : FunctionBinExport ,
162- function2 : FunctionBinExport
176+ def iter_basicblock_matches (
177+ self , function1 : FunctionBinExport , function2 : FunctionBinExport
163178 ) -> list [tuple [BasicBlockBinExport , BasicBlockBinExport , BasicBlockMatch ]]:
164179 """
165180 Return a list of all the matched basic blocks between the two provided functions.
166181 Each element of the list is a tuple containing the basic blocks of the primary and secondary
167182 functions and the BasicBlockMatch object describing the match.
168183 The first function must be part of the primary program while the second function must be
169184 part of the secondary program.
170-
185+
171186 :param function1: A function of the primary program
172187 :param function2: A function of the secondary program
173188 :return: list of tuple, each containing the primary basic block, the secondary basic block
@@ -180,7 +195,9 @@ def iter_basicblock_matches(self,
180195 items .append ((bb , function2 [match .address2 ], match ))
181196 return items
182197
183- def _unmatched_instrs (self , bb : BasicBlockBinExport , map : dict [int , dict [int , int ]]) -> list [InstructionBinExport ]:
198+ def _unmatched_instrs (
199+ self , bb : BasicBlockBinExport , map : dict [int , dict [int , int ]]
200+ ) -> list [InstructionBinExport ]:
184201 instrs = []
185202 for addr , instr in bb .instructions .items ():
186203 if addr not in map :
@@ -191,31 +208,34 @@ def primary_unmatched_instruction(self, bb: BasicBlockBinExport) -> list[Instruc
191208 """
192209 Return a list of the unmatched instructions in the provided basic block.
193210 The basic block must be part of the primary program.
194-
211+
195212 :param bb: A basic block belonging to the primary program
196213 :return: list of unmatched instructions
197214 """
198215 return self ._unmatched_instrs (bb , self .primary_instruction_match )
199216
200- def secondary_unmatched_instruction (self , bb : BasicBlockBinExport ) -> list [InstructionBinExport ]:
217+ def secondary_unmatched_instruction (
218+ self , bb : BasicBlockBinExport
219+ ) -> list [InstructionBinExport ]:
201220 """
202221 Return a list of the unmatched instructions in the provided basic block.
203222 The basic block must be part of the secondary program.
204-
223+
205224 :param bb: A basic block belonging to the secondary program
206225 :return: list of unmatched instructions
207226 """
208227 return self ._unmatched_instrs (bb , self .secondary_instruction_match )
209228
210- def iter_instruction_matches (self , block1 : BasicBlockBinExport ,
211- block2 : BasicBlockBinExport ) -> list [tuple [InstructionBinExport , InstructionBinExport ]]:
229+ def iter_instruction_matches (
230+ self , block1 : BasicBlockBinExport , block2 : BasicBlockBinExport
231+ ) -> list [tuple [InstructionBinExport , InstructionBinExport ]]:
212232 """
213233 Return a list of all the matched instructions between the two provided basic blocks.
214234 Each element of the list is a tuple containing the instructions of the primary and secondary
215235 basic blocks.
216236 The first basic block must belong to the primary program while the second one must be
217237 part of the secondary program.
218-
238+
219239 :param block1: A basic block belonging to the primary program
220240 :param block2: A basic block belonging to the secondary program
221241 :return: list of tuple, each containing the primary instruction and the secondary instruction
@@ -226,10 +246,12 @@ def iter_instruction_matches(self, block1: BasicBlockBinExport,
226246 insts .append ((instr , block2 .instructions [addr2 ]))
227247 return insts
228248
229- def get_match (self , function : FunctionBinExport ) -> tuple [FunctionBinExport , FunctionMatch ] | None :
249+ def get_match (
250+ self , function : FunctionBinExport
251+ ) -> tuple [FunctionBinExport , FunctionMatch ] | None :
230252 """
231253 Get the function that matches the provided one.
232-
254+
233255 :param function: A function that belongs either to primary or secondary
234256 :return: A tuple with the matched function and the match object if there is a match for
235257 the provided function, otherwise None
@@ -268,10 +290,12 @@ def raw_diffing(p1_path: Union[Path, str], p2_path: Union[Path, str], out_diff:
268290 f1 = Path (p1_path )
269291 f2 = Path (p2_path )
270292
271- cmd_line = [BINDIFF_BINARY .as_posix (),
272- f"--primary={ p1_path } " ,
273- f"--secondary={ p2_path } " ,
274- f"--output_dir={ tmp_dir .as_posix ()} " ]
293+ cmd_line = [
294+ BINDIFF_BINARY .as_posix (),
295+ f"--primary={ p1_path } " ,
296+ f"--secondary={ p2_path } " ,
297+ f"--output_dir={ tmp_dir .as_posix ()} " ,
298+ ]
275299
276300 logging .debug (f"run diffing: { ' ' .join (cmd_line )} " )
277301 process = subprocess .Popen (cmd_line , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
@@ -301,7 +325,7 @@ def raw_diffing(p1_path: Union[Path, str], p2_path: Union[Path, str], out_diff:
301325 return True
302326
303327 @staticmethod
304- def from_binary_files (p1_path : str , p2_path : str , diff_out : str ) -> Optional [' BinDiff' ]:
328+ def from_binary_files (p1_path : str , p2_path : str , diff_out : str ) -> Optional [" BinDiff" ]:
305329 """
306330 Diff two executable files. Thus it export .BinExport files from IDA
307331 and then diff the two resulting files in BinDiff.
@@ -324,7 +348,9 @@ def from_binary_files(p1_path: str, p2_path: str, diff_out: str) -> Optional['Bi
324348 return None
325349
326350 @staticmethod
327- def from_binexport_files (p1_binexport : str , p2_binexport : str , diff_out : str ) -> Optional ['BinDiff' ]:
351+ def from_binexport_files (
352+ p1_binexport : str , p2_binexport : str , diff_out : str
353+ ) -> Optional ["BinDiff" ]:
328354 """
329355 Diff two binexport files. Diff the two binexport files with bindiff
330356 and then load a BinDiff instance.
@@ -346,8 +372,10 @@ def _configure_bindiff_path() -> None:
346372 if not _check_environ ():
347373 if not _check_default_path ():
348374 if not _check_path ():
349- logging .warning (f"Can't find a valid bindiff executable. (should be available in PATH or"
350- f"as ${ BINDIFF_PATH_ENV } env variable" )
375+ logging .warning (
376+ f"Can't find a valid bindiff executable. (should be available in PATH or"
377+ f"as ${ BINDIFF_PATH_ENV } env variable"
378+ )
351379
352380 @staticmethod
353381 def assert_installation_ok () -> None :
0 commit comments