首页
文章分类
逆向网安
中英演讲
杂类教程
学习笔记
前端开发
汇编
数据库
.NET
服务器
Python
Java
PHP
Git
算法
安卓开发
生活记录
读书笔记
作品发布
人体健康
网上邻居
留言板
欣赏小姐姐
关于我
Search
登录
1
利用AList搭建家庭个人影音库
4,449 阅读
2
浅尝Restful Fast Request插件,一句话完成 逆向过程
3,391 阅读
3
i茅台app接口自动化csharp wpf实现,挂机windows服务器每日自动预约
2,411 阅读
4
完美破解The Economist付费墙
2,286 阅读
5
青龙面板基本使用并添加修改微信/支付宝步数脚本
1,760 阅读
Search
标签搜索
PHP
Laravel
前端
csharp
安卓逆向
JavaScript
Python
Java
爬虫
抓包
Git
winform
android
Fiddler
Vue
selenium
LeetCode
每日一题
简单题
docker
Hygge
累计撰写
94
篇文章
累计收到
439
条评论
首页
栏目
逆向网安
中英演讲
杂类教程
学习笔记
前端开发
汇编
数据库
.NET
服务器
Python
Java
PHP
Git
算法
安卓开发
生活记录
读书笔记
作品发布
人体健康
页面
网上邻居
留言板
欣赏小姐姐
关于我
用户登录
搜索到
5
篇与
的结果
2023-07-26
第四篇Android逆向:动态调试&Log插桩
一、基本概念1.1 动态调试动态调试是指自带的调试器跟踪自己软件的运行,可以在调试的过程中知道参数或者局部变量的值记忆捋清代码运行的先后顺序。多用于爆破注册码(CTF必备技能)1.2 Log插桩Log插桩是指在反编译APK文件时,在对应的smali文件里,添加相应的smali代码,将程序的关键信息,以log日志的形式进行输出。二、动态调试2.1 修改debug权限方法一:在AndroidManifest.xml里添加可调试权限android:debuggable="true"方法二:XappDebug模块hook对应的app项目地址XappDebughttps://github.com/Palatis/XAppDebug方法三:Magisk命令(重启失效)1. adb shell # adb进入命令行模式 2. su # 切换至超级用户 3. magisk resetprop ro.debuggable 1 4. stop;start; # 一定要通过该方式重启方法四:刷入MagiskHide Props Config模块(永久有效)一般来说,在4选项中如果有ro.debuggable那就直接修改没有的话就选5修改ro.debuggable的值为12.2 端口转发以及开启adb权限版本后点击七次开启开发者模式并开启adb调试权限夜神模拟器: adb connect 127.0.0.1:620012.3 下端点Jeb里使用ctrl + b下断点2.4 debug模式启动adb shell am start -D -n com.zj.wuaipojie/.ui.MainActivity adb shell am start -D -n 包名/类名am start -n 表示启动一个activityam start -D 表示将应用设置为可调试模式2.5 Jeb附加调试进程快捷键作用F6进入方法F7从方法中跳出来F8 R运行到光标处三、修改debug权限实操3.1 修改AndroidManifest3.2 XAppDebug模块3.3 Magisk命令上文3.4 MigiskHide Props Config安装模块打开Mt管理器终端模拟器输入props进入模块然后按照上文操作即可四、追码练习4.1 开发者选项开启USB调试,目标App要开启Debug调试4.2 apk拖入JEB,搜索关键字密钥错误发现关键点是if(this.check(((EditText)this.findViewById(0x7F0800AC)).getText().toString())) { // id:edit_check Context context0 = (Context)this; Toast.makeText(context0, "恭喜你,密钥正确!", 1).show(); SPUtils.INSTANCE.saveInt(context0, "level", 3); return; } Toast.makeText(((Context)this), "密钥错误哦,再想想!", 1).show();4.3 继续追check方法,双击方法名进入public final boolean check(String s) { int v = 0; Integer integer0 = null; if(!StringsKt.startsWith$default(s, "flag{", false, 2, null)) { return false; } if(!StringsKt.endsWith$default(s, "}", false, 2, null)) { return false; } String s1 = s.substring(5, s.length() - 1); Intrinsics.checkNotNullExpressionValue(s1, "this as java.lang.String…ing(startIndex, endIndex)"); String s2 = SPUtils.INSTANCE.getString(((Context)this), "id", ""); if(s2 != null) { integer0 = (int)s2.length(); } int v1 = 1000; Intrinsics.checkNotNull(integer0); int v2 = (int)integer0; if(v2 >= 0) { while(true) { v1 += -7; if(v == v2) { break; } ++v; } } byte[] arr_b = Encode.encode(s2 + v1).getBytes(Charsets.UTF_8); Intrinsics.checkNotNullExpressionValue(arr_b, "this as java.lang.String).getBytes(charset)"); return Intrinsics.areEqual(s1, Base64Utils.INSTANCE.encodeToString(arr_b)); }首先密钥必须以flag{开头,以}结尾然后回取出除开头和结尾中间的内容和一个base64加密的字符串进行比对base64加密的数据是由s2(打开软件注册的用户名) + v1(整数常量组成),当s2固定时base64加密的结果也就固定了。下一步就需要对加密结果打断点4.4 app开启调试4.5 Jeb附加调试进程然后再去应用模拟验证一下已经成功断点了,右边的寄存器也能看到局部变量此时已拿到密钥:5YaF57OkDAUM五、Log插桩5.1 日志插桩dex注入5.2 代码关键处添加输出invoke-static {对应寄存器}, Lcom/mtools/LogUtils;->v(Ljava/lang/Object;)V5.3 使用算法助手查看日志然后启动 去触发一下关键点拿到密钥实战反编译发现程序逻辑如下:可以直接通过程序跑出来结果:let str = 'e10adc3949ba59abbe56e057f20f883e'; // 对 123456 进行md5 再转 十六进制的结果 let sb = '' for(let i = 0;true;i+=2){ if(i >= str.length){ console.log(sb); return sb == '123'; } // 将 str i位置上的字符追加到sb中 sb += str.charAt(i); }引用1.《安卓逆向这档事》五、1000-7=?&动态调试&Log插桩:https://www.52pojie.cn/thread-1714727-1-1.html2.吾爱破解安卓逆向入门教程《安卓逆向这档事》五、1000-7? & 动态调试&Log插桩:https://www.bilibili.com/video/BV1hg411q7dj/3.JEB动态调试Smali-真机/模拟器(详细,新手必看):https://www.52pojie.cn/thread-1598242-1-1.html4.Log简易打印工具,超简单的调用方法:https://www.52pojie.cn/thread-411454-1-1.html5.Android修改ro.debuggable 的四种方法:https://blog.csdn.net/jinmie0193/article/details/111355867
2023年07月26日
327 阅读
0 评论
0 点赞
2023-07-25
第三篇Android逆向:去除广告和弹窗
一、基本概念1.1 安卓四大组件组件描述Activity(活动)在应用中的一个Activity可以用来表示一个界面,意思可以理解为“活动”,即一个活动开始,代表 Activity组件启动,活动结束,代表一个Activity的生命周期结束。一个Android应用必须通过Activity来运行和启动,Activity的生命周期交给系统统一管理。Service(服务)Service它可以在后台执行长时间运行操作而没有用户界面的应用组件,不依赖任何用户界面,例如后台播放音乐,后台下载文件等。Broadcast Receiver(广播接收器)一个用于接收广播信息,并做出对应处理的组件。比如我们常见的系统广播:通知时区改变、电量低、用户改变了语言选项等。Content Provider(内容提供者)作为应用程序之间唯一的共享数据的途径,Content Provider主要的功能就是存储并检索数据以及向其他应用程序提供访问数据的接口。Android内置的许多数据都是使用Content Provider形式,供开发者调用的(如视频,音频,图片,通讯录等)1.2 activity的切换<!---声明实现应用部分可视化界面的 Activity,必须使用 AndroidManifest 中的 <activity> 元素表示所有 Activity。系统不会识别和运行任何未进行声明的Activity。-----> <activity android:label="@string/app_name" android:name="com.zj.wuaipojie.ui.MainActivity" android:exported="true"> <!--当前Activity是否可以被另一个Application的组件启动:true允许被启动;false不允许被启动--> <!---指明这个activity可以以什么样的意图(intent)启动---> <intent-filter> <!--表示activity作为一个什么动作启动,android.intent.action.MAIN表示作为主activity启动---> <action android:name="android.intent.action.MAIN" /> <!--这是action元素的额外类别信息,android.intent.category.LAUNCHER表示这个activity为当前应用程序优先级最高的Activity--> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.zj.wuaipojie.ui.ChallengeFirst" /> <activity android:name="com.zj.wuaipojie.ui.ChallengeFifth" android:exported="true" /> <activity android:name="com.zj.wuaipojie.ui.ChallengeFourth" android:exported="true" /> <activity android:name="com.zj.wuaipojie.ui.ChallengeThird" android:exported="false" /> <activity android:name="com.zj.wuaipojie.ui.ChallengeSecond" android:exported="false" /> <activity android:name="com.zj.wuaipojie.ui.AdActivity" /> 启动广告流程:启动Activity->广告Activity->主页Activity修改方法:1.修改加载时间2.Acitivity切换定位,修改Intent的Activity类名switch (position) { case 0: Intent intent = new Intent(); intent.setClass(it.getContext(), ChallengeFirst.class); it.getContext().startActivity(intent); return; case 1: Intent intent2 = new Intent(); intent2.setClass(it.getContext(), ChallengeSecond.class); it.getContext().startActivity(intent2); return; case 2: Intent intent3 = new Intent(); //new一个Intent, intent3.setClass(it.getContext(), AdActivity.class); //传入要切换的Acitivity的类名 it.getContext().startActivity(intent3); //启动对应的Activity return; case 3: Intent intent4 = new Intent(); intent4.setClass(it.getContext(), ChallengeFourth.class); it.getContext().startActivity(intent4); return; default: return; }1.3 Activity生命周期函数名称描述onCreate()一个Activity启动后第一个被调用的函数,常用来在此方法中进行Activity的一些初始化操作。例如创建View,绑定数据,注册监听,加载参数等。onStart()当Activity显示在屏幕上时,此方法被调用但此时还无法进行与用户的交互操作。onResume()这个方法在onStart()之后调用,也就是在Activity准备好与用户进行交互的时候调用,此时的Activity一定位于Activity栈顶,处于运行状态。onPause()这个方法是在系统准备去启动或者恢复另外一个Activity的时候调用,通常在这个方法中执行一些释放资源的方法,以及保存一些关键数据。onStop()这个方法是在Activity完全不可见的时候调用的。onDestroy()这个方法在Activity销毁之前调用,之后Activity的状态为销毁状态。onRestart()当Activity从停止stop状态恢进入start状态时调用状态。1.4 弹窗定位&堆栈分析修改方法:1.修改xml中的versioncode2.Hook弹窗(推荐算法助手开启弹窗定位)3.修改dex弹窗代码4.抓包修改响应体(也可以路由器拦截)1.5 布局优化1.开发者助手抓布局2.MT管理器xml搜索定位3.修改xml代码android:visibility="gone"二、练习2.1 去开屏广告首先定位到这个Activity弹出的广告的是com.zj.wuaipojie.ui.AdActivity,mt管理器进行搜索类名.method private final loadAd()V .registers 5 .line 27 new-instance v0, Landroid/os/Handler; invoke-direct {v0}, Landroid/os/Handler;-><init>()V new-instance v1, Lcom/zj/wuaipojie/ui/AdActivity$$ExternalSyntheticLambda0; invoke-direct {v1, p0}, Lcom/zj/wuaipojie/ui/AdActivity$$ExternalSyntheticLambda0;-><init>(Lcom/zj/wuaipojie/ui/AdActivity;)V // v2赋值0xbb8 即3000毫秒 = 3秒 const-wide/16 v2, 0xbb8 // 调用延时的方法postDelayed 意为3秒后广告结束 切入主窗口 // 这里的参数 vo 代表 Handler的引用 v1 表示Runnable的引用 v2表示时长的引用 v3没有用到忽略 invoke-virtual {v0, v1, v2, v3}, Landroid/os/Handler;->postDelayed(Ljava/lang/Runnable;J)Z return-void .end method2.1.1 修改广告时长了解v2寄存器存储广告时长后可以直接赋值为0x0变相实现跳过但其实还是会跳转到AdActivity2.1.2 修改Activity切换重新搜索Lcom/zj/wuaipojie/ui/AdActivity;类型选择代码,目的是定位在smali层面哪里调用了AdActivity就可以找到切换Activity的逻辑。2.1.3 修改AndroidManifest将启动类的名称直接修改为ChallengeThird不推荐,容易跳过应用内部加载数据的逻辑2.2 跳弹窗广告2.2.1 版本更新广告方式一:修改AndroidManifest.xml中的versionCode<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1"># 由1改成2即可过 </manifest> 方式二:直接注释掉弹窗代码1.直接根据文件内容搜索有新版本需要更新 得到布局文件为y4.xml2.使用Arsc编辑器打开resources.arsc得到布局名称为fragment_update,再在Dex编辑器++中根据代码搜索,得到对应的资源Id0x7f0b003a在搜索整数十六进制,拿到关键类DialogUtilsKt,这是一个工具类,只需要找到在主Activity中调用的位置进行注释即可。3.定位DialogUtilsKt的使用注释掉即可。2.2.2 普通弹窗分别是可回退跳过和不可回退跳过的类型。2.2.2.1 算法助手的使用勾选上后原先无法使用回退的弹窗也可以进行返回取消了。查看使用日志分析发现是在ChallengeThird.onCreate生命周期内调用的方法。 protected void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView(2131427361); Context context = (Context) this; Builder builder = new Builder(context); builder.setTitle("这是二号广告标题"); builder.setMessage("这是二号广告内容"); builder.setCancelable(false); String str = "前往论坛"; builder.setPositiveButton(str, new ExternalSyntheticLambda1(this)); String str2 = "退出软件"; builder.setNegativeButton(str2, ExternalSyntheticLambda2.INSTANCE); builder.show(); new CommonDialog.Builder(context).setMessage("一号广告弹窗已就位").setNegativeButton(str2, ExternalSyntheticLambda3.INSTANCE).setMessageColor(-16777216).setPositiveButton(str, new ExternalSyntheticLambda0(this)).setWith(0.8f).create().show(); checkUpdate(); }直接切到smali下将两个show的调用注释即可。2.3 去横幅遮挡广告1.首先定位元素Id(Hex):0x7f0801ca直接将宽高改为0dp或添加属性android:visibility="gone"三、课后作业这里发现有三个方法 三处show调用。方法一: show全部注释掉即可。方法二:查看每个方法的调用找到真正的函数调用,并从调用处解决引用1.《安卓逆向这档事》四、恭喜你获得广告&弹窗静默卡:https://www.52pojie.cn/thread-1706691-1-1.html2.吾爱破解安卓逆向入门教程《安卓逆向这档事》四、恭喜你获得广告&弹窗静默卡:https://www.bilibili.com/video/BV14v4y1D7yA/3.算法助手!基于Xposed的通用Hook工具:https://bbs.kanxue.com/thread-267985.htm
2023年07月25日
406 阅读
0 评论
0 点赞
2023-07-24
第二篇Android逆向:初识smali破解vip
一、基本概念1.什么是JVM、Dalvik、ARTJVM是JAVA虚拟机,运行JAVA字节码程序Dalvik是Google专门为Android设计的一个虚拟机,Dalvik有专属的文件执行格式dex(Dalvik executable)Art(Android Runtime)相当于Dalvik的升级版,本质与Dalvik无异2.smali及其语法smali是Dalvik的寄存器语言,smali代码是dex反编译而来的。关键字名称注释.class类名.super父类名,继承的上级类名名称.source源名.field变量.method方法名.register寄存器.end method方法名的结束public公有protected半公开,只有同一家人才能用private私有,只能自己使用.parameter方法参数.prologue方法开始.line xxx位于第xxx行数据类型对应smali类型java类型注释Vvoid无返回值Zboolean布尔值类型,返回0或1Bbyte字节类型,返回字节Sshort短整数类型,返回数字Cchar字符类型,返回字符Iint整数类型,返回数字Jlong (64位 需要2个寄存器存储)长整数类型,返回数字Ffloat单浮点类型,返回数字Ddouble (64位 需要2个寄存器存储)双浮点类型,返回数字stringString文本类型,返回字符串Lxxx/xxx/xxxobject对象类型,返回对象常用指令关键字注释const重写整数属性,真假属性内容,只能是数字类型const-string重写字符串内容const-wide重写长整数类型,多用于修改到期时间。return返回指令if-eq全称equal(a=b),比较寄存器ab内容,相同则跳if-ne全称not equal(a!=b),ab内容不相同则跳if-eqz全称equal zero(a=0),z即是0的标记,a等于0则跳if-nez全称not equal zero(a!=0),a不等于0则跳if-ge全称greater equal(a>=b),a大于或等于则跳if-le全称little equal(a<=b),a小于或等于则跳goto强制跳到指定位置switch分支跳转,一般会有多个分支线,并根据指令跳转到适当位置iget获取寄存器数据其余指令可用语法工具查询定位方法:搜索弹窗关键字、抓取按钮id例子://一个私有、静态、不可变的方法 方法名 .method private static final onCreate$lambda-2(Lkotlin/jvm/internal/Ref$IntRef;Lcom/zj/wuaipojie/ui/ChallengeSecond;Landroid/widget/ImageView;Landroid/widget/ImageView;Landroid/widget/ImageView;Landroid/view/View;)Z //(这里面是方法的参数)这里是方法返回值类型,表示布尔值类型,返回假或真 .registers 7 //寄存器数量 .line 33 //代码所在的行数 iget p0, p0, Lkotlin/jvm/internal/Ref$IntRef;->element:I //读取p0(第一个参数,参考寄存器知识)中element的值赋值给p0 const/4 p5, 0x1 //p5赋值1 const/16 v0, 0xa //v0赋值10,在16进制里a表示10 if-ge p0, v0, :cond_15 //判断p0的值是否大于或等于v0的值(即p0的值是否大于或等于10),如果大于或等于则跳转到:cond_15 .line 34 //以下是常见的Toast弹窗代码 check-cast p1, Landroid/content/Context; //检查Context对象引用 const-string p0, "请先获取10个硬币哦" //弹窗文本信息,把""里的字符串数据赋值给p0 check-cast p0, Ljava/lang/CharSequence; //检查CharSequence对象引用 invoke-static {p1, p0, p5}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast; //将弹窗文本、显示时间等信息传给p1 move-result-object p0 //结果传递给p0 invoke-virtual {p0}, Landroid/widget/Toast;->show()V //当看到这个Toast;->show你就应该反应过来这里是弹窗代码 goto :goto_31 //跳转到:goto_31 :cond_15 //跳转的一个地址 invoke-virtual {p1}, Lcom/zj/wuaipojie/ui/ChallengeSecond;->isvip()Z //判断isvip方法的返回值是否为真(即结果是否为1) move-result p0 //结果赋值给p0 if-eqz p0, :cond_43 //如果结果为0则跳转cond_43地址 const p0, 0x7f0d0018 //在arsc中的id索引,这个值可以进行查询 .line 37 invoke-virtual {p2, p0}, Landroid/widget/ImageView;->setImageResource(I)V //设置图片资源 const p0, 0x7f0d0008 .line 38 invoke-virtual {p3, p0}, Landroid/widget/ImageView;->setImageResource(I)V const p0, 0x7f0d000a .line 39 invoke-virtual {p4, p0}, Landroid/widget/ImageView;->setImageResource(I)V .line 40 sget-object p0, Lcom/zj/wuaipojie/util/SPUtils;->INSTANCE:Lcom/zj/wuaipojie/util/SPUtils; check-cast p1, Landroid/content/Context; const/4 p2, 0x2 //p2赋值2 const-string p3, "level" //sp的索引 invoke-virtual {p0, p1, p3, p2}, Lcom/zj/wuaipojie/util/SPUtils;->saveInt(Landroid/content/Context;Ljava/lang/String;I)V //写入数据 goto :goto_50 //跳转地址 :cond_43 check-cast p1, Landroid/content/Context; const-string p0, "\u8bf7\u5148\u5145\u503c\u5927\u4f1a\u5458\u54e6\uff01" //请先充值大会员哦! check-cast p0, Ljava/lang/CharSequence; invoke-static {p1, p0, p5}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast; move-result-object p0 invoke-virtual {p0}, Landroid/widget/Toast;->show()V :goto_50 return p5 //返回p5的值 .end method //方法结束 //判断是否是大会员的方法 .method public final isvip()Z .registers 2 const/4 v0, 0x0 //v0赋值0 return v0 //返回v0的值 .end method修改方法:修改判断、强制跳转、修改寄存器的值3.寄存器在smali里的所有操作都必须经过寄存器来进行:本地寄存器用v开头数字结尾的符号来表示,如v0、 v1、v2。 参数寄存器则使用p开头数字结尾的符号来表示,如p0、p1、p2。特别注意的是,p0不一定是函数中的第一个参数,在非static函数中,p0代指“this",p1表示函数的第一个 参数,p2代表函数中的第二个参数。而在static函数中p0才对应第一个参数(因为Java的static方法中没有this方法)二、实现修改教程中使用的是jadx来分析smail代码,然后通过mt管理器打包修改。最近逛看雪论坛发现一个神器GDA,可以分析并直接完成打包。目标: 长按一键三连按钮可以点亮图标2.1 定位关键类2.1.1 搜索关键字直接搜索关键字大会员2.1.2 抓取按钮id分析界面布局,获取控件Id-Hex切换Mt管理器,使用Dex编辑器++打开Classes.dex,搜索控件2.2 修改方式2.2.1 修改判断分析图按下R重打包运行2.2.2 强制跳转2.2.3 修改寄存器的值三、实战demo搜索关键字登录失败可以直接拿到密钥引用1.《安卓逆向这档事》三、初识smali,vip终结者:https://www.52pojie.cn/thread-1701353-1-1.html2.[原创]基于Smali即时编译的DEX静态补丁技术实现:https://bbs.kanxue.com/thread-278098.htm3.GDA-android-reversing-Tool:https://github.com/charles2gan/GDA-android-reversing-Tool4.GJoy Dex Analyzer(GDA),亚洲第一款全交互式的现代反编译器,同时也是世界上最早实现的dalvik字节码反编译器。:http://www.gda.wiki:9090/
2023年07月24日
333 阅读
0 评论
0 点赞
2023-07-23
第一篇Android逆向:App双开、汉化、基本内容修改
一、基本概念1.1 Magisk介绍Magisk 是一套用于定制 Android 的开源软件,支持高于 Android 5.0 的设备。以下是一些功能亮点:MagiskSU:为应用程序提供 root 访问权限Magisk 模块:通过安装模块修改只读分区MagiskHide:从根检测 / 系统完整性检查中隐藏 Magisk(Shamiko)MagiskBoot : 最完整的安卓启动镜像解包和重新打包工具1.2 Apk结构apk 全称 Android Package,它相当于一个压缩文件,只要在电脑上将apk后缀改为zip即可解压。文件注释assets目录存放APK的静态资源文件,比如视频,音频,图片等lib 目录armeabi-v7a基本通用所有android设备,arm64-v8a只适用于64位的android设备,x86常见用于android模拟器,其目录下的.so文件是c或c++编译的动态链接库文件META-INF目录保存应用的签名信息,签名信息可以验证APK文件的完整性,相当于APK的身份证(验证文件是否被修改)res目录res目录存放资源文件,包括图片,字符串等等,APK的脸蛋由他的layout文件设计AndroidMainfest.xml文件APK的应用清单信息,它描述了应用的名字,版本,权限,引用的库文件等等信息classes.dex文件classes.dex是java源码编译后生成的java字节码文件,APK运行的主要逻辑resources.arsc文件resources.arsc是编译后的二进制资源文件,它是一个映射表,映射着资源和id,通过R文件中的id就可以找到对应的资源二、 双开及原理双开:简单来说,就是手机同时运行两个或多个相同的应用,例如同时运行两个微信原理解释修改包名让手机系统认为这是2个APP,这样的话就能生成2个数据存储路径,此时的多开就等于你打开了两个互不干扰的APP修改Framework对于有系统修改权限的厂商,可以修改Framework来实现双开的目的,例如:小米自带多开通过虚拟化技术实现虚拟Framework层、虚拟文件系统、模拟Android对组件的管理、虚拟应用进程管理 等一整套虚拟技术,将APK复制一份到虚拟空间中运行,例如:平行空间以插件机制运行利用反射替换,动态代理,hook了系统的大部分与system—server进程通讯的函数,以此作为“欺上瞒下”的目的,欺骗系统“以为”只有一个apk在运行,瞒过插件让其“认为”自己已经安装。例如:VirtualApp2.1 修改包名NT管理器安装包提取点击提取的Apk,选择APK共存修改包名简单情况下实现APK共存2.2 修改Framework2.3 通过虚拟化技术实现2.4 以插件机制运行三、 汉化APK汉化:使用专门的工具对外文版的软件资源进行读取、翻译、修改、回写等一系列处理,使软件的菜单、对话框、提示等用户界面显示为中文,而程序的内核和功能保持不变,这个过程即为软件汉化基本上字符串都是在arsc里,建议一键汉化,然后再润色。少量没汉化到的字符串参考视频中的方法定位去逐个汉化。3.1 流程图这里还需要注意的是,如果要直装应用,那就应该先签名安装,看看是否有签名校验导致的闪退简单的汉化有三个分支Arsc汉化Xml汉化Dex汉化教程中还提到较为复杂的so层面的字符串资源3.2 Xml汉化汉化前:1.全局搜索文件内容Hello 52pojie2.字符常量池打开资源文件3.字符串编辑4.更新并自动签名5.完成3.3 Arsc汉化接着替换下方的俄文,使用开发者助手检索界面资源复制文本后再次使用MT管理器进行搜索Я не могу поверить, что это работает, почему?选择翻译模式定位到要翻译的字符串后进行编辑完成汉化3.4 dex汉化这次要替换掉 Reverse determines height, development determines depth.这段文本还是先搜索再在Dex编辑器++中搜索直接进行替换即可完成汉化四、修改应用名称和图标4.1 初识AndroidManifest.xmlAndroidManifest.xml文件是整个应用程序的信息描述文件,定义了应用程序中包含的Activity,Service,Content provider和BroadcastReceiver组件信息。每个应用程序在根目录下必须包含一个AndroidManifest.xml文件,且文件名不能修改。它描述了package中暴露的组件,他们各自的实现类,各种能被处理的数据和启动位置。属性定义versionCode版本号,主要用来更新,例如:12versionName版本名,给用户看的,例如:1.2package包名,例如:com.zj.52pj.demouses-permission android:name=""应用权限,例如:android.permission.INTERNET 代表网络权限android:label="@string/app_name"应用名称android:icon="@mipmap/ic_launcher"应用图标路径android:debuggable="true"应用是否开启debug权限4.2 修改测试切换到NT管理器修改成功五、修改应用内图标对图中的表情包进行替换首先找到对应的布局文件,查看ImageView的资源ID:@7F0D000B使用Arsc编辑方式打开resources.arsc,搜索资源ID再去搜索first_img定位图片哦~原来first_img已经在对应资源图片了,那我直接修改它的映射关系改成D2.png完成引用1.《安卓逆向这档事》一、模拟器环境搭建:https://www.52pojie.cn/thread-1695141-1-1.html2.《安卓逆向这档事》二、初识APK文件结构、双开、汉化、基础修改:https://www.52pojie.cn/thread-1695796-1-1.html3.吾爱破解安卓逆向入门教程《安卓逆向这档事》二、初识APK文件结构、双开、汉化、基础修改:https://www.bilibili.com/video/BV18G411j7gV/?spm_id_from=333.788&vd_source=33cfe7dc102c64b5cac16bcfaad7f2a84.[更新!]适用于几乎所有安卓模拟器(7+)安装magisk的教程-简单无脑向:https://www.52pojie.cn/thread-1583586-1-1.html5.【VirtualAPP 双开系列08】如何实现多开 - UID:https://blog.csdn.net/u014294681/article/details/116270479
2023年07月23日
372 阅读
0 评论
0 点赞
2023-06-08
RecyclerView Adding Ripple Effect to RecyclerView item
实现recyclerView item长按的水波纹效果<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> <data> <variable name="m" type="cn.lisok.rf.model.SettingItemModel" /> </data> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:attr/selectableItemBackground" android:clickable="true" android:focusable="true" android:paddingStart="40dp" android:paddingEnd="40dp" android:paddingBottom="8dp"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="24dp" android:layout_marginBottom="20dp" android:text="@{m.title,default=无障碍权限}" android:textColor="@color/black" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@id/textView" android:layout_marginTop="24dp" android:maxWidth="250dp" android:text="@{m.desc,default=`依次点击:无障碍 > 已下载的应用 > ❤️真实好友`}" android:visibility="@{m.desc == null ? android.view.View.GONE : android.view.View.VISIBLE}" /> <com.google.android.material.switchmaterial.SwitchMaterial android:id="@+id/power" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_centerVertical="true" android:layout_marginTop="8dp" android:layout_marginEnd="4dp" android:checked="true" android:visibility="@{m.showSwitch? android.view.View.VISIBLE: android.view.View.GONE}" /> </RelativeLayout> </layout>核心三行代码 添加给item的父布局android:background="?android:attr/selectableItemBackground" android:clickable="true" android:focusable="true"引用1.Adding Ripple Effect to RecyclerView item: https://stackoverflow.com/questions/30931889/adding-ripple-effect-to-recyclerview-item
2023年06月08日
295 阅读
0 评论
0 点赞