android的应用程序都是以apk包进行安装的,这一点想必大家都不陌生,apk本身就是一个zip压缩包


解压缩打开以后,发现里面的文件如下图


Android安全讲座第八层[二] 替换已经安装后的应用的dex文件_第1张图片


里面的各个文件夹或者文件的作用我就不详细介绍了,这个在网上一搜一大堆的。其中本文中需要引起


注意的是META-INF文件夹,其实是android apk中的数字签名文件信息,如果应用包中没有这个文件夹的时候应用是不允许被安装的。而如果我们仅仅是替换一下其中的某一个文件呢,比如我们替换一下classes.dex这个文件呢,对不起,android系统依然不会让你安装这个应用,因为在安装的时候android系统会将里面的各个文件安装同样的加密算法算一遍的,算出来的结果和META-INF这个文件夹里面的文件对比较,你人为修改了某一个文件,最后算出来的结果和原来的打包的时候签名的结果肯定是不一样的,所以在安装的时候就不能够安装了。这也是android在安装程序的时候一种保护手段吧。

如下面的错误提示


F:\apktool4.0_armel\apkprotectlite\dexchange>adb install com.example.so

cketcomm-1.apk

1968 KB/s (68536 bytes in 0.034s)

       pkg: /data/local/tmp/com.example.socketcomm-1.apk

Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]


但是如果这个android设备已经root了呢,这个时候这种保护机制基本上就形同虚设了。


下面听我慢慢道来,其中的缘故。

首先我们要知道android手机安装应用安装的位置,这在我前面的一篇博客上已经说明了。由于我们已经有root权限,可以修改任何文件夹的权限。所以我们知道android应用安装的位置是在/data/app/这个目录下面的。

而安装后的应用一般改名为安装包名加上 -1.apk 或者 -2.apk的后缀名,这里随便找一个例子应用

socketcomm.apk

这个应用,这个应用使用手机助手或者adb安装上去以后,查看/data/app/下面其实是



shell@android:/data/app # ll -a | busybox grep socketcomm

-rw-r--r-- system   system      68837 2013-12-29 14:33 com.example.socketcomm-1.apk


注意是com.example.socketcomm-1.apk 这个名字的,而真正被虚拟机加载的文件classes.dex也同时放在了/data/dalvik-cache 这个文件夹目录下


shell@android:/data/dalvik-cache # ll -a | busybox grep socketcomm

-rw-r--r-- system   u0_a97      18576 2013-12-29 14:33 data@[email protected]@classes.dex


名字也做了相应的修改。

这个是已经安装过的应用了,所以我们就可以在这里做文章了,首先修改/data/app 和 /data/dalvik-cache 这两个文件夹的权限。

chmod 777 /data/app

chmod 777 /data/dalvik-cache


然后使用baksmali 工具将原始的apk中的dex文件反编译成smali汇编语言,

java -jar baksmali.jar -o socketcomm classes.dex

在smali文件中修改,插入自己想要插入的code,然后再使用smali工具编译回classes.dex 文件

java -jar smali.jar -o classes.dex socketcomm


这个时候将原始的 socketcomm.apk 解压缩文件夹,文件夹名称换成com.example.socketcomm-1

这个文件夹,将新生成的classes.dex替换该文件夹中的同名文件,然后再zip压缩一下,后缀名修改成apk,最后使用


adb push com.example.socketcomm-1.apk /data/app/com.example.socketcomm-1.apk

adb push classes.dex /data/dalvik-cache/data@[email protected]@classes.dex


这两个命令将新修改和生成的包和dex文件写入进去,覆盖原来的同名文件,这个时候你kill掉原来在手机系统中运行的 com.example.socketcomm 这个进程,再次打开,会发现已经加入了自己的逻辑。其实运行的是你修改过的classes.dex文件了。


补充说明:估计有人会发出疑问,其实我刚才所说这些东西是使用apktool自动化不都能搞定了么,并且仅仅是 adb install -r  重新安装一下即可,再签名一下而已啊。这样做对于一些小的应用是没有什么问题,但是对于一些大的应用的反编译和再装入来说,每次签名和安装都是一场噩梦啊,那么多,那么大的文件 signed一遍,安装的时候再signed一遍,估计十分钟后就过去了,而adb push 仅仅执行的是拷贝一遍,效率是不可同日而语的。


附件:里面有本文中各种工具和apk,请做参考。

不知道为啥附件中上传不了了,就放在下载中了

http://down.51cto.com/data/1056675