| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- 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"
- 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 = path.resolve(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/")
- 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/spoof1.js")
- const source_gms = loadSource("../scripts/spoof_gms.js")
- const source_ssl = loadSource("../scripts/ssl_bypass.js")
- fs.writeFileSync("scripts/_spoof.js", source)
- fs.writeFileSync("scripts/_spoof_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,
- loadSource("../scripts/spoof1.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,
- loadSource("../scripts/spoof_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, source) {
- this.pid = pid
- this.source = source
- 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)
- }
- }
- _onSessionDetached(reason) {
- Log.w(`[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(function (args, callback) {
- try {
- const app = args.app
- if ("sms" === app) {
- execSync("adb shell pm clear 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") {
- execSync("adb shell pm clear com.google.android.gsf")
- } else if ("all" === app) {
- execSync("adb shell pm clear com.google.android.apps.messaging")
- execSync("adb shell pm clear com.google.android.gms")
- pushFile(
- "../gson.dex",
- "/sdcard/Android/data/com.google.android.gms/"
- )
- }
- } 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.delimiter("rcs$").show()
|