class ChipWhispererExtra(Parameterized): _name = 'CW Extra' def __init__(self, parentParam, cwtype, scope, oa): #self.cwADV = CWAdvTrigger() if cwtype == "cwrev2": self.cwEXTRA = CWExtraSettings(self, oa) elif cwtype == "cwlite": self.cwEXTRA = CWExtraSettings(self, oa, hasFPAFPB=False, hasGlitchOut=True, hasPLL=False) else: raise ValueError("Unknown ChipWhisperer: %s" % cwtype) self.enableGlitch = True if self.enableGlitch: self.glitch = ChipWhispererGlitch.ChipWhispererGlitch(self, cwtype, scope, oa) self.params = Parameter(name=self.getName(), type='group') self.params.append(self.cwEXTRA.getParams()) self.params.append(self.glitch.getParams()) def armPreScope(self): if self.enableGlitch: self.glitch.armPreScope() def armPostScope(self): if self.enableGlitch: self.glitch.armPostScope()
def setPreprocessing(self, num, module): """Insert the preprocessing module selected from the GUI into the list of active modules. This ensures that the options for that module are then displayed in the GUI, along with writing the auto-generated script. """ #Walk backwards to find previous trace source last_trace_src = self.cwGUI.api.project().traceManager() for i in range(num, 0, -1): if self.preprocessingListGUI[i] is not None: last_trace_src = self.preprocessingListGUI[i] break if self.preprocessingListGUI[num] is not None: self.preprocessingListGUI[num].deregister() self.preprocessingParams.getChild('Pre-Processing Mod. #%d'% num).delete() if module: self.preprocessingListGUI[num] = module(traceSource=last_trace_src) self.preprocessingListGUI[num].scriptsUpdated.connect(self.reloadScripts) par = Parameter(name = 'Pre-Processing Mod. #%d'% num, type = "group") par.append(self.preprocessingListGUI[num].getParams()) self.preprocessingParams.append(par) else: self.preprocessingListGUI[num] = None self.reloadScripts()
def setPreprocessing(self, num, module): """Insert the preprocessing module selected from the GUI into the list of active modules. This ensures that the options for that module are then displayed in the GUI, along with writing the auto-generated script. """ #Walk backwards to find previous trace source last_trace_src = self.cwGUI.api.project().traceManager() for i in range(num, 0, -1): if self.preprocessingListGUI[i] is not None: last_trace_src = self.preprocessingListGUI[i] break if self.preprocessingListGUI[num] is not None: self.preprocessingListGUI[num].deregister() self.preprocessingParams.getChild('Pre-Processing Mod. #%d' % num).delete() if module: self.preprocessingListGUI[num] = module(traceSource=last_trace_src) self.preprocessingListGUI[num].scriptsUpdated.connect( self.reloadScripts) par = Parameter(name='Pre-Processing Mod. #%d' % num, type="group") par.append(self.preprocessingListGUI[num].getParams()) self.preprocessingParams.append(par) else: self.preprocessingListGUI[num] = None self.reloadScripts()
class AttackSettings(Parameterized): def __init__(self): self._attack = None self.valid_attacks = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.analyzer.attacks", True, True) self.params = Parameter(name="Attack Settings", type="group") self.params.addChildren([ {'name': 'Attack', 'type':'list', 'values':self.valid_attacks, 'get':self.getAttack, 'set':self.setAttack} ]) @setupSetParam("Attack") def setAttack(self, atk): self._attack = atk if self._attack is not None: self.params.append(self._attack.params) def getAttack(self): return self._attack
class AttackScriptGen(Parameterized): _name = "Attack Script Generator" def __init__(self, cwGUI): self.cwGUI = cwGUI self.locked = False self.utilList = [] self.scriptList = [] self.scriptList.append({'widget':MainScriptEditor(self.cwGUI)}) self.scriptList[0]['filename'] = self.scriptList[0]['widget'].filename self.scriptList[0]['dockname'] = 'Auto-Generated' self.defaultEditor = self.scriptList[0] autogen = (self.defaultEditor['dockname'], self.defaultEditor['filename']) self.preprocessingListGUI = [None, None, None, None] self.setAttack(self.cwGUI.api.valid_attacks.get("CPA", None), blockSignal=True) self.getParams().addChildren([ {'name':'Attack Script', 'type':'group', 'children':[ {'name':'Filename', 'key':'attackfilelist', 'type':'filelist', 'values':{autogen:0}, 'value':0, 'editor':self.editorControl,}, ]}, {'name':'Pre-Processing', 'type':'group', 'children':[ {'name':'Module #%d' % step, 'type':'list', 'values':self.cwGUI.api.valid_preprocessingModules, 'get':partial(self.getPreprocessing, step), 'set':partial(self.setPreprocessing, step)} for step in range(0, len(self.preprocessingListGUI)) ]}, {'name':'Attack', 'type':'group', 'children':[ {'name':'Module', 'type':'list', 'values':self.cwGUI.api.valid_attacks, 'get':self.getAttack, 'set':self.setAttack}, ]}, ]) self.params.init() self.preprocessingParams = Parameter(name="Preprocessing", type='group') self.attackParams = Parameter(name="Attack", type='group') self.params.getChild(['Attack','Module']).stealDynamicParameters(self.attackParams) self.cwGUI.api.sigTracesChanged.connect(self.updateAttackTraceLimits) def flushTimer(self): """Flush all pending script updates""" [p.updateDelayTimer.flush() for p in self.preprocessingListGUI if p is not None] self.attack.updateDelayTimer.flush() def updateAttackTraceLimits(self): self.attack.setTraceLimits(self.cwGUI.api.project().traceManager().numTraces(), self.cwGUI.api.project().traceManager().numPoints()) def editorControl(self, filename, filedesc, default=False, bringToFront=True): """This is the call-back from the script editor file list, which opens editors""" # Find filename thisEditor = None for e in self.scriptList: if e['filename'] == filename: thisEditor = e break if thisEditor is None: thisEditor = {'widget':MainScriptEditor(parent=self.cwGUI, filename=filename)} thisEditor['filename'] = filename thisEditor['dockname'] = filedesc self.scriptList.append(thisEditor) # Update all docks if required thisEditor['dockname'] = filedesc self.editorDocks() if bringToFront: thisEditor['dock'].show() thisEditor['dock'].raise_() if default: # Set as default for attacks etc self.defaultEditor = thisEditor def editorDocks(self): """Ensure we have a script editor window for each referenced analyzer script file""" for script in self.scriptList: dockname = "Analysis Script: %s" % script['dockname'] # No previous dock, do setup if 'dock' not in script.keys(): self.__runScriptConverter = partial(self.runScriptFunction, filename=script['filename']) script['widget'].editWindow.runFunction.connect(self.__runScriptConverter) script['dock'] = self.cwGUI.addDock(script['widget'], name=dockname, area=Qt.BottomDockWidgetArea) script['dock'].setWindowTitle(dockname) def getPreprocessing(self, num): return self.preprocessingListGUI[num] @setupSetParam("") def setPreprocessing(self, num, module): """Insert the preprocessing module selected from the GUI into the list of active modules. This ensures that the options for that module are then displayed in the GUI, along with writing the auto-generated script. """ #Walk backwards to find previous trace source last_trace_src = self.cwGUI.api.project().traceManager() for i in range(num, 0, -1): if self.preprocessingListGUI[i] is not None: last_trace_src = self.preprocessingListGUI[i] break if self.preprocessingListGUI[num] is not None: self.preprocessingListGUI[num].deregister() self.preprocessingParams.getChild('Pre-Processing Mod. #%d'% num).delete() if module: self.preprocessingListGUI[num] = module(traceSource=last_trace_src) self.preprocessingListGUI[num].scriptsUpdated.connect(self.reloadScripts) par = Parameter(name = 'Pre-Processing Mod. #%d'% num, type = "group") par.append(self.preprocessingListGUI[num].getParams()) self.preprocessingParams.append(par) else: self.preprocessingListGUI[num] = None self.reloadScripts() def getAttack(self): return self.attack @setupSetParam(["Attack","Module"]) def setAttack(self, module): self.attack = module if module: self.updateAttackTraceLimits() self.reloadScripts() self.attack.scriptsUpdated.connect(self.reloadScripts) self.attack.runScriptFunction.connect(self.runScriptFunction) def runScriptFunction(self, funcName, filename=None): """Loads a given script and runs a specific function within it.""" mod = self.setupScriptModule(filename) self.cwGUI.api.runScriptModule(mod, funcName) def setupScriptModule(self, filename=None): """Loads a given script as a module for dynamic run-time insertion. Args: filename (str): The full filename to open. If None it opens the auto-generated script instead. """ if filename and filename != self.defaultEditor['filename']: raise Warning("Script Error: Cannot run script from non-default function") return self.defaultEditor['widget'].loadModule() def reloadScripts(self): """Rewrite the auto-generated analyzer script, using settings from the GUI""" if self.cwGUI.api.executingScripts.value(): self.cwGUI.api.executingScripts.connect(self.reloadScripts) return self.cwGUI.api.executingScripts.disconnect(self.reloadScripts) # Auto-Generated is always first mse = self.scriptList[0]['widget'] mse.saveSliderPosition() mse.editWindow.clear() mse.append("# Date Auto-Generated: %s" % datetime.now().strftime('%Y.%m.%d-%H.%M.%S'), 0) mse.append("from chipwhisperer.common.api.CWCoreAPI import CWCoreAPI", 0) mse.append("from chipwhisperer.common.scripts.base import UserScriptBase", 0) # Get imports from preprocessing mse.append("# Imports from Preprocessing", 0) mse.append("import chipwhisperer.analyzer.preprocessing as preprocessing", 0) for p in self.preprocessingListGUI: if p: imports = p.getImportStatements() for i in imports: mse.append(i, 0) # Get imports from attack mse.append("# Imports from Attack", 0) if self.attack: for i in self.attack.getImportStatements(): mse.append(i, 0) # Some other imports mse.append("# Imports from utilList", 0) for index, util in enumerate(self.utilList): if util.findParam("enabled").getValue(): for i in util.getImportStatements(): mse.append(i, 0) mse.append("", 0) # Add main class mse.append("class UserScript(UserScriptBase):", 0) mse.append("name = \"Auto-generated\"",1) mse.append("description = \"Auto-generated Attack Script\"",1) mse.append("def __init__(self, api):", 1) mse.append("UserScriptBase.__init__(self, api)") mse.append("self.initProject()") mse.append("self.initPreprocessing()") mse.append("self.initAnalysis()") mse.append("self.initReporting()") mse.append("def initProject(self):", 1) mse.append("pass") mse.append("def initPreprocessing(self):", 1) # Get init from preprocessing lastOutput = "self.api.project().traceManager()" for i, p in enumerate(self.preprocessingListGUI): if p and p.getName() != "None": classname = type(p).__name__ instname = "ppMod%d" % i mse.append("%s = preprocessing.%s.%s(%s)" % (instname, classname, classname, lastOutput)) for s in p.getStatements('init'): mse.append(s.replace("self.", instname + ".").replace("UserScript.", "self.")) mse.append("%s.init()" % (instname)) lastOutput = instname mse.append("self.traces = %s" % lastOutput) # Get init from analysis mse.append("def initAnalysis(self):", 1) if self.attack: mse.append('self.attack = %s()' % type(self.attack).__name__) for s in self.attack.getStatements('init'): mse.append(s.replace("self.", "self.attack.").replace("UserScript.", "self.")) else: mse.append('pass') # Get init from reporting mse.append("def initReporting(self):", 1) mse.append("# Configures the attack observers (usually a set of GUI widgets)") if len(ResultsBase.registeredObjects)>0: for k, v in ResultsBase.registeredObjects.iteritems(): if hasattr(v,"setTraceSource"): mse.append("self.api.getResults(\"%s\").setTraceSource(self.traces)" % k) if hasattr(v,"setAnalysisSource"): mse.append("self.api.getResults(\"%s\").setAnalysisSource(self.attack)" % k) else: mse.append("pass") # Do the attack mse.append("def run(self):", 1) mse.append("self.attack.processTraces()") # Get other commands from attack module if self.attack: for k in self.attack._smartstatements: if k == 'init' or k == 'go' or k == 'done': pass else: mse.append("def %s(self):" % k, 1) for s in self.attack.getStatements(k): mse.append(s.replace("self.", "self.attack.").replace("UserScript.", "self.")) # Get other commands from other utilities for index, util in enumerate(self.utilList): if util.findParam("enabled").getValue(): for k in util._smartstatements: util._smartstatements[k].addSelfReplacement("utilList[%d]." % index) util._smartstatements[k].addSelfReplacement("cwagui.attackScriptGen.") #TODO-temp hack statements = util.getStatements(k) if len(statements) > 0: mse.append("def %s_%s(self):" % (util.__class__.__name__, k), 1) mse.append("self.cwagui = CWAnalyzerGUI.getInstance()") #TODO - temp hack for s in statements: mse.append(s.replace("UserScript.", "self.")) mse.append("if __name__ == '__main__':\n" " import chipwhisperer.analyzer.ui.CWAnalyzerGUI as cwa\n" " from chipwhisperer.common.utils.parameter import Parameter\n" " Parameter.usePyQtGraph = True # Comment if you don't need the GUI\n" " api = CWCoreAPI() # Instantiate the API\n" " app = cwa.makeApplication(\"Analyzer\") # Comment if you don't need the GUI\n" " gui = cwa.CWAnalyzerGUI(api) # Comment if you don't need the GUI\n" " gui.show() # Comment if you don't need the GUI\n" " api.runScriptClass(UserScript) # Run UserScript through the API\n" " app.exec_() # Comment if you don't need the GUI\n", 0) mse.restoreSliderPosition() self.cwGUI.api.runScriptModule(self.setupScriptModule(), None)
class ChipWhispererComm(Parameterized): _name = "Sakurag" CODE_READ = 0x80 CODE_WRITE = 0xC0 ADDR_STATUS = 49 ADDR_FIFO = 50 FLAG_RESET = 0x01 FLAG_WRFULL = 0x02 FLAG_RDEMPTY = 0x04 def __init__(self, standalone=False): self.standalone = standalone self.serialnum = None self.params = Parameter(name=self.getName(), type='group') if standalone: self.setSerial = self._setSerial def _setSerial(self, serialnum): self.serialnum = serialnum def reset(self): self.oa.sendMessage(self.CODE_WRITE, self.ADDR_STATUS, [self.FLAG_RESET], Validate=False) time.sleep(0.05) self.oa.sendMessage(self.CODE_WRITE, self.ADDR_STATUS, [0x00], Validate=False) def con(self, scope = None): if scope and scope.qtadc and scope.qtadc.sc: self.oa = scope.qtadc.sc else: if self.serialnum is not None: self.qtadc = openadc_qt.OpenADCQt() self.params.append(self.qtadc.getParams()) self.oaiface = ftdi.OpenADCInterface_FTDI(None, self.qtadc) self.params.append(self.oaiface.getParams()) self.oaiface.setSerialNumberLimits([self.serialnum]) self.oaiface.setSelectedDevice(self.serialnum) self.oaiface.con() self.oa = self.qtadc.sc else: raise Warning("No OpenADC detected - did you connect in scope module already and/or set serial number (hit 'REFRESH')?") # Reset AES Core self.oa.sendMessage(self.CODE_WRITE, self.ADDR_STATUS, [self.FLAG_RESET], Validate=False) self.oa.sendMessage(self.CODE_WRITE, self.ADDR_STATUS, [0x00], Validate=False) return True def disconnect(self): return def flush(self): while (self.readStatus() & self.FLAG_RDEMPTY) != self.FLAG_RDEMPTY: self.oa.sendMessage(self.CODE_READ, self.ADDR_FIFO, Validate=False) def readStatus(self): b = self.oa.sendMessage(self.CODE_READ, self.ADDR_STATUS, Validate=False) return b[0] def writeMsg(self, msg): for b in msg: # while (self.readStatus() & self.FLAG_WRFULL) == self.FLAG_WRFULL: # pass self.oa.sendMessage(self.CODE_WRITE, self.ADDR_FIFO, [b], Validate=False) def readMsg(self, nbytes): msg = bytearray() for i in range(0, nbytes): if self.readStatus() & self.FLAG_RDEMPTY: pass b = self.oa.sendMessage(self.CODE_READ, self.ADDR_FIFO, Validate=False) msg.append(b[0]) return msg def write(self, address, MSB, LSB): msg = bytearray(5) msg[0] = 0x01 msg[1] = (address >> 8) & 0xFF # MSB msg[2] = address & 0xFF # LSB msg[3] = MSB msg[4] = LSB # msg = bytearray(strmsg) # print "Write: %x %x %x %x %x"%(msg[0],msg[1],msg[2],msg[3],msg[4]) self.writeMsg(msg) def read(self, address): self.flush() msg = bytearray(3) msg[0] = 0x00 msg[1] = (address >> 8) & 0xFF # MSB msg[2] = address & 0xFF # LSB self.writeMsg(msg) # print "Write: %x %x %x"%(msg[0],msg[1],msg[2]), msg = self.readMsg(2) # print " Read: %x %x"%(msg[0],msg[1]) # Order = MSB, LSB return msg def read128(self, address): self.flush() msg = bytearray(3 * 8) for i in range(0, 8): msg[i * 3] = 0x00 msg[i * 3 + 1] = (address >> 8) & 0xFF msg[i * 3 + 2] = (address & 0xFF) + (i * 2) self.writeMsg(str(msg)) msg = self.readMsg(16) return bytearray(msg) def close(self): pass
class AttackScriptGen(Parameterized): _name = "Attack Script Generator" def __init__(self, cwGUI): self.cwGUI = cwGUI self.locked = False self.utilList = [] self.scriptList = [] self.scriptList.append({'widget': MainScriptEditor(self.cwGUI)}) self.scriptList[0]['filename'] = self.scriptList[0]['widget'].filename self.scriptList[0]['dockname'] = 'Auto-Generated' self.defaultEditor = self.scriptList[0] autogen = (self.defaultEditor['dockname'], self.defaultEditor['filename']) self.preprocessingListGUI = [None, None, None, None] self.setAttack(self.cwGUI.api.valid_attacks.get("CPA", None), blockSignal=True) self.getParams().addChildren([ { 'name': 'Attack Script', 'type': 'group', 'children': [ { 'name': 'Filename', 'key': 'attackfilelist', 'type': 'filelist', 'values': { autogen: 0 }, 'value': 0, 'editor': self.editorControl, }, ] }, { 'name': 'Pre-Processing', 'type': 'group', 'children': [{ 'name': 'Module #%d' % step, 'type': 'list', 'values': self.cwGUI.api.valid_preprocessingModules, 'get': partial(self.getPreprocessing, step), 'set': partial(self.setPreprocessing, step) } for step in range(0, len(self.preprocessingListGUI))] }, { 'name': 'Attack', 'type': 'group', 'children': [ { 'name': 'Module', 'type': 'list', 'values': self.cwGUI.api.valid_attacks, 'get': self.getAttack, 'set': self.setAttack }, ] }, ]) self.params.init() self.preprocessingParams = Parameter(name="Preprocessing", type='group') self.attackParams = Parameter(name="Attack", type='group') self.params.getChild(['Attack', 'Module' ]).stealDynamicParameters(self.attackParams) def projectChanged(self): if self.attack: self.attack.findParam('input').setValue( TraceSource.registeredObjects["Trace Management"]) def flushTimer(self): """Flush all pending script updates""" [ p.updateDelayTimer.flush() for p in self.preprocessingListGUI if p is not None ] self.attack.updateDelayTimer.flush() def editorControl(self, filename, filedesc, default=False, bringToFront=True): """This is the call-back from the script editor file list, which opens editors""" # Find filename thisEditor = None for e in self.scriptList: if e['filename'] == filename: thisEditor = e break if thisEditor is None: thisEditor = { 'widget': MainScriptEditor(parent=self.cwGUI, filename=filename) } thisEditor['filename'] = filename thisEditor['dockname'] = filedesc self.scriptList.append(thisEditor) # Update all docks if required thisEditor['dockname'] = filedesc self.editorDocks() if bringToFront: thisEditor['dock'].show() thisEditor['dock'].raise_() if default: # Set as default for attacks etc self.defaultEditor = thisEditor def editorDocks(self): """Ensure we have a script editor window for each referenced analyzer script file""" for script in self.scriptList: dockname = "Analysis Script: %s" % script['dockname'] # No previous dock, do setup if 'dock' not in script.keys(): self.__runScriptConverter = partial( self.runScriptFunction, filename=script['filename']) script['widget'].editWindow.runFunction.connect( self.__runScriptConverter) script['dock'] = self.cwGUI.addDock( script['widget'], name=dockname, area=Qt.BottomDockWidgetArea) script['dock'].setWindowTitle(dockname) def getPreprocessing(self, num): return self.preprocessingListGUI[num] @setupSetParam("") def setPreprocessing(self, num, module): """Insert the preprocessing module selected from the GUI into the list of active modules. This ensures that the options for that module are then displayed in the GUI, along with writing the auto-generated script. """ #Walk backwards to find previous trace source last_trace_src = self.cwGUI.api.project().traceManager() for i in range(num, 0, -1): if self.preprocessingListGUI[i] is not None: last_trace_src = self.preprocessingListGUI[i] break if self.preprocessingListGUI[num] is not None: self.preprocessingListGUI[num].deregister() self.preprocessingParams.getChild('Pre-Processing Mod. #%d' % num).delete() if module: self.preprocessingListGUI[num] = module(traceSource=last_trace_src) self.preprocessingListGUI[num].scriptsUpdated.connect( self.reloadScripts) par = Parameter(name='Pre-Processing Mod. #%d' % num, type="group") par.append(self.preprocessingListGUI[num].getParams()) self.preprocessingParams.append(par) else: self.preprocessingListGUI[num] = None self.reloadScripts() def getAttack(self): return self.attack @setupSetParam(["Attack", "Module"]) def setAttack(self, module): self.attack = module if module: self.reloadScripts() self.attack.scriptsUpdated.connect(self.reloadScripts) self.attack.runScriptFunction.connect(self.runScriptFunction) self.attack.findParam('input').setValue( TraceSource.registeredObjects["Trace Management"]) def runScriptFunction(self, funcName, filename=None): """Loads a given script and runs a specific function within it.""" mod = self.setupScriptModule(filename) self.cwGUI.api.runScriptModule(mod, funcName) def setupScriptModule(self, filename=None): """Loads a given script as a module for dynamic run-time insertion. Args: filename (str): The full filename to open. If None it opens the auto-generated script instead. """ if filename and filename != self.defaultEditor['filename']: raise Warning( "Script Error: Cannot run script from non-default function") return self.defaultEditor['widget'].loadModule() def reloadScripts(self): """Rewrite the auto-generated analyzer script, using settings from the GUI""" if self.cwGUI.api.executingScripts.value(): self.cwGUI.api.executingScripts.connect(self.reloadScripts) return self.cwGUI.api.executingScripts.disconnect(self.reloadScripts) # Auto-Generated is always first mse = self.scriptList[0]['widget'] mse.saveSliderPosition() mse.editWindow.clear() mse.append( "# Date Auto-Generated: %s" % datetime.now().strftime('%Y.%m.%d-%H.%M.%S'), 0) mse.append("from chipwhisperer.common.api.CWCoreAPI import CWCoreAPI", 0) mse.append( "from chipwhisperer.common.scripts.base import UserScriptBase", 0) # Get imports from preprocessing mse.append("# Imports from Preprocessing", 0) for p in self.preprocessingListGUI: if p: imports = p.getImportStatements() for i in imports: mse.append(i, 0) # Get imports from attack mse.append("# Imports from Attack", 0) if self.attack: for i in self.attack.getImportStatements(): mse.append(i, 0) # Some other imports mse.append("# Imports from utilList", 0) for index, util in enumerate(self.utilList): if util.findParam("enabled").getValue(): for i in util.getImportStatements(): mse.append(i, 0) mse.append("", 0) # Add main class mse.append("class UserScript(UserScriptBase):", 0) mse.append("_name = \"Auto-generated\"", 1) mse.append("_description = \"Auto-generated Attack Script\"", 1) mse.append("def __init__(self, api):", 1) mse.append("UserScriptBase.__init__(self, api)") mse.append("self.initProject()") mse.append("self.initPreprocessing()") mse.append("self.initAnalysis()") mse.append("self.initReporting()") mse.append("def initProject(self):", 1) mse.append("pass") mse.append("def initPreprocessing(self):", 1) # Get init from preprocessing lastOutput = "self.api.project().traceManager()" for i, p in enumerate(self.preprocessingListGUI): if p and p.getName() != "None": classname = type(p).__name__ instname = "ppMod%d" % i mse.append( "%s = %s.%s(%s)" % (instname, sys.modules[p.__class__.__module__].__name__, classname, lastOutput)) for s in p.getStatements('init'): mse.append( s.replace("self.", instname + ".").replace( "UserScript.", "self.")) mse.append("%s.init()" % (instname)) lastOutput = instname mse.append("self.traces = %s" % lastOutput) # Get init from analysis mse.append("def initAnalysis(self):", 1) if self.attack: mse.append('self.attack = %s()' % type(self.attack).__name__) for s in self.attack.getStatements('init'): mse.append( s.replace("self.", "self.attack.").replace("UserScript.", "self.")) else: mse.append('pass') # Get init from reporting mse.append("def initReporting(self):", 1) mse.append( "# Configures the attack observers (usually a set of GUI widgets)") if len(ResultsBase.registeredObjects) > 0: for k, v in ResultsBase.registeredObjects.iteritems(): if hasattr(v, "setTraceSource"): mse.append( "self.api.getResults(\"%s\").setTraceSource(self.traces)" % k) if hasattr(v, "setAnalysisSource"): mse.append( "self.api.getResults(\"%s\").setAnalysisSource(self.attack)" % k) else: mse.append("pass") # Do the attack mse.append("def run(self):", 1) mse.append("self.attack.processTraces()") # Get other commands from attack module if self.attack: for k in self.attack._smartstatements: if k == 'init' or k == 'go' or k == 'done': pass else: mse.append("def %s(self):" % k, 1) for s in self.attack.getStatements(k): mse.append( s.replace("self.", "self.attack.").replace( "UserScript.", "self.")) # Get other commands from other utilities for index, util in enumerate(self.utilList): if util.findParam("enabled").getValue(): for k in util._smartstatements: util._smartstatements[k].addSelfReplacement( "utilList[%d]." % index) util._smartstatements[k].addSelfReplacement( "cwagui.attackScriptGen.") #TODO-temp hack statements = util.getStatements(k) if len(statements) > 0: mse.append( "def %s_%s(self):" % (util.__class__.__name__, k), 1) mse.append("self.cwagui = CWAnalyzerGUI.getInstance()" ) #TODO - temp hack for s in statements: mse.append(s.replace("UserScript.", "self.")) mse.append( "if __name__ == '__main__':\n" " import chipwhisperer.analyzer.ui.CWAnalyzerGUI as cwa\n" " from chipwhisperer.common.utils.parameter import Parameter\n" " Parameter.usePyQtGraph = True # Comment if you don't need the GUI\n" " api = CWCoreAPI() # Instantiate the API\n" " app = cwa.makeApplication(\"Analyzer\") # Comment if you don't need the GUI\n" " gui = cwa.CWAnalyzerGUI(api) # Comment if you don't need the GUI\n" " api.runScriptClass(UserScript) # Run UserScript through the API\n" " app.exec_() # Comment if you don't need the GUI\n", 0) mse.restoreSliderPosition() self.cwGUI.api.runScriptModule(self.setupScriptModule(), None)
class ChipWhispererComm(Parameterized): _name = "Sakurag" CODE_READ = 0x80 CODE_WRITE = 0xC0 ADDR_STATUS = 49 ADDR_FIFO = 50 FLAG_RESET = 0x01 FLAG_WRFULL = 0x02 FLAG_RDEMPTY = 0x04 def __init__(self, standalone=False): self.standalone = standalone self.serialnum = None self.params = Parameter(name=self.getName(), type='group') if standalone: self.setSerial = self._setSerial def _setSerial(self, serialnum): self.serialnum = serialnum def reset(self): self.oa.sendMessage(self.CODE_WRITE, self.ADDR_STATUS, [self.FLAG_RESET], Validate=False) time.sleep(0.05) self.oa.sendMessage(self.CODE_WRITE, self.ADDR_STATUS, [0x00], Validate=False) def con(self, scope=None): if scope and scope.qtadc and scope.qtadc.sc: self.oa = scope.qtadc.sc else: if self.serialnum is not None: self.qtadc = openadc_qt.OpenADCQt() self.params.append(self.qtadc.getParams()) self.oaiface = ftdi.OpenADCInterface_FTDI(None, self.qtadc) self.params.append(self.oaiface.getParams()) self.oaiface.setSerialNumberLimits([self.serialnum]) self.oaiface.setSelectedDevice(self.serialnum) self.oaiface.con() self.oa = self.qtadc.sc else: raise Warning( "No OpenADC detected - did you connect the scope module and/or set serial number (hit 'REFRESH')?" ) # Reset AES Core self.oa.sendMessage(self.CODE_WRITE, self.ADDR_STATUS, [self.FLAG_RESET], Validate=False) self.oa.sendMessage(self.CODE_WRITE, self.ADDR_STATUS, [0x00], Validate=False) return True def disconnect(self): return def flush(self): while (self.readStatus() & self.FLAG_RDEMPTY) != self.FLAG_RDEMPTY: self.oa.sendMessage(self.CODE_READ, self.ADDR_FIFO, Validate=False) def readStatus(self): b = self.oa.sendMessage(self.CODE_READ, self.ADDR_STATUS, Validate=False) return b[0] def writeMsg(self, msg): for b in msg: # while (self.readStatus() & self.FLAG_WRFULL) == self.FLAG_WRFULL: # pass self.oa.sendMessage(self.CODE_WRITE, self.ADDR_FIFO, [b], Validate=False) def readMsg(self, nbytes): msg = bytearray() for i in range(0, nbytes): if self.readStatus() & self.FLAG_RDEMPTY: pass b = self.oa.sendMessage(self.CODE_READ, self.ADDR_FIFO, Validate=False) msg.append(b[0]) return msg def write(self, address, MSB, LSB): msg = bytearray(5) msg[0] = 0x01 msg[1] = (address >> 8) & 0xFF # MSB msg[2] = address & 0xFF # LSB msg[3] = MSB msg[4] = LSB # msg = bytearray(strmsg) # print "Write: %x %x %x %x %x"%(msg[0],msg[1],msg[2],msg[3],msg[4]) self.writeMsg(msg) def read(self, address): self.flush() msg = bytearray(3) msg[0] = 0x00 msg[1] = (address >> 8) & 0xFF # MSB msg[2] = address & 0xFF # LSB self.writeMsg(msg) # print "Write: %x %x %x"%(msg[0],msg[1],msg[2]), msg = self.readMsg(2) # print " Read: %x %x"%(msg[0],msg[1]) # Order = MSB, LSB return msg def read128(self, address): self.flush() msg = bytearray(3 * 8) for i in range(0, 8): msg[i * 3] = 0x00 msg[i * 3 + 1] = (address >> 8) & 0xFF msg[i * 3 + 2] = (address & 0xFF) + (i * 2) self.writeMsg(str(msg)) msg = self.readMsg(16) return bytearray(msg) def close(self): pass
class PreprocessingSettings(Parameterized): _num_modules = 4 def __init__(self, api): self._api = api self.valid_preprocessingModules = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.analyzer.preprocessing", False, False) self.params = Parameter(name="Preprocessing Settings", type='group') self._moduleParams = [ Parameter(name='self.ppmod[%d]' % (i), type='group') for i in range(self._num_modules) ] self._initModules() self.params.addChildren([ {'name':'Selected Modules', 'type':'group', 'children':[ {'name':'self.ppmod[%d]' % (step), 'type':'list', 'values':self.valid_preprocessingModules, 'get':partial(self.getModule, step), 'set':partial(self.setModule, step)} for step in range(0, len(self._modules)) ]}, ]) for m in self._moduleParams: self.params.append(m) def _initModules(self): self._modules = [None]*self._num_modules for i in range(self._num_modules): mod = PassThrough(name="Preprocessing Module ppmod[%d]" % (i)) self.setModule(i, mod) def getModule(self, num): return self._modules[num].__class__ # TODO: calling this from the command line causes a cosmetic bug @setupSetParam("") def setModule(self, num, module): """Insert the preprocessing module selected from the GUI into the list of active modules. This ensures that the options for that module are then displayed in the GUI, along with writing the auto-generated script. """ if module is None: raise ValueError("Received None as module in setModule()" % module) if num == 0: trace_source = self._api.project().traceManager() else: trace_source = self._modules[num-1] if self._modules[num] is not None: self._modules[num].deregister() self._moduleParams[num].clearChildren() if inspect.isclass(module): module = module(name="Preprocessing Module #%d" % (num+1)) self._modules[num] = module self._modules[num].setTraceSource(trace_source) self._moduleParams[num].append(self._modules[num].getParams()) if (num+1) < len(self._modules) and self._modules[num+1] is not None: self._modules[num+1].setTraceSource(module) def __getitem__(self, idx): return self._modules[idx] def __setitem__(self, idx, module): self.setModule(idx, module) logging.warning("Selected Modules parameter list didn't update during setModule call in PreprocessingSettings") def __str__(self): return str(self._modules) def __repr__(self): return str(self)
class CWCoreAPI(Parameterized): """ ChipWisperer API Class. Provides access to the most important parts of the tool. It has a singleton method called CWCoreAPI.getInstance() that returns a reference to the API instance. """ __name__ = "ChipWhisperer" __organization__ = "NewAE Technology Inc." __version__ = "V4.0.2" _name = 'Generic Settings' instance = None def __init__(self): logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO) CWCoreAPI.instance = self self.sigNewProject = util.Signal() self.sigConnectStatus = util.Signal() self.sigAttackChanged = util.Signal() self.sigNewInputData = util.Signal() self.sigNewTextResponse = util.Signal() self.sigTraceDone = util.Signal() self.sigCampaignStart = util.Signal() self.sigCampaignDone = util.Signal() self.executingScripts = util.Observable(False) self.valid_scopes = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.scopes", True, True) self.valid_targets = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.targets", True, True) self.valid_traces = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.common.traces", True, True) self.valid_aux = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.auxiliary", True, True) self.valid_acqPatterns = pluginmanager.getPluginsInDictFromPackage("chipwhisperer.capture.acq_patterns", True, False) self.settings = Settings() # Initialize default values self._project = self._scope = self._target = self._traceFormat = self._acqPattern = self._attack = None self._acqPattern = self.valid_acqPatterns["Basic"] self._auxList = AuxList() self._numTraces = 50 self._numTraceSets = 1 # Storage for last key/plaintext/ciphertext self._lastKey = None self._lastTextin = None self._lastTextout = None self._lastExpected = None self.params = Parameter(name='Generic Settings', type='group', addLoadSave=True).register() self.params.addChildren([ {'name':'Scope Module', 'key':'scopeMod', 'type':'list', 'values':self.valid_scopes, 'get':self.getScope, 'set':self.setScope}, {'name':'Target Module', 'key':'targetMod', 'type':'list', 'values':self.valid_targets, 'get':self.getTarget, 'set':self.setTarget}, {'name':'Acquisition Settings', 'type':'group', 'children':[ {'name':'Number of Traces', 'type':'int', 'limits':(1, 1E9), 'get':self.getNumTraces, 'set':self.setNumTraces, 'linked':['Traces per Set']}, {'name':'Number of Sets', 'type':'int', 'limits':(1, 1E6), 'get':self.getNumTraceSets, 'set':self.setNumTraceSets, 'linked':['Traces per Set'], 'tip': 'Break acquisition into N sets, ' 'which may cause data to be saved more frequently. The default capture driver requires that NTraces/NSets is small enough to avoid running out of system memory ' 'as each segment is buffered into RAM before being written to disk.'}, {'name':'Traces per Set', 'type':'int', 'readonly':True, 'get':self.tracesPerSet}, {'name':'Key/Text Pattern', 'type':'list', 'values':self.valid_acqPatterns, 'get':self.getAcqPattern, 'set':self.setAcqPattern}, ]}, ]) self.scopeParam = Parameter(name="Scope Settings", type='group', addLoadSave=True).register() self.params.getChild('Scope Module').stealDynamicParameters(self.scopeParam) self.targetParam = Parameter(name="Target Settings", type='group', addLoadSave=True).register() self.params.getChild('Target Module').stealDynamicParameters(self.targetParam) # Aux settings self.auxParam = self._auxList.getParams().register() # Note: Project settings are set up in setProject() self.newProject() def updateLastKeyText(self, key, textin, textout, exp): """Callback for acq controller signal - update key/textin/textout """ self._lastKey = key self._lastTextin = textin self._lastTextout = textout self._lastExpected = exp self.sigNewTextResponse.emit(key, textin, textout, exp) def getResults(self, name): """Return the requested result widget. It should be registered.""" return ResultsBase.registeredObjects[name] def getScope(self): """Return the current scope module object.""" return self._scope @setupSetParam("Scope Module") def setScope(self, driver): """Set the current scope module object.""" if self.getScope(): # Don't do anything if we're not changing scopes if self.getScope() is driver: return else: self.getScope().dis() self._scope = driver if self.getScope(): self.getScope().connectStatus.connect(self.sigConnectStatus.emit) self.scopeParam.append(self.getScope().params) try: ResultsBase.registeredObjects["Trace Output Plot"].setTraceSource( TraceSource.registeredObjects[next(reversed(TraceSource.registeredObjects))]) except KeyError: pass if self.getScope().getStatus(): self.getScope().connectStatus.emit() def getTarget(self): """Return the current target module object.""" return self._target @setupSetParam("Target Module") def setTarget(self, driver): """Set the current target module object.""" if self.getTarget(): # Don't do anything if we're not changing targets if self.getTarget() is driver: return self.getTarget().dis() self._target = driver if self.getTarget(): self.targetParam.append(self.getTarget().params) self.getTarget().newInputData.connect(self.sigNewInputData.emit) self.getTarget().connectStatus.connect(self.sigConnectStatus.emit) if self.getTarget().getStatus(): self.getTarget().connectStatus.emit() def getAuxList(self): return self._auxList def setAuxList(self, new_list): self._auxList = new_list def getAuxFunctions(self, only_enabled): """TODO: doc """ return self._auxList.getDict(only_enabled) def getAcqPattern(self): """Return the selected acquisition pattern.""" return self._acqPattern def getAttack(self): return self._attack @setupSetParam(["Attack Settings", "Attack"]) def setAttack(self, atk): self._attack = atk #if self._attack is not None: # self.attackParam.append(self._attack.params) @setupSetParam(["Acquisition Settings", "Key/Text Pattern"]) def setAcqPattern(self, pat): """Set the current acquisition pattern.""" self._acqPattern = pat if self._acqPattern is not None: self._acqPattern.getParams().remove() self.getParams().append(self._acqPattern.getParams()) def getNewTrace(self, format): """Return a new trace object for the specified format.""" if format is None: raise Warning("No trace format selected.") tmp = copy.copy(format) tmp.clear() starttime = datetime.now() prefix = starttime.strftime('%Y.%m.%d-%H.%M.%S') + "_" tmp.config.setConfigFilename(CWCoreAPI.getInstance().project().datadirectory + "traces/config_" + prefix + ".cfg") tmp.config.setAttr("prefix", prefix) tmp.config.setAttr("date", starttime.strftime('%Y-%m-%d %H:%M:%S')) return tmp def getTraceFormat(self): """Return the selected trace format.""" if self._project is not None: return self._project.getTraceFormat() else: return None def setTraceFormat(self, format): """Set the current trace format for acquisition.""" if self._project is not None: self._project.setTraceFormat(format) def project(self): """Return the current opened project""" return self._project def setProject(self, proj): """Set the current opened project""" self._project = proj self.params.append(proj.getParams()) self.sigNewProject.emit() def newProject(self): """Create a new project""" self.setProject(ProjectFormat(self.__name__, self.__version__)) def openProject(self, fname): """Open project file""" self.newProject() self.project().load(fname) try: ResultsBase.registeredObjects["Trace Output Plot"].setTraceSource(TraceSource.registeredObjects["Trace Management"]) except KeyError: pass def saveProject(self, fname=None): """Save the current opened project to file""" if fname is not None: self.project().setFilename(fname) self.project().save() def connectScope(self): """Connect to the selected scope""" try: if self.getScope(): self.getScope().con() try: # Sets the Plot Widget input (if it exists) to the last added TraceSource ResultsBase.registeredObjects["Trace Output Plot"].setTraceSource( TraceSource.registeredObjects[next(reversed(TraceSource.registeredObjects))]) except KeyError: pass except Warning: sys.excepthook(*sys.exc_info()) return False return True def disconnectScope(self): """Disconnect the current scope""" self.getScope().dis() def connectTarget(self): """Connect to the selected target""" try: if self.getTarget(): self.getTarget().con(scope=self.getScope()) except Warning: sys.excepthook(*sys.exc_info()) return False return True def disconnectTarget(self): """Disconnect the current target""" self.getTarget().dis() def doConDis(self): """DEPRECATED: It is here just for compatibility reasons""" logging.warning('Method doConDis() is deprecated... use connect() or disconnect() instead') return self.connect() def connect(self): """Connect both: scope and target""" return self.connectScope() and self.connectTarget() def disconnect(self): """Disconnect both: scope and target""" self.disconnectScope() self.disconnectTarget() def getNumTraces(self): """Return the total number or traces for acquisition purposes""" return self._numTraces @setupSetParam(["Acquisition Settings", "Number of Traces"]) def setNumTraces(self, n): """Set the total number or traces for acquisition purposes""" self._numTraces = n def getNumTraceSets(self): """Return the number of sets/segments""" return self._numTraceSets @setupSetParam(["Acquisition Settings", "Number of Sets"]) def setNumTraceSets(self, s): """Set the number of sets/segments""" self._numTraceSets = s def tracesPerSet(self): """Return the number of traces in each set/segment""" return int(self._numTraces / self._numTraceSets) def capture1(self): """Capture one trace""" try: aux_dict = self.getAuxFunctions(True) ac = AcquisitionController(self.getScope(), self.getTarget(), writer=None, aux=aux_dict, keyTextPattern=self.getAcqPattern()) ac.sigNewTextResponse.connect(self.updateLastKeyText) if self.getTarget(): self.getTarget().init() return ac.doSingleReading() except Warning: sys.excepthook(*sys.exc_info()) return False def captureM(self, progressBar=None, scope=None, target=None, project=None, aux_list=None, ktp=None, N=1, seg_size=None): """Capture multiple traces and save its result""" if not progressBar: progressBar = ProgressBarText() if seg_size is None: seg_size = 1000 trace_mgr = project.traceManager() if project is not None else None trace_fmt = project.getTraceFormat() if project is not None else None aux_dict = aux_list.getDict(True) if aux_list is not None else None segments = int(math.ceil(N / float(seg_size))) with progressBar: progressBar.setStatusMask("Current Segment = %d Current Trace = %d", (0,0)) progressBar.setMaximum(N) waveBuffer = None tcnt = 0 for i in range(0, segments): if progressBar.wasAborted(): break this_seg_size = min(seg_size, N - i*seg_size) if trace_fmt is not None: currentTrace = self.getNewTrace(trace_fmt) # Load trace writer information prefix = currentTrace.config.attr("prefix")[:-1] currentTrace.config.setAttr("targetHW", target.getName() if target is not None else "None") currentTrace.config.setAttr("targetSW", os.path.split(Programmer.lastFlashedFile)[1]) currentTrace.config.setAttr("scopeName", scope.getName() if scope is not None else "None") notes_str = "AckPattern: " + str(ktp) + "; " notes_str += "Aux: " if aux_dict is not None: for t in aux_dict.keys(): notes_str += "%s" % t + ", ".join([str(item) for item in aux_dict[t] if item]) currentTrace.config.setAttr("notes", notes_str) currentTrace.setTraceHint(this_seg_size) if waveBuffer is not None: currentTrace.setTraceBuffer(waveBuffer) else: currentTrace = None prefix = datetime.now().strftime('%Y.%m.%d-%H.%M.%S') if aux_dict is not None: for func in aux_dict['set_prefix']: func(prefix) ac = AcquisitionController(scope, target, currentTrace, aux_dict, ktp) ac.setMaxtraces(this_seg_size) ac.sigNewTextResponse.connect(self.updateLastKeyText) ac.sigTraceDone.connect(self.sigTraceDone.emit) __pb = lambda: progressBar.updateStatus(i*seg_size + ac.currentTrace + 1, (i, ac.currentTrace)) ac.sigTraceDone.connect(__pb) self.sigCampaignStart.emit(prefix) ac.doReadings(tracesDestination=trace_mgr, progressBar=progressBar) if currentTrace is not None: project.saveAllSettings(os.path.dirname(currentTrace.config.configFilename()) + "/%s_settings.cwset" % prefix, onlyVisibles=True) waveBuffer = currentTrace.traces # Re-use the wave buffer to avoid memory reallocation self.sigCampaignDone.emit() tcnt += seg_size if progressBar.wasAborted(): break if currentTrace is not None: currentTrace.unloadAllTraces() # Required in order to make the GC work properly :( trace_fmt.unloadAllTraces() return True def runScriptModule(self, mod, funcName="run"): """Execute the function in the Plugin classes of the specified module""" try: classes = pluginmanager.getPluginClassesFromModules([mod]) if len(classes) == 0: raise Warning("No UserScriptBase class found") return [self.runScriptClass(c, funcName) for c in classes] except Exception as e: sys.excepthook(Warning, "Could not execute Script Module %s: '%s:%s'" % (str(mod), "".join(traceback.format_exception_only(sys.exc_info()[0], e.message)).rstrip("\n "), str(e).rstrip("\n ") ), sys.exc_info()[2]) def runScriptClass(self, scriptClass, funcName="run"): """Execute the funcName function in the specified class.""" try: self.executingScripts.setValue(True) m = scriptClass(self) if funcName is not None: return eval('m.%s()' % funcName) except Exception as e: sys.excepthook(Warning, "Could not execute method %s in script class %s: '%s:%s'" % (funcName, scriptClass.__name__, "".join(traceback.format_exception_only(sys.exc_info()[0], e.message)).rstrip("\n "), str(e).rstrip("\n ") ), sys.exc_info()[2]) finally: self.executingScripts.setValue(False) def getParameter(self, path): """Return the value of a registered parameter""" return Parameter.getParameter(path) def setParameter(self, pathAndValue): """Set the parameter value, given its path. It should be registered in Parameter.registeredParameters""" Parameter.setParameter(pathAndValue) @staticmethod def getInstance(): """Implements the singleton pattern/anti-pattern. Returns a reference to the API instance.""" return CWCoreAPI.instance def getLastKey(self): return self._lastKey def getLastTextin(self): return self._lastTextin def getLastTextout(self): return self._lastTextout def getLastExpected(self): return self._lastExpected
class TraceExplorerDialog(AutoScript, Parameterized): """Open dialog to explore trace properties, data graphs, etc""" _name = "Trace Explorer" def __init__(self, parent): AutoScript.__init__(self) self.enabled = False self.autoScriptInit() # Add example scripts to this list self.exampleScripts = [PartitionDisplay(self), TextDisplay(self)] # Add Scripts self.setupCommonScripts() self.progressBar = ProgressBar(show=False) def setupCommonScripts(self): # Setup parameer tree self.getParams().addChildren([{ 'name': 'Enabled', 'key': 'enabled', 'type': 'bool', 'default': self.getEnabled(), 'get': self.getEnabled, 'set': self.setEnabled }]) self.commonScriptParams = [] self.paramCommonScripts = Parameter(name='Common Scripts', type='group', children=self.commonScriptParams) for example in self.exampleScripts: self.paramCommonScripts.append(example.getParams()) example.scriptsUpdated.connect(self.updateScripts) example.runScriptFunction.connect(self.runScriptFunction.emit) self.getParams().append(self.paramCommonScripts) self.paramCommonScripts.hide() self.updateScripts() def getEnabled(self): return self.enabled @setupSetParam("Enabled") def setEnabled(self, enabled): self.enabled = enabled self.paramCommonScripts.show(enabled) self.updateChildren() ####COMMON SCRIPTING STUFF def getProgressIndicator(self): return self.progressBar def updateChildren(self): for example in self.exampleScripts: if hasattr(example, 'updateScript'): example.updateScript("traceexplorer_show") self.updateScripts() def updateScripts(self): for index, example in enumerate(self.exampleScripts): if hasattr(example, "_smartstatements"): for k in example._smartstatements: statements = example.getStatements(k) if len(statements) > 0: prefix = example.__class__.__name__ + "_" self._smartstatements[prefix + k] = example._smartstatements[k] self._smartstatements[prefix + k].addSelfReplacement( "exampleScripts[%d]." % index) for k in example.getImportStatements(): self.importsAppend(k) self.scriptsUpdated.emit()
class TraceExplorerDialog(AutoScript, Parameterized): """Open dialog to explore trace properties, data graphs, etc""" _name = "Trace Explorer" def __init__(self, parent): AutoScript.__init__(self) self.enabled = False self.autoScriptInit() # Add example scripts to this list self.exampleScripts = [PartitionDisplay(self), TextDisplay(self)] # Add Scripts self.setupCommonScripts() self.progressBar = ProgressBar(show=False) def setupCommonScripts(self): # Setup parameer tree self.getParams().addChildren([ {'name':'Enabled', 'key':'enabled', 'type':'bool', 'default':self.getEnabled(), 'get':self.getEnabled, 'set':self.setEnabled} ]) self.commonScriptParams = [] self.paramCommonScripts = Parameter(name='Common Scripts', type='group', children=self.commonScriptParams) for example in self.exampleScripts: self.paramCommonScripts.append(example.getParams()) example.scriptsUpdated.connect(self.updateScripts) example.runScriptFunction.connect(self.runScriptFunction.emit) self.getParams().append(self.paramCommonScripts) self.paramCommonScripts.hide() self.updateScripts() def getEnabled(self): return self.enabled @setupSetParam("Enabled") def setEnabled(self, enabled): self.enabled = enabled self.paramCommonScripts.show(enabled) self.updateChildren() ####COMMON SCRIPTING STUFF def getProgressIndicator(self): return self.progressBar def updateChildren(self): for example in self.exampleScripts: if hasattr(example, 'updateScript'): example.updateScript("traceexplorer_show") self.updateScripts() def updateScripts(self): for index, example in enumerate(self.exampleScripts): if hasattr(example, "_smartstatements"): for k in example._smartstatements: statements = example.getStatements(k) if len(statements) > 0: prefix = example.__class__.__name__ + "_" self._smartstatements[prefix + k] = example._smartstatements[k] self._smartstatements[prefix + k].addSelfReplacement("exampleScripts[%d]." % index) for k in example.getImportStatements(): self.importsAppend(k) self.scriptsUpdated.emit()