动态改android 参数,动态修改Android参数信息的方法绕过改机检测

有很多朋友咨询过我如果修改android的系统参数 比如 ro.build.id ro.product.name ro.product.device ro.product.model等参数。对应在APP端的Java代码就是Build.ID Build.PRODUCT Build.MODEL等参数。

不同于XpoSED&nBSP; VirtualApp 双开助手

DualSpace

Go双开

双开精灵 这些软件是通过hook方式,让app 运行在一个虚拟的环境中。世面上有很多成熟的技术可以检测到app 是真实运行在Android中还是虚拟空间中。如果彻底的修改只能通过修改Android源码的方式。一劳永逸的解决

Android 的参数信息主要保存在build.prop中,

```

# begin build properties

# autogenerated by buildinfo.sh

ro.build.id=KOT49H

ro.build.display.id=V1.01

ro.build.version.incremental=eng.dyna.1477556289

ro.custom.build.version=1477556289

ro.build.version.SDK=19

ro.build.version.codename=REL

ro.build.version.release=4.4.2

ro.build.date=Thu Oct 27 16:21:53 CST 2016

ro.build.date.utc=1477556513

ro.build.type=user

ro.build.user=dyna

ro.build.host=dyna-powerEDGE-R720

ro.build.tags=test-keys

ro.product.model=P92

ro.product.brand=alps

ro.product.name=sanstar82_cwet_kk

ro.product.device=sanstar82_cwet_kk

ro.product.board=sanstar82_cwet_kk

ro.product.CPU.abi=armeabi-v7a

ro.product.cpu.abi2=armeabi

ro.product.manufacturer=alps

ro.product.locale.language=zh

ro.product.locale.region=CN

```

一个标准的build.prop文件如上图所示,Android系统在启动的阶段,会在解析init的时候加载这些属性文件

\system\core\init\Init.c

```

int main(int argc, char **argv)

{

//加入到action queue队列

queue_builtin_action(property_service_init_action, "property_service_init");

for(;;)

//执行action queue队列

//接收通过SOCket向property service 发送的数据;

nr = poll(ufds, fd_count, timeout);

……

handle_property_set_fd();

}

```

property_service_init_action是初始化属性的入口

```

static int property_service_init_action(int nargs, char **args)

{

start_property_service();

}

```

\system\core\init\property_service.c:

```

void start_property_service(void)

{

//加载属性配置文件

load_properties_from_file(PROP_PATH_SYSTEM_BUILD);

load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT);

load_properties_from_file(PROP_PATH_LOCAL_OVERRIDE);

load_persistent_properties();

//创建socket资源 并绑定

fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM, 0666, 0, 0);

//监听

listen(fd, 8);

}

Property Service 是运行在init守护进程中。

```

这里会加载 /system/build.prop /default.prop 这两个属性文件

之后保存这些属性到共享内存空间。供所有进程访问

这里有三种方式访问系统属性。

第一种是adb  shell  方式

```

PS C:\Users\xxx> adb shell getprop  ro.product.cpu.abilist32

armeabi-v7a,armeabi

PS C:\Users\xxx>

```

第二种 通过SystemProperties 类访问,这个需要导入Android 源码的Framework.jar ,否则编译通过不了

```

String test = SystemProperties.get("o.build.id");

```

没有framework.jar ,也可以通过反射的方式

```

public String getProperty(String key, String defaultValue) {

String value = defaultValue;

try {

Class> c = Class.forName("android.os.SystemProperties");

Method get = c.getMethod("get", String.class, String.class);

value = (String)(get.invoke(c, key, "unknown" ));

} catch (Exception e) {

e.printStackTrace();

}

return value;

}

```

第三种是

```

android.os.Build.PRODUCT

android.os.Build.ID

```

通过源码可以明显看到这种方法只是第二种做了一层封装

```

public static  final String PRODUCT = getString("ro.product.name");

/** The name of the industrial design. */

public static  final String DEVICE = getString("ro.product.device");

```

```

private static String getString(String property) {

return SystemProperties.get(property, UNKNOWN);

}

```

最后还是调用 SystemProperties.get 获取系统参数

现在如果想修改Android系统参数,可以通过上面三种方式。但是在实际测试中。大家在获取参数的时候只会用到第二种和第三种。

有人首先想到修改\frameworks\base\core\java\android\build.java文件。

```

public class Build {

private static final String TAG = "Build";

/** Value used for when a build property is unknown. */

public static final String UNKNOWN = "unknown";

/** Either a changelist number, or a label like "M4-rc20". */

public static final String ID = "PPTVID";

/** A build ID string meant for displaying to the user */

public static final String DISPLAY = "PPTVDISPLAY";

/** The name of the overall product. */

public static final String PRODUCT = "PPTVTV";

/** The name of the industrial design. */

public static final String DEVICE = "PPTV_OS";

```

这种方式完全可以,但是没法做到动态。

后面我又想到一种方法。加入B 是检测改机的APP,我让B 在调用时候 执行下面的语句

```

public static final String PRODUCT = SystemProperties.get(ro.product.name, UNKNOWN);

```

然后我专门做一个A app 用于修改

```

SystemProperties.set(ro.product.name,"PPTV")

.......

```

每次B 启动前,我先让A执行  SystemProperties.set 修改系统参数。

测试后发现A的修改只对 A这个app 起作用。后来查看源码得知

1、首先public static final String PRODUCT 是final 类型

只会在初始化执行一次。

2、build.java 是static类型。每个进程单独有一份。不是共享的。

所以修改A只会对A进程起作用

我又想到动态修改 SystemProperties 里面的属性。在系统启动的时候加载我自己预置/sdcard/build.prop

```

private  String FindProp(String key) {

String fileName = "build.prop";

String retValue = null;

try {

String sdPath = Environment.getExternalStorageDirectory().getPath();

File file = new File(sdPath,fileName);

if (file.isFile() && file.exists()) {

InputStreAMReader isr = new InputStreamReader(new FileInputStream(file));

BufferedReader br = new BufferedReader(isr);

String lineTxt = null;

while ((lineTxt = br.readLine()) != null) {

if (!"".equals(lineTxt)) {

if(lineTxt.contains("#")){

continue;

}

String props[] = lineTxt.split("\\=");

if(props.length == 2){

String propKey = lineTxt.split("\\=")[0];

String propValue = lineTxt.split("\\=")[1];

if(propKey.equals(key)){

retValue = propValue;

break;

}else{

continue;

}

}

}

}

isr.close();

br.close();

}else {

//                  Toast.MAKEText(getApplicationContext(),"can not find file",0).show();

}

} catch (Exception e) {

e.printStackTrace();

}

return  retValue;

}

```

测试之后跟上面一样,无法正常修改。

最后经过多次测试终于找到一个合适的方法,原理是

原理是开发一个app 用于检测管理

1、读取要修改的系统参数文件,可以是/sdcard/build.prop 或者

从网络获取

2、设置当前的属性到SystemProperties  和build中。

3、开启标志,开启后改机检测工具就读我们设置的属性

经过测试完全满足要求。有希望交流的朋友可以加我qq:875646589

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值