[Android Security] APK自我保护 - 字符串处理

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 程序被破解。

原文地址:https://www.cnblogs.com/0616--ataozhijia/p/8921614.html

时间: 2024-10-23 14:18:02

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

Android Security

Android Security¶ 确认签名¶ Debug签名: $ jarsigner -verify -certs -verbose bin/TemplateGem.apk sm 2525 Sun Jun 02 23:44:06 CST 2013 assets/XmlPullParser X.509, CN=Android Debug, O=Android, C=US [证书的有效期为 12-10-10 下午9:48 至 42-10-3 下午9:48] ... sm 544036 Sun J

Xamarin.Android 打包Apk

由于大部分内容来自Xamarin的官网,因此这篇文章定义为翻译,原文地址: http://developer.xamarin.com/guides/android/deployment,_testing,_and_metrics/publishing_an_application/part_1_-_preparing_an_application_for_release/ 转载请注明出处:http://blog.csdn.net/supluo/article/details/43950105 个

Android中apk加固完善篇之内存加载dex方案实现原理(不落地方式加载)

一.前言 时隔半年,困扰的问题始终是需要解决的,之前也算是没时间弄,今天因为有人在此提起这个问题,那么就不能不解决了,这里写一篇文章记录一下吧.那么是什么问题呢? 就是关于之前的一个话题:Android中apk加固技术实现 关于这个问题,之前的一篇文章已经说过了,没有了解的同学可以点击这里:Android中apk加固技术实现 请务必仔细的看完这篇文章,不然今天说的内容会感觉很蛋疼的,因为今天的文章就是为了解决当初的加固技术遗留的问题,这里先大致来说一下加固apk的原理吧,先来看一张图: 看到这张

转:android中APK开机自动运行

背景知识:当Android启动时,会发出一个系统广播,内容为ACTION_BOOT_COMPLETED,它的字符串常量表示为android.intent.action.BOOT_COMPLETED.只要在程序中“捕捉”到这个消息,再启动之即可.记住,Android框架说:Don't call me, I'll call you back.我们要做的是做好接收这个消息的准备,而实现的手段就是实现一个BroadcastReceiver. 代码解析: 1.界面Activity:SayHello.jav

记:Android 安装apk的代码实现

private void installApk(String fileUri) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.parse("file://" + fileUri), "application/vnd.android.package-archive"); startActivity(intent); this.finish();} 记:Androi

Cocos2d-x3.1下 Android,APK自动升级

项目要做Android的自动升级,对于我们之前做iOS的转Cocos开发做Android方面的功能..... 不对说了.这里记录下我的实现过程. 原文地址:http://blog.csdn.net/qqmcy/article/details/36713113 首先我们要先知道Cocos下Android有几个Activity,我推测是只有一个,如果不对的话请批评指正啊. 所以我们要在主Activity也就是AppActivity.java里面添加如下代码: static AppActivity a

Android实践APK一键反编译

1.需要软件:onekey-decompile-apk 2.软件功能: 1)集成apktool/dex2jar/jd-gui. 2)只需执行一步即可反编译出apk所有文件(资源文件和jar等等). 3)反编译完毕后自动打开jd-gui反编译jar文件. 3.使用方法: 1)将下载的 onekey-decompile-apk.zip解压缩. 2)将apk文件放到 onekey-decompile-apk目录下. 3)将apk文件拖拽到_onekey-decompile-apk.bat上. 4.执行

Android 下载APK 安装APK 打开APK

今天有了一个这样的需求 :下载一个apk文件,然后当你下载完成后,按钮的文字发生改变,变成点击安装,然后安装完成之后,变成打开. 这是下载apk的方法: /** * 后台在下面一个Apk 下载完成后返回下载好的文件 * * @param httpUrl * @return */ private File downFile(final String httpUrl) { new Thread(new Runnable() { @Override public void run() { try {

Android学习--apk打包过程

1. 使用aapt工具,给所有的res目录下的资源文件生成对应的id,id会被放进R.java文件中 2. JavaC编译器,将所有Java文件转换为Class文件,其中,内部类会分别生成.class文件,命名格式为MainActivity$内部类.class R$String.class等 3. 将class中的公共常量提取出来,生成dex文件 4. aapt将生成的menifest+dex+resource+程序签名打包成zip格式,其实就是apk格式.说明,META-INF是程序签名信息