SpoofedSimInfoRepo.kt 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. package com.example.modifier.repo
  2. import android.Manifest
  3. import android.annotation.SuppressLint
  4. import android.content.Context
  5. import android.telephony.SubscriptionManager
  6. import android.telephony.TelephonyManager
  7. import android.util.Log
  8. import androidx.datastore.preferences.core.booleanPreferencesKey
  9. import androidx.datastore.preferences.core.edit
  10. import androidx.datastore.preferences.core.intPreferencesKey
  11. import androidx.datastore.preferences.core.stringPreferencesKey
  12. import androidx.datastore.preferences.preferencesDataStore
  13. import com.example.modifier.BuildConfig
  14. import com.example.modifier.baseTag
  15. import com.example.modifier.constants.PACKAGE_GMS
  16. import com.example.modifier.constants.PACKAGE_MESSAGING
  17. import com.example.modifier.constants.SIMView
  18. import com.example.modifier.extension.kill
  19. import com.example.modifier.model.SpoofedSimInfo
  20. import com.example.modifier.utils.ApduChannel
  21. import com.example.modifier.utils.ROOT_ACCESS
  22. import com.example.modifier.utils.SimEncoder
  23. import com.example.modifier.utils.genICCID
  24. import com.example.modifier.utils.genIMEI
  25. import com.example.modifier.utils.genIMSI
  26. import com.example.modifier.utils.getContext
  27. import com.example.modifier.utils.hasPermission
  28. import com.example.modifier.utils.isOldVersion
  29. import com.example.modifier.utils.resumePackage
  30. import com.example.modifier.utils.shellRun
  31. import com.example.modifier.utils.suspendPackage
  32. import kotlinx.coroutines.CoroutineScope
  33. import kotlinx.coroutines.Dispatchers
  34. import kotlinx.coroutines.delay
  35. import kotlinx.coroutines.flow.MutableStateFlow
  36. import kotlinx.coroutines.flow.map
  37. import kotlinx.coroutines.launch
  38. val Context.simInfoDataStore by preferencesDataStore(name = "${BuildConfig.APPLICATION_ID}.simInfo")
  39. class SpoofedSimInfoRepo private constructor(private val context: Context) {
  40. companion object {
  41. private const val TAG = "$baseTag/SpoofedSimInfoRepository"
  42. val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { SpoofedSimInfoRepo(getContext()) }
  43. }
  44. private object PreferencesKeys {
  45. val NUMBER_ID = intPreferencesKey("number_id")
  46. val NUMBER = stringPreferencesKey("number")
  47. val MCC = stringPreferencesKey("mcc")
  48. val MNC = stringPreferencesKey("mnc")
  49. val ICCID = stringPreferencesKey("iccid")
  50. val IMSI = stringPreferencesKey("imsi")
  51. val IMEI = stringPreferencesKey("imei")
  52. val COUNTRY = stringPreferencesKey("country")
  53. val AREA_CODE = stringPreferencesKey("area_code")
  54. val AVAILABLE = booleanPreferencesKey("available")
  55. val CARRIER_ID = stringPreferencesKey("carrier_id")
  56. val CARRIER_NAME = stringPreferencesKey("carrier_name")
  57. }
  58. private val simInfoFlow = context.simInfoDataStore.data.map {
  59. val numberId = it[PreferencesKeys.NUMBER_ID] ?: 0
  60. val number = it[PreferencesKeys.NUMBER] ?: ""
  61. val mcc = it[PreferencesKeys.MCC] ?: ""
  62. val mnc = it[PreferencesKeys.MNC] ?: ""
  63. val iccid = it[PreferencesKeys.ICCID] ?: ""
  64. val imsi = it[PreferencesKeys.IMSI] ?: ""
  65. val imei = it[PreferencesKeys.IMEI] ?: ""
  66. val country = it[PreferencesKeys.COUNTRY] ?: ""
  67. val areaCode = it[PreferencesKeys.AREA_CODE] ?: ""
  68. val available = it[PreferencesKeys.AVAILABLE] ?: false
  69. val carrierId = it[PreferencesKeys.CARRIER_ID] ?: ""
  70. val carrierName = it[PreferencesKeys.CARRIER_NAME] ?: ""
  71. SpoofedSimInfo(
  72. numberId = numberId,
  73. number = number,
  74. mcc = mcc,
  75. mnc = mnc,
  76. iccid = iccid,
  77. imsi = imsi,
  78. imei = imei,
  79. country = country,
  80. areaCode = areaCode,
  81. available = available,
  82. carrierId = carrierId,
  83. carrierName = carrierName
  84. )
  85. }
  86. val spoofedSimInfo = MutableStateFlow(
  87. SpoofedSimInfo(
  88. numberId = 0,
  89. number = "",
  90. mcc = "",
  91. mnc = "",
  92. iccid = "",
  93. imsi = "",
  94. imei = "",
  95. country = "",
  96. areaCode = "",
  97. available = false,
  98. carrierId = "",
  99. carrierName = ""
  100. )
  101. )
  102. init {
  103. CoroutineScope(Dispatchers.IO).launch {
  104. simInfoFlow.collect {
  105. spoofedSimInfo.emit(it)
  106. }
  107. }
  108. }
  109. @SuppressLint("MissingPermission")
  110. suspend fun updateSpoofedSimInfo(spoofedSimInfo: SpoofedSimInfo, suspend: Boolean? = true) {
  111. context.simInfoDataStore.edit {
  112. it[PreferencesKeys.NUMBER_ID] = spoofedSimInfo.numberId
  113. it[PreferencesKeys.NUMBER] = spoofedSimInfo.number
  114. it[PreferencesKeys.MCC] = spoofedSimInfo.mcc
  115. it[PreferencesKeys.MNC] = spoofedSimInfo.mnc
  116. it[PreferencesKeys.ICCID] = spoofedSimInfo.iccid
  117. it[PreferencesKeys.IMSI] = spoofedSimInfo.imsi
  118. it[PreferencesKeys.IMEI] = spoofedSimInfo.imei
  119. it[PreferencesKeys.COUNTRY] = spoofedSimInfo.country
  120. it[PreferencesKeys.AREA_CODE] = spoofedSimInfo.areaCode
  121. it[PreferencesKeys.AVAILABLE] = spoofedSimInfo.available
  122. it[PreferencesKeys.CARRIER_ID] = spoofedSimInfo.carrierId
  123. it[PreferencesKeys.CARRIER_NAME] = spoofedSimInfo.carrierName
  124. }
  125. try {
  126. if (ROOT_ACCESS) {
  127. if (suspend == true) {
  128. suspendPackage(PACKAGE_GMS, PACKAGE_MESSAGING)
  129. }
  130. shellRun(
  131. "setprop persist.spoof.number ${spoofedSimInfo.number}",
  132. "setprop persist.spoof.mcc ${spoofedSimInfo.mcc}",
  133. "setprop persist.spoof.mnc ${spoofedSimInfo.mnc}",
  134. "setprop persist.spoof.iccid ${spoofedSimInfo.iccid}",
  135. "setprop persist.spoof.imsi ${spoofedSimInfo.imsi}",
  136. "setprop persist.spoof.imei ${spoofedSimInfo.imei}",
  137. "setprop persist.spoof.country ${spoofedSimInfo.country}",
  138. "setprop persist.spoof.carrier.id ${spoofedSimInfo.carrierId}",
  139. "setprop persist.spoof.carrier.name '${spoofedSimInfo.carrierName}'",
  140. )
  141. val context = getContext()
  142. val subscriptionManager: SubscriptionManager =
  143. context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
  144. if (hasPermission(Manifest.permission.READ_PHONE_STATE)) {
  145. val simCount = subscriptionManager.activeSubscriptionInfoCountMax
  146. for (i in 0 until simCount) {
  147. val info = subscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(i)
  148. if (info != null) {
  149. val mcc = info.mccString
  150. val mnc = info.mncString
  151. Log.i(TAG, "mccmnc spoofed: $mcc$mnc")
  152. }
  153. }
  154. }
  155. if (suspend == true) {
  156. resumePackage(PACKAGE_GMS, PACKAGE_MESSAGING)
  157. }
  158. } else {
  159. if (suspend == true) {
  160. suspendPackage(PACKAGE_GMS, PACKAGE_MESSAGING)
  161. shellRun(
  162. PACKAGE_GMS.kill(),
  163. PACKAGE_MESSAGING.kill()
  164. )
  165. }
  166. val plmn = spoofedSimInfo.mcc + spoofedSimInfo.mnc
  167. val plmnHex = SimEncoder.encPLMN(spoofedSimInfo.mcc + spoofedSimInfo.mnc)
  168. val plmnwactHex = SimEncoder.encPLMNwAcT("$plmn:4000,$plmn:8000,$plmn:0080")
  169. val fplmn =
  170. SimEncoder.encPLMN("46000,46001,46002,46006,46007,46011,46012,46015,46020")
  171. val telephonyManager =
  172. context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
  173. val apduChannel = ApduChannel(telephonyManager, SIMView.AID_CUSTOM)
  174. apduChannel.select(SIMView.FID_MF)
  175. apduChannel.select(SIMView.FID_EF_ICCID)
  176. apduChannel.writeBinary(SimEncoder.encICCID(spoofedSimInfo.iccid))
  177. apduChannel.select(SIMView.FID_DF_GSM)
  178. apduChannel.select(SIMView.FID_EF_IMSI)
  179. apduChannel.writeBinary(SimEncoder.encIMSI(spoofedSimInfo.imsi))
  180. apduChannel.select(SIMView.FID_EF_PLMNSEL)
  181. apduChannel.writeBinary(plmnHex.padEnd(120, 'f'))
  182. apduChannel.select(SIMView.FID_EF_EHPLMN)
  183. apduChannel.writeBinary(plmnHex.padEnd(24, 'f'))
  184. apduChannel.select(SIMView.FID_EF_PLMNWACT)
  185. apduChannel.writeBinary(plmnwactHex.padEnd(240, 'f'))
  186. apduChannel.select(SIMView.FID_EF_OPLMNWACT)
  187. apduChannel.writeBinary(plmnwactHex.padEnd(120, 'f'))
  188. apduChannel.select(SIMView.FID_EF_HPLMNWACT)
  189. apduChannel.writeBinary(plmnwactHex.padEnd(40, 'f'))
  190. apduChannel.select(SIMView.FID_EF_FPLMN)
  191. apduChannel.writeBinary(fplmn.padEnd(60, 'f'))
  192. if (plmn.isNotEmpty()) {
  193. if (plmn.length == 5) {
  194. apduChannel.select(SIMView.FID_EF_AD)
  195. apduChannel.writeBinary("00000102")
  196. } else if (plmn.length == 6) {
  197. apduChannel.select(SIMView.FID_EF_AD)
  198. apduChannel.writeBinary("00000103")
  199. }
  200. }
  201. apduChannel.close()
  202. val apduChannel1 = ApduChannel(telephonyManager, SIMView.AID_USIM)
  203. apduChannel1.writeMSISDN_USIM(spoofedSimInfo.number)
  204. apduChannel.close()
  205. telephonyManager.rebootModem()
  206. delay(5000)
  207. if (suspend == true) {
  208. shellRun(
  209. PACKAGE_GMS.kill(),
  210. PACKAGE_MESSAGING.kill()
  211. )
  212. resumePackage(PACKAGE_GMS, PACKAGE_MESSAGING)
  213. }
  214. }
  215. } catch (e: Exception) {
  216. Log.e(TAG, "Error updateSpoofedSimInfo: ${e.message}", e)
  217. }
  218. }
  219. suspend fun mock() {
  220. if (isOldVersion(context)) {
  221. val content = getContext().assets.open("us_numbers.txt").bufferedReader().use {
  222. it.readText()
  223. }
  224. // get random number
  225. content.split("\n")
  226. .filter { it.isNotBlank() }
  227. .shuffled()
  228. .firstOrNull()
  229. ?.let {
  230. updateSpoofedSimInfo(
  231. SpoofedSimInfo(
  232. numberId = 0,
  233. number = it,
  234. mcc = "310",
  235. mnc = "150",
  236. iccid = genICCID("150", "1"),
  237. imsi = genIMSI("310150"),
  238. imei = genIMEI(),
  239. country = "us",
  240. areaCode = "1",
  241. available = false,
  242. carrierId = "1779",
  243. carrierName = "Cricket Wireless"
  244. )
  245. )
  246. }
  247. } else {
  248. val content = getContext().assets.open("us_numbers.txt")
  249. .bufferedReader().use { it.readText() }
  250. // get random number
  251. content.split("\n")
  252. .filter { it.isNotBlank() }
  253. .shuffled()
  254. .firstOrNull()
  255. ?.let {
  256. updateSpoofedSimInfo(
  257. SpoofedSimInfo(
  258. numberId = 0,
  259. number = it,
  260. mcc = "310",
  261. mnc = "240",
  262. iccid = genICCID("240", "1"),
  263. imsi = genIMSI("310240"),
  264. imei = genIMEI(),
  265. country = "us",
  266. areaCode = "1",
  267. available = false,
  268. carrierId = "1",
  269. carrierName = "T-Mobile"
  270. )
  271. )
  272. }
  273. }
  274. }
  275. }