apk逆向(1)

聲明:本篇文禁止用作商业目的,謝絕一切形式的轉載。

從過年說起

過年的時候,父母手機上面裝上了一個某多多,然後過年時候突然見冒出了"您有98塊錢待領取". 於是,點擊進去了,然後給出提示要100元才能提現金。然後開始了轉發,然後還是湊不夠100塊錢,然後,我就想着找個時間破解下這個騙取流量的機制。

功能

拿到apk,簡單看一下功能,和淘宝的购物网站差不多。商品可谓琳琅满目,还有些额外的小程序,下面是主页面。
在这里插入图片描述

破解

apktool

apk的本质是一个压缩包,只是它使用了自己的一套机制进行的压缩。因此直接使用解压缩软件很多文件会出现乱码。因此需要专门的工具来进行解压缩,这个工具的名字叫做apktool。

apktool is a tool for reverse engineering 3rd party, closed, binary Android apps. It can decode resources to nearly original form and rebuild them after making some modifications. It also makes working with an app easier because of the project like file structure and automation of some repetitive tasks like building apk, etc.

反编译

使用apktool d apk名称即可对apk进行反编译操作,其中d代表decode。
在这里插入图片描述解压缩之后的文件如下所示:
在这里插入图片描述可以看出asserts、res、lib、AndroidManifest、smali文件等都被解压出来了。Smali是Android虚拟机识别的指令代码,和dex文件可以相互转换。

查看权限

如下是在AndroidManifest中申请的权限:

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:maxSdkVersion="29" android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.READ_PHONE_NUMBERS"/>
    <uses-permission android:name="android.permission.READ_LOGS"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.FLASHLIGHT"/>
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.GET_PACKAGE_SIZE"/>
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <permission android:name="com.xunmeng.pinduoduo.permission.lifecycle" android:protectionLevel="signature"/>
    <uses-permission android:name="com.xunmeng.pinduoduo.permission.lifecycle"/>
    <uses-permission android:name="android.permission.WRITE_CALENDAR"/>
    <uses-permission android:name="com.coloros.mcs.permission.RECIEVE_MCS_MESSAGE"/>
    <uses-permission android:name="com.heytap.mcs.permission.RECIEVE_MCS_MESSAGE"/>
    <uses-permission android:name="android.permission.GET_TASKS"/>
    <uses-permission android:name="android.permission.VIBRATE"/>
    <permission android:name="com.xunmeng.pinduoduo.permission.MIPUSH_RECEIVE" android:protectionLevel="signature"/>
    <uses-permission android:name="com.xunmeng.pinduoduo.permission.MIPUSH_RECEIVE"/>
    <uses-permission android:name="com.meizu.flyme.push.permission.RECEIVE"/>
    <permission android:name="com.xunmeng.pinduoduo.push.permission.MESSAGE" android:protectionLevel="signature"/>
    <uses-permission android:name="com.xunmeng.pinduoduo.push.permission.MESSAGE"/>
    <uses-permission android:name="com.meizu.c2dm.permission.RECEIVE"/>
    <permission android:name="com.xunmeng.pinduoduo.permission.C2D_MESSAGE" android:protectionLevel="signature"/>
    <uses-permission android:name="com.xunmeng.pinduoduo.permission.C2D_MESSAGE"/>
    <permission android:name="com.xunmeng.pinduoduo.remote_config" android:protectionLevel="signature"/>
    <uses-permission android:name="com.xunmeng.pinduoduo.remote_config"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="com.xunmeng.pinduoduo.permission.NOTIFICATION_RECORD"/>
    <permission android:name="com.xunmeng.pinduoduo.permission.NOTIFICATION_RECORD" android:protectionLevel="signature"/>
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
    <uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY"/>
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
    <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/>
    <uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/>
    <uses-permission android:name="android.permission.READ_SYNC_STATS"/>
    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <permission android:name="com.xunmeng.pinduoduo.permission.JPUSH_MESSAGE" android:protectionLevel="signature"/>
    <uses-permission android:name="com.xunmeng.pinduoduo.permission.JPUSH_MESSAGE"/>
    <uses-permission android:name="com.coloros.assistantscreen.permission.XCARD_INSTANT_SERVICE"/>
    <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
    <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS"/>
    <uses-permission android:name="com.android.launcher.permission.WIRTE_SETTINGS"/>
    <uses-permission android:name="com.android.launcher.permission.ID"/>
    <uses-permission android:name="com.samsung.android.launcher.permission.READ_SETTINGS"/>
    <uses-permission android:name="com.sec.android.provider.badge.permission.READ"/>
    <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE"/>
    <uses-permission android:name="com.bbk.launcher2.permission.READ_SETTINGS"/>
    <uses-permission android:name="com.bbk.launcher2.permission.WRITE_SETTINGS"/>
    <uses-permission android:name="com.oppo.launcher.permission.READ_SETTINGS"/>
    <uses-permission android:name="com.oppo.launcher.permission.WRITE_SETTINGS"/>
    <uses-permission android:name="net.oneplus.launcher.permission.READ_SETTINGS"/>
    <uses-permission android:name="net.oneplus.launcher.permission.WRITE_SETTINGS"/>
    <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
    <queries>
        <package android:name="com.tencent.mobileqq"/>
        <package android:name="com.tencent.mm"/>
        <package android:name="com.sina.weibo"/>
        <package android:name="com.eg.android.AlipayGphone"/>
    </queries>
    <permission android:name="com.xunmeng.pinduoduo.XLOG_UPLOAD_RECEIVER" android:protectionLevel="normal"/>
    <uses-permission android:name="com.xunmeng.pinduoduo.XLOG_UPLOAD_RECEIVER"/>
    <uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
    <uses-feature android:name="android.software.leanback" android:required="false"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-feature android:name="android.hardware.camera"/>
    <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/>
    <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
    <uses-permission android:name="com.vivo.assistant.StepProvider"/>
    <uses-permission android:name="com.vivo.assistant.permission.access.provider"/>
    <uses-permission android:name="com.vivo.assistant.permission.sport.broadcast"/>
    <uses-permission android:name="android.permission.USE_BIOMETRIC"/>
    <uses-permission android:name="android.permission.USE_FINGERPRINT"/>

