log.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. import frida from 'frida'
  2. import fs from 'fs'
  3. import url from 'url'
  4. import path from 'path'
  5. import util from 'util'
  6. import Vorpal from 'vorpal'
  7. import { spawn, execSync } from 'child_process'
  8. import { setTimeout } from 'timers/promises'
  9. const filePath = url.fileURLToPath(import.meta.url)
  10. const __dirname = path.dirname(filePath)
  11. function pushFile(file, dest, force = false) {
  12. const fileName = path.basename(file)
  13. const srcPath = path.resolve(__dirname, file)
  14. const destPath = dest + fileName
  15. if (!force) {
  16. console.log(`Checking if ${destPath} exists`)
  17. try {
  18. if (execSync(`adb shell ls ${destPath}`).toString().includes('No such file or directory')) {
  19. throw new Error('File not found')
  20. }
  21. console.log(`File ${fileName} already exists`)
  22. return
  23. } catch (e) {
  24. console.log(`File ${fileName} not found`)
  25. }
  26. }
  27. // execSync(`adb shell mkdir ${dest}`)
  28. console.log(`Pushing ${srcPath} to ${destPath}`)
  29. execSync(`adb push ${srcPath} ${destPath}`)
  30. console.log(`Push success: ${fileName}`)
  31. console.log(`set permission 777 to ${destPath}`)
  32. execSync(`adb shell chmod 777 ${destPath}`)
  33. console.log(`set permission success: ${fileName}`)
  34. }
  35. pushFile('../RcsHackTool.dex', '/sdcard/Download/')
  36. pushFile('../gson.dex', '/sdcard/Android/data/com.google.android.gms/')
  37. pushFile('../gson.dex', '/sdcard/Android/data/com.google.android.apps.messaging/')
  38. class Log {
  39. static TAG = ''
  40. static format(...msg) {
  41. let m = []
  42. for (let i = 0; i < msg.length; i++) {
  43. if (typeof msg[i] === 'object') {
  44. if ('[object Object]' === msg[i].toString()) {
  45. m.push(util.inspect(msg[i]))
  46. }
  47. } else {
  48. m.push(msg[i])
  49. }
  50. }
  51. m = m.join(' ')
  52. return m
  53. }
  54. static i(...msg) {
  55. console.log(`\x1b[30m${this.TAG} ${this.format(...msg)}\x1b[0m`)
  56. }
  57. static w(...msg) {
  58. console.log(`\x1b[33m${this.TAG} ${this.format(...msg)}\x1b[0m`)
  59. }
  60. static e(...msg) {
  61. console.log(`\x1b[31m${this.TAG} ${this.format(...msg)}\x1b[0m`)
  62. }
  63. static s(...msg) {
  64. console.log(`\x1b[32m${this.TAG} ${this.format(...msg)}\x1b[0m`)
  65. }
  66. }
  67. function replaceVars(source) {
  68. const vars = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../vars.json')).toString())
  69. return source
  70. .replace('{{mcc}}', vars.mcc)
  71. .replace('{{mnc}}', vars.mnc)
  72. .replace('{{simOperator}}', vars.simOperator)
  73. .replace('{{networkOperator}}', vars.networkOperator)
  74. .replace('{{simSerialNumber}}', vars.simSerialNumber)
  75. .replace('{{iccId}}', vars.iccId)
  76. .replace('{{number}}', vars.number)
  77. .replace('{{imei}}', vars.imei)
  78. .replace('{{imsi}}', vars.imsi)
  79. .replace('{{countryIso}}', vars.countryIso)
  80. .replace('{{subId}}', vars.subId)
  81. .replace('{{androidId}}', vars.androidId)
  82. .replace('{{serialNumber}}', vars.serialNumber)
  83. }
  84. function loadSource(filePath) {
  85. Log.s(`Loading ${filePath}`)
  86. return replaceVars(fs.readFileSync(path.resolve(__dirname, filePath)).toString())
  87. }
  88. const source = loadSource('../scripts/log_sms.js')
  89. const source_gms = loadSource('../scripts/log_gms.js')
  90. const source_ssl = loadSource('../scripts/ssl_bypass.js')
  91. fs.writeFileSync('scripts/_spoof.js', source)
  92. fs.writeFileSync('scripts/_log_gms.js', source_gms)
  93. let device = null
  94. let tracers = []
  95. async function stop() {
  96. Log.i('[*] Stopping all tracers')
  97. for (const tracer of tracers) {
  98. Log.i('[*] Stopping', tracer.pid)
  99. tracer.session.detach()
  100. try {
  101. await device.kill(tracer.pid)
  102. } catch (error) {}
  103. }
  104. process.exit(1)
  105. }
  106. process.on('SIGTERM', stop)
  107. process.on('SIGINT', stop)
  108. async function main() {
  109. device = await frida.getUsbDevice()
  110. device.spawnAdded.connect(onSpawnAdded)
  111. Log.i('[*] Enabling spawn gating')
  112. await device.enableSpawnGating()
  113. Log.i('[*] Enabled spawn gating')
  114. // Log.i("[*] Spawning com.google.android.apps.messaging")
  115. // const pid = await device.spawn("com.google.android.apps.messaging")
  116. // Log.i("[*] Spawned com.google.android.apps.messaging: " + pid)
  117. // const tracer = await Tracer.open(pid)
  118. // tracers.push(tracer)
  119. }
  120. async function onSpawnAdded(spawn) {
  121. try {
  122. if (spawn.identifier.startsWith('com.google.android.apps.messaging')) {
  123. Log.i('[*] Tracing', spawn.pid, spawn.identifier)
  124. const tracer = await Tracer.open(spawn.pid, '../scripts/log_sms.js')
  125. tracers.push(tracer)
  126. }
  127. if (spawn.identifier.startsWith('com.google.android.gms')) {
  128. Log.i('[*] Tracing', spawn.pid, spawn.identifier)
  129. const tracer = await Tracer.open(spawn.pid, '../scripts/log_gms.js')
  130. tracers.push(tracer)
  131. } else {
  132. Log.i('[*] Resuming', spawn.pid, spawn.identifier)
  133. await device.resume(spawn.pid)
  134. }
  135. } catch (e) {
  136. Log.e(`err: ${e}`)
  137. }
  138. }
  139. class Tracer {
  140. static async open(pid, source) {
  141. const tracer = new Tracer(pid, source)
  142. await tracer._initialize()
  143. return tracer
  144. }
  145. constructor(pid, sourceFile) {
  146. this.pid = pid
  147. this.sourceFile = sourceFile
  148. this.source = loadSource(sourceFile)
  149. this.session = null
  150. this.script = null
  151. }
  152. async _initialize() {
  153. const session = await device.attach(this.pid)
  154. this.session = session
  155. session.detached.connect(this._onSessionDetached.bind(this))
  156. const script = await session.createScript(this.source)
  157. this.script = script
  158. script.message.connect(this._onScriptMessage.bind(this))
  159. await script.load()
  160. // const script_ssl = await session.createScript(source_ssl)
  161. // await script_ssl.load()
  162. try {
  163. await device.resume(this.pid)
  164. } catch (e) {
  165. Log.e(e)
  166. }
  167. }
  168. async reload() {
  169. if (this.script) {
  170. this.script.unload()
  171. }
  172. this.source = loadSource(this.sourceFile)
  173. this.script = await this.session.createScript(this.source)
  174. this.script.message.connect(this._onScriptMessage.bind(this))
  175. await this.script.load()
  176. }
  177. _onSessionDetached(reason) {
  178. Log.i(`[PID ${this.pid}] onSessionDetached(reason='${reason}')`)
  179. const i = tracers.findIndex((tracer) => tracer.pid === this.pid)
  180. if (i !== -1) {
  181. tracers.splice(i, 1)
  182. }
  183. }
  184. _onScriptMessage(message, data) {
  185. if (message.type === 'error') {
  186. Log.e(`[PID ${this.pid}] onScriptMessage()`, message, data ? JSON.stringify(data) : '')
  187. } else {
  188. Log.i(`[PID ${this.pid}] onScriptMessage()`, message, data ? JSON.stringify(data) : '')
  189. }
  190. }
  191. }
  192. main()
  193. const vorpal = new Vorpal()
  194. vorpal.sigint(function () {
  195. stop()
  196. })
  197. vorpal.command('clear [app]').action(async function (args, callback) {
  198. try {
  199. const app = args.app
  200. if ('sms' === app) {
  201. execSync('adb shell pm clear com.google.android.apps.messaging')
  202. pushFile('../gson.dex', '/sdcard/Android/data/com.google.android.apps.messaging/')
  203. } else if ('gms' === app) {
  204. execSync('adb shell pm clear com.google.android.gms')
  205. pushFile('../gson.dex', '/sdcard/Android/data/com.google.android.gms/')
  206. } else if ('gsf' === app) {
  207. execSync('adb shell pm clear com.google.android.gsf')
  208. } else if ('all' === app) {
  209. execSync('adb shell pm clear com.google.android.apps.messaging')
  210. await setTimeout(1000)
  211. execSync('adb shell pm clear com.google.android.gms')
  212. pushFile('../gson.dex', '/sdcard/Android/data/com.google.android.gms/')
  213. pushFile('../gson.dex', '/sdcard/Android/data/com.google.android.apps.messaging/')
  214. }
  215. } catch (error) {
  216. Log.e(error)
  217. }
  218. callback()
  219. })
  220. vorpal.command('stop').action(function (args, callback) {
  221. try {
  222. execSync('adb shell am force-stop com.google.android.apps.messaging')
  223. execSync('adb shell am force-stop com.google.android.gms')
  224. } catch (error) {
  225. Log.e(error)
  226. }
  227. callback()
  228. })
  229. vorpal.command('gen').action(function (args, callback) {
  230. execSync(`node ${path.resolve(__dirname, '../gen.js')}`)
  231. callback()
  232. })
  233. vorpal.command('reload').action(function (args, callback) {
  234. tracers.forEach((tracer) => {
  235. tracer.reload()
  236. })
  237. callback()
  238. })
  239. vorpal.command('otp [code]').action(async function (args, callback) {
  240. const code = args.code
  241. let phoneProcess
  242. try {
  243. phoneProcess = await device.getProcess('com.android.phone')
  244. } catch (error) {
  245. try {
  246. phoneProcess = await device.getProcess('SIM 卡工具包')
  247. } catch (error) {}
  248. }
  249. if (!phoneProcess) {
  250. Log.e('Phone process not found')
  251. callback()
  252. return
  253. }
  254. const session = await device.attach(phoneProcess.pid)
  255. const script = await session.createScript(
  256. loadSource('../scripts/sendsms.js')
  257. .replace('{{sender}}', '3538')
  258. .replace('{{msg}}', `Your Messenger verification code is G-${code}`)
  259. )
  260. script.message.connect((message) => {
  261. console.log('[*] Message:', message)
  262. if (message.type === 'send' && message.payload === 'ok') {
  263. script.unload()
  264. }
  265. })
  266. await script.load()
  267. callback()
  268. })
  269. vorpal.delimiter('rcs$').show()