发布于

Frida 实战案例分析:真实场景下的动态分析应用

作者

Frida 实战案例分析:真实场景下的动态分析应用

本文将通过多个真实案例,展示 Frida 在不同场景下的实际应用,包括移动应用安全分析、API 逆向工程、网络协议分析等。

案例一:移动应用登录绕过

场景描述

某移动应用使用复杂的登录验证机制,包括用户名密码验证、设备指纹检查和服务器端验证。我们需要分析其登录流程并实现绕过。

# login_bypass_analysis.py - 登录绕过分析
import frida
import sys
import json
import time

class LoginBypassAnalyzer:
    def __init__(self, package_name):
        self.package_name = package_name
        self.device = None
        self.session = None
        self.script = None
        self.login_data = {}
    
    def connect_and_spawn(self):
        """连接设备并启动应用"""
        try:
            self.device = frida.get_usb_device()
            pid = self.device.spawn([self.package_name])
            self.session = self.device.attach(pid)
            
            # 加载分析脚本
            script_content = self.get_login_analysis_script()
            self.script = self.session.create_script(script_content)
            self.script.on('message', self.on_message)
            self.script.load()
            
            # 恢复应用执行
            self.device.resume(pid)
            
            print(f"[+] Analysis started for {self.package_name}")
            return True
            
        except Exception as e:
            print(f"[-] Failed to start analysis: {e}")
            return False
    
    def on_message(self, message, data):
        """处理脚本消息"""
        if message['type'] == 'send':
            payload = message['payload']
            
            if payload.get('type') == 'login_attempt':
                self.handle_login_attempt(payload)
            elif payload.get('type') == 'network_request':
                self.handle_network_request(payload)
            elif payload.get('type') == 'crypto_operation':
                self.handle_crypto_operation(payload)
            else:
                print(f"[Info] {payload}")
        elif message['type'] == 'error':
            print(f"[Error] {message['stack']}")
    
    def handle_login_attempt(self, data):
        """处理登录尝试"""
        print(f"\n[Login Attempt]")
        print(f"Username: {data.get('username', 'N/A')}")
        print(f"Password: {'*' * len(data.get('password', ''))}")
        print(f"Method: {data.get('method', 'N/A')}")
        print(f"Result: {data.get('result', 'N/A')}")
        
        self.login_data['attempts'] = self.login_data.get('attempts', [])
        self.login_data['attempts'].append(data)
    
    def handle_network_request(self, data):
        """处理网络请求"""
        print(f"\n[Network Request]")
        print(f"URL: {data.get('url', 'N/A')}")
        print(f"Method: {data.get('method', 'N/A')}")
        print(f"Headers: {json.dumps(data.get('headers', {}), indent=2)}")
        
        if data.get('body'):
            print(f"Body: {data['body'][:200]}...")
    
    def handle_crypto_operation(self, data):
        """处理加密操作"""
        print(f"\n[Crypto Operation]")
        print(f"Algorithm: {data.get('algorithm', 'N/A')}")
        print(f"Operation: {data.get('operation', 'N/A')}")
        print(f"Input Length: {data.get('input_length', 0)}")
        print(f"Output Length: {data.get('output_length', 0)}")
    
    def get_login_analysis_script(self):
        """获取登录分析脚本"""
        return """
        Java.perform(function() {
            console.log("[+] Login analysis script loaded");
            
            // 1. Hook 登录相关方法
            hookLoginMethods();
            
            // 2. Hook 网络请求
            hookNetworkRequests();
            
            // 3. Hook 加密操作
            hookCryptographicOperations();
            
            // 4. Hook 设备指纹
            hookDeviceFingerprinting();
            
            // 5. Hook 存储操作
            hookStorageOperations();
        });
        
        function hookLoginMethods() {
            try {
                // 通用登录方法模式
                var loginPatterns = [
                    "login", "signin", "authenticate", "verify", "check"
                ];
                
                // 枚举所有类并查找登录相关方法
                Java.enumerateLoadedClasses({
                    onMatch: function(className) {
                        if (className.indexOf("com.example.app") !== -1) {
                            try {
                                var targetClass = Java.use(className);
                                var methods = targetClass.class.getDeclaredMethods();
                                
                                for (var i = 0; i < methods.length; i++) {
                                    var method = methods[i];
                                    var methodName = method.getName().toLowerCase();
                                    
                                    // 检查是否为登录相关方法
                                    for (var j = 0; j < loginPatterns.length; j++) {
                                        if (methodName.indexOf(loginPatterns[j]) !== -1) {
                                            hookLoginMethod(targetClass, method.getName());
                                        }
                                    }
                                }
                            } catch (e) {
                                // 忽略无法访问的类
                            }
                        }
                    },
                    onComplete: function() {
                        console.log("[+] Login method enumeration completed");
                    }
                });
                
                // Hook 常见的登录方法
                hookSpecificLoginMethods();
                
            } catch (e) {
                console.log("[-] Failed to hook login methods: " + e);
            }
        }
        
        function hookLoginMethod(targetClass, methodName) {
            try {
                var overloads = targetClass[methodName].overloads;
                
                for (var i = 0; i < overloads.length; i++) {
                    overloads[i].implementation = function() {
                        console.log("[Login] Method called: " + methodName);
                        
                        // 记录参数
                        var args = Array.prototype.slice.call(arguments);
                        var loginData = {
                            type: 'login_attempt',
                            method: methodName,
                            arguments: args.map(function(arg) {
                                return arg ? arg.toString() : 'null';
                            })
                        };
                        
                        // 尝试提取用户名和密码
                        for (var j = 0; j < args.length; j++) {
                            var arg = args[j];
                            if (arg && typeof arg.toString === 'function') {
                                var argStr = arg.toString();
                                if (argStr.indexOf('@') !== -1 || argStr.length > 3) {
                                    if (!loginData.username && argStr.indexOf('@') !== -1) {
                                        loginData.username = argStr;
                                    } else if (!loginData.password && argStr.length >= 6) {
                                        loginData.password = argStr;
                                    }
                                }
                            }
                        }
                        
                        // 调用原始方法
                        var result = this[methodName].apply(this, arguments);
                        loginData.result = result ? result.toString() : 'null';
                        
                        send(loginData);
                        
                        // 尝试绕过:如果返回 false,改为返回 true
                        if (result === false || result === 0) {
                            console.log("[+] Login bypass: changing result to true");
                            return true;
                        }
                        
                        return result;
                    };
                }
                
                console.log("[+] Hooked login method: " + methodName);
                
            } catch (e) {
                console.log("[-] Failed to hook method " + methodName + ": " + e);
            }
        }
        
        function hookSpecificLoginMethods() {
            try {
                // Hook 常见的认证类
                var authClasses = [
                    "com.example.app.auth.AuthManager",
                    "com.example.app.login.LoginManager",
                    "com.example.app.user.UserManager"
                ];
                
                authClasses.forEach(function(className) {
                    try {
                        var AuthClass = Java.use(className);
                        
                        // Hook 所有公共方法
                        var methods = AuthClass.class.getDeclaredMethods();
                        for (var i = 0; i < methods.length; i++) {
                            var method = methods[i];
                            if ((method.getModifiers() & 1) !== 0) { // 公共方法
                                hookLoginMethod(AuthClass, method.getName());
                            }
                        }
                        
                    } catch (e) {
                        // 类不存在,继续
                    }
                });
                
            } catch (e) {
                console.log("[-] Failed to hook specific login methods: " + e);
            }
        }
        
        function hookNetworkRequests() {
            try {
                // Hook OkHttp
                var OkHttpClient = Java.use("okhttp3.OkHttpClient");
                var Request = Java.use("okhttp3.Request");
                
                OkHttpClient.newCall.implementation = function(request) {
                    var url = request.url().toString();
                    var method = request.method();
                    
                    // 检查是否为登录相关请求
                    if (url.indexOf("login") !== -1 || 
                        url.indexOf("auth") !== -1 || 
                        url.indexOf("signin") !== -1) {
                        
                        var headers = {};
                        var headerNames = request.headers().names();
                        var iterator = headerNames.iterator();
                        
                        while (iterator.hasNext()) {
                            var name = iterator.next();
                            headers[name] = request.headers().get(name);
                        }
                        
                        var requestData = {
                            type: 'network_request',
                            url: url,
                            method: method,
                            headers: headers
                        };
                        
                        // 尝试获取请求体
                        try {
                            var body = request.body();
                            if (body) {
                                // 这里需要更复杂的逻辑来读取请求体
                                requestData.body = "[Request Body Present]";
                            }
                        } catch (e) {
                            // 无法读取请求体
                        }
                        
                        send(requestData);
                    }
                    
                    return this.newCall(request);
                };
                
                // Hook HttpURLConnection
                var HttpURLConnection = Java.use("java.net.HttpURLConnection");
                
                HttpURLConnection.getResponseCode.implementation = function() {
                    var url = this.getURL().toString();
                    var responseCode = this.getResponseCode();
                    
                    if (url.indexOf("login") !== -1 || url.indexOf("auth") !== -1) {
                        console.log("[Network] Login response: " + responseCode + " for " + url);
                        
                        // 如果是认证失败,尝试修改为成功
                        if (responseCode === 401 || responseCode === 403) {
                            console.log("[+] Network bypass: changing response code to 200");
                            return 200;
                        }
                    }
                    
                    return responseCode;
                };
                
                console.log("[+] Network request hooks installed");
                
            } catch (e) {
                console.log("[-] Failed to hook network requests: " + e);
            }
        }
        
        function hookCryptographicOperations() {
            try {
                // Hook Cipher
                var Cipher = Java.use("javax.crypto.Cipher");
                
                Cipher.doFinal.overload('[B').implementation = function(input) {
                    var algorithm = this.getAlgorithm();
                    var result = this.doFinal(input);
                    
                    send({
                        type: 'crypto_operation',
                        algorithm: algorithm,
                        operation: 'doFinal',
                        input_length: input.length,
                        output_length: result.length
                    });
                    
                    return result;
                };
                
                // Hook MessageDigest
                var MessageDigest = Java.use("java.security.MessageDigest");
                
                MessageDigest.digest.overload('[B').implementation = function(input) {
                    var algorithm = this.getAlgorithm();
                    var result = this.digest(input);
                    
                    send({
                        type: 'crypto_operation',
                        algorithm: algorithm,
                        operation: 'digest',
                        input_length: input.length,
                        output_length: result.length
                    });
                    
                    return result;
                };
                
                console.log("[+] Cryptographic operation hooks installed");
                
            } catch (e) {
                console.log("[-] Failed to hook cryptographic operations: " + e);
            }
        }
        
        function hookDeviceFingerprinting() {
            try {
                // Hook 设备信息获取
                var TelephonyManager = Java.use("android.telephony.TelephonyManager");
                var Settings = Java.use("android.provider.Settings$Secure");
                var Build = Java.use("android.os.Build");
                
                // Hook IMEI 获取
                TelephonyManager.getDeviceId.implementation = function() {
                    console.log("[Device] IMEI requested");
                    var result = this.getDeviceId();
                    
                    // 可以返回固定值来绕过设备检查
                    return result;
                };
                
                // Hook Android ID 获取
                Settings.getString.implementation = function(resolver, name) {
                    var result = this.getString(resolver, name);
                    
                    if (name === "android_id") {
                        console.log("[Device] Android ID requested: " + result);
                    }
                    
                    return result;
                };
                
                console.log("[+] Device fingerprinting hooks installed");
                
            } catch (e) {
                console.log("[-] Failed to hook device fingerprinting: " + e);
            }
        }
        
        function hookStorageOperations() {
            try {
                // Hook SharedPreferences
                var SharedPreferences = Java.use("android.content.SharedPreferences");
                var Editor = Java.use("android.content.SharedPreferences$Editor");
                
                SharedPreferences.getBoolean.implementation = function(key, defValue) {
                    var result = this.getBoolean(key, defValue);
                    
                    // 检查登录状态相关的键
                    if (key.indexOf("login") !== -1 || 
                        key.indexOf("auth") !== -1 || 
                        key.indexOf("logged") !== -1) {
                        console.log("[Storage] Login state check: " + key + " = " + result);
                        
                        // 强制返回已登录状态
                        if (key.indexOf("logged_in") !== -1 || key.indexOf("is_login") !== -1) {
                            console.log("[+] Storage bypass: forcing login state to true");
                            return true;
                        }
                    }
                    
                    return result;
                };
                
                SharedPreferences.getString.implementation = function(key, defValue) {
                    var result = this.getString(key, defValue);
                    
                    if (key.indexOf("token") !== -1 || key.indexOf("session") !== -1) {
                        console.log("[Storage] Token/Session access: " + key);
                    }
                    
                    return result;
                };
                
                console.log("[+] Storage operation hooks installed");
                
            } catch (e) {
                console.log("[-] Failed to hook storage operations: " + e);
            }
        }
        """
    
    def generate_bypass_script(self):
        """生成绕过脚本"""
        bypass_script = """
        Java.perform(function() {
            console.log("[+] Login bypass script loaded");
            
            // 基于分析结果的绕过策略
            implementLoginBypass();
        });
        
        function implementLoginBypass() {
            try {
                // 1. 强制登录成功
                forceLoginSuccess();
                
                // 2. 绕过设备检查
                bypassDeviceCheck();
                
                // 3. 修改网络响应
                modifyNetworkResponse();
                
                // 4. 修改存储状态
                modifyStorageState();
                
            } catch (e) {
                console.log("[-] Bypass implementation failed: " + e);
            }
        }
        
        function forceLoginSuccess() {
            // 根据分析结果实现具体的绕过逻辑
            console.log("[+] Login bypass strategies implemented");
        }
        
        function bypassDeviceCheck() {
            // 设备检查绕过
            console.log("[+] Device check bypass implemented");
        }
        
        function modifyNetworkResponse() {
            // 网络响应修改
            console.log("[+] Network response modification implemented");
        }
        
        function modifyStorageState() {
            // 存储状态修改
            console.log("[+] Storage state modification implemented");
        }
        """
        
        return bypass_script
    
    def cleanup(self):
        """清理资源"""
        if self.script:
            self.script.unload()
        if self.session:
            self.session.detach()

