Exemple #1
0
/*
 * Convert an array of char* into a String[].
 *
 * Returns NULL on failure, with an exception raised.
 */
static ArrayObject* convertStringArray(char** strings, size_t count)
{
    Thread* self = dvmThreadSelf();

    /*
     * Allocate an array to hold the String objects.
     */
    ClassObject* stringArrayClass =
        dvmFindArrayClass("[Ljava/lang/String;", NULL);
    if (stringArrayClass == NULL) {
        /* shouldn't happen */
        LOGE("Unable to find [Ljava/lang/String;\n");
        dvmAbort();
    }

    ArrayObject* stringArray =
        dvmAllocArrayByClass(stringArrayClass, count, ALLOC_DEFAULT);
    if (stringArray == NULL) {
        /* probably OOM */
        LOGD("Failed allocating array of %d strings\n", count);
        assert(dvmCheckException(self));
        return NULL;
    }

    /*
     * Create the individual String objects and add them to the array.
     */
    size_t i;
    for (i = 0; i < count; i++) {
        Object *str =
            (Object *)dvmCreateStringFromCstr(strings[i]);
        if (str == NULL) {
            /* probably OOM; drop out now */
            assert(dvmCheckException(self));
            dvmReleaseTrackedAlloc((Object*)stringArray, self);
            return NULL;
        }
        dvmSetObjectArrayElement(stringArray, i, str);
        /* stored in tracked array, okay to release */
        dvmReleaseTrackedAlloc(str, self);
    }

    dvmReleaseTrackedAlloc((Object*)stringArray, self);
    return stringArray;
}
Exemple #2
0
static bool initClassReference(ClassObject** pClass, const char* name) {
    ClassObject* result;

    assert(*pClass == NULL);

    if (name[0] == '[') {
        result = dvmFindArrayClass(name, NULL);
    } else {
        result = dvmFindSystemClassNoInit(name);
    }

    if (result == NULL) {
        ALOGE("Could not find essential class %s", name);
        return false;
    }

    *pClass = result;
    return true;
}
/*
 * Find the named class object.  We have to trim "*pSignature" down to just
 * the first token, do the lookup, and then restore anything important
 * that we've stomped on.
 *
 * "pSig" will be advanced to the start of the next token.
 */
