Frida javascript hook 检测设备信息获取等

本文介绍了如何使用Frida进行Android应用的合规检测,包括权限、启动Activity、设备标识、文件操作、系统属性、网络信息、定位、IP地址、剪贴板、IMEI、MAC地址、SSID、OAID、IMSI、SN等的检查,以及部分API的hook实现。
摘要由CSDN通过智能技术生成

在这里插入图片描述

对 Android 应用进行 hook 常见的有 Xposed、Frida 等,Xposed 有时候可能不尽人意,或许您可以试试 Frida ~

frida -U -f com.primer.gamecerter -l hookStartActivity.js

TODO

  • 后续是否可以对检测数据(堆栈、类名、方法名、参数、返回值)进行收集和统计,数据经过进一步处理后格式化输出更好~
/**
 * 时间:2024年2月22日12:17:44
 * 作者:村长
 * 描述:合规检测 hook
 * 
 * 
 * 如何使用:
 *      1、确保设备启动 frida-service
 *          adb shell
 *          su                                      需要 root 设备
 *          cd data/local/tmp/                      firda-service 可执行文件存放位置
 *          ./frida-service*** &                    后台运行
 *          frida -U -f 【包名】 -l 【脚本路径】      注入脚本启动应用 
 * */


//全局配置
var runConfig = {
    "permission": false,
    "startActivity": false,
    "deviceId": true,
    "file": false,
    "ipAddress": false,
    "location": false,
    "other": false,
    "systemProperties": false,
    "packageList": false,
    "enablePrintStackTrace": false,
}


Java.perform(function x() {
    console.log(" --------- 启动检测 ----------");

    if (runConfig.permission) {
        checkPermission();
    }

    if (runConfig.startActivity) {
        checkStartActivity();
    }

    if (runConfig.deviceId) {
        checkAndroidId();
        checkIMEI();
        checkOtherId()
    }

    if (runConfig.file) {
        checkExternalFileRW();
    }

    if (runConfig.ipAddress) {
        checkIPAddress();
    }

    if (runConfig.location) {
        checkLocation();
    }

    if (runConfig.other) {
        checkOther();
    }

    if (runConfig.systemProperties) {
        checkSystemProperties();
    }

    if (runConfig.packageList) {
        checkPackageList();
    }


    console.log(" --------- 结束检测 ----------");
})



///

function log() {
    if (runConfig.enablePrintStackTrace) {
        console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
    }
}




function checkPackageList() {
    console.log("----------- 应用安装列表检查 -----------")

    var ApplicationPackageManager = Java.use("android.app.ApplicationPackageManager")
    ApplicationPackageManager.getInstalledPackages.implementation = function (flags) {
        var list = this.getInstalledPackages(flags)

        console.log("ApplicationPackageManager 获取安装列表 " + list)
        log();
        return list;
    }

    ApplicationPackageManager.getPackageInfo
        .overload('java.lang.String', 'int')
        .implementation = function (pkg, flags) {
            var info = this.getPackageInfo(pkg, flags)

            console.log("ApplicationPackageManager 获取包名信息 " + info)
            log();
            return info;
        }

    ApplicationPackageManager.getPackageInfo
        .overload('android.content.pm.VersionedPackage', 'int')
        .implementation = function (pkg, flags) {
            var info = this.getPackageInfo(pkg, flags)

            console.log("ApplicationPackageManager 获取包名信息 " + info)
            log();
            return info;
        }


    ApplicationPackageManager.getLaunchIntentForPackage.implementation = function (pkg) {
        var intent = this.getLaunchIntentForPackage(pkg)

        console.log("ApplicationPackageManager 获取启动 intent: " + intent)
        log();
        return intent;
    }
}


function checkSystemProperties() {
    console.log("----------- 系统属性检查 -----------")
    var SystemProperties = Java.use("android.os.SystemProperties")
    SystemProperties.get
        .overload('java.lang.String').implementation = function (key) {
            var val = this.get(key)

            console.log("SystemProperties 获取系统属性 " + key + " -> " + val)
            log();
            return val;
        }

    SystemProperties.get
        .overload('java.lang.String', 'java.lang.String').implementation = function (key, def) {
            var val = this.get(key, def)

            console.log("SystemProperties 获取系统属性 " + key + " -> " + val + " " + def)
            log();
            return val;
        }
}



