xiongzhu 1 年間 前
コミット
49751ac0ff

+ 13 - 0
app/build.gradle

@@ -17,10 +17,23 @@ android {
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
     }
 
+    signingConfigs {
+        release {
+            storeFile file('../release.keystore')
+            storePassword '123456'
+            keyAlias 'key'
+            keyPassword '123456'
+        }
+    }
+
     buildTypes {
         release {
             minifyEnabled false
             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+            signingConfig signingConfigs.release
+        }
+        debug {
+            signingConfig signingConfigs.release
         }
     }
     compileOptions {

+ 19 - 18
app/src/main/java/com/example/uicceditor/ApduChannel.kt

@@ -21,7 +21,7 @@ fun String.stripF(): String {
 }
 
 
-class ApduChannel(private val telephonyManager: TelephonyManager, private val adm: String) {
+class ApduChannel(private val telephonyManager: TelephonyManager) {
 
     class ApduResponse(rawStr: String) {
 
@@ -40,7 +40,7 @@ class ApduChannel(private val telephonyManager: TelephonyManager, private val ad
 
     private val TAG = "ApduShell"
 
-    private var authorized: Boolean = false
+    public var authorized: Boolean = false
 
     fun execute(cmd: String): ApduResponse {
         val cla = cmd.substring(0, 2).toInt(16)
@@ -67,7 +67,7 @@ class ApduChannel(private val telephonyManager: TelephonyManager, private val ad
         return ascii.toByteArray().joinToString("") { "%02x".format(it) }
     }
 
-    fun authorize() {
+    fun authorize(adm: String) {
         if (adm.length != 8) {
             Log.e(TAG, "ADM must be 8 characters long")
             throw IllegalArgumentException("ADM must be 8 characters long")
@@ -77,17 +77,19 @@ class ApduChannel(private val telephonyManager: TelephonyManager, private val ad
         if (res.sw != "9000") {
             Log.e(TAG, "Authorization failed")
             throw SecurityException("Authorization failed")
+        } else {
+            authorized = true
         }
 
-        execute("00fbffff083239303833303131")
-        execute("00fb0000095b37b1da0cea13c501")
-        execute("00fb0001095b37b1da0cea13c500")
-        execute("00fb0002095b37b1da0cea13c501")
-        execute("00fb0003095b37b1da0cea13c500")
+//        execute("00fbffff083239303833303131")
+//        execute("00fb0000095b37b1da0cea13c501")
+//        execute("00fb0001095b37b1da0cea13c500")
+//        execute("00fb0002095b37b1da0cea13c501")
+//        execute("00fb0003095b37b1da0cea13c500")
     }
 
     init {
-        authorize()
+        //authorize()
     }
 
     fun readIccid(): String {
@@ -107,9 +109,13 @@ class ApduChannel(private val telephonyManager: TelephonyManager, private val ad
     }
 
     fun readImsi(): String {
-        var res = execute("00a4040410a0000000871002ff86ff0389ffffffff")
+        var res = execute("00a40004023f00")
+        if (res.sw != "9000") {
+            throw Exception("Failed to select MF")
+        }
+          res = execute("00a40004027f2000")
         if (res.sw != "9000") {
-            throw Exception("Failed to select AF.USIM")
+            throw Exception("Failed to select DF.GSM")
         }
         res = execute("00a40004026f07")
         if (res.sw != "9000") {
@@ -177,23 +183,18 @@ class ApduChannel(private val telephonyManager: TelephonyManager, private val ad
 
     fun writeImsi(imsi: String) {
 
-
-
         var res = execute("00a40004023f00")
         if (res.sw != "9000") {
             throw Exception("Failed to select MF")
         }
-        Thread.sleep(100)
-        res = execute("00a4040410a0000000871002ff86ff0389ffffffff")
+        res = execute("00a40004027f2000")
         if (res.sw != "9000") {
-            throw Exception("Failed to select ADF.USIM")
+            throw Exception("Failed to select DF.GSM")
         }
-        Thread.sleep(100)
         res = execute("00a40004026f07")
         if (res.sw != "9000") {
             throw Exception("Failed to select EF.IMSI")
         }
-        Thread.sleep(100)
         res = execute("00d6000009${encImsi(imsi)}")
 
         if (res.sw != "9000") {

+ 22 - 2
app/src/main/java/com/example/uicceditor/MainActivity.kt

@@ -33,8 +33,20 @@ class MainActivity : AppCompatActivity() {
             insets
         }
 
-        apduChannel =
-            ApduChannel(getSystemService(TELEPHONY_SERVICE) as TelephonyManager, "88888888")
+        val sharedPrefs = getSharedPreferences(applicationInfo.packageName, MODE_PRIVATE)
+        binding.etAdm.setText(sharedPrefs.getString("adm", ""))
+        apduChannel = ApduChannel(getSystemService(TELEPHONY_SERVICE) as TelephonyManager)
+
+        binding.btnAuth.setOnClickListener {
+            val admKey = binding.etAdm.text.toString()
+            if (Regex("^\\d{8}$").matches(admKey)) {
+                apduChannel.authorize(admKey)
+                Toast.makeText(this, "Authorized", Toast.LENGTH_SHORT).show()
+                sharedPrefs.edit().putString("adm", admKey).apply()
+            } else {
+                Toast.makeText(this, "Invalid ADM", Toast.LENGTH_SHORT).show()
+            }
+        }
 
         binding.btnReadIccid.setOnClickListener {
             val iccid = apduChannel.readIccid()
@@ -42,6 +54,10 @@ class MainActivity : AppCompatActivity() {
         }
 
         binding.btnWriteIccid.setOnClickListener {
+            if (!apduChannel.authorized) {
+                Toast.makeText(this, "Not authorized", Toast.LENGTH_SHORT).show()
+                return@setOnClickListener
+            }
             val iccid = binding.etIccid.text.toString()
             if (Regex("^[0-9]{20}$").matches(iccid)) {
                 apduChannel.writeIccid(iccid)
@@ -57,6 +73,10 @@ class MainActivity : AppCompatActivity() {
         }
 
         binding.btnWriteImsi.setOnClickListener {
+            if (!apduChannel.authorized) {
+                Toast.makeText(this, "Not authorized", Toast.LENGTH_SHORT).show()
+                return@setOnClickListener
+            }
             try {
                 val imsi = binding.etImsi.text.toString()
                 if (Regex("^[0-9]{15,18}$").matches(imsi)) {

+ 24 - 0
app/src/main/res/layout/activity_main.xml

@@ -18,12 +18,35 @@
         <com.google.android.material.textfield.TextInputLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:hint="ADM Key">
+
+            <com.google.android.material.textfield.TextInputEditText
+                android:id="@+id/et_adm"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:inputType="numberDecimal"
+                android:lines="1" />
+        </com.google.android.material.textfield.TextInputLayout>
+
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/btn_auth"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:layout_marginTop="8dp"
+            android:text="AUTH" />
+
+        <com.google.android.material.textfield.TextInputLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="8dp"
             android:hint="ICCID">
 
             <com.google.android.material.textfield.TextInputEditText
                 android:id="@+id/et_iccid"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
+                android:inputType="numberDecimal"
                 android:lines="1" />
         </com.google.android.material.textfield.TextInputLayout>
 
@@ -58,6 +81,7 @@
                 android:id="@+id/et_imsi"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
+                android:inputType="numberDecimal"
                 android:lines="1" />
         </com.google.android.material.textfield.TextInputLayout>