# 使用示例
def main():
    if len(sys.argv) != 2:
        print("Usage: python login_bypass_analysis.py <package_name>")
        return
    
    package_name = sys.argv[1]
    analyzer = LoginBypassAnalyzer(package_name)
    
    if analyzer.connect_and_spawn():
        print("[+] Analysis running. Perform login attempts in the app.")
        print("[+] Press Enter to generate bypass script and exit")
        input()
        
        # 生成绕过脚本
        bypass_script = analyzer.generate_bypass_script()
        with open(f"bypass_script_{package_name}.js", 'w') as f:
            f.write(bypass_script)
        
        print(f"[+] Bypass script saved to bypass_script_{package_name}.js")
    
    analyzer.cleanup()

if __name__ == "__main__":
    main()

案例二:API 接口逆向分析

场景描述

某应用使用自定义的 API 协议,包含加密、签名验证等机制。我们需要逆向分析其 API 调用流程和参数构造方法。

// api_reverse_analysis.js - API 逆向分析脚本
Java.perform(function() {
    console.log("[+] API reverse analysis script loaded");
    
    // 1. Hook 网络库
    hookNetworkLibraries();
    
    // 2. Hook 加密算法
    hookEncryptionAlgorithms();
    
    // 3. Hook 签名生成
    hookSignatureGeneration();
    
    // 4. Hook JSON 处理
    hookJsonProcessing();
    
    // 5. Hook Base64 编码
    hookBase64Operations();
});

