探索xpose如何通过修改手机数据来实现刷某积分墙某团购的
2016-01-07 10:46
766 查看
最近看到网上的基于xpose的android修改器可以通过修改手机信息来实现刷单刷广告刷积分墙,于是乎,照着做了一个,已经可以完美支持刷大部分积分墙广告,然后在此发布一些主要的实现方法。
关于xpose简单使用可以看上一篇,网上的xposeapp实在太多了,例如绿色守护
某些赚钱平台是没有用户登陆体系的,判断用户的依据无非是一些imei,mac,androidid码,我只要分析这个软件是使用什么id来判断用户的,然后在使用xpose修改他们,就可以很好的装成很多个用户的样子。
那么接下来就是修改手机数据了,查看下面代码
只要将要修改的数据保存到static JsonObject中,每次只要程序执行到你hook的方法,就能执行你上面写的回调啦,注意每个app的static JsonObject不是共用的,你会发现每次启动一个app都会调用handleLoadPackage方法。
当你将imei 从123改为321的时候,将他保存到本地文件,但是static JsonObject没有更新,我这里是在handleLoadPackage更新,或者在hook方法里面更新数据,比如
initConfigMap也就是将数据读取到 static JSONObject 而已
上面的功能就能实现某些该数据神器的功能,只要摸清大致的思路,想要修改什么数据都能依瓢画葫芦出来,数据来源什么的大家就自己想办法了,希望能起到帮助!!!
关于xpose简单使用可以看上一篇,网上的xposeapp实在太多了,例如绿色守护
某些赚钱平台是没有用户登陆体系的,判断用户的依据无非是一些imei,mac,androidid码,我只要分析这个软件是使用什么id来判断用户的,然后在使用xpose修改他们,就可以很好的装成很多个用户的样子。
那么接下来就是修改手机数据了,查看下面代码
public class XposeHook implements IXposedHookLoadPackage{ @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { if(android.os.Process.myUid() <= 10000){ L.debug("系统应用"+loadPackageParam.packageName+android.os.Process.myUid()); return ; }else{ L.debug("普通应用"+loadPackageParam.packageName+android.os.Process.myUid()); } //xpose生效之后,每次启动一个app都会执行handleLoadPackage方法。当你将imei 从123改为321的时候,将他保存到本地文件,但是static JsonObject没有更新,initConfigMap是为了更新static JsonObject,要执行到改方法必须要重启app,或者在addHookMethod方法更新的话可以更快,但是addHookMethod调用太频繁了,强迫症不喜欢 XposeUtil.initConfigMap(); if(RecordFileUtil.ExternalStorage.length() == 0){ RecordFileUtil.ExternalStorage = Environment.getExternalStorageDirectory().getAbsolutePath(); } //劫持字段值 setSystemData(); //劫持指定的方法 addHookMethod(loadPackageParam.packageName, TelephonyManager.class.getName(), loadPackageParam.classLoader, "getDeviceId", new Object[]{}); addHookMethod(loadPackageParam.packageName, Settings.Secure.class.getName(), loadPackageParam.classLoader, "getString", new Object[]{ContentResolver.class.getName(), String.class.getName()}); addHookMethod(loadPackageParam.packageName, Settings.System.class.getName(), loadPackageParam.classLoader, "getString", new Object[]{ContentResolver.class.getName(), String.class.getName()}); addHookMethod(loadPackageParam.packageName, TelephonyManager.class.getName(), loadPackageParam.classLoader, "getLine1Number", new Object[]{}); addHookMethod(loadPackageParam.packageName, TelephonyManager.class.getName(), loadPackageParam.classLoader, "getSimSerialNumber", new Object[]{}); addHookMethod(loadPackageParam.packageName, TelephonyManager.class.getName(), loadPackageParam.classLoader, "getSubscriberId", new Object[]{}); addHookMethod(loadPackageParam.packageName, TelephonyManager.class.getName(), loadPackageParam.classLoader, "getSimOperator", new Object[]{}); addHookMethod(loadPackageParam.packageName, TelephonyManager.class.getName(), loadPackageParam.classLoader, "getNetworkOperatorName", new Object[]{}); addHookMethod(loadPackageParam.packageName, TelephonyManager.class.getName(), loadPackageParam.classLoader, "getNetworkType", new Object[]{}); addHookMethod(loadPackageParam.packageName, TelephonyManager.class.getName(), loadPackageParam.classLoader, "getPhoneType", new Object[]{}); addHookMethod(loadPackageParam.packageName, TelephonyManager.class.getName(), loadPackageParam.classLoader, "getSimState", new Object[]{}); addHookMethod(loadPackageParam.packageName, WifiInfo.class.getName(), loadPackageParam.classLoader, "getMacAddress", new Object[]{}); addHookMethod(loadPackageParam.packageName, WifiInfo.class.getName(), loadPackageParam.classLoader, "getSSID", new Object[]{}); addHookMethod(loadPackageParam.packageName, WifiInfo.class.getName(), loadPackageParam.classLoader, "getBSSID", new Object[]{}); addHookMethod(loadPackageParam.packageName, Build.class.getName(), loadPackageParam.classLoader, "getRadioVersion", new Object[]{}); addHookMethod(loadPackageParam.packageName, BluetoothAdapter.class.getName(), loadPackageParam.classLoader, "getAddress", new Object[]{}); addHookMethod(loadPackageParam.packageName, NetworkInfo.class.getName(), loadPackageParam.classLoader, "getTypeName", new Object[]{}); addHookMethod(loadPackageParam.packageName, NetworkInfo.class.getName(), loadPackageParam.classLoader, "getType", new Object[]{}); addHookMethod(loadPackageParam.packageName, NetworkInfo.class.getName(), loadPackageParam.classLoader, "getSubtype", new Object[]{}); addHookMethod(loadPackageParam.packageName, NetworkInfo.class.getName(), loadPackageParam.classLoader, "getSubtypeName", new Object[]{}); addHookMethod(loadPackageParam.packageName, NetworkInfo.class.getName(), loadPackageParam.classLoader, "getExtraInfo", new Object[]{}); addHookMethod(loadPackageParam.packageName, ConnectivityManager.class.getName(), loadPackageParam.classLoader, "getNetworkInfo", new Object[]{Integer.TYPE.getName()}); addHookMethod(loadPackageParam.packageName, ActivityManager.class.getName(), loadPackageParam.classLoader, "getRunningAppProcesses", new Object[]{}); addHookMethod(loadPackageParam.packageName, "android.app.ApplicationPackageManager", loadPackageParam.classLoader, "getInstalledPackages", new Object[]{Integer.TYPE.getName()}); addHookMethod(loadPackageParam.packageName, "android.app.ApplicationPackageManager", loadPackageParam.classLoader, "getPackageInfo", new Object[]{String.class.getName(), Integer.TYPE.getName()}); addHookMethod(loadPackageParam.packageName, "android.app.ApplicationPackageManager", loadPackageParam.classLoader, "getApplicationInfo", new Object[]{String.class.getName(), Integer.TYPE.getName()}); addHookMethod(loadPackageParam.packageName, "android.app.ApplicationPackageManager", loadPackageParam.classLoader, "getInstalledApplications", new Object[]{Integer.TYPE.getName()}); addHookMethod(loadPackageParam.packageName, "android.os.SystemProperties", loadPackageParam.classLoader, "get", new Object[]{String.class.getName()}); addHookMethod(loadPackageParam.packageName, "android.content.ContextWrapper", loadPackageParam.classLoader, "getExternalCacheDir", new Object[]{}); //劫持构造方法 addHookConstructor(loadPackageParam.packageName, File.class.getName(), loadPackageParam.classLoader, new Object[]{String.class.getName()}); addHookConstructor(loadPackageParam.packageName, File.class.getName(), loadPackageParam.classLoader, new Object[]{String.class.getName(), String.class.getName()}); addHookConstructor(loadPackageParam.packageName, FileReader.class.getName(), loadPackageParam.classLoader, new Object[]{String.class.getName()}); addHookConstructor(loadPackageParam.packageName, FileReader.class.getName(), loadPackageParam.classLoader, new Object[]{File.class.getName()}); } //修改字段值,上面的XposeUtil.initConfigMap();方法已经将本地数据保存到map中,我这里用jsonobject保存要修改的数据 private void setSystemData() { if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_RELEASE))){ XposedHelpers.setStaticObjectField(Build.VERSION.class,"RELEASE",XposeUtil.configMap.optString(XposeUtil.m_RELEASE)); } if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_SDK))){ XposedHelpers.setStaticObjectField(Build.VERSION.class, "SDK", XposeUtil.configMap.optString(XposeUtil.m_SDK)); } if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_framework))){ String[] split = XposeUtil.configMap.optString(XposeUtil.m_framework).split("_"); if(split.length == 2){ XposedHelpers.setStaticObjectField(Build.class,"CPU_ABI",split[0]); XposedHelpers.setStaticObjectField(Build.class,"CPU_ABI2",split[1]); } } if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_brand))){ XposedHelpers.setStaticObjectField(Build.class, "BRAND", XposeUtil.configMap.optString(XposeUtil.m_brand)); } if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_model))){ XposedHelpers.setStaticObjectField(Build.class, "MODEL", XposeUtil.configMap.optString(XposeUtil.m_model)); } if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_product))){ XposedHelpers.setStaticObjectField(Build.class, "PRODUCT", XposeUtil.configMap.optString(XposeUtil.m_product)); } if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_manufacture))){ XposedHelpers.setStaticObjectField(Build.class, "MANUFACTURER", XposeUtil.configMap.optString(XposeUtil.m_manufacture)); } if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_hardware))){ XposedHelpers.setStaticObjectField(Build.class, "HARDWARE", XposeUtil.configMap.optString(XposeUtil.m_hardware)); } if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_fingerprint))){ XposedHelpers.setStaticObjectField(Build.class, "FINGERPRINT", XposeUtil.configMap.optString(XposeUtil.m_fingerprint)); } if(!TextUtils.isEmpty(XposeUtil.configMap.optString(XposeUtil.m_serial))){ XposedHelpers.setStaticObjectField(Build.class, "SERIAL", XposeUtil.configMap.optString(XposeUtil.m_serial)); } } //劫持指定方法 public void addHookMethod(final String packageName, final String className, ClassLoader classLoader, final String methodName, Object[] parameterTypesAndCallback){ XC_MethodHook xc_methodHook = new XC_MethodHook() { //方法调用前劫持,将参数替换成指定参数,实现屏蔽指定的包名 @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { if("getPackageInfo".equals(methodName) ){ if(param.args[0].equals(XposeUtil.pkg1) || param.args[0].equals(XposeUtil.pkg2) || param.args[0].equals(XposeUtil.pkg3)){ param.args[0] = "yyyy.mmmm.aaaa.xxxx"; } }else if("getApplicationInfo".equals(methodName) ){ if(param.args[0].equals(XposeUtil.pkg1) || param.args[0].equals(XposeUtil.pkg2) || param.args[0].equals(XposeUtil.pkg3)){ param.args[0] = "yyyy.mmmm.aaaa.xxxx"; } } } @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { // L.log("android.os.SystemProperties获取序列号"); if("get".equals(methodName) && className.equals("android.os.SystemProperties")){ if(param.args[0].equals("ro.serialno")){ String serial = XposeUtil.configMap.optString(XposeUtil.m_serial); if(!TextUtils.isEmpty(serial)){ param.setResult(serial); } } }else //屏蔽自己的包名 if("getInstalledApplications".equals(methodName) ){ List<ApplicationInfo> installedApplications = (List<ApplicationInfo>) param.getResult(); for (int i = installedApplications.size() - 1; i >= 0 ; i--) { ApplicationInfo applicationInfo = installedApplications.get(i); if(applicationInfo.equals(XposeUtil.pkg1) || applicationInfo.equals(XposeUtil.pkg2) || applicationInfo.equals(XposeUtil.pkg3)){ installedApplications.remove(i); } } param.setResult(installedApplications); }else ////屏蔽自己 if("getRunningAppProcesses".equals(methodName) ){ List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = (List<ActivityManager.RunningAppProcessInfo>) param.getResult(); for (int i = runningAppProcesses.size() - 1; i >= 0; i--) { ActivityManager.RunningAppProcessInfo runningAppProcessInfo = runningAppProcesses.get(i); if(runningAppProcessInfo.processName.equals(XposeUtil.pkg1) || runningAppProcessInfo.processName.equals(XposeUtil.pkg2) || runningAppProcessInfo.processName.equals(XposeUtil.pkg3)){ runningAppProcesses.remove(i); } } param.setResult(runningAppProcesses); }else //屏蔽自己 if("getInstalledPackages".equals(methodName) ){ List<PackageInfo> installedPackages = (List<PackageInfo>) param.getResult(); for (int i = installedPackages.size() - 1; i >= 0; i--) { String s = installedPackages.get(i).packageName; if(s.equals(XposeUtil.pkg1) || s.equals(XposeUtil.pkg2) || s.equals(XposeUtil.pkg3)){ L.debug("getInstalledPackages+移除"+s); installedPackages.remove(i); } } param.setResult(installedPackages); }else //蓝牙地址 if("getAddress".equals(methodName)){ String m_bluetoothaddress = XposeUtil.configMap.optString(XposeUtil.m_bluetoothaddress); if(!TextUtils.isEmpty(m_bluetoothaddress)){ param.setResult(m_bluetoothaddress); }else{ } }else //固件版本 if("getRadioVersion".equals(methodName)){ String m_firmwareversion = XposeUtil.configMap.optString(XposeUtil.m_firmwareversion); if(!TextUtils.isEmpty(m_firmwareversion)){ L.debug("修改m_firmwareversion"); param.setResult(m_firmwareversion); }else{ L.debug("获取m_firmwareversion为空"); } }else //无线路由地址 if("getBSSID".equals(methodName)){ String m_BSSID = XposeUtil.configMap.optString(XposeUtil.m_BSSID); if(!TextUtils.isEmpty(m_BSSID)){ L.debug("修改m_BSSID"); param.setResult(m_BSSID); }else{ L.debug("获取m_BSSID为空"); } }else //无线路由名 if("getSSID".equals(methodName)){ String m_SSID = XposeUtil.configMap.optString(XposeUtil.m_SSID); if(!TextUtils.isEmpty(m_SSID)){ L.debug("修改m_SSID"); param.setResult(m_SSID); }else{ L.debug("获取m_SSID为空"); } }else //mac地址 if("getMacAddress".equals(methodName)){ String m_macAddress = XposeUtil.configMap.optString(XposeUtil.m_macAddress); if(!TextUtils.isEmpty(m_macAddress)){ L.debug("修改m_macAddress"); param.setResult(m_macAddress); }else{ L.debug("获取m_macAddress为空"); } }else //手机卡状态 if("getSimState".equals(methodName)){ int m_simState = XposeUtil.configMap.optInt(XposeUtil.m_simState, -1); if(m_simState != -1) param.setResult(5); }else //手机类型 if("getPhoneType".equals(methodName)){ int m_phoneType = XposeUtil.configMap.optInt(XposeUtil.m_phoneType,-1); if(m_phoneType != -1) param.setResult(m_phoneType); }else //网络类型 if("getNetworkType".equals(methodName)){ int m_networkType = XposeUtil.configMap.optInt(XposeUtil.m_networkType, -1); if(m_networkType != -1) param.setResult(m_networkType); }else //网络类型名 if("getNetworkOperatorName".equals(methodName)){ String networkOperatorName = XposeUtil.configMap.optString(XposeUtil.m_networkOperatorName); if(!TextUtils.isEmpty(networkOperatorName)){ L.debug("修改networkOperatorName"); param.setResult(networkOperatorName); }else{ L.debug("获取networkOperatorName为空"); } }else //运营商 if("getSimOperator".equals(methodName)){ String simOperator = XposeUtil.configMap.optString(XposeUtil.m_simOperator); if(!TextUtils.isEmpty(simOperator)){ L.debug("修改simOperatord"); param.setResult(simOperator); }else{ L.debug("获取simOperator为空"); } }else //IMSI if("getSubscriberId".equals(methodName)){ String subscriberId = XposeUtil.configMap.optString(XposeUtil.m_subscriberId); if(!TextUtils.isEmpty(subscriberId)){ L.debug("修改subscriberId"); param.setResult(subscriberId); }else{ L.debug("获取subscriberId为空"); } }else //手机卡序列号 if("getSimSerialNumber".equals(methodName)){ String simSerialNumber = XposeUtil.configMap.optString(XposeUtil.m_simSerialNumber); if(!TextUtils.isEmpty(simSerialNumber)){ L.debug("修改simSerialNumber"); param.setResult(simSerialNumber); }else{ L.debug("获取simSerialNumber为空"); } }else //电话号码 if("getLine1Number".equals(methodName)){ String phoneNum = XposeUtil.configMap.optString(XposeUtil.m_phoneNum); if(!TextUtils.isEmpty(phoneNum)){ L.debug("修改phoneNum"); param.setResult(phoneNum); }else{ L.debug("获取phoneNum为空"); } }else //android_id if("getString".equals(methodName) && param.args[1].equals("android_id")){ String androidId = XposeUtil.configMap.optString(XposeUtil.m_androidId); if(!TextUtils.isEmpty(androidId)){ L.debug("修改androidId"); param.setResult(androidId); }else{ L.debug("获取androidId为空"); } }else //device_id if("getDeviceId".equals(methodName)){ L.debug("packageName" + packageName + "configMap" + XposeUtil.configMap.toString()); XposeUtil.initConfigMap(); String deviceid = XposeUtil.configMap.optString(XposeUtil.m_deviceId); if(!TextUtils.isEmpty(deviceid)){ L.debug("修改deviceid"); param.setResult(deviceid); }else{ L.debug("获取deviceid为空"); } }else if("testXpose".equals(methodName)){ param.setResult(1); } } }; //执行hook方法findAndHookMethod的param值为参数+回调的可变参数,故要将回调加入进去 Object [] param = new Object[parameterTypesAndCallback.length + 1]; for (int i = 0; i < param.length; i++) { if(i == param.length-1){ param[param.length - 1] = xc_methodHook; XposedHelpers.findAndHookMethod(className, classLoader, methodName, param); return ; } param[i] = parameterTypesAndCallback[i]; } } //劫持构造方法 public void addHookConstructor(final String packageName,String className,ClassLoader classLoader,Object[] parameterTypesAndCallback){ XC_MethodHook xc_methodHook = new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); //监听File实例构建,实现监听文件的操作 if (XposeUtil.configMap.optBoolean(XposeUtil.FileRecordPackageNameSwitch) && XposeUtil.configMap.optString(XposeUtil.FileRecordPackageName).contains(packageName)) { String attr = ""; if(param.args[0]instanceof File){ attr = ((File) param.args[0]).getAbsolutePath(); }else if(param.args.length > 1 && param.args[1] != null ){ String separator = ""; if(!param.args[0].toString().endsWith("/")) separator = "/"; attr = param.args[0].toString() + separator + param.args[1].toString(); }else{ attr = (String) param.args[0]; } if (attr.contains(RecordFileUtil.ExternalStorage) && !attr.contains("xpose") && !(attr.startsWith(RecordFileUtil.ExternalStorage+RecordFileUtil.FILE_PATH_RECORD)) && RecordFileUtil.addFileRecord(packageName, attr)) ; } } }; //执行hook方法findAndHookConstructor的param值为参数+回调的可变参数,故要将回调加入进去 Object [] param = new Object[parameterTypesAndCallback.length + 1]; for (int i = 0; i < param.length; i++) { if(i == param.length-1){ param[param.length - 1] = xc_methodHook; XposedHelpers.findAndHookConstructor(className,classLoader,param); return ; } param[i] = parameterTypesAndCallback[i]; } } }
只要将要修改的数据保存到static JsonObject中,每次只要程序执行到你hook的方法,就能执行你上面写的回调啦,注意每个app的static JsonObject不是共用的,你会发现每次启动一个app都会调用handleLoadPackage方法。
当你将imei 从123改为321的时候,将他保存到本地文件,但是static JsonObject没有更新,我这里是在handleLoadPackage更新,或者在hook方法里面更新数据,比如
if("getDeviceId".equals(methodName)){ //每次执行这个方法就更新数据 XposeUtil.initConfigMap(); String deviceid = XposeUtil.configMap.optString(XposeUtil.m_deviceId); if(!TextUtils.isEmpty(deviceid)){ L.debug("修改deviceid"); param.setResult(deviceid); }else{ L.debug("获取deviceid为空"); } }
initConfigMap也就是将数据读取到 static JSONObject 而已
public class XposeUtil { public static String FILE_PATH_XPOSR = "/.xpose/"; public static String FileRecordPackageName = "FileRecordPackageName"; public static String FileRecordPackageNameSwitch = "FileRecordPackageNameSwitch"; public static String m_deviceId = "deviceId";//设备id public static String m_androidId = "androidId";//android_id public static String m_phoneNum = "phoneNum";//电话号码 public static String m_simSerialNumber = "simSerialNumber";//手机卡序列号 public static String m_subscriberId = "subscriberId";//IMSI public static String m_simOperator = "simOperator";//运营商 public static String m_networkOperatorName = "networkOperatorName";//网络类型名 public static String m_networkType = "networkType";//网络类型 public static String m_phoneType = "phoneType";//手机类型 public static String m_simState = "simState";//手机卡状态 public static String m_macAddress = "macAddress";//mac地址 public static String m_SSID = "SSID";//无线路由名 public static String m_BSSID = "BSSID";//无线路由地址 public static String m_firmwareversion = "firmwareversion";//固件版本 public static String m_bluetoothaddress = "bluetoothaddress";//蓝牙地址 public static String m_screenSize = "screenSize";//蓝牙地址 public static String m_RELEASE = "RELEASE";//系统版本 public static String m_SDK = "SDK";//系统版本值 public static String m_framework = "framework";//系统架构 public static String m_brand = "brand";//手机品牌 public static String m_model = "model";//手机型号 public static String m_product = "product";//产品名 public static String m_manufacture = "manufacture";//制造商 public static String m_hardware = "hardware";//硬件 public static String m_fingerprint = "fingerprint";//指纹 public static String m_serial = "serial";//序列号 public static String pkg1 = "de.robv.android.xpose.installer"; public static String pkg2 = "pro.burgerz.wsm.manager"; public static JSONObject configMap = new JSONObject(); /** * 将map信息写入供xpose调用 */ public static void saveConfigMap(){ new Thread(){ @Override public void run() { saveFileData("xposeDevice.txt",configMap.toString()); } }.start(); } /** * 读取文本数据到configMap */ public static void initConfigMap(){ try { configMap = new JSONObject(getFileData("xposeDevice.txt")); } catch (JSONException e) { e.printStackTrace(); } } private static void saveFileData(String fileName,String value){ File localFile = new File(Environment.getExternalStorageDirectory()+FILE_PATH_XPOSR); if(!localFile.exists()){ localFile.mkdir(); } localFile = new File(localFile,fileName); if(!localFile.exists()){ try { localFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } L.debug("写入文本"+value); FileOutputStream fos = null; try { fos = new FileOutputStream(localFile); fos.write(value.getBytes("UTF-8")); fos.flush(); } catch (Exception e) { e.printStackTrace(); }finally { if (fos != null) try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } private static String getFileData(String fileName){ File localFile = new File(Environment.getExternalStorageDirectory()+FILE_PATH_XPOSR,fileName); if(!localFile.exists()){ try { localFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } BufferedReader reader = null; String result = ""; try { reader = new BufferedReader(new FileReader(localFile)); result = reader.readLine(); if(result == null) return ""; } catch (Exception e) { e.printStackTrace(); }finally { if(reader != null) try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } return result; } }
上面的功能就能实现某些该数据神器的功能,只要摸清大致的思路,想要修改什么数据都能依瓢画葫芦出来,数据来源什么的大家就自己想办法了,希望能起到帮助!!!
相关文章推荐
- 【Android】实现XML解析的几种技术
- 原子操作
- C语言学习之关键字第五讲
- PullTorefreshListView初级用法
- java实现深复制:clone()及序列化
- 谈对业务系统的切入----如何让项目成员尽快熟悉系统业务?
- Struts官网
- 获取已安装设备的高级信息
- 蓝桥杯 身份证号码升级(模拟)
- 某电商网站数据库宕机故障解决实录(下)
- 直方图均衡化
- SSO单点登录学习总结(3)—— 基于CAS实现单点登录实例
- SSO单点登录学习总结(3)—— 基于CAS实现单点登录实例
- Spring 使用注解方式进行事务管理 /==/ Spring分布式事务实现
- git diff查看本地已经commit的内容
- SSO单点登录学习总结(3)—— 基于CAS实现单点登录实例
- (IOS自学)C语言基础学习(一)
- MySQL + Atlas --- 部署读写分离
- DButils数据库查询
- world break