class GraphletsConstraints(RWEngineBase):

    __printConds = False

    def __init__(self, nodeGradesInfos):
        self.nodeGradesInfos = nodeGradesInfos
        self.sol = None

    # a field is somthing seperated by " " , an argument is a list of params seperated by "," ; a member is a param seperated by "+"
    def breakCommand(self, cmd):
        cmdFields = seperateCmd(cmd)
        if len(cmdFields) == 0:
            print "asd"
        assert (len(cmdFields) > 0)
        if len(cmdFields) == 1:
            return {
                'nemonic': cmdFields[0],
                'nemonicWithDecoretors': " ".join(cmdFields[0:-1]),
                'ParamsList': []
            }
        else:
            return {
                'nemonic': cmdFields[0],
                'nemonicWithDecoretors': " ".join(cmdFields[0:-1]),
                'ParamsList': cmdFields[-1].split(",")
            }

    #TODO - add to this..
    lvalCmdsStarts = ["mov", "sub", "add", "xor"]

    def getNemonicType(self, nemonic):
        if any(
                map(lambda startString: nemonic.startswith(startString),
                    self.lvalCmdsStarts)):
            return "WriteThenRead"
        else:
            return "Read"

    FuncPrefix = "f"
    VARPrefix = "s"
    RegisterPrefix = "r"
    OffsetPrefix = "o"
    OtherPrefix = "X"

    def getPrefix(self, Str):
        if isVarStr(Str):
            return self.VARPrefix
        elif isRegisterStr(Str):
            return self.RegisterPrefix
        elif isOffset(Str):
            return self.OffsetPrefix
        else:
            return self.OtherPrefix

    def varsEqual(self, v1, v2):
        return v1 == v2

    def checkInputVsTarget(self, target):
        def retFunc(inputVal):
            return inputVal == target

        return retFunc

    def getVarName(self, prefix, lineNumber, varsInThisLine):
        return prefix + str(lineNumber) + "-" + str(varsInThisLine) + "_TAR"

    def getMembers(self, param):
        refMembers = param.split("+")
        refMembers[0] = refMembers[0][1:]  #remove [ from first
        refMembers[-1] = refMembers[-1][
            0:-1]  # remove ] from last (they can be the same one!)
        return refMembers

    def getDomains(self):
        domains = {
            self.FuncPrefix: set(),
            self.VARPrefix: set(),
            self.RegisterPrefix: set(),
            self.OffsetPrefix: set()
        }

        def getCmdSymbols(cmd):
            cmdBasicInfo = self.breakCommand(cmd)
            for param in cmdBasicInfo['ParamsList']:
                if param.startswith("["):
                    for member in self.getMembers(param):
                        yield member
                else:
                    yield param

        def getCmds(cmdsDelimited):
            return filter(None, cmdsDelimited.split(";"))

        for cmdList in itertools.imap(
                lambda nodeGradesInfo: getCmds(nodeGradesInfo['refCode']),
                self.nodeGradesInfos):
            for cmd in cmdList:

                if isCall(cmd):
                    prefix = self.FuncPrefix
                    domains[prefix].add(list(getCmdSymbols(cmd))[0])
                else:
                    for symbol in getCmdSymbols(cmd):
                        prefix = self.getPrefix(symbol)
                        if prefix != self.OtherPrefix:
                            domains[prefix].add(symbol)

        for domainName in domains.keys():
            domains[domainName] = list(domains[domainName])

        return domains

    def callSol(self):

        domains = self.getDomains()

        #domains[refPrefix].add(refVal)

        self.problem = Problem(MinConflictsSolver())

        tarSymbolsCache = {}

        self.varsInThisLine = 0

        def addInTraceletCons(tarVal, newVarName):
            if (self.__printConds):
                print "CONS(IN) -> " + tarSymbolsCache[
                    tarVal] + " == " + newVarName
            self.problem.addConstraint(self.varsEqual,
                                       [newVarName, tarSymbolsCache[tarVal]])

        def addCrossTraceletCons(refVal, newVarName, refPrefix):
            if (self.__printConds):
                print "CONS(CROSS) -> " + newVarName + " == " + refVal
            self.problem.addConstraint(self.checkInputVsTarget(refVal),
                                       [newVarName])

        def addVarWithPrefix(prefix, lineNumber):
            newVarName = self.getVarName(prefix, lineNumber,
                                         self.varsInThisLine)
            if len(domains[prefix]) == 0:
                print "EMP"
            self.problem.addVariables([newVarName], domains[prefix])
            self.varsInThisLine += 1
            return newVarName

        # mode can be - WRITE or NORMAL
        def doDF(refSymbol, tarSymbol, lineNumber, refPrefix, tarPrefix,
                 nemonicType):

            if refPrefix == self.OtherPrefix or tarPrefix == self.OtherPrefix:
                return

            newVarName = addVarWithPrefix(tarPrefix, lineNumber)

            if (refPrefix == tarPrefix):
                addCrossTraceletCons(refSymbol, newVarName, refPrefix)

            if tarSymbol in tarSymbolsCache:
                addInTraceletCons(tarSymbol, newVarName)

            if tarPrefix != self.RegisterPrefix or nemonicType == "WriteThenRead":
                tarSymbolsCache[tarSymbol] = newVarName

        #for matchedCmd in itertools.chain(map(lambda nodeInfo:nodeInfo['matchedCmds'],self.nodeGradesInfos)):

        tarBase = 0
        refBase = 0

        for nodeInfo in self.nodeGradesInfos:
            for matchedCmd in nodeInfo['matchedCmds']:

                self.varsInThisLine = 1

                # if these cmds are not an operational match, we cannot cross tracelet match them.
                if matchedCmd['operationMatch'] == True:

                    currentLineNumber = tarBase + matchedCmd[
                        'tarCmdNum']  #  matchedCmd['tarCmdNum'] is 1 based so we are ok

                    if matchedCmd['tar'] == "" or matchedCmd['ref'] == "":
                        continue

                    tarCmdBasicInfo = self.breakCommand(matchedCmd['tar'])
                    refCmdBasicInfo = self.breakCommand(matchedCmd['ref'])
                    if len(tarCmdBasicInfo['ParamsList']) > 0 and len(
                            refCmdBasicInfo['ParamsList']) > 0:

                        if tarCmdBasicInfo['nemonic'] == 'call':

                            assert (len(refCmdBasicInfo['ParamsList']) == 1)
                            assert (len(tarCmdBasicInfo['ParamsList']) == 1)

                            doDF(refCmdBasicInfo['ParamsList'][0],
                                 tarCmdBasicInfo['ParamsList'][0],
                                 currentLineNumber, self.FuncPrefix,
                                 self.FuncPrefix, "Read")
                        else:

                            nemonicType = self.getNemonicType(
                                tarCmdBasicInfo['nemonic'])

                            for (refParam, tarParam) in zip(
                                    refCmdBasicInfo['ParamsList'],
                                    tarCmdBasicInfo['ParamsList']):

                                tarIsMem = "[" in tarParam
                                if tarIsMem != ("[" in refParam):
                                    continue
                                    print matchedCmd
                                    print "BOY"

                                assert tarIsMem == ("[" in refParam)

                                if not tarIsMem:
                                    tarPreFix = self.getPrefix(tarParam)
                                    refPreFix = self.getPrefix(refParam)

                                    doDF(refParam, tarParam, currentLineNumber,
                                         tarPreFix, refPreFix, nemonicType)

                                    # TODO - return this to find more classes when we have time...
                                    """
                                    if nemonicType == "WriteThenRead":  
                                        if tarPreFix != self.RegisterPrefix:
                                            print matchedCmd
                                        
                                        assert (tarPreFix == self.RegisterPrefix)
                                        # the write is only to the left most param, rest are normal
                                    """
                                else:
                                    # this is memory! , first remove '[',']'

                                    for (refMember, tarMember) in zip(
                                            self.getMembers(refParam),
                                            self.getMembers(tarParam)):
                                        tarPreFix = self.getPrefix(tarMember)
                                        refPreFix = self.getPrefix(refMember)
                                        doDF(refMember, tarMember,
                                             currentLineNumber, tarPreFix,
                                             refPreFix, nemonicType)

                                nemonicType = "Read"

                    #TODO handle the False clause ?

            tarBase += nodeInfo['tarCode'].count(";")
            refBase += nodeInfo['refCode'].count(";")

        self.sol = self.problem.getSolution()

        #print self.sol

    def getBrokenNumber(self):
        return self.problem.getSolver().getHack()

    # TODO - make this __
    def getRW(self):
        sol = self.getSolution()

        tarBase = 0

        symbolsCache = {}

        self.varsInThisLine = 0
        TotalLineNumber = 0

        def getRewrittenSymbolUpdateCache(prefix, symbol):
            varName = self.getVarName(prefix, TotalLineNumber,
                                      self.varsInThisLine)
            if sol != None and varName in sol:
                symbolsCache[symbol] = sol[varName]
                return sol[varName]
            else:
                return symbol

        def rewrittenParam(param):
            if param.startswith("["):
                rewrittenMembers = []
                for member in self.getMembers(param):
                    rewrittenMembers.append(
                        getRewrittenSymbolUpdateCache(self.getPrefix(member),
                                                      member))
                    self.varsInThisLine += 1
                return "[" + "+".join(rewrittenMembers) + "]"
            else:
                newParam = getRewrittenSymbolUpdateCache(
                    self.getPrefix(param), param)
                self.varsInThisLine += 1
                return newParam

        for nodeInfo in self.nodeGradesInfos:

            cmdsStr = nodeInfo['tarCode']
            rewrittenCmds = []

            lastLineNumber = 0  #filter(None,)
            for (lineNumber, cmd) in enumerate(cmdsStr.split(";")):

                TotalLineNumber = tarBase + lineNumber + 1  # we are one based
                lastLineNumber = lineNumber + 1  # we are one based

                self.varsInThisLine = 1

                if cmd != "":
                    tarCmdBasicInfo = self.breakCommand(cmd)
                    if len(tarCmdBasicInfo['ParamsList']) > 0:
                        if tarCmdBasicInfo['nemonic'] == 'call':
                            rewrittenCmds.append(
                                "call " + getRewrittenSymbolUpdateCache(
                                    self.FuncPrefix,
                                    tarCmdBasicInfo['ParamsList'][0]))
                        else:
                            rewrittenCmds.append(
                                tarCmdBasicInfo['nemonicWithDecoretors'] +
                                " " + ",".join(
                                    map(rewrittenParam,
                                        tarCmdBasicInfo['ParamsList'])))
                    else:
                        rewrittenCmds.append(cmd)
                else:
                    # this mostly cuz of bugs, but if i wont accumidate them it will cause a bad grade for nothing..(everything else wont be aligned)
                    rewrittenCmds.append(cmd)

            tarBase += lastLineNumber - 1

            yield ";".join(rewrittenCmds)

    def getSolution(self):
        if self.sol == None:
            self.callSol()

        return self.sol

    def printSol(self, sol):
        #better call sol!

        if sol == None:
            print "NO SOL!"
            return

        last = 1
        for key in sorted(sol.iterkeys()):
            if int(key[1:2]) != last:
                last = int(key[1:2])
                print ""

            print key + ": " + sol[key] + " ",
