/* 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); } } }
/* Returns the taint tag for a field * - obj only used if the field is not static */ u4 getTaintFromField(Field* field, Object* obj) { u4 tag = TAINT_CLEAR; if (dvmIsStaticField(field)) { StaticField* sfield = (StaticField*) field; tag = dvmGetStaticFieldTaint(sfield); } else { InstField* ifield = (InstField*) field; if (field->signature[0] == 'J' || field->signature[0] == 'D') { tag = dvmGetFieldTaintWide(obj, ifield->byteOffset); } else { tag = dvmGetFieldTaint(obj, ifield->byteOffset); } } return tag; }
/* * Primitive field getters, e.g.: * private double getIField(Object o, Class declaringClass, * Class type, int slot, boolean noAccessCheck, int type_no) * * The "type_no" is defined by the java.lang.reflect.Field class. */ static void Dalvik_java_lang_reflect_Field_getPrimitiveField(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]; #ifdef WITH_TAINT_TRACKING u4* rtaint = (u4*) &args[7]; /* return taint tag slot */ #endif PrimitiveType targetType = convPrimType(typeNum); const JValue* fieldPtr; JValue value; if (!dvmIsPrimitiveClass(fieldType)) { dvmThrowException("Ljava/lang/IllegalArgumentException;", "not a primitive field"); RETURN_VOID(); } /* get a pointer to the field's data; performs access checks */ fieldPtr = getFieldDataAddr(obj, declaringClass, slot, false,noAccessCheck); if (fieldPtr == NULL) RETURN_VOID(); /* copy 4 or 8 bytes out */ if (fieldType->primitiveType == PRIM_LONG || fieldType->primitiveType == PRIM_DOUBLE) { value.j = fieldPtr->j; } else { value.i = fieldPtr->i; } /* retrieve value, performing a widening conversion if necessary */ if (dvmConvertPrimitiveValue(fieldType->primitiveType, targetType, &(value.i), &(pResult->i)) < 0) { dvmThrowException("Ljava/lang/IllegalArgumentException;", "invalid primitive conversion"); RETURN_VOID(); } #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; *rtaint = dvmGetStaticFieldTaint(sfield); } 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) { *rtaint = dvmGetFieldTaintWide(obj, ifield->byteOffset); } else { *rtaint = dvmGetFieldTaint(obj, ifield->byteOffset); } } } #endif }
/* * private Object getField(Object o, Class declaringClass, Class type, * int slot, boolean noAccessCheck) * * Primitive types need to be boxed. */ static void Dalvik_java_lang_reflect_Field_getField(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); #ifdef WITH_TAINT_TRACKING u4* rtaint = (u4*) &args[6]; /* return taint tag slot */ #endif JValue value; const JValue* fieldPtr; DataObject* result; //dvmDumpClass(obj->clazz, kDumpClassFullDetail); /* get a pointer to the field's data; performs access checks */ fieldPtr = getFieldDataAddr(obj, declaringClass, slot, false,noAccessCheck); if (fieldPtr == NULL) RETURN_VOID(); /* copy 4 or 8 bytes out */ if (fieldType->primitiveType == PRIM_LONG || fieldType->primitiveType == PRIM_DOUBLE) { value.j = fieldPtr->j; } else { value.i = fieldPtr->i; } result = dvmWrapPrimitive(value, fieldType); dvmReleaseTrackedAlloc((Object*) result, NULL); #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; *rtaint = dvmGetStaticFieldTaint(sfield); } 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) { *rtaint = dvmGetFieldTaintWide(obj, ifield->byteOffset); } else { *rtaint = dvmGetFieldTaint(obj, ifield->byteOffset); } } } #endif RETURN_PTR(result); }