吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 7522|回复: 31
收起左侧

[Android 原创] 某apk破解之利用异步回调机制实现软件注册的分析(2)

  [复制链接]
killer5 发表于 2015-7-26 17:36
新人刚接触android逆向,请多多包涵!注意:本文仅用于移动安全的研究,勿用于非法用途,由此带来的后果与本文作者无关。如果感觉好用,请支持正版,毕竟软件作者也是不容易的。

接上篇,柳暗花明之注册机制系统分析
-----------------------------------------------
     二       注册机制系统分析
-----------------------------------------------
在上篇中,讲解的注册机制的初步分析,但是当软件重启后,会失效,也就是说该apk会有重启验证。
在分析重启验证之前,我们首先来分析下,下图中的注册机制的实现。
1.PNG
首先看下付款的实现,如下:
[Java] 纯文本查看 复制代码
public void onClick(DialogInterface arg4, int arg5) {
        m.a(this.a).startActivity(new Intent("android.intent.action.VIEW", Uri.parse("https://me.alipay.com/fengyun2108")));
    }

看到没,比较简单,就是支付宝支付的界面,所以这部分不是关键。
再来到授权看看
[Java] 纯文本查看 复制代码
public void onClick(DialogInterface arg6, int arg7) {
        new q(m.a(this.a), null).start();
        AboutActivity.a(m.a(this.a), ProgressDialog.show(m.a(this.a), "提示", "授权中,请稍后...", true));
        AboutActivity.a(m.a(this.a)).setCancelable(false);
    }

在授权处理中,新建了一个多线程类q,跟进如下所示
[Java] 纯文本查看 复制代码
public void run() {
        super.run();
        Message v0 = AboutActivity.e(this.a).obtainMessage();
        v0.what = AboutActivity.f(this.a).a();
        AboutActivity.e(this.a).sendMessage(v0);
    }


看到没,此处利用异步回调机制发送了消息,那我们看下消息的what是什么,跟进bf类的a()方法,如下:
[Java] 纯文本查看 复制代码
public int a() {
        String v0 = this.a.getSystemService("phone").getDeviceId();
        Log.d("tt", "IMEI=" + v0);
        try {
            URL v1 = new URL(this.b);
            v1.openConnection().connect();
            InputStream v1_1 = v1.openStream();
            BufferedReader v2 = new BufferedReader(new InputStreamReader(v1_1));
            do {
                String v3 = v2.readLine();
                if(v3 == null) {
                    goto label_19;
                }
            }
            while(!v3.equals(v0));

            v1_1.close();
            int v0_2 = 0;
            return v0_2;
        label_19:
            v1_1.close();
            return 1;
        }
        catch(Exception v0_1) {
            Log.d("tt", v0_1.getMessage());
            return 2;
        }
    }

可以清楚的看到,该软件是如何授权的,流程为:
  首先获得机器码->然后连接服务器获取数据->将服务器获得的数据与机器码对比,如果相等返回0,否则返回1。
然后我们再看下,异步回调的实现过程。来到f类的handleMessage(Message arg5)方法中,如下:
[Java] 纯文本查看 复制代码
public void handleMessage(Message arg5) {
        DialogInterface$OnClickListener v3 = null;
        AboutActivity.a(this.a).dismiss();
        if(arg5.what == 0) {
            Log.d("tt", "Authorization success!");
            if(AboutActivity.c(this.a) != null) {
                AboutActivity.c(this.a).h(true);
                new ce().a(this.a, AboutActivity.c(this.a));
                AboutActivity.d(this.a);
                new AlertDialog$Builder(this.a).setTitle("授权成功").setMessage("恭喜,授权成功!请重新启动应用。").setPositiveButton(
                        "好的", v3).show();
            }
        }
        else if(arg5.what == 1) {
            Log.d("tt", "Authorization failed!");
            new AlertDialog$Builder(this.a).setTitle("授权失败").setMessage("请确认:\n1.您已付款成功,并按提示正确填写“付款说明”!\n2.付款成功后需要一段时间(一般为一个工作日),才能授权成功,请耐心等待。")
                    .setPositiveButton("好的", v3).show();
        }
        else if(arg5.what == 2) {
            Log.d("tt", "Authorization has exception!");
            new AlertDialog$Builder(this.a).setTitle("授权失败").setMessage("请检查网络!").setPositiveButton(
                    "好的", v3).show();
        }
    }

