def __init__(self, state): self.state = state self.debug_view = None self.last_ip = 0 self.regs = [] self.stack = [] registers_widget = self.widget("Debugger Registers") modules_widget = self.widget("Debugger Modules") threads_widget = self.widget("Debugger Threads") stack_widget = self.widget("Debugger Stack") bp_widget = self.widget("Debugger Breakpoints") #console_widget = self.widget('Debugger Console') if registers_widget is None or modules_widget is None or threads_widget is None or stack_widget is None or bp_widget is None: # One of the views failed to create, bail log_debug( "Creating Debugger UI for view with missing dock widgets!") return # Initial view data self.context_display() self.update_highlights() self.update_breakpoints() Settings().register_group("debugger", "Debugger") key = 'debugger.extra_annotations' if not Settings().contains(key): Settings().register_setting( key, '{"description" : "Enables automatic additional annotations to be added to the start of functions that will persist after the debugger has moved away. Must break or step across the start of a function to trigger. Currently uses comments but will be migrated to ephemeral comments when that system is finished.", "title" : "Debugger Function Start Annotations", "default" : false, "type" : "boolean"}' )
def fuzzability(self) -> float: """ Calculate a final fuzzability score once analysis is completed. """ score = 0.0 # function is publicly exposed if not self.stripped: score += 1.0 # name contains interesting patterns often useful for fuzz harnesses if self.interesting_name: score += 1.0 # function signature can directly consume fuzzer input if self.interesting_args: score += 1.0 # function achieved an optimal threshold of coverage to be fuzzed depth_threshold = int( Settings().get_string("fuzzable.depth_threshold")) if self.depth >= depth_threshold: score += 1.0 # contains loop won't change score if configured loop_increase = Settings().get_bool("fuzzable.loop_increase_score") if not loop_increase and self.has_loop: score += 1.0 # auxiliary: recursive call doesn't change score, but useful information return score
def test_settings_create(self): s1 = Settings() s2 = Settings(None) s3 = Settings("default") s4 = Settings("test") assert s1 == s2, "test_settings_create failed" assert s1 == s3, "test_settings_create failed" assert s1 != s4, "test_settings_create failed"
def openSelectedFiles(self): failedToOpen = [] files = set() for index in self.tree.selectionModel().selectedIndexes(): if self.model.fileInfo(index).isFile(): files.add(self.model.fileInfo(index).absoluteFilePath()) for filename in files: QSettings().setValue("triage/recentFile", filename) f = FileContext.openFilename(filename) if not f: failedToOpen.append(filename) continue f.createBinaryViews() for data in f.getAllDataViews(): Settings().set_string("analysis.mode", Settings().get_string("triage.analysisMode"), data) Settings().set_bool("triage.preferSummaryView", True, data) if data.view_type != "Raw": linearSweepMode = Settings().get_string("triage.linearSweep") if linearSweepMode == "none": Settings().set_bool("analysis.linearSweep.autorun", False, data) elif linearSweepMode == "partial": Settings().set_bool("analysis.linearSweep.autorun", True, data) Settings().set_bool("analysis.linearSweep.controlFlowGraph", False, data) elif linearSweepMode == "full": Settings().set_bool("analysis.linearSweep.autorun", True, data) Settings().set_bool("analysis.linearSweep.controlFlowGraph", True, data) self.context.openFileContext(f) if len(failedToOpen) > 0: QMessageBox.critical(self, "Error", "Unable to open:\n" + "\n".join(failedToOpen))
def getPriority(self, data, filename): is_full = Settings().get_string("analysis.mode", data) == "full" always_prefer = Settings().get_bool("triage.preferSummaryView", data) prefer_for_raw = Settings().get_bool("triage.preferSummaryViewForRaw", data) if data.executable and (always_prefer or not is_full): return 100 if len(data) > 0: if always_prefer or data.executable or prefer_for_raw: return 25 return 1 return 0
def perform_custom_request(self, method, url, headers, data): try: proxy_setting = Settings().get_string('downloadClient.httpsProxy') if proxy_setting: proxies = {"https": proxy_setting} else: proxies = None r = requests.request(pyNativeStr(method), pyNativeStr(url), headers=headers, data=data, proxies=proxies) response = r.content if len(response) == 0: core.BNSetErrorForDownloadInstance(self.handle, "No data received from server!") return None raw_bytes = (ctypes.c_ubyte * len(response)).from_buffer_copy(response) bytes_wrote = core.BNWriteDataForDownloadInstance(self.handle, raw_bytes, len(raw_bytes)) if bytes_wrote != len(raw_bytes): core.BNSetErrorForDownloadInstance(self.handle, "Bytes written mismatch!") return None continue_download = core.BNNotifyProgressForDownloadInstance(self.handle, bytes_wrote, bytes_wrote) if continue_download is False: core.BNSetErrorForDownloadInstance(self.handle, "Download aborted!") return None return DownloadInstance.Response(r.status_code, r.headers, None) except requests.RequestException as e: core.BNSetErrorForDownloadInstance(self.handle, e.__class__.__name__) return None except: core.BNSetErrorForDownloadInstance(self.handle, "Unknown Exception!") log.log_error(traceback.format_exc()) return None
def annotate_context(self): if not Settings().get_bool("debugger.extra_annotations"): return if not self.state.connected: return remote_rip = self.state.ip local_rip = self.state.local_ip if self.state.bv.read(local_rip, 1) is None: return function = self.state.bv.get_function_at(local_rip) if not function: return annotation = "At {}:\n\n".format(datetime.datetime.now().isoformat()) address_size = self.state.bv.arch.address_size for reg in self.regs: if address_size * 8 == reg['bits']: annotation += " {reg:>4} = {value:0{valuewidth}x}\n".format( reg=reg['name'], value=reg['value'], valuewidth=address_size * 2) annotation += "\n\nStack:\n\n" # Read up and down from rsp for entry in self.stack: annotation += " {offset} {value:>{address_size}s} {address:x} {refs}\n".format( offset=entry['offset'], value=entry['value'].hex(), address=entry['address'], refs=entry['refs'], address_size=address_size * 2) function.set_comment_at(local_rip, annotation)
def init(self): data = self.parent_view ram_size = Settings().get_integer('arch.m16c.ramSize') * 1024 seg_rw_ = (SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable) seg_r_x = (SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable) seg_code = SegmentFlag.SegmentContainsCode seg_data = SegmentFlag.SegmentContainsData self.add_auto_segment(0x00000, 0x00400, 0, 0, seg_rw_) self.add_auto_segment(0x00400, ram_size, 0, 0, seg_rw_ | seg_data) self.add_auto_segment(0x100000 - len(data), len(data), data.start, len(data), seg_r_x | seg_code | seg_data) sec_default = SectionSemantics.DefaultSectionSemantics sec_ro_code = SectionSemantics.ReadOnlyCodeSectionSemantics sec_ro_data = SectionSemantics.ReadOnlyDataSectionSemantics sec_rw_data = SectionSemantics.ReadWriteDataSectionSemantics self.add_auto_section('.sfr', 0x00000, 0x00400, sec_default) self.add_auto_section('.data', 0x00400, ram_size, sec_rw_data) self.add_auto_section('.text', 0x100000 - len(data), len(data), sec_ro_code) self.add_auto_section('.rodata', 0x100000 - len(data), len(data), sec_ro_data) for vector_addr, vector_name in zip(range(0xFFFDC, 0x100000, 4), self.vector_names): vector, = struct.unpack("<L", self.read(vector_addr, 4)) symbol = Symbol(SymbolType.FunctionSymbol, vector & 0xFFFFF, vector_name) self.define_auto_symbol(symbol) return True
def perform_request(self, url): try: proxy_setting = Settings().get_string('downloadClient.httpsProxy') if proxy_setting: proxies = {"https": proxy_setting} else: proxies = None r = requests.get(pyNativeStr(url), proxies=proxies) if not r.ok: core.BNSetErrorForDownloadInstance(self.handle, "Received error from server") return -1 data = r.content if len(data) == 0: core.BNSetErrorForDownloadInstance(self.handle, "No data received from server!") return -1 raw_bytes = (ctypes.c_ubyte * len(data)).from_buffer_copy(data) bytes_wrote = core.BNWriteDataForDownloadInstance(self.handle, raw_bytes, len(raw_bytes)) if bytes_wrote != len(raw_bytes): core.BNSetErrorForDownloadInstance(self.handle, "Bytes written mismatch!") return -1 continue_download = core.BNNotifyProgressForDownloadInstance(self.handle, bytes_wrote, bytes_wrote) if continue_download is False: core.BNSetErrorForDownloadInstance(self.handle, "Download aborted!") return -1 except requests.RequestException as e: core.BNSetErrorForDownloadInstance(self.handle, e.__class__.__name__) return -1 except: core.BNSetErrorForDownloadInstance(self.handle, "Unknown Exception!") log.log_error(traceback.format_exc()) return -1 return 0
def startFullAnalysis(self): Settings().set_string("analysis.mode", "full", self.data) for f in self.data.functions: if f.analysis_skipped: f.reanalyze() self.data.update_analysis() self.fullAnalysisButton.hide()
def __init__(self, state): self.state = state self.debug_view = None self.last_ip = 0 self.regs = [] self.stack = [] # Initial view data self.context_display() self.update_highlights() self.update_breakpoints() Settings().register_group("debugger", "Debugger") Settings().register_setting( "debugger.extra_annotations", '{"description" : "Enables automatic additional annotations to be added to the start of functions that will persist after the debugger has moved away. Must break or step across the start of a function to trigger. Currently uses comments but will be migrated to ephemeral comments when that system is finished.", "title" : "Debuger Function Start Annotations", "default" : false, "type" : "boolean"}' )
def save_svg(bv, function): sym = bv.get_symbol_at(function.start) if sym: offset = sym.name else: offset = "%x" % function.start path = Path(os.path.dirname(bv.file.filename)) origname = os.path.basename(bv.file.filename) filename = path / f'binaryninja-{origname}-{offset}.html' functionChoice = TextLineField("Blank to accept default") # TODO: implement linear disassembly settings and output modeChoices = ["Graph"] modeChoiceField = ChoiceField("Mode", modeChoices) if Settings().get_bool('ui.debugMode'): formChoices = [ "Assembly", "Lifted IL", "LLIL", "LLIL SSA", "Mapped Medium", "Mapped Medium SSA", "MLIL", "MLIL SSA", "HLIL", "HLIL SSA" ] formChoiceField = ChoiceField("Form", formChoices) else: formChoices = ["Assembly", "LLIL", "MLIL", "HLIL"] formChoiceField = ChoiceField("Form", formChoices) showOpcodes = ChoiceField("Show Opcodes", ["Yes", "No"]) showAddresses = ChoiceField("Show Addresses", ["Yes", "No"]) saveFileChoices = SaveFileNameField("Output file", 'HTML files (*.html)', str(filename)) if not get_form_input([ f'Current Function: {offset}', functionChoice, formChoiceField, modeChoiceField, showOpcodes, showAddresses, saveFileChoices ], "SVG Export") or saveFileChoices.result is None: return if saveFileChoices.result == '': outputfile = filename else: outputfile = saveFileChoices.result content = render_svg(function, offset, modeChoices[modeChoiceField.result], formChoices[formChoiceField.result], showOpcodes.result == 0, showAddresses.result == 0, origname) output = open(outputfile, 'w') output.write(content) output.close() result = show_message_box("Open SVG", "Would you like to view the exported SVG?", buttons=MessageBoxButtonSet.YesNoButtonSet, icon=MessageBoxIcon.QuestionIcon) if result == MessageBoxButtonResult.YesButton: # might need more testing, latest py3 on windows seems.... broken with these APIs relative to other platforms if sys.platform == 'win32': webbrowser.open(outputfile) else: webbrowser.open('file://' + str(outputfile))
def test_settings_defaults(self): settings = Settings() assert settings.contains("analysis.linearSweep.autorun"), "test_settings_defaults failed" assert settings.contains("analysis.unicode.blocks"), "test_settings_defaults failed" assert settings.contains("downloadClient.providerName"), "test_settings_defaults failed" assert settings.get_bool_with_scope("analysis.linearSweep.autorun", scope=SettingsScope.SettingsDefaultScope)[0], "test_settings_defaults failed" assert settings.get_bool_with_scope("analysis.linearSweep.autorun", scope=SettingsScope.SettingsDefaultScope)[1] == SettingsScope.SettingsDefaultScope, "test_settings_defaults failed"
def get_instruction_text(self, data, addr): decoded = mc.decode(data, addr) if decoded: encoded = data[:decoded.length()] recoded = mc.encode(decoded, addr) if encoded != recoded: log.log_error("Instruction roundtrip error") log.log_error("".join([str(x) for x in decoded.render(addr)])) log.log_error("Orig: {}".format(encoded.hex())) log.log_error("New: {}".format(recoded.hex())) decoded.show_suffix = Settings().get_bool('arch.m16c.showSuffix') return decoded.render(addr), decoded.length()
def perform_request(self, url): try: proxy_setting = Settings().get_string( 'downloadClient.httpsProxy') if proxy_setting: opener = build_opener( ProxyHandler({'https': proxy_setting})) install_opener(opener) r = urlopen(pyNativeStr(url)) total_size = int(r.headers.get('content-length', 0)) bytes_sent = 0 while True: data = r.read(4096) if not data: break raw_bytes = (ctypes.c_ubyte * len(data)).from_buffer_copy(data) bytes_wrote = core.BNWriteDataForDownloadInstance( self.handle, raw_bytes, len(raw_bytes)) if bytes_wrote != len(raw_bytes): core.BNSetErrorForDownloadInstance( self.handle, "Bytes written mismatch!") return -1 bytes_sent = bytes_sent + bytes_wrote continue_download = core.BNNotifyProgressForDownloadInstance( self.handle, bytes_sent, total_size) if continue_download is False: core.BNSetErrorForDownloadInstance( self.handle, "Download aborted!") return -1 if not bytes_sent: core.BNSetErrorForDownloadInstance(self.handle, "Received no data!") return -1 except URLError as e: core.BNSetErrorForDownloadInstance(self.handle, e.__class__.__name__) log.log_error(str(e)) return -1 except: core.BNSetErrorForDownloadInstance(self.handle, "Unknown Exception!") log.log_error(traceback.format_exc()) return -1 return 0
def perform_custom_request(self, method, url, headers, data): result = None try: proxy_setting = Settings().get_string('downloadClient.httpsProxy') if proxy_setting: opener = build_opener(ProxyHandler({'https': proxy_setting})) install_opener(opener) if b"Content-Length" in headers: del headers[b"Content-Length"] req = PythonDownloadInstance.CustomRequest(pyNativeStr(url), data=data, headers=headers, method=pyNativeStr(method)) result = urlopen(req) except HTTPError as he: result = he except URLError as e: core.BNSetErrorForDownloadInstance(self.handle, e.__class__.__name__) log.log_error(str(e)) return None except: core.BNSetErrorForDownloadInstance(self.handle, "Unknown Exception!") log.log_error(traceback.format_exc()) return None total_size = int(result.headers.get('content-length', 0)) bytes_sent = 0 while True: data = result.read(4096) if not data: break raw_bytes = (ctypes.c_ubyte * len(data)).from_buffer_copy(data) bytes_wrote = core.BNWriteDataForDownloadInstance(self.handle, raw_bytes, len(raw_bytes)) if bytes_wrote != len(raw_bytes): core.BNSetErrorForDownloadInstance(self.handle, "Bytes written mismatch!") return None bytes_sent = bytes_sent + bytes_wrote continue_download = core.BNNotifyProgressForDownloadInstance(self.handle, bytes_sent, total_size) if continue_download is False: core.BNSetErrorForDownloadInstance(self.handle, "Download aborted!") return None if not bytes_sent: core.BNSetErrorForDownloadInstance(self.handle, "Received no data!") return None return DownloadInstance.Response(result.getcode(), result.headers, None)
def test_settings_registration(self): settings = Settings("test") assert not settings.contains( "testGroup.testSetting"), "test_settings_registration failed" assert settings.register_group( "testGroup", "Title"), "test_settings_registration failed" assert settings.register_setting( "testGroup.testSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : true, "type" : "boolean", "id" : "testSetting"}' ), "test_settings_registration failed" assert settings.contains( "testGroup.testSetting"), "test_settings_registration failed"
import json import struct from binaryninja import Architecture, Platform, BinaryView, Symbol from binaryninja.enums import SegmentFlag, SectionSemantics, SymbolType from binaryninja.settings import Settings __all__ = ['RenesasM16CRawBinaryView'] Settings().register_setting( 'arch.m16c.ramSize', json.dumps({ "title": "M16C RAM Size", "description": "Specify the amount of address space allocated for internal RAM.", "type": "number", "minValue": 0, "maxValue": 31, "default": 31, })) class RenesasM16CRawBinaryView(BinaryView): name = "M16C ROM" long_name = "M16C ROM Binary" vector_names = [ '_handle_und_instr', '_handle_overflow', '_handle_brk_instr', '_handle_addr_match',
return # Do not try to set the parent window when creating tabs, as this will create a parent relationship in # the bindings and will cause the widget to be destructed early. The correct parent will be assigned # when createTabForWidget is called. fp = TriageFilePicker(currentContext) currentContext.createTabForWidget("Open for Triage", fp) Settings().register_setting("triage.analysisMode", """ { "title" : "Triage Analysis Mode", "type" : "string", "default" : "basic", "description" : "Controls the amount of analysis performed on functions when opening for triage.", "enum" : ["controlFlow", "basic", "full"], "enumDescriptions" : [ "Only perform control flow analysis on the binary. Cross references are valid only for direct function calls.", "Perform fast initial analysis of the binary. This mode does not analyze types or data flow through stack variables.", "Perform full analysis of the binary." ] } """) Settings().register_setting("triage.linearSweep", """ { "title" : "Triage Linear Sweep Mode", "type" : "string", "default" : "partial", "description" : "Controls the level of linear sweep performed when opening for triage.", "enum" : ["none", "partial", "full"], "enumDescriptions" : [
def __init__(self, parent, data): QScrollArea.__init__(self, parent) View.__init__(self) View.setBinaryDataNavigable(self, True) self.setupView(self) self.data = data self.currentOffset = 0 self.byteView = None self.fullAnalysisButton = None self.importsWidget = None container = QWidget(self) layout = QVBoxLayout() entropyGroup = QGroupBox("Entropy", container) entropyLayout = QVBoxLayout() entropyLayout.addWidget( entropy.EntropyWidget(entropyGroup, self, self.data)) entropyGroup.setLayout(entropyLayout) layout.addWidget(entropyGroup) hdr = None try: if self.data.view_type == "PE": hdr = headers.PEHeaders(self.data) elif self.data.view_type != "Raw": hdr = headers.GenericHeaders(self.data) except: log.log_error(traceback.format_exc()) if hdr is not None: headerGroup = QGroupBox("Headers", container) headerLayout = QVBoxLayout() headerWidget = headers.HeaderWidget(headerGroup, hdr) headerLayout.addWidget(headerWidget) headerGroup.setLayout(headerLayout) layout.addWidget(headerGroup) if self.data.executable: importExportSplitter = QSplitter(Qt.Horizontal) importGroup = QGroupBox("Imports", container) importLayout = QVBoxLayout() self.importsWidget = imports.ImportsWidget(importGroup, self, self.data) importLayout.addWidget(self.importsWidget) importGroup.setLayout(importLayout) importExportSplitter.addWidget(importGroup) exportGroup = QGroupBox("Exports", container) exportLayout = QVBoxLayout() exportLayout.addWidget( exports.ExportsWidget(exportGroup, self, self.data)) exportGroup.setLayout(exportLayout) importExportSplitter.addWidget(exportGroup) layout.addWidget(importExportSplitter) if self.data.view_type != "PE": segmentsGroup = QGroupBox("Segments", container) segmentsLayout = QVBoxLayout() segmentsWidget = sections.SegmentsWidget( segmentsGroup, self.data) segmentsLayout.addWidget(segmentsWidget) segmentsGroup.setLayout(segmentsLayout) layout.addWidget(segmentsGroup) if len(segmentsWidget.segments) == 0: segmentsGroup.hide() sectionsGroup = QGroupBox("Sections", container) sectionsLayout = QVBoxLayout() sectionsWidget = sections.SectionsWidget(sectionsGroup, self.data) sectionsLayout.addWidget(sectionsWidget) sectionsGroup.setLayout(sectionsLayout) layout.addWidget(sectionsGroup) if len(sectionsWidget.sections) == 0: sectionsGroup.hide() buttonLayout = QHBoxLayout() buttonLayout.addStretch(1) self.loadDynamicButton = QPushButton("Load Dynamic Imports") self.loadDynamicButton.clicked.connect( self.importsWidget.scanDynamic) buttonLayout.addWidget(self.loadDynamicButton) self.fullAnalysisButton = QPushButton("Start Full Analysis") self.fullAnalysisButton.clicked.connect(self.startFullAnalysis) buttonLayout.addWidget(self.fullAnalysisButton) layout.addLayout(buttonLayout) layout.addStretch(1) else: self.byteView = byte.ByteView(self, self.data) layout.addWidget(self.byteView, 1) container.setLayout(layout) self.setWidgetResizable(True) self.setWidget(container) if self.fullAnalysisButton is not None and Settings().get_string( "analysis.mode", data) == "full": self.fullAnalysisButton.hide()
def detect_new_code(self): if not self.state.connected: return local_rip = self.state.local_ip if local_rip < self.state.bv.start or local_rip >= self.state.bv.end: return if self.state.bv.read(local_rip, 1) is None: raise Exception('cannot read from local address 0x%X' % local_rip) update_analysis = False try: # if executing where a function isn't defined, define one! if len(self.state.bv.get_functions_containing(local_rip)) == 0: #print('adding function at: 0x%X' % local_rip) self.state.bv.add_function(local_rip) update_analysis = True # analyze current instruction through LLIL remote_rip = self.state.ip llil = self.state.remote_arch.get_low_level_il_from_bytes( self.state.memory_view.read( remote_rip, self.state.remote_arch.max_instr_length), remote_rip) call = llil.operation == LowLevelILOperation.LLIL_CALL jump = llil.operation == LowLevelILOperation.LLIL_JUMP or llil.operation == LowLevelILOperation.LLIL_JUMP_TO indirect = (call or jump) and llil.operands[0].operation not in [ LowLevelILOperation.LLIL_CONST, LowLevelILOperation.LLIL_CONST_PTR ] if not (call or jump): return remote_target = self.evaluate_llil(self.state, llil.dest) local_target = self.state.memory_view.remote_addr_to_local( remote_target) if local_target < self.state.bv.start or local_target >= self.state.bv.end: return # if call target is within bv, and no function, make one if call and ( not self.state.bv.get_functions_containing(local_target)): self.state.bv.add_function(local_target) update_analysis = True # if call is indirect, optionally annotate the destination if call and indirect and Settings().get_bool( "debugger.extra_annotations"): for func in self.state.bv.get_functions_containing(local_rip): annotation = 'called 0x%X' % remote_target comment = func.get_comment_at(local_rip) if not annotation in comment.split('\n'): if comment: annotation = '\n' + annotation func.set_comment_at(local_rip, comment + annotation) # if jump target isn't in analysis's indirect jumps, add it if jump and indirect: for func in self.state.bv.get_functions_containing(local_rip): # get auto and user branches, autos shadowed by user branches = [ (b.dest_arch, b.dest_addr) for b in func.get_indirect_branches_at(local_rip) ] new_branch = (self.state.remote_arch, local_target) if not new_branch in branches: #print('adding indirect branch target: 0x%X' % (new_branch[1])) branches.append(new_branch) func.set_user_indirect_branches( local_rip, list(branches)) update_analysis = True except NotImplementedError as e: raise Exception("llil eval failed: {}".format(e)) finally: if update_analysis: self.state.bv.update_analysis()
always_prefer = Settings().get_bool("triage.preferSummaryView", data) prefer_for_raw = Settings().get_bool("triage.preferSummaryViewForRaw", data) if data.executable and (always_prefer or not is_full): return 100 if len(data) > 0: if always_prefer or data.executable or prefer_for_raw: return 25 return 1 return 0 def create(self, data, view_frame): return TriageView(view_frame, data) Settings().register_group("triage", "Triage") Settings().register_setting( "triage.preferSummaryView", """ { "title" : "Prefer Triage Summary View", "type" : "boolean", "default" : false, "description" : "Always prefer Triage Summary View when opening a binary, even when performing full analysis." } """) Settings().register_setting( "triage.preferSummaryViewForRaw", """ { "title" : "Prefer Triage Summary View for Raw Files", "type" : "boolean",
def test_settings_usage(self): settings = Settings("test") assert not settings.contains( "testGroup.testSetting"), "test_settings_types failed" assert settings.register_group("testGroup", "Title"), "test_settings_types failed" assert not settings.register_setting( "testGroup.boolSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : 500, "type" : "boolean", "id" : "boolSetting"}' ), "test_settings_types failed" assert settings.register_setting( "testGroup.boolSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : true, "type" : "boolean", "id" : "boolSetting"}' ), "test_settings_types failed" assert not settings.register_setting( "testGroup.doubleSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : true, "type" : "number", "id" : "doubleSetting"}' ), "test_settings_types failed" assert settings.register_setting( "testGroup.doubleSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : 500, "type" : "number", "id" : "doubleSetting"}' ), "test_settings_types failed" assert settings.register_setting( "testGroup.integerSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : 500, "type" : "number", "id" : "integerSetting"}' ), "test_settings_types failed" assert not settings.register_setting( "testGroup.stringSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : 500, "type" : "string", "id" : "stringSetting"}' ), "test_settings_types failed" assert settings.register_setting( "testGroup.stringSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : "value", "type" : "string", "id" : "stringSetting"}' ), "test_settings_types failed" assert not settings.register_setting( "testGroup.stringListSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : true, "type" : "array", "id" : "stringListSetting"}' ), "test_settings_types failed" assert settings.register_setting( "testGroup.stringListSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : ["value1", "value2"], "type" : "array", "id" : "stringListSetting"}' ), "test_settings_types failed" assert settings.register_setting( "testGroup.ignoreResourceBoolSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : true, "type" : "boolean", "id" : "boolSetting", "ignore" : ["SettingsResourceScope"]}' ), "test_settings_types failed" assert settings.register_setting( "testGroup.ignoreUserBoolSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : true, "type" : "boolean", "id" : "boolSetting", "ignore" : ["SettingsUserScope"]}' ), "test_settings_types failed" assert settings.register_setting( "testGroup.readOnlyBoolSetting", '{"description" : "Test description.", "title" : "Test Title", "default" : true, "type" : "boolean", "id" : "boolSetting", "ignore" : ["SettingsResourceScope", "SettingsUserScope"]}' ), "test_settings_types failed" assert settings.contains( "testGroup.boolSetting"), "test_settings_types failed" assert settings.contains( "testGroup.doubleSetting"), "test_settings_types failed" assert settings.contains( "testGroup.integerSetting"), "test_settings_types failed" assert settings.contains( "testGroup.stringSetting"), "test_settings_types failed" assert settings.contains( "testGroup.stringListSetting"), "test_settings_types failed" assert settings.get_bool( "testGroup.boolSetting") == True, "test_settings_types failed" assert settings.get_double( "testGroup.doubleSetting") == 500, "test_settings_types failed" assert settings.get_integer( "testGroup.integerSetting") == 500, "test_settings_types failed" assert settings.get_string( "testGroup.stringSetting") == "value", "test_settings_types failed" assert settings.get_string_list("testGroup.stringListSetting") == [ "value1", "value2" ], "test_settings_types failed" assert settings.set_bool("testGroup.boolSetting", False), "test_settings_types failed" assert settings.set_double("testGroup.doubleSetting", 700), "test_settings_types failed" assert settings.set_integer("testGroup.integerSetting", 700), "test_settings_types failed" assert settings.set_string("testGroup.stringSetting", "value_user"), "test_settings_types failed" assert settings.set_string_list( "testGroup.stringListSetting", ["value3", "value4"]), "test_settings_types failed" assert settings.get_bool( "testGroup.boolSetting") == False, "test_settings_types failed" assert settings.get_double( "testGroup.doubleSetting") == 700, "test_settings_types failed" assert settings.get_integer( "testGroup.integerSetting") == 700, "test_settings_types failed" assert settings.get_string( "testGroup.stringSetting" ) == "value_user", "test_settings_types failed" assert settings.get_string_list("testGroup.stringListSetting") == [ "value3", "value4" ], "test_settings_types failed" assert settings.get_bool_with_scope( "testGroup.boolSetting", scope=SettingsScope.SettingsDefaultScope )[0] == True, "test_settings_types failed" assert settings.get_double_with_scope( "testGroup.doubleSetting", scope=SettingsScope.SettingsDefaultScope )[0] == 500, "test_settings_types failed" assert settings.get_integer_with_scope( "testGroup.integerSetting", scope=SettingsScope.SettingsDefaultScope )[0] == 500, "test_settings_types failed" assert settings.get_string_with_scope( "testGroup.stringSetting", scope=SettingsScope.SettingsDefaultScope )[0] == "value", "test_settings_types failed" assert settings.get_string_list_with_scope( "testGroup.stringListSetting", scope=SettingsScope.SettingsDefaultScope)[0] == [ "value1", "value2" ], "test_settings_types failed" assert settings.get_bool_with_scope( "testGroup.boolSetting", scope=SettingsScope.SettingsUserScope )[0] == False, "test_settings_types failed" assert settings.get_double_with_scope( "testGroup.doubleSetting", scope=SettingsScope.SettingsUserScope )[0] == 700, "test_settings_types failed" assert settings.get_integer_with_scope( "testGroup.integerSetting", scope=SettingsScope.SettingsUserScope )[0] == 700, "test_settings_types failed" assert settings.get_string_with_scope( "testGroup.stringSetting", scope=SettingsScope.SettingsUserScope )[0] == "value_user", "test_settings_types failed" assert settings.get_string_list_with_scope( "testGroup.stringListSetting", scope=SettingsScope.SettingsUserScope)[0] == [ "value3", "value4" ], "test_settings_types failed" raw_view = BinaryView.new(b'0x55') assert not settings.set_bool("testGroup.ignoreResourceBoolSetting", False, scope=SettingsScope.SettingsDefaultScope ), "test_settings_types failed" assert not settings.set_bool("testGroup.ignoreResourceBoolSetting", False, scope=SettingsScope.SettingsResourceScope ), "test_settings_types failed" assert not settings.set_bool("testGroup.ignoreResourceBoolSetting", False, raw_view, scope=SettingsScope.SettingsResourceScope ), "test_settings_types failed" assert settings.set_bool("testGroup.ignoreResourceBoolSetting", False, scope=SettingsScope.SettingsUserScope ), "test_settings_types failed" assert not settings.set_bool("testGroup.ignoreUserBoolSetting", False), "test_settings_types failed" assert settings.set_bool("testGroup.ignoreUserBoolSetting", False, raw_view), "test_settings_types failed" assert settings.set_bool("testGroup.ignoreUserBoolSetting", False, raw_view, scope=SettingsScope.SettingsResourceScope ), "test_settings_types failed" assert not settings.set_bool("testGroup.readOnlyBoolSetting", False), "test_settings_types failed" assert not settings.set_bool("testGroup.readOnlyBoolSetting", False, scope=SettingsScope.SettingsResourceScope ), "test_settings_types failed" assert not settings.set_bool("testGroup.readOnlyBoolSetting", False, scope=SettingsScope.SettingsUserScope ), "test_settings_types failed" s2 = Settings("test2") assert s2.serialize_schema() == "", "test_settings_types failed" test_schema = settings.serialize_schema() assert test_schema != "", "test_settings_types failed" assert s2.deserialize_schema(test_schema), "test_settings_types failed" assert s2.get_bool( "testGroup.boolSetting") == True, "test_settings_types failed" assert s2.get_double( "testGroup.doubleSetting") == 500, "test_settings_types failed" assert s2.get_integer( "testGroup.integerSetting") == 500, "test_settings_types failed" assert s2.get_string( "testGroup.stringSetting") == "value", "test_settings_types failed" assert s2.get_string_list("testGroup.stringListSetting") == [ "value1", "value2" ], "test_settings_types failed" assert s2.deserialize_settings( settings.serialize_settings(scope=SettingsScope.SettingsUserScope), raw_view, SettingsScope.SettingsResourceScope), "test_settings_types failed" assert s2.get_bool("testGroup.boolSetting", raw_view) == False, "test_settings_types failed" assert s2.get_double("testGroup.doubleSetting", raw_view) == 700, "test_settings_types failed" assert s2.get_integer("testGroup.integerSetting", raw_view) == 700, "test_settings_types failed" assert s2.get_string( "testGroup.stringSetting", raw_view) == "value_user", "test_settings_types failed" assert s2.get_string_list("testGroup.stringListSetting", raw_view) == ["value3", "value4" ], "test_settings_types failed" assert s2.reset_all(), "test_settings_types failed" assert s2.get_bool( "testGroup.boolSetting") == True, "test_settings_types failed" assert s2.get_double( "testGroup.doubleSetting") == 500, "test_settings_types failed" assert s2.get_integer( "testGroup.integerSetting") == 500, "test_settings_types failed" assert s2.get_string( "testGroup.stringSetting") == "value", "test_settings_types failed" assert s2.get_string_list("testGroup.stringListSetting") == [ "value1", "value2" ], "test_settings_types failed" s3 = Settings("test3") assert s3.deserialize_schema(test_schema, SettingsScope.SettingsResourceScope) assert not s3.contains("testGroup.ignoreResourceBoolSetting" ), "test_settings_types failed" assert s3.contains( "testGroup.ignoreUserBoolSetting"), "test_settings_types failed" assert not s3.contains( "testGroup.readOnlyBoolSetting"), "test_settings_types failed" assert s3.deserialize_schema(test_schema, SettingsScope.SettingsUserScope, False) assert s3.contains("testGroup.ignoreResourceBoolSetting" ), "test_settings_types failed" assert not s3.contains( "testGroup.ignoreUserBoolSetting"), "test_settings_types failed" assert not s3.contains( "testGroup.readOnlyBoolSetting"), "test_settings_types failed" assert s3.deserialize_schema(test_schema, SettingsScope.SettingsUserScope, False) assert s3.deserialize_schema(s3.serialize_schema(), SettingsScope.SettingsResourceScope, False) assert not s3.contains("testGroup.ignoreResourceBoolSetting" ), "test_settings_types failed" assert not s3.contains( "testGroup.ignoreUserBoolSetting"), "test_settings_types failed" assert not s3.contains( "testGroup.readOnlyBoolSetting"), "test_settings_types failed"
def __init__(self, context, parent=None): super(Snippets, self).__init__(parent) # Create widgets self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) self.title = QLabel(self.tr("Snippet Editor")) self.saveButton = QPushButton(self.tr("&Save")) self.saveButton.setShortcut(QKeySequence(self.tr("Ctrl+S"))) self.runButton = QPushButton(self.tr("&Run")) self.runButton.setShortcut(QKeySequence(self.tr("Ctrl+R"))) self.closeButton = QPushButton(self.tr("Close")) self.clearHotkeyButton = QPushButton(self.tr("Clear Hotkey")) self.setWindowTitle(self.title.text()) #self.newFolderButton = QPushButton("New Folder") self.browseButton = QPushButton("Browse Snippets") self.browseButton.setIcon(QIcon.fromTheme("edit-undo")) self.deleteSnippetButton = QPushButton("Delete") self.newSnippetButton = QPushButton("New Snippet") indentation = Settings().get_string("snippets.indentation") if Settings().get_bool("snippets.syntaxHighlight"): self.edit = QCodeEditor(SyntaxHighlighter=Pylighter, delimeter=indentation) else: self.edit = QCodeEditor(SyntaxHighlighter=None, delimeter=indentation) self.edit.setPlaceholderText("python code") self.resetting = False self.columns = 3 self.context = context self.keySequenceEdit = QKeySequenceEdit(self) self.currentHotkey = QKeySequence() self.currentHotkeyLabel = QLabel("") self.currentFileLabel = QLabel() self.currentFile = "" self.snippetDescription = QLineEdit() self.snippetDescription.setPlaceholderText("optional description") #Set Editbox Size font = getMonospaceFont(self) self.edit.setFont(font) font = QFontMetrics(font) self.edit.setTabStopDistance( 4 * font.horizontalAdvance(' ')) #TODO, replace with settings API #Files self.files = QFileSystemModel() self.files.setRootPath(snippetPath) self.files.setNameFilters(["*.py"]) #Tree self.tree = QTreeView() self.tree.setModel(self.files) self.tree.setSortingEnabled(True) self.tree.hideColumn(2) self.tree.sortByColumn(0, Qt.AscendingOrder) self.tree.setRootIndex(self.files.index(snippetPath)) for x in range(self.columns): #self.tree.resizeColumnToContents(x) self.tree.header().setSectionResizeMode( x, QHeaderView.ResizeToContents) treeLayout = QVBoxLayout() treeLayout.addWidget(self.tree) treeButtons = QHBoxLayout() #treeButtons.addWidget(self.newFolderButton) treeButtons.addWidget(self.browseButton) treeButtons.addWidget(self.newSnippetButton) treeButtons.addWidget(self.deleteSnippetButton) treeLayout.addLayout(treeButtons) treeWidget = QWidget() treeWidget.setLayout(treeLayout) # Create layout and add widgets buttons = QHBoxLayout() buttons.addWidget(self.clearHotkeyButton) buttons.addWidget(self.keySequenceEdit) buttons.addWidget(self.currentHotkeyLabel) buttons.addWidget(self.closeButton) buttons.addWidget(self.runButton) buttons.addWidget(self.saveButton) description = QHBoxLayout() description.addWidget(QLabel(self.tr("Description: "))) description.addWidget(self.snippetDescription) vlayoutWidget = QWidget() vlayout = QVBoxLayout() vlayout.addLayout(description) vlayout.addWidget(self.edit) vlayout.addLayout(buttons) vlayoutWidget.setLayout(vlayout) hsplitter = QSplitter() hsplitter.addWidget(treeWidget) hsplitter.addWidget(vlayoutWidget) hlayout = QHBoxLayout() hlayout.addWidget(hsplitter) self.showNormal() #Fixes bug that maximized windows are "stuck" #Because you can't trust QT to do the right thing here if (sys.platform == "darwin"): self.settings = QSettings("Vector35", "Snippet Editor") else: self.settings = QSettings("Vector 35", "Snippet Editor") if self.settings.contains("ui/snippeteditor/geometry"): self.restoreGeometry( self.settings.value("ui/snippeteditor/geometry")) else: self.edit.setMinimumWidth(80 * font.averageCharWidth()) self.edit.setMinimumHeight(30 * font.lineSpacing()) # Set dialog layout self.setLayout(hlayout) # Add signals self.saveButton.clicked.connect(self.save) self.closeButton.clicked.connect(self.close) self.runButton.clicked.connect(self.run) self.clearHotkeyButton.clicked.connect(self.clearHotkey) self.tree.selectionModel().selectionChanged.connect(self.selectFile) self.newSnippetButton.clicked.connect(self.newFileDialog) self.deleteSnippetButton.clicked.connect(self.deleteSnippet) #self.newFolderButton.clicked.connect(self.newFolder) self.browseButton.clicked.connect(self.browseSnippets) if self.settings.contains("ui/snippeteditor/selected"): selectedName = self.settings.value("ui/snippeteditor/selected") self.tree.selectionModel().select( self.files.index(selectedName), QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows) if self.tree.selectionModel().hasSelection(): self.selectFile(self.tree.selectionModel().selection(), None) self.edit.setFocus() cursor = self.edit.textCursor() cursor.setPosition(self.edit.document().characterCount() - 1) self.edit.setTextCursor(cursor) else: self.readOnly(True) else: self.readOnly(True)
def tearDownClass(cls): setting = Settings()
def test_bool_settings(self): setting = Settings()
def test_float_settings(self): setting = Settings()
import json from binaryninja import log, Architecture, RegisterInfo, IntrinsicInfo, InstructionInfo from binaryninja.enums import Endianness, FlagRole, LowLevelILFlagCondition from binaryninja.types import Type from binaryninja.settings import Settings from . import mc __all__ = ['RenesasM16CArchitecture'] Settings().register_setting( 'arch.m16c.showSuffix', json.dumps({ "title": "M16C Disassembly Suffix", "description": "Whether or not to display the :G/:Q/:S/:Z suffix.", "type": "boolean", "default": True, })) class RenesasM16CArchitecture(Architecture): name = "m16c" endianness = Endianness.LittleEndian default_int_size = 2 address_size = 3 stack_pointer = 'SP' regs = { # Data (banked in hardware) 'R2R0': RegisterInfo('R2R0', 4, 0),
def test_int_list_settings(self): setting = Settings()
def test_str_list_settings(self): setting = Settings()