x1ongzhu 2 years ago
parent
commit
3ae00bcb62
7 changed files with 522 additions and 2 deletions
  1. 2 2
      injects/all.js
  2. 301 0
      injects/log.js
  3. 6 0
      readsdcard.js
  4. 77 0
      scripts/_log_gms.js
  5. 77 0
      scripts/log_gms.js
  6. 59 0
      scripts/log_sms.js
  7. 0 0
      scripts/spoof_sms.js

+ 2 - 2
injects/all.js

@@ -96,7 +96,7 @@ function loadSource(filePath) {
     return replaceVars(fs.readFileSync(path.resolve(__dirname, filePath)).toString())
 }
 
-const source = loadSource('../scripts/spoof1.js')
+const source = loadSource('../scripts/spoof_sms.js')
 const source_gms = loadSource('../scripts/spoof_gms.js')
 const source_ssl = loadSource('../scripts/ssl_bypass.js')
 
@@ -140,7 +140,7 @@ 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/spoof1.js')
+            const tracer = await Tracer.open(spawn.pid, '../scripts/spoof_sms.js')
             tracers.push(tracer)
         }
         if (spawn.identifier.startsWith('com.google.android.gms')) {

+ 301 - 0
injects/log.js

@@ -0,0 +1,301 @@
+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()

+ 6 - 0
readsdcard.js

@@ -0,0 +1,6 @@
+Java.perform(() => {
+    const ActivityThread = Java.use('android.app.ActivityThread')
+    const app = ActivityThread.currentApplication()
+
+    console.log('Application:', app)
+})

+ 77 - 0
scripts/_log_gms.js

@@ -0,0 +1,77 @@
+const mcc = '255'
+const mnc = '06'
+const simOperator = '25506'
+const networkOperator = '25506'
+const simSerialNumber = '52463878170561652433'
+const iccId = '52463878170561652433'
+const number = '739727133'
+const imei = '352260057378931'
+const imsi = '255064887029478'
+const countryIso = 'ua'
+const subId = '59'
+const androidId = '50b4577c46ef5e96'
+const serialNumber = '1955b056'
+
+function trace(tag) {
+    Log.e((tag || '') + Java.use('android.util.Log').getStackTraceString(Java.use('java.lang.Throwable').$new()))
+}
+
+function dump(obj) {
+    try {
+        const gson = Java.use('com.google.gson.Gson').$new()
+        const json = gson.toJson(obj)
+        return json
+    } catch (error) {
+        return ''
+    }
+}
+
+function dumpJson(obj) {
+    try {
+        const gson = Java.use('com.google.gson.Gson').$new()
+        const json = gson.toJson(obj)
+        return JSON.parse(json)
+    } catch (error) {
+        return ''
+    }
+}
+
+class Log {
+    static TAG = '[GMS]'
+    static Debug = false
+    static format(...msg) {
+        let m = []
+        for (let i = 0; i < msg.length; i++) {
+            if (typeof msg[i] === 'object') {
+                m.push(msg[i] + '')
+            } else {
+                m.push(msg[i])
+            }
+        }
+        m = m.join(' ')
+        return m
+    }
+    static i(...msg) {
+        if (!this.Debug) return
+        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`)
+    }
+}
+
+Java.perform(function () {
+    try {
+        const GsonClass = Java.openClassFile('/sdcard/Android/data/com.google.android.gms/gson.dex')
+        GsonClass.load()
+        Log.s('gson class loaded')
+    } catch (error) {
+        Log.e('load gson error', error)
+    }
+})

+ 77 - 0
scripts/log_gms.js

@@ -0,0 +1,77 @@
+const mcc = '{{mcc}}'
+const mnc = '{{mnc}}'
+const simOperator = '{{simOperator}}'
+const networkOperator = '{{networkOperator}}'
+const simSerialNumber = '{{simSerialNumber}}'
+const iccId = '{{iccId}}'
+const number = '{{number}}'
+const imei = '{{imei}}'
+const imsi = '{{imsi}}'
+const countryIso = '{{countryIso}}'
+const subId = '{{subId}}'
+const androidId = '{{androidId}}'
+const serialNumber = '{{serialNumber}}'
+
+function trace(tag) {
+    Log.e((tag || '') + Java.use('android.util.Log').getStackTraceString(Java.use('java.lang.Throwable').$new()))
+}
+
+function dump(obj) {
+    try {
+        const gson = Java.use('com.google.gson.Gson').$new()
+        const json = gson.toJson(obj)
+        return json
+    } catch (error) {
+        return ''
+    }
+}
+
+function dumpJson(obj) {
+    try {
+        const gson = Java.use('com.google.gson.Gson').$new()
+        const json = gson.toJson(obj)
+        return JSON.parse(json)
+    } catch (error) {
+        return ''
+    }
+}
+
+class Log {
+    static TAG = '[GMS]'
+    static Debug = false
+    static format(...msg) {
+        let m = []
+        for (let i = 0; i < msg.length; i++) {
+            if (typeof msg[i] === 'object') {
+                m.push(msg[i] + '')
+            } else {
+                m.push(msg[i])
+            }
+        }
+        m = m.join(' ')
+        return m
+    }
+    static i(...msg) {
+        if (!this.Debug) return
+        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`)
+    }
+}
+
+Java.perform(function () {
+    try {
+        const GsonClass = Java.openClassFile('/sdcard/Android/data/com.google.android.gms/gson.dex')
+        GsonClass.load()
+        Log.s('gson class loaded')
+    } catch (error) {
+        Log.e('load gson error', error)
+    }
+})

+ 59 - 0
scripts/log_sms.js

@@ -0,0 +1,59 @@
+const mcc = '{{mcc}}'
+const mnc = '{{mnc}}'
+const simOperator = '{{simOperator}}'
+const networkOperator = '{{networkOperator}}'
+const simSerialNumber = '{{simSerialNumber}}'
+const iccId = '{{iccId}}'
+const number = '{{number}}'
+const imei = '{{imei}}'
+const imsi = '{{imsi}}'
+const countryIso = '{{countryIso}}'
+const subId = '{{subId}}'
+
+class Log {
+    static TAG = '[SMS]'
+    static Debug = true
+    static format(...msg) {
+        let m = []
+        for (let i = 0; i < msg.length; i++) {
+            if (typeof msg[i] === 'object') {
+                m.push(JSON.stringify(msg[i]))
+            } else {
+                m.push(msg[i])
+            }
+        }
+        m = m.join(' ')
+        return m
+    }
+    static i(...msg) {
+        if (!this.Debug) return
+        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 trace(tag) {
+    Log.e((tag || '') + Java.use('android.util.Log').getStackTraceString(Java.use('java.lang.Throwable').$new()))
+}
+
+setImmediate(() => {
+    Java.perform(function () {
+        const biyg = Java.use('biyg')
+        biyg.al.overload('int').implementation = function (a) {
+            const res = this.al(a)
+            Log.w(`biyg.al(${a}) => ${res}`)
+            if ('Config document received' === res) {
+                trace('biyg.al')
+            }
+            return this.al(a)
+        }
+    })
+})

+ 0 - 0
scripts/spoof1.js → scripts/spoof_sms.js