function hookNetworkLibraries() {
    try {
        // Hook Retrofit (如果使用)
        hookRetrofit();
        
        // Hook Volley (如果使用)
        hookVolley();
        
        // Hook 原生 HTTP 客户端
        hookNativeHttpClient();
        
    } catch (e) {
        console.log("[-] Failed to hook network libraries: " + e);
    }
}

function hookRetrofit() {
    try {
        // 查找 Retrofit 相关类
        Java.enumerateLoadedClasses({
            onMatch: function(className) {
                if (className.indexOf("retrofit") !== -1) {
                    console.log("[Retrofit] Found class: " + className);
                    
                    try {
                        var RetrofitClass = Java.use(className);
                        
                        // Hook create 方法
                        if (RetrofitClass.create) {
                            RetrofitClass.create.implementation = function(service) {
                                console.log("[Retrofit] Creating service: " + service);
                                var result = this.create(service);
                                
                                // Hook 服务方法
                                hookServiceMethods(result, service);
                                
                                return result;
                            };
                        }
                        
                    } catch (e) {
                        // 忽略无法访问的类
                    }
                }
            },
            onComplete: function() {
                console.log("[+] Retrofit enumeration completed");
            }
        });
        
    } catch (e) {
        console.log("[-] Failed to hook Retrofit: " + e);
    }
}