Esempio n. 2
0
class GraphletsConstraints(X86AnalyzerBase):

    #__registers32Bit = ["eax","ebx","ecx","edx","esi","edi","ebp","esp"]

    __dictNames = ['ref', 'tar']

    __printConds = False

    def __init__(self, nodeGradesInfos=[]):

        X86AnalyzerBase.__init__(self, nodeGradesInfos)
        self.problem = Problem(MinConflictsSolver())
        # this is to make it human readable ..
        # we will generator the solution only when we need it and then cache it

        # TODO make __
        self.sol = None

        for key in self.rewriteDict.keys():
            self.rewriteDict[key]['symbolCache'] = {}
            self.rewriteDict[key]['curLine'] = 1
            self.rewriteDict[key]['curPos'] = 1

        self.createRewrite()

    def getEmptyDict(self):
        d = X86AnalyzerBase.getEmptyDict(self)
        for key in d.keys():
            d[key]['transitions'] = []
            d[key]['valuesTrackDict'] = {}
            #if key != self.REGISTER:
            d[key]['domain'] = set()
            #self.rewriteDict[key]['inCmdCounter'] = 1

        return d

    # this will add recorded value to dict, even if there is a conflict it will be recorded...
    #
    def insertToDictWithType(self,
                             tarCmdNum,
                             fromStr,
                             refCmdNum,
                             toStr,
                             typeStr,
                             dict2insert=None):

        assert (dict2insert != None)
        dict2insert[typeStr]['transitions'].append((tarCmdNum, fromStr, toStr))

        #if typeStr != self.REGISTER:
        dict2insert[typeStr]['domain'].add(toStr)

    def commitChanges(self, tmpDict):
        for key in self.rewriteDict.keys():
            self.rewriteDict[key]['transitions'].extend(
                tmpDict[key]['transitions'])
            #if key != self.REGISTER:
            self.rewriteDict[key]['domain'].update(tmpDict[key]['domain'])

    # black list has no generation:) , we can use the rwdict type as they are the same..
    def getRewriteWithType(self, tarCmdNum, fromStr, typeStr,
                           FoundBlacklistElement):

        if self.sol == None:
            self.callSol()

        if self.rewriteDict[typeStr]['curLine'] < tarCmdNum:
            self.rewriteDict[typeStr]['curLine'] = tarCmdNum
            self.rewriteDict[typeStr]['curPos'] = 1

        varName = self.getVarName(self.getShort(typeStr), tarCmdNum,
                                  self.rewriteDict[typeStr]['curPos'])
        self.rewriteDict[typeStr]['curPos'] += 1

        if self.sol != None and varName in self.sol:
            # we have a value! update cache and return it
            newVal = self.sol[varName]
            self.rewriteDict[typeStr]['symbolCache'][fromStr] = newVal
            return newVal
        elif fromStr in self.rewriteDict[typeStr]['symbolCache']:
            return self.rewriteDict[typeStr]['symbolCache'][fromStr]
        else:
            #not found in this type's map in this generation, return original
            return fromStr

    def getShort(self, name):
        if name == self.FUNCNAME:
            return "f"
        elif name == self.VAR:
            return "m"
        elif name == self.REGISTER:
            return "r"
        else:
            raise hell

    def getVarName(self, preFix, curLine, curPos):
        return preFix + str(curLine) + "-" + str(curPos) + "_TAR"

    # TODO - make this __
    def callSol(self):
        # we need to go over each dict that is useable, and feed vars and constraints
        for typeDict in [
                x for x in self.rewriteDict.keys()
                if self.rewriteDict[x]['useAble'] == True
        ]:
            curLine = 1
            curPos = 1

            preFix = self.getShort(typeDict)
            #if typeDict != self.REGISTER:
            domain = list(self.rewriteDict[typeDict]['domain'])
            #else:
            #    domain =self.__registers32Bit
            for (line, tarStr,
                 refStr) in self.rewriteDict[typeDict]['transitions']:
                if curLine < line:
                    curPos = 1
                    curLine = line

                tarName = self.getVarName(preFix, curLine, curPos)

                self.problem.addVariables([tarName], domain)
                if (self.__printConds):
                    print "CONS(text) -> " + tarName + " == " + refStr
                self.problem.addConstraint(self.checkInputVsTarget(refStr),
                                           [tarName])

                if tarStr in self.rewriteDict[typeDict][
                        'valuesTrackDict'] != None:
                    if (self.__printConds):
                        print "CONS(bag) -> " + self.rewriteDict[typeDict][
                            'valuesTrackDict'][tarStr] + " == " + tarName
                    self.problem.addConstraint(self.varsEqual, [
                        tarName,
                        self.rewriteDict[typeDict]['valuesTrackDict'][tarStr]
                    ])
                self.rewriteDict[typeDict]['valuesTrackDict'][tarStr] = tarName

                curPos += 1

        self.sol = self.problem.getSolution()
        if traceHack:
            print "(Number of broken - " + str(
                self.problem.getSolver().getHack()) + ")",

    def varsEqual(self, v1, v2):
        return v1 == v2

    def checkInputVsTarget(self, target):
        def retFunc(inputVal):
            return inputVal == target

        return retFunc

    def getSolution(self):
        if self.sol == None:
            self.callSol()

        return self.sol

    def printSol(self, sol):
        #better call sol!

        if sol == None:
            print "NO SOL!"
            return

        last = 1
        for key in sorted(sol.iterkeys()):
            if int(key[1:2]) != last:
                last = int(key[1:2])
                print ""

            print key + ": " + sol[key] + " ",

    def getBrokenNumber(self):
        return self.problem.getSolver().getHack()