比较危险的权限

  • <uses-permission android:name="android.permission.READ_PHONE_NUMBERS"/> 获取手机号码
  • <uses-permission android:name="android.permission.CAMERA"/> 请求访问使用照相设备
  • <uses-permission android:name="android.permission.READ_CONTACTS"/> 允许程序读取用户联系人数据
  • <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 允许一个程序访问精良位置(如GPS)
  • <uses-permission android:name="android.permission.RECORD_AUDIO"/> 允许程序录制视频
  • <uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/> 允许程序管理AccountManager中的账户列表
  • <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> 允许一个程序接收到ACTION_BOOT_COMPLETED广播在系统完成启动,就是开机启动权限

更多权限相关的内容会在后续文章中介绍。

修改文件

在很多时候需要对app进行调试,这个时候可以通过在AndroidManifest.xml中添加如下的代码:

android:debuggable="true"

这时app就能够调试了。
在这里插入图片描述

重新打包

修改文件之后,需要重新编译打包。使用如下的命令进行打包,其中的b代表build:

apktool b pdd pdd.apk

很不幸运的事情发生了,居然报错了。很显然,某多多采用了保护措施。通过查看错误提示,应该和.9.png格式有关,推测可能是apktool版本的问题。
在这里插入图片描述

获取最新apktool

不得已,用上github了,在这里获取到最新的apktool的源代码。编译。重新打包,出现了另外一种错误。如下图所示:
在这里插入图片描述

问题分析

通过比较下面3个文件可知,根据在public.xml中的"qq"是找不到属性"normalTextColor"的。

在这里插入图片描述
某多多明显使用了资源混淆技术。资源混淆技术在后面会详细介绍,这种技术可以实现app瘦身以及提高破解难度的功能。

问题解决

通过上面的分析可知是在解析过程中出现了资源混淆,需要修改源码,比较麻烦,暂时不用修改源码的方式,后续会介绍。

由于重新编译失败,可以考虑不反编译apk。直接对二进制文件进行修改,然后将修改的二进制文件直接放入压缩包。

