1595901624 发表于 2016-11-4 16:15

【双码锁机】对"卡Iphone7 plus永久在线"的逆向分析+加密源码

本帖最后由 1595901624 于 2016-11-7 19:47 编辑

昨天,一位坛友,给我发消息,说有款锁机,让我看看,我看了一下,现在把分析过程与大家分享一下

I首先认识一下这款软件

知彼知己,才能百战百胜,现在我们看看软件长啥样,如图(左为图标,右为锁屏界面):

         

随便输入密码,显示“输入不正确”

static/image/hrline/1.gif



II反编译


这反编译工具,我在这里有必要说明一下,许多坛友好像使用的是Android改之理或者AndroidKiller,但是我建议大家使用JEB,关于好处,
大家可以自己对比一下,我在这儿就不多说了。

我们看目录得知,锁屏界面对应的是MainActivity,定位到关键位置(因为这里有密码不正确)


从图中,可以看到,v3是获取编辑框的值,然后判断,v3和jb * 6如果不相等,就会显示密码错误,那么我们的密码就是jb*6;那么这jb是什么呢,我们网上找(如图)


发现是个随机数,那么,他就是锁屏界面的随机码,得知 随机码 * 6就是密码,输入看看,对不对(我这里是39442 * 6 = 236652)

http://www.52pojie.cn/static/image/hrline/1.gif

重点来了->锁机确实解开了,但是锁机软件还设置了pin码(如图),这锁机是双码锁机



我们再看目录,还有一个pin(也可以看一下manifest,入口Activiy是pin),那么这个就是pin码的锁机了




这个szmm()就是关键函数,划圈的就是设置密码的语句,所以我们现在就是吧pass这个变量作为重中之重,pass有个初始值6088,输入试试,
提示不对,但是,现在有些人可能输入6088会成功解锁,原因我后面再说【疑问一】


我们看看这个szmm()是从哪调用来的,找到OnCreate()函数,这个函数相当于我们学各种语言的main()函数,当程序进入Activity时,会执行它


看这个OnCreate()函数:
红圈就是调用的地方,看上面
看蓝圈,特殊字符,乍一看是base64加密的,网页上找工具,解出是乱码,暂时先不管;
看青色的圈,decoder解密俩字符,一个赋值到pinm,一个赋值到url;
(这个解密函数在enorde类里面,这个类我稍后分析,暂时跳过)【疑问二】
看绿圈,启动了一个线程,我们定位到这里,看看



线程里,又有个get(url),又把url传到get函数里面,再看get()函数



发现是联网获取数据,现在的锁机真实可怕啊,获取的什么数据(但是我们需要知道url)

【疑问一解答】这里是获取了网络上的锁机密码,但是如果当前APP没有联网,则会直接设置密码为6088,
这也就是为什么,有些人刚才输入6088,会解锁的原因

接着分析,这里调用了正则表达式,获取了网络上的密码,最后赋值给pass




因此,我们的重中之重是加解密函数


【疑问二解答】
加解密类是enorde,我就不上图了,作者采用的是Zlib+Base64回合加密,但是又在原来的基础上修改了,
加入了加密密钥,这款软件的加密密钥是“password”(加解密都需要用到它)
我试着还原了作者这个加解密函数,文章最后奉上源码的下载链接


解码之后的url是 http://www.wencaojun.top/in.html,网站截图如下



因为网页是gbk编码,要用utf8编码,否则会显示乱码,经过zhengze()函数之后,留下的就只有7593
因此7593就是当手机在网络良好状况下的锁机pin码



static/image/hrline/1.gif




III总结


软件双码加密,普通锁机密码是 随机码*6 ;在断网和网络不好的情况下,pin码是6088;
在网络良好的状况下,pin码【暂时是】7593——(作者可以更改网页内容,来修改锁机密码)


源码里面有加解密例子,在这里就不写例子了

IV 源码

最后公开【锁机中的Zlib + Base64】加解密源码

import java.io.ByteArrayOutputStream;
import java.util.zip.Deflater;
import java.util.zip.Inflater;

