无锡军自考网站建设,做网站美工工资多少钱,标志设计软件,建站模板有哪些文章目录 安装frida安装python3.7设置环境变量安装pycharm和nodejs 使用frida将frida-server push到手机设备中端口转发安装apk使用jadx查看java代码运行frida-server frida源码阅读frida hook方法Frida Java层hoookJavaHook.javaJavaHook.js Frida native层hook 一NativeHook.… 文章目录 安装frida安装python3.7设置环境变量安装pycharm和nodejs 使用frida将frida-server push到手机设备中端口转发安装apk使用jadx查看java代码运行frida-server frida源码阅读frida hook方法Frida Java层hoookJavaHook.javaJavaHook.js Frida native层hook 一NativeHook.js 安装frida
Frida框架简介
Frida是一款基于Python JavaScript的Hook与调试框架。
Firda是一款易用的跨平Hook工具Java层到Native层的Hook无所不能是一种动态
的插桩工具可以插入代码到原生 App 的内存空间中动态的去监视和修改行为
原生平台包括Win、Mac、Linux、Android、iOS全平台。环境配置步骤:
1.安装Python环境 3.72.安装frida模块打开Py输入命令pip install fridapip install frida-toolspip uninstall fridapip uninstall frida-toolspip install frida15.1.27pip install frida-tools10.6.2google pixels 3a
frida16.1.3
frida-tools12.2.13.frida-server下载地址查看版本信息frida --versionhttps://github.com/frida/frida/releases下载安装frida server 版本和类型对应框架和设备对应4.安装PyCharm 5.启动frida-server6.端口转发adb forward tcp:27042 tcp:270427.测试frida-ps -U frida -U -f com.qianyu.fridaapp --no-pause安装python3.7 设置环境变量 安装pycharm和nodejs
创建工程的时候记得将鼠标所在的两个勾选框选上
使用frida
将frida-server push到手机设备中 端口转发 安装apk
使用jadx查看java代码 运行frida-server
我使用15.1.27版本的frida版本在安卓手机上会报错。所以我果断升级了frida版本
sargo:/data/local/tmp # ./frida-server-15.1.27-android-arm64
{type:error,
description:Error: Unable to determine ClassLinker field offsets,
stack:Error: Unable to determine ClassLinker field offsets\n at Ye (frida/node_modules/frida-java-bridge/lib/android.js:400:1)\n at frida/node_modules/frida-java-bridge/lib/memoize.js:4:1\n at ze (frida/node_modules/frida-java-bridge/lib/android.js:193:1)\n at Oe (frida/node_modules/frida-java-bridge/lib/android.js:16:1)\n at _tryInitialize (frida/node_modules/frida-java-bridge/index.js:29:1)\n at new _ (frida/node_modules/frida-java-bridge/index.js:21:1)\n at Object.4../lib/android (frida/node_modules/frida-java-bridge/index.js:332:1)\n at o (frida/node_modules/browser-pack/_prelude.js:1:1)\n at frida/node_modules/browser-pack/_prelude.js:1:1\n at Object.22.frida-java-bridge (frida/runtime/java.js:1:1),
fileName:frida/node_modules/frida-java-bridge/lib/android.js,lineNumber:400,columnNumber:1}frida源码阅读 frida hook方法
注意点
frida和frida-server版本号必须要一致hook的时候必须要运行hook的程序否则报错
Frida Java层hoook
JavaHook.java
# -*- coding: utf-8 -*-import os
import sys
import frida
import codecsdef message(message, data):if message[type] send:print([*] {0}.format(message[payload]))else:print(message)process frida.get_remote_device().attach(NDKDemo)
if not os.path.isfile(./JavaHook.js):raise TypeError(./JavaHook.js does not exist)
with codecs.open(./JavaHook.js, r, UTF-8) as file:js_code file.read()
script process.create_script(js_code)
script.on(message, message)
script.load()
# script.exports.test()
# script.exports.test()
# script.exports.test()
# script.exports.test()
sys.stdin.read()# frida使用非标准端口
# /data/local/tmp # ./fs_12.7.22_arm64 -l 127.0.0.1:31928 默认端口: 27046
# process frida.get_device_manager().add_remote_device(127.0.0.1:31928).attach(FridaApp)
# if not os.path.isfile(./JavaHook.js):
# raise TypeError(./JavaHook.js does not exist)
# with codecs.open(./JavaHook.js, r, UTF-8) as file:
# js_code file.read()
# script process.create_script(js_code)
# script.on(message, message)
# script.load()
# sys.stdin.read()
JavaHook.js
// HOOK普通方法、静态方法
function Test01(){let loginActivity Java.use(com.yijincc.ndkdemo.LoginActivity);loginActivity.login.implementation function () {console.log(login);console.log(Java.use(android.util.Log).getStackTraceString(Java.use(java.lang.Throwable).$new()));console.log(arguments[0]);console.log(arguments[1]);this.login(arguments[0],arguments[1]);}
}// HOOK构造方法、重载方法
function Test02(){let intent Java.use(android.content.Intent);intent.$init.overload(android.content.Context, java.lang.Class).implementation function () {console.log(intent);console.log(arguments[0]);console.log(arguments[1]);this.$init(arguments[0],arguments[1]);}
}// HOOK内部类
function Test03(){let loginActivity$1 Java.use(com.yijincc.ndkdemo.LoginActivity$1);loginActivity$1.onClick.implementation function () {console.log(onClick);console.log(arguments[0]);this.onClick(arguments[0]);}
}// 主动调用构造方法
function Test04(){let money Java.use(com.yijincc.fridaapp.Money);let obj money.$new(1000,RMB);console.log(obj.getInfo());
}// 操作对象里面的成员变量
function Test05(){let money Java.use(com.yijincc.fridaapp.Money);let obj money.$new(10000,RMB);console.log(obj.name.value);console.log(obj.num.value);console.log();obj.name.value RMB;obj.num.value 10000000;console.log(obj.name.value);console.log(obj.num.value);
}// 主动调用普通方法
function Test06(){let money Java.use(com.yijincc.fridaapp.Money);let obj money.$new(2000,RMB);console.log(obj.getInfo());
}// 获取当前类已有的实例实现主动调用普通方法
function Test07(){Java.choose(com.yijincc.ndkdemo.MainActivity,{onMatch: function(obj){ // 枚举时调用console.log(obj);console.log(obj.name.value);console.log(obj.age.value);console.log(obj.sex.value);console.log(obj.rand(B,99))}, onComplete: function(){ // 枚举完成后调用console.log(end);}});
}// 主动调用静态方法
function Test08(){let mainActivity Java.use(com.yijincc.ndkdemo.MainActivity);console.log(mainActivity.isRel(444,444));
}// HOOK打印堆栈信息
// function Test09(){
// let money Java.use(com.yijincc.fridaapp.Money);
// money.getInfo.implementation function () {
// console.log(getInfo);
// console.log(Java.use(android.util.Log).getStackTraceString(Java.use(java.lang.Throwable).$new()));
// return this.getInfo();
// }
// }// HOOK指定类的所有方法
function Test10(){let money Java.use(com.yijincc.ndkdemo.MainActivity);let methods money.class.getDeclaredMethods();for(let j 0; j methods.length; j){let methodName methods[j].getName();console.log(methodName);for(let k 0; k money[methodName].overloads.length; k){money[methodName].overloads[k].implementation function(){console.log(methodName);for(let i 0; i arguments.length; i){console.log(arguments[i]);}console.log(end);return this[methodName].apply(this, arguments);}}}
}// 枚举已加载的所有类与枚举类的所有方法
function Test11(){let classes Java.enumerateLoadedClassesSync();for(let i 0; i classes.length; i){if(classes[i].indexOf(com.) ! -1){console.log(clazzclasses[i]);let clazz Java.use(classes[i]);let methods clazz.class.getDeclaredMethods();for(let j 0; j methods.length; j){console.log(methodmethods[j]);}}}
}// hook动态加载dex文件
function Test12(){// Java.enumerateLoadedClasses({// onMatch: function (name, handle) {// if (name.indexOf(com.example) 0) {// console.log(name);// let class6 Java.use(name);// class6.check.implementation function () {// console.log(check:, this);// return true;// };// }// }, onComplete: function () {}// });Java.enumerateClassLoaders({onMatch: function (loader) {try {if (loader.findClass(com.example.androiddemo.Dynamic.DynamicCheck)) {console.log(loader);Java.classFactory.loader loader; //切换classloader}} catch (error) {}}, onComplete: function () {}});let DynamicCheck Java.use(com.example.androiddemo.Dynamic.DynamicCheck);console.log(DynamicCheck);DynamicCheck.check.implementation function () {console.log(DynamicCheck.check);return true;}
}// 动态加载dex文件
function Test13(){// jar -cvf dex.jar com/example/androiddemo/StringUtils.class// dx --dex --outputdex.dex dex.jarlet dex Java.openClassFile(/data/local/tmp/dex.dex);dex.load();let stringUtils Java.use(com.example.androiddemo.StringUtils);console.log(stringUtils.tohexString(1234567890));
}rpc.exports {test:function () {Java.choose(com.yijincc.ndkdemo.MainActivity,{onMatch: function(obj){ // 枚举时调用console.log(obj);console.log(obj.name.value);console.log(obj.age.value);console.log(obj.sex.value);console.log(obj.rand(B,99))}, onComplete: function(){ // 枚举完成后调用console.log(end);}});}
}Java.perform(function () {Test01();// Test02(); // 重载方法// Test03(); // 内部类// Test04() // 主动调用构造方法,创建一个对象// Test07();// Test08();// Test10(); // 打印所有的方法// Test11();//Test13();
});
Frida native层hook 一
通过IDA找到要hook的native函数静态 base64魔改 ## NativeHook.py
# -*- coding: utf-8 -*-import os
import sys
import frida
import codecsdef message(message, data):if message[type] send:print([*] {0}.format(message[payload]))else:print(message)process frida.get_remote_device().attach(NDKDemo)
if not os.path.isfile(./NativeHook.js):raise TypeError(./NativeHook.js does not exist)
with codecs.open(./NativeHook.js, r, UTF-8) as file:js_code file.read()
script process.create_script(js_code)
script.on(message, message)
script.load()
sys.stdin.read()# frida使用非标准端口
# /data/local/tmp # ./fs_12.7.22_arm64 -l 127.0.0.1:31928 默认端口: 27046
# process frida.get_device_manager().add_remote_device(127.0.0.1:31928).attach(Android_crackme)
# if not os.path.isfile(./NativeHook.js):
# raise TypeError(./NativeHook.js does not exist)
# with codecs.open(./NativeHook.js, r, UTF-8) as file:
# js_code file.read()
# script process.create_script(js_code) # 创建脚本
# script.on(message, message)
# script.load()
# sys.stdin.read()
NativeHook.js
// HOOK导出函数
function Test01(){// 用于在指定的模块中查找导出函数的地址let funGetFlag Module.findExportByName(libnative-lib.so, Java_com_yijincc_ndkdemo_LoginActivity_login);send(native: funGetFlag); // 基地址Interceptor.attach(funGetFlag, {onEnter: function(args){send(getFlag);send(args[0]);send(args[1]);},onLeave: function(retval){send(result);send(retval);// 获取JNIEnv*let env Java.vm.tryGetEnv();// 将jstring 转换 const char*let strenv.getStringUtfChars(retval,0);send(str.readCString());}});
}// HOOK未导出函数
function Test02(){// 绝对地址so模块起始地址(基地址)偏移地址let baseAddr Module.findBaseAddress(libnative-lib.so);send(baseAddr:baseAddr);// 指令集 分为ARM指令、thumb指令// ARM指令地址不变 thumb指令地址1 sub_ 开头的函数 这种函数只能使用这种方式来进行Interceptor.attach(baseAddr.add(0x15F08), {onEnter: function(args){send(encrypt);send(args[0]);send(args[1]);send(args[2]);console.log(hexdump(args[2], {offset: 0,length: 16,header: true,ansi: false}));// 获取JNIEnv*let env Java.vm.tryGetEnv();// 将jstring 转换 const char*let strenv.getStringUtfChars(args[2],0);send(str.readCString());},onLeave: function(retval){send(result);send(retval);// 获取JNIEnv*let env Java.vm.tryGetEnv();// 将jstring 转换 const char*let strenv.getStringUtfChars(retval,0);send(str.readCString());}});
}// HOOK枚举导入函数信息
function Test03(){send(Test03)let imports Module.enumerateImportsSync(libnative-lib.so);send(imports)for(let i0;iimports.length;i){// if(imports[i].name.indexOf(raise) ! -1){send(imports[i]);// }}
}// HOOK枚举导出函数信息
function Test04(){send(Test04-start)send(device)let exports Module.enumerateExportsSync(libnative-lib.so);send(exports)for(let i0;iexports.length;i){if(exports[i].name.indexOf(Java_) ! -1){send(name:exports[i].name address:exports[i].address);}}send(Test04-end)
}// 遍历模块列表信息
function Test05(){Process.enumerateModules({onMatch: function(exp){send(exp)if(exp.name.indexOf(libnative-lib.so) ! -1){send(enumerateModules find);send(exp);return stop;}},onComplete: function(){send(enumerateModules stop);}});
}// 读写内存数据
function Test06(){let mem_addrMemory.alloc(20);//Memory.writeInt(mem_addr,0x1234567890abcdef);Memory.writeLong(mem_addr,0x1234567890abcdef);// console.log(hexdump(mem_addr));console.log(hexdump(mem_addr, {offset: 0,length: 20,header: true,ansi: true}));
}// 使用frida api读写文件
function Test07(){let file new File(/data/data/com.yijincc.ndkdemo/yijincc.txt, w);file.write(hello world!!!\\n);file.flush();file.close();
}// 基于主动调用libc.so里面的函数实现文件的读写操作
function Test08(){let addr_fopen Module.findExportByName(libc.so, fopen);send(1)let addr_fputs Module.findExportByName(libc.so, fputs);send(2)let addr_fclose Module.findExportByName(libc.so, fclose);send(3)let fopen new NativeFunction(addr_fopen, pointer, [pointer, pointer]);send(4)let fputs new NativeFunction(addr_fputs, int, [pointer, pointer]);send(5)let fclose new NativeFunction(addr_fclose, int, [pointer]);send(6)let filename Memory.allocUtf8String(/data/data/com.yijincc.ndkdemo/yijincc.txt);send(7)let open_mode Memory.allocUtf8String(w);send(8)let file fopen(filename, open_mode);send(9)let buffer Memory.allocUtf8String(hello world!!!\\n);send(10)let result fputs(buffer, file);send(11)send(fputs: result);fclose(file);
}Java.perform(function () {// Test01();// Test02();// Test03();// Test04();// Test05();// Test06();// Test07();Test08();
})