android逆向基础教程一
工具 :Jadx AndroidKiller frida
熟练使用jadx ,Androidkiller frida,了解android逆向流程分析,熟悉Smali汇编以及Frida脚本编写,通过Jadx 流程分析android 中逻辑代码。AndroidKiller修改Smali汇编方式修改执行流程重新打包绕过某些逻辑条件判断,frida hook在逆向中占有重要地位,熟练掌握 frida hook基础知识是逆向必不可少的内容。
一、loginActivity
流程分析
解题
方法一:逻辑算法计算获取密码
通过逻辑算法输入用户名计算出返回的字符串即为密码。
public class Main {public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {String inputs1="PwnGuo";String str =a(inputs1,inputs1);
System.out.println("log:"+str);}public static String a(String str, String str2) throws InvalidKeyException, NoSuchAlgorithmException {
SecretKeySpec secretKeySpec = new SecretKeySpec(str2.getBytes(), "HmacSHA256");Mac instance = Mac.getInstance("HmacSHA256");instance.init(secretKeySpec);
return a(instance.doFinal(str.getBytes())) ;}private static String a(byte[] bArr) {StringBuilder sb = new StringBuilder();int i = 0;while (bArr != null && i < bArr.length) {String hexString = Integer.toHexString(bArr[i] & 255);if (hexString.length() == 1) {sb.append('0');}sb.append(hexString);i++;}return sb.toString().toLowerCase();}
}
//log:12638599104995570fcae7895cc54a57e485d9818887ba6762c5abaaebe670dc
方法二:Smali 汇编修改绕过
1.AndroidKiller 直接硬编码修改成功跳过
2.AndroidKiller插桩方式输出计算后的密码成功完成
用户名 :123456 密码:b8ad08a3a547e35829b821b75370301dd8c4b06bdd7771f9b541a75914068718
方法三:hook Java 层函数
通过hook a方法的返回参数获得密码
function hook_java() {Java.perform(function () {var LoginActivity = Java.use("com.example.androiddemo.Activity.LoginActivity");console.log(LoginActivity);LoginActivity.a.overload('java.lang.String', 'java.lang.String').implementation = function (str, str2) {var result = this.a(str, str2); //调用原来的函数console.log("LoginActivity.a:", str, str2, result);return result;};
var FridaActivity1 = Java.use("com.example.androiddemo.Activity.FridaActivity1");console.log(FridaActivity1);
//hook函数,没有调用原来的函数,直接返回值FridaActivity1.a.implementation = function (barr) {console.log("FridaActivity1.a");return "R4jSLLLLLLLLLLOrLE7/5B+Z6fsl65yj6BgC6YWz66gO6g2t65Pk6a+P65NK44NNROl0wNOLLLL=";};
console.log("hook_java");});
}
二、FridaActivity1
流程分析
解题
方法一: Smali 汇编修改
直接修改onCheck()方法中返回值
或者修改a(byte[] bArr)方法中返回值。
方法二:hook Java 层函数
修改函数返回值或参数
function hook_java() {Java.perform(function () {var FridaActivity1 = Java.use("com.example.androiddemo.Activity.FridaActivity1");console.log(FridaActivity1);//hook函数,没有调用原来的函数,直接返回值FridaActivity1.a.implementation = function (barr) {console.log("FridaActivity1.a");return "R4jSLLLLLLLLLLOrLE7/5B+Z6fsl65yj6BgC6YWz66gO6g2t65Pk6a+P65NK44NNROl0wNOLLLL=";};
console.log("hook_java");});
}
三、FridaActivity2
流程分析
解题
通过分析 static_bool_var bool_var参数为true时第二关通关成功,修改参数或调用setStatic_bool_var()/setBool_var()方法即可
方法一:修改跳转语句
方法二:直接调用方法
方法三:hook Java 层函数
调用静态函数和调用非静态函数
function call_FridaActivity2() {//主动调用函数Java.perform(function () {var FridaActivity2 = Java.use("com.example.androiddemo.Activity.FridaActivity2");//调用静态函数FridaActivity2.setStatic_bool_var(); //Java.choose 非静态函数调用Java.choose("com.example.androiddemo.Activity.FridaActivity2", {onMatch: function (instance) {instance.setBool_var();},onComplete: function () {
}});});
}
四、FridaActivity3
流程分析
静态/非静态成员变量通过满足if语句使通关成功
在Smali汇编中静态成员变量与非静态成员变量区别
解题
方法一:修改成员变量boolan值
方法二:设置成员变量
设置静态成员变量,非静态成员变量和函数名相同的成员变量
function call_FridaActivity3() {Java.perform(function () {var FridaActivity3 = Java.use("com.example.androiddemo.Activity.FridaActivity3");//设置静态成员变量FridaActivity3.static_bool_var.value = true; console.log(FridaActivity3.static_bool_var.value);Java.choose("com.example.androiddemo.Activity.FridaActivity3", {onMatch: function (instance) {//设置非静态成员变量的值instance.bool_var.value = true;//设置有相同函数名的成员变量的值instance._same_name_bool_var.value = true;console.log(instance.bool_var.value, instance._same_name_bool_var.value);},onComplete: function () {}});});
}
五、FridaActivity4
流程分析
解题
方法一:Smali修改返回值
方法二:hook 内部类
//方式一
function hook_InnerClasses() {Java.perform(function () {var InnerClasses = Java.use("com.example.androiddemo.Activity.FridaActivity4$InnerClasses");console.log(InnerClasses);InnerClasses.check1.implementation = function () {return true;};InnerClasses.check2.implementation = function () {return true;};InnerClasses.check3.implementation = function () {return true;};InnerClasses.check4.implementation = function () {return true;};InnerClasses.check5.implementation = function () {return true;};InnerClasses.check6.implementation = function () {return true;};});
}
//方式二
//枚举类的函数
function hook_enum_function() {Java.perform(function () {//hook 类的多个函数var class_name = "com.example.androiddemo.Activity.FridaActivity4$InnerClasses";var InnerClasses = Java.use(class_name);var all_methods = InnerClasses.class.getDeclaredMethods();for (var i = 0; i < all_methods.length; i++) {var method = (all_methods[i]);var methodStr = method.toString();var substring = methodStr.substr(methodStr.indexOf(class_name) + class_name.length + 1);var methodname = substring.substr(0, substring.indexOf("("));console.log(methodname);InnerClasses[methodname].implementation = function () {console.log("hook_mul_function:", this);return true;}}});
}
六、FridaActivity5
流程分析
动态加载dex ,调用check()方法,返回参数满足条件语句通关成功。
解题
方法一:Smali修改条件语句
getDynamicDexCheck()接口调用判断成立,只需修改check()方法满足条件。
方法二:hook动态加载的Dex
function hook_dyn_dex() {Java.perform(function () {var FridaActivity5 = Java.use("com.example.androiddemo.Activity.FridaActivity5");Java.choose("com.example.androiddemo.Activity.FridaActivity5", {onMatch: function (instance) {console.log(instance.getDynamicDexCheck().$className);}, onComplete: function () {
}});//hook 动态加载的dexJava.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 () {}});var DynamicCheck = Java.use("com.example.androiddemo.Dynamic.DynamicCheck");console.log(DynamicCheck);DynamicCheck.check.implementation = function () {console.log("DynamicCheck.check");return true;}});
}
七、FridaActivity6
流程分析
解题
方法一:Smali修改条件语句
方法二:hook java类
//方式一:直接返回参数为真
function hook_FridaActivity6() {Java.perform(function () {var Frida6Class0 = Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class0");Frida6Class0.check.implementation = function () {return true;};var Frida6Class1 = Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class1");Frida6Class1.check.implementation = function () {return true;};var Frida6Class2 = Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class2");Frida6Class2.check.implementation = function () {return true;};});
}
//方式二:枚举class
function hook_enum_class() {Java.perform(function () {Java.enumerateLoadedClasses({onMatch: function (name, handle) {if (name.indexOf("com.example.androiddemo.Activity.Frida6") >= 0) {console.log(name);var fridaclass6 = Java.use(name);fridaclass6.check.implementation = function () {console.log("frida 6 check:", this);return true;};}}, onComplete: function () {}})});
}
android逆向基础教程一相关推荐
- 学android逆向能干,教我兄弟学Android逆向04
8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? <教我兄弟学Android逆向>04的课后作业. 教程笔记 将apk反编译成smali文件 AndroidK ...
- android逆向基础教程四
前面我们主要对JNI动态注册流程作介绍,了解了Java层如何通过JNI 调用Native层实现的MD5,下面我们接着上篇中的工程介绍Native中调用Java API 及Native反射调用Java层 ...
- Android逆向基础——APK的格式
Android 安装包常以apk(android Package).xapk为后缀,本质是一个压缩包,包内存存放运行着应用程序安装必要的所有资源.代码.可直接修改后缀为zip解包. 解包后目录大致如下 ...
- Android Studio系列教程一:下载与安装
原文出处:http://stormzhang.com/devtools/2014/11/25/android-studio-tutorial1/ 背景 相信大家对Android Studio已经不陌生 ...
- Android逆向基础----Android Dalvik虚拟机
Android Dalvik虚拟机的特点: l 体积小,占用内存空间小. l 专有DEX可执行文件. l 常量池采用32位索引值,寻址类方法名,字段名,常量更快. l 基于寄存器架构,并拥有一 ...
- Android逆向基础笔记—初识逆向
(本笔记来源于吾爱以及吾爱坛友,加上本人自己的整理) 一.初识 APK.Dalvik字节码以及Smali 1. apk是什么? apk实质上是一个zip压缩包,将apk后缀修改为zip,解压之后可以看 ...
- Android 逆向基础
Android 反编译教程 博客内容 基本知识 几个重要的工具 技术原理 apktool dex2jar + jd-gui DEX文件结构学习 Monkey使用手册 Android权限列表以及说明 博 ...
- android逆向基础教程三
CMake下JNI动态注册及逆向 在对native层hook首先我们先了解android native 开发流程及简单的逆向关注点,在后续的hook native 层中会有更加复杂的过程,加密,加壳等 ...
- Android逆向基础笔记—Android中的常用ARM汇编指令
一 ARM寄存器 1.通用寄存器 1).未分组寄存器:R0~R7 2).分组寄存器:R8~812 R13:SP,常用作堆栈指针,始终指向堆栈的顶部,当一个数据(32位)推入堆栈时,SP(R13的值减 ...
- Ogre3D基础教程一
文档:教程:基础教程:基础教程一 出自Ogre3D开放资源地带 跳转到: 导航, 搜索 目录 [隐藏] 1 简介 2 从这里开始 2.1 错误排除 2.1.1 编译错误 2.1.2 运行失败 3 OG ...
最新文章
- 动态分区添加的新字段无法插入数据
- cubrid php,PHP - Manual: CUBRID (官方文档)
- 白话容器namespace
- spring-retry小结
- C#只能靠参数而不能靠返回值类型的不同来区分方法重载
- OSG仿真案例(5)——创建火光、爆炸(碎片)
- 超级强悍的PHP代码编辑器PHPstorm及配置
- [linux]linux mint zsh安装和配置
- 【牛客网-公司真题-前端入门篇】——百度2021校招Web前端研发工程师笔试卷(第二批)
- Thinkpad部分机型支持的智能感知功能介绍
- 计算机应用基础——计算机硬件(一)
- windows server中opencv运行过程中MF.dll/MFReadWrite.dll/MFPlat.DLL文件丢失问题解决
- 网站上线教程(购买域名、主机)
- 阿里云的服务器,网站域名没有备案时为什么不可以访问?
- H3C对接外部Portal+Radius认证计费系统实现mac-trigger快速认证Mac无感知认证并结合L2TP实现阿里云部署对接配置
- harbor登录报错doesn‘t contain any IP SANs问题
- 2012网易校园招聘笔试试题
- 2022中国新能源汽车客户体验价值排名:理想、小鹏、几何、极氪位居前列 | 美通社头条...
- 复制百度文库文字收费内容
- EDG一追一追平LGD,四保一阵容的Iboy从来不会让我们失望!
热门文章
- 论文复现:土卫六(Titan)大气参数计算
- 人脸对齐—3DDFA
- PHP之字符串常用函数
- 学习iOS逆向有什么用?
- linux无线网卡模拟ap,在 openSUSE 上使用 create_ap 创建虚拟 WiFi 热点来方便使用 KDE Connect 连接手机...
- 信号与系统 第二版pdf 作者:奥本海姆 翻译:刘树棠
- Realtek网卡如何识别具体型号是8111B/8111C/8111D还是8111E
- 大数据产品推荐:金蜂巢大数据集成与脱敏系统
- 固态硬盘测试软件怎么测速,AS SSD Benchmark(SSD硬盘测速工具),如何发挥最佳性能?...
- 在 COMSOL 中模拟地震波的传播