wangxiaobai123 发表于 2024-9-29 16:12

illusion题解

题目特征

!(https://s2.loli.net/2024/09/29/HeO9aUKMEZ2dXpj.png)

查看是否存在壳

!(https://s2.loli.net/2024/09/29/hdqAQnaEcsMpVil.png)

Jeb反编译查看oncreate(),观察到一个点击事件监听

!(https://s2.loli.net/2024/09/29/jNsB4qF9w3QxLoy.png)

在事件监听上观察到先从assets文件下读取Flag文件内容再和用户输入字符串作为参数传给CheckFlag()函数,而CheckFlag方法有native修饰,说明是由so库加载的

!(https://s2.loli.net/2024/09/29/FtjS6yLgiTQWIcE.png)

IDA找到lib文件夹下的libnative-lib.so并加载,老方法直接搜java_包名,F5后,可以看到逻辑很简单:**将用户输入的每个字符,加上内置data字符串对应的下标的字符,然后再减去64。在和93一起作为参数传给sub_C40290C0(),运行后结果同Flag中的字符串进行比较得出。**

!(https://s2.loli.net/2024/09/29/uzU49rsMiDtgveY.png)

其中内置data字符串为

!(https://s2.loli.net/2024/09/29/ZG4rngPszcMJfSq.png)

进入sub_C40290C0(),可以看到恒跳转到sub_C4029028()处,继续跟进

!(https://s2.loli.net/2024/09/29/B54KovnxUeQEqWm.png)

可以看到这里的逻辑也很简单,通过位运算和循环逻辑来模拟除法

1. **位移操作**:使用右移(`>>`)将 `a2` 缩小,等价于除以2的幂,这样可以快速找到 `a1` 和 `a2` 的比值。
2. **逐步减法**:通过不断从 `a1` 中减去 `a2` 的不同倍数(如 `a2`、`a2 >> 1`、`a2 >> 2` 等),积累结果到 `v4`,这实际上是实现了除法的过程。
3. **乘法扩展**:通过不断乘以16和2来扩展 `a2`,实现了找到合适的倍数以提高计算效率。

综合这些步骤,最终可以得到 `a1` 除以 `a2` 的结果,反映了除法的本质。

!(https://s2.loli.net/2024/09/29/vJMLBKiP6hkYaw8.png)

**综上所诉,该题是通过将用户输入的每个字符,加上内置data字符串对应的下标的字符,然后再减去64; 得到的结果,取余93后,进行比较**

可以写逆向脚本来破解:

!(https://s2.loli.net/2024/09/29/LSz4s1t7TvfblpM.png)

结果如下,明显不符合flag的格式

!(https://s2.loli.net/2024/09/29/7zYEwdhraBGJKUo.png)

考虑是动态注册,函数处搜索JNI_Load(),看到`RegisterNatives`函数果然存在

!(https://s2.loli.net/2024/09/29/pEJTjBMFlOu3fyY.png)

跟进后发现其CheckFlag()同上面的代码逻辑一摸一样,不同的是内置data字符串发生改变

!(https://s2.loli.net/2024/09/29/rOP9CFGSblqa682.png)

动态注册的内置data字符串:

!(https://s2.loli.net/2024/09/29/47TLNj6BI8DYzpb.png)

只需更改上面脚本的data字符串即可,运行结果如下:

!(https://s2.loli.net/2024/09/29/N51xtCzGXfwOimu.png)

------

补充知识:

在 Android NDK 开发中,如果静态注册和动态注册的函数命名相同,Java 层会优先调用动态注册的函数。这是因为动态注册函数是在运行时通过 JNI_OnLoad 函数注册的,而静态注册函数在编译时被固化。具体来说,动态注册的函数会覆盖静态注册的同名函数,因此 Java 调用的会是动态注册的实现。

!(https://s2.loli.net/2024/09/29/INlqZV51jgRvACi.webp)

| 特性         | 静态注册                              | 动态注册                                       |
| -------------- | ------------------------------------- | ---------------------------------------------- |
| 注册方式       | 根据JNI命名规则自动查找方法         | 通过`RegisterNatives`在运行时绑定方法          |
| 方法签名和命名 | 方法名遵循`Java_包名_类名_方法名`格式 | 通过`RegisterNatives`函数进行注册            |
| JNI_OnLoad   | 无需使用动态注册相关API               | 包含`RegisterNatives`调用                      |
| 实现查找       | C/C++实现文件中存在静态注册命名方式   | C/C++实现文件中通过`RegisterNatives`绑定的方法 |



题目及:
链接: https://pan.baidu.com/s/1LXN1v-4HW5_Wgzv9bI9FyA?pwd=ic6w 提取码: ic6w

------

## 参考博客

(https://www.cnblogs.com/pengxurui/p/16526272.html)

[深入浅出Android NDK之使用RegisterNatives函数动态注册native函数_registernatives() 最后一个参数-CSDN博客](https://blog.csdn.net/taohongtaohuyiwei/article/details/104938240)

(https://blog.csdn.net/wangzhongshun/article/details/101273128)

(https://zhuanlan.zhihu.com/p/357885076)

(https://david1840.github.io/2020/11/09/Android-JNI函数动态注册/#:~:text=不同于静态注册中在Java类中定义好native方法后由编译器生成JNI方法,动态注册基本思想是在JNI_Onload ()函数中通过JNI中提供的RegisterNatives ()方法来将C%2FC%2B%2B方法和java方法对应起来%2C,JNI_OnLoad ()函数会在我们调用 System.loadLibrary的时候回调,注册整体流程如下%3A)

justwz 发表于 2024-9-29 20:34

跟着大佬学逆向

0nepunch 发表于 2024-9-30 12:34

学习一下

XXCAINIAO110 发表于 2024-9-30 21:50

牛逼,我想知道有没有压缩文件加密后破解的资料

xixicoco 发表于 2024-9-30 22:36

不错的学习资料

Brantfang 发表于 2024-10-1 20:03

不错的教程啊

fridaand 发表于 2024-10-2 18:27

学到了plus
页: [1]
查看完整版本: illusion题解