File IO-app的加固

目录

安卓包内容分析

代码加固的几种方式

Dex文件加固技术原理解析

加固需要解决的问题

加固流程

加固的整体框架

解密流程

拓展知识:对称加密与非对称加密


安卓包内容分析

META-INF里边是签名的文件 ,dex文件就是Dalvik,反编译主要是针对这个文件。

混淆之后的代码基本逻辑没有变化,还是可以了解到其中的逻辑。

免费的加固方案加固的意义不是很大。

代码加固的几种方式

反模拟器:模拟器的代码是可以自己写的,这样子我们可以安卓源码上进行log的打印,可以监控模拟器上代码的运行。

代码虚拟化:所有代码都运行在虚拟机上,那么我们能不能让你的代码不运行在虚拟机上?因为我们的代码最终都要运行在虚拟机上,无论怎么加固,我们都逃不了编解码的方式,所以现在商用的加固方式采用了他们自定义的虚拟机运行,通过他们的虚拟机,转换成另一种编码,相当于多了一种编码方式,代码虚拟化,相当于在虚拟机上边再套一个虚拟机。整体上代码就运行在自定义的虚拟机上边。这就是代码虚拟化。

加密方式:dex文件必须要加载到内存中才能运行,如果没有找到,必须在磁盘中加载进来。类是需要的时候才加载。

代码并不一定需要全部加固。加固核心代码就行了。有两个原因:1、全部加固影响性能;2、全部加固,那么我们用谁来对加固的代码进行解密呢?微信就是使用加密技术。

参考文章[原创]从第一代到第五代,App加固技术详解-Android安全-看雪论坛-安全社区|安全招聘|bbs.pediy.com

面向二进制代码的多线程虚拟化保护技术 - 安全内参 | 决策者的网络安全知识库

Dex文件加固技术原理解析

 

 打包需要进行对齐,dex的一个优化。这样可以减少加固后的包的体积。

加固需要解决的问题

1、dex文件可以随便拼凑吗?

2、壳dex怎么来的?

3、如何签名?

4、如何运行新的apk(如何脱壳)?

一个Dex文件的整体结构:

在加固的时候,可以对将类的定义区展示,将类的数据区进行加密,这样在最后展示的dex文件中,就会出现只看得到定义区 ,而数据区是空的情况,例如微信的一部分代码:

checksun:对文件的整体的校验,signature:签名信息;file_size:文件大小,我们进行dex文件加密的时候需要注意这几个参数的修改。正是因为dex文件的构造我们才能对dex文件进行加密。

apk打包流程:

都是在SDK里边的build-tools文件夹下边的工具帮我们做的。 

加固流程

1、apk->解压缩->过滤文件(找到所有的dex文件)

文件操作中flush()方法的的作用:强制将未填满的缓存数据写到硬盘中。缓存之所以能够提高新能,是通过减少磁盘的磁头操作来提高性能。

如果是写的是字符,调用close的时候,也会自动调用flush(),字节流也有自动flush(),看源码。

调用bwdef.close()会报错;bwdef关闭--》oswDef关闭--》fos关闭,所以会报错。
File file = new File("src/testtxt/OutputStreamWriter.txt");
// true, 设置内容可以追加
FileOutputStream fos = new FileOutputStream(file, true);
//todo 是否有一个封装好的writer?
OutputStreamWriter oswDef = new OutputStreamWriter(fos);
BufferedWriter bwdef = new BufferedWriter(oswDef);
bwdef.write(STRING);
bwdef.newLine();
bwdef.flush();
// bwdef.close();  // 为什么不能写?
System.out.println("oswDef encoding: " + oswDef.getEncoding());
Exception in thread "main" java.io.IOException: Stream Closed
	at java.base/java.io.FileOutputStream.writeBytes(Native Method)
	at java.base/java.io.FileOutputStream.write(FileOutputStream.java:349)
	at java.base/sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:234)
	at java.base/sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:313)
	at java.base/sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:318)
	at java.base/sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:160)
	at java.base/java.io.OutputStreamWriter.flush(OutputStreamWriter.java:250)
	at java.base/java.io.BufferedWriter.flush(BufferedWriter.java:257)
	at classTop.OutputStreamWriterTest.testOutputStreamWriter(OutputStreamWriterTest.java:38)
	at classTop.OutputStreamWriterTest.main(OutputStreamWriterTest.java:15)