/**
* 被修改的Zlib + Base64加解密算法
*
* @author lhy 2016-11-03
* @version 1.1.0.5
*
*/
public class Enorde {
      private static char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();
      private String key = ""; // 自定义加密的密钥

      /**
         * 初始化base64字符集表
         */
      private static byte[] codes = new byte;

      static {
                for (int i = 0; i < 256; i++)
                        codes = -1;
                for (int i = 'A'; i <= 'Z'; i++)
                        codes = (byte) (i - 'A');
                for (int i = 'a'; i <= 'z'; i++)
                        codes = (byte) (26 + i - 'a');
                for (int i = '0'; i <= '9'; i++)
                        codes = (byte) (52 + i - '0');
                codes['+'] = 62;
                codes['/'] = 63;
      }

      public Enorde(String key) {
                this.key = key;
      }

      /**
         * 被修改的 Zlib 压缩算法
         *
         * @author lhy
         * @param str
         *            : 需要压缩的String数组
         * @Return 压缩之后的String数组
         * @throws Exception
         *             : 数据为空,则报出“数据错误”异常
         */
      public String encoder(String str) throws Exception {
                return new String(encoder(str.getBytes()));
      }
      
      /**
         * 被修改的 Zlib 解压缩算法
         *
         * @author lhy
         * @param str
         *            : 需要解压缩的String数组
         * @return 解压缩之后的String数组
         * @throws Exception
         *             : 数据为空,则报出“数据错误”异常
         */
      public String decoder(String str) throws Exception {
                return new String(decoder(str.getBytes()));
      }

      /**
         * @author lhy
         * @param str
         *            : 需要编码成Base64的String数组
         * @return : 编码后的String数组
         */
      public String encodeToBase64(String str) {
                return new String(encodeToBase64(str.getBytes()));
      }

      /**
         * @author lhy
         * @param str
         *            : 需要解码Base64的String数组
         * @return : 解码后的String数组
         */
      public String decodeFromBase64(String str) {
                return new String(decodeFromBase64(str.getBytes()));
      }

      /**
         * @author lhy
         * @param byteArray
         *            : 需要编码成Base64的Byte数组
         * @return : 编码后的Byte数组
         */
      public byte[] encodeToBase64(byte[] byteArray) {
                byte[] b = new byte[(byteArray.length + 2) / 3 * 4];
                for (int i = 0, index = 0; i < byteArray.length; i += 3, index += 4) {
                        boolean quad = false;
                        boolean trip = false;
                        int val = (0xFF & (int) byteArray);
                        val <<= 8;
                        if ((i + 1) < byteArray.length) {
                              val |= (0xFF & (int) byteArray);
                              trip = true;
                        }
                        val <<= 8;
                        if ((i + 2) < byteArray.length) {
                              val |= (0xFF & (int) byteArray);
                              quad = true;
                        }
                        b = (byte) alphabet[(quad ? (val & 0x3F) : 64)];
                        val >>= 6;
                        b = (byte) alphabet[(trip ? (val & 0x3F) : 64)];
                        val >>= 6;
                        b = (byte) alphabet;
                        val >>= 6;
                        b = (byte) alphabet;
                }
                return b;
      }

      /**
         * Base64解码
         *
         * @author lhy
         *
         * @param byteArray
         *            : 需要解码的Base64的Byte数组
         * @return : 解码后的Byte数组
         */
      public byte[] decodeFromBase64(byte[] byteArray) {
                int length = (byteArray.length + 3) / 4 * 3;
                if (byteArray.length > 0 && byteArray == '=') {
                        --length;
                }

                if (byteArray.length > 1 && byteArray == '=') {
                        --length;
                }

                byte[] b = new byte;
                int shift = 0;
                int accum = 0;
                int index = 0;
                for (int ix = 0; ix < byteArray.length; ix++) {
                        int value = codes & 0xFF];
                        if (value >= 0) {
                              accum <<= 6;
                              shift += 6;
                              accum |= value;
                              if (shift >= 8) {
                                        shift -= 8;
                                        b = (byte) ((accum >> shift) & 0xff);
                              }
                        }
                }

