Beispiel #1
0
static UINT32 process_rop(UINT32 src, UINT32 dst, UINT32 pat, const char* rop,
                          UINT32 format)
{
	DWORD stack[10] = { 0 };
	DWORD stackp = 0;

	while (*rop != '\0')
	{
		char op = *rop++;

		switch (op)
		{
			case '0':
				stack[stackp++] = FreeRDPGetColor(format, 0, 0, 0, 0xFF);
				break;

			case '1':
				stack[stackp++] = FreeRDPGetColor(format, 0xFF, 0xFF, 0xFF, 0xFF);
				break;

			case 'D':
				stack[stackp++] = dst;
				break;

			case 'S':
				stack[stackp++] = src;
				break;

			case 'P':
				stack[stackp++] = pat;
				break;

			case 'x':
				op_xor(stack, &stackp);
				break;

			case 'a':
				op_and(stack, &stackp);
				break;

			case 'o':
				op_or(stack, &stackp);
				break;

			case 'n':
				op_not(stack, &stackp);
				break;

			default:
				break;
		}
	}

	return stack[0];
}
Beispiel #2
0
void StackInterpreter::processOpCode(const OpCode& oc)
{
   ++opcount_;

   //handle push data by itself, doesn't play well with switch
   if (oc.opcode_ == 0)
   {
      op_0();
      return;
   }

   if (oc.opcode_ <= 75)
   {
      stack_.push_back(oc.dataRef_);
      return;
   }

   if (oc.opcode_ < 79)
   {
      //op push data
      stack_.push_back(oc.dataRef_);
      return;
   }

   if (oc.opcode_ == OP_1NEGATE)
   {
      op_1negate();
      return;
   }

   if (oc.opcode_ <= 96 && oc.opcode_ >= 81)
   {
      //op_1 - op_16
      uint8_t val = oc.opcode_ - 80;
      stack_.push_back(move(intToRawBinary(val)));
      return;
   }

   //If we got this far this op code is not push data. If this is the input
   //script, set the flag as per P2SH parsing rules (only push data in inputs)
   if (outputScriptRef_.getSize() == 0)
      onlyPushDataInInput_ = false;

   switch (oc.opcode_)
   {
   case OP_NOP:
      break;

   case OP_IF:
   {
      BinaryRefReader brr(oc.dataRef_);
      op_if(brr, false);
      break;
   }

   case OP_NOTIF:
   {
      op_not();
      BinaryRefReader brr(oc.dataRef_);
      op_if(brr, false);
      break;
   }

   case OP_ELSE:
      //processed by opening if statement
      throw ScriptException("a wild else appears");

   case OP_ENDIF:
      //processed by opening if statement
      throw ScriptException("a wild endif appears");

   case OP_VERIFY:
      op_verify();
      break;

   case OP_TOALTSTACK:
      op_toaltstack();
      break;

   case OP_FROMALTSTACK:
      op_fromaltstack();
      break;

   case OP_IFDUP:
      op_ifdup();
      break;

   case OP_2DROP:
   {
      stack_.pop_back();
      stack_.pop_back();
      break;
   }

   case OP_2DUP:
      op_2dup();
      break;

   case OP_3DUP:
      op_3dup();
      break;

   case OP_2OVER:
      op_2over();
      break;

   case OP_DEPTH:
      op_depth();
      break;

   case OP_DROP:
      stack_.pop_back();
      break;

   case OP_DUP:
      op_dup();
      break;

   case OP_NIP:
      op_nip();
      break;

   case OP_OVER:
      op_over();
      break;

   case OP_PICK:
      op_pick();
      break;

   case OP_ROLL:
      op_roll();
      break;

   case OP_ROT:
      op_rot();
      break;

   case OP_SWAP:
      op_swap();
      break;

   case OP_TUCK:
      op_tuck();
      break;

   case OP_SIZE:
      op_size();
      break;

   case OP_EQUAL:
   {
      op_equal();
      if (onlyPushDataInInput_ && p2shScript_.getSize() != 0)
      {
         //check the op_equal result
         op_verify();
         if (!isValid_)
            break;

         if (flags_ & SCRIPT_VERIFY_SEGWIT)
            if (p2shScript_.getSize() == 22 ||
               p2shScript_.getSize() == 34)
            {
               auto versionByte = p2shScript_.getPtr();
               if (*versionByte <= 16)
               {
                  processSW(p2shScript_);
                  return;
               }
            }

         processScript(p2shScript_, true);
      }
      break;
   }

   case OP_EQUALVERIFY:
   {
      op_equal();
      op_verify();
      break;
   }

   case OP_1ADD:
      op_1add();
      break;

   case OP_1SUB:
      op_1sub();
      break;

   case OP_NEGATE:
      op_negate();
      break;

   case OP_ABS:
      op_abs();
      break;

   case OP_NOT:
      op_not();
      break;

   case OP_0NOTEQUAL:
      op_0notequal();
      break;

   case OP_ADD:
      op_add();
      break;

   case OP_SUB:
      op_sub();
      break;

   case OP_BOOLAND:
      op_booland();
      break;

   case OP_BOOLOR:
      op_boolor();
      break;

   case OP_NUMEQUAL:
      op_numequal();
      break;

   case OP_NUMEQUALVERIFY:
   {
      op_numequal();
      op_verify();
      break;
   }

   case OP_NUMNOTEQUAL:
      op_numnotequal();
      break;

   case OP_LESSTHAN:
      op_lessthan();
      break;

   case OP_GREATERTHAN:
      op_greaterthan();
      break;

   case OP_LESSTHANOREQUAL:
      op_lessthanorequal();
      break;

   case OP_GREATERTHANOREQUAL:
      op_greaterthanorequal();
      break;

   case OP_MIN:
      op_min();
      break;

   case OP_MAX:
      op_max();
      break;

   case OP_WITHIN:
      op_within();
      break;

   case OP_RIPEMD160:
      op_ripemd160();
      break;

   case OP_SHA256:
   {
      //save the script if this output is a possible p2sh
      if (flags_ & SCRIPT_VERIFY_P2SH_SHA256)
         if (opcount_ == 1 && onlyPushDataInInput_)
            p2shScript_ = stack_back();

      op_sha256();
      break;
   }

   case OP_HASH160:
   {
      //save the script if this output is a possible p2sh
      if (flags_ & SCRIPT_VERIFY_P2SH)
         if (opcount_ == 1 && onlyPushDataInInput_)
            p2shScript_ = stack_back();

      op_hash160();
      break;
   }

   case OP_HASH256:
      op_hash256();
      break;

   case OP_CODESEPARATOR:
   {
      opcount_ = 0;
      if (outputScriptRef_.getSize() != 0)
         txStubPtr_->setLastOpCodeSeparator(inputIndex_, oc.offset_);
      break;
   }

   case OP_CHECKSIG:
      op_checksig();
      break;

   case OP_CHECKSIGVERIFY:
   {
      op_checksig();
      op_verify();
      break;
   }

   case OP_CHECKMULTISIG:
      op_checkmultisig();
      break;

   case OP_CHECKMULTISIGVERIFY:
   {
      op_checkmultisig();
      op_verify();
   }

   case OP_NOP1:
      break;

   case OP_NOP2:
   {
      if (!(flags_ & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY))
         break; // not enabled; treat as a NOP

      //CLTV mechanics
      throw ScriptException("OP_CLTV not supported");
   }

   case OP_NOP3:
   {
      if (!(flags_ & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY))
         break; // not enabled; treat as a NOP

      //CSV mechanics
      throw ScriptException("OP_CSV not supported");
   }

   case OP_NOP4:
      break;

   case OP_NOP5:
      break;

   case OP_NOP6:
      break;

   case OP_NOP7:
      break;

   case OP_NOP8:
      break;

   case OP_NOP9:
      break;

   case OP_NOP10:
      break;

   default:
   {
      stringstream ss;
      ss << "unknown opcode: " << (unsigned)oc.opcode_;
      throw runtime_error(ss.str());
   }
   }
}
Beispiel #3
0
void Step()
{
	Opcodes OP = (Opcodes)Fetch8();
	//printf("%08X:%08X\n", Registers[sp], Registers[pc]);
	switch (OP)
	{
	case O_NOP:
		op_nop();
		break;
	case O_MOV:
		op_mov();
		break;
	case O_ADD:
		op_add();
		break;
	case O_SUB:
		op_sub();
		break;
	case O_MUL:
		op_mul();
		break;
	case O_DIV:
		op_div();
		break;
	case O_LI:
		op_li();
		break;
	case O_MOVF:
		op_movf();
		break;
	case O_ADDF:
		op_addf();
		break;
	case O_SUBF:
		op_subf();
		break;
	case O_MULF:
		op_mulf();
		break;
	case O_DIVF:
		op_divf();
		break;
	case O_LIF:
		op_lif();
		break;
	case O_XOR:
		op_xor();
		break;
	case O_AND:
		op_and();
		break;
	case O_MOD:
		op_mod();
		break;
	case O_OR:
		op_or();
		break;
	case O_NOT:
		op_not();
		break;
	case O_SHR:
		op_shr();
		break;
	case O_SHL:
		op_shl();
		break;
	case O_PUSH:
		op_push();
		break;
	case O_POP:
		op_pop();
		break;
	case O_STB:
		op_stb();
		break;
	case O_LDB:
		op_ldb();
		break;
	case O_STH:
		op_sth();
		break;
	case O_LDH:
		op_ldh();
		break;
	case O_STW:
		op_stw();
		break;
	case O_LDW:
		op_ldw();
		break;
	case O_LDF:
		op_ldf();
		break;
	case O_STF:
		op_stf();
		break;
	case O_CMP:
		op_cmp();
		break;
	case O_B:
		op_b(0);
		break;
	case O_BC:
		op_b(1);
		break;
	case O_BEQ:
		op_bcond(ctr0_eq);
		break;
	case O_BNE:
		op_bcond(ctr0_ne);
		break;
	case O_BGT:
		op_bcond(ctr0_gt);
		break;
	case O_BLT:
		op_bcond(ctr0_lt);
		break;
	case O_BTC:
		op_btc();
		break;
	case O_INC:
		op_inc();
		break;
	case O_DEC:
		op_dec();
		break;
	default:
		Error("Error: Unknown Opcode PC = %d OP = %08X\n", Registers[pc], OP);
	}

	Ticks++;
}
Beispiel #4
0
static int
op_oplevel(int level)
{
   int             precision;

   bwx_DEBUG(__FUNCTION__);

   /* set the precision */

   if ((precision = op_getprecision(level)) == OP_ERROR)
   {
      op_pulldown(2);
      sprintf(bwb_ebuf, "exp_operation(): failed to set precision.");
      bwb_error(bwb_ebuf);
      return FALSE;
   }
   /* precision is set correctly */

   else
   {

      switch (CURTASK exps[level].operation)
      {
      case OP_ADD:
         op_add(level, precision);
         break;

      case OP_SUBTRACT:
         op_subtract(level, precision);
         break;

      case OP_MULTIPLY:
         op_multiply(level, precision);
         break;

      case OP_DIVIDE:
         op_divide(level, precision);
         break;

      case OP_ASSIGN:
         op_assign(level, precision);
         break;

      case OP_EQUALS:
         op_equals(level, precision);
         break;

      case OP_LESSTHAN:
         op_lessthan(level, precision);
         break;

      case OP_GREATERTHAN:
         op_greaterthan(level, precision);
         break;

      case OP_LTEQ:
         op_lteq(level, precision);
         break;

      case OP_GTEQ:
         op_gteq(level, precision);
         break;

      case OP_NOTEQUAL:
         op_notequal(level, precision);
         break;

      case OP_MODULUS:
         op_modulus(level, precision);
         break;

      case OP_INTDIVISION:
         op_intdiv(level, precision);
         break;

      case OP_OR:
         op_or(level, precision);
         break;

      case OP_AND:
         op_and(level, precision);
         break;

      case OP_NOT:
         op_not(level, precision);
         break;

      case OP_XOR:
         op_xor(level, precision);
         break;

      case OP_IMPLIES:
         op_imp(level, precision);
         break;

      case OP_EQUIV:
         op_eqv(level, precision);
         break;

      case OP_EXPONENT:
         op_exponent(level, precision);
         break;

      case OP_NEGATION: /* JBV */
         op_negation(level, precision);
         break;

      case OP_POSATION:
         op_posation(level, precision);
         break;

      default:
         sprintf(bwb_ebuf, "PROGRAMMING ERROR: operator <%d> not (yet) supported.", CURTASK exps[level].operation);
         op_pulldown(2);
         bwb_error(bwb_ebuf);
         return FALSE;
         break;
      }     /* end of case statement for operators */
   }        /* end of else statement, precision set */

   return TRUE;

}           /* end of function op_oplevel() */
Beispiel #5
0
Expr phi( Expr cond, Expr ok, Expr ko ) {
    // known value ?
    bool v;
    if ( cond.get_val( v ) )
        return v ? ok : ko;

    // the same value in all the cases ?
    if ( ok == ko )
        return ok;

    // if ok or ko are undefined
    // if ( ok.inst->undefined() ) return ko;
    // if ( ko.inst->undefined() ) return ok;


    // phi( not c, a, b ) -> phi( c, b, a )
    if ( cond.inst->inst_id() == Inst::Id_Op_not )
        return phi( cond.inst->inp_expr( 0 ), ko, ok );

    // phi( c, true, false ) -> c
    // phi( c, false, true ) -> not c
    if ( ok.size_in_bits() == 1 and ko.size_in_bits() == 1 ) {
        bool va, vb;
        if ( ok.get_val( va ) and ko.get_val( vb ) ) {
            if ( va and not vb )
                return cond;
            if ( vb and not va )
                return op_not( bt_Bool, cond );
        }
    }

    // phi( c, b, c )
    if ( cond == ko )
        return phi( cond, ok, cst( false ) );

    // phi( c, c, b )
    if ( cond == ok )
        return phi( cond, cst( true ), ko );


    // if ok is a phi node tree which contain cond in the conditions
    if ( Expr nok = phi_with_cond( cond, 1, ok ) )
        return phi( cond, nok, ko );

    // if ko is a phi node tree which contain cond in the conditions
    if ( Expr nko = phi_with_cond( cond, 0, ko ) )
        return phi( cond, ok, nko );

    // phi( cond, a, phi( cond,  ) )

    // cond = bool( ... )
    //if ( cond.inst->inst_id() == Inst::Id_Conv and cond.inst->out_bt( 0 ) == bt_Bool )
    //    cond = cond.inst->inp_expr( 0 );

    // else, create a new inst
    Phi *res = new Phi;
    res->inp_repl( 0, cond );
    res->inp_repl( 1, ok );
    res->inp_repl( 2, ko );
    return Expr( Inst::factorized( res ), 0 );
}