Esempio n. 3
0
class GraphletsConstraints(X86AnalyzerBase):
    
    #__registers32Bit = ["eax","ebx","ecx","edx","esi","edi","ebp","esp"]
    
    __dictNames = ['ref','tar']
    
    __printConds = False
    
    def __init__(self,nodeGradesInfos=[]):

        X86AnalyzerBase.__init__(self,nodeGradesInfos)
        self.problem = Problem(MinConflictsSolver())
        # this is to make it human readable ..
        # we will generator the solution only when we need it and then cache it
        
        # TODO make __
        self.sol = None 
        
        for key in self.rewriteDict.keys():
            self.rewriteDict[key]['symbolCache'] = {}
            self.rewriteDict[key]['curLine'] = 1
            self.rewriteDict[key]['curPos'] = 1
        
        self.createRewrite()
    
    def getEmptyDict(self):
        d = X86AnalyzerBase.getEmptyDict(self)
        for key in d.keys():
            d[key]['transitions'] = []
            d[key]['valuesTrackDict'] = {}
            #if key != self.REGISTER:
            d[key]['domain'] = set()
            #self.rewriteDict[key]['inCmdCounter'] = 1
            
        return d
    
    # this will add recorded value to dict, even if there is a conflict it will be recorded...
    #
    def insertToDictWithType(self,tarCmdNum,fromStr,refCmdNum,toStr,typeStr,dict2insert=None):

        assert(dict2insert != None)
        dict2insert[typeStr]['transitions'].append((tarCmdNum,fromStr,toStr))
        
        #if typeStr != self.REGISTER:
        dict2insert[typeStr]['domain'].add(toStr)
            

    def commitChanges(self,tmpDict):
        for key in self.rewriteDict.keys():
            self.rewriteDict[key]['transitions'].extend(tmpDict[key]['transitions'])
            #if key != self.REGISTER:
            self.rewriteDict[key]['domain'].update(tmpDict[key]['domain'])
        

    # black list has no generation:) , we can use the rwdict type as they are the same..
    def getRewriteWithType(self,tarCmdNum,fromStr,typeStr,FoundBlacklistElement):
        
        if self.sol == None:
            self.callSol()

        if self.rewriteDict[typeStr]['curLine'] < tarCmdNum :
            self.rewriteDict[typeStr]['curLine'] = tarCmdNum
            self.rewriteDict[typeStr]['curPos'] = 1

            
        varName = self.getVarName(self.getShort(typeStr), tarCmdNum, self.rewriteDict[typeStr]['curPos'])
        self.rewriteDict[typeStr]['curPos'] += 1
        
        if self.sol != None and varName in self.sol:
            # we have a value! update cache and return it
            newVal = self.sol[varName]
            self.rewriteDict[typeStr]['symbolCache'][fromStr] = newVal
            return newVal
        elif fromStr in self.rewriteDict[typeStr]['symbolCache']:
            return self.rewriteDict[typeStr]['symbolCache'][fromStr]
        else:
            #not found in this type's map in this generation, return original
            return fromStr

    def getShort(self,name):
        if name == self.FUNCNAME:
            return "f"
        elif name == self.VAR:
            return "m"
        elif name == self.REGISTER:
            return "r"
        else :
            raise hell
        
    def getVarName(self,preFix,curLine,curPos):
        return preFix + str(curLine) + "-" + str(curPos) + "_TAR"

    # TODO - make this __
    def callSol(self):
        # we need to go over each dict that is useable, and feed vars and constraints
        for typeDict in [x for x in self.rewriteDict.keys() if self.rewriteDict[x]['useAble']==True ]:
            curLine = 1
            curPos = 1
            
            preFix = self.getShort(typeDict)
            #if typeDict != self.REGISTER:
            domain = list(self.rewriteDict[typeDict]['domain']) 
            #else:
            #    domain =self.__registers32Bit
            for (line,tarStr,refStr) in self.rewriteDict[typeDict]['transitions']:
                if curLine < line:
                    curPos = 1
                    curLine = line
                    
                tarName = self.getVarName(preFix, curLine, curPos)
                
                self.problem.addVariables([tarName],domain)
                if (self.__printConds):
                    print "CONS(text) -> " + tarName + " == " + refStr 
                self.problem.addConstraint(self.checkInputVsTarget(refStr),[tarName])
                
            
                if tarStr in self.rewriteDict[typeDict]['valuesTrackDict'] != None:
                    if (self.__printConds):
                        print "CONS(bag) -> " + self.rewriteDict[typeDict]['valuesTrackDict'][tarStr] + " == " + tarName 
                    self.problem.addConstraint(self.varsEqual,[tarName,self.rewriteDict[typeDict]['valuesTrackDict'][tarStr]])
                self.rewriteDict[typeDict]['valuesTrackDict'][tarStr] = tarName
                        
                curPos+=1
                
        self.sol = self.problem.getSolution()
        if traceHack:
            print "(Number of broken - " + str(self.problem.getSolver().getHack()) + ")",

    def varsEqual(self,v1, v2):
        return v1==v2
    
    def checkInputVsTarget(self,target):
        def retFunc(inputVal):
            return inputVal == target
        
        return retFunc     
    
               
    def getSolution(self):
        if self.sol == None:
            self.callSol()
            
        return self.sol
    
    def printSol(self,sol):
        #better call sol!
        
        if sol == None:
            print "NO SOL!"
            return
        
        last = 1
        for key in sorted(sol.iterkeys()):
            if int(key[1:2]) != last:
                last = int(key[1:2])
                print ""
            
            print key + ": " + sol[key] + " ",
             
    def getBrokenNumber(self):
        return self.problem.getSolver().getHack()