2、将一个文件文件按照字节流读出来的方式:

RandomAccessFile fis = new RandomAccessFile(dexFile, "r");
byte[] buffer = new byte[(int)fis.length()];
// 把这个文件全部读出来。
fis.readFully(buffer);
fis.close();

加密之后,需要对文件重新命名,用来区分壳文件和源文件。

if (newApkFile.isDirectory()) {
	File[] listFiles = newApkFile.listFiles();
	for (File file : listFiles) {
		if (file.isFile()) {
			if (file.getName().endsWith(".dex")) {
				String name = file.getName();
				System.out.println("rename step1:"+name);
				int cursor = name.indexOf(".dex");
				// 给文件重新命名。
				String newName = file.getParent()+ File.separator + name.substring(0, cursor) + "_" + ".dex";
				System.out.println("rename step2:"+newName);
				file.renameTo(new File(newName));
			}
		}
	}

arr文件与apk的区别:仅仅没有签名文件而已。

为什么壳从aar来?

我的application来自module的application,正式因为application在aar中的,代码在aar的jar包里边,正式因为这个jar是和我们的dex文件是分开的,那么这个时候aar的application就不会被加密,正是因为不会被加密,我们可以这个application来进行解密,因为我们把apk里边所有的dex文件进行加密。这就是我们的主要目的。

加固的整体框架

 我们要明白,要能运行加固后的apk,必须要多加密的dex文件进行解密。加密的dex文件分两部分,一部分是壳dex,另一部分是加密的dex,那么我们的源dex文件要能解密运行,就需要利用可以运行的程序解密,这个程序要在java虚拟机中运行,这个代码必然没有加密,如何让这部分代码没有加密呢?需要将两部分dex文件分开,加密的称为源,未加密的称为壳,不加密的壳应该具有什么功能?需要能够解密的功能,解密最好在application中进行。所以application成为了我们解密的入口代码,这个代码一定不能加密。

 此时我们就需要将这个application写到一个独立的module里边去。编译成一个aar文件:

 最终会被编译到这个jar包里边去。

 但是真正的项目中,一般不会这么写,因为application里边一般会做很多初始化的操作,一般的,我们会在也会另外再写一个主application,利用插件化的技术,将mylibrary变成一个插件。 当主application启动的时候,通过反射hookapplication的启动流程,进而启动module中的未加密的application,利用这个application解密之后再启动主application。

解密流程

脱壳->源dex 解密->加载这些dex文件

脱壳应该有两个时机,安装apk(错误的,不可以这么用)和运行apk时。但是一般更可靠的时机是运行apk,因为只有此时才会运行代码。运行时越早越好,在attachBaseContext中进行解密。

我们也不需要在每次启动的时候都进行解密,在app启动时增加一个判断,如果解密后的文件已经存在了,就不用再走解密流程了。

加密解密是一个攻防的工程。

加载dex文件涉及到热修复的流程。hook就是用反射技术去反射安卓源码的过程,就是搞我们想做的事情。

拓展知识:对称加密与非对称加密

对称加密:加密与解密所有的密钥是同一个,一旦泄露,就会出现不安全的情况。

非对称加密:加密与解密的密钥不同,分为公钥和私钥。

常见的算法:1022 ^ 2343 %1110(无数种可能) = 4567

                       1024 输入                4567 输出

                       1203是私钥

                       2343是公钥

HTTPS是通过证书来保证后续服务器与客户端的对称加密的密钥的安全。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值