function hookServiceMethods(serviceInstance, serviceClass) {
    try {
        var methods = serviceClass.getDeclaredMethods();
        
        for (var i = 0; i < methods.length; i++) {
            var method = methods[i];
            var methodName = method.getName();
            
            // Hook API 方法
            if (serviceInstance[methodName]) {
                serviceInstance[methodName].implementation = function() {
                    console.log("[API] Calling method: " + methodName);
                    console.log("[API] Arguments: " + JSON.stringify(Array.prototype.slice.call(arguments)));
                    
                    var result = this[methodName].apply(this, arguments);
                    console.log("[API] Result: " + result);
                    
                    return result;
                };
            }
        }
        
    } catch (e) {
        console.log("[-] Failed to hook service methods: " + e);
    }
}

function hookVolley() {
    try {
        var RequestQueue = Java.use("com.android.volley.RequestQueue");
        
        RequestQueue.add.implementation = function(request) {
            console.log("[Volley] Adding request: " + request);
            
            // 获取请求详情
            try {
                var url = request.getUrl();
                var method = request.getMethod();
                var headers = request.getHeaders();
                
                console.log("[Volley] URL: " + url);
                console.log("[Volley] Method: " + method);
                console.log("[Volley] Headers: " + JSON.stringify(headers));
                
                // 尝试获取请求体
                var body = request.getBody();
                if (body) {
                    var bodyStr = Java.use("java.lang.String").$new(body);
                    console.log("[Volley] Body: " + bodyStr);
                }
                
            } catch (e) {
                console.log("[-] Failed to get request details: " + e);
            }
            
            return this.add(request);
        };
        
    } catch (e) {
        console.log("[-] Failed to hook Volley: " + e);
    }
}