class GraphletsConstraints(RWEngineBase):
    
    __printConds = False
    
    def __init__(self,nodeGradesInfos):
        self.nodeGradesInfos = nodeGradesInfos
        self.sol = None
    
    
    # a field is somthing seperated by " " , an argument is a list of params seperated by "," ; a member is a param seperated by "+"
    def breakCommand(self,cmd):
        cmdFields = seperateCmd(cmd)
        if len(cmdFields) ==0:
            print "asd"
        assert (len(cmdFields) >0)
        if len(cmdFields) == 1 :
            return {'nemonic':cmdFields[0],'nemonicWithDecoretors':" ".join(cmdFields[0:-1]),'ParamsList':[]}
        else:
            return {'nemonic':cmdFields[0],'nemonicWithDecoretors':" ".join(cmdFields[0:-1]),'ParamsList':cmdFields[-1].split(",")}
    
    
    #TODO - add to this..
    lvalCmdsStarts = ["mov","sub","add","xor"]
    
    def getNemonicType(self,nemonic):
        if any(map(lambda startString: nemonic.startswith(startString),self.lvalCmdsStarts)):
            return "WriteThenRead"
        else:
            return "Read"
    
    FuncPrefix = "f"
    VARPrefix = "s"
    RegisterPrefix = "r"
    OffsetPrefix = "o"
    OtherPrefix = "X"
    
    def getPrefix(self,Str):
        if isVarStr(Str):
            return self.VARPrefix
        elif isRegisterStr(Str):
            return self.RegisterPrefix
        elif isOffset(Str):
            return self.OffsetPrefix
        else:
            return self.OtherPrefix 
            

    def varsEqual(self,v1, v2):
        return v1==v2
    
    def checkInputVsTarget(self,target):
        def retFunc(inputVal):
            return inputVal == target
        
        return retFunc     


    def getVarName(self,prefix,lineNumber,varsInThisLine):
        return prefix + str(lineNumber) + "-" + str(varsInThisLine) + "_TAR"

    def getMembers(self,param):
        refMembers = param.split("+")
        refMembers[0] = refMembers[0][1:] #remove [ from first
        refMembers[-1] = refMembers[-1][0:-1]  # remove ] from last (they can be the same one!)
        return refMembers

    def getDomains(self):
        domains = {self.FuncPrefix:set(),self.VARPrefix:set(),self.RegisterPrefix:set(),self.OffsetPrefix:set()}
        
        def getCmdSymbols(cmd):
            cmdBasicInfo = self.breakCommand(cmd)
            for param in cmdBasicInfo['ParamsList']:
                if param.startswith("["):
                    for member in self.getMembers(param):
                        yield member
                else:
                    yield param
        
        def getCmds(cmdsDelimited):
            return filter(None,cmdsDelimited.split(";"))
        
        for cmdList in itertools.imap(lambda nodeGradesInfo:getCmds(nodeGradesInfo['refCode']),self.nodeGradesInfos):
            for cmd in cmdList:
                
                if isCall(cmd):
                    prefix = self.FuncPrefix
                    domains[prefix].add(list(getCmdSymbols(cmd))[0])
                else:
                    for symbol in getCmdSymbols(cmd):
                        prefix = self.getPrefix(symbol)
                        if prefix != self.OtherPrefix:
                            domains[prefix].add(symbol)
            
        for domainName in domains.keys():
            domains[domainName] = list(domains[domainName])
            
        return domains

    def callSol(self):
        
        
        domains = self.getDomains()
        
        #domains[refPrefix].add(refVal) 
        
        self.problem = Problem(MinConflictsSolver())
        
        tarSymbolsCache = {}
        
        self.varsInThisLine = 0
        
        def addInTraceletCons(tarVal,newVarName):
            if (self.__printConds):
                print "CONS(IN) -> " + tarSymbolsCache[tarVal] + " == " + newVarName 
            self.problem.addConstraint(self.varsEqual,[newVarName,tarSymbolsCache[tarVal]])
            
            
        def addCrossTraceletCons(refVal,newVarName,refPrefix):
            if (self.__printConds):
                print "CONS(CROSS) -> " + newVarName + " == " + refVal
            self.problem.addConstraint(self.checkInputVsTarget(refVal),[newVarName])
        
        
        def addVarWithPrefix(prefix,lineNumber):
            newVarName = self.getVarName(prefix,lineNumber,self.varsInThisLine)
            if len(domains[prefix]) == 0:
                print "EMP"
            self.problem.addVariables([newVarName],domains[prefix])
            self.varsInThisLine+=1
            return newVarName
        
        
        # mode can be - WRITE or NORMAL
        def doDF(refSymbol,tarSymbol,lineNumber,refPrefix,tarPrefix,nemonicType):
            
            if refPrefix == self.OtherPrefix or tarPrefix == self.OtherPrefix:
                return 
            
            newVarName = addVarWithPrefix(tarPrefix,lineNumber)
            
            if (refPrefix == tarPrefix):
                addCrossTraceletCons(refSymbol,newVarName,refPrefix)
        
            if tarSymbol in tarSymbolsCache:  
                addInTraceletCons(tarSymbol,newVarName)
                
            if tarPrefix != self.RegisterPrefix or nemonicType=="WriteThenRead":
                tarSymbolsCache[tarSymbol] = newVarName
        
        
        #for matchedCmd in itertools.chain(map(lambda nodeInfo:nodeInfo['matchedCmds'],self.nodeGradesInfos)):
        
        tarBase = 0
        refBase = 0
        
        for nodeInfo in self.nodeGradesInfos:
            for matchedCmd in nodeInfo['matchedCmds']:
                
                self.varsInThisLine = 1
        
                # if these cmds are not an operational match, we cannot cross tracelet match them.
                if matchedCmd['operationMatch'] == True:
                    
                    currentLineNumber = tarBase + matchedCmd['tarCmdNum'] #  matchedCmd['tarCmdNum'] is 1 based so we are ok
                    
                    if matchedCmd['tar'] =="" or matchedCmd['ref'] =="":
                        continue
                    
                    tarCmdBasicInfo = self.breakCommand(matchedCmd['tar'])
                    refCmdBasicInfo = self.breakCommand(matchedCmd['ref'])
                    if len(tarCmdBasicInfo['ParamsList'])>0 and len(refCmdBasicInfo['ParamsList'])>0:
                        
                        if tarCmdBasicInfo['nemonic'] == 'call':
                            
                            assert(len(refCmdBasicInfo['ParamsList'])==1)
                            assert(len(tarCmdBasicInfo['ParamsList'])==1)
                            
                            doDF(refCmdBasicInfo['ParamsList'][0], tarCmdBasicInfo['ParamsList'][0], currentLineNumber, self.FuncPrefix,self.FuncPrefix, "Read")
                        else:
                        
                            nemonicType = self.getNemonicType(tarCmdBasicInfo['nemonic'])
                            
                            for (refParam,tarParam) in zip(refCmdBasicInfo['ParamsList'],tarCmdBasicInfo['ParamsList']):
                                
                                tarIsMem = "[" in tarParam
                                if tarIsMem != ("[" in refParam):
                                    continue
                                    print matchedCmd
                                    print "BOY"
                                
                                assert  tarIsMem == ("[" in refParam)
                                
                                if not tarIsMem:
                                    tarPreFix = self.getPrefix(tarParam)
                                    refPreFix = self.getPrefix(refParam)
                                    
                                    doDF(refParam, tarParam, currentLineNumber, tarPreFix,refPreFix, nemonicType)
                                      
                                      
                                    # TODO - return this to find more classes when we have time...
                                    """
                                    if nemonicType == "WriteThenRead":  
                                        if tarPreFix != self.RegisterPrefix:
                                            print matchedCmd
                                        
                                        assert (tarPreFix == self.RegisterPrefix)
                                        # the write is only to the left most param, rest are normal
                                    """
                                else:
                                    # this is memory! , first remove '[',']'
    
                                    for (refMember,tarMember) in zip(self.getMembers(refParam),self.getMembers(tarParam)):
                                        tarPreFix = self.getPrefix(tarMember)
                                        refPreFix = self.getPrefix(refMember)
                                        doDF(refMember, tarMember, currentLineNumber, tarPreFix,refPreFix, nemonicType)
                                        
                                nemonicType = "Read"
                                        
                                        
                    #TODO handle the False clause ?
                     
            tarBase += nodeInfo['tarCode'].count(";")
            refBase += nodeInfo['refCode'].count(";")
                    
                   
            
        self.sol = self.problem.getSolution()
        
        #print self.sol
    
    def getBrokenNumber(self):
        return self.problem.getSolver().getHack()
    
    # TODO - make this __
    def getRW(self):
        sol = self.getSolution()
        
        tarBase = 0
               
        symbolsCache = {}
        
        self.varsInThisLine = 0
        TotalLineNumber = 0
        
        def getRewrittenSymbolUpdateCache(prefix,symbol):
            varName = self.getVarName(prefix, TotalLineNumber, self.varsInThisLine)
            if sol != None and varName in sol:
                symbolsCache[symbol] = sol[varName]
                return sol[varName]
            else:
                return symbol
        
        def rewrittenParam(param):
            if param.startswith("["):
                rewrittenMembers = []
                for member in self.getMembers(param):
                    rewrittenMembers.append(getRewrittenSymbolUpdateCache(self.getPrefix(member), member))
                    self.varsInThisLine+=1
                return "[" + "+".join(rewrittenMembers) + "]"
            else:
                newParam = getRewrittenSymbolUpdateCache(self.getPrefix(param), param)
                self.varsInThisLine+=1
                return newParam
               
        
        for nodeInfo in self.nodeGradesInfos:
        
            cmdsStr = nodeInfo['tarCode']
            rewrittenCmds = []
    
            lastLineNumber = 0 #filter(None,)
            for (lineNumber,cmd) in enumerate(cmdsStr.split(";")):
                
                TotalLineNumber = tarBase + lineNumber + 1 # we are one based
                lastLineNumber = lineNumber +1  # we are one based
                
                self.varsInThisLine = 1
                
                if cmd != "":
                    tarCmdBasicInfo = self.breakCommand(cmd)
                    if len(tarCmdBasicInfo['ParamsList'])>0:
                        if tarCmdBasicInfo['nemonic'] == 'call':
                            rewrittenCmds.append("call " + getRewrittenSymbolUpdateCache(self.FuncPrefix,tarCmdBasicInfo['ParamsList'][0]))
                        else:
                            rewrittenCmds.append(tarCmdBasicInfo['nemonicWithDecoretors'] + " " + ",".join(map(rewrittenParam,tarCmdBasicInfo['ParamsList'])))
                    else:
                        rewrittenCmds.append(cmd)
                else:
                    # this mostly cuz of bugs, but if i wont accumidate them it will cause a bad grade for nothing..(everything else wont be aligned)
                    rewrittenCmds.append(cmd)
            
            tarBase += lastLineNumber-1
    
            yield ";".join(rewrittenCmds)
        
        
    def getSolution(self):
        if self.sol == None:
            self.callSol()
            
        return self.sol
    
    def printSol(self,sol):
        #better call sol!
        
        if sol == None:
            print "NO SOL!"
            return
        
        last = 1
        for key in sorted(sol.iterkeys()):
            if int(key[1:2]) != last:
                last = int(key[1:2])
                print ""
            
            print key + ": " + sol[key] + " ",