Beispiel #1
0
def generateBinaryExp(operator, lnode, rnode):
    node = TreeNode('BinaryOperation')
    node.attributes = {}
    node.attributes['operator'] = operator
    node.children.append(lnode)
    node.children.append(rnode)
    return node
Beispiel #2
0
def repair_unmatched_type(ast, charno):
    for num in charno:
        try:
            defectNode = BFSGetNode(ast, num)

            decNode = None
            nodeQ = Queue()
            nodeQ.put(defectNode)  # root
            while (not nodeQ.empty()):
                tmpNode = nodeQ.get()
                if tmpNode.nodeType == 'VariableDeclaration':
                    decNode = tmpNode
                    break
                for childNode in tmpNode.children:
                    nodeQ.put(childNode)

            if len(decNode.children) > 0:
                oriType = decNode.children[0].attributes['name']
                curType = oriType.translate(str.maketrans('', '', digits))
                decNode.children[0].attributes['name'] = curType
                decNode.children[0].attributes['type'] = curType
            else:
                # handle the var
                typeNode = TreeNode('ElementaryTypeName')
                typeNode.attributes = {}
                typeNode.attributes['name'] = 'uint'
                typeNode.attributes['type'] = 'uint'
                decNode.children.append(typeNode)

        except:
            print('failing to repair the unmatched type defect in charnum:' +
                  str(num))
            continue
Beispiel #3
0
def generateRequire():
    node = TreeNode('FunctionCall')
    identifierNode = TreeNode('Identifier')
    identifierNode.attributes = {}
    identifierNode.attributes['value'] = 'require'
    node.children.append(identifierNode)
    return node
Beispiel #4
0
def repair_misleading_dataloc(ast, charno):
    for num in charno:
        try:
            defectNode = BFSGetNode(ast, num)
            
            funcCallNode = TreeNode('FunctionCall')
            newNode = TreeNode('NewExpression')
            idenNode = defectNode.children[0].children[0]
            newNode.children.append(idenNode)
            funcCallNode.children.append(newNode)
            defectNode.children.append(funcCallNode)

        except:
            print('failing to repair the misleading defect in charnum:' + str(num))
            continue
Beispiel #5
0
def generateJudgeZero(rnode):
    node = TreeNode('IfStatement')
    zeroNode = TreeNode('Literal')
    zeroNode.attributes = {}
    zeroNode.attributes['value'] = '0'
    zeroNode.attributes['token'] = 'number'
    binaryNode = generateBinaryExp('!=', rnode, zeroNode)
    node.children.append(binaryNode)
    return node
