all.js 8.9 KB

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