Exemple #1
0
    def detectMemAccess(self, reil_code, callstack, inputs, counter):

        pins = parse_reil(reil_code[-1])
        ins = Instruction(pins, None)

        assert (ins.instruction in ["stm", "ldm"])
        addr_op = ins.getMemReg()
        #print "op:", addr_op, ins.address
        val = getTypedValueFromCode(reil_code, callstack, inputs, self,
                                    addr_op)
        #print val
        if (val.isMem()):

            #if self.__isArgMem__(val, callstack.callstack[1]):
            #  print "arg detected at", ins, "with", str(val)
            #  self.access[counter] = self.__getArgMemAccess__(ins, val, callstack.callstack[1])
            #else:
            #print val
            self.access[counter] = self.__getMemAccess__(ins, val)
        elif (val.isImm):
            self.access[counter] = self.__getGlobalMemAccess__(
                ins, int(val.name))

        else:
            assert (0)
Exemple #2
0
    def __init__(self, params=dict()):
        self.num_threads = int(
            params["NUM_THREAD"]) if "NUM_THREAD" in params.keys(
            ) else NUM_THREADS
        self.num_stages = int(
            params["NUM_STAGES"]) if "NUM_STAGES" in params.keys(
            ) else NUM_STAGES
        self.stages = FIFOQueue(self.num_stages)
        self.stages.set_q_list([Instruction.empty_inst(0)] * self.num_stages)
        # Statistics
        self.committed_inst = Instruction()
        self.count_flushed_inst = 0
        self.count_committed_inst = 0
        self.num_of_flushes = 0
        # Resources
        # TODO-?
        # Pointer to relevant units units
        self.thread_unit = None
        self.issue_unit = None
        self.fetch_unit = None

        self.generate_csv()

        # bp
        self.bp_en = params["BP_EN"] == "True" if "BP_EN" in params.keys(
        ) else BP_EN
Exemple #3
0
 def generate_csv(self):
     if EX_DUMP_TO_CSV:
         with open(EX_DUMP_CSV_PATH, 'w', newline='') as csv_file:
             report_writer = csv.writer(csv_file)
             if EX_DUMP_TO_CSV:
                 empty = Instruction()
                 header = empty.csv_list(header=True)
                 report_writer.writerow(header)
Exemple #4
0
 def executeProgram(self, instructions: bytes):
     self.instructions = instructions
     self.PC = 0
     instructionArr = [Instruction.ADC(), Instruction.ORA()]
     print("Running program: \n" + str(instructions))
     while (self.PC >= 0 and self.PC < len(instructions)):
         print("Current instruction: " + str(self.PC) + " : " +
               str(int(instructions[self.PC])))
         instructionArr[0].execute(instructions[self.PC], self)
def inst_typedef(instruction):
    if instruction[0] == '*':
        return None
    elif instruction[0] == 's':
        return Ins.InitialInstruction(instruction[0], instruction[4])
    elif instruction[2] == ' ':
        return Ins.WriteInstruction(instruction[0], instruction[4], instruction[6:-1])
    else:
        return Ins.ReadInstruction(instruction[0], instruction[4], instruction[2])
Exemple #6
0
def getValueFromCode(inss, initial_values, op):
    assert (len(inss) > 0)

    # code should be copied and reversed
    inss.reverse()

    # counter is set
    counter = len(inss)

    ssa = SSA()
    smt_conds = SMT()

    # we will track op
    mvars = set([op])
    ssa.getMap(mvars, set(), set())

    for ins_str in inss:
        #print ins_str.strip("\n")
        pins = parse_reil(ins_str)

        ins = Instruction(pins, None)  # no memory and callstack are available

        ins_write_vars = set(ins.getWriteVarOperands())
        ins_read_vars = set(ins.getReadVarOperands())

        if len(ins_write_vars.intersection(mvars)) > 0:

            ssa_map = ssa.getMap(ins_read_vars.difference(mvars),
                                 ins_write_vars,
                                 ins_read_vars.intersection(mvars))

            cons = conds.get(pins.instruction, Condition)
            condition = cons(ins, ssa_map)

            mvars = mvars.difference(ins_write_vars)
            mvars = ins_read_vars.union(mvars)
            mvars = set(filter(lambda o: o.name <> "ebp", mvars))

            smt_conds.add(condition.getEq())

        counter = counter - 1

    for iop in initial_values.keys():
        if not (iop in ssa):
            del initial_values[iop]

    ssa_map = ssa.getMap(set(), set(), set(initial_values.keys()))
    eq = Eq(None, None)

    for iop in initial_values:
        smt_conds.add(eq.getEq(ssa_map[iop.name], initial_values[iop]))

    op.name = op.name + "_0"
    smt_conds.solve()

    return smt_conds.getValue(op)