Beispiel #6
0
def add_require_protect(defectNode):
    # find the contract node
    contractNode = defectNode
    while contractNode.nodeType != 'ContractDefinition':
        contractNode = contractNode.father
    
    state_var = []
    for item in contractNode.children:
        if item.nodeType == 'VariableDeclaration':
            if len(item.children) > 0 and item.children[0].nodeType == 'ElementaryTypeName' and item.children[0].attributes['name'] == 'address':
                state_var.append(item.attributes['name'])
    owner_var = ''
    
    for var in state_var:
        if 'owner' in var or 'create' in var or 'admin' in var:
            owner_var = var
            break
    
    if owner_var == '' and len(state_var) > 0:
        owner_var = state_var[0]
    
    if len(state_var) == 0:
        # add a variable declaration and insert into constructor
        owner_idennode = TreeNode('VariableDeclaration')
        owner_idennode.attributes = {'name':'contractOwner'}
        ele_node = TreeNode('ElementaryTypeName')
        ele_node.attributes = {'name':'address', 'value':'address'}
        owner_idennode.children.append(ele_node)

        idx = 0
        while idx < len(contractNode.children):
            if contractNode.children[idx].nodeType != 'InheritanceSpecifier':
                break
            idx+=1

        constructorNode = ''
        for child in contractNode.children:
            if child.nodeType == 'FunctionDefinition' and child.attributes['isConstructor'] == True:
                constructorNode = child
                break
        
        param_node = copy.deepcopy(owner_idennode)
        param_node.attributes['name'] = '_owner'
        # constructorNode.children[0].children.append(param_node)
        for ele in constructorNode.children:
            if ele.nodeType == 'ParameterList':
                ele.children.append(param_node)
                break

        expNode = TreeNode('ExpressionStatement')
        curbinaryOpNode = TreeNode('BinaryOperation')
        curbinaryOpNode.attributes = {}
        curbinaryOpNode.attributes['operator'] = '='

        left_node = TreeNode('Identifier')
        left_node.attributes = {'value':'contractOwner'}
        right_node = TreeNode('Identifier')
        right_node.attributes = {'value':'_owner'}

        curbinaryOpNode.children.append(left_node)
        curbinaryOpNode.children.append(right_node)
        expNode.children.append(curbinaryOpNode)
        # constructorNode.children[2].children.insert(0, expNode)
        for ele in constructorNode.children:
            if ele.nodeType == 'Block':
                ele.children.append(expNode)
                break

        contractNode.children.insert(idx, owner_idennode)
        owner_var = 'contractOwner'

    # add a require(xxx == msg.sender)
    fatherNode = defectNode.father
    idx = fatherNode.children.index(defectNode)
    # msg.sender
    memaccNode = TreeNode('MemberAccess')
    memaccNode.attributes = {}
    memaccNode.attributes['member_name'] = 'sender'
    idenNode = TreeNode('Identifier')
    idenNode.attributes = {}
    idenNode.attributes['value'] = 'msg'
    memaccNode.children.append(idenNode)

    reqexpNode = TreeNode('ExpressionStatement')
    requireNode = TreeNode('FunctionCall')
    nameNode = TreeNode('Identifier')
    nameNode.attributes = {}
    nameNode.attributes['value'] = 'require'
    binaryOpNode = TreeNode('BinaryOperation')
    binaryOpNode.beginPoint = -1
    binaryOpNode.attributes = {}
    binaryOpNode.attributes['operator'] = '=='
    userdefNode = TreeNode('Identifier')
    userdefNode.attributes = {}
    userdefNode.attributes['value'] = owner_var
    binaryOpNode.children.append(userdefNode)
    binaryOpNode.children.append(memaccNode)
    requireNode.children.append(nameNode)
    requireNode.children.append(binaryOpNode)
    reqexpNode.children.append(requireNode)

    fatherNode.children.insert(idx, reqexpNode)
Beispiel #7
0
def repair_strict_balance(ast, charno):
    for num in charno:
        try:
            defectNode = BFSGetNode(ast, num)
            # find this.balance

            thisNode = None
            nodeQ = Queue()
            nodeQ.put(defectNode)  # root
            while (not nodeQ.empty()):
                tmpNode = nodeQ.get()
                if 'value' in tmpNode.attributes.keys(
                ) and tmpNode.attributes['value'] == 'this':
                    thisNode = tmpNode
                for childNode in tmpNode.children:
                    nodeQ.put(childNode)

            binaryOpNode = thisNode.father.father
            binaryOpNode1 = copy.deepcopy(binaryOpNode)
            binaryOpNode2 = copy.deepcopy(binaryOpNode)
            # >=
            binaryOpNode1.attributes['operator'] = '>='
            binaryOpNode2.attributes['operator'] = '<'

            origvalNode = binaryOpNode2.children[
                1]  # maybe behind is an expression
            tmpBinaryNode = TreeNode('BinaryOperation')
            tmpBinaryNode.beginPoint = -1
            tmpBinaryNode.attributes = {}
            tmpBinaryNode.attributes['operator'] = '+'
            oneNode = TreeNode('Literal')
            oneNode.attributes = {}
            oneNode.attributes['value'] = '1'
            oneNode.attributes['token'] = 'number'
            tmpBinaryNode.children.append(origvalNode)
            tmpBinaryNode.children.append(oneNode)
            secTuple = TreeNode('TupleExpression')
            secTuple.attributes = {'isInlineArray': False}
            secTuple.children.append(tmpBinaryNode)
            binaryOpNode2.children[1] = secTuple

            binaryOpNodeTotal = TreeNode('BinaryOperation')
            binaryOpNodeTotal.attributes = {}
            binaryOpNodeTotal.attributes['operator'] = '&&'

            tupleNode1 = TreeNode('TupleExpression')
            tupleNode1.attributes = {'isInlineArray': False}
            tupleNode1.children.append(binaryOpNode1)
            tupleNode2 = TreeNode('TupleExpression')
            tupleNode2.attributes = {'isInlineArray': False}
            tupleNode2.children.append(binaryOpNode2)

            binaryOpNodeTotal.children.append(tupleNode1)
            binaryOpNodeTotal.children.append(tupleNode2)

            upNode = binaryOpNode.father
            idx = upNode.children.index(binaryOpNode)
            upNode.children[idx] = binaryOpNodeTotal

        except:
            print('failing to repair the strict balance defect in charnum:' +
                  str(num))
            continue
