def generic_keydep(self, key_symbol_name, key_length, plaintext_symbol_name, plaintext_length, num_instructions, num_bitflips, skip=0): key_dependency_graph = DependencyGraph(DependencyGraphKey.KEY, name="Key dependency graph") plaintext_dependency_graph = DependencyGraph(DependencyGraphKey.PLAINTEXT, name="Plaintext dependency graph") key = b"\x00" * key_length plaintext = b"\x00" * plaintext_length clean_state = X64EmulationState(self.elf) clean_state.write_symbol(key_symbol_name, key) clean_state.write_symbol(plaintext_symbol_name, plaintext) clean_state.write_register(UC_X86_REG_RSP, self.elf.sp) for b in range(0, num_bitflips): # Create reference state: this state will contain a key with all bits zero during the execution ref_state = clean_state.copy() # Create current key state: this state will contain flipped key bits during the execution current_key_state = clean_state.copy() current_key_state.write_symbol(key_symbol_name, binascii.unhexlify(("%0" + str(key_length*2) + "x") % (1 << b))) # Create current plaintext state: this state will contain flipped plaintext bits during the execution current_plaintext_state = clean_state.copy() current_plaintext_state.write_symbol(plaintext_symbol_name, binascii.unhexlify(("%0" + str(plaintext_length*2) + "x") % (1 << b))) # Run <skip> steps if skip != 0: emulate(ref_state, self.elf.get_symbol_address('stop'), skip) emulate(current_key_state, self.elf.get_symbol_address('stop'), skip) emulate(current_plaintext_state, self.elf.get_symbol_address('stop'), skip) # Emulate for num_instructions steps for t in range(1, num_instructions+1-skip): if t % 10 == 0: print("\rBitflipped index: %d, t: %d " % (b, t), end='') # Progress reference and current states with 1 step emulate(ref_state, self.elf.get_symbol_address('stop'), 1) emulate(current_key_state, self.elf.get_symbol_address('stop'), 1) emulate(current_plaintext_state, self.elf.get_symbol_address('stop'), 1) # Diff states and store result in dependency_graph for time t current_key_state.diff(ref_state, b, t, key_dependency_graph) current_plaintext_state.diff(ref_state, b, t, plaintext_dependency_graph) # Print dependencies print(key_dependency_graph) print(plaintext_dependency_graph) both_modified = DependencyGraph.from_intersection(key_dependency_graph, plaintext_dependency_graph) pickle.dump(key_dependency_graph, open('/tmp/key_dependency_graph.p', 'wb')) pickle.dump(plaintext_dependency_graph, open('/tmp/plaintext_dependency_graph.p', 'wb')) pickle.dump(both_modified, open('/tmp/combined_dependency_graph.p', 'wb'))
if __name__ == "__main__": with open('/tmp/key_dependency_graph.p', 'rb') as f: key_dependency_graph = pickle.load(f) with open('/tmp/plaintext_dependency_graph.p', 'rb') as f: plaintext_dependency_graph = pickle.load(f) print(key_dependency_graph) print(plaintext_dependency_graph) union_graph = DependencyGraph.from_union(key_dependency_graph, plaintext_dependency_graph) print(union_graph) intersection_graph = DependencyGraph.from_intersection( key_dependency_graph, plaintext_dependency_graph) print(intersection_graph) #d = DependencyGraphVisualization(union_graph, lines=True, exclude_partial_registers=False) #d.show() #d = DependencyGraphVisualization(intersection_graph, lines=True, exclude_partial_registers=False) #d.show() d = DependencyGraphVisualization(key_dependency_graph, lines=True, exclude_partial_registers=False) d.show() #d = DependencyGraphVisualization(plaintext_dependency_graph, lines=True, exclude_partial_registers=False) #d.show()