// Runtime Secret Extractor — SharedPreferences, SQLite queries, crypto keys, JWT
// Usage: frida -U -f com.target.app -l extract-secrets.js --no-pause

Java.perform(function() {
    // --- SharedPreferences ---
    try {
        var SharedPreferencesImpl = Java.use('android.app.SharedPreferencesImpl');
        SharedPreferencesImpl.getString.implementation = function(key, defVal) {
            var val = this.getString(key, defVal);
            if (val && val.length > 0) console.log('[SharedPrefs] ' + key + ' = ' + val);
            return val;
        };
        SharedPreferencesImpl.getInt.implementation = function(key, defVal) {
            var val = this.getInt(key, defVal);
            console.log('[SharedPrefs:int] ' + key + ' = ' + val);
            return val;
        };
    } catch(e) {}

    // --- Crypto key material ---
    try {
        var SecretKeySpec = Java.use('javax.crypto.spec.SecretKeySpec');
        SecretKeySpec.$init.overload('[B', 'java.lang.String').implementation = function(key, algo) {
            var hexKey = Array.from(key, function(b) { return ('0' + (b & 0xff).toString(16)).slice(-2); }).join('');
            console.log('[CRYPTO KEY] algo=' + algo + ' key(hex)=' + hexKey);
            return this.$init(key, algo);
        };
    } catch(e) {}

    // --- Cipher init — IV + key ---
    try {
        var Cipher = Java.use('javax.crypto.Cipher');
        Cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec').implementation = function(mode, key, params) {
            var modeStr = mode === 1 ? 'ENCRYPT' : mode === 2 ? 'DECRYPT' : 'mode=' + mode;
            console.log('[CIPHER] ' + modeStr + ' algo=' + key.getAlgorithm());
            return this.init(mode, key, params);
        };
    } catch(e) {}

    // --- SQLiteDatabase queries ---
    try {
        var SQLiteDatabase = Java.use('android.database.sqlite.SQLiteDatabase');
        SQLiteDatabase.rawQuery.overload('java.lang.String', '[Ljava.lang.String;').implementation = function(sql, args) {
            console.log('[SQLite] ' + sql);
            return this.rawQuery(sql, args);
        };
        SQLiteDatabase.execSQL.overload('java.lang.String').implementation = function(sql) {
            console.log('[SQLite execSQL] ' + sql);
            return this.execSQL(sql);
        };
    } catch(e) {}

    // --- JWT/Base64 encoded tokens ---
    try {
        var Base64 = Java.use('android.util.Base64');
        Base64.decode.overload('java.lang.String', 'int').implementation = function(str, flags) {
            if (str && str.startsWith('ey')) console.log('[JWT TOKEN] ' + str);
            return this.decode(str, flags);
        };
    } catch(e) {}

    // --- Authorization headers ---
    try {
        var Headers = Java.use('okhttp3.Headers');
        Headers.get.overload('java.lang.String').implementation = function(name) {
            var val = this.get(name);
            if (name.toLowerCase() === 'authorization' && val) {
                console.log('[AUTH HEADER] ' + val);
            }
            return val;
        };
    } catch(e) {}

    console.log('[RTExit] Secret extractor loaded.');
});