function checkOther() {
    console.log("----------- 剪切板检查 -----------")

    var ClipboardManager = Java.use("android.content.ClipboardManager")
    ClipboardManager.getPrimaryClip.implementation = function () {
        var val = this.getPrimaryClip()

        console.log("ClipboardManager 1 获取短信 " + val)
        log();
        return val;
    }

    ClipboardManager.getPrimaryClipDescription.implementation = function () {
        var val = this.getPrimaryClipDescription()

        console.log("ClipboardManager 1 获取短信 " + val)
        log();
        return val;
    }

    console.log("----------- 网络信息检查 -----------")

    var ConnectivityManager = Java.use("android.net.ConnectivityManager")
    ConnectivityManager.getActiveNetworkInfo.implementation = function () {
        var val = this.getActiveNetworkInfo()

        console.log("ConnectivityManager 获取网络信息 " + val)
        log();
        return val;
    }
}

/**
* 未完善,需要解析 content 判断属于哪一种类型
*/
function checkContentResolve() {

    var ContentResolver = Java.use("android.content.ContentResolver")
    ContentResolver.query
        .overload('android.net.Uri', '[Ljava.lang.String;', 'android.os.Bundle', 'android.os.CancellationSignal')
        .implementation = function (uri, strs, bundle, signal) {
            var val = this.query(uri, strs, bundle, signal)

            console.log("ContentResolver 1 获取短信 " + val)
            log();
            return val;
        }

    ContentResolver.query
        .overload('android.net.Uri', '[Ljava.lang.String;', 'java.lang.String', '[Ljava.lang.String;', 'java.lang.String')
        .implementation = function (uri, strs, str1, strs2, str3) {
            var val = this.query(uri, strs, str1, strs2, str3)

            console.log("ContentResolver 2  获取短信 " + val)
            log();
            return val;
        }

    ContentResolver.query
        .overload('android.net.Uri', '[Ljava.lang.String;', 'java.lang.String', '[Ljava.lang.String;', 'java.lang.String', 'android.os.CancellationSignal')
        .implementation = function (uri, strs1, str2, strs3, str4, signal) {
            var val = this.query(uri, strs1, str2, strs3, str4, signal)

            console.log("ContentResolver 3 获取短信 " + val)
            log();
            return val;
        }
}



function checkLocation() {
    console.log("----------- 定位检查 -----------")

    var LocationManager = Java.use("android.location.LocationManager")
    LocationManager.getLastLocation.implementation = function () {
        var location = this.getLastLocation()

        console.log("LocationManager 获取定位 " + location)
        log();
        return location;
    }

    LocationManager.getLastKnownLocation.implementation = function () {
        var location = this.getLastKnownLocation()

        console.log("LocationManager 获取定位 " + location)
        log();
        return location;
    }
}

function checkIPAddress() {
    console.log("----------- IP 地址检查 -----------")

    var NetworkInterface = Java.use("java.net.NetworkInterface")
    NetworkInterface.getInterfaceAddresses.implementation = function () {
        var addessList = this.getInterfaceAddresses()

        console.log("NetworkInterface 获取 IP 地址 " + addessList)
        log();
        return addessList;
    }

    var Inet4Address = Java.use("java.net.Inet4Address")
    Inet4Address.getHostAddress.implementation = function () {
        var address = this.getHostAddress()

        console.log("Inet4Address 获取主机地址 " + address)
        log();
        return address;
    }

    var Inet6Address = Java.use("java.net.Inet6Address")
    Inet6Address.getHostAddress.implementation = function () {
        var address = this.getHostAddress()

        console.log("Inet6Address 获取主机地址 " + address)
        log();
        return address;
    }
}

function checkExternalFileRW() {
    console.log("----------- 外部文件读写检查 -----------")

    var ContextImpl = Java.use("android.app.ContextImpl")
    ContextImpl.getExternalFilesDirs.implementation = function (type) {
        var files = this.getExternalFilesDirs(type)

        console.log("ContextImpl 获取外部文件目录 " + type)
        log();
        return files;
    }

    ContextImpl.getExternalMediaDirs.implementation = function () {
        var files = this.getExternalMediaDirs()

        console.log("ContextImpl 获取媒体文件目录")
        log();
        return files;
    }

    ContextImpl.getExternalCacheDirs.implementation = function () {
        var files = this.getExternalCacheDirs()

        console.log("ContextImpl 获取缓存目录")
        log();
        return files;
    }



    var Environment = Java.use("android.os.Environment")
    Environment.getExternalStorageDirectory.implementation = function () {
        var file = this.getExternalStorageDirectory()

        console.log("ContextImpl 获取外部存储目录")
        log();
        return file;
    }

}


