/* add tag to a field * - obj only used if the field is not static */ void addTaintToField(Field* field, Object* obj, u4 tag) { if (dvmIsStaticField(field)) { StaticField* sfield = (StaticField*) field; tag |= dvmGetStaticFieldTaint(sfield); dvmSetStaticFieldTaint(sfield, tag); } else { InstField* ifield = (InstField*) field; if (field->signature[0] == 'J' || field->signature[0] == 'D') { tag |= dvmGetFieldTaintWide(obj, ifield->byteOffset); dvmSetFieldTaintWide(obj, ifield->byteOffset, tag); } else { tag |= dvmGetFieldTaint(obj, ifield->byteOffset); dvmSetFieldTaint(obj, ifield->byteOffset, tag); } } }
/* * Primitive field setters, e.g.: * private void setIField(Object o, Class declaringClass, * Class type, int slot, boolean noAccessCheck, int type_no, int value) * * The "type_no" is defined by the java.lang.reflect.Field class. */ static void Dalvik_java_lang_reflect_Field_setPrimitiveField(const u4* args, JValue* pResult) { // ignore thisPtr in args[0] Object* obj = (Object*) args[1]; ClassObject* declaringClass = (ClassObject*) args[2]; ClassObject* fieldType = (ClassObject*) args[3]; int slot = args[4]; bool noAccessCheck = (args[5] != 0); int typeNum = args[6]; const s4* valuePtr = (s4*) &args[7]; #ifdef WITH_TAINT_TRACKING /* rtaint = args[8] * thisPtr taint = args[9] * obj taint = args[10] * declaringClass taint = args[11] * fieldType taint = args[12] * slot taint = args[13] * noAccessCheck taint = args[14] * typeNum taint = args[15] */ u4 valueTaint = args[16]; #endif PrimitiveType srcType = convPrimType(typeNum); JValue* fieldPtr; JValue value; if (!dvmIsPrimitiveClass(fieldType)) { dvmThrowException("Ljava/lang/IllegalArgumentException;", "not a primitive field"); RETURN_VOID(); } /* convert the 32/64-bit arg to a JValue matching the field type */ if (dvmConvertPrimitiveValue(srcType, fieldType->primitiveType, valuePtr, &(value.i)) < 0) { dvmThrowException("Ljava/lang/IllegalArgumentException;", "invalid primitive conversion"); RETURN_VOID(); } /* get a pointer to the field's data; performs access checks */ fieldPtr = getFieldDataAddr(obj, declaringClass, slot, true, noAccessCheck); if (fieldPtr == NULL) RETURN_VOID(); /* store 4 or 8 bytes */ if (fieldType->primitiveType == PRIM_LONG || fieldType->primitiveType == PRIM_DOUBLE) { fieldPtr->j = value.j; } else { fieldPtr->i = value.i; } #ifdef WITH_TAINT_TRACKING /* If we got this far, we know the fields is okay to access and there * will not be a problem getting the field from the slot */ { Field* field = dvmSlotToField(declaringClass, slot); assert(field != NULL); if (dvmIsStaticField(field)) { StaticField* sfield = (StaticField*)field; dvmSetStaticFieldTaint(sfield, valueTaint); } else { /* Note, getFieldDataAddr() already checked that * obj is of type declaringClass, so no need to check here */ InstField* ifield = (InstField*)field; if (fieldType->primitiveType == PRIM_LONG || fieldType->primitiveType == PRIM_DOUBLE) { dvmSetFieldTaintWide(obj, ifield->byteOffset, valueTaint); } else { dvmSetFieldTaint(obj, ifield->byteOffset, valueTaint); } } } #endif RETURN_VOID(); }
/* * private void setField(Object o, Class declaringClass, Class type, * int slot, boolean noAccessCheck, Object value) * * When assigning into a primitive field we will automatically extract * the value from box types. */ static void Dalvik_java_lang_reflect_Field_setField(const u4* args, JValue* pResult) { // ignore thisPtr in args[0] Object* obj = (Object*) args[1]; ClassObject* declaringClass = (ClassObject*) args[2]; ClassObject* fieldType = (ClassObject*) args[3]; int slot = args[4]; bool noAccessCheck = (args[5] != 0); Object* valueObj = (Object*) args[6]; #ifdef WITH_TAINT_TRACKING /* rtaint = args[7] * thisPtr taint = args[8] * obj taint = args[9] * declaringClass taint = args[10] * fieldType taint = args[11] * slot taint = args[12] * noAccessCheck taint = args[13] */ u4 valueTaint = args[14]; #endif JValue* fieldPtr; JValue value; /* unwrap primitive, or verify object type */ if (!dvmUnwrapPrimitive(valueObj, fieldType, &value)) { dvmThrowException("Ljava/lang/IllegalArgumentException;", "invalid value for field"); RETURN_VOID(); } /* get a pointer to the field's data; performs access checks */ fieldPtr = getFieldDataAddr(obj, declaringClass, slot, true, noAccessCheck); if (fieldPtr == NULL) RETURN_VOID(); /* store 4 or 8 bytes */ if (fieldType->primitiveType == PRIM_LONG || fieldType->primitiveType == PRIM_DOUBLE) { fieldPtr->j = value.j; } else if (fieldType->primitiveType == PRIM_NOT) { if (slot < 0) { StaticField *sfield; sfield = (StaticField *)dvmSlotToField(declaringClass, slot); assert(fieldPtr == &sfield->value); dvmSetStaticFieldObject(sfield, value.l); } else { int offset = declaringClass->ifields[slot].byteOffset; assert(fieldPtr == (JValue *)BYTE_OFFSET(obj, offset)); dvmSetFieldObject(obj, offset, value.l); } } else { fieldPtr->i = value.i; } #ifdef WITH_TAINT_TRACKING /* If we got this far, we know the fields is okay to access and there * will not be a problem getting the field from the slot */ { Field* field = dvmSlotToField(declaringClass, slot); assert(field != NULL); if (dvmIsStaticField(field)) { StaticField* sfield = (StaticField*)field; dvmSetStaticFieldTaint(sfield, valueTaint); } else { /* Note, getFieldDataAddr() already checked that * obj is of type declaringClass, so no need to check here */ InstField* ifield = (InstField*)field; if (fieldType->primitiveType == PRIM_LONG || fieldType->primitiveType == PRIM_DOUBLE) { dvmSetFieldTaintWide(obj, ifield->byteOffset, valueTaint); } else { dvmSetFieldTaint(obj, ifield->byteOffset, valueTaint); } } } #endif RETURN_VOID(); }