吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1885|回复: 21
收起左侧

[Android 分享] 安卓逆向学习2-APP攻防01

  [复制链接]
Juana111 发表于 2024-8-8 10:23
本帖最后由 Juana111 于 2024-8-8 10:42 编辑

2.1APK结构
apk本质是一个zip压缩文件,可以通过打开压缩包的形式打开apk文件。
1.PNG


.dex文件
除了源文件与资源文件之外,可以发现.dex文件,是逆向分析的核心文件。
Tip: .dex文件是Android系统虚拟机的可执行文件,是Java文件夹中所有Java类编译的二进制文件,存储apk整体业务逻辑的核心。一般是将.dex文件反编译为smali语言【Android虚拟机的汇编语言】的文件。
其他文件
其他文件一把梭!
assets文件夹:配置文件,包含非xml的静态资源文件,音频、字体、html这些文件;
lib文件夹:应用程序的本地链接库目录(.so文件),存放与特定硬件架构相关的本地库文件,下图文件包括armeabi-v7a【通用所有Android设备】和x86【Android模拟器】,一般会存在,下图lib文件在assets文件夹中;
2.PNG
kotlin文件夹:kotlin编程语言开发的源文件,Android官方开发语言,与Java兼容;
META-INF文件夹:存储apk程序的签名信息,用做校验计算存储计算结果,保证包的文件不被替换;
okhttps3文件夹:处理网络请求的框架,使用Get\Post请求,上传下载文件等功能;
org文件夹:不了解,查看文件有关于Antlr的,百度了下是一个语法分析器生成器。嗯,暂时不重要;
res/raw文件夹:xml、json、txt、图片文件这些文件的存储。
AndroidManifest.xml文件:配置清单文件,编译自动生成的文件,在安装时会读取该文件确定应用的基本信息和权限要求。文件中包括包名、应用名、权限、安卓四大组件、版本等信息的声明。学到的方法是通过资源文件中的AndroidManifest.xml文件中的四大组件标签【activity/service/receiver/provider】标识来找到app包名(进程的唯一标志)。通过<intent-filter>标签内容定位app入口类。
[XML] 纯文本查看 复制代码
<intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>

resources.arsc文件:资源索引表,用来描述具有ID值的资源的配置信息。再使用反编译工具查看,主要是源代码与资源文件两种。
3.PNG
2.2安卓加固
预告:安卓安全相关手段
代码混淆手段:更改类名、函数名、变量名,实现两种结果。一是符号混淆:将有意义的类名或者函数名改为a,b,c这种没有意义的名称,破解人员看不懂,增加破解难度;二是压缩文件大小。代码混淆中又包括了字符串加密、花指令和资源加密等。
动态加载方案:将保护的代码单独编译,加密后保存在外部二进制文件中,常见的是将程序的业务逻辑放置在.so文件中。使用动态分析的手段破解程序,在加载后的函数中设置断点dump内存,找到真实的dex文件,具体是通过注入将指令代码和数据注入到目标进程,对目标进程进行调试和内存监控。
正片:安卓加固手段
  • DEX加固:对dex整体加固,将dex整体加密后动态加载。-->先解密文件并在解密完成后写入到另一个文件,解密完调用加载函数来加载解密后文件。-->加密的dex文件在内存中解密并直接在内存中加载。
  • 代码抽取保护:利用私有函数,通过对进程的hook拦截函数调用路径,在函数真实调用前使用nop代码数据填充。-->存在兼容性和性能损耗问题。
  • VMP和DEX2C:VMP-->java代码变成Native层代码,找到与系统解释器的映射关系;DEX2C-->java代码转为Native层代码,native的二进制编码(C/C++)比Java字节码更难。
  • OLLVM保护native层:编写PASS控制中间代码混淆,实现平坦化。
