Options: --version show program's version number and exit -h, --help show this help message and exit -D ID, --device=ID connect to device with the given ID -U, --usb connect to USB device -R, --remote connect to remote frida-server -H HOST, --host=HOST connect to remote frida-server on HOST -a, --applications list only applications -i, --installed include all installed applications
╰─$ python3 frida_demo_rpc_loader2.py Script loaded successfully {'type': 'send', 'payload': 'Sending to the server :ZWVlZWU6MTIzMTIz\n'} None Sending to the server :ZWVlZWU6MTIzMTIz
message: {'type': 'send', 'payload': 'Sending to the server :ZWVlZWU6MTIzMTIz\n'} data: b'eeeee:123123' pw: 123123' encoded data: b'YWRtaW46MTIzMTIzJw==' Modified data sent string_to_recv: b'YWRtaW46MTIzMTIzJw=='
Java.perform(fn: () => void): void Function to run while attached to the VM. Ensures that the current thread is attached to the VM and calls fn. (This isn’t necessary in callbacks from Java.) Will defer calling fn if the app’s class loader is not available yet. Use Java.performNow() if access to the app’s classes is not needed.
send(message: any, data?: ArrayBuffer | number[]): void 任何JSON可序列化的值。 将JSON序列化后的message发送到您的基于Frida的应用程序,并包含(可选)一些原始二进制数据。 The latter is useful if you e.g. dumped some memory using NativePointer#readByteArray().
recv(callback: MessageCallback): MessageRecvOperation Requests callback to be called on the next message received from your Frida-based application. This will only give you one message, so you need to call recv() again to receive the next one.
Java.perform(function(){ var dexclassLoader = Java.use("dalvik.system.DexClassLoader"); var hookClass = undefined; var ClassUse = Java.use("java.lang.Class");
Java.perform(function(){ var hookClass = undefined; var ClassUse = Java.use("java.lang.Class"); var dexclassLoader = Java.use("dalvik.system.DexClassLoader"); var constructorclass = Java.use("java.lang.reflect.Constructor"); var objectclass= Java.use("java.lang.Object"); dexclassLoader.loadClass.overload('java.lang.String').implementation = function(name){ var hookname = "cn.chaitin.geektan.crackme.MainActivityPatch"; var result = this.loadClass(name,false);
if(name == hookname){ var hookClass = result; console.log("------------------------------CAST--------------------------------") //类型转换 var hookClassCast = Java.cast(hookClass,ClassUse); //调用getMethods()获取类下的所有方法 var methods = hookClassCast.getMethods(); console.log(methods); console.log("-----------------------------NOT CAST-----------------------------") //未进行类型转换,看看能否调用getMethods()方法 var methodtest = hookClass.getMethods(); console.log(methodtest); console.log("---------------------OVER------------------------") return result;
Java.perform(function(){ var hookClass = undefined; var ClassUse = Java.use("java.lang.Class"); var objectclass= Java.use("java.lang.Object"); var dexclassLoader = Java.use("dalvik.system.DexClassLoader"); var orininclass = Java.use("cn.chaitin.geektan.crackme.MainActivity"); var Integerclass = Java.use("java.lang.Integer"); //实例化MainActivity对象 var mainAc = orininclass.$new();
dexclassLoader.loadClass.overload('java.lang.String').implementation = function(name){ var hookname = "cn.chaitin.geektan.crackme.MainActivityPatch"; var result = this.loadClass(name,false);
if(name == hookname){ var hookClass = result; var hookClassCast = Java.cast(hookClass,ClassUse); console.log("-----------------------------BEGIN-------------------------------------"); //获取构造器 var ConstructorParam =Java.array('Ljava.lang.Object;',[objectclass.class]); var Constructor = hookClassCast.getDeclaredConstructor(ConstructorParam); console.log("Constructor:"+Constructor); console.log("orinin:"+mainAc); //实例化,newInstance的参数也是Ljava.lang.Object; var instance = Constructor.newInstance([mainAc]); console.log("patchAc:"+instance); send(instance); console.log("--------------------------------------------------------------------"); return result;
} return result; } });
利用getDeclaredMethods(),获取本类中的所有方法
Java.perform(function(){ var hookClass = undefined; var ClassUse = Java.use("java.lang.Class"); var objectclass= Java.use("java.lang.Object"); var dexclassLoader = Java.use("dalvik.system.DexClassLoader"); var orininclass = Java.use("cn.chaitin.geektan.crackme.MainActivity"); var Integerclass = Java.use("java.lang.Integer"); //实例化MainActivity对象 var mainAc = orininclass.$new();
dexclassLoader.loadClass.overload('java.lang.String').implementation = function(name){ var hookname = "cn.chaitin.geektan.crackme.MainActivityPatch"; var result = this.loadClass(name,false);
if(name == hookname){ var hookClass = result; var hookClassCast = Java.cast(hookClass,ClassUse); console.log("-----------------------------BEGIN-------------------------------------"); //获取构造器 var ConstructorParam =Java.array('Ljava.lang.Object;',[objectclass.class]); var Constructor = hookClassCast.getDeclaredConstructor(ConstructorParam); console.log("Constructor:"+Constructor); console.log("orinin:"+mainAc); //实例化,newInstance的参数也是Ljava.lang.Object; var instance = Constructor.newInstance([mainAc]); console.log("MainActivityPatchInstance:"+instance); send(instance); console.log("----------------------------Methods---------------------------------"); var func = hookClassCast.getDeclaredMethods(); console.log(func); console.log("--------------------------Need Method---------------------------------"); console.log(func[0]); var f = func[0]; console.log("---------------------------- OVER---------------------------------"); return result;
function stackTrace() { var stack = ThreadObj.currentThread().getStackTrace(); for (var i = 0; i < stack.length; i++) { send(i + " => " + stack[i].toString()); } send("--------------------------------------------------------------------------"); }
});
Non-ASCII
int ֏(int x) { return x + 100; }
甚至有一些不可视, 所以可以先编码打印出来, 再用编码后的字符串去 hook.<\br>
Java.perform( function x() {
var targetClass = "com.example.hooktest.MainActivity";
var hookCls = Java.use(targetClass); var methods = hookCls.class.getDeclaredMethods();
for (var i in methods) { console.log(methods[i].toString()); console.log(encodeURIComponent(methods[i].toString().replace(/^.*?\.([^\s\.\(\)]+)\(.*?$/, "$1"))); }
hookCls[decodeURIComponent("%D6%8F")] .implementation = function (x) { console.log("original call: fun(" + x + ")"); var result = this[decodeURIComponent("%D6%8F")](900); return result; } } )
Hook 数据库
var SQLiteDatabase = Java.use('com.tencent.wcdb.database.SQLiteDatabase'); var Set = Java.use("java.util.Set"); var ContentValues = Java.use("android.content.ContentValues"); SQLiteDatabase.insert.implementation = function (arg1,arg2,arg3) {
this.insert.call(this, arg1, arg2, arg3); console.log("[insert] -> arg1:" + arg1 + "\t arg2:" + arg2); var values = Java.cast(arg3, ContentValues); var sets = Java.cast(values.keySet(), Set); var arr = sets.toArray().toString().split(","); for (var i = 0; i < arr.length; i++){ console.log("[insert] -> key:" + arr[i] + "\t value:" + values.get(arr[i])); } };
Hook JNI Native GetStringUTFChars
function hook_native_GetStringUTFChars() { var env = Java.vm.getEnv(); var handlePointer = Memory.readPointer(env.handle); console.log("env handle: " + handlePointer); var GetStringUTFCharsPtr = Memory.readPointer(handlePointer.add(0x2A4)); console.log("GetStringUTFCharsPtr addr: " + GetStringUTFCharsPtr); Interceptor.attach(GetStringUTFCharsPtr, { onEnter: function (args) { var str = ""; Java.perform(function () { str = Java.cast(args[1], Java.use('java.lang.String')); }); console.log("GetStringUTFChars: " + str);
} }); }
主动弹窗
Java.perform(function() { var System = Java.use('java.lang.System'); var ActivityThread = Java.use("android.app.ActivityThread"); var AlertDialogBuilder = Java.use("android.app.AlertDialog$Builder"); var DialogInterfaceOnClickListener = Java.use('android.content.DialogInterface$OnClickListener');
Java.use("android.app.Activity").onCreate.overload("android.os.Bundle").implementation = function(savedInstanceState) { var currentActivity = this;
// Get Main Activity var application = ActivityThread.currentApplication(); var launcherIntent = application.getPackageManager().getLaunchIntentForPackage(application.getPackageName()); var launchActivityInfo = launcherIntent.resolveActivityInfo(application.getPackageManager(), 0);
// Alert Will Only Execute On Main Package Activity Creation console.log(this.getComponentName().getClassName()) /** * non protective application * if (launchActivityInfo === this.getComponentName().getClassName()) { * ... * } */
if (this.getComponentName().getClassName() === "com.xxx") {
var alert = AlertDialogBuilder.$new(this); var jString = Java.use('java.lang.String'); var CharSequence = Java.use('java.lang.CharSequence'); var charSequence = Java.cast(jString.$new("What you want to do now?"), CharSequence); var charSequence1 = Java.cast(jString.$new("Dismiss"), CharSequence); var charSequence2 = Java.cast(jString.$new("Force Close!"), CharSequence); alert.setMessage(charSequence);