cp : https://segmentfault.com/a/1190000005128037

在开发过程中字符串不可避免,但是这些字符串也可能是破解的关键点,比如服务器的地址和错误提示这些敏感的字符串信息。如果这些字符串采用硬编码方式,很容易通过静态分析获取。之前的一篇blog以提示的字符串以突破点 Android程序逆向分析

普通方式定义字符串

Java 中定义一个字符串:

private String normalString(){
String str = "Hello world";
return str;
}

反编译的.smali代码

.method private normalString()Ljava/lang/String;
.registers 2 .prologue
.line 16
const-string v0, "Hello world" .line 17
.local v0, "str":Ljava/lang/String;
return-object v0
.end method

可以看出来 const-string 关键字后面就是定义的字符串值,甚至可以使用自动化分析工具批量提取。

解决方案

1. StringBuilder 拼接

StringBuilder 类通过 append 方法来构造需要的字符串。这种方式可以增加自动化分析的难度,如果要获取完整的字符串就必须进行相应的词法语法解析了。

Java 中拼接字符串代码:

private String buildString(){
StringBuilder builder = new StringBuilder();
builder.append("Hello");
builder.append(" ");
builder.append("world");
return builder.toString();
}

反编译的.smali代码:

.method private buildString()Ljava/lang/String;
.registers 3 .prologue
.line 21
new-instance v0, Ljava/lang/StringBuilder; invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V .line 22
.local v0, "builder":Ljava/lang/StringBuilder;
const-string v1, "Hello" invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; .line 23
const-string v1, " " invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; .line 24
const-string v1, "world" invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; .line 25
invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; move-result-object v1 return-object v1
.end method

可以看出反编译后的 .smali 代码对破解增加了一定的难度,并不能一眼就识别出来。

2. 编码混淆

编码混淆是在硬编码的时候将字符串先转换成 16进制 的数组或者 Unicode 编码,在使用的时候在转回字符串。这种方式在反编译成 .smali 代码比 StringBuilder 方式更难直接识别。

Java代码:

private String encodeString(){
byte[] strBytes = {0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64};
String str = new String(strBytes);
return str;
}

反编译 .smali 代码:

