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]; }
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()); } } }
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++; }
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() */
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 ); }