安卓加固脱壳分享

admin 2023年4月2日02:24:03评论80 views字数 5591阅读18分38秒阅读模式

安卓加固脱壳分享

本文为看雪论坛优秀文章

看雪论坛作者ID:CpuDbg


首先反编译apk

看看AndroidManifest.xml情况!


重点看包名

package="com.faloo.BookReader4Android"


还有application下的android:name

android:name="com.tencent.StubShell.TxAppEntry"


看看对应的smali!

smali不熟悉的话,可以反编译dex再转jar 直接用java gui看java代码。

  private void a(String paramString)
{
// Byte code:
// 0: aload_0
// 1: invokevirtual 59 com/tencent/StubShell/TxAppEntry:getApplicationInfo ()Landroid/content/pm/ApplicationInfo;
// 4: astore_2
// 5: aload_2
// 6: getfield 64 android/content/pm/ApplicationInfo:dataDir Ljava/lang/String;
// 9: astore_3
// 10: new 66 java/lang/StringBuilder
// 13: dup
// 14: invokespecial 67 java/lang/StringBuilder:<init> ()V
// 17: aload_3
.....
}


有很多 // 开头的,这个是smali 加了 -d 调试选项时 才会出现的。换jeb看看。


查看smali代码主要是为了找他调用的哪个so来解密dex , 这里代码有点多,没必要花时间去细品代码。一般so文件都是放在 assets 或者 lib目录下。先看看 assets 目录。

安卓加固脱壳分享

没看到有so文件,可以再看看 lib 目录下。

安卓加固脱壳分享

有很多 so 文件! 不出意外的话解密的 so 应该就在其中。


这么多so文件一个个分析也不现实, 为了省事 可以直接上ida查看他加载了哪个so也是一样的。


首先启动ida server 为了防止被检测到,最好将 android_server 改一个名字。


默认的端口也修改一下,命令如下 (有的情况 adb shell su 连着打不能生效,需要进入 adb shell 再 su提权后再执行):

adb shell su ./data/local/tmp/ida7032 -p5555


执行成功提示:

IDA Android 32-bit remote debug server(ST) v1.22. Hex-Rays (c) 2004-2017

Listening on 0.0.0.0:5555...


手机端的服务运行起来 并开了一个 5555 端口, 接着需要将手机端口映射到PC上来。

adb forward tcp:6666 tcp:5555

其中5555 是手机里 android_server的端口(需和执行命令时的端口一样)  。

6666是映射到PC上的端口(理论上是可以1-65535任意端口,前提是没被占用)。


注意: 端口转发命令只需运行一次即可。即使android_server关闭 重开了,也不需要重复运行。可以打如下命令查看是否映射过。

PS > adb forward --list

84B5T15B03002203 tcp:6666 tcp:5555


如果映射过就无需再重复映射。


接着以调试模式启动apk 命令格式是 am start -D -n 包名/入口 具体包名可以通过 AndroidManifest.xml 文件查看。或者通过如下命令查看:

PS > adb shell dumpsys activity top
TASK com.faloo.BookReader4Android id=120
ACTIVITY com.faloo.BookReader4Android/com.faloo.app.activity.LogoPageActivity 8fc46c9 pid=9911
Failure while dumping the activity: java.io.IOException: Timeout


其中 

com.faloo.BookReader4Android/com.faloo.app.activity.LogoPageActivity 是包名+入口。


命令连起来则是如下:

PS E:Android虚拟机临时使用临时> adb shell
angler:/ $ su
angler:/ # am start -D -n com.faloo.BookReader4Android/com.faloo.app.activity.BookActivity
Starting: Intent { cmp=com.faloo.BookReader4Android/com.faloo.app.activity.BookActivity }
angler:/ #

执行此命令后,手机上会提示 Walting For Debugger 字样。因为我们是以调试方式启动,所以 apk 在运行后 PC会在第一条指令处等待 恢复运行。


上IDA 

安卓加固脱壳分享

端口输入我们映射后的端口 6666 

安卓加固脱壳分享

因为我们要看他加载哪个so来解密so和dex文件。所以要勾选加载LIB时中断。如果是多个so解密dex,这样我们还能观察几个解密so的加载顺序。

安卓加固脱壳分享

点OK后 选择相应的包名。

安卓加固脱壳分享

挂载上去后, 不出意外的话,就能看到如下的画面:

安卓加固脱壳分享

直接F9运行。

安卓加固脱壳分享

运行后 手机里面还是 等待状态,这时 需要使用 JDB唤醒进程。


JDB命令如下:

jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8888
java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at com.sun.tools.jdi.SocketTransportService.attach(SocketTransportService.java:222)
at com.sun.tools.jdi.GenericAttachingConnector.attach(GenericAttachingConnector.java:116)
at com.sun.tools.jdi.SocketAttachingConnector.attach(SocketAttachingConnector.java:90)
at com.sun.tools.example.debug.tty.VMConnection.attachTarget(VMConnection.java:519)
at com.sun.tools.example.debug.tty.VMConnection.open(VMConnection.java:328)
at com.sun.tools.example.debug.tty.Env.init(Env.java:63)
        at com.sun.tools.example.debug.tty.TTY.main(TTY.java:1082)

致命错误:

无法附加到目标 VM。