2.3app分析与破解
2.3.1未加固app进行分析破解
目的:使用Objection对未加固应用包中的弹窗进行快速定位操作,并去掉弹窗
实验工具:
adb - 35.0.1
FrIDA - 16.3.0
objection - 1.11.0
雷电模拟器 安卓4.0(64位)
jadx-gui
具体操作:
第一步:先在adb中安装apk文件:
[Shell] 纯文本查看 复制代码
adb install XXX.apk
这里遇到问题有两个
  • adb.exe: more than one device/emulator

        Xxxx offline 检查是不是开了多个设备或者模拟器使用命令:

      [Shell] 纯文本查看 复制代码
      adb devices
      ##解决方式
      ##adb -s emulator-5554 shell
      ##adb kill-server
      ##adb start-server
  • adb: failed to install zhibo.apk: Failure [INSTALL_FAILED_ALREADY_EXISTS: Attempt to re-install com.hd.zhibo without first uninstalling.]

      安装apk之前,设备上已经安装过了一个版本,再次安装会安装失败。

      [Shell] 纯文本查看 复制代码
      ##解决方式 -r覆盖安装
      adb install -r XXX.apk
第二步:在adb启动frida-server,执行命令如下
[Shell] 纯文本查看 复制代码
D:\CTF_Tools\APK_Tools\adb>adb shell
aosp:/ # su
aosp:/ # cd /data/local/tmp/
aosp:/data/local/tmp # ./fs

另外起一个cmd,objection注入
[Shell] 纯文本查看 复制代码
D:\CTF_Tools\APK_Tools\adb>objection -g com.hd.zhibo explore

4.png
成功之后就像图中这样,这里尝试了用不同机型来启动,发现只有xiaomi不报错,牛批!
这里遇到的问题比较多
  • 电脑重新安装过,之前的frida版本乱乱的,总体还是遗留了之前和朋友打比赛复现的环境,重新将frida-server push到adb中

      [Shell] 纯文本查看 复制代码
      adb.exe push frida-server /data/local/tmp
      ##push 文件名 文件位置
  • objection安装

        直接在python中安装frida和objection的包,直接使用cmd会发现报错,就直接在pycharm中进行了package的安装,一种蛮快捷的方式!
对反编译之后的apk进行文本的搜索,找到弹窗调用的类名,使用命令
[Shell] 纯文本查看 复制代码
android heap search instances android.app.AlertDialog

5.png
跑出来的效果太亏贼了,需要进一步了解弹窗类的类型,大概先了解操作,笔者又使用了ubuntu和真机测试,发现又出现了一系列问题,等到后面重新解决。这里还推荐了一个插件Wallbreaker,在github可以搜到,等后面换设备再重新搭建。
使用命令对AlterDialog类进行hook来去欸的那个调用弹窗的函数。
[Shell] 纯文本查看 复制代码
objection -g com.hd.zhibo explore -s "android hooking watch class android.app.AlertDialog"

6.png
确定被调用函数后,选取其中一个再进行hook来确定提示弹窗中在app下的函数,这里选定activity启动调用的第一个函数OnCreat()进行hook并打印调用栈。
手动关闭app之后输入命令:
[Shell] 纯文本查看 复制代码
objection -g com.hd.zhibo explore -s "android hooking watch class_method android.app.AlertDialog.OnCreate --dump-args --dump-backtrace --dump-return"

确定app弹窗的创建函数com.zhibo.media.channel_main.update_show(),用jadx具体查看函数的内容。
[Shell] 纯文本查看 复制代码
public void update_show(Bundle bundle) {

        if (bundle != null && bundle.containsKey("ver") && bundle.containsKey("info") && bundle.containsKey("path")) {

            new AlertDialog.Builder(this).setTitle("发现新版本 " + bundle.getString("ver") + " 是否升级").setMessage(bundle.getString("info")).setPositiveButton("立刻升级", new DialogInterface$OnClickListenerC0971o(this, bundle)).show();
        }
    }

根据外面的if条件判断,不再弹出弹窗就需要修改对应的判断语句重新打包app。使用apktool命令对app进行反编译
[Shell] 纯文本查看 复制代码
apktool_2.8.0.jar d D:\CTF_Tools\APK_Tools\adb\zhibo.apk

