bool xposedOnVmCreated(JNIEnv* env, const char* className) { if (!keepLoadingXposed) return false; startClassName = className; // disable some access checks char asmReturnTrue[] = { 0x01, 0x20, 0x70, 0x47 }; replaceAsm((void*) &dvmCheckClassAccess, asmReturnTrue, sizeof(asmReturnTrue)); replaceAsm((void*) &dvmCheckFieldAccess, asmReturnTrue, sizeof(asmReturnTrue)); replaceAsm((void*) &dvmInSamePackage, asmReturnTrue, sizeof(asmReturnTrue)); if (access(XPOSED_DIR "do_not_hook_dvmCheckMethodAccess", F_OK) != 0) replaceAsm((void*) &dvmCheckMethodAccess, asmReturnTrue, sizeof(asmReturnTrue)); xposedClass = env->FindClass(XPOSED_CLASS); xposedClass = reinterpret_cast<jclass>(env->NewGlobalRef(xposedClass)); if (xposedClass == NULL) { ALOGE("Error while loading Xposed class '%s':\n", XPOSED_CLASS); dvmLogExceptionStackTrace(); env->ExceptionClear(); return false; } ALOGI("Found Xposed class '%s', now initializing\n", XPOSED_CLASS); register_de_robv_android_xposed_XposedBridge(env); register_android_content_res_XResources(env); return true; }
static void patchReturnTrue(void* function) { #ifdef __arm__ char asmReturnTrueThumb[] = { 0x01, 0x20, 0x70, 0x47 }; char asmReturnTrueArm[] = { 0x01, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1 }; if ((int)function & 1) replaceAsm(function, asmReturnTrueThumb, sizeof(asmReturnTrueThumb)); else replaceAsm(function, asmReturnTrueArm, sizeof(asmReturnTrueArm)); #else char asmReturnTrueX86[] = { 0x31, 0xC0, 0x40, 0xC3 }; replaceAsm(function, asmReturnTrueX86, sizeof(asmReturnTrueX86)); #endif }
static void patchReturnTrue(uintptr_t function) { #ifdef __arm__ unsigned const char asmReturnTrueThumb[] = {0x01, 0x20, 0x70, 0x47}; unsigned const char asmReturnTrueArm[] = {0x01, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1}; if (function & 1) replaceAsm(function, asmReturnTrueThumb, sizeof(asmReturnTrueThumb)); else replaceAsm(function, asmReturnTrueArm, sizeof(asmReturnTrueArm)); #else unsigned const char asmReturnTrueX86[] = { 0x31, 0xC0, 0x40, 0xC3 }; replaceAsm(function, asmReturnTrueX86, sizeof(asmReturnTrueX86)); #endif }
int main(int argc, const char* const argv[]) { int result; result = asmReplaceTest(); if (result != 123) { printf("ERROR: Result of first call is %d instead of 123\n", result); return 1; } #ifdef __arm__ unsigned const char asmReturn42[] = { 42, 0x20, 0x70, 0x47 }; #else unsigned const char asmReturn42[] = { 0xB8, 42, 0x00, 0x00, 0x00, 0xC3 }; #endif replaceAsm((void*) asmReplaceTest, asmReturn42, sizeof(asmReturn42)); result = asmReplaceTest(); if (result != 42) { printf("ERROR: Result of second call is %d instead of 42\n", result); return 1; } printf("OK\n"); return 0; }
int main(int argc, const char* const argv[]) { int result; result = asmReplaceTest(); if (result != 123) { printf("ERROR: Result of first call is %d instead of 123\n", result); return 1; } char asmReturn42[] = { 42, 0x20, 0x70, 0x47 }; replaceAsm((void*) asmReplaceTest, asmReturn42, sizeof(asmReturn42)); result = asmReplaceTest(); if (result != 42) { printf("ERROR: Result of second call is %d instead of 42\n", result); return 1; } printf("OK\n"); return 0; }