Exemple #7
0
def getValueFromCode(inss, initial_values, op):
  assert(len(inss) > 0)
  
  # code should be copied and reversed
  inss.reverse()
  
  # counter is set
  counter = len(inss)
  
  ssa = SSA()
  smt_conds  = SMT()
 
  # we will track op
  mvars = set([op])    
  ssa.getMap(mvars, set(), set())

  for ins_str in inss:
    #print ins_str.strip("\n")
    pins = parse_reil(ins_str)
      
    ins = Instruction(pins, None) # no memory and callstack are available
    
    ins_write_vars = set(ins.getWriteVarOperands())
    ins_read_vars = set(ins.getReadVarOperands())

    if len(ins_write_vars.intersection(mvars)) > 0: 
      
      ssa_map = ssa.getMap(ins_read_vars.difference(mvars), ins_write_vars, ins_read_vars.intersection(mvars))

      cons = conds.get(pins.instruction, Condition)
      condition = cons(ins, ssa_map)
     
      mvars = mvars.difference(ins_write_vars) 
      mvars = ins_read_vars.union(mvars)
      mvars = set(filter(lambda o: o.name <> "ebp", mvars))
   
      smt_conds.add(condition.getEq())
      
    counter = counter - 1
  
  for iop in initial_values.keys():
    if not (iop in ssa):
      del initial_values[iop]
    
  ssa_map = ssa.getMap(set(), set(), set(initial_values.keys()))
  eq = Eq(None, None)
    
  for iop in initial_values:
    smt_conds.add(eq.getEq(ssa_map[iop.name],initial_values[iop]))
  
  op.name = op.name+"_0"
  smt_conds.solve()
  
  return smt_conds.getValue(op)
Exemple #8
0
def decode(mode, instr):
    re_line = re.compile(
        r'^(?:\S+\s+)?(?P<instr>add|sub|xor|not|mul)\s+(?P<arg1>([A-Za-z0-9_\[\]+*\-]|\s)+)\s*'
        r'(?:,\s*(?P<arg2>([A-Za-z0-9_\[\]+*\-]|\s)+))?'
    )
    instruction = re_line.search(instr)
    if instruction is None:
        return '>>> Invalid instruction! Please try again.'
    instruction = instruction.groupdict()
    instruction = Instruction(mode, instruction['instr'], instruction['arg1'], instruction['arg2'])
    instruction.validate_arguments()
    ans = instruction.translate()
    ans = ' '.join([ans[i : i + 4] for i in range(0, len(ans), 4)])
    return ans
Exemple #9
0
    def decode(self, address, inst):
        """
        Find the type of an instruction, and call for it to be decoded.
        """
        i = Instruction()
        i.address = address
        i.inst = inst
        i.decode()

        # Pass on to specific op
        if i.system:
            decoder = sys_ops[i.op]
        else:
            decoder = ops[i.op][i.subop]
        if decoder == None:
            # unknown instruction
            # system, op, subop
            return i
        else:
            # Use specific decoder
            i = decoder(i)
            try:
                i.decode()
            except DecodeError, e:  # Error decoding instruction
                i.warnings.append(e.message)
            return i
Exemple #10
0
    def __init__(self, reil_code):

        # The first instruction should be a call
        self.callstack = [None]
        self.stack_diff = []

        self.index = 0
        #self.prev_callstack = [None]

        # aditional information need to compute the callstack
        self.calls = [None]
        self.esp_diffs = [None]
        self.reil_code = reil_code
        reil_size = len(reil_code)
        start = 0

        for (end, ins_str) in enumerate(self.reil_code):
            #print ins_str.strip("\n")
            pins = parse_reil(ins_str)
            ins = Instruction(pins, None)

            if (ins.instruction == "call" and ins.called_function
                    == None) or ins.instruction == "ret":
                self.__getStackDiff__(ins.instruction, ins.address,
                                      reil_code[start:end])
                start = end

        if (start <> reil_size - 1):
            pins = parse_reil(reil_code[start])
            self.__getStackDiff__(pins.instruction, pins.address,
                                  reil_code[start:reil_size])

        self.index = len(self.callstack) - 1
Exemple #11
0
 def move_inst_unit_unpipelined(self, to_unit, from_unit, number_of_cycles):
     if (to_unit.is_free()):
         if (from_unit == None):
             if (self.all_inst_fetched == False):
                 from_unit_complete_inst = Instruction(
                     self.set_of_instructions[self.registers['PC']].strip(),
                     self.current_inst)
                 self.registers['PC'] += 1
                 self.current_inst += 1
             else:
                 return
         else:
             from_unit_complete_inst = from_unit.get_completed_inst()
         if (from_unit_complete_inst != False):
             if (to_unit.add_new_inst_unpipelined(
                     from_unit_complete_inst, number_of_cycles) == False):
                 print "Debugging Time"
                 return False
         return from_unit_complete_inst
     else:
         if (from_unit != None and from_unit != self.IF):
             if (from_unit.peek_completed_inst() != False):
                 self.result[
                     from_unit.peek_completed_inst().inst_addr][7] = 'Y'
         return False
Exemple #12
0
 def _get_corresponding_inst(self, label):
     for i in range(len(self.set_of_instructions)):
         instruction = Instruction(self.set_of_instructions[i], i)
         if instruction.label == label:
             return i
     print "Error: Invalid instruction: missing label"
     exit()
