频道栏目
首页 > 安全 > 系统安全 > 正文
Android 字符串及字典混淆开源实现
2017-03-13 09:35:00      个评论      
收藏   我要投稿

Android 字符串及字典混淆开源实现。Android上对App进行混淆是常见的事情,目的就在于一定程序上保护app的逻辑不被逆向,同时还可以减少app的体积。
在开发中常用的混淆工具首先就要提ProGuard了,这是一款免费工具,默认已被Android IDE集成,开发者只需要适当的进行配置混淆规则就可以使用proguard来混淆app,但既然是免费软件,局限性自然也比较大,首先就是不支持字符串混淆,如果要使用字符串混淆,就需要使用它的商业版本DexGuard。
既然没有免费的字符串混淆工具,那就自己先实现一个,分析了JEB(Android反编译工具),Zelix(JAVA混淆器),BurpSuite(网络代理工具)等几款混淆效果比较好的软件,了解了它们的实现思路后,自己写了个简单的字符串混淆工具,先上效果:

可以看到,这里的字符串已经被处理成16进制了,每次执行时,会调用decode方法对字符串进行还原,decode方法也很简单
(str) {
    ByteArrayOutputStream(str.length() );
    (; str.length(); )
        .write((.indexOf(str.charAt()) .indexOf(str.charAt())));
    [] .toByteArray();
    .;
    .length();
    (; ; ) {
        [] () ([] .charAt());
    }
    String();
}
原理很简单,那是如何实现的呢,这里的实现思路是在smali层进行处理,即在App编译生成apk后再进行处理,使用apktool将apk进行反编译,然后再对smali中字符串进行混淆。
既然是混淆,就需要遍历每个smali文件,这个很简单
(filePath) {
    [] File(filePath).listFiles();
    () {
        ;
    }
    () {
        (.isDirectory()) {
            (.getPath());
        } {
            .add(.getPath());
        }
    }
}
使用迭代方式将每个文件添加到list中,之后就是对遍历到的文件进行处理了,直接上代码,注释写的很清楚
(path) {
    StringBuilder();
    {
        InputStreamReader(FileInputStream(path), );
        BufferedReader();
        ;
        ((.readLine()) ) {
            .().matcher();
            (.find()) {
                .group();
                (.equals()) {
                    .append();
                    ;
                }
                .();
                .group();
                .();
                ;
                ;
                (.(.substring()) .startsWith()) {
                    ;
                    } (.startsWith() (.startsWith() .(.substring()) )) {
                    ;
                } {
                    .append();
                    ;
                }
                ;
                .append();

                .append();
                .append();
            } {
                .append();
            }
        }
        .close();
        .close();
        FileOutputStream(File(path));
        .write(.toString().getBytes());
        .flush();
        .close();
    } (e) {
    }
}
这里没有去考虑全局变量,有兴趣的可以一起交流下
既然要使用字符串加密,那加密方法自然不能漏:
(str) {
    [] str.getBytes();
    .;
    .length();
    (; ; ) {
        [] () ([] .charAt());
    }
    StringBuilder(.);
    (; .; ) {
        .append(.charAt(([] ) ));
        .append(.charAt(([] ) ));
    }
    .toString();
}
插入解密smali文件,这里可以自己写个Android工程,将解密方法写入,然后打包反编译成smali即可,注意插入代码的路径要和方法中对应上,最后再使用apktool打包签名即可。
使用字符串混淆,可以更大程度上保护一些敏感信息的安全性,如加密方式,JAVA中一般使用原生加密api时会在字符串中注明类型,如”AES/CBC/PKCS5Padding”,以及一些密钥硬编码,当然想还原这种字符串混淆也并不难。
说完了字符串混淆,那字典混淆又是什么,在ProGuard中默认混淆过的效果如下:

可以看到变量名,方法名以及目录名都已经以abcd等字母替换,但这种混淆只能一定程度上提高逆向难度,可以语意还是可以慢慢对变量名等进行人工恢复的,那如何大幅度提高难度呢,就需要借助字典了,在ProGuard中,允许用户使用自定义字典,并提供了三个命令
-obfuscationdictionary dic.txt
-classobfuscationdictionary dic.txt
-packageobfuscationdictionary dic.txt
那这个自定义字典的效果如何呢?如下:

正常使用中需要注意proguard-rules.pro中的配置,以免app无法运行或者运行异常。
点击复制链接 与好友分享!回本站首页
上一篇:Apache struts2漏洞血洗中国互联网 系统安全如何保障?
下一篇:CVE-2017-2636:linux 内核n_hdlc驱动模块 本地提权漏洞
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训

版权所有: 红黑联盟--致力于做实用的IT技术学习网站