[Android Security] APK自我保护 - 代码乱序
cp : https://segmentfault.com/a/1190000005095406
乱序原理
为了增加逆向分析的难度,可以将原有代码在 smali 格式上进行乱序处理同时又不会影响程序的正常运行。乱序的基本原理如下图所示,将指令重新布局,并给每块指令赋予一个 label,在函数开头处使用 goto 跳到原先的第一条指令处,然后第一条指令处理完,再跳到 第二条指令,以此类推。
乱序流程
下面步骤需要使用到的 smali, baksmali 和 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
编译生成 Hello.class
dx 工具生成 Hello.dex
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自我保护 - 代码乱序的更多相关文章
- [Android Security] APK自我保护 - 字符串处理
cp : https://segmentfault.com/a/1190000005128037 在开发过程中字符串不可避免,但是这些字符串也可能是破解的关键点,比如服务器的地址和错误提示这些敏感的字 ...
- [Android Security] APK自我保护 - DEX/APK校验
cp : https://segmentfault.com/a/1190000005105973 DEX校验 classes.dex 是 Android 虚拟机的可执行文件,我们所写的 java 代码 ...
- java代码乱序问题
java两个线程互相访问的时候并不能按照你的思路运行,因为执行语句可能有前后快慢之分,比如a=1和flag=true.下面线程B访问的时候 这两个赋值语句不一定按顺序执行 产生这种原因是因为指令重排序 ...
- APK自我保护方法
标 题: [原创]APK自我保护方法 作 者: MindMac 时 间: 2013-12-28,21:41:15 链 接: http://bbs.pediy.com/showthread.php?t= ...
- 乱序优化与GCC的bug
以下内容来自搜狗实验室技术交流文档,搜狐公司研发中心版权所有,仅供技术交流 摘要 --------- 乱序优化是现代编译器非常重要的特性,本文介绍了什么是乱序优化,以及由此引发的一个bug,希 ...
- Android ListView异步载入图片乱序问题,原因分析及解决方式
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/45586553 在Android全部系统自带的控件其中,ListView这个控件算是 ...
- Chrome谷歌浏览器中js代码Array.sort排序的bug乱序解决办法
[现象] 代码如下: var list = [{ n: "a", v: 1 }, { n: "b", v: 1 }, { n: "c", v ...
- Android 7.0系统代码调用安装apk时报错FileUriExposedException完美解决
项目更新遇到问题 Android项目开发中经常遇到下载更新的需求,以前调用系统安装器执行安装操作代码如下: Intent intent = new Intent(); intent.setActi ...
- Android Studio(十一):代码混淆及打包apk
Android Studio相关博客: Android Studio(一):介绍.安装.配置 Android Studio(二):快捷键设置.插件安装 Android Studio(三):设置Andr ...
随机推荐
- NET Core中使用Angular2的Token base身份认证
下载本文提到的完整代码示例请访问:How to authorization Angular 2 app with asp.net core web api 在ASP.NET Core中使用Angula ...
- 【AtCoder】AGC020
A - Move and Win 题解 看两个人相遇的时候谁先手即可,相遇之后第一个移动的人必输 代码 #include <bits/stdc++.h> #define fi first ...
- js+ajax+springmvc实现无刷新文件上传
话不多说直接上代码 <%@ page language="java" contentType="text/html; charset=UTF-8" pag ...
- HDU - 1525
题意:给你两个数,a,b,有两个人轮流进行一次操作, 每次操作可以将大的数减去k倍的小的数,最后不能操作的人输了,问你谁赢了. 思路:我们可以用辗转相除法求出对于每一个状态可以改变几次,这样问题就变成 ...
- UEFI启动
uefi是一种更快捷快速的电脑启动配置,它的全称是“统一可扩展固件接口”(Unified Extensible Firmware Interface) 要详细了解uefi之前,我们不得不从bios说起 ...
- 搭建微信小程序基本的https与wss环境
年底了写一篇小程序环境搭建的文章, 主要是怎么搭建一个线上环境以及怎么不改动原有http Api的情况 1.准备工作 域名一个 免费证书(推荐: 腾讯云.阿里云.便宜ssl 都是免费的 配置好后先将证 ...
- 系统管理员常用的Linux命令
整理Linux的一些基本系统管理命令作为备忘 ========================================================================= 查看文 ...
- 1038 一元三次方程求解 2001年NOIP全国联赛提高组
题目描述 Description 有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程.给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100 ...
- 使用NewLife网络库构建可靠的自动售货机Socket服务端(一)
最近有个基于tcp socket 协议和设备交互需求,想到了新生命团队的各种组件,所以决定用NewLife网络库作为服务端来完成一系列的信息交互. 第一,首先说一下我们需要实现的功能需求吧 1,首先客 ...
- ubuntu中chown设置文件权限
参考文献: http://yanwen.org/doc/chown.html http://www.cppblog.com/deercoder/articles/110129.html 可以通过ls ...