前言:本贴的软件校验并未完全过完,因为最后的校验的部分的代码实在是没找到(应该是数据包的问题),静态分析太困难,frida和ida动态调试我目前的手机有问题搞不了,索性只能研究一半发出来给大家分析一下前半部分的签名校验,如果可以的话欢迎大佬指点一二。
准备工具:
ida7.7
任意一个java反编译工具(MT,jeb,jadx)
任意一个日志查看器(Android studio,异常跟踪)
在实战开始之前,我们需要先了解一下什么是svc指令?什么又是syscall?
SVC 是ARM 架构中用于触发系统调用的指令。它类似于传统的 syscall 指令,主要用于在用户空间(user mode)和内核空间(kernel mode)之间进行上下文切换
作用:SVC 指令允许用户态程序请求操作系统提供的特权服务,通常是在用户程序需要执行特权操作(例如文件操作、内存分配等)时使用。
执行流程:当执行 SVC 指令时,处理器会从用户模式切换到内核模式,操作系统会根据传入的参数和服务号决定执行哪个系统调用。执行完系统调用后,操作系统会返回并将控制权交还给用户程序。而在linux系统里面内存又分为内核态和用户态
SVC与中断Syscall函数里面的实现实际上就是一段汇编,这里面便是调用了svc这段指令。 它与普通的执行函数有什么区别? 它无法被inlinehook Hook,所以会极大的提高安全程度。(update:搜到 svc 指令地址,仍然可以 inlinehook)
我们可以通过反编译libc这个so文件看到syscall的底层其实就是使用了svc指令 - BTI c
- MOV X8, X0
- MOV X0, X1
- MOV X1, X2
- MOV X2, X3
- MOV X3, X4
- MOV X4, X5
- MOV X5, X6
- SVC 0
- CMN X0, #1,LSL#12
- CNEG X0, X0, HI
- B.HI __set_errno_internal
- RET
复制代码 这是64位的,如果想看32位的自行反汇编即可。
随便我们便开始今天的主题,反汇编某软件的svc签名校验并静态分析看看。
通过logcat的日志我们轻易就可以看到问题出在了什么地方。java.lang.UnsatisfiedLinkError: JNI_ERR returned from JNI_OnLoad in "/data/app/~~9gL3js7TxDHvaCG8jb5f-w==/com.yslkjgs.azmzwtds-sMuX6fs9Qu-MPmZI7MoS-A==/lib/arm64/libcycnet.so"
2025-02-16 12:10:32.497 29534-29534 DEBUG com.yslkjgs.azmzwtds E at java.lang.Runtime.loadLibrary0(Runtime.java:1077)
2025-02-16 12:10:32.497 29534-29534 DEBUG com.yslkjgs.azmzwtds E at java.lang.Runtime.loadLibrary0(Runtime.java:998)
2025-02-16 12:10:32.497 29534-29534 DEBUG com.yslkjgs.azmzwtds E at java.lang.System.loadLibrary(System.java:1661)
libcycnet.so这个so它的native方法在JNI_OnLoad中注册失败了!
JNI_OnLoad又是什么?
你现在只需要知道它是Android Native开发中动态注册方法的一个特定函数即可,如果你想逆向某个native方法,在导出表搜不到Java开头,那就是动态注册了
那么,我们已经知道是JNI_OnLoad方法出了问题,那我们就把这个so给push到电脑上去看看它的JNI_OnLoad中做了些什么吧
我们在导出表中ctrl+F搜索JNI_OnLoad,然后点进去看看,随后Tap转一下伪c代码,
是不是看着有点懵?小问题,其实只要仔细分析一下,你便能发现
是图片中框选的部分出了问题?为什么?因为正常的JNI_OnLoad中应该是不会出现两个异或判断的,如果不确定,咱们可以点进去看看djefi函数看看
哦?这不就是很明显了吗,我们可以看到47行的elfApkFd = fefes::fffga::getSelfApkFd(this);(获得APK文件描述符)我们在往下滑滑。
可以看到90行的fefes::fffga::getV2Signature(v9);,以及一大堆linux_eabi_syscall(__NR_munmap, v7, (size_t)v5);之类的调用,那么就差不多确定了,这是一个通过svc来解析APK的V2签名的签名校验函数,我们这里就会延申一种解决办法。直接找调用验证的地方,随后给它的判断改掉,或者说给他的调用NOP掉。所以说我们就可以对刚才的那个JNI_OnLoad地方修改一下判断。但是这个时候就会出现一个问题?
你会发现软件进去一会儿后就又闪退了。我们尝试Hook一下RegisterNatives看看是加载到哪个方法出了问题。到这里你就会发现好像都没啥问题,于是我就打开了Android studio的logcat看了看,还是没发现什么有用的东西,于是便把视线转到libcycnet.so中的JNI_OnLoad函数,发现了
- strcpy((char *)&qword_5B680, "libapp.so");
- v6 = dlopen((const char *)&qword_5B680, 2);
- if ( !v6 )
- return -1;
复制代码 这个比较可疑的代码,难不成?是libapp这个so中还有检测?打开libapp.so,发现的确有很多奇奇怪怪的函数,但并不能确定是否做了什么检测2025-02-16 13:22:38.083 16200-16200 Genuine com.yslkjgs.azmzwtds E invalid signature, path: /data/app/~~TnVZM32rpDYXVJkM_yQfFw==/com.yslkjgs.azmzwtds---RTx8uP7q8ZXbu7Xs9jUw==/base.apk
2025-02-16 13:22:38.083 16200-16200 Genuine com.yslkjgs.azmzwtds E invalid signature, path: /data/app/~~TnVZM32rpDYXVJkM_yQfFw==/com.yslkjgs.azmzwtds---RTx8uP7q8ZXbu7Xs9jUw==/base.apk
2025-02-16 13:22:38.083 16200-16200 Genuine com.yslkjgs.azmzwtds E invalid signature, path: /data/app/~~TnVZM32rpDYXVJkM_yQfFw==/com.yslkjgs.azmzwtds---RTx8uP7q8ZXbu7Xs9jUw==/base.apk
直到看到这个,我才感觉可能在这里面,但是从闪退情况来看更像是获取不到数据,并不是某种检测。。。当真是奇怪,打算后面抓包看一看
软件链接:https://www.123865.com/s/VYqzVv-x0P6v
|