前幾天忙着公司的活,最近又能夠歇歇了,休息不能不作事呀?今天就來研究一下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了。不過這種作法實現起來難度有點大。這裏就詳細討論了。