function hookNativeHttpClient() {
    try {
        var HttpURLConnection = Java.use("java.net.HttpURLConnection");
        
        // Hook connect 方法
        HttpURLConnection.connect.implementation = function() {
            var url = this.getURL().toString();
            var method = this.getRequestMethod();
            
            console.log("[HTTP] Connecting to: " + url);
            console.log("[HTTP] Method: " + method);
            
            // 获取请求头
            var headerFields = this.getRequestProperties();
            if (headerFields) {
                console.log("[HTTP] Request headers:");
                var keySet = headerFields.keySet();
                var iterator = keySet.iterator();
                
                while (iterator.hasNext()) {
                    var key = iterator.next();
                    var values = headerFields.get(key);
                    console.log("  " + key + ": " + values);
                }
            }
            
            this.connect();
        };
        
        // Hook getInputStream
        HttpURLConnection.getInputStream.implementation = function() {
            var url = this.getURL().toString();
            var responseCode = this.getResponseCode();
            
            console.log("[HTTP] Response from " + url + ": " + responseCode);
            
            var inputStream = this.getInputStream();
            
            // 包装 InputStream 以读取响应内容
            return wrapInputStream(inputStream, url);
        };
        
    } catch (e) {
        console.log("[-] Failed to hook native HTTP client: " + e);
    }
}