执行后报了一堆错误。这是因为目标APK没有开启调试选项。APK拆包后,在 AndroidManiFest.xml 文件中的application 标签里添加一句 android:debuggable="true"。添加后再重打包即可。添加 debuggable 操作是必须的,否则是无法唤醒进程的。


但是因为一些壳会检测自身是否被修改。重打包的话,可能会崩溃。解决办法就是直接修改系统配置文件。


这里直接用 mprop 文件修改,修改之后 所有的APK都不需要手动添加 debuggable 选项,默认就是开启的。


打如下命令查看是否开启调试:

adb shell getprop ro.debuggable

1


返回1 表示开启了  返回0 表示未开启。


开启后, 再执行 jdb 命令 发现还是同样的错误提示。

这是因为jdb 的 -connect 也是需要端口操作的,所以还是需要映射端口。

Forward 本身是可以通过端口映射端口,也可以通过进程映射端口。


命令:

adb forward tcp:8888 jdwp:10152


将之前的 tcp 换成了 jdwp 表示通过进程映射。所以后面的 10152 是我们前面查看的 pid。但这操作有点麻烦, 每次启动都需要执行此命令。


另一种方法可以用 Android Studio 自带的 DDMS 来映射端口。

Android Studio 3.x版本之后 没有将 DDMS 集成到菜单栏中了,需要用Eventthing 搜索 monitor.bat 来启动。使用DDMS的好处是每次重启APK不需要再有其他操作。端口一般默认都是 8700 或者 8600 (貌似不能修改默认端口, 容易被检测)。


这个时候在执行 jdb 命令就提示成功了。

jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8888

设置未捕获的java.lang.Throwable

设置延迟的未捕获的java.lang.Throwable

正在初始化jdb...


看到这个提示表示成功了。

这个时候IDA界面也唤醒了。

安卓加固脱壳分享

当子进程状态发生改变的时候, IDA会抛一个错误码为 11 的提示。调试期间可能会反复出现类似的提示,可以通过异常选项里面,忽略掉它。


第一次运行。不下断点。因为前面我们已经勾选 lib 加载中断了。第一次主要看他加载了哪些so。直接F9 跑起。

安卓加固脱壳分享

模块窗口中看到有两个so 再运行程序就飞了。


因为我们要从SO的入口处开始分析,所以下的断点一定要精准,否则我们中断后,入口函数可能已经被执行过了。


SO中有一个类似 PE TLS的东西 可以在 main 和构造函数之前执行,就是 init_array 。

还有一个关键的函数是 JNI_OnLoad。

但这两个函数经常被一些壳 给混淆乱序了,静态是无法分析的。


静态方法定位init_array 


方法1:

通过 readelf -d 命令 readelf 是 linux下的程序。

安卓加固脱壳分享

libshella-2.9.0.2.so 文件 INIT_ARRAY 偏移是 0x3e84。

安卓加固脱壳分享

libBugly.so 的偏移是 0x176c8。


方法2: 

直接将目标SO拖入IDA 待IDA加载完后,直接按CTRL + S。

安卓加固脱壳分享

libshella-2.9.0.2.so 文件 INIT_ARRAY 看不到。

安卓加固脱壳分享

libBugly.so 的偏移是 0x176c8。


从图中可以看出 IDA 的识别能力明显不如 readelf。但readelf 也不是万能的,很多混淆乱序壳 也是查不出的。有的查出来 可能也是错误的。


通过IDA可以看到 libBugly.so 没有做处理,而 libshella-2.9.0.2.so 故意隐藏了 init_array 有点此地无银三百两的感觉。


我们重点分析 libshella-2.9.0.2.so 文件。他的偏移是 0x3e84。

IDA运行,待 libshella-2.9.0.2.so 加载后,我们在 image+0x3e84 处下断。

安卓加固脱壳分享

EB686000+0x3e84=0xEB689E84

来到此处

安卓加固脱壳分享

第1个调用的是 libBugly.so 执行的函数:

安卓加固脱壳分享

安卓加固脱壳分享

安卓加固脱壳分享

--------------------------------------------

这个是很早的时候帮朋友写的,整理硬盘的时候发现的,一起发出来。


文章好像没有写完,视频是完整的。

这个是视频地址: https://www.bilibili.com/video/BV1PL411W7P3


附件请点击阅读原文获取,其中包含6个文件:

样本APK;

样本脱壳后APK;

样本APK解压后文件;

样本APK解压后dex;

本文文章DOC格式;

本文文章PDF格式。




安卓加固脱壳分享


看雪ID:CpuDbg

https://bbs.kanxue.com/user-home-971484.htm

*本文由看雪论坛 CpuDbg 原创,转载请注明来自看雪社区

安卓加固脱壳分享

# 往期推荐

1、Realworld CTF 2023 ChatUWU 详解

2、安卓协议逆向 cxdx 分析与实现

3、Kernel PWN从入门到提升

4、Kernel PWN-开启smap保护的babydrive

5、【详解】CTFHUB-FastBin Attack

6、Relocate、PLT、GOT And Lazy Binding


安卓加固脱壳分享


安卓加固脱壳分享

球分享

安卓加固脱壳分享

球点赞

安卓加固脱壳分享

球在看


安卓加固脱壳分享

点击“阅读原文”,了解更多!

原文始发于微信公众号(看雪学苑):安卓加固脱壳分享

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年4月2日02:24:03
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   安卓加固脱壳分享http://cn-sec.com/archives/1645908.html

发表评论

匿名网友 填写信息