function checkIMEI() {

    console.log("----------- imei 检查 -----------")

    var TelephonyManager = Java.use("android.telephony.TelephonyManager")

    //getDeviceId    
    TelephonyManager.getDeviceId.overload("int").implementation = function (slotIndex) {
        var iemi = this.getDeviceId(slotIndex)
        console.log("TelephonyManager 获取 IMEI getDeviceId slotIndex = " + slotIndex + "  iemi = " + iemi)
        log();
        return iemi;
    }
    TelephonyManager.getDeviceId.overload().implementation = function () {
        var iemi = this.getDeviceId()
        console.log("TelephonyManager 获取 getDeviceId IMEI = " + iemi)
        log();
        return iemi;
    }

    //getMeid
    TelephonyManager.getMeid.overload("int").implementation = function (slotIndex) {
        var iemi = this.getMeid(slotIndex)
        console.log("TelephonyManager 获取 IMEI getMeid slotIndex = " + slotIndex + "  iemi = " + iemi)
        log();
        return iemi;
    }
    TelephonyManager.getMeid.overload().implementation = function () {
        var iemi = this.getMeid()
        console.log("TelephonyManager 获取 getMeid IMEI = " + iemi)
        log();
        return iemi;
    }


    //getImei
    TelephonyManager.getImei.overload("int").implementation = function (slotIndex) {
        var iemi = this.getImei(slotIndex)
        console.log("TelephonyManager 获取 IMEI getImei slotIndex = " + slotIndex + "  iemi = " + iemi)
        log();
        return iemi;
    }

    TelephonyManager.getImei.overload().implementation = function () {
        var iemi = this.getImei()
        console.log("TelephonyManager 获取 getImei IMEI = " + iemi)
        log();
        return iemi;
    }

}


function checkOtherId() {


    console.log("----------- mac 检查 -----------")

    var NetworkInterface = Java.use("java.net.NetworkInterface")
    NetworkInterface.getHardwareAddress.implementation = function () {
        var mac = this.getHardwareAddress()
        console.log("NetworkInterface 获取 MAC = " + mac)
        log();
        return mac;
    }

    var WifiInfo = Java.use("android.net.wifi.WifiInfo")
    WifiInfo.getMacAddress.implementation = function () {
        var mac = this.getMacAddress()
        console.log("WifiInfo 获取 MAC = " + mac)
        log();
        return mac;
    }

    console.log("----------- SSID 检查 -----------")
    WifiInfo.getSSID.implementation = function () {
        var ssid = this.getSSID()
        console.log("WifiInfo 获取 ssid = " + ssid)
        log();
        return ssid;
    }


    console.log("----------- oaid 检查 -----------")

    var OAID_LIST = ["com.bun.supplier.IdSupplier",
        "com.bun.miitmdid.provider.DefaultProvider",
        "com.bun.miitmdid.supplier.IdSupplier",
        "com.bun.miitmdid.interfaces.IdSupplier"]

    for (let index in OAID_LIST) {
        try {
            var oaid = Java.use(OAID_LIST[index])
            oaid.getOAID.implementation = function () {
                var result = this.getOAID()

                console.log('获取 oaid   = ' + result);
                log();
                return result
            }

        } catch (e) {

        }
    }

    console.log("----------- IMSI 检查 -----------")
    var TelephonyManager = Java.use("android.telephony.TelephonyManager")
    TelephonyManager.getSubscriberId.overload().implementation = function () {
        var imsi = this.getSubscriberId()
        console.log("TelephonyManager 获取 imsi = " + imsi)
        log();
        return imsi;
    }

    TelephonyManager.getSubscriberId.overload('int').implementation = function (index) {
        var imsi = this.getSubscriberId(index)
        console.log("TelephonyManager 获取 1 imsi = " + imsi)
        log();
        return imsi;
    }

    console.log("----------- SN 检查 -----------")
    var Build = Java.use("android.os.Build")
    Build.getSerial.implementation = function () {
        var sn = this.getSerial()
        console.log("TelephonyManager 获取 sn = " + sn)
        log();
        return sn;
    }
}

