spoof_phone.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. class Log {
  2. static TAG = '[Phone]'
  3. static Debug = true
  4. static format(...msg) {
  5. let m = []
  6. for (let i = 0; i < msg.length; i++) {
  7. if (typeof msg[i] === 'object') {
  8. m.push(JSON.stringify(msg[i]))
  9. } else {
  10. m.push(msg[i])
  11. }
  12. }
  13. m = m.join(' ')
  14. return m
  15. }
  16. static i(...msg) {
  17. if (!this.Debug) return
  18. console.log(`\x1b[30m${this.TAG} ${this.format(...msg)}\x1b[0m`)
  19. }
  20. static w(...msg) {
  21. console.log(`\x1b[33m${this.TAG} ${this.format(...msg)}\x1b[0m`)
  22. }
  23. static e(...msg) {
  24. console.log(`\x1b[31m${this.TAG} ${this.format(...msg)}\x1b[0m`)
  25. }
  26. static s(...msg) {
  27. console.log(`\x1b[32m${this.TAG} ${this.format(...msg)}\x1b[0m`)
  28. }
  29. }
  30. function trace(tag) {
  31. Log.e((tag || '') + Java.use('android.util.Log').getStackTraceString(Java.use('java.lang.Throwable').$new()))
  32. }
  33. const config = {
  34. "mcc": "310",
  35. "mnc": "240",
  36. "iccid": "15003704960405101503",
  37. "number": "4432486416",
  38. "imei": "359028036674149",
  39. "imsi": "310240158368215",
  40. "country": "us"
  41. }
  42. setImmediate(() => {
  43. Java.perform(function () {
  44. function checkPackage(name) {
  45. // return (
  46. // name.startsWith('com.google.android.gsf') ||
  47. // name.startsWith('com.google.android.gms') ||
  48. // name.startsWith('com.google.android.apps') ||
  49. // name.startsWith('com.example')
  50. // )
  51. return true
  52. }
  53. const PhoneInterfaceManager = Java.use('com.android.phone.PhoneInterfaceManager')
  54. PhoneInterfaceManager.getLine1NumberForDisplay.overload(
  55. 'int',
  56. 'java.lang.String',
  57. 'java.lang.String'
  58. ).implementation = function (subId, callingPackage, callingFeatureId) {
  59. const res = this.getLine1NumberForDisplay(subId, callingPackage, callingFeatureId)
  60. if (!checkPackage(callingPackage)) {
  61. return res
  62. }
  63. Log.i(
  64. `spoof PhoneInterfaceManager.getLine1NumberForDisplay(${subId}, ${callingPackage}, ${callingFeatureId}): ${res} -> ${config.number}`
  65. )
  66. return config.number
  67. }
  68. PhoneInterfaceManager.getNetworkCountryIsoForPhone.overload('int').implementation = function (phoneId) {
  69. const res = this.getNetworkCountryIsoForPhone(phoneId)
  70. Log.i(`spoof PhoneInterfaceManager.getNetworkCountryIsoForPhone(${phoneId}): ${res} -> ${config.country}`)
  71. return config.country
  72. }
  73. PhoneInterfaceManager.getImeiForSlot.overload('int', 'java.lang.String', 'java.lang.String').implementation =
  74. function (slotId, callingPackage, callingFeatureId) {
  75. const res = this.getImeiForSlot(slotId, callingPackage, callingFeatureId)
  76. if (!checkPackage(callingPackage)) {
  77. return res
  78. }
  79. Log.i(
  80. `spoof PhoneInterfaceManager.getImeiForSlot(${slotId}, ${callingPackage}, ${callingFeatureId}): ${res} -> ${config.imei}`
  81. )
  82. return config.imei
  83. }
  84. const SystemProperties = Java.use('android.os.SystemProperties')
  85. SystemProperties.get.overload('java.lang.String').implementation = function (key) {
  86. if ('gsm.sim.operator.iso-country' === key) {
  87. Log.i(`spoof SystemProperties.get(${key}): ${config.countryIso}`)
  88. return config.country
  89. }
  90. if ('gsm.sim.operator.numeric' === key) {
  91. Log.i(`spoof SystemProperties.get(${key}): ${config.mcc + config.mnc}`)
  92. return config.mcc + config.mnc
  93. }
  94. if ('gsm.operator.numeric' === key) {
  95. Log.i(`spoof SystemProperties.get(${key}): ${config.mcc + config.mnc}`)
  96. return config.mcc + config.mnc
  97. }
  98. return this.get(key)
  99. }
  100. const SubscriptionController = Java.use('com.android.internal.telephony.SubscriptionController')
  101. SubscriptionController.getSimStateForSlotIndex.overload('int').implementation = function (slotIndex) {
  102. const res = this.getSimStateForSlotIndex(slotIndex)
  103. Log.i(`spoof SubscriptionController.getSimStateForSlotIndex(${slotIndex}): ${res} -> 5`)
  104. return 5
  105. }
  106. SubscriptionController.getPhoneNumberFromFirstAvailableSource.overload(
  107. 'int',
  108. 'java.lang.String',
  109. 'java.lang.String'
  110. ).implementation = function (subId, callingPackage, callingFeatureId) {
  111. const res = this.getPhoneNumberFromFirstAvailableSource(subId, callingPackage, callingFeatureId)
  112. if (!checkPackage(callingPackage)) {
  113. return res
  114. }
  115. Log.i(
  116. `spoof SubscriptionController.getPhoneNumberFromFirstAvailableSource(${subId}, ${callingPackage}, ${callingFeatureId}): ${res} -> ${config.number}`
  117. )
  118. return config.number
  119. }
  120. const SubscriptionInfo = Java.use('android.telephony.SubscriptionInfo')
  121. SubscriptionController.getActiveSubscriptionInfoList.overload('java.lang.String').implementation = function (
  122. callingPackage
  123. ) {
  124. const res = this.getActiveSubscriptionInfoList(callingPackage)
  125. if (!checkPackage(callingPackage)) {
  126. return res
  127. }
  128. Log.i(`spoof SubscriptionController.getActiveSubscriptionInfoList(${callingPackage})`)
  129. for (let i = 0; i < res.size(); i++) {
  130. const info = Java.cast(res.get(i), SubscriptionInfo)
  131. info.mMcc.value = config.mcc
  132. info.mMnc.value = config.mnc
  133. info.mCountryIso.value = config.country
  134. info.mIccId.value = config.iccid
  135. }
  136. SystemProperties.set('gsm.sim.operator.iso-country', config.country)
  137. SystemProperties.set('gsm.sim.operator.numeric', config.mcc + config.mnc)
  138. SystemProperties.set('gsm.operator.numeric', config.mcc + config.mnc)
  139. return res
  140. }
  141. SubscriptionController.getActiveSubscriptionInfoList.overload(
  142. 'java.lang.String',
  143. 'java.lang.String'
  144. ).implementation = function (callingPackage, callingFeatureId) {
  145. const res = this.getActiveSubscriptionInfoList(callingPackage, callingFeatureId)
  146. if (!checkPackage(callingPackage)) {
  147. return res
  148. }
  149. Log.i(`spoof SubscriptionController.getActiveSubscriptionInfoList(${callingPackage}, ${callingFeatureId})`)
  150. for (let i = 0; i < res.size(); i++) {
  151. const info = Java.cast(res.get(i), SubscriptionInfo)
  152. info.mMcc.value = config.mcc
  153. info.mMnc.value = config.mnc
  154. info.mCountryIso.value = config.country
  155. info.mIccId.value = config.iccid
  156. }
  157. SystemProperties.set('gsm.sim.operator.iso-country', config.country)
  158. SystemProperties.set('gsm.sim.operator.numeric', config.mcc + config.mnc)
  159. SystemProperties.set('gsm.operator.numeric', config.mcc + config.mnc)
  160. return res
  161. }
  162. SubscriptionController.getActiveSubscriptionInfoList.overload('java.lang.String').implementation = function (
  163. callingPackage
  164. ) {
  165. const res = this.getActiveSubscriptionInfoList(callingPackage)
  166. if (!checkPackage(callingPackage)) {
  167. return res
  168. }
  169. Log.i(`spoof SubscriptionController.getActiveSubscriptionInfoList(${callingPackage})`)
  170. for (let i = 0; i < res.size(); i++) {
  171. const info = Java.cast(res.get(i), SubscriptionInfo)
  172. info.mMcc.value = config.mcc
  173. info.mMnc.value = config.mnc
  174. info.mCountryIso.value = config.country
  175. info.mIccId.value = config.iccid
  176. }
  177. SystemProperties.set('gsm.sim.operator.iso-country', config.country)
  178. SystemProperties.set('gsm.sim.operator.numeric', config.mcc + config.mnc)
  179. SystemProperties.set('gsm.operator.numeric', config.mcc + config.mnc)
  180. return res
  181. }
  182. const PhoneSubInfoController = Java.use('com.android.internal.telephony.PhoneSubInfoController')
  183. PhoneSubInfoController.getIccSerialNumberForSubscriber.overload(
  184. 'int',
  185. 'java.lang.String',
  186. 'java.lang.String'
  187. ).implementation = function (subId, callingPackage, callingFeatureId) {
  188. const res = this.getIccSerialNumberForSubscriber(subId, callingPackage, callingFeatureId)
  189. if (!checkPackage(callingPackage)) {
  190. return res
  191. }
  192. Log.i(
  193. `spoof PhoneInterfaceManager.getIccSerialNumberForSubscriber(${subId}, ${callingPackage}, ${callingFeatureId}): ${res} -> ${config.iccid}`
  194. )
  195. return config.iccid
  196. }
  197. PhoneSubInfoController.getSubscriberIdForSubscriber.overload(
  198. 'int',
  199. 'java.lang.String',
  200. 'java.lang.String'
  201. ).implementation = function (subId, callingPackage, callingFeatureId) {
  202. const res = this.getSubscriberIdForSubscriber(subId, callingPackage, callingFeatureId)
  203. if (!checkPackage(callingPackage)) {
  204. return res
  205. }
  206. Log.i(
  207. `spoof PhoneInterfaceManager.getSubscriberIdForSubscriber(${subId}, ${callingPackage}, ${callingFeatureId}): ${res} -> ${config.imsi}`
  208. )
  209. return config.imsi
  210. }
  211. })
  212. })