前几天忙着公司的活,最近又能够歇歇了,休息不能不作事呀?今天就来研究一下Android中应用锁的实现。应用锁顾名思义就是对app进行加密,在打开app的时候须要输入指定的密码才能打开应用。java
如今市场中这种应用不少的,他们的实现原理很简单,网上也有人解释了。android
咱们来随便看一下那些加密锁的应用的实现,这里我从豌豆荚上面下载了一个:应用锁.apkshell
安装运行,而后对360手机卫士进行加密,app
咱们在打开360手机卫士:ide
这时候就弹出了加密的页面oop
这时候咱们查看一下系统中正在运行的程序:this
这个应用果真在后台开启一个监听服务加密
而后咱们在使用命令:spa
adb shell dumpsys activity >activity.txtcode
查看正在运行的Activity
能够发现当前的Activity就是它的解锁页面
原理:在后台启动一个Service,而后每隔一段时间进行轮询一次,查看当前系统中topActivity,而后获取到其app的包名,从而进行过滤
直接来看代码:
LockService.java
package com.example.applock; import java.util.ArrayList; import java.util.List; import android.app.ActivityManager; import android.app.Service; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.util.Log; /** * Created by jiangwei on 2014/12/23. */ public class LockService extends Service{ private final String TAG = "LockService"; private Handler mHandler = null; private final static int LOOPHANDLER = 0; private HandlerThread handlerThread = null; private final List<String> lockName = new ArrayList<String>(); private boolean isUnLockActivity = false; //每隔100ms检查一次 private static long cycleTime = 100; @Override public void onCreate() { super.onCreate(); handlerThread = new HandlerThread("count_thread"); handlerThread.start(); //这里只是作了一个例子:只对360手机卫士作锁机制 lockName.add("com.qihoo360.mobilesafe"); //开始循环检查 mHandler = new Handler(handlerThread.getLooper()) { public void dispatchMessage(android.os.Message msg) { switch (msg.what) { case LOOPHANDLER: Log.i(TAG,"do something..."+(System.currentTimeMillis()/1000)); /** * 这里须要注意的是:isLockName是用来判断当前的topActivity是否是咱们须要加锁的应用 * 同时仍是须要作一个判断,就是是否已经对这个app加过锁了,否则会出现一个问题 * 当咱们打开app时,启动咱们的加锁界面,解锁以后,回到了app,可是这时候又发现栈顶app是 * 须要加锁的app,那么这时候又启动了咱们加锁界面,这样就出现死循环了。 * 能够自行的实验一下 * 因此这里用isUnLockActivity变量来作判断的 */ if(isLockName() && !isUnLockActivity){ Log.i(TAG, "locking..."); Intent intent = new Intent(LockService.this,UnLockActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); //调用了解锁界面以后,须要设置一下isUnLockActivity的值 isUnLockActivity = true; } break; } mHandler.sendEmptyMessageDelayed(LOOPHANDLER, cycleTime); } }; mHandler.sendEmptyMessage(LOOPHANDLER); } /** * 判断当前的Activity是否是咱们开启解锁界面的app * @return */ private boolean isLockName(){ ActivityManager mActivityManager; mActivityManager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE); ComponentName topActivity = mActivityManager.getRunningTasks(1).get(0).topActivity; String packageName = topActivity.getPackageName(); //若是当前的Activity是桌面app,那么就须要将isUnLockActivity清空值 if(getHomes().contains(packageName)){ isUnLockActivity = false; } Log.v("LockService", "packageName == " + packageName); if("com.qihoo360.mobilesafe".equals(packageName)){ return true; } return false; } /** * 返回全部桌面app的包名 * @return */ private List<String> getHomes() { List<String> names = new ArrayList<String>(); PackageManager packageManager = this.getPackageManager(); //属性 Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_HOME); List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); for(ResolveInfo ri : resolveInfo){ names.add(ri.activityInfo.packageName); System.out.println(ri.activityInfo.packageName); } return names; } @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { return Service.START_STICKY; } }这里主要就是开启一个轮询操做,而后每隔100ms去查询当前运行的Activity的包名。而后和咱们须要进行加密的app进行比较。
当发现是加密的app的时候,就会弹出咱们本身的解锁页面,而后咱们退出(这里的退出就是简单的点击返回键,固然正常状况下是须要用户输入正确的密码才能够的,可是最后都是把这个activity给finish了)解锁页面。就进入了加密的app了
固然这里作的很简单,直接对360手机卫士进行加密的,其实咱们应该会维护一个白名单,里面存储了须要加密的应用。
这里在作的过程当中其实仍是有一个问题须要注意的:
当咱们解锁了,进入到应用以后,这时候会发现又弹出了咱们的加锁页面,而后解锁了,又弹出来了。。。
这样无休止的操做,这是一个问题,其实问题很简单:
当咱们解锁以后,就会进入360手机卫士,可是这时候咱们还在轮询的检查,发现运行的仍是360手机卫士,因此还会弹出咱们的解锁页面。
这里咱们能够这么处理:
就是添加一个变量,用来记录咱们的解锁页面弹过一次了。当咱们检测到当前的activity是桌面时,就是用户不在手机卫士的页面了,这时候咱们须要将这个变量在清零,以便下次继续弹出解锁页面。
这里说的可能有点抽象,具体能够本身操做一下,就会发现问题的。
效果以下图:
好吧,上面就介绍了应用锁的实现原理。
那么下面就来进入咱们今天的主题吧
如何经过应用锁来进行帐号的盗取?
咱们如今知道一些应用在打开的时候都是须要登录的
好比QQ:
那么咱们怎么能够进行帐号盗取呢?
其实很简单:
咱们将咱们的解锁页面布置成和QQ的登录页面同样,而后监听文本框的输入内容,就能够轻松的记下用户名和密码了。
有人说盗取QQ没意思,那么还有咱们常常用的支付宝,那个实现和这个是同样的,盗取支付宝帐号就有意义了。哈哈~~
上面是说经过应用锁来进行帐号的盗取。因此说本身的设备最好仍是不要安装什么应用锁的app,特别是来历不明的应用。
上面说的都是经过应用锁这样的app.若是如今有一些坏人,他们会将上面的代码放到恶意的apk中,那么那就完蛋了。
这篇文章就介绍了经过应用锁的实现原理,来进行帐号的盗取。实现很简单,想法很大胆。因此咱们如今能作的是,尽可能少安装应用,若是真的要安装的话,那么就要安装可靠的app。关于上面的问题的解决办法:
我的感受很难作到。不过之前看过一篇文章,说能够经过当前内存运行的大小以及应用运行时预期须要的内存大小,而后作比对,就能够判断当前应用究竟是不是真实的app了。不过这种作法实现起来难度有点大。这里就详细讨论了。