function checkAndroidId() {
    console.log("----------- android id检查 -----------")

    var ANDROID_ID = "android_id"
    var Secure = Java.use("android.provider.Settings$Secure")
    Secure.getString.implementation = function (resolver, name) {
        var result = this.getString(resolver, name);
        console.log("getString  name = " + name + " val =" + result)
        if (ANDROID_ID == name) {
            console.log("getString 获取 androidID")
            log();
        }
        return result;
    }

    Secure.getStringForUser.implementation = function (resolver, name, userHandle) {
        var result = this.getStringForUser(resolver, name, userHandle);
        console.log("getStringForUser  name = " + name + " val =" + result)
        if (ANDROID_ID == name) {
            console.log("Secure getStringForUser 获取 androidID")
            log();
        }
        return result;
    }

    var SecureSystem = Java.use("android.provider.Settings$System")
    SecureSystem.getStringForUser.implementation = function (resolver, name, userHandle) {
        var result = this.getStringForUser(resolver, name, userHandle);
        console.log("System getStringForUser  name = " + name + " val =" + result)
        if (ANDROID_ID == name) {
            console.log("System getStringForUser 获取 androidID")
            log();
        }

        return result;
    }
}

function checkPermission() {
    console.log("----------- 权限检查 -----------")

    var ActivityCompat = Java.use("android.app.Activity")
    ActivityCompat.requestPermissions.overload("[Ljava.lang.String;", "int")
        .implementation = function (permissions, requestCode) {
            console.log("requestPermissions 2 requestCode = " + requestCode + "  permissions = " + permissions)

            log();
            this.requestPermissions(permissions, requestCode)
        }

    var Fragment = Java.use("android.app.Fragment")
    Fragment.requestPermissions.implementation = function (permissions, code) {
        console.log('权限申请  android permissions = ' + permissions + "  code = " + code);
        log();

        this.requestPermissions(permissions, code)
    }

    var Fragmentx = Java.use("androidx.fragment.app.Fragment")
    Fragmentx.requestPermissions.implementation = function (permissions, code) {
        console.log('权限申请 androidx permissions = ' + permissions + "  code = " + code);
        log();

        this.requestPermissions(permissions, code)
    }
}

function checkStartActivity() {
    console.log("----------- startActivity 检查 -----------")


    var Instrumentation = Java.use('android.app.Instrumentation');
    Instrumentation.execStartActivity
        .overload(
            'android.content.Context',
            'android.os.IBinder',
            'android.os.IBinder',
            'android.app.Activity',
            'android.content.Intent',
            'int',
            'android.os.Bundle')
        .implementation =
        function (
            who, contextThread, token, target, intent, requestCode, options) {
            console.log(
                '【当前应用 1   Instrumentation】 启动 execStartActivity  intent = ' +
                intent);
            var pkg = intent.getPackage()
            console.log('pkg = ' + pkg)
            if (pkg != undefined && pkg != NULL && pkg == 'com.xiaomi.market') {
                intent.setPackage('com.heytap.market')
            }

            log();

            return this.execStartActivity(
                who, contextThread, token, target, intent, requestCode, options);
        }

    Instrumentation.execStartActivity
        .overload(
            'android.content.Context',
            'android.os.IBinder',
            'android.os.IBinder',
            "java.lang.String",
            'android.content.Intent',
            'int',
            'android.os.Bundle')
        .implementation =
        function (
            who, contextThread, token, target, intent, requestCode, options) {
            console.log(
                '【当前应用 2   Instrumentation】 启动 execStartActivity  intent = ' +
                intent);
            var pkg = intent.getPackage()
            console.log('pkg = ' + pkg)
            if (pkg != undefined && pkg != NULL && pkg == 'com.xiaomi.market') {
                intent.setPackage('com.heytap.market')
            }

            log();

            return this.execStartActivity(
                who, contextThread, token, target, intent, requestCode, options);
        }

    Instrumentation.execStartActivity
        .overload(
            'android.content.Context',
            'android.os.IBinder',
            'android.os.IBinder',
            "java.lang.String",
            'android.content.Intent',
            'int',
            'android.os.Bundle',
            "android.os.UserHandle"
        )
        .implementation =
        function (
            who, contextThread, token, resultWho, intent, requestCode, options, user) {
            console.log(
                '【当前应用 3   Instrumentation】 启动 execStartActivity  intent = ' +
                intent);
            var pkg = intent.getPackage()
            console.log('pkg = ' + pkg)
            if (pkg != undefined && pkg != NULL && pkg == 'com.xiaomi.market') {
                intent.setPackage('com.heytap.market')
            }

            log();

            return this.execStartActivity(who, contextThread, token, resultWho, intent, requestCode, options, user)
        }

    Instrumentation.checkStartActivityResult.implementation = function (res, intent) {
        console.log('【checkStartActivityResult 启动  intent = ' + intent);

        log();

        return this.checkStartActivityResult(res, intent)
    }
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值