frida主要是看
r0ysue大佬的github
android开发主要看安卓开发文档中文版
当然frida的api有些功能不明白,主要看官方文档
manifest文件描述了项目的基本特征并列出了组成应用的各个组件
activity_main.xml 此 XML 文件定义了 Activity 界面的布局。它包含一个 TextView 元素,其中具有“Hello, World!”文本
Android 的图形用户界面由多个视图(View)和视图组(ViewGroup)构建而成。
这是视图的唯一标识符。可以在程序代码中通过该标识符引用对象。
请记下此方法中的详细信息。系统需要这些信息来识别此方法是否与 android:onClick 属性兼容。具体来说,此方法具有以下特性:
公开访问。
返回值为空,或在 Kotlin 中为隐式单元。
View 是唯一的参数。这是您在第 1 步结束时点击的 View 对象。
接下来,您将填写此方法,以读取文本字段的内容,并将该文本传递给另一个 Activity。
Intent 是在相互独立的组件(如两个 Activity)之间提供运行时绑定功能的对象
r0ysue的trace脚本
/*
* raptor_frida_android_trace.js - Code tracer for Android
* Copyright (c) 2017 Marco Ivaldi <raptor@0xdeadbeef.info>
*
* Frida.re JS script to trace arbitrary Java Methods and
* Module functions for debugging and reverse engineering.
* See https://www.frida.re/ and https://codeshare.frida.re/
* for further information on this powerful tool.
*
* "We want to help others achieve interop through reverse
* engineering" -- @oleavr
*
* Many thanks to @inode-, @federicodotta, @leonjza, and
* @dankluev.
*
* Example usage:
* # frida -U -f com.target.app -l raptor_frida_android_trace.js --no-pause
*
* Get the latest version at:
* https://github.com/0xdea/frida-scripts/
*/
// generic trace
function trace(pattern)
{
var type = (pattern.toString().indexOf("!") === -1) ? "java" : "module";
if (type === "module") {
console.log("module")
// trace Module
var res = new ApiResolver("module");
var matches = res.enumerateMatchesSync(pattern);
var targets = uniqBy(matches, JSON.stringify);
targets.forEach(function(target) {
try{
traceModule(target.address, target.name);
}
catch(err){}
});
} else if (type === "java") {
console.log("java")
// trace Java Class
var found = false;
Java.enumerateLoadedClasses({
onMatch: function(aClass) {
if (aClass.match(pattern)) {
found = true;
console.log("found is true")
console.log("before:"+aClass)
//var className = aClass.match(/[L](.*);/)[1].replace(/\//g, ".");
var className = aClass.match(/[L]?(.*);?/)[1].replace(/\//g, ".");
console.log("after:"+className)
traceClass(className);
}
},
onComplete: function() {}
});
// trace Java Method
if (!found) {
try {
traceMethod(pattern);
}
catch(err) { // catch non existing classes/methods
console.error(err);
}
}
}
}
// find and trace all methods declared in a Java Class
function traceClass(targetClass)
{
console.log("entering traceClass")
var hook = Java.use(targetClass);
var methods = hook.class.getDeclaredMethods();
hook.$dispose();
console.log("entering pasedMethods")
var parsedMethods = [];
methods.forEach(function(method) {
try{
parsedMethods.push(method.toString().replace(targetClass + ".", "TOKEN").match(/\sTOKEN(.*)\(/)[1]);
}
catch(err){}
});
console.log("entering traceMethods")
var targets = uniqBy(parsedMethods, JSON.stringify);
targets.forEach(function(targetMethod) {
try{
traceMethod(targetClass + "." + targetMethod);
}
catch(err){}
});
}
// trace a specific Java Method
function traceMethod(targetClassMethod)
{
var delim = targetClassMethod.lastIndexOf(".");
if (delim === -1) return;
var targetClass = targetClassMethod.slice(0, delim)
var targetMethod = targetClassMethod.slice(delim + 1, targetClassMethod.length)
var hook = Java.use(targetClass);
var overloadCount = hook[targetMethod].overloads.length;
console.log("Tracing " + targetClassMethod + " [" + overloadCount + " overload(s)]");
for (var i = 0; i < overloadCount; i++) {
hook[targetMethod].overloads[i].implementation = function() {
console.warn("\n*** entered " + targetClassMethod);
// print backtrace
// Java.perform(function() {
// var bt = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new());
// console.log("\nBacktrace:\n" + bt);
// });
// print args
if (arguments.length) console.log();
for (var j = 0; j < arguments.length; j++) {
console.log("arg[" + j + "]: " + arguments[j]);
}
// print retval
var retval = this[targetMethod].apply(this, arguments); // rare crash (Frida bug?)
console.log("\nretval: " + retval);
console.warn("\n*** exiting " + targetClassMethod);
return retval;
}
}
}
// trace Module functions
function traceModule(impl, name)
{
console.log("Tracing " + name);
Interceptor.attach(impl, {
onEnter: function(args) {
// debug only the intended calls
this.flag = false;
// var filename = Memory.readCString(ptr(args[0]));
// if (filename.indexOf("XYZ") === -1 && filename.indexOf("ZYX") === -1) // exclusion list
// if (filename.indexOf("my.interesting.file") !== -1) // inclusion list
this.flag = true;
if (this.flag) {
console.warn("\n*** entered " + name);
// print backtrace
console.log("\nBacktrace:\n" + Thread.backtrace(this.context, Backtracer.ACCURATE)
.map(DebugSymbol.fromAddress).join("\n"));
}
},
onLeave: function(retval) {
if (this.flag) {
// print retval
console.log("\nretval: " + retval);
console.warn("\n*** exiting " + name);
}
}
});
}
// remove duplicates from array
function uniqBy(array, key)
{
var seen = {};
return array.filter(function(item) {
var k = key(item);
return seen.hasOwnProperty(k) ? false : (seen[k] = true);
});
}
// usage examples
setTimeout(function() { // avoid java.lang.ClassNotFoundException
Java.perform(function() {
console.log("first entering selector")
trace("com.example.mysecondapp.MainActivity");
//trace("exports:*!open*");
//trace("exports:*!write*");
//trace("exports:*!malloc*");
//trace("exports:*!free*");
});
}, 0);