.method private encodeString()Ljava/lang/String;
.registers 4 .prologue
.line 29
const/16 v2, 0xb new-array v1, v2, [B fill-array-data v1, :array_e .line 30
.local v1, "strBytes":[B
new-instance v0, Ljava/lang/String; invoke-direct {v0, v1}, Ljava/lang/String;-><init>([B)V .line 31
.local v0, "str":Ljava/lang/String;
return-object v0 .line 29
nop :array_e
.array-data 1
0x48t
0x65t
0x6ct
0x6ct
0x6ft
0x20t
0x77t
0x6ft
0x72t
0x6ct
0x64t
.end array-data
.end method

.smali 代码中可以看出已经隐藏了所有字符。

3. 加密处理

加密处理是先将字符串在本地进行加密处理,后将密文硬编码进去,运行时载进行解密。  
加密步骤:

  • 字符串加密

  • 硬编码进程序

  • 编译运行

  • 解密密文

当然因为 Java 代码相对来说比较容易反编译,并且该方式需要将解密方法放在 APK 本地,所以我们可以将解密方法通过 JNI 实现,加大反编译难度。

总结

任何一种加固方式都只是加大了反破解的难度,并不能完全避免 Android 程序被破解。

[Android Security] APK自我保护 - 字符串处理的更多相关文章

  1. [Android Security] APK自我保护 - DEX/APK校验

    cp : https://segmentfault.com/a/1190000005105973 DEX校验 classes.dex 是 Android 虚拟机的可执行文件,我们所写的 java 代码 ...

  2. [Android Security] APK自我保护 - 代码乱序

    cp : https://segmentfault.com/a/1190000005095406 乱序原理 为了增加逆向分析的难度,可以将原有代码在 smali 格式上进行乱序处理同时又不会影响程序的 ...

  3. APK自我保护方法

    标 题: [原创]APK自我保护方法 作 者: MindMac 时 间: 2013-12-28,21:41:15 链 接: http://bbs.pediy.com/showthread.php?t= ...

  4. 转:android中APK开机自动运行

    背景知识:当Android启动时,会发出一个系统广播,内容为ACTION_BOOT_COMPLETED,它的字符串常量表示为android.intent.action.BOOT_COMPLETED.只 ...

  5. Android Security

    Android Security¶ 确认签名¶ Debug签名: $ jarsigner -verify -certs -verbose bin/TemplateGem.apk sm 2525 Sun ...

  6. Python 通过脚本获取Android的apk的部分属性,再通过加密算法生成秘钥。

    Python 通过脚本获取Android的apk的部分属性,再通过加密算法生成秘钥. #!/usr/bin/env python # -*- coding: utf- -*- import os im ...

  7. 将HTML5封装成android应用APK文件的几种方法

    越来越多的开发者热衷于使用html5+JavaScript开发移动Web App.不过,HTML5 Web APP的出现能否在未来取代移动应用,就目前来说,还是个未知数.一方面,用户在使用习惯上,不喜 ...

  8. Android 天猫apk聊天数据库解密

    1.使用Android 天猫apk 进行聊天会产生tmallWangXinDB的数据库.2.用sqlite3 工具打开提示加密或者错误.3.需要对该数据库进行解密. 解密流程:1.反编译apk,dex ...

  9. 将HTML5封装成android应用APK文件的几种方法(转载)

    越来越多的开发者热衷于使用html5+JavaScript开发移动Web App.不过,HTML5 Web APP的出现能否在未来取代移动应用,就目前来说,还是个未知数.一方面,用户在使用习惯上,不喜 ...

随机推荐

  1. 解决连不上dl.google.com和dl-ssl.google.com

    http://ping.chinaz.com/ 开发android遇到的最大问题就是Google被墙了,而我们的sdk又需要通过dl.google.com和dl-ssl.google.com去下载一些 ...

  2. C语言:指针实现交换两个变量的值

    用指针交换两个变量的值(10分) 题目内容: 用指针交换两个变量的值 主函数参考: int main( ) { int a,b; scanf("%d%d",&a,& ...

  3. Flutter与Dart 入门

    Flutter简介 Flutter是google推出的,一个使用Dart语言开发的跨平台移动UI框架,通过自建绘制引擎,能高性能.高保真地进行Android和IOS开发. Flutter是什么 Flu ...

  4. Codeforces Round #296 (Div. 1) B - Clique Problem

    B - Clique Problem 题目大意:给你坐标轴上n个点,每个点的权值为wi,两个点之间有边当且仅当 |xi - xj| >= wi + wj, 问你两两之间都有边的最大点集的大小. ...

  5. 关于spark ui中executor显示的内存量与设置的内存量不符的问题

    executor显示的内存量是实际执行程序使用的内存量,也就是排除bspark.storage.memoryFraction设置的比例外,然后使用的内存量. 默认是0.6,所以executory和dr ...

  6. Db2与Oracle的区别

    这个部分是自己随便整理下. 在工作上需要,公司需要DB2兼容Oracle. 不懂DB2与Oracle的细节,这里努力整理,以后精通了再回来重新修改. https://www.2cto.com/data ...

  7. 【IObit】五大软件激活码( Advanced Systemcare....)

    IObit Malware Fighter 6Pro 破解: 打开软件安装位置,下载替换dll文件 链接: https://pan.baidu.com/s/1Euz87MCANuCnRqZsMQ_w4 ...

  8. 网页图表Highcharts实践教程之标签组与载入动画

    网页图表Highcharts实践教程之标签组与载入动画 Highcharts标签组 在图表的大部分元素都提供了标签功能.但很多时候,我们需要额外说明一些信息.这个时候借助原有的图表元素的标签功能就不是 ...

  9. Codeforces.835E.The penguin's game(交互 按位统计 二分)

    题目链接 \(Description\) 有一个长为\(n\)的序列,其中有两个元素为\(y\),其余全为\(x\).你可以进行\(19\)次询问,每次询问你给出一个下标集合,交互库会返回这些元素的异 ...

  10. 堆排序的C++代码实现

    堆排序C++实现 堆排序的具体思路可以查看<算法导论>这本书,一下只提供笔者的C++实现代码,并且将笔者在编写程序的过程当中所遇到的一些细节问题拿出来作一番解释,希望能够对对堆排序有一个透 ...