吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 18940|回复: 169
收起左侧

[Android 原创] 南X周易系列逆向思路-就改一行代码

  [复制链接]
YMXuan 发表于 2020-6-3 15:42
本帖最后由 YMXuan 于 2020-6-21 00:33 编辑

更新

填坑|南X周易程序超出试用的解决办法
https://www.52pojie.cn/thread-1204354-1-1.html
(出处: 吾爱破解论坛)

1.缘起

前几天在咱们论坛发了一篇x奥周易系列软件逆向思路\更新了视频演示,反响还不错。然后正好找到了一款竞品,就是下面这位了。其实这篇文章从发完X奥就一直在酝酿了,但是技术不过关,一直没达到完美的欺骗效果。今天顺藤摸瓜就摸到了一个关键点,改一下就好。如果不想看思路的就直接看第6部分,如果想看思路的就往下翻翻,看完全文,不过思路挺长的,但是如果您像我一样,也是小白,看完还是有收获的。

2.软件介绍

八字、六爻、风水、奇门、姓名、择吉、合婚,多种平台上应用,不断完善!

3.软件列表(版本在支持系统里面有区分)

练手包下载地址在附件里

以下安卓手机软件都可免费试用30次。

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

  1. 批八字算命
  2. 玄空风水
  3. 综合排盘
  4. 六爻断卦
  5. 奇门适甲
  6. 专业起名
  7. 八字合婚
  8. 择吉程序
  9. 金口诀
  10. 八字用神
  11. 南方万年历
  12. 家居风水
  13. 六爻排盘
  14. 八字排盘

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”类。

然后点击搜索,搜索上面几个关键词。

比如搜索“注册”可以看到以下结果

image-20200529193633955

我们点击“您已经注册了本程序”这一条,看到如下代码:

    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

修改之后,我们可以看到效果如图

image-20200529194936610

但是经过测试之后我发现,这只是个美化效果,也就是说,我们只是更改了外观,并没有欺骗软件以达到注册的目的

好,接下来接着操作。

回到MT管理器,先反编译一下AndroidManifest.xml,这里是软件权限,我感觉给它联网权限不太好,那么删除android.permission.INTERNET就行了

......
    <!-- 拥有完全的网络访问权限 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- 读取手机状态和身份 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <!-- 修改或删除您的USB存储设备中的内容 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <!-- 检索正在运行的应用 -->
    <uses-permission android:name="android.permission.GET_TASKS" />
    <!-- 安装快捷方式 -->
    <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
    <!-- 此应用可显示在其他应用上方 -->
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

下面是软件的Activity

   <!-- 这块注释是我加的,一般第一个Activity就是程序的入口(主界面),不过也不绝对 -->
        <activity
            android:theme="@style/startback"
            android:label="@string/app_name"
            android:name=".An_PaiBaziActivity"
            android:configChanges="keyboardHidden|orientation"
            android:windowSoftInputMode="adjustPan">
            <intent-filter>
   <!-- 但是有下面这句 android.intent.action.MAIN 就确定了,这就是入口(主界面) -->   
                <action  android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
   <!-- 下面的代码被我精简了,省篇幅,主要就是让大家看一下有这么几个Activity -->
        <activity android:name=".activity_register" /> <!-- 注册 -->
        <activity android:name=".webshow"  /> <!-- 排盘结果 -->
        <activity android:name=".baziList" /> 
        <activity android:name=".BaziToShengri" />
        <activity android:name=".BaziSetting" />
        <activity android:name=".SelectSet" />
        <activity android:name=".DushuList" />
        <activity android:name=".textShareActivity"/>
        <activity android:name=".ShareOrFeedback" />
        <activity android:name=".BazippActivity" />
        <activity android:name=".RuanjianXuyong" /> <!-- 软件续用 -->
        <!-- 没写注释的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;-><init>()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;

一路保存,反编译,覆盖安装,排个八字

image-20200603140132849

嘿嘿,剧本好像有点不一样,软件试用界面是没了,排盘界面也出来了,可是内容去哪了?玩呢?气得我脑瓜子嗡嗡的,算了,先不破了,看看这软件哪里还有验证的地方。。咋这么麻烦呢?

这还有一个显示命例,按钮,点进去一看就是个档案夹的功能,可以时不时的把保存的案例拿出来复盘。然后我随便点了一个,想要看看复原效果,结果又看到这个熟悉的面孔了:

GIF

事情进行到这里,我又要开始深思了

  • 这软件到底搞了多少个验证的地方?
  • 验证方法是啥?
  • 就我这水平还能不能破完给我可爱的坛友写文章去了?
  • 这软件就没啥总阀门吗?

嗯~总的,我好像嗅到成功的味道了,突破点在试用次数上!试用期间功能不受限制,说干就干。成功我来了。

痛定思痛、细心研读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 < 32) {
            a.k++;
        }
        this.h.edit().putString("tms", this.a.a("65AB242" + String.valueOf(h.e(a.k)))).commit();
        a.d("trytimesxml");
        a.a("trytimesxml.xml", "system.out");
    }

看完之后,啊,这段代码就是。。嗯,,那啥的、、是吧。(球都没看懂)

不过,这段代码过于眼熟

        if (a.k < 32) {                /*如果a.k < 32,就执行a.k++*/
            a.k++;                        /*a.k++ 就是 a.k = a.k + 1*/
        }                                        /*a.k = a.k + 1就是说a.k每次加1*/

我混迹吾爱数载,一看这货就是在计数,没猜错的话,应该是这样的:

