为什么Android项目mainactivity中有一个变量R_教我兄弟学Android逆向12 编写xpose模块...
作者论坛账号:会飞的丑小鸭
课程导航:
《教我兄弟学Android逆向01 编写第一个Android程序》
《教我兄弟学Android逆向02 破解第一个Android程序 》
《教我兄弟学Android逆向03 破解第一个Android游戏 》
《教我兄弟学Android逆向04 动态调试smali代码 》
《教我兄弟学Android逆向05 在smali代码中插入Log 》
《教我兄弟学Android逆向06 用AndroidStudio编写第一个so》
《教我兄弟学Android逆向07 IDA破解第一个so》
《教我兄弟学Android逆向08 IDA爆破签名验证》
《教我兄弟学Android逆向09 IDA动态破解登陆验证》
《教我兄弟学Android逆向10 静态分析反调试apk》
《教我兄弟学Android逆向11 动态调试init_array》
番外篇导航:
《教我兄弟学Android逆向番外01 apktool的使用》
《教我兄弟学Android逆向番外02 jeb工具的使用》
《教我兄弟学Android逆向番外03 Android逆向必会命令》
《教我兄弟学Android逆向番外04 OLLVM混淆环境搭建》
上一篇 《教我兄弟学Android逆向11 动态调试init_array》我带你 用IDA动态调试了init_array段和JNI_OnLoad里面的方法,虽然你学的很吃力,但是经过自己不断上网查阅资料,花了几天的时间终于把不懂的地方弄清楚了。你从网上面加了好几个Android逆向学习交流群,看到群里面有人说xposed相关的内容,你听的云里雾里的,想到之前面试的时候面试官也问过xpose相关的问题,你对xpose更是产生了浓厚的好奇心。
那么xpose到底是什么东西呢?在开始本节课之前我们先了解一下它。
原理:
Xpose是一款特殊的安卓应用,诞生于著名的XDA论坛,它的原理是替换安卓系统/system/bin目录下的app_process来控制zygote进程,使得app_pross在启动时会加载XposedBridge.jar,从而实现对zygode进程以及其创建的虚拟机的劫持,最终对系统的某些功能实现接管。
优点:
xpose可以在我们不破坏apk自身的情况下实现对函数的hook,修改函数的参数和返回值,改变函数的结构并执行我们自己的代码,用好了xposed可以对我们的逆向过程起到事半功倍的作用。
缺点:
本身不能对so中的函数进行修改 需要结合其他框架。
看完上面的介绍我想你应该对xpose有个基本的了解了 那么本节课我们一起来揭开xpose的神秘面纱。
要么学!要么不学!学和不学之间没有中间值 不学就放弃,学就要去认真的学! --致选择
编译环境:
AndroidStudio3.0.1版本
测试手机:
Nexus 4
所需框架和jar包:
1.XposedBridge的jar包
[color=rgba(0, 0, 0, 0.75)]主要功能是提供给Xpose的模块开发者所需的api 我们接下来开发xpose模块需要这个jar包
2.xposedInstaller框架
Xpose安装到手机的框架,用来加载我们编写出来的模块
下载链接:
https://pan.baidu.com/s/1fEShR4h1XK7yJIhOKtiYiw
提取码:vrxg
补充:
上面下载链接所给的xpose框架和模块都是事先编译好的,我们平常做项目时直接拿来用就可以。
xpose是一个开源项目,开源地址:
https://github.com/rovo89一 .搭建hook环境用来编译框架所需要的模块
1.打开AS在项目app目录下新建lib目录并将XposedBridgeApi-54.jar放到lib目录下 右键Add As Library将jar包添加进依赖。
2.打开项目分支src/main目录下的AndroidManifest.xml 在application标签里面添加内容如下图所示: android:name="xposedmodule"
android:value="true" /> android:name="xposeddescription"
android:value="Easy example" /> android:name="xposedminversion"
android:value="54" />
3.打开app目录下的build.gradle将
compile files('lib/XposedBridgeApi-54.jar')
更改为
provided files('lib/XposedBridgeApi-54.jar')
4.新建Hook入口类HookMain实现xposed的接口IXposedHookLoadPackage并重写方法handleLoadPackage 如图所示 这个写法格式是固定的。
public class HookMain implements IXposedHookLoadPackage {
public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
}
}
5.在src/main/assets下新建文件xposed_init并将HookMain类并将hook的主入口类以包名+类名的格式写进去。
com.example.xposed_test.HookMain
二.编写框架所需模块 Hook系统的imei检测hook环境是否配置成功
1.打开项目的MainActivity类并写一个getIMEI方法获取当前系统的imei并在程序运行的时候打印出来。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
Log.i("手机的imei是",getIMEI(this));
}
public static final String getIMEI(Context context) {
try {
//实例化TelephonyManager对象
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
//获取IMEI号
String imei = telephonyManager.getDeviceId();
//在次做个验证,也不是什么时候都能获取到的啊
if (imei == null) {
imei = "";
}
return imei;
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
2.运行程序得到当前手机的imei 355136055053345 说明hook环境配置成功。
3.打开HookMain编写Hook imei的代码
Hook一个函数需要满足三个条件:
(1)方法的包名+类名
(2)方法名
(3)方法的参数类型
对初学者这里可能会有个疑问
(1)如何找到方法的包名+类名?
(2)如何找到方法参数类型
针对上面的两个问题这里有个小技巧,对于系统函数你要hook哪个方法就先找到这个方法的定义 这里我们要hook的方法是getDeviceId 所以我们要找到它的定义位置
4.方法的包名+类名和参数类型都知道了 下面就可以按照固定格式编写hook代码了。
public class HookMain implements IXposedHookLoadPackage {
public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
//固定格式
findAndHookMethod(
"android.telephony.TelephonyManager", //要hook的包名+类名
lpparam.classLoader, //classLoader固定
"getDeviceId", //要hook的方法名
//方法参数 没有就不填
new XC_MethodHook() {
@Override
//方法执行前执行
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
}
//方法执行后执行,改方法的返回值一定要在方法执行完毕后更改
protected void afterHookedMethod(MethodHookParam param)
throws Throwable {
param.setResult("355888888888888");
}
}
);
}
}
5.将AndroidStudio编译出来的hook程序安装到手机 并将xposedInstaller框架安装到手机 打开xposed应用 在我们编写的模块后面打钩后点安装更新。
6.重启后打开模块运行查看log看到imei已经变成355888888888888说明hook成功。如果有没hook成功的同学可能环境没搭建好,重新来一次。
三.实战
安装并打开附件中的解锁程序apk发现程序需要输入密码才能解锁,接下来我将带你一起完成以下两个任务:
任务一
获得解锁码
任务二
解锁程序开启宝箱
要求:只能通过hook去开启宝箱,修改本地文件等视为无效。任务一
1.用JEB打开解锁程序apk发现程序被简单混淆,我们找到MainActivity查看反编译代码
2.经过大致的分析我们知道解锁码为当前手机的androidid经过md5加密后与固定字符串hfdcxy1011进行拼接后再进行一次md5加密得到的值截取前6位。
这里我们有三种方式可以把这个解锁码打印出来
(1)我们知道第一个a方法是最后一层的加密 我们可以hook这个a方法把它的返回值打印出来 然后取其前6位为解锁码
(2)因为整个apk只有一处对substring的调用 我们可以hook系统函数substring把函数返回值打印出来
(3)通过分析知道第二个a方法为log打印的方法 我们可以Hook这个a方法的参数 把解锁码通过log打印出来
这里我给大家演示第一种hook方法
前面我们hook imei的时候已经说过了如果要hook一个方法要满足以下三个条件:
(1)方法的包名+类名
我们找打它为com.hfdcxy.android.by.test.a
(2)方法名
这里不用多提了吧,你要hook哪个方法,方法名就是哪个这里为a
(3)方法的参数类型
String
3.下面开始编写Hook代码
我们把Hook imei的那份代码复制粘贴后放到下面,按照格式修改成hook a方法的代码。还要过滤下包名防止xposed找不到包名对应的类报错 这里的包名是Manifest下的包名。
com.ss.android.ugc.aweme
HookMain类
public class HookMain implements IXposedHookLoadPackage {
public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
//固定格式 因为是系统函数所以无需过滤包名
findAndHookMethod(
"android.telephony.TelephonyManager", //要hook的包名+类名
lpparam.classLoader, //classLoader固定
"getDeviceId", //要hook的方法名
//方法参数 没有就不填
new XC_MethodHook() {
@Override
//方法执行前执行
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
}
//方法执行后执行,改方法的返回值一定要在方法执行完毕后更改
protected void afterHookedMethod(MethodHookParam param)
throws Throwable {
param.setResult("355888888888888");
}
}
);
if(!lpparam.packageName.equals("com.ss.android.ugc.aweme")) //这里过滤一下包名
{
return;
}
Log.i("Tiger_test","hook进入解锁程序");
//Hook a方法
findAndHookMethod(
"com.hfdcxy.android.by.test.a", //要hook的包名+类名
lpparam.classLoader, //classLoader固定
"a", //要hook的方法名
String.class, //方法的参数类型 这里为String类
new XC_MethodHook() {
@Override
//方法执行前执行
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
}
//方法执行后执行,改方法的返回值一定要在方法执行完毕后更改
protected void afterHookedMethod(MethodHookParam param)
throws Throwable {
Log.i("Tiger_test","a方法的第一个参数为:"+param.args[0].toString());//param.args[0]为方法的第一个参数,同理param.args[1]为第二个参数
Log.i("Tiger_test","a方法的返回值为:"+param.getResult());//方法的返回值只能放在afterHookedMethod中获取
//以下为修改
//param.args[0] = "235wtwerteq" //如果要修改第一个参数可以直接这样写
//param.setResult("7f769c0f91efd402a23d63627f48f03e"); //param.setResult修改方法的返回值
}
}
);
}
}
4.编译项目并安装到手机,xposed框架打钩模块,安装并更新重启后打开解锁程序随便输入一个解锁码点击解锁,可以看到a方法的参数和返回值已经被我们通过log打印出来了,因为a方法在程序中被调用了两次所以这里打印了两次。
我们只需看最后一次的返回值即可,取前6位可以看到我的手机的解锁码为4567d2
5.输入这个解锁码点击解锁 出现如图所示的界面说明解锁码正确 任务一获取解锁码也就完成了。
下面我们开看下任务二
1.任务二要求解锁程序开启宝箱,我们看到这个界面有两个按钮一个是充值1金币,另一个按钮是开启宝箱。测试发现这里我不断手点充值1金币把金币总量充值到100还是开启不了宝箱,提示金币不足,请充值。
2.我们继续分析代码,发现输入正确的解锁码后程序会跳转到DrawActivity类,这个类中有两个onClick 第一个是充值的onClick第二个是开启宝箱,分析发现只有金币大于9999时才能开启宝箱。
这里我们有两种方法去开启宝箱
(1)用手不断点击充值1金币,需要点9999次,这无疑是太耗费时间的,所以不可取。
(2)直接Hook第一个onClick里面的a方法把第三个参数改成10000即可开启宝箱。
3.编写hook代码
找到hook所需要的三个条件:
(1)方法的包名+类名
我们找打它为com.hfdcxy.android.by.test.b
(2)方法名
这里不用多提了吧,你要hook哪个方法,方法名就是哪个这里为a
(3)方法的参数类型 这里有三个
SharedPreferences
TextView
int
HookMain类
public class HookMain implements IXposedHookLoadPackage {
public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
//固定格式
findAndHookMethod(
"android.telephony.TelephonyManager", //要hook的包名+类名
lpparam.classLoader, //classLoader固定
"getDeviceId", //要hook的方法名
//方法参数 没有就不填
new XC_MethodHook() {
@Override
//方法执行前执行
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
}
//方法执行后执行,改方法的返回值一定要在方法执行完毕后更改
protected void afterHookedMethod(MethodHookParam param)
throws Throwable {
param.setResult("355888888888888");
}
}
);
if(!lpparam.packageName.equals("com.ss.android.ugc.aweme")) //这里过滤一下包名
{
return;
}
Log.i("Tiger_test","hook进入解锁程序");
//Hook a方法
findAndHookMethod(
"com.hfdcxy.android.by.test.a", //要hook的包名+类名
lpparam.classLoader, //classLoader固定
"a", //要hook的方法名
String.class, //方法的参数类型 这里为String类
new XC_MethodHook() {
@Override
//方法执行前执行,修改参数的地方
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
}
//方法执行后执行,修改方法的返回值的地方
protected void afterHookedMethod(MethodHookParam param)
throws Throwable {
Log.i("Tiger_test","a方法的第一个参数为:"+param.args[0].toString());//param.args[0]为方法的第一个参数,同理param.args[1]为第二个参数
Log.i("Tiger_test","a方法的返回值为:"+param.getResult());//方法的返回值只能放在afterHookedMethod中获取
//以下为修改
//param.args[0] = "235wtwerteq" //如果要修改第一个参数可以直接这样写
//param.setResult("7f769c0f91efd402a23d63627f48f03e"); //param.setResult修改方法的返回值
}
}
);
findAndHookMethod(
"com.hfdcxy.android.by.test.b", //要hook的包名+类名
lpparam.classLoader, //classLoader固定
"a", //要hook的方法名
SharedPreferences.class, //方法的参数类型
TextView.class, //方法的参数类型
int.class, //方法的参数类型
new XC_MethodHook() {
@Override
//方法执行前执行,修改参数的地方
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.args[2] = 10000; //注意修改参数要放在beforeHookedMethod里面写
Log.i("Tiger_test","成功充值一万金币");
}
//方法执行后执行,修改方法的返回值的地方
protected void afterHookedMethod(MethodHookParam param)
throws Throwable {
}
}
);
}
}
4.编译xposed框架安装模块,打开解锁程序输入解锁码后点击充值1金币,然后点击开启宝箱。显示弹框开启成功,获得xposed新手称号。
四.总结
本节课我们首先了解了xpose的基本原理并一起搭建了xpose的hook环境。接下来我们又一起用xpose破解了解锁程序这个apk,通过对本节课的学习我想你对xpose已经有了一个全新的认识。环境搭建有问题的的同学可以直接把下面的课堂Demo导入到项目中去学习,课堂上面讲解的内容一定要多加练习,看不懂的要多百度,百度上面有很多关于xpose的教程,各种教程对比着来学习,总能理解的。五.课后作业
1.hook本节课例子中的其他函数获取解锁码
2.hook修改极品美女找茬游戏中的金币余额为999
游戏下载链接
链接:https://pan.baidu.com/s/1HdW4CgJqaqr4IorOB1Z7Mw
提取码:7hud
六.进阶
课堂作业完成后请参考以下两条链接,并自己编写对应模块练习里面的例子,完成对xpose的进阶。
http://www.cnblogs.com/gordon0918/p/6732100.html
https://bbs.pediy.com/thread-225190-1.htm
课堂Demo
链接:https://pan.baidu.com/s/1uTkofcZIORJeAscXIRaf6g
提取码:6vi6
--官方论坛
www.52pojie.cn
--推荐给朋友
公众微信号:吾爱破解论坛
或搜微信号:pojie_52
为什么Android项目mainactivity中有一个变量R_教我兄弟学Android逆向12 编写xpose模块...相关推荐
- 为什么Android项目mainactivity中有一个变量R_博客笔记大汇总,Android优化总结篇
博客笔记大汇总[16年3月到至今],包括Java基础及深入知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,当然也在工作之余收集了大量的面试题,长期更新维护并 ...
- 为什么Android项目mainactivity中有一个变量R_安卓4:第一个安卓程序 AS 安卓项目结构解析 手机运行app 模拟器运行app...
学习于:https://www.bilibili.com/video/av22836860?p=2 首先,要知道AS的一个基本模型,1个Android project可以有多个module,而每个mo ...
- 为什么Android项目mainactivity中有一个变量R_【Android开发入门教程】二.Android应用程序结构分析!...
一.新建HelloWorld项目: 1.打开Eclipse,点击"File"->"New"->"Project"-Android ...
- 《教我兄弟学Android逆向01 编写第一个Android程序》
前言 之所以准备写这一系列逆向的教程是因为有一些同学私信我说自己想学习Android逆向但是不知道怎么去学习 包括自己身边的一些计算机专业的同学 在大学里面老师讲的那些东西要么是自己不感兴趣 要么是自 ...
- 《教我兄弟学Android逆向07 IDAPro破解第一个so》
上一篇 < 教我兄弟学Android逆向06 用AndroidStudio编写第一个so>我带你用AS编写了第一个so 现在回顾一下 首先我创建了一个myJNI类 里面包含一个Native ...
- 《教我兄弟学Android逆向03 破解第一个Android游戏 》
上一篇 <教我兄弟学Android逆向02 破解第一个Android程序 >我带着你破解了我们自己编的一个小程序 里面我分析并讲解的一些smali语法你都记住了 给你布置的课后作业你发 ...
- 学android逆向能干,教我兄弟学Android逆向04
8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? <教我兄弟学Android逆向>04的课后作业. 教程笔记 将apk反编译成smali文件 AndroidK ...
- 《教我兄弟学Android逆向10 静态分析反调试apk》
上一篇 <教我兄弟学Android逆向09 IDA动态破解登陆验证>我带你分析了黑宝宝.apk,并且用IDA动态调试破解了登陆验证 看上节课你学习的不错 这节课给你带来的是过反调试的教程 ...
- 《教我兄弟学Android逆向11 动态调试init_array》
上一篇 <教我兄弟学Android逆向10 静态分析反调试apk>我带你用jeb+IDA静态分析了反调试apk,并且了解了init_array和jnionload的执行顺序 通过静态pat ...
- 教我兄弟学Android逆向
作者论坛****账号:会飞的丑小鸭 课程导航: <教我兄弟学Android逆向01 编写第一个Android程序> <教我兄弟学Android逆向02 破解第一个Android程序 ...
最新文章
- 【JavaScript总结】JavaScript语法基础:BOM
- spring Batch实现数据库大数据量读写
- 终于完成需求模块开发了,jQuery实现的效果,PHP操作数据库
- 不要相信修改注册表EnablePrefetcher文件达到加速开机速度的说法
- uitableviw 自适应高度
- 程序员的十个层次 你属于哪一层?小菜看后
- JAVA月数输入24回车后变成12_Java语言程序设计(一)自考2012年10月真题
- macOS下Apache+nginx+mysql+php多版本切换的配置
- 全国计算机等级考试题库二级C操作题100套(第91套)
- FPGA硬件学习基础知识点总结(1)
- linux系统备份和恢复
- Html-Css标签lable中定义宽度需要其他的支持
- 1.1.0-简介-P10-分布式事务的解决方案
- arp协议属于哪一层_ARP的攻击与防御
- 关于安装和使用IAR的出现的一些错误
- 苹果手机来电归属地_手机号码归属地能否取消?
- mov视频怎么转换成mp4格式?
- 数学家吴文俊批判“中国式奥数”:害人害数学
- Rush Hour Puzzle
- Ubuntu中安装和使用vim
热门文章
- Scintilla教程(4): 复制粘贴以及撤销回退
- matlab时域频域信号特征提取资料整合
- 禁用计算机声卡设备,电脑声音被禁用了怎么办
- 服务器系统2008网络发现,Windows Server 2008中解决局域网共享发现问题
- 小马哥---高仿山寨三星S8出世 谨防购买到假货!! 高仿三星S8 s305刷机拆机主板图示
- linux中的计划任务
- Android开发环境搭建笔记总结
- window下ruby的下载与gem安装
- 查岗神器!如何查看连接过的WiFi记录+详细信息+密码找回
- Mac系统MATLAB_R2018a软件CVX下载及安装