新获得一个同名的文件夹,使用android stdio打开文件夹。找到channel_main类中对应的smali文件以及update_show()函数在的文件中的位置。【对代码进行注释解释】
[Shell] 纯文本查看 复制代码
.method public update_show(Landroid/os/Bundle;)V
##.method定义updata_show这个方法

    .locals 3
    ##本地寄存器的个数

    if-eqz p1, :cond_0
    ##p1寄存器 p开头--->参数寄存器
    ##equals zero,p1寄存器等于0则跳转到:cond_0处
    ##nez not equals zero 

    const-string v0, "ver"
    ##v0寄存器 v开头--->本地寄存器
    
    invoke-virtual {p1, v0}, Landroid/os/Bundle;->containsKey(Ljava/lang/String;)Z
    ##方法调用 {参数},方法所属类的包路径->方法名(参数类型)方法返回值类型【Z:boolean】
    
    move-result v0
    ##将上一个方法调用的结果值移到v0
    
    if-eqz v0, :cond_0

    const-string v0, "info"

    invoke-virtual {p1, v0}, Landroid/os/Bundle;->containsKey(Ljava/lang/String;)Z

    move-result v0
    

    if-eqz v0, :cond_0

    const-string v0, "path"

    invoke-virtual {p1, v0}, Landroid/os/Bundle;->containsKey(Ljava/lang/String;)Z

    move-result v0

    if-eqz v0, :cond_0

    new-instance v0, Landroid/app/AlertDialog$Builder;

    invoke-direct {v0, p0}, Landroid/app/AlertDialog$Builder;-><init>(Landroid/content/Context;)V
    ##方法构造【V:void】
    
    new-instance v1, Ljava/lang/StringBuilder;

    const-string v2, "\u53d1\u73b0\u65b0\u7248\u672c "

    invoke-direct {v1, v2}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V

    const-string v2, "ver"

    invoke-virtual {p1, v2}, Landroid/os/Bundle;->getString(Ljava/lang/String;)Ljava/lang/String;
    ##【Lpackage/name/ObjectName格式-->Ljava/lang/String:String-->对象数组】
    
    move-result-object v2

    invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v1

    const-string v2, " \u662f\u5426\u5347\u7ea7"

    invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v1

    invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v1

    invoke-virtual {v0, v1}, Landroid/app/AlertDialog$Builder;->setTitle(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;

    move-result-object v0

    const-string v1, "info"

    invoke-virtual {p1, v1}, Landroid/os/Bundle;->getString(Ljava/lang/String;)Ljava/lang/String;

    move-result-object v1

    invoke-virtual {v0, v1}, Landroid/app/AlertDialog$Builder;->setMessage(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;

    move-result-object v0

    const-string v1, "\u7acb\u523b\u5347\u7ea7"

    new-instance v2, Lcom/zhibo/media/o;

    invoke-direct {v2, p0, p1}, Lcom/zhibo/media/o;-><init>(Lcom/zhibo/media/channel_main;Landroid/os/Bundle;)V

    invoke-virtual {v0, v1, v2}, Landroid/app/AlertDialog$Builder;->setPositiveButton(Ljava/lang/CharSequence;Landroid/content/DialogInterface$OnClickListener;)Landroid/app/AlertDialog$Builder;

    move-result-object v0

    invoke-virtual {v0}, Landroid/app/AlertDialog$Builder;->show()Landroid/app/AlertDialog;

    :cond_0
    return-void
.end method
##定义方法结束

这里是直接在第一个if判断那里的eqz(等于0跳转),改为nez(不等于0跳转)。使用打包命令对修改后的app重新打包,在dist文件下生成一个未作签名的out.apk文件。
[Shell] 纯文本查看 复制代码
apktool_2.8.0.jar b zhibo

7.png
最后生成的apk是在目录的dist文件下,由于修改后缺少对应的app签名,这里需要使用签名工具生成签名文件对新打包的apk进行签名。这里使用的是自带的签名工具,也可以选择其他的工具。使用的两条命令:
[Shell] 纯文本查看 复制代码
keytool -genkey -alias new_zhibo.keystore -keyalg RSA -validity 2000 -keystore /home/juana-2u/Software/zhibo/dist/new_zhibo.key 
##生成签名文件
##-genkey 生成证书
##-alias 证书别名,包名
##-keyalg RSA 签名文件使用的加密类型
##-validity 签名有效期2000days
##-keystore 签名文件生成的路径

8、.png
[Shell] 纯文本查看 复制代码
jarsigner -verbose -keystore new_zhibo.key -signedjar zhibo_patch.apk out.apk new_zhibo.keystore
##生成patch之后的apk文件
##jarsigner -verbose -keystore [签名秘钥文件路径] -signerjar [签名后apk的文件路径] [未签名apk的文件路径] [证书别名]

9.png
2.3.2对加固app进行分析破解
目的:使用Objection对加固后应用包中的弹窗进行快速定位操作,并去掉弹窗
实验工具:
adb - 35.0.1
Frida - 16.3.0
objection - 1.11.0
雷电模拟器 安卓4.0(64位)
jadx-gui
具体操作:
apk启动不了,直接反编译来看了,与上面的未加固app的分析步骤类似。对弹窗类进行hook判断具体实现的弹窗类名,使用watch class的方式hook弹窗类,根据函数的被调用记录判断类是否被使用。前面都是差不多的,点击对应的弹窗位置或者操作,objection都会返回被调用的函数,与下图类似。
10.png
确定样本中升级提示弹窗的实现类对setCancelate(boolean)函数进行hook,根据调用栈发现app中发起弹窗的函数这样。
重点是加固的部分的处理。总结如下两点
  • 对加固的dex进行脱壳处理,app的dex要替换壳的dex
  • 修改app的入口点:加固后的入口点只是壳的入口点,即在重打包时要在配置AndroidManifest.xml文件中修改入口类。
第一步:对dex脱壳
用jadx打开apk文件,与上面的非加固的apk不一样,加固之后的apk只显示了外部壳的类信息。
11.png
使用frida-dexdump,github地址:https://github.com/hluwa/frida-dexdump,需要在frida-server调试的同时进行脱壳。
这里的插件安装存在问题,windows上直接安装不了,使用pip安装出现一排? 安装失败ubuntu安装好了,看资料需要在apk运行的条件下进行dexdump【?】准备再研究一下继续复现这一块。

彩蛋:来填上期留下的Objection的坑!
2.4Objection简单介绍
1. objection是什么
Objection是基于Firda的一个工具。利用Frida(安卓逆向的一种Hook框架)提供各种api实现安卓逆向分析的具体功能,Objection是集合体,同时支持android和IOS两大平台。完成任务:内存搜索、类和模块搜索、方法Hook、打印参数、打印返回值、调用栈等功能(内存漫游+逆向分析),依托Frida完成对应用注入和对函数的hook模板使用:填充具体的类完成Hook测试
2.objection三大组成部分:
  • Objection重打包的组件:完成Frida无root调试,重打包Frida运行需要的firda-gadget.so文件
  • Objection本身的pypi包:和包含firda-gadget.so文件的app交互,运行hook脚本,分析hook结果
  • Objection编译的agent.js文件:【TypeScript】项目,在app运行中插入了Frida的运行库

参考资料:
《安卓Frida逆向与抓包实战》陈佳林
附件地址:https://github.com/r0ysue/AndroidFridaBeginnersBook
笔者复现附件地址:https://github.com/Juana-2u/Android_Study_demo

免费评分

参与人数 12吾爱币 +17 热心值 +11 收起 理由
Open0A0ASS + 1 + 1 谢谢@Thanks!
wzvideni + 1 + 1 用心讨论,共获提升!
janken + 1 + 1 谢谢@Thanks!
正己 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
lihuhu + 1 我很赞同!
allspark + 1 + 1 用心讨论,共获提升!
MargaretTOTO + 1 谢谢@Thanks!
令君怀瑾 + 1 + 1 我很赞同!
wenmingziyou + 1 + 1 我很赞同!
ghwanz + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
jackies + 1 + 1 热心回复!
debug_cat + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

ltgb 发表于 2024-8-9 08:17
xiaomi?牛批!
 楼主| Juana111 发表于 2024-8-16 11:41
h1989 发表于 2024-8-15 11:13
请问大佬,某软件查题,不论mt什么反混淆,都无法查到兑换码、会员、vip等字眼,这是什么原因呢?

会不会是进行了类似加密的方式将文本格式转成了其他格式 试试触发带有这些字眼的操作进行抓包呢
acg7878 发表于 2024-8-8 17:46
wenmingziyou 发表于 2024-8-8 20:04
感谢分享,学习了
shimeiyangwei 发表于 2024-8-8 21:08
介绍详细,回头学学
wangyuyan 发表于 2024-8-8 21:39
感谢 学习了
amwquhwqas128 发表于 2024-8-8 23:20
非常感谢详细内容的文章
kennygui 发表于 2024-8-9 01:03
刚从ios切换到安卓,正好对这块内容感兴趣,感谢分享
sx007 发表于 2024-8-9 05:42
感谢学习了
daxi33 发表于 2024-8-9 09:48
详细,感谢分享!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-11 19:35

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表