南X周易系列逆向思路-就改一行代码

查看 206|回复 11
作者:YMXuan   
更新
填坑|南X周易程序超出试用的解决办法
https://www.52pojie.cn/thread-1204354-1-1.html
(出处: 吾爱破解论坛)
1.缘起
前几天在咱们论坛发了一篇x奥周易系列软件逆向思路\更新了视频演示,反响还不错。然后正好找到了一款竞品,就是下面这位了。其实这篇文章从发完X奥就一直在酝酿了,但是技术不过关,一直没达到完美的欺骗效果。今天顺藤摸瓜就摸到了一个关键点,改一下就好。如果不想看思路的就直接看第6部分,如果想看思路的就往下翻翻,看完全文,不过思路挺长的,但是如果您像我一样,也是小白,看完还是有收获的。
2.软件介绍
八字、六爻、风水、奇门、姓名、择吉、合婚,多种平台上应用,不断完善!
3.软件列表(版本在支持系统里面有区分)
练手包下载地址在附件里
以下安卓手机软件都可免费试用30次。

当然,跟着我做完以后就没有使用限制了

[ol]
  • 批八字算命
  • 玄空风水
  • 综合排盘
  • 六爻断卦
  • 奇门适甲
  • 专业起名
  • 八字合婚
  • 择吉程序
  • 金口诀
  • 八字用神
  • 南方万年历
  • 家居风水
  • 六爻排盘
  • 八字排盘
    [/ol]
    4.支持系统
    V1.73,适用于安卓系统4.0版至安卓7.11版。
    V1.81,适用于安卓8.0及以上版本。
    5.逆向程序
    MT管理器
    6.害,我都不好意思写标题
    方法很简单,MT进入安装包,DEX++编辑器打开classes.dex文件,打开An_xxxxxActivity,搜索add,第一个结果如下:
    add-int/lit8 v0,v0,0x1
    删除这一行,一路保存后编译、签名。
    好了,破解完了。
    说句题外话,兄弟们,看着玩意没用,这句add-int/lit8 v0,v0,0x1是我找出来的,不是你。就像我能按照小夜大佬交代的查找ChkNum来欺骗X奥系列软件一样。换成这个系列我又啥都不会了。所以你只看这句价值不大,想学点东西还得看下面的思路。
    至于成品嘛,这么简单你还好意思要成品?
    7逆向过程
    以“八字排盘 V1.73”为例,首先安装原版软件点完试用的30次,从第31次开始,则无法正常排盘,会引导注册。如图

    我们点击注册,然后会弹出注册页面

    然后有以下几种情景:
        - 点击“确定”,提示“您还没有输入注册码”
        - 随便输入注册码,点击“确定”,提示“您输入的注册码不对”
        - 点击“退出”,则返回软件主页面
    好了,直接进到MT管理器里,打开apk文件,使用DEX编辑器++打开classes.dex
    随便浏览一下类列表,有一个“activity_register”类。
    然后点击搜索,搜索上面几个关键词。
    比如搜索“注册”可以看到以下结果

    我们点击“您已经注册了本程序”这一条,看到如下代码:
        if-nez v1, :cond_96
        sget-boolean v1, Lcom/nfbazi/PaiBazi/a/a;->f:Z
        if-eqz v1, :cond_aa
        :cond_96
        const v1, -0xffff01
        invoke-virtual {v0, v1}, Landroid/widget/TextView;->setTextColor(I)V
        const-string v1, "您已经注册了本程序。"
        invoke-virtual {v0, v1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
        const-string v0, "************"
        invoke-virtual {v6, v0}, Landroid/widget/EditText;->setText(Ljava/lang/CharSequence;)V
        const/4 v0, 0x0
        invoke-virtual {v6, v0}, Landroid/widget/EditText;->setEnabled(Z)V
        :cond_aa
        return-void
    .end method
    这里面有两条判断:
        if-nez v1, :cond_96
        if-eqz v1, :cond_aa
    关于Smali语法的解读,我们可以参考这篇文章:

    if-eq        如果等于
    if-ne        如果不等于
    if-lt        如果小于
    if-le        如果小于等于
    if-gt        如果大于
    if-ge        如果大于等于
    if-eqz        如果等于零
    if-nez        如果不等于0
    if-ltz        如果小于零
    if-lez        如果小于等于零
    if-gtz        如果大于零
    if-gez        如果大于等于零
    ————————————————
    版权声明:本文为CSDN博主「Ceryool」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/Ceryool/java/article/details/51314394

    我们现在知道了
    if-nez v1, :cond_96 #如果v1不等于0,就执行cond_96的代码
    if-eqz v1, :cond_aa #如果v1等于0,就执行cond_aa的代码
    我们通过第一个代码块可以发现cond_96的代码就是包含"您已经注册了本程序。"的那一堆,cond_aa返回空,就是什么都不返回。
    可以推断一下,未注册的情况下,v1应该是0,注册后,v1就不是0了,此时返回cond_96,也就是"您已经注册了本程序。"
    那我们就欺骗一下,让未注册情况下,也能返回"您已经注册了本程序。"有两种途径可以实现此目的
        - 修改if-nez v1, :cond_96为if-eqz v1, :cond_96
        - 修改if-eqz v1, :cond_aa为if-eqz v1, :cond_96
    修改之后,我们可以看到效果如图

    但是经过测试之后我发现,这只是个美化效果,也就是说,我们只是更改了外观,并没有欺骗软件以达到注册的目的
    好,接下来接着操作。
    回到MT管理器,先反编译一下AndroidManifest.xml,这里是软件权限,我感觉给它联网权限不太好,那么删除android.permission.INTERNET就行了
    ......
       
       
       
       
       
       
       
       
       
       
       
       
       
    下面是软件的Activity
       
            
                
          
                   
                   
                

            
       
             
             
             
            
            
            
            
            
            
            
             
            
    看完之后,接着使用DEX编辑器++打开classes.dex,刚才咱们修改了activity_register,并且发现这里面并不是验证是否激活的关键所在。
    然后看一眼An_PaiBaziActivity,毕竟这是主界面,信息会多一些。Smali可读性比较差,我们转化成Java代码,可是代码有很多,看哪?咱们在一开始测试过,试用次数没了之后,再使用就会跳转到软件续用界面,那我们就搜一搜什么条件下跳转,搜索我们在AndroidManifest.xml看到的RuanjianXuyong,然后我们发现就一处可以找到:
        public void b() {
            Intent intent = new Intent();
            intent.setClass(this, RuanjianXuyong.class);
            startActivity(intent);
        }
    这句代码是什么意思呢。因为我没学过Java。所以我也没看明白,不过我清楚,肯定就是从这里跳转到软件续用界面去了。
    我们不想见到软件续用界面,因此就不能让它intent.setClass(this, RuanjianXuyong.class);
    所以,我就兴致勃勃的在Smali代码中定位RuanjianXuyong
    .method public b()V
        .registers 3
        new-instance v0, Landroid/content/Intent;
        invoke-direct {v0}, Landroid/content/Intent;->()V
        const-class v1, Lcom/nfbazi/PaiBazi/RuanjianXuyong;
        invoke-virtual {v0, p0, v1}, Landroid/content/Intent;->setClass(Landroid/content/Context;Ljava/lang/Class;)Landroid/content/Intent;
        invoke-virtual {p0, v0}, Lcom/nfbazi/PaiBazi/An_PaiBaziActivity;->startActivity(Landroid/content/Intent;)V
        return-void
    .end method
    用我这脑子想,就是,我不想要哪一行就直接注释掉哪一行,于是我在    const-class v1, Lcom/nfbazi/PaiBazi/RuanjianXuyong;前面加了一个#,然后心满意足的转进Java看了一眼,注释错了,然后我返回Smali代码,又把    invoke-virtual {v0, p0, v1}, Landroid/content/Intent;->setClass(Landroid/content/Context;Ljava/lang/Class;)Landroid/content/Intent;注释掉了,结果还是不行。
    我不禁陷入了深思!我为啥要注释掉它?因为我不想见到软件续用啊;那我想见到什么?肯定是排盘结果啊!那我直接把RuanjianXuyong替换成webshow不就行了吗?!我可真是个小机灵鬼,说干就干。
    然后我就把这行代码改成了:
        const-class v1, Lcom/nfbazi/PaiBazi/webshow;
    一路保存,反编译,覆盖安装,排个八字

    嘿嘿,剧本好像有点不一样,软件试用界面是没了,排盘界面也出来了,可是内容去哪了?玩呢?气得我脑瓜子嗡嗡的,算了,先不破了,看看这软件哪里还有验证的地方。。咋这么麻烦呢?
    这还有一个显示命例,按钮,点进去一看就是个档案夹的功能,可以时不时的把保存的案例拿出来复盘。然后我随便点了一个,想要看看复原效果,结果又看到这个熟悉的面孔了:

    事情进行到这里,我又要开始深思了
  • 这软件到底搞了多少个验证的地方?
  • 验证方法是啥?
  • 就我这水平还能不能破完给我可爱的坛友写文章去了?
  • 这软件就没啥总阀门吗?

    嗯~总的,我好像嗅到成功的味道了,突破点在试用次数上!试用期间功能不受限制,说干就干。成功我来了。
    痛定思痛、细心研读An_PaiBaziActivity的Java代码(我能看懂?其实我就是看看我认识哪几个单词)
    147行:如果我没猜错的话,trytimes就是试用次数吧,我真是个小机灵鬼
    private void e() {
            this.h = getSharedPreferences("trytimesxml", 0);
            a.k = Integer.parseInt(this.a.b(this.h.getString("tms", this.a.a("65AB24201"))).substring(7, 9));
            if (a.k
    看完之后,啊,这段代码就是。。嗯,,那啥的、、是吧。(球都没看懂)
    不过,这段代码过于眼熟
            if (a.k
    我混迹吾爱数载,一看这货就是在计数,没猜错的话,应该是这样的:
    if(使用次数
    然后我又开始我的脑洞了:
  • 试用次数设置为一个特别大的数,然后就随便试用呗!
  • 不行,再多的试用次数也有用完的时候?
  • 那就让使用次数自减,这样永远都小于32
  • 不行,减成负数报错怎么办?
  • 即便不报错,减到特别小,程序会不会崩也是个问题
  • 为什么不锁定使用次数?

    啊哈,直接把使用次数++;删掉不就行了,我真是个小机灵鬼。当然上面是java代码,咱不能修改,那咱就去改Smali代码,怎么定位呢?反正我看不懂这东西,翻也不见得能翻到,先去网上冲一会儿浪:

    ARM常用指令
    ADD    加指令
    SUB    减指令
    STR     把寄存器内容存到栈上
    LDR    把栈上内容载入一个寄存器中
    .W        是一个可选指令宽度说明符。不会影响为此指令的行为,它只是确保生成32位指令。
    BL        执行函数调用,并把使lr指向调用者的下一条指令,即函数的返回地址
    BLX        同上,但是在ARM和thumb指令集间切换
    CMP    指令进行比较两个操作数的大小
    来源: wOw的博客
    文章作者: Wossoneri
    文章链接: http://wossoneri.github.io/2019/09/12/[Android][Security]Decompile-smali/#toc-heading-23
    本文章著作权归作者所有,任何形式的转载都请注明出处。

    浪了一圈,哦不,搜索了一圈,我感觉我又行了,看样子,直接搜add就行,然后这是搜索add的第一个结果:
    1.const/16 v1,0x20
    2.if-ge vo,v1,:cond_38
    3.sget vo,Lcom/nfbazi/LiuyaoPaipan/a/a;>l:I
    4.add-int/lit8 v0,v0,0x1
    5.sput vo,Lcom/nfbazi/LiuyaoPaipan/a/a;>l:I
    第1行就是给v1赋值,16位的20正好对应十进制的32。十六进制20=2*161+0*160=32
    第2行就是那个判断语句
    第4行就是让使用次数+1
    第3、5行兴许是传递参数的?看不懂
    我们只需要删除或者注释掉add-int/lit8 v0,v0,0x1即可,注释就是在行首输入#。删除就是直接删掉。
    然后保存、编译、签名、安装、测试。畅通无阻。
    软件截图
    略,分析里面都有了,截图没意义。
    总结
    感悟
    有个故事:

    一天,一个农夫的农机坏了。自己怎么修也修不好。没办法,只能找人来修了。他请来一个修机器的,那人左看看又看看,最后在机器的某个部位,敲了一下,然后机器重新启动起来。农夫很高兴,于是便问:“多少钱。”那人说:“200美元”,农夫说:“这么贵”。那人说:“这一锤子并不贵,但是,这一锤子往哪敲就贵了”。

    其实小夜大神的搜索ChkNum和我的搜索add都没啥价值,分析思路是我得到的教训,这是有价值的地方。所以希望想自己学逆向的同学可以看看我的思路,少走一些弯路,而不是学会搜add,从我的例子来说,学会搜ChkNum对于此次欺骗毫无价值。
    其他小问题
  • 如果在删除使用次数++以前就用完了32次试用机会,触发了跳转到软件续用界面,再覆盖安装欺骗版的,仍然会跳转到软件续用界面。解决方案:https://www.52pojie.cn/thread-1204354-1-1.html
  • 如果把时间调到几年后(具体没测试),会弹窗提示软件过期、悬浮窗提示软件过期,但是没什么影响,跳过即可。去除弹窗、悬浮窗可以在论坛搜一些其他大佬的帖子,或者我晚一些时间再补一个帖子。
  • 如果仅删除add那一句,注册界面仍然显示未注册,这个地方就是个强迫症问题,想改就改,不想改的话正常使用也没人点进去看。
  • 这几个小问题我还没着手解决,如果你尝试解决时遇到难题,可以在评论区交流,或者在论坛求助。

    这个帖子前后耗时6个多小时吧,总算写清楚自己思路了,希望对您有用,也期待大家踊跃互动,我目前着手欺骗一个新的系列,这一系列的软件颜值很高,像是iOS界面,如果这贴子反响比较好,我就抓紧把这个高颜值的欺骗手段放出来。
    最后这句话没什么用,就是怕复制MD出错。

    软件, 代码

  • YMXuan
    OP
      


    kenxy 发表于 2020-6-5 10:09
    我下载了一个批八字 an_Pibazi80.apk安装包  ,用MT打开后,我选择了Classex.dex,然后用dex编辑器++打开, ...

    感谢你的支持,你能说出自己的思路,肯定认真看了我的思路。其中,在反编译xml的时候我贴了一段代码
       
            
                
          
                   
                   
                

            
    这里面写到了寻找主界面Activity的方法,由于我直接在代码里注释的,所以可能很容易忽略掉,下次我写到正文中。
    然后寻找An_xxxxActivity是173版本的办法,后来我试了181版本的,确实不太一样,但是我们触类旁通,可以反编译你说软件的xml,可以看到
            
                
                   
                   
                   
                

            
            
    然后用DEX++打开dex文件,发现com.nfsoft.pibazi中的splash_activity并不是我们要找的,再去看MainActivity,发现是我们要找的,我们修改这个就可以了。
    这里还有一个问题,那就是,181版本的,搜add的话,可能第一个结果不是我们要改的,具体位置不确定,你可以先搜搜看,如果有困难了,我们再交流。
    感谢支持
    YMXuan
    OP
      


    東君丶 发表于 2020-6-4 18:31
    我是小白,但是我实际操作了一下,直接搜索删除,保存,然后点一下小锤子编译,退出,最后安装,发现还是老 ...

    你说的老样子是什么样?
    如果在删除使用次数++以前就用完了32次试用机会,触发了跳转到软件续用界面,再覆盖安装欺骗版的,仍然会跳转到软件续用界面。
    这个问题现在还没解决
    如果仅删除add那一句,注册界面仍然显示未注册,这个地方就是个强迫症问题,想改就改,不想改的话正常使用也没人点进去看。
    这并不影响使用
    如果之前没试用结束,删了这一句之后可以先测试50遍左右,你就知道超过32次仍然可以正常使用
    wushuang100   

    不错听说这个软件比较有名
    bachelor66   

    害本来准备写注册机跑算法的。。。穷举法有点。。。
    太慢了....(15位数字自增。。。。)


    Screenshot_20200603_160901_com.aide.ui.jpg (253.89 KB, 下载次数: 1)
    下载附件
    2020-6-3 16:09 上传

    YMXuan
    OP
      

    真的很详细啊,非常好的学习资料                       
    shenjfun   


    涛之雨 发表于 2020-6-3 16:08
    害本来准备写注册机跑算法的。。。穷举法有点。。。
    太慢了....(15位数字自增。。。。)

    啊,这是玄奥那个吧。
    你看看南X的算法简单些不?
    我这种战五渣就不想了
    Strugglion   

    谢谢分享
    YMXuan
    OP
      

    下下来就是一代大师了
    YMXuan
    OP
      


    Strugglion 发表于 2020-6-3 16:27
    下下来就是一代大师了

    又省了大几千,官网一套下来不便宜呢
    您需要登录后才可以回帖 登录 | 立即注册