来到这,我想大家应该明白了吧,作者就是利用在异步回调中,进行注册授权的。
下面来看下,软件重启验证的实现过程
找到类MainActivityFree(主活动)的oncreate方法,如下:
[Java] 纯文本查看 复制代码
public void onCreate(Bundle arg3) {
        super.onCreate(arg3);
        Log.d("tt", "onCreate");
        this.getWindow().setSoftInputMode(3);
        this.requestWindowFeature(1);
        this.R = s.a(((Activity)this));
        if(this.R.n()) {
            Intent v0 = new Intent();
            v0.setClass(((Context)this), WelcomeActivity.class);
            this.startActivityForResult(v0, 1001);
        }

        this.a();
        this.b();
        this.c();
        AppConnect.getInstance(((Context)this));
        if(this.R.o()) {
            new bf(((Activity)this)).b();
        }
    }

从该方法可知,同样利用S类的a()方法,获取config.xml的内容,如下:
[Java] 纯文本查看 复制代码
this.R = s.a(((Activity)this));

最后,如果config.xml文件获得中的payVersion标签为true,则会new一个bf类,并调用其b()方法,来到该方法:
[Java] 纯文本查看 复制代码
 public void b() {
        new bh(this, null).start();
    }

继续跟进bh类如下:
[Java] 纯文本查看 复制代码
public void run() {
        Log.d("tt", "VerificateLicense...");
        super.run();
        Message v0 = bf.b(this.a).obtainMessage();
        v0.what = this.a.a();
        bf.b(this.a).sendMessage(v0);
    }

其中 this.a.a();同样为上面讲解的bf类的 public int a()方法,即在此访问服务器进行重启验证,是否非法。
流程如下所示:
APK重启->再次连接服务器验证(防止非法授权)->根据返回结果,在异步回调中,进行处理,如果正常授权,则不变,
否则,提示非法授权用户,并修改config.xml中的payVersion标签为false。
上面便是整个异步回调实现软件注册的详细过程。在了解了注册机制后,破解也就变的特别简单了。
-----------------------------------------------
     三        APK破解之道
-----------------------------------------------
根据上面的分析,最佳的破解点在于bf类的 public int a()方法中。
利用apktool反编译后,打开bf.smali文件,找到a()方法,修改如下:
2.PNG

3.PNG

4.PNG

其中,第一处和第二处修改,主要是为了获得服务器的访问网址和参数。
然后打包,签名,点击授权,并在cmd中输入adb logcat -s SN:V
运行效果如下:
5.PNG

6.PNG

7.PNG

然后打开LOG出的网址看看
8.PNG

看到没,全是授权的设备号,也算是一次意外的发现吧。








免费评分

参与人数 9威望 +1 热心值 +9 收起 理由
honckly + 1 谢谢@Thanks!
逍遥枷锁 + 1 谢谢@Thanks!
tusiji0952 + 1 我就喜欢楼主这样的
CF5702 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩.
frankpi + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩.
绘梨衣 + 1 谢谢@Thanks!
powerjiang + 1 感谢发布原创作品,吾爱破解论坛因你更精彩.
qtfreet00 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩.
Super817 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩.

查看全部评分

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

Major 发表于 2015-7-26 18:08
虽然看不懂但是还要顶一下
1847123212 发表于 2015-7-26 18:12
china豪 发表于 2015-7-27 13:47
是否就是把重启验证干掉,再修改config.xml值,便可PJ成功?
绘梨衣 发表于 2015-7-27 14:12
长知识,正在学习
caleb110 发表于 2015-7-27 14:12
多谢楼主,学习啦!
封神之剑 发表于 2015-7-27 14:43
这是干嘛用的???
jian1314 发表于 2015-7-27 15:10
刚学习的人!长见识了
叠噢 发表于 2015-7-27 15:22
我看懂了但是不知道用什么东西修改
chuge 发表于 2015-7-27 15:42
先顶帖再看
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-28 07:35

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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