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

乱序原理

为了增加逆向分析的难度,可以将原有代码在 smali 格式上进行乱序处理同时又不会影响程序的正常运行。乱序的基本原理如下图所示,将指令重新布局,并给每块指令赋予一个 label,在函数开头处使用 goto 跳到原先的第一条指令处,然后第一条指令处理完,再跳到 第二条指令,以此类推。

乱序流程

下面步骤需要使用到的 smalibaksmali 和 dex2jar 工具可以在:/tools 下载。

Java代码

写了一个简单的Java代码:

public class Hello {
public static void main(String[] argc) {
String a = "1";
String b = "2";
String c = a + b;
System.out.println(c);
}
}

反编译.smali文件

我们最后是通过修改 smali 指令来达到重新布局代码,所以需要通过编译生成 smali 文件。

javac Hello.java
dx --dex --output=Hello.dex Hello.class
java -jar baksmali-2.1.1.jar Hello.dex
  1. 编译生成 Hello.class

  2. dx 工具生成 Hello.dex

  3. baksmali 工具生成 Hello.smali

经过上面命令会在跟目录下生成 out/Hello.smali 文件。

修改smali文件

生成的 Hello.smali 代码为:

.class public LHello;
.super Ljava/lang/Object;
.source "Hello.java" # direct methods
.method public constructor <init>()V
.registers 1 .prologue
.line 1
invoke-direct {p0}, Ljava/lang/Object;-><init>()V return-void
.end method .method public static main([Ljava/lang/String;)V
.registers 4 .prologue
.line 3
const-string v0, "1" .line 4
const-string v1, "2" .line 5
new-instance v2, Ljava/lang/StringBuilder; invoke-direct {v2}, Ljava/lang/StringBuilder;-><init>()V invoke-virtual {v2, v0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v0 invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v0 invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; move-result-object v0 .line 6
sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V .line 7
return-void
.end method

其中我们需要关注的是 main 函数的内部流程,main 函数主要是分了三个步骤:

  • 定义字符串常量

  • 拼接字符

  • 打印字符串

修改 smali 代码顺序(只要修改 main 函数其他不变):

.method public static main([Ljava/lang/String;)V
.registers 4 .prologue goto :lab1 :lab3 sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V goto :end :lab2 new-instance v2, Ljava/lang/StringBuilder; invoke-direct {v2}, Ljava/lang/StringBuilder;-><init>()V invoke-virtual {v2, v0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v0 invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v0 invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; move-result-object v0 goto :lab3 :lab1 const-string v0, "1" const-string v1, "2" goto :lab2 :end return-void
.end method

修改后的代码顺序:

重新编译回dex文件

重新编译回 dex 文件很简单,只需要 smali 工具就可以了:

java -jar smali-2.1.1.jar Hello.smali

运行完成会生成一个 out.dex 文件。

代码对比

生成的 out.dex 不能直接用 jd-gui 查看源码,所以可以 dex2jar 工具转化为 jar 文件:

d2j-dex2jar.sh out.dex


上边为未做处理的反编译代码,下边为乱序后的代码。可以看出右边的代码逻辑相对来说会比较难懂。

[Android Security] APK自我保护 - 代码乱序的更多相关文章

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

    cp : https://segmentfault.com/a/1190000005128037 在开发过程中字符串不可避免,但是这些字符串也可能是破解的关键点,比如服务器的地址和错误提示这些敏感的字 ...

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

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

  3. java代码乱序问题

    java两个线程互相访问的时候并不能按照你的思路运行,因为执行语句可能有前后快慢之分,比如a=1和flag=true.下面线程B访问的时候 这两个赋值语句不一定按顺序执行 产生这种原因是因为指令重排序 ...

  4. APK自我保护方法

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

  5. 乱序优化与GCC的bug

      以下内容来自搜狗实验室技术交流文档,搜狐公司研发中心版权所有,仅供技术交流   摘要 --------- 乱序优化是现代编译器非常重要的特性,本文介绍了什么是乱序优化,以及由此引发的一个bug,希 ...

  6. Android ListView异步载入图片乱序问题,原因分析及解决方式

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/45586553 在Android全部系统自带的控件其中,ListView这个控件算是 ...

  7. Chrome谷歌浏览器中js代码Array.sort排序的bug乱序解决办法

    [现象] 代码如下: var list = [{ n: "a", v: 1 }, { n: "b", v: 1 }, { n: "c", v ...

  8. Android 7.0系统代码调用安装apk时报错FileUriExposedException完美解决

    项目更新遇到问题   Android项目开发中经常遇到下载更新的需求,以前调用系统安装器执行安装操作代码如下: Intent intent = new Intent(); intent.setActi ...

  9. Android Studio(十一):代码混淆及打包apk

    Android Studio相关博客: Android Studio(一):介绍.安装.配置 Android Studio(二):快捷键设置.插件安装 Android Studio(三):设置Andr ...

随机推荐

  1. APIO2018酱油记

    苟比主席树太难了学不会 还是把APIO几天的过程记下来吧...免得忘了 DAY -5 去CTSC的人都走了,机房好冷清...只有我.PSB.yasar.Chlience四个人 CSTC辣么难又辣么贵, ...

  2. UEditor插入视频,Object Iframe等标签被过滤问题处理

    UEditor插入视频由于兼容性问题,需要再处理一个视频代码,但是新版ueditor不支持Objec IFrame标签,所以要加入// xss过滤白名单 名单来源: https://raw.githu ...

  3. Codeforces 486E LIS of Sequence

    LIS of Sequence 我们先找出那些肯定不会再LIS里面. 然后我们从前往后扫一次, 当前位置为 i , 看存不存在一个 j 会在lis上并且a[ j ] > a[ i ], 如果满足 ...

  4. Java之路(五) 访问权限控制

    在Java中,所有事物都具有某种形式的访问权限控制. 访问权限的控制等级从最大到最小依次为:public,protected,包访问权限(无关键词)和private. public,protected ...

  5. Centos下命令行编译MapReduce代码(Java)并打包在Hadoop中执行

    前提条件:搭建好Hadoop系统 新建文件夹:input  和  output hdfs dfs -mkdir /inputhdfs dfs -mkdir /output 查看文件系统 hdfs df ...

  6. jquery下载,实时更新jquery1.2到最新3.3.1所有版本下载

    描述:jquery下载,实时更新jquery1.2到最新3.3.1所有版本下载 https://www.jb51.net/zt/jquerydown.htm (注意:jquery-2.0以上版本不再支 ...

  7. cv2 与 matplotlib 的 Bug 记录

    cv2 的 imread 无法读取中文路径 解决方案: img = cv2.imdecode(np.fromfile(image_path,dtype=np.uint8),cv2.IMREAD_COL ...

  8. JAVA 多线程制作大球吃小球 一、实现球的自动生成及运动 生产消费模型

    前几天用多线程实现了创建小球并移动,想到大鱼吃小鱼,便突发奇想要写一个大球吃小球.首先第一步自然是先把界面弄好啦 public class BallUI extends JPanel { privat ...

  9. AngularJS过滤器filter入门

    在开发中,经常会遇到这样的场景 如用户的性别分为“男”和“女”,在数据库中保存的值为1和0,用户在查看自己的性别时后端返回的值自然是1或0,前端要转换为“男”或“女”再显示出来: 如我要换个羽毛球拍, ...

  10. jvm在什么情况下会执行GC

    jvm在什么情况下会执行GC?[五种情况] 对象没有引用 作用域发生未捕获异常 程序在作用域正常执行完毕 程序执行了System.exit() 程序发生意外终止(被杀进程等) 什么是没有对象引用?