diff --git a/app/src/main/java/us/beckmeyer/vvmsmsreceiver/SmsReceiver.kt b/app/src/main/java/us/beckmeyer/vvmsmsreceiver/SmsReceiver.kt index 496fb9f..35b9da0 100644 --- a/app/src/main/java/us/beckmeyer/vvmsmsreceiver/SmsReceiver.kt +++ b/app/src/main/java/us/beckmeyer/vvmsmsreceiver/SmsReceiver.kt @@ -3,20 +3,24 @@ package us.beckmeyer.vvmsmsreceiver import android.content.BroadcastReceiver import android.content.Context import android.content.Intent +import android.net.Uri import android.os.Bundle import android.provider.Telephony import android.telephony.SmsMessage import android.util.Log +import kotlin.io.encoding.Base64 +import kotlin.io.encoding.ExperimentalEncodingApi class SmsReceiver : BroadcastReceiver() { private val TAG = "SmsReceiver" - @OptIn(ExperimentalStdlibApi::class) + @OptIn(ExperimentalStdlibApi::class, ExperimentalEncodingApi::class) override fun onReceive(context: Context, intent: Intent) { if (intent.action == Telephony.Sms.Intents.SMS_RECEIVED_ACTION || - intent.action == Telephony.Sms.Intents.DATA_SMS_RECEIVED_ACTION) { + intent.action == Telephony.Sms.Intents.DATA_SMS_RECEIVED_ACTION + ) { val bundle: Bundle? = intent.extras bundle?.let { val pdus = bundle.get("pdus") as Array @@ -26,6 +30,13 @@ class SmsReceiver : BroadcastReceiver() { smsMessage?.let { if (intent.action == Telephony.Sms.Intents.DATA_SMS_RECEIVED_ACTION) { Log.d(TAG, "Data SMS received on port 5499") + val bodyUri = Uri.parse("advvm://" + smsMessage.messageBody) + bodyUri.getQueryParameter("p")?.let { p -> + val ciphertext = Base64.decode(p).toString(Charsets.US_ASCII) + Log.d(TAG, "ciphertext = $ciphertext") + val password = decode(ciphertext, "8107308422") + Log.d(TAG, "password = $password") + } } val messageBody = smsMessage.messageBody Log.d(TAG, "Message body: $messageBody") @@ -36,4 +47,29 @@ class SmsReceiver : BroadcastReceiver() { } } } + + private fun stripPrefix(char: Char): Int { + return char.code and 0x0F + } + + private fun getStripped(text: String): ByteArray { + val stripped = text.map { stripPrefix(it).toByte() } + return stripped.toByteArray() + } + + fun decode(cipher: String, phoneNumber: String): String { + val cipherStripped = getStripped(cipher) + val phoneNumberStripped = getStripped(phoneNumber) + val secret = byteArrayOf(12, 5, 3, 11, 9, 4, 5, 3, 8, 14) + + val text = cipherStripped.zip(phoneNumberStripped) + .zip(secret.asIterable()) { (c, p), s -> (c.toInt() xor p.toInt() xor s.toInt()).toByte() } + .toMutableList() + + if (cipherStripped.size > 10) { + text.addAll(cipherStripped.slice(10 until cipherStripped.size).toMutableList()) + } + + return text.toByteArray().map { (it + 0x30).toChar() }.joinToString("") + } } \ No newline at end of file