static ClassObject* convertSignaturePartToClass(char** pSignature,
    const ClassObject* defClass)
{
    ClassObject* clazz = NULL;
    char* signature = *pSignature;

    if (*signature == '[') {
        /* looks like "[[[Landroid/debug/Stuff;"; we want the whole thing */
        char savedChar;

        while (*++signature == '[')
            ;
        if (*signature == 'L') {
            while (*++signature != ';')
                ;
        }

        /* advance past ';', and stomp on whatever comes next */
        savedChar = *++signature;
        *signature = '\0';
        clazz = dvmFindArrayClass(*pSignature, defClass->classLoader);
        *signature = savedChar;
    } else if (*signature == 'L') {
        /* looks like 'Landroid/debug/Stuff;"; we want the whole thing */
        char savedChar;
        while (*++signature != ';')
            ;
        savedChar = *++signature;
        *signature = '\0';
        clazz = dvmFindClassNoInit(*pSignature, defClass->classLoader);
        *signature = savedChar;
    } else {
        clazz = dvmFindPrimitiveClass(*signature++);
    }

    if (clazz == NULL) {
        ALOGW("Unable to match class for part: '%s'", *pSignature);
    }
    *pSignature = signature;
    return clazz;
}
Exemple #4
0
static jboolean de_robv_android_xposed_XposedBridge_initNative(JNIEnv* env,
		jclass clazz) {
	if (!keepLoadingXposed) {
		ALOGE("Not initializing Xposed because of previous errors\n");
		return false;
	}

	::Thread* self = dvmThreadSelf();

	xposedHandleHookedMethod =
			(Method*) env->GetStaticMethodID(xposedClass, "handleHookedMethod",
					"(Ljava/lang/reflect/Member;ILjava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
	if (xposedHandleHookedMethod == NULL) {
		ALOGE(
				"ERROR: could not find method %s.handleHookedMethod(Member, int, Object, Object, Object[])\n",
				XPOSED_CLASS);
		dvmLogExceptionStackTrace();
		env->ExceptionClear();
		keepLoadingXposed = false;
		return false;
	}

	Method* xposedInvokeOriginalMethodNative =
			(Method*) env->GetStaticMethodID(xposedClass,
					"invokeOriginalMethodNative",
					"(Ljava/lang/reflect/Member;I[Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
	if (xposedInvokeOriginalMethodNative == NULL) {
		ALOGE(
				"ERROR: could not find method %s.invokeOriginalMethodNative(Member, int, Class[], Class, Object, Object[])\n",
				XPOSED_CLASS);
		dvmLogExceptionStackTrace();
		env->ExceptionClear();
		keepLoadingXposed = false;
		return false;
	}
	dvmSetNativeFunc(xposedInvokeOriginalMethodNative,
			de_robv_android_xposed_XposedBridge_invokeOriginalMethodNative,
			NULL);

	objectArrayClass = dvmFindArrayClass("[Ljava/lang/Object;", NULL);
	if (objectArrayClass == NULL) {
		ALOGE("Error while loading Object[] class");
		dvmLogExceptionStackTrace();
		env->ExceptionClear();
		keepLoadingXposed = false;
		return false;
	}

	//It's not found here?
	xresourcesClass = env->FindClass(XRESOURCES_CLASS);
	xresourcesClass = reinterpret_cast<jclass>(env->NewGlobalRef(
			xresourcesClass));
	if (xresourcesClass == NULL) {
		ALOGE("Error while loading XResources class '%s':\n", XRESOURCES_CLASS);
		dvmLogExceptionStackTrace();
		env->ExceptionClear();
		keepLoadingXposed = false;
		return false;
	}
	if (register_android_content_res_XResources(env) != JNI_OK) {
		ALOGE("Could not register natives for '%s'\n", XRESOURCES_CLASS);
		return false;
	}

	xresourcesTranslateResId =
			env->GetStaticMethodID(xresourcesClass, "translateResId",
					"(ILandroid/content/res/XResources;Landroid/content/res/Resources;)I");
	if (xresourcesTranslateResId == NULL) {
		ALOGE(
				"ERROR: could not find method %s.translateResId(int, Resources, Resources)\n",
				XRESOURCES_CLASS);
		dvmLogExceptionStackTrace();
		env->ExceptionClear();
		keepLoadingXposed = false;
		return false;
	}

	xresourcesTranslateAttrId = env->GetStaticMethodID(xresourcesClass,
			"translateAttrId",
			"(Ljava/lang/String;Landroid/content/res/XResources;)I");
	if (xresourcesTranslateAttrId == NULL) {
		ALOGE(
				"ERROR: could not find method %s.findAttrId(String, Resources, Resources)\n",
				XRESOURCES_CLASS);
		dvmLogExceptionStackTrace();
		env->ExceptionClear();
		keepLoadingXposed = false;
		return false;
	}

	return true;
}
/*
 * Cache pointers to some of the exception classes we use locally.
 *
 * Note this is NOT called during dexopt optimization.  Some of the fields
 * are initialized by the verifier (dvmVerifyCodeFlow).
 */
bool dvmExceptionStartup(void)
{
    gDvm.classJavaLangThrowable =
        dvmFindSystemClassNoInit("Ljava/lang/Throwable;");
    gDvm.classJavaLangRuntimeException =
        dvmFindSystemClassNoInit("Ljava/lang/RuntimeException;");
    gDvm.classJavaLangStackOverflowError =
        dvmFindSystemClassNoInit("Ljava/lang/StackOverflowError;");
    gDvm.classJavaLangError =
        dvmFindSystemClassNoInit("Ljava/lang/Error;");
    gDvm.classJavaLangStackTraceElement =
        dvmFindSystemClassNoInit("Ljava/lang/StackTraceElement;");
    gDvm.classJavaLangStackTraceElementArray =
        dvmFindArrayClass("[Ljava/lang/StackTraceElement;", NULL);
    if (gDvm.classJavaLangThrowable == NULL ||
        gDvm.classJavaLangStackTraceElement == NULL ||
        gDvm.classJavaLangStackTraceElementArray == NULL)
    {
        LOGE("Could not find one or more essential exception classes\n");
        return false;
    }

    /*
     * Find the constructor.  Note that, unlike other saved method lookups,
     * we're using a Method* instead of a vtable offset.  This is because
     * constructors don't have vtable offsets.  (Also, since we're creating
     * the object in question, it's impossible for anyone to sub-class it.)
     */
    Method* meth;
    meth = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangStackTraceElement,
        "<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V");
    if (meth == NULL) {
        LOGE("Unable to find constructor for StackTraceElement\n");
        return false;
    }
    gDvm.methJavaLangStackTraceElement_init = meth;

    /* grab an offset for the stackData field */
    gDvm.offJavaLangThrowable_stackState =
        dvmFindFieldOffset(gDvm.classJavaLangThrowable,
            "stackState", "Ljava/lang/Object;");
    if (gDvm.offJavaLangThrowable_stackState < 0) {
        LOGE("Unable to find Throwable.stackState\n");
        return false;
    }

    /* and one for the message field, in case we want to show it */
    gDvm.offJavaLangThrowable_message =
        dvmFindFieldOffset(gDvm.classJavaLangThrowable,
            "detailMessage", "Ljava/lang/String;");
    if (gDvm.offJavaLangThrowable_message < 0) {
        LOGE("Unable to find Throwable.detailMessage\n");
        return false;
    }

    /* and one for the cause field, just 'cause */
    gDvm.offJavaLangThrowable_cause =
        dvmFindFieldOffset(gDvm.classJavaLangThrowable,
            "cause", "Ljava/lang/Throwable;");
    if (gDvm.offJavaLangThrowable_cause < 0) {
        LOGE("Unable to find Throwable.cause\n");
        return false;
    }

    return true;
}