Exemple #13
0
    def detectFuncParameters(self, reil_code, memaccess, callstack, inputs,
                             counter):

        pins = parse_reil(reil_code[-1])
        ins = Instruction(pins, None)

        assert (ins.instruction == "call" and ins.called_function <> None)

        # first we locate the stack pointer to know where the parameters are located
        esp = Operand("esp", "DWORD")
        pbase = getTypedValueFromCode(reil_code, callstack, inputs, memaccess,
                                      esp)

        #print pbase.name
        #print pbase.mem_source
        #
        func_cons = funcs.get(ins.called_function, Function)
        func = func_cons(pbase=pbase)

        parameters = []

        for (par_type, location, needed) in func.getParameterLocations():
            #print (ins.called_function, par_type, location.mem_source, needed)
            if needed:
                reil_code.reverse()
                reil_code.reset()
                val = getTypedValueFromCode(reil_code, callstack, inputs,
                                            memaccess, location)
                #print  "parameter of",ins.called_function, "at", str(location) , "has value:", val.name
                parameters.append((location, val))
            else:
                parameters.append((None, None))

        if parameters <> []:
            self.parameters[counter] = self.__getParameters__(ins, parameters)
Exemple #14
0
    def __init__(self, in_filename, out_filename):
        # Set initial values for MIPS engine
        print("Loading...")
        self._offset = 0
        self._program = {}
        self._PC = 0
        self._error = False

        # Read in hex file
        self._f = open(in_filename)
        inst_all = self._f.read()
        inst_temp = inst_all.split('\n')

        # Store all instructions by initializing Instruction objects into _program dictionary
        # indexed by _PC
        self._program_len = len(inst_temp)
        self._PC_last = self._program_len - 1
        print('# instructions: {}\tLast Instruction: {}'.format(
            len(inst_temp), self._PC_last))
        for i in range(0, len(inst_temp)):
            self._program[self._PC] = Instruction.Instruction(inst_temp[i])
            self._PC = self._PC + 1

        # Output assembly file
        self._output_f = open(out_filename, 'w')
        for key in self._program:
            self._program[key].print_inst()
            self._output_f.write(self._program[key].get_inst() + '\n')
        self._output_f.close()

        print()
        self._PC = 0
        #self.print_state()
        self._save_cur_state()
        print('...Program loaded successfully')
 def test_SLL(self):
     instrn_list = [
         '00050018',
         '00010001',
         '00432020',
         '009E001C',
         '009E001E',
         '0121482E',
         '00031025',
         '34830000',
         'ACC40000',
         '00C60001',
         '10050002',
         '0BFFFFF6',
     ]
     human_instrn_list = [
         '00050018',
         '00010001',
         '00432020',
         '009E001C',
         '009E001E',
         '0121482E',
         '00031025',
         '34830000',
         'ACC40000',
         '00C60001',
         '10050002',
         '0BFFFFF6',
     ]
     for instrn, human_instrn in zip(instrn_list, human_instrn_list):
         print 'instrn: ', instrn
         bin_string = Memory.Memory.get_bin_from_hex_instruction(instrn)
         instruction = Instruction.Instruction(bin_string)
         print instruction
Exemple #16
0
 def advance(self):
     #Fetch the next instruction according to simulator program counter
     # ...if we are not outside instruction memory
     if self.simulator.programCounter < (
             len(self.simulator.instrCollection) * 4 + 0x0):
         self.instr = self.simulator.instructionMemory[
             self.simulator.programCounter]
         # Non-NOP instruction
         if (self.instr and self.instr.op != "nop"
                 and self.instr.op != None):
             self.simulator.instrCount += 1
         # NOP
         if (self.instr.op is 'nop'):
             self.simulator.instrCount += 1
             self.simulator.nopCount += 1
         # Instruction is a core instruction
         if (self.instr.coreInstr):
             self.simulator.coreInstrCount += 1
             # Instruction is a core instruction and a NOP
             if (self.instr.op is 'nop'):
                 self.simulator.coreNopCount += 1
     else:
         # Something wrong (outside memory range) - ignore instruction
         self.instr = Instruction(op='nop', coreInstr=False)
     # Advance PC
     self.simulator.programCounter += 4
Exemple #17
0
def main():
    print("Start")
    print("Setting all types of instructions into a dict")
    iparser = Instruction.InstructionParser()
    print("iparser : ", iparser)
    pipelinesim = PipelineSimulator.PipelineSimulator(
        iparser.parseFile("sample.txt"))
    config = iparser.parseConfigFile("config.txt")

    print("***************************************************")
    print("Summary so far: ")
    print("1. File Read")
    print("2. Parsed and determined type of instruction")
    print("3. Stored in a list of instructions")
    print("4. Created Registers")
    print("5. Created Main Memory")
    print("6. Added each instruction to the main memory")
    print("***************************************************")

    filename = "debug.txt"
    print("File name : ", filename)

    f = open(filename, 'w')

    print("Begining to Run")
    pipelinesim.run()
    print("Done Running")

    sys.stdout = f
