Example #1
0
 def getSemantics(self, value):
     if( isinstance( value, Expr)):
         return self.semantics.get(value)
     else:
         # Try to translate into a reg 
         if( isinstance(value, int)):
             num = value
         elif( value in Arch.regNameToNum ):
             num = Arch.n2r(value)
         else:
             return []
         # Return corresponding if present 
         if( num in self.graph.lastMod ):
             reg = SSAReg(num, self.graph.lastMod[num])
             return self.semantics.get(reg)
         # Or return the same
         else:
             return [SPair(SSAExpr(num, 0), CTrue())]
Example #2
0
 def __init__(self, addr_list, raw):
     """
     addr_list = list of addresses of the gadget (if duplicate gadgets)
     raw = raw string of gadget asm 
     """
     # Check the type of the gadget 
     # Check for 'int 0x80' gadgets
     if( raw == '\xcd\x80' and Arch.currentIsIntel()): 
         self.type = GadgetType.INT80
         self.asmStr = 'int 0x80'
         self.hexStr = '\\xcd\\x80'
         self.addrList = addr_list
         self.nbInstr = self.nbInstrREIL = 1
         self.semantics = Semantics() 
         return 
     # Check for 'syscall' gadgets 
     elif( raw == '\x0f\x05' and Arch.currentIsIntel()):
         self.type = GadgetType.SYSCALL
         self.asmStr = 'syscall'
         self.hexStr = '\\x0f\\x05'
         self.addrList = addr_list
         self.nbInstr = self.nbInstrREIL = 1
         self.semantics = Semantics()
         return 
     
     # Translate raw assembly into REIL 
     # Then compute the Graph and its semantics 
     try:
         (irsb, ins) = Arch.currentArch.asmToREIL(raw)
     except Arch.ArchException as e:
         raise GadgetException(str(e))
     try: 
         self.graph = REILtoGraph(irsb)
         self.semantics = self.graph.getSemantics()
     except GraphException as e:
         raise GadgetException("(In {}) - ".format('; '.join(str(i) for i in ins)) + str(e))
     
     self.type = GadgetType.REGULAR
     # Possible addresses     
     self.addrList = addr_list
     # String representations
     self.asmStr = '; '.join(str(i) for i in ins) 
     self.hexStr = '\\x' + '\\x'.join("{:02x}".format(ord(c)) for c in raw)
     # Length of the gadget 
     self.nbInstr = len(ins)
     self.nbInstrREIL = len(irsb)
     
     # List of modified registers 
     # And of memory-read accesses 
     self._modifiedRegs = []
     self._memoryReads = []
     for reg_num in list(set([reg.num for reg in self.semantics.registers.keys()])):
         # Check if there is an empty semantics 
         if( not self.getSemantics(reg_num)):
             #self.semantics.registers.pop(reg)
             log("Gadget ({}) : empty semantics for {}"\
             .format(self.asmStr, Arch.r2n(reg_num)))
             self._modifiedRegs.append(reg_num)
             continue
         # Get modified reg
         if ((SSAExpr(reg_num,0) != self.getSemantics(reg_num)[0].expr) ):
             self._modifiedRegs.append(reg_num)
         # Get memory reads 
         for pair in self.getSemantics(reg_num):
             self._memoryReads += [m[0] for m in pair.expr.getMemAcc()]
               
     self._modifiedRegs = list(set(self._modifiedRegs))
     
     # SP Increment 
     if( self.type != GadgetType.REGULAR ):
         self.spInc = None
     else:
         sp_num = Arch.spNum()
         if( not sp_num in self.graph.lastMod ):
             self.spInc = 0
         else:                
             sp = SSAReg(sp_num, self.graph.lastMod[sp_num])
             if( len(self.semantics.get(sp)) == 1 ):
                 (isInc, inc) = self.semantics.get(sp)[0].expr.isRegIncrement(sp_num)
                 if( isInc ):
                     self.spInc = inc
                 else:
                     self.spInc = None
             else:
                 self.spInc = None
     
     # Return type
     self.retType = RetType.UNKNOWN
     self.retValue = None
     if( self.type == GadgetType.REGULAR ):
         ip_num = Arch.n2r(Arch.currentArch.ip)
         ip = SSAReg(ip_num, self.graph.lastMod[ip_num])
         sp_num = Arch.n2r(Arch.currentArch.sp)
         
         if( self.spInc != None ):
             for p in self.semantics.get(ip):
                 if( p.cond.isTrue()):
                     if( isinstance(p.expr, MEMExpr)):
                         addr = p.expr.addr
                         (isInc, inc) = addr.isRegIncrement(sp_num)    
                         # Normal ret if the final value of the IP is value that was in memory before the last modification of SP ( i.e final_IP = MEM[final_sp - size_of_a_register )        
                         if( isInc and inc == (self.spInc - (Arch.currentArch.octets)) ):
                             self.retType = RetType.RET
                             self.retValue = p.expr
                     elif( isinstance(p.expr, SSAExpr )):
                         self.retValue = p.expr
                         # Try to detect gadgets ending by 'call' 
                         if( ins[-1]._mnemonic[:4] == "call"):
                             self.retType = RetType.CALL
                         else:
                             self.retType = RetType.JMP