要让apk可调试,需要添加debuggable属性,本文使用的工具是AXMLEditor,可以通过如下的命令来实现添加debuggable属性。

java -jar AXMLEditor.jar -attr -i application com.xunmeng.pinduoduo.app.SampleApplication debuggable true AndroidManifest.xml AndroidManifest_new.xml
签名

在压缩包中把META-INF删除,这样以前的签名就被清除了。

  1. 生成burning.keystore
keytool -genkey -alias burning -keyalg RSA -validity 36500 -keystore burning.keystore
  1. 使用jarsigner进行签名
jarsigner -verbose -keystore burning.keystore -signedjar pdd_signed.apk pdd.apk burning
  1. 安装,查看主页面可知多出了"非官方发布版本"的字样,说明重新签名成功,具体如图
    在这里插入图片描述
调试

可以使用jeb进行调试,后文会详细讲解。

写在最后

开发一个apk可能需要很久的周期,而破解一个apk可能只需要一两周。无论apk加壳、加固、混淆等,这些技术都只是增加破解难度而无法阻止破解。

在2015年、2016年一大批相似的聊天软件能够出现,大部分原因就是当时市场还不规范,审核不够严格,而这些相似的软件基本都是反编译一个apk而产生的,最神奇的是他们的服务器都是一家的。

公众号

更多内容,欢迎关注公众号:无情剑客。
在这里插入图片描述

### APK逆向工程的工具与方法 #### 基础概念 在进行APK逆向工程之前,需要掌握一定的基础知识,包括但不限于Dalvik虚拟机的工作原理以及Android应用程序的整体架构设计。这些知识有助于理解反编译后的代码逻辑及其运行环境。 #### 使用的主要工具 以下是常用的几类工具及其功能描述: 1. **Apktool** Apktool 是一款强大的开源工具,能够将 `.apk` 文件中的资源文件 (resources) 和 `classes.dex` 转换成可读的形式。通过它,可以提取并修改 Android 应用程序的各种组件,比如布局 XML 文件、字符串表以及其他静态数据[^1]。 安装和使用 Apktool 的基本命令如下所示: ```bash apktool.bat d -f test.apk test ``` 或者更简洁的方式: ```bash apktool.bat d test.apk ``` 2. **Dex2Jar** Dex2Jar 将 Dalvik 字节码转换成 Java 字节码 (.class),从而使得开发者可以用标准的 Java 反编译器来查看源代码。此过程允许进一步深入研究应用内部实现细节[^4]。 3. **JD-GUI/JAD** JD-GUI 是一种图形化的 Java 反编译器,它可以快速地把 .class 文件还原为接近原始状态下的 Java 源代码;而 JAD 则是一个较老但仍然有效的命令行版本替代品。两者都适用于解析由 Dex2Jar 处理过的 jar 包内容[^2]。 4. **Frida/Xposed** 对于某些复杂的交互行为或者加密算法的研究,则可能需要用到像 Frida 或 Xposed 这样的框架来进行实时监控与干预操作系统的 API 调用情况。这类技术特别适合处理那些依赖动态加载机制的应用场景。 5. **Flasm** Flasm 主要针对 Flash 动画内的脚本部分提供支持——尽管现代移动开发很少涉及 SWF 文件了,但在特定条件下仍有可能遇到相关需求。例如,在分析旧版游戏资产时可能会碰到 ActionScript 编写的业务逻辑片段[^5]。 #### 实际案例演示 假设我们有一个名为 `example.apk` 的目标文件,并希望对其进行初步分解以获取更多信息。具体步骤如下: - 首先利用 Apktool 解压该 APK 并导出其资源配置项; - 接着采用 Dex2Jar 把其中的核心执行单元转化为兼容 JVM 的形式; - 最终借助 JD-GUI 查看最终呈现出来的伪代码表示法。 ```bash # Step 1: Decompile the APK using Apktool. apktool d example.apk output_folder/ # Step 2: Convert DEX files into JAR format via Dex2Jar. d2j-dex2jar.sh --force example/classes.dex -o example.jar # Step 3: Open generated JAR file with JD-GUI for inspection. java -jar jd-gui.jar example.jar ``` 以上即完成了一个简单却完整的逆向流程概述。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

helloworddm

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值