Exemple #18
0
    def disassemble(self, filename):
        #Exécution d'opdis et récupération du XML
        xml = subprocess.Popen(
            ["opdis", "-q", "-d", "-f", "xml", "-N", "main", filename],
            stdout=subprocess.PIPE,
            stderr=subprocess.DEVNULL).stdout.read()
        document = parseString(xml).documentElement

        #Création de la liste des instructions
        instructions_table = []
        vma_instructions_table = {}

        for instructionNode in document.getElementsByTagName("instruction"):
            instruction = Instruction.Instruction(
                self.get_xml_child_value(instructionNode, "offset"),
                self.get_xml_child_value(instructionNode, "vma"),
                self.get_xml_child_value(instructionNode, "ascii"),
                self.get_xml_child_value(instructionNode, "mnemonic"))

            if (self.xml_node_has_child(instructionNode, "operands")):
                for operandNode in instructionNode.getElementsByTagName(
                        "operand"):
                    operand = Operand.Operand(
                        operandNode.attributes["name"] if
                        ("name" in operandNode.attributes) else "",
                        self.get_xml_child_value(operandNode, "ascii"))
                    instruction.add_operand(operand)

            instructions_table.append(instruction)
            vma_instructions_table[int(instruction.vma, 0)] = instruction

        return (instructions_table, vma_instructions_table)
Exemple #19
0
def getJumpConditions(trace, addr):
    raw_ins = parse_reil(trace["code"][-1])
    addr = int(addr, 16)
    pos = trace["code"].last - 1

    if (raw_ins.instruction == "jcc"):
        ins = Instruction(raw_ins, None)
        jmp_op = ins.operands[2]

        if (jmp_op.isVar()):

            #print addr
            trace["final_conditions"] = dict([(jmp_op,
                                               Operand(str(addr), "DWORD"))])
            sol = getPathConditions(trace)

            if (sol <> None):
                print "SAT conditions found!"
                filename = raw_ins.instruction + "[" + str(pos) + "]"
                dumped = sol.dump(filename, input_vars)
                for filename in dumped:
                    print filename, "dumped!"
            else:
                print "Impossible to jump to", hex(
                    addr), "from", raw_ins.instruction, "at", pos
        else:
            return None

    else:
        return None
Exemple #20
0
    def __init__(self, in_filename, out_filename, mem_config=0):
        # Set initial values for MIPS engine
        self._offset = 0
        self._program = {}
        self._PC = 0

        # Initialize memory configuration
        self._mem = Memory.Memory(mem_config)

        # Read in hex file
        self._f = open(in_filename)
        inst_all = self._f.read()
        inst_temp = inst_all.split('\n')

        # Store all instructions by initializing Instruction objects into _program dictionary
        # indexed by _PC
        self._program_len = len(inst_temp)
        self._PC_last = (self._program_len * 4) - 4
        print('# instructions: {}\tLast Instruction: {}'.format(
            len(inst_temp), self._PC_last))
        for i in range(0, len(inst_temp)):
            self._program[self._PC] = Instruction.Instruction(inst_temp[i])
            self._PC = self._PC + 4

        # Output assembly file
        self._output_f = open(out_filename, 'w')
        for key in self._program:
            self._program[key].print_inst()
            self._output_f.write(self._program[key].get_inst() + '\n')
        self._output_f.close()

        print()
        self._PC = 0
        self.print_state()
        self._save_cur_state()
def main():
    iparser = Instruction.InstructionParser()
    pipelinesim = PipelineSimulator.PipelineSimulator(iparser.parseFile(sys.argv[1]))
    
    filename = sys.argv[2] if len(sys.argv) > 2 else "debug.txt"
    f = open(filename, 'w')
    sys.stdout = f
    pipelinesim.run()
Exemple #22
0
def getExploitConditions(trace, value, address, filename): 

  callstack  = trace["callstack"]
  inss       = trace["raw_code"]
  mem_access = trace["mem_access"]
  
  stm = parse_reil(inss[-1])
  
  if stm.instruction <> "stm":
    print "#ERROR: Selected instruction is not a store memory"
    return
  else:
    stm = Instruction(stm,None)
    addr_op = stm.getMemReg()
    val_op  = stm.getReadRegOperands()[0]
    
    getValueFromCode(inss[:-1], callstack, mem_access, addr_op, address, val_op, value)
Exemple #23
0
 def populateDests(self):
     #dest
     self.__m_Dests.append(Instruction.Instruction('null', '000'))
     self.__m_Dests.append(Instruction.Instruction('M', '001'))
     self.__m_Dests.append(Instruction.Instruction('D', '010'))
     self.__m_Dests.append(Instruction.Instruction('MD', '011'))
     self.__m_Dests.append(Instruction.Instruction('A', '100'))
     self.__m_Dests.append(Instruction.Instruction('AM', '101'))
     self.__m_Dests.append(Instruction.Instruction('AD', '110'))
     self.__m_Dests.append(Instruction.Instruction('AMD', '111'))
Exemple #24
0
 def populateJumps(self):
     #jumps
     self.__m_Jumps.append(Instruction.Instruction('null', '000'))
     self.__m_Jumps.append(Instruction.Instruction('JGT', '001'))
     self.__m_Jumps.append(Instruction.Instruction('JEQ', '010'))
     self.__m_Jumps.append(Instruction.Instruction('JGE', '011'))
     self.__m_Jumps.append(Instruction.Instruction('JLT', '100'))
     self.__m_Jumps.append(Instruction.Instruction('JNE', '101'))
     self.__m_Jumps.append(Instruction.Instruction('JLE', '110'))
     self.__m_Jumps.append(Instruction.Instruction('JMP', '111'))