Beispiel #8
0
def repair_missing_interrupter(ast, charno):
    for num in charno:
        try:
            defectNode = BFSGetNode(ast, num)
            if defectNode.nodeType != 'ContractDefinition': # the line is line 1
                defectNode = defectNode.children[0]

            contractNode = defectNode
        
            state_var = []
            for item in contractNode.children:
                if item.nodeType == 'VariableDeclaration':
                    if len(item.children) > 0 and item.children[0].nodeType == 'ElementaryTypeName' and item.children[0].attributes['name'] == 'address':
                        state_var.append(item.attributes['name'])
            owner_var = ''

            for var in state_var:
                if 'owner' in var or 'create' in var or 'admin' in var:
                    owner_var = var
                    break
            
            if owner_var == '' and len(state_var) > 0:
                owner_var = state_var[0]
            
            if len(state_var) == 0:
                # add a variable declaration and insert into constructor
                owner_idennode = TreeNode('VariableDeclaration')
                owner_idennode.attributes = {'name':'contractOwner'}
                ele_node = TreeNode('ElementaryTypeName')
                ele_node.attributes = {'name':'address', 'value':'address'}
                owner_idennode.children.append(ele_node)

                idx = 0
                while idx < len(contractNode.children):
                    if contractNode.children[idx].nodeType != 'InheritanceSpecifier':
                        break
                    idx+=1
                constructorNode = ''
                for child in contractNode.children:
                    if child.nodeType == 'FunctionDefinition' and child.attributes['isConstructor'] == True:
                        constructorNode = child
                        break
                
                param_node = copy.deepcopy(owner_idennode)
                param_node.attributes['name'] = '_owner'

                for ele in constructorNode.children:
                    if ele.nodeType == 'ParameterList':
                        ele.children.append(param_node)
                        break

                expNode = TreeNode('ExpressionStatement')
                curbinaryOpNode = TreeNode('BinaryOperation')
                curbinaryOpNode.attributes = {}
                curbinaryOpNode.attributes['operator'] = '='

                left_node = TreeNode('Identifier')
                left_node.attributes = {'value':'contractOwner'}
                right_node = TreeNode('Identifier')
                right_node.attributes = {'value':'_owner'}

                curbinaryOpNode.children.append(left_node)
                curbinaryOpNode.children.append(right_node)
                expNode.children.append(curbinaryOpNode)

                for ele in constructorNode.children:
                    if ele.nodeType == 'Block':
                        ele.children.append(expNode)
                        break

                contractNode.children.insert(idx, owner_idennode)
                owner_var = 'contractOwner'


            funcDefNode = TreeNode('FunctionDefinition')
            funcDefNode.attributes = {}
            funcDefNode.attributes['name'] = 'suicideFunc'
            funcDefNode.attributes['isConstructor'] = False
            funcDefNode.attributes['constant'] = False
            funcDefNode.attributes['visibility'] = 'public'
            funcDefNode.attributes['stateMutability'] = 'nonpayable'

            paramNode = TreeNode('ParameterList')
            returnParamNode = TreeNode('ParameterList')
            funcDefNode.children.append(paramNode)
            funcDefNode.children.append(returnParamNode)

            # msg.sender
            memaccNode = TreeNode('MemberAccess')
            memaccNode.attributes = {}
            memaccNode.attributes['member_name'] = 'sender'
            idenNode = TreeNode('Identifier')
            idenNode.attributes = {}
            idenNode.attributes['value'] = 'msg'
            memaccNode.children.append(idenNode)

            # require
            reqexpNode = TreeNode('ExpressionStatement')
            requireNode = TreeNode('FunctionCall')
            nameNode = TreeNode('Identifier')
            nameNode.attributes = {}
            nameNode.attributes['value'] = 'require'
            binaryOpNode = TreeNode('BinaryOperation')
            binaryOpNode.attributes = {}
            binaryOpNode.attributes['operator'] = '=='
            userdefNode = TreeNode('Identifier')
            userdefNode.attributes = {}
            userdefNode.attributes['value'] = owner_var
            binaryOpNode.children.append(userdefNode)
            binaryOpNode.children.append(memaccNode)
            requireNode.children.append(nameNode)
            requireNode.children.append(binaryOpNode)
            reqexpNode.children.append(requireNode)



            # selfdestruct
            blockNode = TreeNode('Block')
            expNode = TreeNode('ExpressionStatement')
            funcCallNode = TreeNode('FunctionCall')
            funcNameNode = TreeNode('Identifier')
            funcNameNode.attributes = {}
            funcNameNode.attributes['value'] = 'selfdestruct'
            funcCallNode.children.append(funcNameNode)
            funcCallNode.children.append(memaccNode)

            expNode.children.append(funcCallNode)
            
            blockNode.children.append(reqexpNode)
            blockNode.children.append(expNode)

            funcDefNode.children.append(blockNode)
            defectNode.children.append(funcDefNode)
        
        except:
            print('failing to repair the missing interrupt defect in charnum:' + str(num))
            continue
