androidSDK中并没有锁定文件相关的api.

但是android是基于linux操作系统的,linux比较底层,灵活性也更大,为了实现锁定文件的效果,大概有以下几种办法:

  1. 用chmod命令修改文件读写权限
  2. 利用linux中的多线程独占锁,启动一个长期占用文件的后台线程
  3. 使用文件IO流,对文件的前1K字节进行加密,使其不能被识别为文件,或者读不出有意义的数据

这三种方法中最优雅的是第三种方法,下面结合金山文件锁的源码和技术文章等来详解第三种方法.

==================================技术分割线===================================

金山文件锁会在SD卡下生成一个.ksbox文件夹,这个文件夹下会保存加密后的文件.这个文件夹下有一个db.sqlite数据库文件,使用SQLite Database Browser打开后可以看到被加密文件的列表.

接下来去反编译金山的apk,最开始我使用的工具是dex2jar和java decompiler然而并没有看到加密核心代码.之后使用Apk IDE来反编译.

相关的核心代码在com/ijinshan/mPrivacy/c/j.smali文件中,里面是一些类似汇编的代码:

method public final read([BII)I

.locals 7

.parameter

.parameter

.parameter

.prologue

const/4 v6, 0x0

const/16 v5, 0x400

.line 61

iget-object v0, p0, Lcom/ijinshan/mPrivacy/c/j;->a:Ljava/io/FileInputStream;

invoke-virtual {v0, p1, p2, p3}, Ljava/io/FileInputStream;->read([BII)I

move-result v0

.line 63

const/4 v1, -0x1

if-ne v0, v1, :cond_0

.line 103

:goto_0

return v0

.line 70

:cond_0

iget-wide v1, p0, Lcom/ijinshan/mPrivacy/c/j;->f:J

const-wide/16 v3, 0x400

cmp-long v1, v1, v3

if-gtz v1, :cond_5

.line 73

iget-boolean v1, p0, Lcom/ijinshan/mPrivacy/c/j;->e:Z

if-nez v1, :cond_1

.line 75

iget-object v1, p0, Lcom/ijinshan/mPrivacy/c/j;->c:Lcom/ijinshan/mPrivacy/c/g;

iget-object v1, p0, Lcom/ijinshan/mPrivacy/c/j;->b:Ljava/lang/String;

invoke-static {v1}, Lcom/ijinshan/mPrivacy/c/g;->b(Ljava/lang/String;)[B

move-result-object v1

iput-object v1, p0, Lcom/ijinshan/mPrivacy/c/j;->d:[B

.line 76

iget-object v1, p0, Lcom/ijinshan/mPrivacy/c/j;->d:[B

if-eqz v1, :cond_1

.line 77

const/4 v1, 0x1

iput-boolean v1, p0, Lcom/ijinshan/mPrivacy/c/j;->e:Z

.line 80

:cond_1

if-ge v0, p3, :cond_3

move v1, v0

.line 82

:goto_1

add-int v2, p2, v1

if-gt v2, v5, :cond_4

.line 84

iget-object v2, p0, Lcom/ijinshan/mPrivacy/c/j;->d:[B

if-eqz v2, :cond_2

.line 85

iget-object v2, p0, Lcom/ijinshan/mPrivacy/c/j;->d:[B

invoke-static {v2, p2, p1, v6, v1}, Ljava/lang/System;->arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V

.line 100

:cond_2

:goto_2

iget-wide v1, p0, Lcom/ijinshan/mPrivacy/c/j;->f:J

int-to-long v3, v0

add-long/2addr v1, v3

iput-wide v1, p0, Lcom/ijinshan/mPrivacy/c/j;->f:J

goto :goto_0

:cond_3

move v1, p3

.line 80

goto :goto_1

.line 89

:cond_4

if-ge p2, v5, :cond_2

.line 91

iget-object v1, p0, Lcom/ijinshan/mPrivacy/c/j;->d:[B

if-eqz v1, :cond_2

.line 92

iget-object v1, p0, Lcom/ijinshan/mPrivacy/c/j;->d:[B

sub-int v2, v5, p2

invoke-static {v1, p2, p1, v6, v2}, Ljava/lang/System;->arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V

goto :goto_2

.line 98

:cond_5

const/4 v1, 0x0

iput-object v1, p0, Lcom/ijinshan/mPrivacy/c/j;->d:[B

goto :goto_2

.end method

还有一些和它相关联的函数,代码比较长就不全贴上来了,参考着文档对其进行分析的大概了解到金山的做法:

首先创建类继承InputStream,使用decodeStream函数得到输入流,重写read()方法,在方法体中对输入流的前1K字节进行解密,后面的字节直接从filename文件中读取.

解密的方法就是读取filename_e文件,每个字节异或0x6b

这样就得到了加密前的文件.

===========================技术分割线================================

这种方法算是所有方法中最优雅的方法了,虽然也有缺点(文件被误删),但是加解密计算小,只计算前1K字节.文件移动代价小,只要改变一下文件指针,就可以移动文件.速度快稳定性高.是业内主流的解决方案!

最新文章

  1. bash/shell编程学习(2)
  2. PHP接入umeditor(百度富文本编辑器)
  3. 【python】继承时注意事项
  4. RMQ (Range Minimal Query) 问题 ,稀疏表 ST
  5. 浅谈Bootstrap自适应功能在Web开发中的应用
  6. #define x do{......} while(0)的用处
  7. [hackerrank]John and GCD list
  8. Unescape HTML entities in Javascript Unescape HTML转成html代码
  9. 独立写作(A or B)
  10. Erlang Resources 资讯小站
  11. Linux系统/dev/mapper目录浅谈
  12. 20175213 2018-2019-2 《Java程序设计》第7周学习总结
  13. OpenStack Juno 版本发布——支持Spark和NFV[转]
  14. DSDS,双模,双卡,双待,单待,双通,单通,概念及相互关系?【转】
  15. Please, another Queries on Array? CodeForces - 1114F (线段树,欧拉函数)
  16. 转:使用JMeter创建数据库(Mysql)测试
  17. SSL虚拟主机安全方案
  18. 简单json---转树形json
  19. POJ3259_Wormholes_KEY
  20. Codeforces 702A Maximum Increase(dp)

热门文章

  1. tomcat 8.5.9.0 解决catalina.out过大的问题
  2. 【教程】简易CDQ分治教程&学习笔记
  3. python学习之路 第四天
  4. weui 多网页切换效果分析
  5. perl
  6. Android必学——AsyncTask
  7. Git怎样撤销一次分支的合并Merge
  8. Unity 组件不常用知识备注
  9. Android Stdio 调试Smali
  10. windows多线程编程实现 简单(1)