低调(d-iao) 发表于 2022-8-19 23:16

如果当吃瓜的也开始种瓜

本帖最后由 低调(d-iao) 于 2022-8-19 23:19 编辑

    今日,某社区又爆出一个大瓜,"xxxx夫妇已秘密离婚",引来了一批吃瓜群众。有的人围观,有的人讨论,有的人等待,迅速将此瓜送上了热搜。

    午后,社区上很快就涌出了大量相关资讯,有来自小道的消息,有事件的经过,有案件的总结,也有网友们的各种猜测。就像在帮助吃瓜群众能更好的了解整个事件的来龙去脉。

    然而这些资讯并非凭空而来,都是通过一些人进行了数据的整理和分析,然后再以能让群众理解的方式去发表。

    在逆向里,我们时常会提到"分析"这一个单词。可是对于新手来说"分析"是一个又熟悉且陌生的词汇。熟悉的是他们理解分析的意思,陌生的则是他们不懂如何去分析。

    所谓分析,就是将代码转化为自己能理解的方式去解读。

    现在来进行一个简单的分析,这是一个smali代码,我们目的是要把它转成能理解的语句。

```java
const-string v0, "Apple"

iput-object v0, v1, Lcom/sample/code;->action:Ljava/lang/String;
```
const-string 是定义一个字符串变量,变量存放着一个apple单词,然后再通过iput把变量里的apple放到了名为action的容器里。

接着我们换一个更好理解的方式去解读。

我手上有一个颗苹果,然后我把苹果放到了一个名为action的箱子里,所以现在我们知道action箱子里被我们放进了一颗苹果。

通过分析解读,可以发现它已经变成显而易懂的内容了。所以玩逆向破解,真正要学习的是如何分析,而不是如何破解,唯有理清原由,我们才会知道下一步该如何去做,对人对事亦如此,而不是不分青红皂白的胡来一顿。

再来看一段smali代码,这是一段判断是否为付费用户的代码

```java
invoke-static {}, Lcom/lightcone/analogcam/dao/AppSharedPrefManager;->getInstance()Lcom/lightcone/analogcam/dao/AppSharedPrefManager;

move-result-object v0

invoke-virtual {v0}, Lcom/lightcone/analogcam/dao/AppSharedPrefManager;->getEvalPro()Z

move-result v0

if-eqz v0, :cond_37

const-string v0, "subscribe user"

return-void

:cond_37
const-string v0, "non subscribe user"

return-void
```
通过分析,可以知道这段代码主要是通过获取AppSharedPrefManager里的getEvalPro来判断自身是否已付费,Z在代码里则表示boolean,boolean数据只有2种结果,"true" or "false",在代码表示上则是"1"或"0"。所以可以知道从getEvalPro返回的结果要么是1,要么是0。然后再把得到的结果存放到v0里,接着通过if-eqz来判断是否等于0,如果等于0则执行未付费代码,等于1则执行已付费代码。

这时候可以再进一步分析,进入到getEvalPro代码段,看看具体情况。

```java
.method private getEvalPro()Z
    .registers 4

    .line 572
    iget-object v0, p0, Lcom/lightcone/analogcam/dao/AppSharedPrefManager;->sharedPreferences:Landroid/content/SharedPreferences;

    const-string v1, "eval_pro"

    const/4 v2, 0x0

    invoke-static {v0, v1, v2}, Lcom/lightcone/analogcam/dao/AppSharedPrefManager;->getBoolean(Landroid/content/SharedPreferences;Ljava/lang/String;Z)Z

    move-result v0

    return v0
.end method
```
SharedPreferences是android的轻量级存储类,可以存储各种配置信息。这段代码主要是获取配置文件里名为evel_pro的boolean数据,最后再把获取到的数据赋予v0并返回到getEvalPro结果。所以从上面的分析,我们就可以知道,在未付费之前,eval_pro的数据一定是0。同时也可以发现,从分析过程中,自然就有了该怎么去破解的思路,只要把0改成1,就能完成破解。所以很多新手都存在一个问题,每次跟着教程都会破解,可是到自己独自破解的时候却就不会了,这就是因为没学会分析,不懂原由,也就不知道如何去破解。

可是现在软件的保护手段越来越强,很多时候并不是只改个判断就能完事,这时候拼的就是技术与知识。所以要记住从分析,破解,到实现,是三种概念。从分析里我们可以了解到如何去破解,可是从破解里我们要做的是如何去实现出来。

理论到这里也讲得差不多了,那现在就来个实践吧。

准备工具:
1. android反编译工具
2. 抓包工具

操刀软件:
Nomo相机

这软件我不会进行完整的讲解,主要前半段的破解只需要修改boolean值就能完成本地vip破解,都是一些初级的东西,所以这里就略过咯。

软件付费限制为相机滤镜,未付费只能使用几款滤镜。


可是当完成本地破解后,发现依然无法使用滤镜。这时候怀疑数据可能是通过网络验证,所以对其进行抓包处理。



