Compare commits

..

No commits in common. 'bb113c72f39fa6f46efc221551e77c6e92605e8c' and '7089b8eb5d36ee89c56fb0bf478a53f9295c0676' have entirely different histories.

@ -9,10 +9,10 @@ android {
defaultConfig { defaultConfig {
applicationId "moe.tqlwsl.aicemu" applicationId "moe.tqlwsl.aicemu"
minSdk 28 minSdk 24
targetSdk 33 targetSdk 33
versionCode 5 versionCode 4
versionName "1.0-Beta4" versionName "1.0-Beta3"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }

@ -8,8 +8,8 @@
<application <application
android:name=".GlobalVar" android:name=".GlobalVar"
android:allowBackup="true" android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:extractNativeLibs="true" android:extractNativeLibs="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"
android:icon="@drawable/aic_fill" android:icon="@drawable/aic_fill"
android:label="@string/app_name" android:label="@string/app_name"
@ -17,52 +17,39 @@
android:theme="@style/Theme.AICEmu" android:theme="@style/Theme.AICEmu"
tools:targetApi="31" > tools:targetApi="31" >
<meta-data
android:name="xposedmodule"
android:value="true" />
<meta-data
android:name="xposedminversion"
android:value="30" />
<meta-data
android:name="xposeddescription"
android:value="Emulate Every AIC Card" />
<meta-data
android:name="xposedscope"
android:resource="@array/xposed_scope" />
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
android:theme="@style/Theme.AICEmu" > android:theme="@style/Theme.AICEmu" >
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
android:name=".ReadCard" android:name=".ReadCard"
android:theme="@style/CardActivityTheme" /> android:theme="@style/CardActivityTheme" />
<activity <activity
android:name=".SettingActivity" android:name=".SettingActivity"
android:exported="false" android:exported="false"
android:label="@string/title_activity_setting" android:label="@string/title_activity_setting"
android:theme="@style/Theme.AICEmuActionBar" /> android:theme="@style/Theme.AICEmuActionBar" />
<meta-data
android:name="xposedscope"
android:resource="@array/xposed_scope" />
<meta-data
android:name="xposedmodule"
android:value="true" />
<meta-data
android:name="xposedminversion"
android:value="93" />
<meta-data
android:name="xposeddescription"
android:value="Emulate Every AIC Card" />
<meta-data
android:name="xposedsharedprefs"
android:value="true" />
<service
android:name=".ApduService"
android:exported="true"
android:permission="android.permission.BIND_NFC_SERVICE">
<intent-filter>
<action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE" />
</intent-filter>
<meta-data
android:name="android.nfc.cardemulation.host_apdu_service"
android:resource="@xml/apdu_service" />
</service>
<service <service
android:name=".EmuCard" android:name=".EmuCard"
android:exported="true" android:exported="true"
@ -74,5 +61,6 @@
android:name="android.nfc.cardemulation.host_nfcf_service" android:name="android.nfc.cardemulation.host_nfcf_service"
android:resource="@xml/host_nfcf_service" /> android:resource="@xml/host_nfcf_service" />
</service> </service>
</application> </application>
</manifest> </manifest>

@ -1,16 +0,0 @@
package moe.tqlwsl.aicemu
import android.nfc.cardemulation.HostApduService
import android.os.Bundle
class ApduService : HostApduService() {
override fun onDeactivated(reason: Int) {
// placeholder
}
override fun processCommandApdu(commandApdu: ByteArray, extras: Bundle): ByteArray {
// placeholder
return ByteArray(0)
}
}

@ -4,7 +4,6 @@ import android.app.AlertDialog
import android.app.PendingIntent import android.app.PendingIntent
import android.content.* import android.content.*
import android.nfc.NfcAdapter import android.nfc.NfcAdapter
import android.nfc.cardemulation.CardEmulation
import android.nfc.cardemulation.NfcFCardEmulation import android.nfc.cardemulation.NfcFCardEmulation
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
@ -13,14 +12,16 @@ import android.widget.*
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.cardview.widget.CardView import androidx.cardview.widget.CardView
import androidx.core.content.edit
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.JsonSyntaxException import com.google.gson.JsonSyntaxException
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import moe.tqlwsl.aicemu.databinding.ActivityMainBinding
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import moe.tqlwsl.aicemu.databinding.ActivityMainBinding
internal data class Card(val name: String, val idm: String) internal data class Card(val name: String, val idm: String)
@ -82,18 +83,6 @@ class MainActivity : AppCompatActivity() {
return return
} }
// set default payment app
var cardEmulation = CardEmulation.getInstance(nfcAdapter)
val componentName = ComponentName(applicationContext, ApduService::class.java)
val isDefault =
cardEmulation.isDefaultServiceForCategory(componentName, CardEmulation.CATEGORY_PAYMENT)
if (!isDefault) {
val intent = Intent(CardEmulation.ACTION_CHANGE_DEFAULT)
intent.putExtra(CardEmulation.EXTRA_CATEGORY, CardEmulation.CATEGORY_PAYMENT)
intent.putExtra(CardEmulation.EXTRA_SERVICE_COMPONENT, componentName)
startActivity(intent)
}
// add pendingintent in order not to read tag at home // add pendingintent in order not to read tag at home
val intent = Intent(this, javaClass).apply { val intent = Intent(this, javaClass).apply {
addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
@ -109,7 +98,7 @@ class MainActivity : AppCompatActivity() {
) )
// setting prefs // setting prefs
prefs = applicationContext.getSharedPreferences("AICEmu", Context.MODE_WORLD_READABLE) prefs = applicationContext.getSharedPreferences("AICEmu", MODE_PRIVATE)
currentCardId = prefs.getInt("currentCardId", -1) currentCardId = prefs.getInt("currentCardId", -1)
compatibleID = prefs.getBoolean("compatibleID", false) compatibleID = prefs.getBoolean("compatibleID", false)
val compatibleButton: Button = findViewById(R.id.button_compatible) val compatibleButton: Button = findViewById(R.id.button_compatible)
@ -187,7 +176,7 @@ class MainActivity : AppCompatActivity() {
true true
} }
R.id.toolbar_menu_settings -> { R.id.toolbar_menu_settings -> {
// Toast.makeText(applicationContext, "还没做完()\nUnder constuction...", Toast.LENGTH_LONG).show() Toast.makeText(applicationContext, "还没做完()\nUnder constuction...", Toast.LENGTH_LONG).show()
val settingIntent = Intent(this, SettingActivity::class.java) val settingIntent = Intent(this, SettingActivity::class.java)
startActivity(settingIntent) startActivity(settingIntent)
true true

@ -1,9 +1,6 @@
package moe.tqlwsl.aicemu package moe.tqlwsl.aicemu
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context
import android.content.SharedPreferences
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.Color import android.graphics.Color
import android.os.Build import android.os.Build
@ -11,11 +8,9 @@ import android.os.Bundle
import android.util.Log import android.util.Log
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SwitchCompat
import org.lsposed.hiddenapibypass.HiddenApiBypass import org.lsposed.hiddenapibypass.HiddenApiBypass
import java.lang.reflect.Method import java.lang.reflect.Method
class SettingActivity : AppCompatActivity() { class SettingActivity : AppCompatActivity() {
private var isHCEFSupported: Boolean = false private var isHCEFSupported: Boolean = false
private var isHCEFUnlocked: Boolean = false private var isHCEFUnlocked: Boolean = false
@ -39,8 +34,8 @@ class SettingActivity : AppCompatActivity() {
textHCEF.setTextColor(Color.RED) textHCEF.setTextColor(Color.RED)
} }
val textUnlocker = findViewById<TextView>(R.id.unlocker_work_text)
if (isHCEFSupported) { if (isHCEFSupported) {
val textUnlocker = findViewById<TextView>(R.id.unlocker_work_text)
try { try {
val globalVar = this.applicationContext as GlobalVar val globalVar = this.applicationContext as GlobalVar
isHCEFUnlocked = globalVar.isHCEFUnlocked isHCEFUnlocked = globalVar.isHCEFUnlocked
@ -57,30 +52,21 @@ class SettingActivity : AppCompatActivity() {
textUnlocker.setText(R.string.Unlocker_work_error) textUnlocker.setText(R.string.Unlocker_work_error)
} }
// val textPmmtool = findViewById<TextView>(R.id.pmmtool_work_text) val textPmmtool = findViewById<TextView>(R.id.pmmtool_work_text)
// pmmtoolStatus = getProperty("tmp.AICEmu.pmmtool"); pmmtoolStatus = getProperty("tmp.AICEmu.pmmtool");
// if (pmmtoolStatus == "") { if (pmmtoolStatus == "") {
// textPmmtool.setText(R.string.Pmmtool_work_false) textPmmtool.setText(R.string.Pmmtool_work_false)
// textPmmtool.setTextColor(Color.RED) textPmmtool.setTextColor(Color.RED)
// } }
// else if (pmmtoolStatus == "0") { else if (pmmtoolStatus == "0") {
// textPmmtool.setText(R.string.Pmmtool_work_hook_failed) textPmmtool.setText(R.string.Pmmtool_work_hook_failed)
// textPmmtool.setTextColor(Color.RED) textPmmtool.setTextColor(Color.RED)
// }
// else if (pmmtoolStatus == "1") {
// textPmmtool.setText(R.string.Pmmtool_work_true)
// textPmmtool.setTextColor(Color.GREEN)
// }
val pmmtoolSwitch = findViewById<SwitchCompat>(R.id.pmmtool_switch)
pmmtoolSwitch.setOnCheckedChangeListener { _, isChecked ->
var prefs: SharedPreferences =
applicationContext.getSharedPreferences("AICEmu", Context.MODE_WORLD_READABLE)
val editor = prefs.edit()
editor.putBoolean("loadPmmtool", isChecked)
editor.apply()
Runtime.getRuntime().exec(arrayOf("su", "-c", "kill -9 $(su -c pidof com.android.nfc)"))
} }
else if (pmmtoolStatus == "1") {
textPmmtool.setText(R.string.Pmmtool_work_true)
textPmmtool.setTextColor(Color.GREEN)
}
} }
} }

@ -1,14 +1,9 @@
package moe.tqlwsl.aicemu; package moe.tqlwsl.aicemu;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.Application; import android.app.Application;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log; import android.util.Log;
import java.util.List; import java.util.List;
@ -16,7 +11,6 @@ import java.util.List;
import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement; import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XSharedPreferences;
import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage; import de.robv.android.xposed.callbacks.XC_LoadPackage;
@ -30,6 +24,7 @@ public class xp implements IXposedHookLoadPackage {
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
XposedBridge.log("In " + lpparam.packageName); XposedBridge.log("In " + lpparam.packageName);
if (lpparam.packageName.equals("com.android.nfc")) { if (lpparam.packageName.equals("com.android.nfc")) {
XposedHelpers.findAndHookMethod("android.nfc.cardemulation.NfcFCardEmulation", lpparam.classLoader, XposedHelpers.findAndHookMethod("android.nfc.cardemulation.NfcFCardEmulation", lpparam.classLoader,
@ -41,47 +36,45 @@ public class xp implements IXposedHookLoadPackage {
}); });
XposedHelpers.findAndHookMethod("com.android.nfc.NfcApplication", // XposedHelpers.findAndHookMethod("com.android.nfc.NfcApplication",
lpparam.classLoader, "onCreate", new XC_MethodHook() { // lpparam.classLoader, "onCreate", new XC_MethodHook() {
@Override // @Override
protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable { // protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
XposedBridge.log("Inside com.android.nfc.NfcApplication#onCreate"); // XposedBridge.log("Inside com.android.nfc.NfcApplication#onCreate");
super.beforeHookedMethod(param); // super.beforeHookedMethod(param);
Application application = (Application) param.thisObject; // Application application = (Application) param.thisObject;
mcontext = application.getApplicationContext(); // mcontext = application.getApplicationContext();
XposedBridge.log("Got context"); // XposedBridge.log("Got context");
} // }
}); // });
XposedHelpers.findAndHookMethod("android.nfc.cardemulation.NfcFCardEmulation", XposedHelpers.findAndHookMethod("android.nfc.cardemulation.NfcFCardEmulation",
lpparam.classLoader, "isValidSystemCode", String.class, new XC_MethodHook() { lpparam.classLoader, "isValidSystemCode", String.class, new XC_MethodHook() {
@Override @Override
protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable { protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
XposedBridge.log("Inside android.nfc.cardemulation.NfcFCardEmulation#isValidSystemCode"); XposedBridge.log("Inside android.nfc.cardemulation.NfcFCardEmulation#isValidSystemCode");
mclassloader = mcontext.getClassLoader(); // mclassloader = mcontext.getClassLoader();
XposedBridge.log("Got classloader"); // XposedBridge.log("Got classloader");
String path = getSoPath(); // String path = getSoPath();
XposedBridge.log("So path = " + path); // XposedBridge.log("So path = " + path);
try { // int version = android.os.Build.VERSION.SDK_INT;
Boolean needLoadPmmtool = false; // try {
XSharedPreferences pref = getPref(); // if (!path.equals("")) {
if (pref != null) { // XposedBridge.log("Start injecting libpmm.so");
needLoadPmmtool = pref.getBoolean("loadPmmtool", false); // if (version >= 28) {
} else { // XposedHelpers.callMethod(Runtime.getRuntime(), "nativeLoad", path, mclassloader);
XposedBridge.log("Cannot load pref for AICEmu properly"); // } else {
} // XposedHelpers.callMethod(Runtime.getRuntime(), "doLoad", path, mclassloader);
XposedBridge.log("loadPmmtool: " + needLoadPmmtool.toString()); // }
if (needLoadPmmtool && !path.equals("")) { // XposedBridge.log("Injected libpmm.so");
XposedBridge.log("Start injecting libpmm.so"); // }
XposedHelpers.callMethod(Runtime.getRuntime(), "nativeLoad", path, mclassloader); // } catch (Exception e) {
XposedBridge.log("Injected libpmm.so"); // XposedBridge.log(e);
} // e.printStackTrace();
} catch (Exception e) { // }
XposedBridge.log(e);
e.printStackTrace();
}
// Unlocker // Unlocker
param.setResult(true); param.setResult(true);
@ -91,10 +84,7 @@ public class xp implements IXposedHookLoadPackage {
XposedBridge.log("Hook succeeded!!!"); XposedBridge.log("Hook succeeded!!!");
} }
} }
private static XSharedPreferences getPref() {
XSharedPreferences pref = new XSharedPreferences("moe.tqlwsl.aicemu", "AICEmu");
return pref.getFile().canRead() ? pref : null;
}
private String getSoPath() { private String getSoPath() {
try { try {
String text = ""; String text = "";

@ -38,7 +38,7 @@ void *new_func(u_int8_t a1, u_int8_t *a2, int a3) {
for (int j = 0; j < 8; ++j) for (int j = 0; j < 8; ++j)
sprintf(pmm_str + j * 3, "%02x ", *(char *)(a2 + i + 2 + j)); sprintf(pmm_str + j * 3, "%02x ", *(char *)(a2 + i + 2 + j));
__android_log_print(6, "AICEmu-pmmtool", "[1] new PMm: %s", pmm_str); __android_log_print(6, "AICEmu-pmmtool", "[1] new PMm: %s", pmm_str);
//__system_property_set("tmp.AICEmu.pmmtool", "1"); __system_property_set("tmp.AICEmu.pmmtool", "1");
} }
} }
@ -60,7 +60,7 @@ void *new_func(u_int8_t a1, u_int8_t *a2, int a3) {
for (int j = 0; j < 8; ++j) for (int j = 0; j < 8; ++j)
sprintf(pmm_str + j * 3, "%02x ", *(char *)(a2 + i + j)); sprintf(pmm_str + j * 3, "%02x ", *(char *)(a2 + i + j));
__android_log_print(6, "AICEmu-pmmtool", "[2] new PMm: %s", pmm_str); __android_log_print(6, "AICEmu-pmmtool", "[2] new PMm: %s", pmm_str);
//__system_property_set("tmp.AICEmu.pmmtool", "1"); __system_property_set("tmp.AICEmu.pmmtool", "1");
} }
} }
//} //}
@ -72,7 +72,7 @@ void *new_func(u_int8_t a1, u_int8_t *a2, int a3) {
jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
__android_log_print(6, "AICEmu-pmmtool", "Inside JNI_OnLoad"); __android_log_print(6, "AICEmu-pmmtool", "Inside JNI_OnLoad");
//__system_property_set("tmp.AICEmu.pmmtool", "0"); __system_property_set("tmp.AICEmu.pmmtool", "0");
JNIEnv *env = nullptr; JNIEnv *env = nullptr;
if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) == JNI_OK) { if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) == JNI_OK) {
//void *func_addr = DobbySymbolResolver("libnfc-nci.so", "_Z23nfa_dm_check_set_confighPhb"); //void *func_addr = DobbySymbolResolver("libnfc-nci.so", "_Z23nfa_dm_check_set_confighPhb");

@ -37,41 +37,7 @@
android:text="@string/Pmmtool_work_false" android:text="@string/Pmmtool_work_false"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/unlocker_work_text" app:layout_constraintTop_toBottomOf="@+id/unlocker_work_text" />
android:visibility="gone"/>
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/pmmtool_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/pmmtool_work_text"
android:text="@string/pmmtool_switch"/>
<TextView
android:id="@+id/version_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:textSize="20sp"
android:text="@string/version_info"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@+id/author_text"/>
<TextView
android:id="@+id/author_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:textSize="16sp"
android:text="@string/author_info"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

@ -25,6 +25,4 @@
<string name="mode_compatible">兼容模式</string> <string name="mode_compatible">兼容模式</string>
<string name="mode_commmon">正常模式</string> <string name="mode_commmon">正常模式</string>
<string name="add_test_card">添加测试卡</string> <string name="add_test_card">添加测试卡</string>
<string name="apdu_service_desc">模拟AIC卡</string>
<string name="pmmtool_switch">用 Pmmtool 修改 PMm</string>
</resources> </resources>

@ -31,8 +31,4 @@
<string name="mode_commmon">Common</string> <string name="mode_commmon">Common</string>
<string name="mode_compatible">Compatible</string> <string name="mode_compatible">Compatible</string>
<string name="add_test_card">Add test card</string> <string name="add_test_card">Add test card</string>
<string name="apdu_service_desc">Emulate AIC Card</string>
<string name="pmmtool_switch">Change PMm with Pmmtool</string>
<string name="author_info" translatable="false">made by wlt233 with ❤\ntqlwsl.moe | 2709684396</string>
<string name="version_info" translatable="false">1.0-Beta4 (2023.09.01)</string>
</resources> </resources>

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
android:apduServiceBanner="@drawable/aic_fill"
android:description="@string/apdu_service_desc"
android:requireDeviceUnlock="false" >
<aid-group
android:category="payment"
android:description="@string/apdu_service_desc" >
<aid-filter android:name="F0010203040506" />
</aid-group>
</host-apdu-service>
Loading…
Cancel
Save