Beispiel #9
0
def repair_first_type(ast, operator, assign):
    lNode = assign.children[0]
    rNode = assign.children[1]
    requireNode = generateRequire()
    binaryNode = generateBinaryExp('>=', lNode, rNode)
    expStatementNode = generateExpStatement()
    requireNode.children.append(binaryNode)
    expStatementNode.children.append(requireNode)
    opStatementNode = assign.father
    orgBlockNode = opStatementNode.father

    idx = orgBlockNode.children.index(opStatementNode)
    if operator == '+=':
        orgBlockNode.children.insert(idx + 1, expStatementNode)

    elif operator == '-=':
        orgBlockNode.children.insert(idx, expStatementNode)

    elif operator == '*=':
        # generate a statement: uint tmp = ?
        tmpVarNode = TreeNode('VariableDeclarationStatement')
        leftNode = TreeNode('VariableDeclaration')
        leftNode.attributes = {'name': 'tmp'}
        eletypeNode = TreeNode('ElementaryTypeName')
        eletypeNode.attributes = {'name': 'uint'}
        leftNode.children.append(eletypeNode)
        rightNode = TreeNode('Identifier')
        rightNode.attributes = {'value': lNode.attributes['value']}
        tmpVarNode.children.append(leftNode)
        tmpVarNode.children.append(rightNode)

        judgeIfZero = generateJudgeZero(rNode)
        requireNode1 = generateRequire()
        binaryNode1 = generateBinaryExp('/', lNode, rNode)

        tmpIdNode = TreeNode('Identifier')
        tmpIdNode.attributes = {'value': 'tmp'}

        binaryTotal1 = generateBinaryExp('==', binaryNode1, tmpIdNode)
        requireNode1.children.append(binaryTotal1)
        expNode1 = generateExpStatement()
        expNode1.children.append(requireNode1)
        judgeIfZero.children.append(expNode1)

        orgBlockNode.children.insert(idx + 1, tmpVarNode)
        orgBlockNode.children.insert(idx + 2, judgeIfZero)
    elif operator == '/=':
        pass
Beispiel #10
0
def generateExpStatement():
    node = TreeNode('ExpressionStatement')
    node.beginPoint = -1
    return node