                try {
                        if (index == b.length) {
                              return b;
                        }
                } catch (Exception e) {
                        System.err.println("miscalculated data length!");
                }

                return b;
      }

      /**
         * 被修改的 Zlib 解压缩算法
         *
         * @author lhy
         * @param byteArray
         *            : 需要解压缩的byte数组
         * @return 解压缩之后的数组
         * @throws Exception
         *             : 数据为空,则报出“数据错误”异常
         */
      public byte[] decoder(byte[] byteArray) throws Exception {
                Enorde e = new Enorde(key);
                if (byteArray == null) {
                        throw new Exception("Data error!");
                }

                byteArray = e.decodeFromBase64(byteArray);
                if (!key.equals("")) {
                        for (int i = 0; i < byteArray.length; ++i) {
                              byte[] keyByte = key.getBytes();
                              byteArray = ((byte) (((char) (byteArray ^ keyByte))));
                        }
                }
                Inflater in = new Inflater();
                in.reset();
                in.setInput(byteArray);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                byte[] b = new byte;
                while (!in.finished()) {
                        bos.write(b, 0, in.inflate(b));
                }

                return bos.toByteArray();
      }

      /**
         * 被修改的 Zlib 压缩算法
         *
         * @author lhy
         * @param byteArray
         *            : 需要压缩的byte数组
         * @return 压缩之后的数组
         * @throws Exception
         *             : 数据为空,则报出“数据错误”异常
         */
      public byte[] encoder(byte[] byteArray) throws Exception {
                Enorde e = new Enorde(key);
                if (byteArray == null) {
                        throw new Exception("Data error");
                }

                Deflater df = new Deflater();
                df.reset();
                df.setInput(byteArray);
                df.finish();
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                byte[] b = new byte;
                while (!df.finished()) {
                        bos.write(b, 0, df.deflate(b));
                }

                byte[] bosArray = bos.toByteArray();
                if (!key.equals("")) {
                        for (int i = 0; i < bosArray.length; ++i) {
                              byte[] keyByte = key.getBytes();
                              bosArray = ((byte) (((char) (bosArray ^ keyByte))));
                        }
                }

                return e.encodeToBase64(bosArray);
      }
}



锁机APK+加解密源码
土豪下载通道:解压密码:52pojie
屌丝下载通道:链接:https://eyun.baidu.com/s/3pLo5y8j 密码:6666


1343450392 发表于 2017-1-25 23:14

http://pan.baidu.com/s/1slfcxsT   大神求破这个锁机软件   作者说很牛逼模拟器都不能开了   我QQ邮箱1343450392@qq.com    求大神破解

1595901624 发表于 2016-11-7 19:35

Hmily 发表于 2016-11-7 19:16
@1595901624 附件样本压缩包上传时必须使用压缩密码保护,压缩密码:52pojie,防止下载样本的时候被杀软拦截 ...

知道了,H大,现在马上改{:1_918:}

505547425 发表于 2016-11-4 16:29

这是什么语言?

iloveheaven 发表于 2016-11-4 16:29

我其实可想直接把第一张图里的
v0.tv1.setText("密码不正确"); 改成 v0.finish();

融化的泪记忆中 发表于 2016-11-4 16:30

厉害啊就是!{:1_921:}

iloveheaven 发表于 2016-11-4 16:30

505547425 发表于 2016-11-4 16:29
这是什么语言?

Java.{:301_1008:}

adadcc 发表于 2016-11-4 16:32

楼主好厉害呀

ShadowY 发表于 2016-11-4 16:32

楼主这不是广告吗?

55555555 发表于 2016-11-4 16:33

这个锁机app比较厉害貌似

有梦人 发表于 2016-11-4 16:38

NB大神....

老衲法号小甜甜 发表于 2016-11-4 16:41

威武霸气,谢谢楼主
页: [1] 2 3 4 5 6 7
查看完整版本: 【双码锁机】对"卡Iphone7 plus永久在线"的逆向分析+加密源码