- 发布于
Frida 动态分析框架入门指南:现代应用安全分析的强大工具
- 作者

- 姓名
- 全能波
- GitHub
- @weicracker
Frida 动态分析框架入门指南:现代应用安全分析的强大工具
Frida 是一个强大的动态分析框架,支持 Windows、macOS、GNU/Linux、iOS、Android 等多个平台。它允许开发者和安全研究人员在运行时注入 JavaScript 代码来分析和修改应用程序的行为。
Frida 框架概述
什么是 Frida
Frida 是一个动态代码插桩工具包,它提供了一套丰富的 API 来进行运行时分析:
// 基础 Frida 脚本示例
Java.perform(function() {
// 获取目标类
var MainActivity = Java.use("com.example.app.MainActivity");
// Hook 方法
MainActivity.checkLicense.implementation = function() {
console.log("[+] checkLicense() called");
// 调用原始方法
var result = this.checkLicense();
console.log("[+] Original result: " + result);
// 修改返回值
console.log("[+] Returning true instead");
return true;
};
console.log("[+] Hook installed successfully");
});
核心特性
// 1. 方法 Hook 和参数修改
Java.perform(function() {
var String = Java.use("java.lang.String");
// Hook String.equals 方法
String.equals.implementation = function(other) {
var result = this.equals(other);
console.log("[String.equals] this: '" + this + "'");
console.log("[String.equals] other: '" + other + "'");
console.log("[String.equals] result: " + result);
return result;
};
});
// 2. 类实例化监控
Java.perform(function() {
var File = Java.use("java.io.File");
// Hook 构造函数
File.$init.overload('java.lang.String').implementation = function(path) {
console.log("[File] Creating file with path: " + path);
// 调用原始构造函数
this.$init(path);
};
});
// 3. 字段访问和修改
Java.perform(function() {
var targetClass = Java.use("com.example.app.Config");
// 修改静态字段
targetClass.DEBUG_MODE.value = true;
console.log("[+] DEBUG_MODE set to true");
// 监控实例字段
targetClass.setApiKey.implementation = function(key) {
console.log("[+] API Key being set: " + key);
// 替换为自定义值
this.setApiKey("custom_api_key");
};
});
环境搭建和安装
安装 Frida
# 1. 安装 Python 和 pip
# 确保 Python 3.6+ 已安装
# 2. 安装 Frida
pip install frida-tools
# 3. 验证安装
frida --version
# 4. 安装 Frida 服务器 (Android)
# 下载对应架构的 frida-server
# https://github.com/frida/frida/releases
# 5. 推送到 Android 设备
adb push frida-server-15.2.2-android-arm64 /data/local/tmp/frida-server
adb shell chmod 755 /data/local/tmp/frida-server
# 6. 启动 Frida 服务器
adb shell su -c "/data/local/tmp/frida-server &"
开发环境配置
# frida_setup.py - Frida 开发环境配置
import frida
import sys
import time
class FridaEnvironment:
def __init__(self):
self.device = None
self.session = None
self.script = None
def setup_device(self, device_id=None):
"""设置目标设备"""
try:
if device_id:
self.device = frida.get_device(device_id)
else:
# 获取 USB 连接的设备
self.device = frida.get_usb_device()
print(f"[+] Connected to device: {self.device}")
return True
except Exception as e:
print(f"[-] Failed to connect to device: {e}")
return False
def list_processes(self):
"""列出设备上的进程"""
try:
processes = self.device.enumerate_processes()
print("\n[+] Running processes:")
for process in processes:
print(f" PID: {process.pid:5d} | Name: {process.name}")
return processes
except Exception as e:
print(f"[-] Failed to list processes: {e}")
return []
def attach_to_process(self, process_name_or_pid):
"""附加到目标进程"""
try:
if isinstance(process_name_or_pid, str):
# 通过进程名附加
self.session = self.device.attach(process_name_or_pid)
else:
# 通过 PID 附加
self.session = self.device.attach(process_name_or_pid)
print(f"[+] Attached to process: {process_name_or_pid}")
return True
except Exception as e:
print(f"[-] Failed to attach to process: {e}")
return False
def spawn_and_attach(self, package_name):
"""启动并附加到应用"""
try:
# 启动应用
pid = self.device.spawn([package_name])
print(f"[+] Spawned process with PID: {pid}")
# 附加到进程
self.session = self.device.attach(pid)
print(f"[+] Attached to spawned process")
# 恢复进程执行
self.device.resume(pid)
print(f"[+] Resumed process execution")
return True
except Exception as e:
print(f"[-] Failed to spawn and attach: {e}")
return False
def load_script(self, script_content):
"""加载 Frida 脚本"""
try:
self.script = self.session.create_script(script_content)
self.script.on('message', self.on_message)
self.script.load()
print("[+] Script loaded successfully")
return True
except Exception as e:
print(f"[-] Failed to load script: {e}")
return False
def on_message(self, message, data):
"""处理脚本消息"""
if message['type'] == 'send':
print(f"[Script] {message['payload']}")
elif message['type'] == 'error':
print(f"[Error] {message['stack']}")
def cleanup(self):
"""清理资源"""
if self.script:
self.script.unload()
if self.session:
self.session.detach()
print("[+] Cleanup completed")
# 使用示例
def main():
frida_env = FridaEnvironment()
# 设置设备
if not frida_env.setup_device():
return
# 列出进程
processes = frida_env.list_processes()
# 附加到目标应用
target_app = "com.example.targetapp"
if frida_env.spawn_and_attach(target_app):
# 基础 Hook 脚本
script_content = """
Java.perform(function() {
console.log("[+] Starting Frida script");
// Hook 示例
var MainActivity = Java.use("com.example.targetapp.MainActivity");
MainActivity.onCreate.implementation = function(savedInstanceState) {
console.log("[+] MainActivity.onCreate() called");
this.onCreate(savedInstanceState);
};
});
"""
# 加载脚本
if frida_env.load_script(script_content):
print("[+] Press Ctrl+C to exit")
try:
sys.stdin.read()
except KeyboardInterrupt:
pass
# 清理
frida_env.cleanup()
if __name__ == "__main__":
main()
基础 Hook 技术
Android Java Hook
// android_java_hooks.js - Android Java Hook 示例
Java.perform(function() {
console.log("[+] Starting Android Java hooks");
// 1. Hook Activity 生命周期
hookActivityLifecycle();
// 2. Hook 网络请求
hookNetworkRequests();
// 3. Hook 加密操作
hookCryptographicOperations();
// 4. Hook 文件操作
hookFileOperations();
// 5. Hook SharedPreferences
hookSharedPreferences();
});
function hookActivityLifecycle() {
try {
var Activity = Java.use("android.app.Activity");
Activity.onCreate.implementation = function(savedInstanceState) {
console.log("[Activity] onCreate: " + this.getClass().getName());
this.onCreate(savedInstanceState);
};
Activity.onResume.implementation = function() {
console.log("[Activity] onResume: " + this.getClass().getName());
this.onResume();
};
Activity.onPause.implementation = function() {
console.log("[Activity] onPause: " + this.getClass().getName());
this.onPause();
};
console.log("[+] Activity lifecycle hooks installed");
} catch (e) {
console.log("[-] Failed to hook Activity lifecycle: " + e);
}
}
function hookNetworkRequests() {
try {
// Hook OkHttp
var OkHttpClient = Java.use("okhttp3.OkHttpClient");
var Request = Java.use("okhttp3.Request");
OkHttpClient.newCall.implementation = function(request) {
console.log("[OkHttp] Request URL: " + request.url().toString());
console.log("[OkHttp] Request Method: " + request.method());
// 打印请求头
var headers = request.headers();
var headerNames = headers.names();
var iterator = headerNames.iterator();
while (iterator.hasNext()) {
var name = iterator.next();
var value = headers.get(name);
console.log("[OkHttp] Header: " + name + " = " + value);
}
return this.newCall(request);
};
// Hook HttpURLConnection
var HttpURLConnection = Java.use("java.net.HttpURLConnection");
HttpURLConnection.getResponseCode.implementation = function() {
var responseCode = this.getResponseCode();
console.log("[HttpURLConnection] Response Code: " + responseCode);
console.log("[HttpURLConnection] URL: " + this.getURL().toString());
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) {
console.log("[Cipher] doFinal called");
console.log("[Cipher] Algorithm: " + this.getAlgorithm());
console.log("[Cipher] Input length: " + input.length);
var result = this.doFinal(input);
console.log("[Cipher] Output length: " + result.length);
return result;
};
// Hook MessageDigest
var MessageDigest = Java.use("java.security.MessageDigest");
MessageDigest.digest.overload('[B').implementation = function(input) {
console.log("[MessageDigest] digest called");
console.log("[MessageDigest] Algorithm: " + this.getAlgorithm());
console.log("[MessageDigest] Input: " + bytesToHex(input));
var result = this.digest(input);
console.log("[MessageDigest] Hash: " + bytesToHex(result));
return result;
};
console.log("[+] Cryptographic operation hooks installed");
} catch (e) {
console.log("[-] Failed to hook cryptographic operations: " + e);
}
}
function hookFileOperations() {
try {
// Hook File operations
var File = Java.use("java.io.File");
File.$init.overload('java.lang.String').implementation = function(path) {
console.log("[File] Creating file: " + path);
this.$init(path);
};
File.exists.implementation = function() {
var result = this.exists();
console.log("[File] exists() called for: " + this.getAbsolutePath() + " -> " + result);
return result;
};
// Hook FileInputStream
var FileInputStream = Java.use("java.io.FileInputStream");
FileInputStream.$init.overload('java.lang.String').implementation = function(name) {
console.log("[FileInputStream] Opening file: " + name);
this.$init(name);
};
console.log("[+] File operation hooks installed");
} catch (e) {
console.log("[-] Failed to hook file operations: " + e);
}
}
function hookSharedPreferences() {
try {
var SharedPreferences = Java.use("android.content.SharedPreferences");
var Editor = Java.use("android.content.SharedPreferences$Editor");
// Hook getString
SharedPreferences.getString.implementation = function(key, defValue) {
var result = this.getString(key, defValue);
console.log("[SharedPreferences] getString: " + key + " = " + result);
return result;
};
// Hook putString
Editor.putString.implementation = function(key, value) {
console.log("[SharedPreferences] putString: " + key + " = " + value);
return this.putString(key, value);
};
console.log("[+] SharedPreferences hooks installed");
} catch (e) {
console.log("[-] Failed to hook SharedPreferences: " + 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;
}
// 动态类加载和 Hook
function hookDynamicClass(className) {
Java.perform(function() {
try {
var targetClass = Java.use(className);
console.log("[+] Successfully loaded class: " + className);
// 获取所有方法
var methods = targetClass.class.getDeclaredMethods();
console.log("[+] Found " + methods.length + " methods in " + className);
// 打印方法信息
for (var i = 0; i < methods.length; i++) {
var method = methods[i];
console.log(" Method: " + method.getName());
}
} catch (e) {
console.log("[-] Failed to load class " + className + ": " + e);
}
});
}
// 运行时类发现
function discoverClasses(packagePrefix) {
Java.perform(function() {
Java.enumerateLoadedClasses({
onMatch: function(className) {
if (className.startsWith(packagePrefix)) {
console.log("[Discovery] Found class: " + className);
}
},
onComplete: function() {
console.log("[Discovery] Class enumeration completed");
}
});
});
}
Native Hook 技术
// native_hooks.js - Native Hook 示例
console.log("[+] Starting Native hooks");
// 1. Hook libc 函数
hookLibcFunctions();
// 2. Hook JNI 函数
hookJniFunctions();
// 3. Hook 自定义 Native 库
hookCustomNativeLibrary();
function hookLibcFunctions() {
try {
// Hook malloc
var malloc = Module.findExportByName("libc.so", "malloc");
if (malloc) {
Interceptor.attach(malloc, {
onEnter: function(args) {
this.size = args[0].toInt32();
console.log("[malloc] Allocating " + this.size + " bytes");
},
onLeave: function(retval) {
console.log("[malloc] Allocated at: " + retval);
}
});
}
// Hook free
var free = Module.findExportByName("libc.so", "free");
if (free) {
Interceptor.attach(free, {
onEnter: function(args) {
console.log("[free] Freeing memory at: " + args[0]);
}
});
}
// Hook strcmp
var strcmp = Module.findExportByName("libc.so", "strcmp");
if (strcmp) {
Interceptor.attach(strcmp, {
onEnter: function(args) {
var str1 = Memory.readUtf8String(args[0]);
var str2 = Memory.readUtf8String(args[1]);
console.log("[strcmp] Comparing: '" + str1 + "' vs '" + str2 + "'");
},
onLeave: function(retval) {
console.log("[strcmp] Result: " + retval.toInt32());
}
});
}
console.log("[+] libc function hooks installed");
} catch (e) {
console.log("[-] Failed to hook libc functions: " + e);
}
}
function hookJniFunctions() {
try {
// Hook JNI GetStringUTFChars
var GetStringUTFChars = Module.findExportByName("libart.so", "_ZN3art3JNI17GetStringUTFCharsEP7_JNIEnvP8_jstringPh");
if (!GetStringUTFChars) {
GetStringUTFChars = Module.findExportByName("libdvm.so", "_Z20dvmGetStringUtfCharsP8_jstringPh");
}
if (GetStringUTFChars) {
Interceptor.attach(GetStringUTFChars, {
onEnter: function(args) {
this.jstring = args[1];
},
onLeave: function(retval) {
if (retval.isNull()) return;
var str = Memory.readUtf8String(retval);
console.log("[JNI] GetStringUTFChars: " + str);
}
});
}
// Hook JNI NewStringUTF
var NewStringUTF = Module.findExportByName("libart.so", "_ZN3art3JNI12NewStringUTFEP7_JNIEnvPKc");
if (!NewStringUTF) {
NewStringUTF = Module.findExportByName("libdvm.so", "_Z15dvmCreateStringPKc");
}
if (NewStringUTF) {
Interceptor.attach(NewStringUTF, {
onEnter: function(args) {
var str = Memory.readUtf8String(args[1]);
console.log("[JNI] NewStringUTF: " + str);
}
});
}
console.log("[+] JNI function hooks installed");
} catch (e) {
console.log("[-] Failed to hook JNI functions: " + e);
}
}
function hookCustomNativeLibrary() {
try {
// 等待库加载
var libName = "libnative.so";
// 监控模块加载
Process.enumerateModules({
onMatch: function(module) {
if (module.name === libName) {
console.log("[+] Found target library: " + libName);
hookNativeLibraryFunctions(module);
}
},
onComplete: function() {
console.log("[+] Module enumeration completed");
}
});
// 或者等待库加载后再 Hook
var intervalId = setInterval(function() {
var module = Process.findModuleByName(libName);
if (module) {
clearInterval(intervalId);
console.log("[+] Target library loaded: " + libName);
hookNativeLibraryFunctions(module);
}
}, 1000);
} catch (e) {
console.log("[-] Failed to hook custom native library: " + e);
}
}
function hookNativeLibraryFunctions(module) {
try {
// Hook 导出函数
var exports = module.enumerateExports();
console.log("[+] Found " + exports.length + " exports in " + module.name);
exports.forEach(function(exp) {
if (exp.name.indexOf("Java_") === 0) {
console.log("[Export] JNI function: " + exp.name + " at " + exp.address);
// Hook JNI 函数
Interceptor.attach(exp.address, {
onEnter: function(args) {
console.log("[" + exp.name + "] Called");
// 打印参数
for (var i = 0; i < 4; i++) {
console.log(" arg[" + i + "]: " + args[i]);
}
},
onLeave: function(retval) {
console.log("[" + exp.name + "] Return: " + retval);
}
});
}
});
// Hook 特定函数
var targetFunction = module.findExportByName("native_function");
if (targetFunction) {
Interceptor.attach(targetFunction, {
onEnter: function(args) {
console.log("[native_function] Called with args:");
console.log(" arg0: " + args[0]);
console.log(" arg1: " + args[1]);
},
onLeave: function(retval) {
console.log("[native_function] Return: " + retval);
}
});
}
} catch (e) {
console.log("[-] Failed to hook native library functions: " + e);
}
}
// 内存操作示例
function memoryOperations() {
// 读取内存
var address = ptr("0x12345678");
var value = Memory.readU32(address);
console.log("Value at " + address + ": " + value);
// 写入内存
Memory.writeU32(address, 0x41414141);
// 搜索内存
Memory.scan(ptr("0x10000000"), 0x1000, "41 41 41 41", {
onMatch: function(address, size) {
console.log("Found pattern at: " + address);
},
onComplete: function() {
console.log("Memory scan completed");
}
});
// 分配内存
var buffer = Memory.alloc(1024);
Memory.writeUtf8String(buffer, "Hello Frida!");
var str = Memory.readUtf8String(buffer);
console.log("Allocated string: " + str);
}
// 代码跟踪
function enableCodeTracing() {
var targetModule = Process.findModuleByName("libnative.so");
if (targetModule) {
Stalker.follow(Process.getCurrentThreadId(), {
events: {
call: true,
ret: true,
exec: false
},
onReceive: function(events) {
console.log("Stalker events: " + events.length);
},
transform: function(iterator) {
var instruction = iterator.next();
do {
if (instruction.address.compare(targetModule.base) >= 0 &&
instruction.address.compare(targetModule.base.add(targetModule.size)) < 0) {
iterator.putCallout(function(context) {
console.log("Executing: " + instruction.address + " " + instruction.mnemonic);
});
}
iterator.keep();
} while ((instruction = iterator.next()) !== null);
}
});
}
}
实际应用案例
应用安全分析
# security_analysis.py - 应用安全分析脚本
import frida
import sys
import json
import time
class SecurityAnalyzer:
def __init__(self, package_name):
self.package_name = package_name
self.device = None
self.session = None
self.script = None
self.findings = []
def connect_device(self):
"""连接到设备"""
try:
self.device = frida.get_usb_device()
print(f"[+] Connected to device: {self.device}")
return True
except Exception as e:
print(f"[-] Failed to connect: {e}")
return False
def start_analysis(self):
"""开始安全分析"""
if not self.connect_device():
return False
try:
# 启动应用
pid = self.device.spawn([self.package_name])
self.session = self.device.attach(pid)
# 加载分析脚本
script_content = self.get_security_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"[+] Security 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') == 'security_finding':
self.findings.append(payload)
self.print_finding(payload)
else:
print(f"[Info] {payload}")
elif message['type'] == 'error':
print(f"[Error] {message['stack']}")
def print_finding(self, finding):
"""打印安全发现"""
severity = finding.get('severity', 'INFO')
category = finding.get('category', 'UNKNOWN')
description = finding.get('description', '')
details = finding.get('details', {})
print(f"\n[{severity}] {category}")
print(f"Description: {description}")
for key, value in details.items():
print(f" {key}: {value}")
def get_security_analysis_script(self):
"""获取安全分析脚本"""
return """
Java.perform(function() {
console.log("[+] Security analysis script loaded");
// 1. 检查调试检测
checkAntiDebugging();
// 2. 检查根检测
checkRootDetection();
// 3. 检查SSL Pinning
checkSSLPinning();
// 4. 检查敏感数据存储
checkSensitiveDataStorage();
// 5. 检查加密实现
checkCryptographicImplementation();
// 6. 检查权限使用
checkPermissionUsage();
});
function checkAntiDebugging() {
try {
var Debug = Java.use("android.os.Debug");
Debug.isDebuggerConnected.implementation = function() {
var result = this.isDebuggerConnected();
send({
type: 'security_finding',
severity: 'MEDIUM',
category: 'Anti-Debugging',
description: 'Application checks for debugger connection',
details: {
'method': 'Debug.isDebuggerConnected()',
'result': result
}
});
return result;
};
} catch (e) {
console.log("[-] Failed to check anti-debugging: " + e);
}
}
function checkRootDetection() {
try {
var File = Java.use("java.io.File");
File.exists.implementation = function() {
var result = this.exists();
var path = this.getAbsolutePath();
// 检查常见的 root 检测路径
var rootPaths = [
"/system/app/Superuser.apk",
"/sbin/su",
"/system/bin/su",
"/system/xbin/su",
"/data/local/xbin/su",
"/data/local/bin/su",
"/system/sd/xbin/su",
"/system/bin/failsafe/su",
"/data/local/su"
];
if (rootPaths.indexOf(path) !== -1) {
send({
type: 'security_finding',
severity: 'HIGH',
category: 'Root Detection',
description: 'Application checks for root indicators',
details: {
'path': path,
'exists': result
}
});
}
return result;
};
} catch (e) {
console.log("[-] Failed to check root detection: " + e);
}
}
function checkSSLPinning() {
try {
var CertificatePinner = Java.use("okhttp3.CertificatePinner");
CertificatePinner.check.implementation = function(hostname, peerCertificates) {
send({
type: 'security_finding',
severity: 'INFO',
category: 'SSL Pinning',
description: 'Application implements SSL certificate pinning',
details: {
'hostname': hostname,
'certificates': peerCertificates.length
}
});
return this.check(hostname, peerCertificates);
};
} catch (e) {
// SSL Pinning 可能未实现
}
}
function checkSensitiveDataStorage() {
try {
var SharedPreferences = Java.use("android.content.SharedPreferences");
var Editor = Java.use("android.content.SharedPreferences$Editor");
Editor.putString.implementation = function(key, value) {
// 检查敏感数据
var sensitiveKeywords = ['password', 'token', 'key', 'secret', 'pin'];
var isSensitive = sensitiveKeywords.some(keyword =>
key.toLowerCase().includes(keyword) ||
value.toLowerCase().includes(keyword)
);
if (isSensitive) {
send({
type: 'security_finding',
severity: 'HIGH',
category: 'Sensitive Data Storage',
description: 'Sensitive data stored in SharedPreferences',
details: {
'key': key,
'value_length': value.length
}
});
}
return this.putString(key, value);
};
} catch (e) {
console.log("[-] Failed to check sensitive data storage: " + e);
}
}
function checkCryptographicImplementation() {
try {
var Cipher = Java.use("javax.crypto.Cipher");
Cipher.getInstance.overload('java.lang.String').implementation = function(transformation) {
var weakAlgorithms = ['DES', 'RC4', 'MD5'];
var isWeak = weakAlgorithms.some(alg => transformation.includes(alg));
if (isWeak) {
send({
type: 'security_finding',
severity: 'HIGH',
category: 'Weak Cryptography',
description: 'Application uses weak cryptographic algorithm',
details: {
'algorithm': transformation
}
});
}
return this.getInstance(transformation);
};
} catch (e) {
console.log("[-] Failed to check cryptographic implementation: " + e);
}
}
function checkPermissionUsage() {
try {
var ContextWrapper = Java.use("android.content.ContextWrapper");
ContextWrapper.checkSelfPermission.implementation = function(permission) {
var result = this.checkSelfPermission(permission);
var sensitivePermissions = [
'android.permission.ACCESS_FINE_LOCATION',
'android.permission.CAMERA',
'android.permission.RECORD_AUDIO',
'android.permission.READ_CONTACTS',
'android.permission.READ_SMS'
];
if (sensitivePermissions.includes(permission)) {
send({
type: 'security_finding',
severity: 'MEDIUM',
category: 'Permission Usage',
description: 'Application requests sensitive permission',
details: {
'permission': permission,
'granted': result === 0
}
});
}
return result;
};
} catch (e) {
console.log("[-] Failed to check permission usage: " + e);
}
}
"""
def generate_report(self):
"""生成安全分析报告"""
report = {
'package_name': self.package_name,
'analysis_time': time.strftime('%Y-%m-%d %H:%M:%S'),
'total_findings': len(self.findings),
'findings': self.findings
}
# 按严重程度分类
severity_counts = {}
for finding in self.findings:
severity = finding.get('severity', 'UNKNOWN')
severity_counts[severity] = severity_counts.get(severity, 0) + 1
report['severity_summary'] = severity_counts
# 保存报告
report_file = f"security_report_{self.package_name}_{int(time.time())}.json"
with open(report_file, 'w') as f:
json.dump(report, f, indent=2)
print(f"\n[+] Security analysis report saved to: {report_file}")
print(f"[+] Total findings: {len(self.findings)}")
for severity, count in severity_counts.items():
print(f" {severity}: {count}")
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 security_analysis.py <package_name>")
return
package_name = sys.argv[1]
analyzer = SecurityAnalyzer(package_name)
if analyzer.start_analysis():
print("[+] Press Enter to generate report and exit")
input()
analyzer.generate_report()
analyzer.cleanup()
if __name__ == "__main__":
main()
总结
Frida 动态分析框架入门要点:
🎯 核心概念
- 动态插桩:运行时代码注入和分析
- 跨平台支持:支持多种操作系统和架构
- JavaScript API:使用 JavaScript 编写分析脚本
- 实时交互:动态修改应用行为和数据
✅ 主要功能
- Java 和 Native 代码 Hook
- 内存读写和搜索
- 函数调用跟踪
- 加密算法分析
- 网络通信监控
🚀 应用场景
- 应用安全分析和漏洞发现
- 逆向工程和协议分析
- 恶意软件分析
- API 调用监控
- 性能分析和调试
💡 最佳实践
- 合理使用 Hook 避免性能影响
- 详细的日志记录和错误处理
- 模块化脚本设计
- 安全和合法的使用方式
掌握 Frida 框架,开启动态分析的强大能力!
Frida 是现代应用安全分析的重要工具,使用时需要遵守法律法规和道德规范。