Exemple #25
0
    def decode(self, address, inst):
        """
        Find the type of an instruction, and call for it to be decoded.
        """
        i = Instruction()
        i.address = address
        i.inst = inst
        i.decode()

        # Pass on to specific op
        if i.system:
            decoder = sys_ops[i.op]
        else:
            decoder = ops[i.op][i.subop]
        if decoder == None:
            # unknown instruction
            # system, op, subop
            return i
        else:
            # Use specific decoder
            i = decoder(i)
            try:
                i.decode()
            except DecodeError, e:  # Error decoding instruction
                i.warnings.append(e.message)
            return i
Exemple #26
0
 def addUserLabels(self):
     for line in self.__m_rawCommands:
         if (self.isLabel(line)):
             #cut out first and last ()
             name = line[1:-1]
             #append label and rom to label table
             self.__m_Symbols.append((Instruction.Instruction(name, self.__m_rom)))
         else:
             self.__m_rom += 1
Exemple #27
0
def test_asm(x):
    i = Instruction()
    i.visited = None
    i.parse(x)
    
    # Print instruction, to test parsing/dumping
    print "in                %s" % (i)
    # Assemble
    i.inst = assemble(i)
    #print "%08x %08x" %(i.inst[0], i.inst[1])
    # Then disassemble again, and see if we get similar result
    d = Disassembler()
    i2 = d.decode(0, i.inst)

    #print i2
    
    print "%08x %08x %s" % (i.inst[0], i.inst[1], i2)
    print
Exemple #28
0
def getPathConditions(trace, filename): 

  callstack  = list(trace["callstack"])
  inss       = list(trace["raw_code"])
  mem_access = trace["memaccess"]

  SSA.SSAinit()

  mvars = set()
  smt_conds = SMT() 

  #assert(False)

  for ins_str in inss:
    #print ins_str.strip("\n")
    # Instruction parsing
    pins = parse_reil(ins_str)

    # Instruction processing
    current_call = trace["current_call"]
    mem_access = trace["memaccess"].getAccess(pins.address)
    ins = Instruction(pins,current_call,mem_access)

    ins_write_vars = set(ins.getWriteVarOperands())
    ins_read_vars = set(ins.getReadVarOperands())

    if pins.instruction == "jcc" or len(ins_write_vars.intersection(mvars)) > 0:
      ssa_map = SSA.SSAMapping(ins_read_vars.difference(mvars), ins_write_vars, ins_read_vars.intersection(mvars))

      cons = conds.get(pins.instruction, Condition)
      condition = cons(ins, ssa_map)
     
      mvars = mvars.difference(ins_write_vars) 
      mvars = ins_read_vars.union(mvars)
      mvars = set(filter(lambda o: o.name <> "ebp", mvars))
   
      smt_conds.add(condition.getEq())

    #print "mvars ops:"  
    #for op in mvars:
    #  print op

  smt_conds.write_smtlib_file(filename+".smt2")  
  smt_conds.write_sol_file(filename+".sol") 
Exemple #29
0
 def addUserSymbols(self):
     self.addUserLabels()
     #user defined symbols (check on address start and increment)
     for line in self.__m_rawCommands:
         name = line[1:]
         if self.isA(line) and (not name.isdigit()) and (not self.isNameInTable(name, self.__m_Symbols)):
             #test if symbol is added at the right address
             #print("symbol is {0}, address is {1}".format(name, self.__m_ram))
             #end test
             self.__m_Symbols.append(Instruction.Instruction(name, self.__m_ram))
             self.__m_ram += 1 
Exemple #30
0
    def doBranch(self):
        # Read target value
        targetval = int(self.instr.immed)
        # Debug output if in verbose mode
        if (self.simulator.verbose):
            print "Branching to target ", hex(targetval)
        # Update PC
        self.simulator.programCounter = targetval + 4
        # Set the other instructions currently in the pipeline to NOPS (depending on the number of IF stages)
        self.simulator.pipeline[0] = FetchStage(
            Instruction(op='nop', coreInstr=True), self)
        if (self.simulator.nIFit >= 2):
            self.simulator.pipeline[1] = FetchStage(
                Instruction(op='nop', coreInstr=True), self)
        if (self.simulator.nIFit == 3):
            self.simulator.pipeline[2] = FetchStage(
                Instruction(op='nop', coreInstr=True), self)

        # Indicate branch by setting branched flag
        self.simulator.branched = True
 def setUp(self):
     self.instruction_string = 'R ADD  R1 R2 R3'
     self.instr = Instruction.Instruction(
         self.instruction_string.strip().split())
     self.npc = 4
     self.PC = 0
     self.input_dict = {
         'instr': self.instr,
         'npc': self.npc,
         'PC': self.PC,
     }
     self.fetcher_buffer = fetcher_buffer.FetcherBuffer(self.input_dict)
 def setUp(self):
     self.instruction_string = 'R ADD  R1 R2 R3'
     self.instr = Instruction.Instruction(
         self.instruction_string.strip().split())
     self.memory = Memory.Memory([self.instruction_string.strip().split()])
     self.fetch_input_buffer = FetchInputBuffer({
         'PC': 0,
         'instr_count': 0,
     })
     self.fetcher_buffer = FetcherBuffer({})
     self.fetch_stage = fetch_stage.FetchStage(self.memory,
                                               self.fetch_input_buffer,
                                               self.fetcher_buffer)
