diff --git a/app/build.gradle b/app/build.gradle index 1ea5bc6..03fac8a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -46,4 +46,5 @@ dependencies { androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' implementation 'com.google.code.gson:gson:2.8.9' + compileOnly 'de.robv.android.xposed:api:82' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ba3a7ee..028419f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,7 +43,15 @@ android:resource="@xml/host_nfcf_service" /> - + + + diff --git a/app/src/main/assets/xposed_init b/app/src/main/assets/xposed_init new file mode 100644 index 0000000..058de28 --- /dev/null +++ b/app/src/main/assets/xposed_init @@ -0,0 +1 @@ +moe.tqlwsl.aicemu.xp \ No newline at end of file diff --git a/app/src/main/java/moe/tqlwsl/aicemu/xp.java b/app/src/main/java/moe/tqlwsl/aicemu/xp.java new file mode 100644 index 0000000..c938d58 --- /dev/null +++ b/app/src/main/java/moe/tqlwsl/aicemu/xp.java @@ -0,0 +1,79 @@ +package moe.tqlwsl.aicemu; + +import android.util.Log; + +import de.robv.android.xposed.IXposedHookLoadPackage; +import de.robv.android.xposed.XC_MethodHook; +import de.robv.android.xposed.XC_MethodReplacement; +import de.robv.android.xposed.XposedBridge; +import de.robv.android.xposed.XposedHelpers; +import de.robv.android.xposed.callbacks.XC_LoadPackage; + +public class xp implements IXposedHookLoadPackage { + private final String TAG = "AICEmu"; + + // from https://github.com/OLIET2357/HCEFUnlocker + @Override + public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { + XposedBridge.log("In " + lpparam.packageName); + if (lpparam.packageName.equals("com.android.nfc")) { + + XposedHelpers.findAndHookMethod("android.nfc.cardemulation.NfcFCardEmulation", lpparam.classLoader, + "isValidSystemCode", String.class, new XC_MethodReplacement() { + @Override + protected Object replaceHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable { + String systemCode = (String) param.args[0]; + if (systemCode == null) { + return false; + } + + if (systemCode.length() != 4) { + Log.e(TAG, "System Code " + systemCode + " is not a valid System Code."); + return false; + } + // check if the value is between "4000" and "4FFF" (excluding "4*FF") + if (!systemCode.startsWith("4") || systemCode.toUpperCase().endsWith("FF")) { + // Log.e(TAG, "System Code " + systemCode + " is not a valid System Code."); + // return false; + } + try { + Integer.parseInt(systemCode, 16); + } catch (NumberFormatException e) { + Log.e(TAG, "System Code " + systemCode + " is not a valid System Code."); + return false; + } + return true; + } + }); + + XposedHelpers.findAndHookMethod("android.nfc.cardemulation.NfcFCardEmulation", lpparam.classLoader, + "isValidNfcid2", String.class, new XC_MethodReplacement() { + @Override + protected Object replaceHookedMethod(MethodHookParam param) throws Throwable { + String nfcid2 = (String) param.args[0]; + if (nfcid2 == null) { + return false; + } + if (nfcid2.length() != 16) { + Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2."); + return false; + } + // check if the the value starts with "02FE" + if (!nfcid2.toUpperCase().startsWith("02FE")) { + // Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2."); + // return false; + } + try { + Long.parseLong(nfcid2, 16); + } catch (NumberFormatException e) { + Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2."); + return false; + } + return true; + } + }); + + XposedBridge.log("Hook successed!!!"); + } + } +} diff --git a/settings.gradle b/settings.gradle index 6abf0c1..e65c0f0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -10,6 +10,7 @@ dependencyResolutionManagement { repositories { google() mavenCentral() + maven { url "https://api.xposed.info/" } } } rootProject.name = "AICEmu"