前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >android手机免root修改hosts

android手机免root修改hosts

原创
作者头像
whp
发布2018-07-09 21:59:33
45.1K2
发布2018-07-09 21:59:33
举报
文章被收录于专栏:个人技术分享个人技术分享

android手机免root修改hosts

痛点在哪里

开发及测试过程中经常需要切换开发、测试、预发布等环境,切换环境是通过修改hosts实现的。

android设备修改hosts看似简单,实际却会遇上不少麻烦,特别是在公司的网络环境中。你可能会遇到这种情况:

adb shell进去修改/etc/hosts,发现只读无法修改,需要root权限。尝试各种方法还是root失败后,转而想要通过电脑代理的方法避开root,但是这种方法需要把电脑也转网到staff-wifi,转网后一堆开发软件设置的代理也得跟着改,linux环境变量也得跟着改,总之一堆麻烦,而且从staff-wifi转回开发网或办公网还需要审核,想想就放弃了。。。

总结几种方法

1、root手机,修改/etc/hosts。

缺点:手机越来越难root,比如华为已经不允许申请手机解锁码。

2、手机和电脑连到同一个wifi(比如staff-wifi),手机设置代理到电脑(fiddler启动电脑代理服务),修改电脑的hosts。

缺点:依赖于电脑,而且因为手机无法连入开发网或办公网,电脑可能需要转网。

3、拦截DNS请求,直接返回所需要的A记录。

思来想去,如果可以修改DNS的回包,不是也相当于修改hosts的效果嘛!但怎么改?会不会也有root权限问题?

如何实现方法3

经历了一番痛苦后,笔者决定写个工具来实现改hosts的效果,一劳永逸,于是一番查找:

cap

km上搜了一下,发现公司有个内部开源项目 -- cap,看介绍非常强大,基于底层hook技术随便抓包改包,看样子应该可以实现篡改DNS的需求。但是笔者只是想实现改hosts的效果,cap显得有点重,作为备选方案吧。

V**Service

后面发现android提供了V**服务框架,基础类是V**Service,免root,能够全局拦截网络请求、修改网络包。

能够拦截,还能够修改,嗯,很好!

逮着V**Service如何修改网络请求,一番google,发现有人已经实现了笔者需要的效果而且开源了,项目 Virtual-Hosts

好吧,有人实现了,而且代码写的挺不错,就用它了。接下来分析一下这个项目。

Virtual-Hosts 分析

简单来说分两步:1、V**Service拦截DNS请求。2、构造DNS回包并写回V**Service。

1、拦截DNS请求

使用V**Service拦截DNS请求很容易实现,对V**Service简单配置,然后startService就可以了。以IPV4为例,配置如下:

代码语言:javascript
复制
    //V**地址,可以随意设置
    private static final String V**_ADDRESS = "192.0.2.111";
    //DNS地址,填个正常的dns地址即可
    private static final String V**_DNS4 = "8.8.8.8";
    ...
    Builder builder = new Builder();
    builder.addAddress(V**_ADDRESS, 32);
    //设置DNS服务器
    builder.addDnsServer(V**_DNS4);
    //所有到V**_DNS4的请求都走这个V**。
    //配合builder.addDnsServer(V**_DNS4),就实现了所有DNS请求都走V**,因此能够拦截到所有DNS请求。
    builder.addRoute(V**_DNS4, 32);

2、构造DNS回包并返回

接下来处理拦截到的包。

代码语言:javascript
复制
    FileChannel V**Input = new FileInputStream(V**FileDescriptor).getChannel();
    ByteBuffer bufferToNetwork = ByteBufferPool.acquire();
    //取出一个拦截到的请求包
    int readBytes = V**Input.read(bufferToNetwork);
    //解析包并构造出Packet
    Packet packet = new Packet(bufferToNetwork);
    if (packet.isUDP()) {
        deviceToNetworkUDPQueue.offer(packet);
    } else if (packet.isTCP()) {
        deviceToNetworkTCPQueue.offer(packet);
    }

这里的DNS请求走UDP,因此会走到UDPOutput:

代码语言:javascript
复制
    Packet currentPacket = inputQueue.poll();
    //handle_dns_packet里面利用开源库 dnsjava 解析DNS请求并构造回包,填入需要的A记录
    ByteBuffer packet_buffer= DnsChange.handle_dns_packet(currentPacket);
    //写入到队列,用于返回给V**Service
    this.outputQueue.offer(packet_buffer);

回包给V**Service:

代码语言:javascript
复制
    FileChannel V**Output = new FileOutputStream(V**FileDescriptor).getChannel();
    ByteBuffer bufferFromNetwork = networkToDeviceQueue.poll();
    V**Output.write(bufferFromNetwork);

传送门:dnsjava

到这里就走通了通过拦截DNS请求实现修改hosts效果的整个过程,以上只是简单分析,感兴趣可以细读代码。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • android手机免root修改hosts
    • 痛点在哪里
      • 总结几种方法
        • 如何实现方法3
          • cap
          • V**Service
        • Virtual-Hosts 分析
          • 1、拦截DNS请求
          • 2、构造DNS回包并返回
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档