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. P1616 疯狂的采药 洛谷

    题目描述 LiYuxiang是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师.为此,他想拜附近最有威望的医师为师.医师为了判断他的资质,给他出了一个难题.医师把他带到一个到处都是草药的山洞里对他说 ...

  2. 洛谷P2894 [USACO08FEB]酒店Hotel [线段树]

    题目传送门 酒店 题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and ...

  3. 【教程】Tomcat 的catalina.out 日志按照自定义日期格式进行切割

    本文简单介绍在使用cronolog对tomcat的日志进行自定义日期格式的切割,方便日志的整理和遇到问题日志的排查! 安装cronolog 安装cronolog的方法网上有很多,这里也简单的介绍一下. ...

  4. Orleans核心功能

    一.Grain持久性 二.定时器和提醒 三.依赖注入 四.观察者 五.无状态工作者Grains 六.流 一.Grain持久化 1,Grain持久化目标 ①允许不同类型的存储提供者使用不同类型的存储提供 ...

  5. python中关于if-else使用性能的一点感悟

    今天做leetcode第7题关于数字倒序的问题,分别使用如下程序:(72ms) class Solution: def reverse(self, x): """ :ty ...

  6. 每日踩坑 2018-12-25 【Unable to convert MySQL date/time value to System.DateTime】异常

    之前的公司一直是用 ORM ,所以底层的事情完全不用在意, 到了这家全是似乎全是 SQL 硬编码 所以也有机会重新去补补以前也没怎么写过的基本 ADO. 不过这两天总有自己写个简易ORM的想法在蠢蠢欲 ...

  7. BZOJ.2007.[NOI2010]海拔(最小割 对偶图最短路)

    题目链接 想一下能猜出,最优解中海拔只有0和1,且海拔相同的点都在且只在1个连通块中. 这就是个平面图最小割.也可以转必须转对偶图最短路,不然只能T到90分了..边的方向看着定就行. 不能忽略回去的边 ...

  8. iOS键盘类型最全

    一.键盘风格 UIKit框架支持8种风格键盘. typedef enum { UIKeyboardTypeDefault,                // 默认键盘:支持所有字符 UIKeyboa ...

  9. spring cloud 学习(9) - turbine stream无法在eureka注册的解决办法

    turbine是啥就不多解释了,初次接触的可以移步spring cloud 学习(4) - hystrix 服务熔断处理 拉到最后看一下,turbine stream默认情况下启动成功后,eureka ...

  10. 反接保护电路 Reverse Voltage Protection

    Reverse Voltage Protection I've long wanted to pull together some reverse polarity protection ideas ...