安卓逆向基础和MT管理器使用
8506
安卓逆向基础和MT管理器使用
感谢正己大佬开源:安卓逆向这档事
APK(Android package)
等于一种压缩包
文件
注释
assets目录
存放APK的静态资源文件,比如视频,音频,图片等
lib 目录
armeabi-v7a基本通用所有android设备,arm64-v8a只适用于64位的android设备,x86常见用于android模拟器,其目录下的.so文件是c或c++编译的动态链接库文件
META-INF目录
保存应用的签名信息,签名信息可以验证APK文件的完整性,相当于APK的身份证(验证文件是否又被修改)
res目录
res目录存放资源文件,包括图片,字符串等等,APK的脸蛋由他的layout文件设计
AndroidManifest.xml文件
APK的应用清单信息,它描述了应用的名字,版本,权限,引用的库文件等等信息
classes.dex文件
classes.dex是java源码编译后生成的java字节码文件,APK运行的主要逻辑
resources.arsc文件
resources.arsc是编译后的二进制资源文件,它是一个映射表,映射着资源和id,通过R文件中的id就可以找到对应的资源
kotlin文件夹
说明使用了kotlin开发
这里放上ctfwiki的说明:
AndroidManifest.xml
该文件主要用于声明应用程序的名称,组件,权限等基本信息。
class.dex
该文件是 dalvik 虚拟机对应的可执行文件,包含应用程序的可执行代码。
resource.arsc
该文件主要是应用程序编译后的二进制资源以及资源位置与资源 id 之间的映射关系,如字符串。
assets
该文件夹一般用于包含应用程序的原始资源文件,例如字体和音乐文件。程序在运行的时候,可以通过 API 获取这些信息。
lib/
lib 目录下主要用于存储通过 JNI(Java Native Interface)机制使用的本地库文件,并且会按照其支持的架构,分别创建对应的子目录。
res/
该目录主要包含了 Android 应用引用的资源,并且会按照资源类型进行存储,如图片,动画,菜单等。主要还有一个 value 文件夹,包含了各类属性资源
colors.xml→颜色资源
dimens.xml---> 尺寸资源
strings---> 字符串资源
styles.xml→样式资源
META-INF/
类似于 JAR 文件,APK 文件中也包含了 META-INF 目录,用于存放代码签名等文件,以便于用来确保 APK 文件不会被人随意修改。
初识AndroidManifest.xml
AndroidManifest.xml文件是整个应用程序的信息描述文件,定义了应用程序中包含的Activity,Service,Content provider和BroadcastReceiver组件信息。每个应用程序在根目录下必须包含一个AndroidManifest.xml文件,且文件名不能修改。它描述了package中暴露的组件,他们各自的实现类,各种能被处理的数据和启动位置。
属性
定义
versionCode
版本号,主要用来更新,例如:12
versionName
版本名,给用户看的,例如:1.2
package
包名,例如:com.zj.52pj.demo
uses-permission android:name=""
应用权限,例如:android.permission.INTERNET 代表网络权限(可以用来阻止某些要权限的apk)
android:label="@string/app_name"
应用名称
android:icon="@mipmap/ic_launcher"
应用图标路径
android:debuggable="true"
应用是否开启debug权限
安卓四大组件
组件
描述
Activity(活动)
在应用中的一个Activity可以用来表示一个界面,意思可以理解为“活动”,即一个活动开始,代表 Activity组件启动,活动结束,代表一个Activity的生命周期结束。一个Android应用必须通过Activity来运行和启动,Activity的生命周期交给系统统一管理。
Service(服务)
Service它可以在后台执行长时间运行操作而没有用户界面的应用组件,不依赖任何用户界面,例如后台播放音乐,后台下载文件等。
Broadcast Receiver(广播接收器)
一个用于接收广播信息,并做出对应处理的组件。比如我们常见的系统广播:通知时区改变、电量低、用户改变了语言选项等。
Content Provider(内容提供者)
作为应用程序之间唯一的共享数据的途径,Content Provider主要的功能就是存储并检索数据以及向其他应用程序提供访问数据的接口。Android内置的许多数据都是使用Content Provider形式,供开发者调用的(如视频,音频,图片,通讯录等)
Activity生命周期
函数名称
描述
onCreate()
一个Activity启动后第一个被调用的函数,常用来在此方法中进行Activity的一些初始化操作。例如创建View,绑定数据,注册监听,加载参数等。
onStart()
当Activity显示在屏幕上时,此方法被调用但此时还无法进行与用户的交互操作。
onResume()
这个方法在onStart()之后调用,也就是在Activity准备好与用户进行交互的时候调用,此时的Activity一定位于Activity栈顶,处于运行状态。
onPause()
这个方法是在系统准备去启动或者恢复另外一个Activity的时候调用,通常在这个方法中执行一些释放资源的方法,以及保存一些关键数据。
onStop()
这个方法是在Activity完全不可见的时候调用的。
onDestroy()
这个方法在Activity销毁之前调用,之后Activity的状态为销毁状态。
onRestart()
当Activity从停止stop状态恢进入start状态时调用状态。
多开,汉化以及替换资源
双开
双开:简单来说,就是手机同时运行两个或多个相同的应用,例如同时运行两个微信.
原理
解释
修改包名
让手机系统认为这是2个APP,这样的话就能生成2个数据存储路径,此时的多开就等于你打开了两个互不干扰的APP.(但是签名校验就比较麻烦了)
修改Framework
对于有系统修改权限的厂商,可以修改Framework来实现双开的目的,例如:小米自带多开
通过虚拟化技术实现
虚拟Framework层、虚拟文件系统、模拟Android对组件的管理、虚拟应用进程管理 等一整套虚拟技术,将APK复制一份到虚拟空间中运行,例如:平行空间
以插件机制运行
利用反射替换,动态代{过}{滤}理,hook了系统的大部分与system—server进程通讯的函数,以此作为“欺上瞒下”的目的,欺骗系统“以为”只有一个apk在运行,瞒过插件让其“认为”自己已经安装。例如:VirtualApp
视频就讲了通过修改包名来解决,但是如果遇到签名校验就比较麻烦.
提取安装包
无需多言,利用MT管理器或者NP管理器(不过这些现在都要会员了,搞个破解版吧)
汉化APK
基本上字符串都是在arsc里,建议一键汉化,然后再润色。少量没汉化到的字符串参考视频中的方法定位去逐个汉化。
流程图:
这里还需要注意的是,如果要直装应用,那就应该先签名安装,看看是否有签名校验导致的闪退
我们跟着视频学习:
先看看需要汉化的地方
通过mt管理器提取安装包
点击右上角的三点,高级搜索hello
弹出一个文件,将其反编译,找到jt需要汉化的地方.
上面一句俄语我们不会打怎么办,接下来就是开发者助手出场
先点击它的图标,然后点击界面资源分析:
然后就像web一样复制文本即可.
找到是resources.arsc,用翻译模式打开,然后翻译即可
结束:
最后一句英文就不找了,在dex,同上处理即可.
替换图标
用NP管理器打开点击功能
用共享文件功能把图片传入,然后替换.(一直要登录,评价为流氓设计,建议开头登录直接别让用,这样至少还合理点)
替换图片
看完挑战3,我们可以把那个表情包给替换了,关于找到图片id这些就不讲了,也就是抓布局然后到xml看,然后会找到这个(我懒得搞,直接复制教程了)
复制后去resources.arsc定位可以直接定位到路径,因为这个是映射表,映射id和位置.
patch 普通java层广告
我们先得看看广告都是什么类型的,有3种类型:开屏,弹窗,横幅.
启动弹窗
看看程序,第一步--启动弹窗:
(呱,是广告口牙)
启动广告流程:
启动Activity->广告Activity->主页Activity
修改方法:
1.修改加载时间
2.Acitivity切换定位,修改Intent的Activity类名
所以接下来学习定位Activity
利用mt管理器的这个功能:
然后再点一次程序
回到mt管理器复制搜索
转java看一下:
//
// Decompiled by Jadx
// By developer-krushna (https://github.com/developer-krushna/)
package com.zj.wuaipojie.ui;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import androidx.appcompat.app.AppCompatActivity;
import com.zj.wuaipojie.ui.AdActivity$.ExternalSyntheticLambda0;
import kotlin.Metadata;
@Metadata(d1 = {"\u0000\u001a\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010\u0002\n\u0002\b\u0003\n\u0002\u0018\u0002\n\u0000\u0018\u00002\u00020\u0001B\u0005¢\u0006\u0002\u0010\u0002J\b\u0010\u0003\u001a\u00020\u0004H\u0002J\b\u0010\u0005\u001a\u00020\u0004H\u0002J\u0012\u0010\u0006\u001a\u00020\u00042\b\u0010\u0007\u001a\u0004\u0018\u00010\bH\u0014¨\u0006\t"}, d2 = {"Lcom/zj/wuaipojie/ui/AdActivity;", "Landroidx/appcompat/app/AppCompatActivity;", "()V", "jump", "", "loadAd", "onCreate", "savedInstanceState", "Landroid/os/Bundle;", "app_release"}, k = 1, mv = {1, 7, 1}, xi = 48)
/* compiled from: AdActivity.kt */
public final class AdActivity extends AppCompatActivity {
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(2131427363);
loadAd();
}
private final void jump() {
startActivity(new Intent((Context) this, ChallengeThird.class));
finish();
}
private final void loadAd() {
new Handler().postDelayed(new ExternalSyntheticLambda0(this), 3000);//读秒等待
}
/* renamed from: loadAd$lambda-0 */
private static final void m0loadAd$lambda-0(AdActivity adActivity) {
adActivity.jump();
}
}
// By developer-krushna (https://github.com/developer-krushna/)
简单的方法是直接修改读秒,但是还是用经过,我们彻底搞定它.去xml修改
android:theme="@7f1101d3" android:label="@7f10001b" android:icon="@7f0d000f" android:allowBackup="true" android:supportsRtl="true" android:extractNativeLibs="false" android:fullBackupContent="@7f130000" android:networkSecurityConfig="@7f130002" android:appComponentFactory="androidx.core.app.CoreComponentFactory" android:dataExtractionRules="@7f130001"> android:name="com.zj.wuaipojie.ui.ChallengeSixth" android:exported="false"/> android:name="com.zj.wuaipojie.ui.ChallengeFifth" android:exported="true"/> android:name="com.zj.wuaipojie.ui.ChallengeFourth" android:exported="true"/> android:name="com.zj.wuaipojie.ui.ChallengeThird" android:exported="false"/> android:name="com.zj.wuaipojie.ui.ChallengeSecond" android:exported="false"/> android:name="com.zj.wuaipojie.ui.AdActivity"/> android:label="@7f10001b" android:name="com.zj.wuaipojie.ui.MainActivity" android:exported="true"> android:name="android.intent.action.MAIN"/> android:name="android.intent.category.LAUNCHER"/> android:name="com.zj.wuaipojie.ui.ChallengeFirst"/>
直接把com.zj.wuaipojie.ui.ChallengeThird设为主活动(但是这个方法容易让应用闪退)
也可以直接在代码修改,把这个类名的smali名字复制搜索改变逻辑,据教程说会比直接修改xml稳妥点.
弹窗广告
改版本号
如果是更新弹窗的话,可以直接修改xml的versioncode
当然这是特殊情况,那种直接弹出来的才常见,甚至会劫持返回键,这时候我们可以hook先用lsp勾选软件,就可以直接hook了.
然后打开算法助手,直接hook
(第二个屏蔽关键词弹窗很有用,但是关键词要用英文逗号隔开)
找代码
我们先跟着第二步走,然后去算法助手的日志看看
找到最新的那个,看函数调用逻辑
用mt搜索(mt突然打不开,用np代替),点开最符合的那个
弹窗总是要显示的,所以一定会有show,我们直接删掉即可,关闭算法助手打开软件发现成功.
还有一个办法,是直接在网络层过滤掉,教程说抓包再讲.
横幅广告
需要定位到图片的id,这点开发者组手不太好用,可以用开发助手来做.
获得图片id0x7f0801ca
去mt搜索xml文件找到,用两种方式,一种是分辨率调为0,一种是不显示android:visibility="gone".
成功了.