SpoofedInfoRepo.kt 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. package com.example.modifier.repo
  2. import android.annotation.SuppressLint
  3. import android.content.Context
  4. import android.os.Build
  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.genMacAddress
  27. import com.example.modifier.utils.genSerialNo
  28. import com.example.modifier.utils.getContext
  29. import com.example.modifier.utils.isOldVersion
  30. import com.example.modifier.utils.shellRun
  31. import kotlinx.coroutines.CoroutineScope
  32. import kotlinx.coroutines.Dispatchers
  33. import kotlinx.coroutines.delay
  34. import kotlinx.coroutines.flow.MutableStateFlow
  35. import kotlinx.coroutines.flow.map
  36. import kotlinx.coroutines.launch
  37. import kotlinx.serialization.encodeToString
  38. import kotlinx.serialization.json.Json
  39. import org.apache.commons.io.FileUtils
  40. import org.json.JSONObject
  41. import java.io.File
  42. val Context.simInfoDataStore by preferencesDataStore(name = "${BuildConfig.APPLICATION_ID}.simInfo")
  43. class SpoofedInfoRepo private constructor(private val context: Context) {
  44. companion object {
  45. private const val TAG = "$baseTag/SpoofedSimInfoRepository"
  46. val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { SpoofedInfoRepo(getContext()) }
  47. }
  48. public object PreferencesKeys {
  49. val NUMBER_ID = intPreferencesKey("number_id")
  50. val NUMBER = stringPreferencesKey("number")
  51. val MCC = stringPreferencesKey("mcc")
  52. val MNC = stringPreferencesKey("mnc")
  53. val ICCID = stringPreferencesKey("iccid")
  54. val IMSI = stringPreferencesKey("imsi")
  55. val IMEI = stringPreferencesKey("imei")
  56. val COUNTRY = stringPreferencesKey("country")
  57. val AREA_CODE = stringPreferencesKey("area_code")
  58. val AVAILABLE = booleanPreferencesKey("available")
  59. val CARRIER_ID = stringPreferencesKey("carrier_id")
  60. val CARRIER_NAME = stringPreferencesKey("carrier_name")
  61. val SERIAL_NO = stringPreferencesKey("serial_no")
  62. val WIFI_MAC = stringPreferencesKey("wifi_mac")
  63. val BSSID = stringPreferencesKey("bssid")
  64. val BT_MAC = stringPreferencesKey("bt_mac")
  65. val ETH_MAC = stringPreferencesKey("eth_mac")
  66. }
  67. private val simInfoFlow = context.simInfoDataStore.data.map {
  68. val numberId = it[PreferencesKeys.NUMBER_ID] ?: 0
  69. val number = it[PreferencesKeys.NUMBER] ?: ""
  70. val mcc = it[PreferencesKeys.MCC] ?: ""
  71. val mnc = it[PreferencesKeys.MNC] ?: ""
  72. val iccid = it[PreferencesKeys.ICCID] ?: ""
  73. val imsi = it[PreferencesKeys.IMSI] ?: ""
  74. val imei = it[PreferencesKeys.IMEI] ?: ""
  75. val country = it[PreferencesKeys.COUNTRY] ?: ""
  76. val areaCode = it[PreferencesKeys.AREA_CODE] ?: ""
  77. val available = it[PreferencesKeys.AVAILABLE] ?: false
  78. val carrierId = it[PreferencesKeys.CARRIER_ID] ?: ""
  79. val carrierName = it[PreferencesKeys.CARRIER_NAME] ?: ""
  80. val serialNo = it[PreferencesKeys.SERIAL_NO] ?: ""
  81. val wifiMac = it[PreferencesKeys.WIFI_MAC] ?: ""
  82. val bssid = it[PreferencesKeys.BSSID] ?: ""
  83. val btMac = it[PreferencesKeys.BT_MAC] ?: ""
  84. val ethMac = it[PreferencesKeys.ETH_MAC] ?: ""
  85. SpoofedSimInfo(
  86. numberId = numberId,
  87. number = number,
  88. mcc = mcc,
  89. mnc = mnc,
  90. iccid = iccid,
  91. imsi = imsi,
  92. imei = imei,
  93. country = country,
  94. areaCode = areaCode,
  95. available = available,
  96. carrierId = carrierId,
  97. carrierName = carrierName,
  98. serialNo = serialNo,
  99. wifiMac = wifiMac,
  100. bssid = bssid,
  101. btMac = btMac,
  102. ethMac = ethMac
  103. )
  104. }
  105. val spoofedSimInfo = MutableStateFlow(
  106. SpoofedSimInfo(
  107. numberId = 0,
  108. number = "",
  109. mcc = "",
  110. mnc = "",
  111. iccid = "",
  112. imsi = "",
  113. imei = "",
  114. country = "",
  115. areaCode = "",
  116. available = false,
  117. carrierId = "",
  118. carrierName = "",
  119. serialNo = "",
  120. wifiMac = "",
  121. bssid = "",
  122. btMac = "",
  123. ethMac = ""
  124. )
  125. )
  126. init {
  127. CoroutineScope(Dispatchers.IO).launch {
  128. simInfoFlow.collect {
  129. spoofedSimInfo.emit(it)
  130. }
  131. }
  132. }
  133. @SuppressLint("MissingPermission")
  134. suspend fun updateSpoofedSimInfo(spoofedSimInfo: SpoofedSimInfo, suspend: Boolean? = true) {
  135. context.getSharedPreferences("share_sim_info", Context.MODE_PRIVATE)
  136. ?.edit()
  137. ?.putString("imei", spoofedSimInfo.imei)
  138. ?.apply()
  139. context.simInfoDataStore.edit {
  140. it[PreferencesKeys.NUMBER_ID] = spoofedSimInfo.numberId
  141. it[PreferencesKeys.NUMBER] = spoofedSimInfo.number
  142. it[PreferencesKeys.MCC] = spoofedSimInfo.mcc
  143. it[PreferencesKeys.MNC] = spoofedSimInfo.mnc
  144. it[PreferencesKeys.ICCID] = spoofedSimInfo.iccid
  145. it[PreferencesKeys.IMSI] = spoofedSimInfo.imsi
  146. it[PreferencesKeys.IMEI] = spoofedSimInfo.imei
  147. it[PreferencesKeys.COUNTRY] = spoofedSimInfo.country
  148. it[PreferencesKeys.AREA_CODE] = spoofedSimInfo.areaCode
  149. it[PreferencesKeys.AVAILABLE] = spoofedSimInfo.available
  150. it[PreferencesKeys.CARRIER_ID] = spoofedSimInfo.carrierId
  151. it[PreferencesKeys.CARRIER_NAME] = spoofedSimInfo.carrierName
  152. it[PreferencesKeys.SERIAL_NO] = spoofedSimInfo.serialNo
  153. it[PreferencesKeys.WIFI_MAC] = spoofedSimInfo.wifiMac
  154. it[PreferencesKeys.BSSID] = spoofedSimInfo.bssid
  155. it[PreferencesKeys.BT_MAC] = spoofedSimInfo.btMac
  156. it[PreferencesKeys.ETH_MAC] = spoofedSimInfo.ethMac
  157. }
  158. try {
  159. runCatching {
  160. val jsonFile = File.createTempFile(
  161. "temp", ".json", getContext().externalCacheDir
  162. )
  163. FileUtils.writeStringToFile(
  164. jsonFile,
  165. Json.encodeToString(spoofedSimInfo),
  166. Charsets.UTF_8
  167. )
  168. shellRun(
  169. "cat ${jsonFile.absolutePath} > /data/user_de/0/com.android.phone/files/config.json",
  170. "cat ${jsonFile.absolutePath} > /data/system/config.json",
  171. )
  172. jsonFile.delete()
  173. }.onFailure {
  174. Log.e(TAG, "Error updateSpoofedSimInfo: ${it.message}", it)
  175. }
  176. if (suspend == true) {
  177. shellRun(
  178. PACKAGE_GMS.kill(),
  179. PACKAGE_MESSAGING.kill(),
  180. )
  181. }
  182. val context = getContext()
  183. runCatching {
  184. val plmn = spoofedSimInfo.mcc + spoofedSimInfo.mnc
  185. val plmnHex = SimEncoder.encPLMN(spoofedSimInfo.mcc + spoofedSimInfo.mnc)
  186. val plmnwactHex = SimEncoder.encPLMNwAcT("$plmn:4000,$plmn:8000,$plmn:0080")
  187. val fplmn =
  188. SimEncoder.encPLMN("46000,46001,46002,46006,46007,46011,46012,46015,46020")
  189. val telephonyManager =
  190. context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
  191. val apduChannel = ApduChannel(telephonyManager, SIMView.AID_CUSTOM)
  192. apduChannel.select(SIMView.FID_MF)
  193. apduChannel.select(SIMView.FID_EF_ICCID)
  194. apduChannel.writeBinary(SimEncoder.encICCID(spoofedSimInfo.iccid))
  195. apduChannel.select(SIMView.FID_MF)
  196. apduChannel.select(SIMView.FID_DF_TELECOM)
  197. apduChannel.select(SIMView.FID_EF_MSISDN)
  198. apduChannel.writeRecord(
  199. 1, SimEncoder.encMSISDN(spoofedSimInfo.number)
  200. .padStart(56, 'F')
  201. )
  202. apduChannel.select(SIMView.FID_MF)
  203. apduChannel.select(SIMView.FID_DF_GSM)
  204. apduChannel.select(SIMView.FID_EF_IMSI)
  205. apduChannel.writeBinary(SimEncoder.encIMSI(spoofedSimInfo.imsi))
  206. apduChannel.select(SIMView.FID_EF_PLMNSEL)
  207. apduChannel.writeBinary(plmnHex.padEnd(120, 'f'))
  208. apduChannel.select(SIMView.FID_EF_EHPLMN)
  209. apduChannel.writeBinary(plmnHex.padEnd(24, 'f'))
  210. apduChannel.select(SIMView.FID_EF_PLMNWACT)
  211. apduChannel.writeBinary(plmnwactHex.padEnd(240, 'f'))
  212. apduChannel.select(SIMView.FID_EF_OPLMNWACT)
  213. apduChannel.writeBinary(plmnwactHex.padEnd(120, 'f'))
  214. apduChannel.select(SIMView.FID_EF_HPLMNWACT)
  215. apduChannel.writeBinary(plmnwactHex.padEnd(40, 'f'))
  216. apduChannel.select(SIMView.FID_EF_FPLMN)
  217. apduChannel.writeBinary(fplmn.padEnd(60, 'f'))
  218. apduChannel.select(SIMView.FID_EF_SPN)
  219. apduChannel.writeBinary("01542d4d6f62696c65ffffffffffffffff") //T-Mobile
  220. if (plmn.isNotEmpty()) {
  221. if (plmn.length == 5) {
  222. apduChannel.select(SIMView.FID_EF_AD)
  223. apduChannel.writeBinary("00000102")
  224. } else if (plmn.length == 6) {
  225. apduChannel.select(SIMView.FID_EF_AD)
  226. apduChannel.writeBinary("00000103")
  227. }
  228. }
  229. apduChannel.close()
  230. val apduChannel1 = ApduChannel(telephonyManager, SIMView.AID_USIM)
  231. apduChannel1.writeMSISDN_USIM(spoofedSimInfo.number)
  232. apduChannel.close()
  233. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && !ROOT_ACCESS) {
  234. telephonyManager.rebootModem()
  235. }
  236. val subscriptionManager =
  237. context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
  238. run rebootModem@{
  239. repeat(20) {
  240. runCatching {
  241. val activeSubscriptionInfoList =
  242. subscriptionManager.activeSubscriptionInfoList
  243. activeSubscriptionInfoList?.forEach {
  244. Log.i(TAG, "iccid:${it.iccId} target:${spoofedSimInfo.iccid}")
  245. if (it.iccId == spoofedSimInfo.iccid) {
  246. Log.i(TAG, "rebootModem: success")
  247. return@rebootModem
  248. }
  249. }
  250. }.onFailure {
  251. Log.e(TAG, "Error reading ICCID: ${it.message}", it)
  252. }
  253. delay(2000)
  254. }
  255. }
  256. }
  257. if (suspend == true) {
  258. shellRun(
  259. PACKAGE_GMS.kill(),
  260. "sleep 3",
  261. PACKAGE_MESSAGING.kill(),
  262. "sleep 3"
  263. )
  264. }
  265. // val base64 = Base64.encode(jsonObject.toString().toByteArray(), Base64.DEFAULT)
  266. // .toString(Charsets.UTF_8)
  267. // shellRun("echo '$base64' > /sdcard/Android/data/com.android.phone/files/config/config.json")
  268. } catch (e: Exception) {
  269. Log.e(TAG, "Error updateSpoofedSimInfo: ${e.message}", e)
  270. }
  271. }
  272. suspend fun updateAvailable(available: Boolean) {
  273. context.simInfoDataStore.edit {
  274. it[PreferencesKeys.AVAILABLE] = available
  275. }
  276. }
  277. suspend fun mock() {
  278. if (isOldVersion(context)) {
  279. val content = getContext().assets.open("us_numbers.txt").bufferedReader().use {
  280. it.readText()
  281. }
  282. // get random number
  283. content.split("\n")
  284. .filter { it.isNotBlank() }
  285. .shuffled()
  286. .firstOrNull()
  287. ?.let {
  288. updateSpoofedSimInfo(
  289. SpoofedSimInfo(
  290. numberId = 0,
  291. number = it,
  292. mcc = "310",
  293. mnc = "150",
  294. iccid = genICCID("150", "1"),
  295. imsi = genIMSI("310150"),
  296. imei = genIMEI(),
  297. country = "us",
  298. areaCode = "1",
  299. available = false,
  300. carrierId = "1779",
  301. carrierName = "Cricket Wireless",
  302. serialNo = genSerialNo(),
  303. wifiMac = genMacAddress(),
  304. bssid = genMacAddress(),
  305. btMac = genMacAddress(),
  306. ethMac = genMacAddress()
  307. ),
  308. suspend = false
  309. )
  310. }
  311. } else {
  312. val content = getContext().assets.open("us_numbers.txt")
  313. .bufferedReader().use { it.readText() }
  314. // get random number
  315. content.split("\n")
  316. .filter { it.isNotBlank() }
  317. .shuffled()
  318. .firstOrNull()
  319. ?.let {
  320. updateSpoofedSimInfo(
  321. SpoofedSimInfo(
  322. numberId = 0,
  323. number = it,
  324. mcc = "310",
  325. mnc = "240",
  326. iccid = genICCID("240", "1"),
  327. imsi = genIMSI("310240"),
  328. imei = genIMEI(),
  329. country = "us",
  330. areaCode = "1",
  331. available = false,
  332. carrierId = "1",
  333. carrierName = "T-Mobile",
  334. serialNo = genSerialNo(),
  335. wifiMac = genMacAddress(),
  336. bssid = genMacAddress(),
  337. btMac = genMacAddress(),
  338. ethMac = genMacAddress()
  339. )
  340. )
  341. }
  342. }
  343. }
  344. }