Exemple #33
0
    def create_graph(self, instructions_table, vma_instructions_table):
        graph = nx.DiGraph()

        start = Instruction.Instruction("-0x1", "-0x1", "\\<start\\>",
                                        "\\<start\\>")
        end = Instruction.Instruction("-0x1", "-0x1", "\\<end\\>", "\\<end\\>")
        instructions_table.insert(0, start)
        instructions_table.append(end)
        for i in range(len(instructions_table)):
            if (i != 0):
                graph.add_edge(
                    "\"" + instructions_table[i - 1].create_string() + "\"",
                    "\"" + instructions_table[i].create_string() + "\"")

            instruction = instructions_table[i]
            if super(RegularDriver, self).is_jump(instruction):
                targetVma = instruction.operands[0].ascii
                graph.add_edge(
                    "\"" + instruction.create_string() + "\"", "\"" +
                    vma_instructions_table[int(targetVma, 0)].create_string() +
                    "\"")
        return graph
Exemple #34
0
 def detectMemAccess(self, reil_code, callstack, inputs, counter):
   
   pins = parse_reil(reil_code[-1])
   ins = Instruction(pins,None)
 
   assert(ins.instruction in ["stm", "ldm"])
   addr_op = ins.getMemReg()
   #print "op:", addr_op, ins.address
   val = getTypedValueFromCode(reil_code, callstack, inputs, self, addr_op)
   #print val
   if (val.isMem()):
     
     #if self.__isArgMem__(val, callstack.callstack[1]):
     #  print "arg detected at", ins, "with", str(val)
     #  self.access[counter] = self.__getArgMemAccess__(ins, val, callstack.callstack[1])
     #else:
     #print val
     self.access[counter] = self.__getMemAccess__(ins, val)
   elif (val.isImm):
     self.access[counter] = self.__getGlobalMemAccess__(ins, int(val.name))
   
   else:
     assert(0)
Exemple #35
0
def getValueFromCode(reil_code, callstack, memory, addr_op, addr, val_op, val):

  assert(reil_code <> [])
  
  free_variables = []
  
  # code should be copied and reversed
  inss = list(reil_code) 
  inss.reverse()
  
  # counter is set
  counter = len(reil_code)
  
  tracked_stack_frame = callstack.index
  
  # especial operands in a call

  ssa = SSA()
  smt_conds  = SMT()
 
  # we will track op
  mvars = set([addr_op, val_op])    
  ssa_map = ssa.getMap(mvars, set(), set())
  eq = Eq(None, None)
  
  addr = Operand(str(addr), "DWORD")
  val = Operand(str(val), "BYTE")
  val.size = val_op.size
  
  smt_conds.add(eq.getEq(ssa_map[addr_op.name],addr))
  smt_conds.add(eq.getEq(ssa_map[val_op.name],val))

  for ins_str in inss:
    #print ins_str.strip("\n")
    
    pins = parse_reil(ins_str)
    
    ins = Instruction(pins, memory.getAccess(counter), mem_regs = False)
  
    ins_write_vars = set(ins.getWriteVarOperands())
    ins_read_vars = set(ins.getReadVarOperands())

    if pins.instruction == "jcc" or len(ins_write_vars.intersection(mvars)) > 0: 
    #if len(ins_write_vars.intersection(mvars)) > 0: 
      
      ssa_map = ssa.getMap(ins_read_vars.difference(mvars), ins_write_vars, ins_read_vars.intersection(mvars))

      cons = conds.get(pins.instruction, Condition)
      condition = cons(ins, ssa_map)
     
      mvars = mvars.difference(ins_write_vars) 
      mvars = ins_read_vars.union(mvars)
   
      smt_conds.add(condition.getEq())
      
    counter = counter - 1
    
    if len(mvars) > 0:
      tracked_stack_frame = callstack.index
    
    if pins.instruction == "call":
      
      if callstack.index == 1:
        esp_val = 4
      else:
        esp_val = 8
 
      ebp_val = 0
  
      esp_op = Operand("esp","DWORD")
      ebp_op = Operand("ebp","DWORD")
  
      initial_values_at_call = dict()
      initial_values_at_call[esp_op] = Operand(str(esp_val), "DWORD")
      initial_values_at_call[ebp_op] = Operand(str(ebp_val), "DWORD") 

      
      for iop in initial_values_at_call.keys():
        if not (iop in mvars):
          del initial_values_at_call[iop]
      
      ssa_map = ssa.getMap(set(), set(), set(initial_values_at_call.keys()))
      eq = Eq(None, None)
    
      for iop in initial_values_at_call:
        smt_conds.add(eq.getEq(ssa_map[iop.name],initial_values_at_call[iop]))
      
      mvars = set(filter(lambda o: not (o in initial_values_at_call.keys()), mvars))
      
      if (counter == 0 and len(mvars)>0):
        
        #cond = Initial_Cond(None, None)
        #
        #for v in mvars:
        #  print str(v),
        #  smt_conds.add(cond.getEq(v))
        
        #print "are free"
        
        #print smt_conds.solver
        free_variables = mvars
        break
      
      new_mvars = set()
      for v in mvars:
        if v.isMem(): # this should work for stack memory 
          eop = callstack.convertStackMemOp(v)
          #print eop
          smt_conds.add(eq.getEq(v,eop))
          new_mvars.add(eop)
      
      mvars = set(filter(lambda o: not (o.isMem()), mvars))
      mvars = mvars.union(new_mvars)
    
    # we update the current call for next instruction
    callstack.prevInstruction(ins_str) 
    
  #op.name = op.name+"_0"
  smt_conds.solve()
  smt_conds.write_smtlib_file("exp.smt2")
  smt_conds.write_sol_file("exp.sol")
  
  if (smt_conds.is_sat()):
    print "Solution:",
    for v in free_variables:
      if v.isReg():
        if (v in ssa_map):
          print v,smt_conds.getValue(ssa_map[v])
      elif v.isMem():
        sname, offset = stack.read(v)
        v.mem_source = sname
        print v, smt_conds.getValue(v)
  else:
    print "Not exploitable"
