def executeOpcode(self, op): # NOTE: If an opcode method returns # other than None, that is the new eip if op.va != None: self.setProgramCounter(op.va) meth = self.op_methods.get(op.mnem, None) if meth == None: raise envi.UnsupportedInstruction(self, op) newpc = meth(op) if newpc != None: self.setProgramCounter(newpc) return if op.prefixes & PREFIX_REP: ecx = self.getRegister(REG_ECX) - 1 self.setRegister(REG_ECX, ecx) if self.getEmuOpt('i386:reponce'): ecx = 0 self.setRegister(REG_ECX, 0) if ecx != 0: self.setProgramCounter(op.va) return pc = self.getProgramCounter() newpc = pc + op.size self.setProgramCounter(newpc)
def i_div(self, op): #FIXME this is probably broke oper = op.opers[0] val = self.getOperValue(op, 1) if val == 0: raise envi.DivideByZero(self) if oper.tsize == 1: ax = self.getRegister(REG_AX) quot = ax / val rem = ax % val #if quot > 255: #FIXME stuff #print "FIXME: division exception" self.setRegister(REG_EAX, (quot << 8) + rem) elif oper.tsize == 4: #FIXME 16 bit over-ride eax = self.getRegister(REG_EAX) edx = self.getRegister(REG_EDX) tot = (edx << 32) + eax quot = tot / val rem = tot % val #if quot > 0xffffffff: #print "FIXME: division exception" self.setRegister(REG_EAX, quot) self.setRegister(REG_EDX, rem) else: raise envi.UnsupportedInstruction(self, op)
def i_div(self, op): oper = op.opers[0] divbase = self.getOperObj(op, 1) if oper.tsize == 1: # TODO: this is broken ax = self._reg_ctx._xlateToNativeReg(e_i386.REG_AX, Var('eax', self._psize)) quot = ax / divbase rem = ax % divbase # TODO: this is broken self.effSetVariable('eax', (quot << 8) + rem) elif oper.tsize == 2: raise Exception("16 bit divide needs help!") elif oper.tsize == 4: eax = Var('eax', self._psize) edx = Var('edx', self._psize) #FIXME 16 bit over-ride tot = (edx << Const(32, self._psize)) + eax quot = tot / divbase rem = tot % divbase self.effSetVariable('eax', quot) self.effSetVariable('edx', rem) #FIXME maybe we need a "check exception" effect? else: raise envi.UnsupportedInstruction(self, op)
def executeOpcode(self, op): meth = self.op_methods.get(op.mnem, None) if meth == None: raise envi.UnsupportedInstruction(self, op) newpc = meth(op) if newpc != None: self.setProgramCounter(newpc) return pc = self.getProgramCounter() newpc = pc + op.size self.setProgramCounter(newpc)
def executeOpcode(self, op): # NOTE: If an opcode method returns # other than None, that is the new pc x = None meth = self.op_methods.get(op.mnem, None) if meth == None: raise envi.UnsupportedInstruction(self, op) x = meth(op) if x == None: pc = self.getProgramCounter() x = pc + op.size self.setProgramCounter(x)
def i_enter(self, op): locsize = self.getOperValue(op, 0) depth = self.getOperValue(op, 1) if depth != 0: raise envi.UnsupportedInstruction(self, op) esp = self.getRegister(REG_ESP) ebp = self.getRegister(REG_EBP) esp -= 4 # Room for the base pointer self.writeMemValue(esp, ebp, 4) self.setRegister(REG_EBP, esp) esp -= locsize self.setRegister(REG_ESP, esp)
def executeOpcode(self, op): # NOTE: If an opcode method returns # other than None, that is the new eip meth = self.op_methods.get(op.mnem, None) if meth == None: raise envi.UnsupportedInstruction(self, op) if op.prefixes & PREFIX_REP: x = self.doRepPrefix(meth, op) else: x = meth(op) if x == None: pc = self.getProgramCounter() x = pc+op.size self.setProgramCounter(x)
def executeOpcode(self, op): # NOTE: If an opcode method returns # other than None, that is the new eip x = None if op.prefixes >= 0xe or conditionals[op.prefixes](self.getRegister(REG_FLAGS)>>28): meth = self.op_methods.get(op.mnem, None) if meth == None: raise envi.UnsupportedInstruction(self, op) x = meth(op) if x == None: pc = self.getProgramCounter() x = pc+op.size self.setProgramCounter(x)
def executeOpcode(self, op): # NOTE: If an opcode method returns # other than None, that is the new eip meth = self.op_methods.get(op.mnem, None) if meth == None: raise envi.UnsupportedInstruction(self, op) # msp430 does not have prefixes....for now, I guess #if op.prefixes & PREFIX_REP: #x = self.doRepPrefix(meth, op) #else: #x = meth(op) x = meth(op) if x == None: pc = self.getProgramCounter() x = pc + len(op) self.setProgramCounter(x)
def executeOpcode(self, op): # NOTE: If an opcode method returns # other than None, that is the new eip x = None if op.prefixes >= 0xe or op.prefixes == (self.getRegister(REG_FLAGS)>>28): #nearly every opcode is optional meth = self.op_methods.get(op.mnem, None) if meth == None: raise envi.UnsupportedInstruction(self, op) x = meth(op) print >>sys.stderr,"executed instruction, returned: %s"%x if x == None: pc = self.getProgramCounter() x = pc+op.size self.setProgramCounter(x)
def i_imul(self, op): #FIXME eflags # FIXME imul bugs ocount = len(op.opers) if ocount == 2: dst = self.getOperValue(op, 0) src = self.getOperValue(op, 1) dsize = op.opers[0].tsize ssize = op.opers[1].tsize # FIXME all these are taken care of in disasm now... if dsize > ssize: src = e_bits.sign_extend(src, ssize, dsize) ssize = dsize res = dst * src sof = e_bits.is_unsigned_carry(res, dsize) self.setFlag(EFLAGS_CF, sof) self.setFlag(EFLAGS_OF, sof) self.setOperValue(op, 0, res) elif ocount == 3: dst = self.getOperValue(op, 0) src1 = self.getOperValue(op, 1) src2 = self.getOperValue(op, 2) dsize = op.opers[0].tsize ssize1 = op.opers[1].tsize ssize2 = op.opers[2].tsize if dsize > ssize2: # Only the last operand may be shorter imm src2 = e_bits.sign_extend(src2, ssize2, dsize) ssize2 = dsize res = src1 * src2 sof = e_bits.is_unsigned_carry(res, dsize) self.setFlag(EFLAGS_CF, sof) self.setFlag(EFLAGS_OF, sof) self.setOperValue(op, 0, res) else: raise envi.UnsupportedInstruction(self, op)
def i_divsd(self, op): ocount = len(op.opers) if ocount == 2: dst = self.getOperObj(op, 0) src = self.getOperObj(op, 1) if src == 0: raise Exception('#DE, divide error') res = dst / src self.setOperObj(op, 0, res) elif ocount == 3: src1 = self.getOperObj(op, 1) src2 = self.getOperObj(op, 2) if src2 == 0: raise Exception('#DE, divide error') res = src1 / src2 self.setOperObj(op, 0, res) else: raise envi.UnsupportedInstruction(self, op)
def executeOpcode(self, op): # NOTE: If an opcode method returns # other than None, that is the new eip try: self.setMeta('forrealz', True) x = None if op.prefixes >= 0xe or conditionals[op.prefixes]( self.getRegister(REG_FLAGS) >> 28): meth = self.op_methods.get(op.mnem, None) if meth is None: raise envi.UnsupportedInstruction(self, op) x = meth(op) if x is None: pc = self.getProgramCounter() x = pc + op.size # should we set this to the odd address or even during thumb? (debugger) self.setProgramCounter(x) finally: self.setMeta('forrealz', False)
def i_idiv(self, op): #FIXME this needs emulation testing! tsize = op.opers[0].tsize if tsize == 1: ax = self.getRegister(REG_AX) ax = e_bits.signed(ax, 2) d = self.getOperValue(op, 0) d = e_bits.signed(d, 1) if d == 0: raise envi.DivideByZero(self) q = ax / d r = ax % d res = ((r & 0xff) << 8) | (q & 0xff) self.setRegister(REG_AX, res) elif tsize == 2: val = self.twoRegCompound(REG_DX, REG_AX, 2) val = e_bits.signed(val, 4) d = self.getOperValue(op, 0) d = e_bits.signed(d, 2) if d == 0: raise envi.DivideByZero(self) q = val / d r = val % d self.setRegister(REG_AX, q) self.setRegister(REG_DX, r) elif tsize == 4: val = self.twoRegCompound(REG_EDX, REG_EAX, 4) val = e_bits.signed(val, 8) d = self.getOperValue(op, 0) d = e_bits.signed(d, 4) if d == 0: raise envi.DivideByZero(self) q = val / d r = val % d self.setRegister(REG_EAX, q) self.setRegister(REG_EDX, r) else: raise envi.UnsupportedInstruction(self, op)
def _div(self, op, isInvalid=None): oper = op.opers[0] divbase = self.getOperObj(op, 0) if isInvalid is None: limit = (2**(oper.tsize * 8)) - 1 isInvalid = lambda val: val > limit if oper.tsize == 1: ax = self.getRegObj(e_i386.REG_AX) quot = ax / divbase rem = ax % divbase if quot.isDiscrete() and isInvalid(quot): raise envi.DivideError('i386 #DE') self.effSetVariable('eax', (rem << 8) + quot) elif oper.tsize == 2: ax = self.getRegObj(e_i386.REG_AX) dx = self.getRegObj(e_i386.REG_DX) tot = (edx << Const(16, self._psize)) + eax quot = tot / divbase rem = tot % divbase if quot.isDiscrete() and isInvalid(quot): raise envi.DivideError('i386 #DE') self.effSetVariable('eax', quot) self.effSetVariable('edx', rem) elif oper.tsize == 4: eax = Var('eax', self._psize) edx = Var('edx', self._psize) tot = (edx << Const(32, self._psize)) + eax quot = tot / divbase rem = tot % divbase if quot.isDiscrete() and isInvalid(quot): raise envi.DivideError('i386 #DE') self.effSetVariable('eax', quot) self.effSetVariable('edx', rem) # FIXME maybe we need a "check exception" effect? else: raise envi.UnsupportedInstruction(self, op)
def i_int(self, op): raise envi.UnsupportedInstruction(self, op)