function wrapInputStream(originalStream, url) {
    try {
        var InputStreamWrapper = Java.registerClass({
            name: 'com.frida.InputStreamWrapper',
            superClass: Java.use('java.io.InputStream'),
            fields: {
                originalStream: 'java.io.InputStream',
                buffer: 'java.io.ByteArrayOutputStream'
            },
            methods: {
                $init: {
                    returnType: 'void',
                    argumentTypes: ['java.io.InputStream'],
                    implementation: function(stream) {
                        this.originalStream.value = stream;
                        this.buffer.value = Java.use('java.io.ByteArrayOutputStream').$new();
                    }
                },
                read: {
                    returnType: 'int',
                    argumentTypes: [],
                    implementation: function() {
                        var data = this.originalStream.value.read();
                        if (data !== -1) {
                            this.buffer.value.write(data);
                        } else {
                            // 流结束,打印内容
                            var content = this.buffer.value.toString();
                            console.log("[HTTP] Response content from " + url + ":");
                            console.log(content);
                        }
                        return data;
                    }
                }
            }
        });
        
        return InputStreamWrapper.$new(originalStream);
        
    } catch (e) {
        console.log("[-] Failed to wrap InputStream: " + e);
        return originalStream;
    }
}

function hookEncryptionAlgorithms() {
    try {
        // Hook AES 加密
        var Cipher = Java.use("javax.crypto.Cipher");
        
        Cipher.doFinal.overload('[B').implementation = function(input) {
            var algorithm = this.getAlgorithm();
            var mode = this.getOpmode();
            
            console.log("[Crypto] Algorithm: " + algorithm);
            console.log("[Crypto] Mode: " + (mode === 1 ? "ENCRYPT" : "DECRYPT"));
            console.log("[Crypto] Input: " + bytesToHex(input));
            
            var result = this.doFinal(input);
            console.log("[Crypto] Output: " + bytesToHex(result));
            
            return result;
        };
        
        // Hook 密钥生成
        var KeyGenerator = Java.use("javax.crypto.KeyGenerator");
        
        KeyGenerator.generateKey.implementation = function() {
            var algorithm = this.getAlgorithm();
            console.log("[Crypto] Generating key for: " + algorithm);
            
            var key = this.generateKey();
            
            // 尝试获取密钥内容
            try {
                var encoded = key.getEncoded();
                console.log("[Crypto] Generated key: " + bytesToHex(encoded));
            } catch (e) {
                console.log("[Crypto] Cannot access key content");
            }
            
            return key;
        };
        
    } catch (e) {
        console.log("[-] Failed to hook encryption algorithms: " + e);
    }
}

function hookSignatureGeneration() {
    try {
        // Hook HMAC 签名
        var Mac = Java.use("javax.crypto.Mac");
        
        Mac.doFinal.overload('[B').implementation = function(input) {
            var algorithm = this.getAlgorithm();
            console.log("[Signature] Algorithm: " + algorithm);
            console.log("[Signature] Input: " + bytesToHex(input));
            
            var result = this.doFinal(input);
            console.log("[Signature] Signature: " + bytesToHex(result));
            
            return result;
        };
        
        // Hook 数字签名
        var Signature = Java.use("java.security.Signature");
        
        Signature.sign.implementation = function() {
            var algorithm = this.getAlgorithm();
            console.log("[DigitalSignature] Algorithm: " + algorithm);
            
            var result = this.sign();
            console.log("[DigitalSignature] Signature: " + bytesToHex(result));
            
            return result;
        };
        
    } catch (e) {
        console.log("[-] Failed to hook signature generation: " + e);
    }
}

function hookJsonProcessing() {
    try {
        // Hook Gson
        var Gson = Java.use("com.google.gson.Gson");
        
        Gson.toJson.overload('java.lang.Object').implementation = function(obj) {
            var result = this.toJson(obj);
            console.log("[JSON] Serializing object to JSON: " + result);
            return result;
        };
        
        Gson.fromJson.overload('java.lang.String', 'java.lang.Class').implementation = function(json, classOfT) {
            console.log("[JSON] Deserializing JSON: " + json);
            var result = this.fromJson(json, classOfT);
            console.log("[JSON] Deserialized to: " + classOfT.getName());
            return result;
        };
        
        // Hook JSONObject
        var JSONObject = Java.use("org.json.JSONObject");
        
        JSONObject.$init.overload('java.lang.String').implementation = function(json) {
            console.log("[JSONObject] Creating from string: " + json);
            this.$init(json);
        };
        
        JSONObject.toString.implementation = function() {
            var result = this.toString();
            console.log("[JSONObject] Converting to string: " + result);
            return result;
        };
        
    } catch (e) {
        console.log("[-] Failed to hook JSON processing: " + e);
    }
}

