| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- package com.example.modifier.repo
- import android.Manifest
- import android.annotation.SuppressLint
- import android.content.Context
- import android.telephony.SubscriptionManager
- import android.util.Log
- import androidx.core.content.ContextCompat
- import androidx.datastore.preferences.core.booleanPreferencesKey
- import androidx.datastore.preferences.core.edit
- import androidx.datastore.preferences.core.stringPreferencesKey
- import androidx.datastore.preferences.preferencesDataStore
- import com.example.modifier.BuildConfig
- import com.example.modifier.Utils
- import com.example.modifier.constants.PACKAGE_GMS
- import com.example.modifier.constants.PACKAGE_MESSAGING
- import com.example.modifier.model.SpoofedSimInfo
- import com.example.modifier.serializer.Json
- import com.example.modifier.utils.genICCID
- import com.example.modifier.utils.genIMEI
- import com.example.modifier.utils.genIMSI
- import com.example.modifier.utils.hasPermission
- import com.example.modifier.utils.isOldVersion
- import com.example.modifier.utils.resumePackage
- import com.example.modifier.utils.shellRun
- import com.example.modifier.utils.suspendPackage
- import com.google.gson.Gson
- import kotlinx.coroutines.CoroutineScope
- import kotlinx.coroutines.flow.map
- import kotlinx.coroutines.flow.stateIn
- import kotlinx.serialization.decodeFromString
- import org.apache.commons.io.FileUtils
- import java.io.File
- import kotlin.coroutines.coroutineContext
- val Context.simInfoDataStore by preferencesDataStore(name = "${BuildConfig.APPLICATION_ID}.simInfo")
- class SpoofedSimInfoRepository(private val context: Context) {
- private object PreferencesKeys {
- val NUMBER = stringPreferencesKey("number")
- val MCC = stringPreferencesKey("mcc")
- val MNC = stringPreferencesKey("mnc")
- val ICCID = stringPreferencesKey("iccid")
- val IMSI = stringPreferencesKey("imsi")
- val IMEI = stringPreferencesKey("imei")
- val COUNTRY = stringPreferencesKey("country")
- val AREA_CODE = stringPreferencesKey("area_code")
- val AVAILABLE = booleanPreferencesKey("available")
- val CARRIER_ID = stringPreferencesKey("carrier_id")
- val CARRIER_NAME = stringPreferencesKey("carrier_name")
- }
- val simInfoFlow = context.simInfoDataStore.data.map {
- val file = File(ContextCompat.getDataDir(context), "config.json")
- val old = file.exists().let {
- if (it) {
- try {
- return@let Json.decodeFromString<SpoofedSimInfo>(
- FileUtils.readFileToString(
- file,
- "UTF-8"
- )
- )
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }
- null
- }
- val number = it[PreferencesKeys.NUMBER] ?: old?.number ?: ""
- val mcc = it[PreferencesKeys.MCC] ?: old?.mcc ?: ""
- val mnc = it[PreferencesKeys.MNC] ?: old?.mnc ?: ""
- val iccid = it[PreferencesKeys.ICCID] ?: old?.iccid ?: ""
- val imsi = it[PreferencesKeys.IMSI] ?: old?.imsi ?: ""
- val imei = it[PreferencesKeys.IMEI] ?: old?.imei ?: ""
- val country = it[PreferencesKeys.COUNTRY] ?: old?.country ?: ""
- val areaCode = it[PreferencesKeys.AREA_CODE] ?: old?.areaCode ?: ""
- val available = it[PreferencesKeys.AVAILABLE] ?: old?.available ?: false
- val carrierId = it[PreferencesKeys.CARRIER_ID] ?: old?.carrierId ?: ""
- val carrierName = it[PreferencesKeys.CARRIER_NAME] ?: old?.carrierName ?: ""
- SpoofedSimInfo(
- number = number,
- mcc = mcc,
- mnc = mnc,
- iccid = iccid,
- imsi = imsi,
- imei = imei,
- country = country,
- areaCode = areaCode,
- available = available,
- carrierId = carrierId,
- carrierName = carrierName
- )
- }
- suspend fun stateFlow() = simInfoFlow.stateIn(CoroutineScope(coroutineContext))
- suspend fun value() {
- }
- @SuppressLint("MissingPermission")
- suspend fun updateSpoofedSimInfo(spoofedSimInfo: SpoofedSimInfo, suspend: Boolean? = true) {
- context.simInfoDataStore.edit {
- it[PreferencesKeys.NUMBER] = spoofedSimInfo.number
- it[PreferencesKeys.MCC] = spoofedSimInfo.mcc
- it[PreferencesKeys.MNC] = spoofedSimInfo.mnc
- it[PreferencesKeys.ICCID] = spoofedSimInfo.iccid
- it[PreferencesKeys.IMSI] = spoofedSimInfo.imsi
- it[PreferencesKeys.IMEI] = spoofedSimInfo.imei
- it[PreferencesKeys.COUNTRY] = spoofedSimInfo.country
- it[PreferencesKeys.AREA_CODE] = spoofedSimInfo.areaCode
- it[PreferencesKeys.AVAILABLE] = spoofedSimInfo.available
- it[PreferencesKeys.CARRIER_ID] = spoofedSimInfo.carrierId
- it[PreferencesKeys.CARRIER_NAME] = spoofedSimInfo.carrierName
- }
- try {
- if (suspend == true) {
- suspendPackage(PACKAGE_GMS, PACKAGE_MESSAGING)
- }
- shellRun(
- "setprop persist.spoof.number ${spoofedSimInfo.number}",
- "setprop persist.spoof.mcc ${spoofedSimInfo.mcc}",
- "setprop persist.spoof.mnc ${spoofedSimInfo.mnc}",
- "setprop persist.spoof.iccid ${spoofedSimInfo.iccid}",
- "setprop persist.spoof.imsi ${spoofedSimInfo.imsi}",
- "setprop persist.spoof.imei ${spoofedSimInfo.imei}",
- "setprop persist.spoof.country ${spoofedSimInfo.country}",
- "setprop persist.spoof.carrier.id ${
- spoofedSimInfo.carrierId.replace(
- "^\\W*\$".toRegex(),
- "''"
- )
- }",
- "setprop persist.spoof.carrier.name ${
- spoofedSimInfo.carrierName.replace(
- "^\\W*\$".toRegex(),
- "''"
- )
- }",
- )
- val context = Utils.getContext()
- val subscriptionManager: SubscriptionManager =
- context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
- if (hasPermission(Manifest.permission.READ_PHONE_STATE)) {
- val simCount = subscriptionManager.activeSubscriptionInfoCountMax
- for (i in 0 until simCount) {
- val info = subscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(i)
- if (info != null) {
- val mcc = info.mccString
- val mnc = info.mncString
- Log.i(com.example.modifier.TAG, "mccmnc spoofed: $mcc$mnc")
- }
- }
- }
- if (suspend == true) {
- resumePackage(PACKAGE_GMS, PACKAGE_MESSAGING)
- }
- } catch (e: Exception) {
- e.printStackTrace()
- }
- }
- suspend fun mock() {
- if (isOldVersion(context)) {
- val content = Utils.getContext().assets.open("us_numbers.txt").bufferedReader().use {
- it.readText()
- }
- // get random number
- content.split("\n")
- .filter { it.isNotBlank() }
- .shuffled()
- .firstOrNull()
- ?.let {
- updateSpoofedSimInfo(
- SpoofedSimInfo(
- number = it,
- mcc = "310",
- mnc = "150",
- iccid = genICCID("310", "1"),
- imsi = genIMSI("310150"),
- imei = genIMEI(),
- country = "us",
- areaCode = "1",
- available = false,
- carrierId = "1779",
- carrierName = "Cricket Wireless"
- )
- )
- }
- } else {
- val content = Utils.getContext().assets.open("us_numbers.txt").bufferedReader().use {
- it.readText()
- }
- // get random number
- content.split("\n")
- .filter { it.isNotBlank() }
- .shuffled()
- .firstOrNull()
- ?.let {
- updateSpoofedSimInfo(
- SpoofedSimInfo(
- number = it,
- mcc = "310",
- mnc = "240",
- iccid = genICCID("310", "1"),
- imsi = genIMSI("310240"),
- imei = genIMEI(),
- country = "us",
- areaCode = "1",
- available = false,
- carrierId = "1",
- carrierName = "T-Mobile"
- )
- )
- }
- }
- }
- }
|