android手机免root修改hosts

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显得有点重,作为备选方案吧。

VpnService

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

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

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

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

Virtual-Hosts 分析

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

1、拦截DNS请求

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

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

2、构造DNS回包并返回

接下来处理拦截到的包。

    FileChannel vpnInput = new FileInputStream(vpnFileDescriptor).getChannel();
    ByteBuffer bufferToNetwork = ByteBufferPool.acquire();
    //取出一个拦截到的请求包
    int readBytes = vpnInput.read(bufferToNetwork);
    //解析包并构造出Packet
    Packet packet = new Packet(bufferToNetwork);
    if (packet.isUDP()) {
        deviceToNetworkUDPQueue.offer(packet);
    } else if (packet.isTCP()) {
        deviceToNetworkTCPQueue.offer(packet);
    }

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

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

回包给VpnService:

    FileChannel vpnOutput = new FileOutputStream(vpnFileDescriptor).getChannel();
    ByteBuffer bufferFromNetwork = networkToDeviceQueue.poll();
    vpnOutput.write(bufferFromNetwork);

传送门:dnsjava

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

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

如有侵权,请联系 zhuanlan_guanli@qq.com 删除。

发表于

个人技术分享

1 篇文章2 人订阅

我来说两句

1 条评论
登录 后参与评论

相关文章

来自专栏程序员笔录

Spark 开发环境搭建

本文是对初始接触 Spark 开发的入门介绍,说明如何搭建一个比较完整的 Spark 开发环境,如何开始应用相关工具。文中如有错误或者不当之处,敬请指正。

1.1K1
来自专栏猿天地

微信中页面二次分享小图标丢失问题

在我们有房APP1.1的版本中增加了房产资讯的功能,昨天晚上有同事在群里反馈从APP中分享的资讯到微信中,然后再次分享出去的时候标题和小图标不见了,见下图:

932
来自专栏前端架构

Nginx实践配置HTTP2.0

http/2.0是http/1.1的升级版,简称h2,主要应用于https。和html的h5简称不在一个维度上。而http://继续使用http1协议. 

602
来自专栏惨绿少年

Zabbix 3.0 从入门到精通(zabbix使用详解)

第1章 zabbix监控 1.1 为什么要监控      在需要的时刻,提前提醒我们服务器出问题了      当出问题之后,可以找到问题的根源      网站/...

4591
来自专栏FreeBuf

任意用户密码重置(四):重置凭证未校验

在逻辑漏洞中,任意用户密码重置最为常见,可能出现在新用户注册页面,也可能是用户登录后重置密码的页面,或者用户忘记密码时的密码找回页面,其中,密码找回功能是重灾区...

3218
来自专栏张善友的专栏

The jQuery UI CSS Framework

jQuery UI是 jquery官方推出的配合jquery使用的用户界面组件集合!包含了许多的界面操作功能,如我们常用的表格排序,拖拽,TAB选项卡,滚动条,...

1766
来自专栏北京马哥教育

一篇了解爬虫技术方方面面

原理 传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件...

3839
来自专栏林德熙的博客

win10 uwp 弹起键盘不隐藏界面元素

本文主要讲,在我们使用手机输入的时候,会因为手机的虚拟键盘隐藏了一些界面的元素。我们有一个简单的方法让虚拟键盘不隐藏界面元素。

331
来自专栏FreeBuf

一个比较好玩的WebShell上传检测绕过案例

背景介绍 一次普通的 WEB 测试过程,遇到了一个上传点,可以上传固定图片格式但是可以任意名字+任意后缀名的文件。 ? 环境 IIS 7.5/ ASP.NET ...

2366
来自专栏Python中文社区

新浪微博爬虫最新分享

專 欄 ❈ 九茶,Python工程师,目前居于广州。Github知名开源爬虫QQSpider和SinaSpider作 者,经常会在CSDN上分享一些爬虫、数据...

1888

扫描关注云+社区