| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- import frida from 'frida'
- import fs from 'fs'
- import url from 'url'
- import path from 'path'
- import util from 'util'
- import Vorpal from 'vorpal'
- import { spawn, execSync } from 'child_process'
- import { setTimeout } from 'timers/promises'
- const filePath = url.fileURLToPath(import.meta.url)
- const __dirname = path.dirname(filePath)
- function pushFile(file, dest, force = false) {
- const fileName = path.basename(file)
- const srcPath = path.resolve(__dirname, file)
- const destPath = dest + fileName
- if (!force) {
- console.log(`Checking if ${destPath} exists`)
- try {
- if (execSync(`adb shell ls ${destPath}`).toString().includes('No such file or directory')) {
- throw new Error('File not found')
- }
- console.log(`File ${fileName} already exists`)
- return
- } catch (e) {
- console.log(`File ${fileName} not found`)
- }
- }
- // execSync(`adb shell mkdir ${dest}`)
- console.log(`Pushing ${srcPath} to ${destPath}`)
- execSync(`adb push ${srcPath} ${destPath}`)
- console.log(`Push success: ${fileName}`)
- console.log(`set permission 777 to ${destPath}`)
- execSync(`adb shell chmod 777 ${destPath}`)
- console.log(`set permission success: ${fileName}`)
- }
- pushFile('../RcsHackTool.dex', '/sdcard/Download/')
- pushFile('../gson.dex', '/sdcard/Android/data/com.google.android.gms/')
- pushFile('../gson.dex', '/sdcard/Android/data/com.google.android.apps.messaging/')
- class Log {
- static TAG = ''
- static format(...msg) {
- let m = []
- for (let i = 0; i < msg.length; i++) {
- if (typeof msg[i] === 'object') {
- if ('[object Object]' === msg[i].toString()) {
- m.push(util.inspect(msg[i]))
- }
- } else {
- m.push(msg[i])
- }
- }
- m = m.join(' ')
- return m
- }
- static i(...msg) {
- console.log(`\x1b[30m${this.TAG} ${this.format(...msg)}\x1b[0m`)
- }
- static w(...msg) {
- console.log(`\x1b[33m${this.TAG} ${this.format(...msg)}\x1b[0m`)
- }
- static e(...msg) {
- console.log(`\x1b[31m${this.TAG} ${this.format(...msg)}\x1b[0m`)
- }
- static s(...msg) {
- console.log(`\x1b[32m${this.TAG} ${this.format(...msg)}\x1b[0m`)
- }
- }
- function replaceVars(source) {
- const vars = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../vars.json')).toString())
- return source
- .replace('{{mcc}}', vars.mcc)
- .replace('{{mnc}}', vars.mnc)
- .replace('{{simOperator}}', vars.simOperator)
- .replace('{{networkOperator}}', vars.networkOperator)
- .replace('{{simSerialNumber}}', vars.simSerialNumber)
- .replace('{{iccId}}', vars.iccId)
- .replace('{{number}}', vars.number)
- .replace('{{imei}}', vars.imei)
- .replace('{{imsi}}', vars.imsi)
- .replace('{{countryIso}}', vars.countryIso)
- .replace('{{subId}}', vars.subId)
- .replace('{{androidId}}', vars.androidId)
- .replace('{{serialNumber}}', vars.serialNumber)
- }
- function loadSource(filePath) {
- Log.s(`Loading ${filePath}`)
- return replaceVars(fs.readFileSync(path.resolve(__dirname, filePath)).toString())
- }
- const source = loadSource('../scripts/log_sms.js')
- const source_gms = loadSource('../scripts/log_gms.js')
- const source_ssl = loadSource('../scripts/ssl_bypass.js')
- fs.writeFileSync('scripts/_spoof.js', source)
- fs.writeFileSync('scripts/_log_gms.js', source_gms)
- let device = null
- let tracers = []
- async function stop() {
- Log.i('[*] Stopping all tracers')
- for (const tracer of tracers) {
- Log.i('[*] Stopping', tracer.pid)
- tracer.session.detach()
- try {
- await device.kill(tracer.pid)
- } catch (error) {}
- }
- process.exit(1)
- }
- process.on('SIGTERM', stop)
- process.on('SIGINT', stop)
- async function main() {
- device = await frida.getUsbDevice()
- device.spawnAdded.connect(onSpawnAdded)
- Log.i('[*] Enabling spawn gating')
- await device.enableSpawnGating()
- Log.i('[*] Enabled spawn gating')
- // Log.i("[*] Spawning com.google.android.apps.messaging")
- // const pid = await device.spawn("com.google.android.apps.messaging")
- // Log.i("[*] Spawned com.google.android.apps.messaging: " + pid)
- // const tracer = await Tracer.open(pid)
- // tracers.push(tracer)
- }
- async function onSpawnAdded(spawn) {
- try {
- if (spawn.identifier.startsWith('com.google.android.apps.messaging')) {
- Log.i('[*] Tracing', spawn.pid, spawn.identifier)
- const tracer = await Tracer.open(spawn.pid, '../scripts/log_sms.js')
- tracers.push(tracer)
- }
- if (spawn.identifier.startsWith('com.google.android.gms')) {
- Log.i('[*] Tracing', spawn.pid, spawn.identifier)
- const tracer = await Tracer.open(spawn.pid, '../scripts/log_gms.js')
- tracers.push(tracer)
- } else {
- Log.i('[*] Resuming', spawn.pid, spawn.identifier)
- await device.resume(spawn.pid)
- }
- } catch (e) {
- Log.e(`err: ${e}`)
- }
- }
- class Tracer {
- static async open(pid, source) {
- const tracer = new Tracer(pid, source)
- await tracer._initialize()
- return tracer
- }
- constructor(pid, sourceFile) {
- this.pid = pid
- this.sourceFile = sourceFile
- this.source = loadSource(sourceFile)
- this.session = null
- this.script = null
- }
- async _initialize() {
- const session = await device.attach(this.pid)
- this.session = session
- session.detached.connect(this._onSessionDetached.bind(this))
- const script = await session.createScript(this.source)
- this.script = script
- script.message.connect(this._onScriptMessage.bind(this))
- await script.load()
- // const script_ssl = await session.createScript(source_ssl)
- // await script_ssl.load()
- try {
- await device.resume(this.pid)
- } catch (e) {
- Log.e(e)
- }
- }
- async reload() {
- if (this.script) {
- this.script.unload()
- }
- this.source = loadSource(this.sourceFile)
- this.script = await this.session.createScript(this.source)
- this.script.message.connect(this._onScriptMessage.bind(this))
- await this.script.load()
- }
- _onSessionDetached(reason) {
- Log.i(`[PID ${this.pid}] onSessionDetached(reason='${reason}')`)
- const i = tracers.findIndex((tracer) => tracer.pid === this.pid)
- if (i !== -1) {
- tracers.splice(i, 1)
- }
- }
- _onScriptMessage(message, data) {
- if (message.type === 'error') {
- Log.e(`[PID ${this.pid}] onScriptMessage()`, message, data ? JSON.stringify(data) : '')
- } else {
- Log.i(`[PID ${this.pid}] onScriptMessage()`, message, data ? JSON.stringify(data) : '')
- }
- }
- }
- main()
- const vorpal = new Vorpal()
- vorpal.sigint(function () {
- stop()
- })
- vorpal.command('clear [app]').action(async function (args, callback) {
- try {
- const app = args.app
- if ('sms' === app) {
- execSync('adb shell pm clear com.google.android.apps.messaging')
- pushFile('../gson.dex', '/sdcard/Android/data/com.google.android.apps.messaging/')
- } else if ('gms' === app) {
- execSync('adb shell pm clear com.google.android.gms')
- pushFile('../gson.dex', '/sdcard/Android/data/com.google.android.gms/')
- } else if ('gsf' === app) {
- execSync('adb shell pm clear com.google.android.gsf')
- } else if ('all' === app) {
- execSync('adb shell pm clear com.google.android.apps.messaging')
- await setTimeout(1000)
- execSync('adb shell pm clear com.google.android.gms')
- pushFile('../gson.dex', '/sdcard/Android/data/com.google.android.gms/')
- pushFile('../gson.dex', '/sdcard/Android/data/com.google.android.apps.messaging/')
- }
- } catch (error) {
- Log.e(error)
- }
- callback()
- })
- vorpal.command('stop').action(function (args, callback) {
- try {
- execSync('adb shell am force-stop com.google.android.apps.messaging')
- execSync('adb shell am force-stop com.google.android.gms')
- } catch (error) {
- Log.e(error)
- }
- callback()
- })
- vorpal.command('gen').action(function (args, callback) {
- execSync(`node ${path.resolve(__dirname, '../gen.js')}`)
- callback()
- })
- vorpal.command('reload').action(function (args, callback) {
- tracers.forEach((tracer) => {
- tracer.reload()
- })
- callback()
- })
- vorpal.command('otp [code]').action(async function (args, callback) {
- const code = args.code
- let phoneProcess
- try {
- phoneProcess = await device.getProcess('com.android.phone')
- } catch (error) {
- try {
- phoneProcess = await device.getProcess('SIM 卡工具包')
- } catch (error) {}
- }
- if (!phoneProcess) {
- Log.e('Phone process not found')
- callback()
- return
- }
- const session = await device.attach(phoneProcess.pid)
- const script = await session.createScript(
- loadSource('../scripts/sendsms.js')
- .replace('{{sender}}', '3538')
- .replace('{{msg}}', `Your Messenger verification code is G-${code}`)
- )
- script.message.connect((message) => {
- console.log('[*] Message:', message)
- if (message.type === 'send' && message.payload === 'ok') {
- script.unload()
- }
- })
- await script.load()
- callback()
- })
- vorpal.delimiter('rcs$').show()
|