Exemple #36
0
def getPathConditions(trace):
  
  inss = trace["code"]
  callstack = trace["callstack"]
  
  initial_values = trace["initial_conditions"]
  final_values = trace["final_conditions"]
  memory = trace["mem_access"]
  parameters = trace["func_parameters"]
  
  # we reverse the code order
  inss.reverse()
  
  # we reset the used memory variables
  Memvars.reset()
  
  # we set the instruction counter
  counter = len(inss)-1
  
  # ssa and smt objects
  ssa = SSA()
  smt_conds  = SMT()
  
  # auxiliary eq condition
  
  eq = Eq(None, None)
  mvars = set()
  
  # final conditions:
  
  for (op, _) in final_values.items():
    mvars.add(op)
  
  ssa.getMap(mvars, set(), set())
  setInitialConditions(ssa, final_values, smt_conds)
  
   
  # we start without free variables
  fvars = set()

  for ins_str in inss:
    #print ins_str.strip("\n")
    #for v in mvars:
    #  print v,
    #   
    pins = parse_reil(ins_str)
    ins = Instruction(pins, memory.getAccess(counter), mem_regs = False)  
  
    ins_write_vars = set(ins.getWriteVarOperands())
    ins_read_vars = set(ins.getReadVarOperands())
 
    if pins.instruction == "jcc" or len(ins_write_vars.intersection(mvars)) > 0:
      
      ssa_map = ssa.getMap(ins_read_vars.difference(mvars), ins_write_vars, ins_read_vars.intersection(mvars))

      cons = conds.get(pins.instruction, Condition)
      condition = cons(ins, ssa_map)
     
      mvars = mvars.difference(ins_write_vars) 
      mvars = ins_read_vars.union(mvars)
   
      smt_conds.add(condition.getEq())
      
    elif (ins.instruction == "call" and ins.called_function <> None):
      
      func_cons = funcs.get(ins.called_function, Function)
      func = func_cons(None, parameters.getParameters(counter))
      
      func_write_vars = set(func.getWriteVarOperands())
      func_read_vars = set(func.getReadVarOperands())
      
      #for op in func_write_vars:
      #  print op
      
      if len(func_write_vars.intersection(mvars)) > 0:
        ssa_map = ssa.getMap(func_read_vars.difference(mvars), func_write_vars, func_read_vars.intersection(mvars))
        
        
        cons = conds.get(ins.called_function, Condition)
        condition = cons(func, None)
        
        c = condition.getEq(func_write_vars.intersection(mvars))
        
        mvars = mvars.difference(func_write_vars) 
        mvars = func_read_vars.union(mvars)
        
        smt_conds.add(c)
    
    # additional conditions
    
    mvars = addAditionalConditions(mvars, ins, ssa, callstack, smt_conds)
    

    # no more things to do
    # we update the counter 
    counter = counter - 1    
    # we update the current call for next instruction
    callstack.prevInstruction(ins_str) 
  
  #for v in mvars:
  #  print v
  
  fvars = filter(lambda v: not (v in initial_values.keys()), mvars)
  for v in fvars:
  #  print v,n
    if not (v in initial_values) and not (":" in v.name):
      print "#Warning", str(v), "is free!" 
  
  setInitialConditions(ssa, initial_values, smt_conds)
  
  if (smt_conds.is_sat()):
    smt_conds.solve()
  
    smt_conds.write_smtlib_file("exp.smt2")  
    smt_conds.write_sol_file("exp.sol")
  
    return Solution(smt_conds.m, fvars)
  else: # unsat :(
    return None
