手机虚拟定位 可以在家里钉钉打卡 现在很多的应用都是基于位置服务的,而且把位置服务作为重要的参考标准,其实这是很不安全的,位置信息的数据未经过任何加密,而且是从我们的手机中发送出去的,所以是可以修改的。这一期我们来探讨一下如何修改手机中的定位信息。太基础的原理我就不多说了,可以参考前几期文章。
先整理一下思路,Android在开发者模式下有一个"允许模拟位置选项",它是location service加载 MOCK location provider 实现的,通过这种线程注入的方式修改GPS信息是hacker们最喜欢的方式,但现在很多应用已经可以检测到这种注入方式而被屏蔽掉,也就是说如果我们只在APP层面上想解决方法总是有被检测出来的可能。那我们就得把问题往深了想,通过修改最底层的GPS数据来欺骗APP,在Framework层面上没有任何修改迹象,这样基于APP层面的检测机制就拿我们没有任何办法。
思路确定后我们来探讨实践路线,首先我们要建立一个管道,让我们想要定位的GPS数据提交到Android操作系统的最底层,也就是Linux Kernel层面;然后我们要修改 GPS的 location report 机制,让它从内核中提取到我们的数据,然后逐层上报到APP层。有点明修栈道暗度陈仓的感觉。
总体来说分成两部实现:1.建立到系统内核的数据管道;2.修改GPS上报机制。
这次实验使用的是闲置的神乐三代手机,编译源码采用CyanogenMod-13
因为Android系统从内核态到APP层要经过很多的层次,所以对于建立数据管道的步骤比较繁琐,我这里分成了5个步骤,对应5个层面来实现,每一步分别对应Android的 Kernel driver,HAL,JNI,Framework,Application。
下面描述一下实践步骤:
=============分割线1==============
第一步,修改Kernel driver
进入 kernel/xiaomi/cancro/drivers 目录下,新建vp.h文件
-
#ifndef _VP_ANDROID_H_
-
#define _VP_ANDROID_H_
-
#include <linux/cdev.h>
-
#include <linux/semaphore.h>
-
#define VP_DEVICE_NODE_NAME "vp"
-
#define VP_DEVICE_FILE_NAME "vp"
-
#define VP_DEVICE_PROC_NAME "vp"
-
#define VP_DEVICE_CLASS_NAME "vp"
-
typedef struct {
-
int toggle;
-
double virtual_latitude;
-
double virtual_longitude;
-
} VirtualPosition;
-
struct vp_android_dev {
-
int lamp;
-
VirtualPosition val;
-
struct semaphore sem;
-
struct cdev dev;
-
};
-
#endif
新建vp.c文件
-
/*******************************************
-
*include file and define functions
-
*******************************************/
-
#include <linux/init.h>
-
#include <linux/module.h>
-
#include <linux/types.h>
-
#include <linux/fs.h>
-
#include <linux/proc_fs.h>
-
#include <linux/device.h>
-
#include <asm/uaccess.h>
-
#include "vp.h"
-
/*主设备和从设备号变量*/
-
static int vp_major = 0;
-
static int vp_minor = 0;
-
/*设备类别和设备变量*/
-
static struct class* vp_class = NULL;
-
static struct vp_android_dev* vp_dev = NULL;
-
/*传统的设备文件操作方法*/
-
static int vp_open(struct inode* inode, struct file* filp);
-
static int vp_release(struct inode* inode, struct file* filp);
-
static ssize_t vp_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos);
-
static ssize_t vp_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos);
-
/*设备文件操作方法表*/
-
static struct file_operations vp_fops = {
-
.owner = THIS_MODULE,
-
.open = vp_open,
-
.release = vp_release,
-
.read = vp_read,
-
.write = vp_write,
-
};
-
/*访问设置属性方法*/
-
static ssize_t vp_lamp_show(struct device* dev, struct device_attribute* attr, char* buf);
-
static ssize_t vp_lamp_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count);
-
/*定义设备属性*/
-
static DEVICE_ATTR(val, S_IRUGO | S_IWUSR, vp_lamp_show, vp_lamp_store);
-
/*******************************************
-
*define traditional file access
-
*******************************************/
-
/*打开设备方法*/
-
static int vp_open(struct inode* inode, struct file* filp) {
-
struct vp_android_dev* dev;
-
/*将自定义设备结构体保存在文件指针的私有数据域中,以便访问设备时拿来用*/
-
dev = container_of(inode->i_cdev, struct vp_android_dev, dev);
-
filp->private_data = dev;
-
return 0;
-
}
-
/*设备文件释放时调用,空实现*/
-
static int vp_release(struct inode* inode, struct file* filp) {
-
return 0;
-
}
-
/*读取设备的寄存器val的值*/
-
static ssize_t vp_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos) {
-
ssize_t err = 0;
-
struct vp_android_dev* dev = filp->private_data;
-
/*同步访问*/
-
if(down_interruptible(&(dev->sem))) {
-
return -ERESTARTSYS;
-
}
-
if(count < sizeof(dev->val)) {
-
goto out;
-
}
-
/*将寄存器val的值拷贝到用户提供的缓冲区*/
-
if(copy_to_user(buf, &(dev->val), sizeof(dev->val))) {
-
err = -EFAULT;
-
goto out;
-
}
-
err = sizeof(dev->val);
-
out:
-
up(&(dev->sem));
-
return err;
-
}
-
/*写设备的寄存器值val*/
-
static ssize_t vp_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos) {
-
struct vp_android_dev* dev = filp->private_data;
-
ssize_t err = 0;
-
/*同步访问*/
-
if(down_interruptible(&(dev->sem))) {
-
return -ERESTARTSYS;
-
}
-
if(count != sizeof(dev->val)) {
-
goto out;
-
}
-
/*将用户提供的缓冲区的值写到设备寄存器去*/
-
if(copy_from_user(&(dev->val), buf, count)) {
-
err = -EFAULT;
-
goto out;
-
}
-
err = sizeof(dev->val);
-
out:
-
up(&(dev->sem));
-
return err;
-
}
-
/*******************************************
-
*define devfs access
-
*******************************************/
-
/*读取寄存器lamp的值到缓冲区buf中,内部使用*/
-
static ssize_t __vp_get_lamp(struct vp_android_dev* dev, char* buf) {
-
int lamp = 0;
-
/*同步访问*/
-
if(down_interruptible(&(dev->sem))) {
-
return -ERESTARTSYS;
-
}
-
lamp = dev->lamp;
-
up(&(dev->sem));
-
return snprintf(buf, PAGE_SIZE, "%d\n", lamp);
-
}
-
/*把缓冲区buf的值写到设备寄存器lamp中去,内部使用*/
-
static ssize_t __vp_set_lamp(struct vp_android_dev* dev, const char* buf, size_t count) {
-
int lamp = 0;
-
/*将字符串转换成数字*/
-
lamp = simple_strtol(buf, NULL, 10);
-
/*同步访问*/
-
if(down_interruptible(&(dev->sem))) {
-
return -ERESTARTSYS;
-
}
-
dev->lamp = lamp;
-
up(&(dev->sem));
-
return count;
-
}
-
/*读取设备属性lamp*/
-
static ssize_t vp_lamp_show(struct device* dev, struct device_attribute* attr, char* buf) {
-
struct vp_android_dev* hdev = (struct vp_android_dev*)dev_get_drvdata(dev);
-
return __vp_get_lamp(hdev, buf);
-
}
-
/*写设备属性lamp*/
-
static ssize_t vp_lamp_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count) {
-
struct vp_android_dev* hdev = (struct vp_android_dev*)dev_get_drvdata(dev);
-
return __vp_set_lamp(hdev, buf, count);
-
}
-
/*******************************************
-
*define proc access
-
*******************************************/
-
/*读取设备寄存器lamp的值,保存在page缓冲区中*/
-
static ssize_t vp_proc_read(char* page, char** start, off_t off, int count, int* eof, void* data) {
-
if(off > 0) {
-
*eof = 1;
-
return 0;
-
}
-
return __vp_get_lamp(vp_dev, page);
-
}
-
/*把缓冲区的值buff保存到设备寄存器lamp中去*/
-
static ssize_t vp_proc_write(struct file* filp, const char __user *buff, unsigned long len, void* data) {
-
int err = 0;
-
char* page = NULL;
-
if(len > PAGE_SIZE) {
-
printk(KERN_ALERT"The buff is too large: %lu.\n", len);
-
return -EFAULT;
-
}
-
page = (char*)__get_free_page(GFP_KERNEL);
-
if(!page) {
-
printk(KERN_ALERT"Failed to alloc page.\n");
-
return -ENOMEM;
-
}
-
/*先把用户提供的缓冲区值拷贝到内核缓冲区中去*/
-
if(copy_from_user(page, buff, len)) {
-
printk(KERN_ALERT"Failed to copy buff from user.\n");
-
err = -EFAULT;
-
goto out;
-
}
-
err = __vp_set_lamp(vp_dev, page, len);
-
out:
-
free_page((unsigned long)page);
-
return err;
-
}
-
/*创建/proc/vp文件*/
-
static void vp_create_proc(void) {
-
struct proc_dir_entry *entry;
-
entry = create_proc_entry(VP_DEVICE_PROC_NAME, 0, NULL);
-
if(entry)
-
{
-
entry->read_proc = vp_proc_read;
-
entry->write_proc = vp_proc_write;
-
}
-
}
-
/*删除/proc/vp文件*/
-
static void vp_remove_proc(void) {
-
remove_proc_entry(VP_DEVICE_PROC_NAME, NULL);
-
}
-
/*******************************************
-
*define load and remove function
-
*******************************************/
-
/*初始化设备*/
-
static int __vp_setup_dev(struct vp_android_dev* dev) {
-
int err;
-
dev_t devno = MKDEV(vp_major, vp_minor);
-
memset(dev, 0, sizeof(struct vp_android_dev));
-
cdev_init(&(dev->dev), &vp_fops);
-
dev->dev.owner = THIS_MODULE;
-
dev->dev.ops = &vp_fops;
-
/*注册字符设备*/
-
err = cdev_add(&(dev->dev),devno, 1);
-
if(err) {
-
return err;
-
}
-
/*初始化信号量和寄存器lamp, val的值*/
-
sema_init(&(dev->sem), 1);
-
dev->lamp = 7777;
-
dev->val.toggle = 1;
-
dev->val.virtual_latitude = 45.104108;
-
dev->val.virtual_longitude = 130.816878;
-
return 0;
-
}
-
/*模块加载方法*/
-
static int __init vp_init(void){
-
int err = -1;
-
dev_t dev = 0;
-
struct device* temp = NULL;
-
printk(KERN_ALERT"Initializing vp device.\n");
-
/*动态分配主设备和从设备号*/
-
err = alloc_chrdev_region(&dev, 0, 1, VP_DEVICE_NODE_NAME);
-
if(err < 0) {
-
printk(KERN_ALERT"Failed to alloc char dev region.\n");
-
goto fail;
-
}
-
vp_major = MAJOR(dev);
-
vp_minor = MINOR(dev);
-
/*分配helo设备结构体变量*/
-
vp_dev = kmalloc(sizeof(struct vp_android_dev), GFP_KERNEL);
-
if(!vp_dev) {
-
err = -ENOMEM;
-
printk(KERN_ALERT"Failed to alloc vp_dev.\n");
-
goto unregister;
-
}
-
/*初始化设备*/
-
err = __vp_setup_dev(vp_dev);
-
if(err) {
-
printk(KERN_ALERT"Failed to setup dev: %d.\n", err);
-
goto cleanup;
-
}
-
/*在/sys/class/目录下创建设备类别目录vp*/
-
vp_class = class_create(THIS_MODULE, VP_DEVICE_CLASS_NAME);
-
if(IS_ERR(vp_class)) {
-
err = PTR_ERR(vp_class);
-
printk(KERN_ALERT"Failed to create vp class.\n");
-
goto destroy_cdev;
-
}
-
/*在/dev/目录和/sys/class/vp目录下分别创建设备文件vp*/
-
temp = device_create(vp_class, NULL, dev, "%s", VP_DEVICE_FILE_NAME);
-
if(IS_ERR(temp)) {
-
err = PTR_ERR(temp);
-
printk(KERN_ALERT"Failed to create vp device.");
-
goto destroy_class;
-
}
-
/*在/sys/class/vp/vp目录下创建属性文件val*/
-
err = device_create_file(temp, &dev_attr_val);
-
if(err < 0) {
-
printk(KERN_ALERT"Failed to create attribute val.");
-
goto destroy_device;
-
}
-
dev_set_drvdata(temp, vp_dev);
-
/*创建/proc/vp文件*/
-
vp_create_proc();
-
printk(KERN_ALERT"Succedded to initialize vp device.\n");
-
return 0;
-
destroy_device:
-
device_destroy(vp_class, dev);
-
destroy_class:
-
class_destroy(vp_class);
-
destroy_cdev:
-
cdev_del(&(vp_dev->dev));
-
cleanup:
-
kfree(vp_dev);
-
unregister:
-
unregister_chrdev_region(MKDEV(vp_major, vp_minor), 1);
-
fail:
-
return err;
-
}
-
/*模块卸载方法*/
-
static void __exit vp_exit(void) {
-
dev_t devno = MKDEV(vp_major, vp_minor);
-
printk(KERN_ALERT"Destroy vp device.\n");
-
/*删除/proc/vp文件*/
-
vp_remove_proc();
-
/*销毁设备类别和设备*/
-
if(vp_class) {
-
device_destroy(vp_class, MKDEV(vp_major, vp_minor));
-
class_destroy(vp_class);
-
}
-
/*删除字符设备和释放设备内存*/
-
if(vp_dev) {
-
cdev_del(&(vp_dev->dev));
-
kfree(vp_dev);
-
}
-
/*释放设备号*/
-
unregister_chrdev_region(devno, 1);
-
}
-
MODULE_LICENSE("GPL");
-
MODULE_DESCRIPTION("Virtualposition Driver");
-
module_init(vp_init);
-
module_exit(vp_exit);
添加 Kconfig 文件
-
config VP
-
tristate "Virtual Position Driver"
-
default n
-
help
-
This is the virtual position driver.
添加 Makefile 文件
obj-$(CONFIG_VP) += vp.o
修改 drivers/Kconfig 文件 在menu "Device Drivers"和endmenu之间添加一行:
source "drivers/vp/Kconfig"
修改drivers/Makefile文件,添加一行:
obj-$(CONFIG_HELLO) += vp/
修改 arch/arm/configs目录下的cyanogen_cancro_defconfig 文件,在文件末尾加入
-
# CONFIG_VP
-
CONFIG_VP=y
=============分割线2==============
第二步,修改HAL
进入 ./hardware/libhardware/include/hardware 目录,新建 vp.h 文件
-
#ifndef ANDROID_VP_INTERFACE_H
-
#define ANDROID_VP_INTERFACE_H
-
#include <hardware/hardware.h>
-
__BEGIN_DECLS
-
/*定义模块ID*/
-
#define VP_HARDWARE_MODULE_ID "vp"
-
//typedef enum{false, true} bool;
-
/*define virtual position structrue*/
-
typedef struct {
-
int toggle;
-
double virtual_latitude;
-
double virtual_longitude;
-
} VirtualPosition;
-
/*硬件模块结构体*/
-
struct vp_module_t {
-
struct hw_module_t common;
-
};
-
/*硬件接口结构体*/
-
struct vp_device_t {
-
struct hw_device_t common;
-
int fd;
-
int (*set_val)(struct vp_device_t* dev, VirtualPosition val);
-
int (*get_val)(struct vp_device_t* dev, VirtualPosition* val);
-
};
-
__END_DECLS
-
#endif
进入到 hardware/libhardware/modules 目录,新建vp目录,并添加vp.c文件
-
#define LOG_TAG "VpStub"
-
#include <hardware/hardware.h>
-
#include <hardware/vp.h>
-
#include <fcntl.h>
-
#include <errno.h>
-
#include <cutils/log.h>
-
#include <cutils/atomic.h>
-
#define DEVICE_NAME "/dev/vp"
-
#define MODULE_NAME "Vp"
-
#define MODULE_AUTHOR "[email protected]"
-
/*设备打开和关闭接口*/
-
static int vp_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device);
-
static int vp_device_close(struct hw_device_t* device);
-
/*设备访问接口*/
-
static int vp_set_val(struct vp_device_t* dev, VirtualPosition val);
-
static int vp_get_val(struct vp_device_t* dev, VirtualPosition* val);
-
/*模块方法表*/
-
static struct hw_module_methods_t vp_module_methods = {
-
open: vp_device_open
-
};
-
/*模块实例变量*/
-
struct vp_module_t HAL_MODULE_INFO_SYM = {
-
common: {
-
tag: HARDWARE_MODULE_TAG,
-
version_major: 1,
-
version_minor: 0,
-
id: VP_HARDWARE_MODULE_ID,
-
name: MODULE_NAME,
-
author: MODULE_AUTHOR,
-
methods: &vp_module_methods,
-
}
-
};
-
static int vp_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device) {
-
struct vp_device_t* dev;dev = (struct vp_device_t*)malloc(sizeof(struct vp_device_t));
-
if(!dev) {
-
ALOGE("Vp Stub: failed to alloc space");
-
return -EFAULT;
-
}
-
memset(dev, 0, sizeof(struct vp_device_t));
-
dev->common.tag = HARDWARE_DEVICE_TAG;
-
dev->common.version = 0;
-
dev->common.module = (hw_module_t*)module;
-
dev->common.close = vp_device_close;
-
dev->set_val = vp_set_val;dev->get_val = vp_get_val;
-
if((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1) {
-
ALOGE("Vp Stub: failed to open /dev/vp -- %s.", strerror(errno));free(dev);
-
return -EFAULT;
-
}
-
*device = &(dev->common);
-
ALOGI("Vp Stub: open /dev/vp successfully.");
-
return 0;
-
}
-
static int vp_device_close(struct hw_device_t* device) {
-
struct vp_device_t* vp_device = (struct vp_device_t*)device;
-
if(vp_device) {
-
close(vp_device->fd);
-
free(vp_device);
-
}
-
return 0;
-
}
-
static int vp_set_val(struct vp_device_t* dev, VirtualPosition val) {
-
ALOGI("Vp Stub: set value %d to device.", val);
-
write(dev->fd, &val, sizeof(val));
-
return 0;
-
}
-
static int vp_get_val(struct vp_device_t* dev, VirtualPosition* val) {
-
if(!val) {
-
ALOGE("Vp Stub: error val pointer");
-
return -EFAULT;
-
}
-
read(dev->fd, val, sizeof(*val));
-
ALOGI("Vp Stub: get value %d from device", *val);
-
return 0;
-
}
继续在vp目录下新建Android.mk文件:
-
LOCAL_PATH := $(call my-dir)
-
include $(CLEAR_VARS)
-
LOCAL_MODULE_TAGS := optional
-
LOCAL_PRELINK_MODULE := false
-
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
-
LOCAL_SHARED_LIBRARIES := liblog
-
LOCAL_SRC_FILES := vp.c
-
LOCAL_MODULE := vp.default
-
include $(BUILD_SHARED_LIBRARY)
=============分割线3==============
第三步,修改JNI
进入 frameworks/base/services/core/jni 目录,新建com_android_server_VirtualPositionService.cpp文件
-
#define LOG_TAG "VirtualPositionService"
-
#include "jni.h"
-
#include "JNIHelp.h"
-
#include "android_runtime/AndroidRuntime.h"
-
#include <utils/misc.h>
-
#include <utils/Log.h>
-
#include <hardware/hardware.h>
-
#include <hardware/vp.h>
-
#include <stdio.h>
-
namespace android
-
{
-
VirtualPosition virtual_position = {1, 0.0, 0.0};
-
/*在硬件抽象层中定义的硬件访问结构体,参考<hardware/vp.h>*/
-
struct vp_device_t* vp_device = NULL;
-
/*通过硬件抽象层定义的硬件访问接口设置硬件寄存器val的值*/
-
static void vp_setVal() {
-
ALOGI("VirtualPosition JNI: set value to device.");
-
if(!vp_device) {
-
ALOGI("VirtualPosition JNI: device is not open.");
-
return;
-
}
-
vp_device->set_val(vp_device, virtual_position);
-
}
-
/*通过硬件抽象层定义的硬件访问接口读取硬件寄存器val的值*/
-
static void vp_getVal() {
-
if(!vp_device) {
-
ALOGI("VirtualPosition JNI: device is not open.");
-
}
-
vp_device->get_val(vp_device, &virtual_position);
-
ALOGI("VirtualPosition JNI: get value from device.");
-
}
-
/*通过硬件抽象层定义的硬件模块打开接口打开硬件设备*/
-
static inline int vp_device_open(const hw_module_t* module, struct vp_device_t** device) {
-
return module->methods->open(module, VP_HARDWARE_MODULE_ID, (struct hw_device_t**)device);
-
}
-
/*通过硬件模块ID来加载指定的硬件抽象层模块并打开硬件*/
-
static jboolean vp_init(JNIEnv* env, jclass clazz) {
-
vp_module_t* module;
-
ALOGI("VirtualPosition JNI: initializing......");
-
if(hw_get_module(VP_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0) {
-
ALOGI("VirtualPosition JNI: vp Stub found.");
-
if(vp_device_open(&(module->common), &vp_device) == 0) {
-
ALOGI("VirtualPosition JNI: vp device is open.");
-
return 0;
-
}
-
ALOGE("VirtualPosition JNI: failed to open vp device.");
-
return -1;
-
}
-
ALOGE("VirtualPosition JNI: failed to get vp stub module.");
-
return -1;
-
}
-
static void android_server_VirtualPositionService_set_virtual_toggle(JNIEnv* env, jclass clazz, jint tog)
-
{
-
virtual_position.toggle = tog;
-
vp_setVal();
-
}
-
static jint android_server_VirtualPositionService_get_virtual_toggle(JNIEnv* env, jclass clazz)
-
{
-
vp_getVal();
-
return virtual_position.toggle;
-
}
-
static void android_server_VirtualPositionService_set_virtual_latitude(JNIEnv* env, jclass clazz, jdouble vlat)
-
{
-
virtual_position.virtual_latitude = vlat;
-
vp_setVal();
-
}
-
static jdouble android_server_VirtualPositionService_get_virtual_latitude(JNIEnv* env, jclass clazz)
-
{
-
vp_getVal();
-
return virtual_position.virtual_latitude;
-
}
-
static void android_server_VirtualPositionService_set_virtual_longitude(JNIEnv* env, jclass clazz, jdouble vlon)
-
{
-
virtual_position.virtual_longitude = vlon;
-
vp_setVal();
-
}
-
static jdouble android_server_VirtualPositionService_get_virtual_longitude(JNIEnv* env, jclass clazz)
-
{
-
vp_getVal();
-
return virtual_position.virtual_longitude;
-
}
-
/*JNI方法表*/
-
static const JNINativeMethod method_table[] = {
-
{"init_native",
-
"()Z",
-
(void*)vp_init},
-
{"native_set_virtual_toggle",
-
"(I)V",
-
(void*)android_server_VirtualPositionService_set_virtual_toggle},
-
{"native_get_virtual_toggle",
-
"()I",
-
(void*)android_server_VirtualPositionService_get_virtual_toggle},
-
{"native_set_virtual_latitude",
-
"(D)V",
-
(void*)android_server_VirtualPositionService_set_virtual_latitude},
-
{"native_get_virtual_latitude",
-
"()D",
-
(void*)android_server_VirtualPositionService_get_virtual_latitude},
-
{"native_set_virtual_longitude",
-
"(D)V",
-
(void*)android_server_VirtualPositionService_set_virtual_longitude},
-
{"native_get_virtual_longitude",
-
"()D",
-
(void*)android_server_VirtualPositionService_get_virtual_longitude},
-
};
-
/*注册JNI方法*/
-
int register_android_server_VirtualPositionService(JNIEnv *env) {
-
return jniRegisterNativeMethods(env, "com/android/server/VirtualPositionService", method_table, NELEM(method_table));
-
}
-
};
修改同目录下的onload.cpp文件,首先在namespace android增加com_android_server_VirtualPositionService函数声明:
-
namespace android {
-
..............................................................................................
-
int register_android_server_VirtualPositionService(JNIEnv *env);
-
};
-
在JNI_onLoad增加register_android_server_VirtualPositionService函数调用:
-
extern "C" jint JNI_onLoad(JavaVM* vm, void* reserved)
-
{
-
.................................................................................................
-
register_android_server_VirtualPositionService(env);
-
.................................................................................................
-
}
修改同目录下的Android.mk文件,在LOCAL_SRC_FILES变量中增加一行:
-
LOCAL_SRC_FILES:= \
-
com_android_server_AlarmManagerService.cpp \
-
com_android_server_BatteryService.cpp \
-
com_android_server_InputManager.cpp \
-
com_android_server_LightsService.cpp \
-
com_android_server_PowerManagerService.cpp \
-
com_android_server_SystemServer.cpp \
-
com_android_server_UsbService.cpp \
-
com_android_server_VibratorService.cpp \
-
com_android_server_location_GpsLocationProvider.cpp \
-
com_android_server_VirtualPositionService.cpp \
-
onload.cpp
=============分割线4==============
第四步,修改Framework
进入到frameworks/base/core/java/android/os目录,新增VirtualPositionService.aidl接口定义文件
-
package android.os;
-
interface IVirtualPositionService {
-
void setVirtualToggle(int tog);
-
int getVirtualToggle();
-
void setVirtualLatitude(double vlat);
-
double getVirtualLatitude();
-
void setVirtualLongitude(double vlon);
-
double getVirtualLongitude();
-
}
然后进入 frameworks/base目录,打开Android.mk文件,修改LOCAL_SRC_FILES变量的值,增加IVirtualPosition.aidl源文件:
-
LOCAL_SRC_FILES += /
-
....................................................................
-
core/java/android/os/IVibratorService.aidl /
-
core/java/android/os/IVirtualPosition.aidl /
-
core/java/android/service/urlrenderer/IUrlRendererService.aidl /
-
.....................................................................
进入到frameworks/base/services/java/com/android/server目录,新增VirtualPositionService.java文件
-
package com.android.server;
-
import android.content.Context;
-
import android.os.IVirtualPositionService;
-
import android.util.Slog;
-
public class VirtualPositionService extends IVirtualPositionService.Stub {
-
private static final String TAG = "VirtualPositionService";
-
VirtualPositionService() {
-
init_native();
-
}
-
public void setVirtualToggle(int tog) {
-
native_set_virtual_toggle(tog);
-
}
-
public int getVirtualToggle(){
-
return native_get_virtual_toggle();
-
}
-
public void setVirtualLatitude(double vlat) {
-
native_set_virtual_latitude(vlat);
-
}
-
public double getVirtualLatitude(){
-
return native_get_virtual_latitude();
-
}
-
public void setVirtualLongitude(double vlon) {
-
native_set_virtual_longitude(vlon);
-
}
-
public double getVirtualLongitude() {
-
return native_get_virtual_longitude();
-
}
-
private static native boolean init_native();
-
private static native void native_set_virtual_toggle(int tog);
-
private static native int native_get_virtual_toggle();
-
private static native void native_set_virtual_latitude(double vlat);
-
private static native double native_get_virtual_latitude();
-
private static native void native_set_virtual_longitude(double vlon);
-
private static native double native_get_virtual_longitude();
-
};
修改同目录的SystemServer.java文件,在ServerThread::run函数中增加加载VirtualPositionService的代码:
-
@Override
-
public void run() {
-
....................................................................................
-
try {
-
Slog.i(TAG, "DiskStats Service");
-
ServiceManager.addService("diskstats", new DiskStatsService(context));
-
} catch (Throwable e) {
-
Slog.e(TAG, "Failure starting DiskStats Service", e);
-
}
-
try {
-
Slog.i(TAG, "VirtualPosition Service");
-
ServiceManager.addService("virtualposition", new VirtualPositionService());
-
} catch (Throwable e) {
-
Slog.e(TAG, "Failure starting VirtualPosition Service", e);
-
}
-
......................................................................................
-
}
然后需要修改sepolicy文件,具体的文件在github上,请下载使用。
=============分割线5==============
第五步,修改application
-
package com.example.phdemo.myapplication;
-
import android.os.RemoteException;
-
import android.app.Activity;
-
import android.os.ServiceManager;
-
import android.os.Bundle;
-
import android.widget.CompoundButton;
-
import android.os.IVirtualPositionService;
-
import android.os.RemoteException;
-
import android.util.Log;
-
import android.view.View;
-
import android.view.View.OnClickListener;
-
import android.widget.Button;
-
import android.widget.EditText;
-
import android.widget.ToggleButton;
-
import android.widget.CompoundButton.OnCheckedChangeListener;
-
public class MainActivity extends Activity implements View.OnClickListener {
-
private final static String LOG_TAG = "com.example.phdemo.virtualposition";
-
private IVirtualPositionService virtualpositionService = null;
-
private ToggleButton toggleButton = null;
-
private EditText altitudeValueText = null;
-
private EditText longitudeValueText = null;
-
private Button getButton = null;
-
private Button setButton = null;
-
private Button clearButton = null;
-
/** Called when the activity is first created. */
-
@Override
-
public void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
setContentView(R.layout.activity_main);
-
virtualpositionService = IVirtualPositionService.Stub.asInterface(
-
ServiceManager.getService("virtualposition"));
-
toggleButton=(ToggleButton)findViewById(R.id.toggleButton);
-
altitudeValueText = (EditText)findViewById(R.id.altitude_value);
-
longitudeValueText = (EditText)findViewById(R.id.longitude_value);
-
getButton = (Button)findViewById(R.id.button_get);
-
setButton = (Button)findViewById(R.id.button_set);
-
clearButton = (Button)findViewById(R.id.button_clear);
-
getButton.setOnClickListener(this);
-
setButton.setOnClickListener(this);
-
clearButton.setOnClickListener(this);
-
try{
-
int val_tog = virtualpositionService.getVirtualToggle();
-
if(val_tog == 1){
-
toggleButton.setChecked(true);
-
}else{
-
toggleButton.setChecked(false);
-
}
-
} catch (Exception e) {}
-
toggleButton.setOnCheckedChangeListener(new OnCheckedChangeListener(){
-
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
-
toggleButton.setChecked(isChecked);
-
try{
-
virtualpositionService.setVirtualToggle(isChecked?1:0);
-
}catch(Exception e){}
-
}
-
});
-
Log.i(LOG_TAG, "VirtualPosition Activity Created");
-
}
-
@Override
-
public void onClick(View v) {
-
if(v.equals(getButton)) {
-
try {
-
double val_altitude = virtualpositionService.getVirtualLatitude();
-
String text_altitude = String.valueOf(val_altitude);
-
altitudeValueText.setText(text_altitude);
-
double val_longitude = virtualpositionService.getVirtualLongitude();
-
String text_longitude = String.valueOf(val_longitude);
-
longitudeValueText.setText(text_longitude);
-
int val_tog = virtualpositionService.getVirtualToggle();
-
if(val_tog == 1){
-
toggleButton.setChecked(true);
-
}else{
-
toggleButton.setChecked(false);
-
}
-
} catch (Exception e) {
-
Log.e(LOG_TAG, "Remote Exception while reading value from GpsLocationProvider.");
-
}
-
}
-
else if(v.equals(setButton)) {
-
try {
-
String text_altitude = altitudeValueText.getText().toString();
-
String text_longitude = longitudeValueText.getText().toString();
-
double val_altitude = Double.parseDouble(text_altitude);
-
double val_longitude = Double.parseDouble(text_longitude);
-
virtualpositionService.setVirtualLatitude(val_altitude);
-
virtualpositionService.setVirtualLongitude(val_longitude);
-
} catch (Exception e) {
-
Log.e(LOG_TAG, "Remote Exception while writing value to GpsLocationProvider.");
-
}
-
}
-
else if(v.equals(clearButton)) {
-
String text = "";
-
altitudeValueText.setText(text);
-
longitudeValueText.setText(text);
-
}
-
}
-
}
=============分割线6==============
最后一步,在JNI层面修改location report 机制。
进入 frameworks/base/services/core/jni 目录,修改com_android_server_location_GpsLocationProvider.cpp文件:
在全局变量部分加入
-
// add by aggresss
-
static int vp_fd = open("/dev/vp", O_RDWR);
-
static VirtualPosition vp_val;
修改location_callback函数:
-
static void location_callback(GpsLocation* location)
-
{
-
JNIEnv* env = AndroidRuntime::getJNIEnv();
-
//add by aggresss
-
read(vp_fd, &vp_val, sizeof(VirtualPosition));
-
if(vp_val.toggle == 1){
-
env->CallVoidMethod(mCallbacksObj, method_reportLocation, location->flags,
-
(jdouble)vp_val.virtual_latitude, (jdouble)vp_val.virtual_longitude,
-
(jdouble)location->altitude,
-
(jfloat)location->speed, (jfloat)location->bearing,
-
(jfloat)location->accuracy, (jlong)location->timestamp);
-
checkAndClearExceptionFromCallback(env, __FUNCTION__);
-
}
-
else{
-
env->CallVoidMethod(mCallbacksObj, method_reportLocation, location->flags,
-
(jdouble)location->latitude, (jdouble)location->longitude,
-
(jdouble)location->altitude,
-
(jfloat)location->speed, (jfloat)location->bearing,
-
(jfloat)location->accuracy, (jlong)location->timestamp);
-
checkAndClearExceptionFromCallback(env, __FUNCTION__);
-
}
-
}
=============我是完成的分割线==============
完成后,重新编译固件,开机后启动VirtualPosition的APP,设置你想要的坐标,想在哪就在哪了。
原文地址:https://www.cnblogs.com/shenlekeji/p/9381611.html