function hookBase64Operations() {
    try {
        var Base64 = Java.use("android.util.Base64");
        
        // Hook encode
        Base64.encode.overload('[B', 'int').implementation = function(input, flags) {
            console.log("[Base64] Encoding: " + bytesToHex(input));
            var result = this.encode(input, flags);
            console.log("[Base64] Encoded: " + Java.use("java.lang.String").$new(result));
            return result;
        };
        
        // Hook decode
        Base64.decode.overload('java.lang.String', 'int').implementation = function(str, flags) {
            console.log("[Base64] Decoding: " + str);
            var result = this.decode(str, flags);
            console.log("[Base64] Decoded: " + bytesToHex(result));
            return result;
        };
        
    } catch (e) {
        console.log("[-] Failed to hook Base64 operations: " + e);
    }
}

// 辅助函数
function bytesToHex(bytes) {
    var hex = "";
    for (var i = 0; i < bytes.length; i++) {
        var byte = bytes[i] & 0xFF;
        hex += ("0" + byte.toString(16)).slice(-2);
    }
    return hex.toUpperCase();
}

function hexToBytes(hex) {
    var bytes = [];
    for (var i = 0; i < hex.length; i += 2) {
        bytes.push(parseInt(hex.substr(i, 2), 16));
    }
    return bytes;
}

// API 重放功能
function replayApiCall(url, method, headers, body) {
    Java.perform(function() {
        try {
            var URL = Java.use("java.net.URL");
            var HttpURLConnection = Java.use("java.net.HttpURLConnection");
            
            var urlObj = URL.$new(url);
            var connection = urlObj.openConnection();
            
            connection.setRequestMethod(method);
            
            // 设置请求头
            for (var key in headers) {
                connection.setRequestProperty(key, headers[key]);
            }
            
            // 设置请求体
            if (body && method !== "GET") {
                connection.setDoOutput(true);
                var outputStream = connection.getOutputStream();
                var bodyBytes = Java.use("java.lang.String").$new(body).getBytes();
                outputStream.write(bodyBytes);
                outputStream.close();
            }
            
            // 发送请求
            var responseCode = connection.getResponseCode();
            console.log("[Replay] Response code: " + responseCode);
            
            // 读取响应
            var inputStream = connection.getInputStream();
            var response = readInputStream(inputStream);
            console.log("[Replay] Response: " + response);
            
        } catch (e) {
            console.log("[-] API replay failed: " + e);
        }
    });
}

function readInputStream(inputStream) {
    var BufferedReader = Java.use("java.io.BufferedReader");
    var InputStreamReader = Java.use("java.io.InputStreamReader");
    var StringBuilder = Java.use("java.lang.StringBuilder");
    
    var reader = BufferedReader.$new(InputStreamReader.$new(inputStream));
    var response = StringBuilder.$new();
    var line;
    
    while ((line = reader.readLine()) !== null) {
        response.append(line);
    }
    
    reader.close();
    return response.toString();
}

总结

Frida 实战案例的核心要点:

🎯 登录绕过案例

  1. 多层分析:登录方法、网络请求、加密操作、存储状态
  2. 动态绕过:实时修改方法返回值和网络响应
  3. 设备指纹:绕过设备检查和指纹识别
  4. 状态管理:修改本地存储的登录状态

✅ API 逆向案例

  • 网络库 Hook 和请求拦截
  • 加密算法和签名机制分析
  • JSON 数据序列化和反序列化
  • API 重放和参数构造

🚀 实战技巧

  • 系统性的 Hook 策略
  • 数据流跟踪和分析
  • 实时修改和绕过
  • 自动化脚本生成

💡 分析方法

  • 从表层到深层的递进分析
  • 多角度验证和交叉确认
  • 动态调试和静态分析结合
  • 完整的攻击链构建

通过实战案例掌握 Frida 的实际应用能力!


实战案例是学习 Frida 最有效的方式,通过真实场景的分析能够快速提升动态分析技能。