通过抓包,其中有一条数据android_product_list引起我注意。


检查响应包发现已通过base64加密。


这里直接使用在线base64解密对其转换成解密数据。解密后发现,会员滤镜在未付费之前是不提供下载地址的。图中可以看到download_url是空白的,所以仅修改本地vip是无法完成破解的。


已知下载地址需要通过服务器验证会员才可以获取,是否就无法破解?咳咳,现在放弃还太早,我们从试用软件过程可以知道,未付费情况下有提供几款免费的滤镜,从数据包里可以看见免费的下载地址并未经过任何加密,所以可以利用这点进行分析。


从2组下载地址里可以看出,不一样的仅仅只是skin后面的内容。如果说skin后面的是滤镜名称,那么名称后面的那组数字又代表什么呢?

```url
https://nomo-cdn-na.dafork.com/Skin-Tropical-30.zip

https://nomo-cdn-na.dafork.com/Skin-FR2-15.zip
```

经过观察内容,可以得出前面是滤镜名称,后面数字表示skin的版本号。这样我们也就可以推断出会员的下载地址了。


首先我们先来整理一下下载地址。

```url
download_url = "https://nomo-cdn-na.dafork.com/Skin" + "-" + skin name + "-" + skin version + ".zip"
```

然后随便找一个会员滤镜在浏览器测试一下,嘿嘿,成功了,可以正常下载。

```url
https://nomo-cdn-na.dafork.com/Skin-135P-18.zip
```


至此我们已经找出了会员的x地址,那么我们也就有了如何破解的思路,只需要把下载地址都补全即可。

接下来我们就要把这想法给实现,mt里搜索download_url定位到关键出。


然后我们需要写一段代码进行补全,代码如下

```java
.method public getDownload_url()Ljava/lang/String;
    .registers 15

    .line 1
    //获取原本的下载地址
    iget-object v0, p0, Lcom/blink/academy/nomo/bean/store/CameraGoodBean;->download_url:Ljava/lang/String;
   
    //判断下载地址是否为空
    invoke-static {v0}, Landroid/text/TextUtils;->isEmpty(Ljava/lang/CharSequence;)Z

    move-result v2

    if-eqz v2, :cond_ac
   
    //下载地址如果不存在则折行此处
    //获取ios_id的滤镜名称
    iget-object v3, p0, Lcom/blink/academy/nomo/bean/store/CameraGoodBean;->ios_id:Ljava/lang/String;

    const-string v4, "blink.academy.nomo."

    const-string v5, ""
   
    //过滤掉前面多余的字符
    invoke-virtual {v3, v4, v5}, Ljava/lang/String;->replace(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;

    move-result-object v3
   
    //然后转换成大写字母
    invoke-virtual {v3}, Ljava/lang/String;->toUpperCase()Ljava/lang/String;

    move-result-object v3
   
    //接着再获取skin版本
    iget v4, p0, Lcom/blink/academy/nomo/bean/store/CameraGoodBean;->skin_version:I
   
    //最后将下载地址进行合并
    new-instance v5, Ljava/lang/StringBuilder;

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

    const-string v6, "https://nomo-cdn-na.dafork.com/Skin-"

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

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

    const-string v3, "-"

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

    invoke-virtual {v5, v4}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;

    const-string v3, ".zip"

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

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

    move-result-object v0

    :cond_ac
    return-object v0
.end method
```

完成后,我们还需要对几个参数的数据进行修改,如图中标记的地方,这里就不一一列出了。


现在可以进行打包和安装了,可以看见已经可以正常下载和使用了,表示我们已经破解完成。





后记: 只要顺着破解三步骤 分析->破解->实现,基本就不会有什么大问题了,如果说破解不到,就是分析不到位,如果说实现不了,就是技术上还需要增强。这样的去进行进行简化,自然就会找到自身的不足。凡事只要理清了,问题也就明了了。

Hmily 发表于 2022-8-19 23:19

哈哈哈,这个开头我是没想到后面。。。

kurokihitomi 发表于 2022-8-20 00:15

UC主编:明天来公司报道~

kk159 发表于 2022-8-20 01:17

当种瓜的去卖瓜呢?{:301_978:}

im热情 发表于 2022-8-19 23:21

你这是uc主编啊

Patches 发表于 2022-8-19 23:25

一瓜接一瓜   瓜瓜相连{:301_993:}

QRQF001 发表于 2022-8-19 23:31

你这开头,让人以为又有什么大瓜了呢,结果后面就给我看这个?

wty3025 发表于 2022-8-19 23:34

响应如果被aes加密了怎么逆向找key

rig 发表于 2022-8-19 23:42

确实,从标题和开头我还以为真是要讲如何收集和分析资讯呢,结果一个急转弯又拐回来破解;www

博爵 发表于 2022-8-20 00:52

还可以这么操作,我说赋值提示版本比较低,无法使用。估计就是网络验证,看来搞不定了,太复杂
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 如果当吃瓜的也开始种瓜