Exemple #37
0
def getTypedValueFromCode(inss, callstack, initial_values, memory, op, debug = False):
  
  # Initialization
  
  # we reverse the code order
  inss.reverse()
  
  # we reset the used memory variables
  Memvars.reset()
  
  # we save the current callstack
  last_index = callstack.index  # TODO: create a better interface
  
  # we set the instruction counter
  counter = len(inss)-1
  
  # ssa and smt objects
  ssa = SSA()
  smt_conds  = SMT()
  
  val_type = None
  mvars = set()
 
  if (op.isImm()):
    return op
  elif (op.isMem()):
    for i in range(op.size):
      name = op.mem_source+"@"+str(op.mem_offset+i)
      mvars.add(Operand(name, "BYTE", op.mem_source, op.mem_offset+i))
      #print name
  else:
    # we will start tracking op
    mvars.add(op)
    
  # we start without free variables
  fvars = set()
  
  ssa.getMap(mvars, set(), set())

  for ins_str in inss:
    #print inss.current, "->", ins_str.strip("\n")
    #print ins_str.strip("\n")
    #for v in mvars:
    #  print v,
    #
    #print ""
    #
    pins = parse_reil(ins_str)
    ins = Instruction(pins, memory.getAccess(counter), mem_regs = False)
  
    ins_write_vars = set(ins.getWriteVarOperands())
    ins_read_vars = set(ins.getReadVarOperands())
 
    if len(ins_write_vars.intersection(mvars)) > 0: 
      
      ssa_map = ssa.getMap(ins_read_vars.difference(mvars), ins_write_vars, ins_read_vars.intersection(mvars))

      cons = conds.get(pins.instruction, Condition)
      condition = cons(ins, ssa_map)
     
      mvars = mvars.difference(ins_write_vars) 
      mvars = ins_read_vars.union(mvars)
   
      smt_conds.add(condition.getEq())
    
    # simple typing
    new_val_type = detectType(mvars, ins, counter, callstack)
    
    # additional conditions
    mvars = addAditionalConditions(mvars, ins, ssa, callstack, smt_conds)
    
    val_type = max(val_type, new_val_type)


    # no more things to do
    # we update the counter 
    counter = counter - 1    
    # we update the current call for next instruction
    callstack.prevInstruction(ins_str) 
  
  if val_type == None:
    val_type = "imm"
  
  for v in mvars:
    if not (v in initial_values):
      print "#Warning__", str(v), "is free!" 
  
  setInitialConditions(ssa, initial_values, smt_conds)
  smt_conds.solve(debug)
  
  if op.isReg():
    op.name = op.name+"_0"
    
  elif op.isMem():
    op.mem_source = op.mem_source+"_0"
  
  callstack.index = last_index  # TODO: create a better interface
  if (debug):
    print val_type, op, smt_conds.getValue(op)
  return mkVal(val_type, smt_conds.getValue(op))
Exemple #38
0
 def assemble(self, i):
     # Parsing phase
     # XXX better error reporting, it should at least print the line
     kernel = None
     state = 0 # closed
     line = 0 # line number
     while True:
         line += 1
         text = i.readline()
         if not text:
             break
         text = text.rstrip("\r\n")
         # strip comments
         for c in self.comment:
             try:
                 text = text[:text.index(c)]
             except ValueError:
                 pass
         # strip trailing or initial whitespace
         text = text.lstrip("\t ")
         text = text.rstrip("\t ")
         # skip empty lines or lines containing only comments
         if len(text)==0:
             continue
         if text == "{":
             # open block
             if state != 0 or kernel == None:
                 raise CompilationError(line, "Block open in wrong context")
             state = 1 # block opened
         elif text == "}":
             # close block
             if state != 1 or kernel == None:
                 raise CompilationError(line, "Block close in wrong context")
             #print kernel.instructions
             self.output.kernels.append(kernel)
             state = 0 # closed
             kernel = None
         elif text.startswith("."):
             # meta instruction
             text = text[1:]
             inst = text.split(" ")
             if inst[0] == "entry":
                 kernel = Kernel()
                 kernel.name = inst[1]
                 kernel.lmem = 0
                 kernel.smem = 0
                 kernel.reg = 0
                 kernel.bar = 0
                 kernel.instructions = []
             elif inst[0] in ["lmem", "smem", "reg", "bar"]:
                 if kernel == None:
                     raise CompilationError(line, "Kernel attribute outside kernel definition")
                 setattr(kernel, inst[0], int(inst[1]))
             elif inst[0] == "constseg":
                 # start of constant segment
                 # N:offset name
                 (N, offset) = inst[1].split(":")
                 try:
                     name = inst[2]
                 except LookupError:
                     name = None
                 print N, offset, name
             else:
                 raise CompilationError(line, "Invalid meta-instruction %s" % inst[0])
         else: 
             # check for label
             try:
                 lend = text.index(":")
             except ValueError:
                 pass
             else:
                 # label
                 label = text[0:lend]
                 text = text[lend+1:]
                 text = text.lstrip("\t ")
                 ptr = len(kernel.instructions)
                 kernel.instructions.append(Label(label))
                 
             if len(text) != 0:
                 # normal instruction
                 if kernel == None:
                     raise CompilationError(line, "Instruction outside kernel definition")
                 inst = Instruction()
                 inst.visited = None
                 inst.line = line
                 try:
                     inst.parse(text)
                 except ValueError,e:
                     raise CompilationError(line, e.message)
                 kernel.instructions.append(inst)