if(使用次数 < 32) {
    使用次数++;
}
/*“使用次数”在具体程序中会对应不一样的变量名,表示的都是使用次数的意思*/

然后我又开始我的脑洞了:

  • 试用次数设置为一个特别大的数,然后就随便试用呗!
  • 不行,再多的试用次数也有用完的时候?
  • 那就让使用次数自减,这样永远都小于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*16<sup>1</sup>+0*16<sup>0</sup>=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出错。

练手包下载.txt

1.62 KB, 下载次数: 440, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 32吾爱币 +29 热心值 +29 收起 理由
竹雨松风 + 1 我很赞同!
flexb15 + 1 谢谢@Thanks!
66099 + 1 用心讨论,共获提升!
simao241 + 1 + 1 我很赞同!
banckfqu + 1 + 1 谢谢@Thanks!
sym945 + 1 + 1 热心回复!
youku2020 + 1 谢谢@Thanks!
幽秀 + 1 + 1 太赞了,论坛里好多教程都是只教步骤,不教思路,对初学者太不友好了。楼主.
sky995 + 2 + 1 热心回复!
港湾999 + 1 + 1 膜拜大佬~
ll19921124 + 1 + 1 之前也试着破解过,因为我也是易学爱好者,不过试着破解注册码后,没成功,.
可靠的乐呵呵 + 1 + 1 用心讨论,共获提升!
dddl + 2 + 1 为易点赞
coopro + 1 + 1 热心回复!
智联通盟 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
土豆aoz + 1 谢谢@Thanks!
yidilove + 1 + 1 谢谢@Thanks!
孙天琪 + 1 + 1 热心回复!
别理我 + 1 + 1 小白一个 还是不懂 操作不来 如有可能 劳烦分享一下 批八字 六爻断卦
mrsdz + 1 + 1 热心回复!
潇洒浪子 + 1 + 1 热心回复!
wguage + 1 谢谢@Thanks!
修罗本灭世 + 1 + 1 用心讨论,共获提升!
yanwc + 1 + 1 热心回复!
wumian + 1 + 1 用心讨论,共获提升!
笨笨hacker + 1 + 1 我很赞同!
ws东哥 + 1 谢谢@Thanks!
Coptis_china + 1 谢谢@Thanks!
zzz777aa + 1 + 1 用心讨论,共获提升!
yjvc + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
fisst + 1 + 1 我很赞同!
紫菜、冰淇淋 + 1 + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

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

感谢你的支持,你能说出自己的思路,肯定认真看了我的思路。其中,在反编译xml的时候我贴了一段代码
   <!-- 这块注释是我加的,一般第一个Activity就是程序的入口(主界面),不过也不绝对 -->
        <activity
            android:theme="@style/startback"
            android:label="@string/app_name"
            android:name=".An_PaiBaziActivity"
            android:configChanges="keyboardHidden|orientation"
            android:windowSoftInputMode="adjustPan">
            <intent-filter>
   <!-- 但是有下面这句 android.intent.action.MAIN 就确定了,这就是入口(主界面) -->   
                <action  android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

这里面写到了寻找主界面Activity的方法,由于我直接在代码里注释的,所以可能很容易忽略掉,下次我写到正文中。

然后寻找An_xxxxActivity是173版本的办法,后来我试了181版本的,确实不太一样,但是我们触类旁通,可以反编译你说软件的xml,可以看到
        <activity
            android:name="com.nfbazi.pibazi.splash_activity">
            <intent-filter>
                <action
                    android:name="android.intent.action.MAIN" />
                <category
                    android:name="android.intent.category.LAUNCHER" />
                <action
                    android:name="android.intent.action.VIEW" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.nfbazi.pibazi.MainActivity" />
然后用DEX++打开dex文件,发现com.nfsoft.pibazi中的splash_activity并不是我们要找的,再去看MainActivity,发现是我们要找的,我们修改这个就可以了。

这里还有一个问题,那就是,181版本的,搜add的话,可能第一个结果不是我们要改的,具体位置不确定,你可以先搜搜看,如果有困难了,我们再交流。
感谢支持
 楼主| YMXuan 发表于 2020-6-4 18:53
東君丶 发表于 2020-6-4 18:31
我是小白,但是我实际操作了一下,直接搜索删除,保存,然后点一下小锤子编译,退出,最后安装,发现还是老 ...

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

害本来准备写注册机跑算法的。。。穷举法有点。。。
太慢了....(15位数字自增。。。。)
Screenshot_20200603_160901_com.aide.ui.jpg
bachelor66 发表于 2020-6-3 16:13
真的很详细啊,非常好的学习资料                       
 楼主| YMXuan 发表于 2020-6-3 16:23
涛之雨 发表于 2020-6-3 16:08
害本来准备写注册机跑算法的。。。穷举法有点。。。
太慢了....(15位数字自增。。。。)

啊,这是玄奥那个吧。
你看看南X的算法简单些不?
我这种战五渣就不想了
shenjfun 发表于 2020-6-3 16:27
谢谢分享
Strugglion 发表于 2020-6-3 16:27
下下来就是一代大师了
 楼主| YMXuan 发表于 2020-6-3 16:29
Strugglion 发表于 2020-6-3 16:27
下下来就是一代大师了

又省了大几千,官网一套下来不便宜呢
 楼主| YMXuan 发表于 2020-6-3 17:58
wushuang100 发表于 2020-6-3 16:07
不错听说这个软件比较有名

这家有年头了
wwb66668 发表于 2020-6-3 17:59
感谢楼主的分享!!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-27 09:16

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表