Beispiel #11
0
def repair_second_type(ast, varDec):
    newvarNode = TreeNode('Identifier')
    newvarNode.attributes = {}
    newvarNode.attributes['value'] = varDec.children[0].attributes['name']

    if (varDec.children[1].nodeType == 'BinaryOperation'):
        lnode = varDec.children[1].children[0]
        rnode = varDec.children[1].children[1]
        operator = varDec.children[1].attributes['operator']

        if operator == '+':
            requireNode = generateRequire()
            binaryNode1 = generateBinaryExp('>=', newvarNode, lnode)
            binaryNode2 = generateBinaryExp('>=', newvarNode, rnode)
            binaryTotal = generateBinaryExp('&&', binaryNode1, binaryNode2)

            expStatementNode = generateExpStatement()
            requireNode.children.append(binaryTotal)
            expStatementNode.children.append(requireNode)

            orgBlockNode = varDec.father

            idx = orgBlockNode.children.index(varDec)

            orgBlockNode.children.insert(idx + 1, expStatementNode)
        elif operator == '-':
            requireNode = generateRequire()
            binaryTotal = generateBinaryExp('>=', lnode, rnode)

            expStatementNode = generateExpStatement()
            requireNode.children.append(binaryTotal)
            expStatementNode.children.append(requireNode)

            orgBlockNode = varDec.father

            idx = orgBlockNode.children.index(varDec)
            orgBlockNode.children.insert(idx, expStatementNode)
        elif operator == '*':
            judgeIfZero1 = generateJudgeZero(lnode)
            requireNode1 = generateRequire()
            binaryNode1 = generateBinaryExp('/', newvarNode, lnode)
            binaryTotal1 = generateBinaryExp('==', binaryNode1, rnode)
            requireNode1.children.append(binaryTotal1)
            expNode1 = generateExpStatement()
            expNode1.children.append(requireNode1)
            judgeIfZero1.children.append(expNode1)

            judgeIfZero2 = generateJudgeZero(rnode)
            requireNode2 = generateRequire()
            binaryNode2 = generateBinaryExp('/', newvarNode, rnode)
            binaryTotal2 = generateBinaryExp('==', binaryNode2, lnode)
            requireNode2.children.append(binaryTotal2)
            expNode2 = generateExpStatement()
            expNode2.children.append(requireNode2)
            judgeIfZero2.children.append(expNode2)

            orgBlockNode = varDec.father

            idx = orgBlockNode.children.index(varDec)
            orgBlockNode.children.insert(idx + 1, judgeIfZero1)
            orgBlockNode.children.insert(idx + 1, judgeIfZero2)
        elif operator == '/':
            pass
    else:
        pass
Beispiel #12
0
def repair_hard_encode(ast, charno):
    hard_encode_cnt = 0
    for num in charno:
        try:
            defectNode = BFSGetNode(ast, num)
            # it is in a function
            if defectNode.father.father.nodeType == 'FunctionDefinition':
                literalNode = None
                nodeQ = Queue()
                nodeQ.put(defectNode)  # root
                while (not nodeQ.empty()):
                    tmpNode = nodeQ.get()
                    if hasattr(tmpNode, 'attributes'
                               ) and 'value' in tmpNode.attributes.keys():
                        if tmpNode.attributes[
                                'value'] != None and tmpNode.attributes[
                                    'value'].startswith('0x'):
                            literalNode = tmpNode
                    for childNode in tmpNode.children:
                        nodeQ.put(childNode)

                # if literalNode.father.nodeType == 'IndexAccess':
                #     goalType = 'address' # currently this way
                # else:

                #     goalType = defectNode.children[0].children[0].attributes['type']
                goalType = 'address'
                #print(goalType)

                funcDefNode = defectNode.father.father
                typeNode = TreeNode('ElementaryTypeName')
                typeNode.attributes = {}
                typeNode.attributes['name'] = goalType
                typeNode.attributes['type'] = goalType
                varDecNode = TreeNode('VariableDeclaration')
                varDecNode.attributes = {}
                varDecNode.attributes['name'] = 'param' + str(hard_encode_cnt)
                varDecNode.children.append(typeNode)
                funcDefNode.children[0].children.append(varDecNode)

                idenNode = TreeNode('Identifier')
                idenNode.attributes = {}
                idenNode.attributes['value'] = 'param' + str(hard_encode_cnt)
                idx = literalNode.father.children.index(literalNode)
                literalNode.father.children[idx] = idenNode

            else:
                # print('cannot repair it')
                pass

            hard_encode_cnt += 1

        except:
            print('failing to repair the hard encode defect in charnum:' +
                  str(num))
            continue
Beispiel #13
0
def generateThrowNode():
    node = TreeNode('Throw')
    blockNode = TreeNode('Block')
    blockNode.children.append(node)
    return blockNode