com.android.ap idemo windows,手机该如何恢复此功能?

如何把Android手机变成一个WIFI下载热点? — 报文转发及DNS报文拦截 - 推酷
如何把Android手机变成一个WIFI下载热点? — 报文转发及DNS报文拦截
随着wifi的普及,移动运营商的热点也越来越多了,如中国移动的CMCC、中国电信的ChinaNet、中国联通的ChinaUnicom等,一般来说,连上此类的热点,打开浏览器上网时都会自动跳转到一个验证页面,最近有个项目也有类似的需求,Android手机自建热点,别的手机wifi连接此热点,打开浏览器,输入任意内容,自动跳转到一个下载列表页面,点击相应的链接即可下载相应的文件。
考虑如下几种情况:
浏览器输入IP地址,请求对应IP地址的80端口的内容
浏览器输入域名,先进行DNS解析域名,得到IP地址后,请求对应的80端口的内容
浏览器输入任意字符,一般浏览器内部设置一个默认的搜索引擎,此时地址栏的内容会作为搜索的关键字,加在搜索的url中
因此,需要解决如下问题:
端口报文转发
DNS报文拦截
端口报文转发
Android系统本身是Linux内核,1024以下端口都名花有主,如http是80,https是443,dns是53,对于这些1024以下端口的绑定需要root权限,但一般的App是没有root权限的,除非在 AndroidManifest.xml 文件中声明 android:sharedUserId=&android.uid.system&,并使用密钥文件进行签名:
java -jar signapk.jar platform.x509.pem platform.pk8 your.apk your_signed.apk
但问题是密钥文件属于手机厂商,显然不可能拿到这个密钥文件,当然,如果在模拟器里测试倒是可以的,从android源代码 build/target/product/security 里找到密钥文件,platform.pk8 和 platform.x509.pem,签名工具 signapk.jar 在 build/tools/signapk 下。
基于以上原因,一般Web服务器都绑定8080端口,手机浏览器如果输入IP地址,会访问Web服务器的80端口,这样就需要进行端口报文转发,对应dns报文拦截,无法监听53端口,同样需要端口转发,此外,浏览器的搜索引擎如果是google的话,使用https,同样也有这个问题。
iptables是个很好的防火墙管理工具,这里需要做如下配置:
iptables -t nat -A PREROUTING -d 0.0.0.0/0 -p tcp --dport 80 -j DNAT --to 192.168.43.1:8080
iptables -t nat -A PREROUTING -d 0.0.0.0/0 -p tcp --dport 443 -j DNAT --to 192.168.43.1:8443
iptables -t nat -A PREROUTING -d 0.0.0.0/0 -p udp --dport 53 -j DNAT --to 192.168.43.1:53530
说明:-t nat:指定nat表,-A:添加,PREROUTING:路由前处理,-d 0.0.0.0/0:任意目的地IP,-p tcp:协议,--dport 80:端口,-j DNAT:地址映射跳转,--to 192.168.43.1:8080:转发目的地,总的意思就是,到达防火墙的报文,不管去往那个IP地址,只要是发往80端口的tcp包,都转发到192.168.43.1的8080端口。剩下两条意思类似。
需要注意的是:
1、如果是App中的java代码调用,需要root权限,一般这么写:
String shell = &su -c iptables -t nat -A PREROUTING -d 0.0.0.0/0 -p tcp --dport 80 -j DNAT --to 192.168.43.1:8080&;
Runtime.getRuntime().exec(shell);
2、Android手机设置为热点模式时,IP地址一般都会固定成192.168.43.1,这是由手机的dhcpcd服务指定的,一般不会去改dhcpcd服务的源代码然后重新编译,但这种写死的做法显然是不太合适的,通用的做法是自动取Ap的IP地址:
public static String getNetworkIpAddress(String name) {
Enumeration&NetworkInterface& interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface networkInterface = (NetworkInterface) interfaces.nextElement();
Enumeration&InetAddress& enumeration = networkInterface.getInetAddresses();
while (enumeration.hasMoreElements()) {
InetAddress inetAddress = (InetAddress) enumeration.nextElement();
if (!inetAddress.isLoopbackAddress()
&& inetAddress instanceof Inet4Address
&& TextUtils.equals(name, networkInterface.getDisplayName())){
return inetAddress.getHostAddress().toString();
} catch (Exception e) {
e.printStackTrace();
return &&;
public static String getApName(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Method method = connectivityManager.getClass().getMethod(&getTetheredIfaces&);
String[] names = (String[]) method.invoke(connectivityManager);
return names[0];
} catch (Exception e) {
e.printStackTrace();
return &&;
看着挺复杂的,因为热点模式和连接到别的热点是完全不同的,取Ap名字时,用到了一个隐藏的方法,需要用反射的方式调用。
DNS报文拦截
DNS意思是域名解析协议,用户打开浏览器浏览网页时,不会记IP地址,而是记某些有含义的网址,DNS就是解决网址到IP地址的对应问题。DNS报文格式参考RFC1035文档,微软的网站上也有介绍:
,这里主要介绍DNS报文的格式。
DNS报文格式
DNS报文一般由如下部分组成:
DNS header (fixed length,12 Bytes)
Question entries (variable length)
Answer resource records (variable length)
Authority resource records (variable length)
Additional resource records(variable length)
套用《TCPIP详解卷》中的一张图
DNS header(固定占12字节)
总共占12字节,结构如下:
-- 标识:报文的标识,占2字节,查询的报文里生成,响应的报文里复制此内容,用来标识是对相应查询的响应
-- 标记:报文的标记位,占2字节,也就是16位,如下:
QR:0标识查询,1标识响应,
opcode:0为一般查询,1为反向查询(IP地址反查域名),2为查询服务器状态,一般为0
AA:是否为授权回答(authoritative - answer),可以理解为当前域名服务器是否对结果负责,如果从别的域名服务器查询过来的结果,显然不是当前域名服务器可掌控的,因此设为0
TC:是否被截断,UDP报文限定512字节(不包含IP及头部信息),如果超出将截断,此标记也被置1
RD:是否递归查询(Recursion Desired),如果为1,说明DNS服务器如果没有结果,那么DNS服务器会递归地找别的DNS服务器要结果,直到得到结果并返回,如果为0,则在没有结果的情况下,返回DNS列表
RA:是否支持递归查询,在响应报文中,一般都会支持递归查询
zero:必须为0
rcode:错误码,一般为0,表示没有错,如果不为0,表示有问题,错误码可以参考相关文档
--问题资源数:占2字节
--回答资源数:占2字节
--授权资源数:占2字节
--附加资源数:占2字节
Question entries(不定长)
不定长,结构如下:
名字:域名的字符串表示,表示为:0x09microsoft0x03com0x00,需要注意的是长度的最高两位必须为0,因此字符长度不能超过63,也就是说最多0x3f,另外,参考rfc1053,为简化起见,域名总长度不能超过255
类型:相关含义可查手册,一般是0x0001,表示IP地址类型
类:一般是0x0001,表示普通的internet问题
Answer resource records(不定长)
不定长,结构如下:
名字:同前面的查询名字,一般会以索引方式表示,引用到前面的字符,比如前面的
字符在报文中的位置
类型:同前面的查询类型
类:同前面的查询类
生存时间:报文生存时间(TTL),占4字节,单位秒
资源长度:占2字节
资源内容:资源具体的内容,如IP地址:1.1.1.1 表示为 0x
Authority resource records(不定长)
Additional resource records(不定长)
经过以上的分析,来看个例子,打开wireshark抓包工具,监听网卡数据包,打开控制台,输入:,并抓取DNS报文。
上图为DNS查询:21d36f6d
21 d5:会话标识,应答中用于标识是哪个查询
01 00:标记,二进制为00 0000,参考标记位,RD被置1,标识是一个递归的查询
00 01:问题数1
00 00:回答资源数0
00 00:授权资源数0
00 00:额外资源数0
05 62 61 69 64 75 03 63 6f 6d 00:域名名字,就是5baidu3com0这种格式,数字标识字符的数量,baidu有5个字符,所以是5baidu,域名字符串最后要跟一个0x00
00 01:查询IP地址
00 01:普通的internet查询
上图为DNS应答:21d36f6dc00c017c0c00c017c0004dcb56f55c00c017c0004dcb56f56
21 d5:标识,和之前的查询一一对应
81 80:标记,二进制为00 0000,QR、RD、RA被置1,表示支持递归查询的应答
00 01:问题数1
00 03:回答资源数3
00 00:授权资源数0
00 00:额外资源数0
05 62 61 69 64 75 03 63 6f 6d 00:域名名字,参考前面的查询报文
00 01:查询IP地址
00 01:普通的internet查询
c0 0c:域名名字,应该和前面的一致,但是为了节省报文长度,这是个引用,怎么知道的呢?因为是c0,二进制是,最高位两位置1了,这串字符前面有12个字节,因此相对位置是0c(从0开始)
00 01:查询IP地址
00 01:普通的internet查询
00 00 01 7c:生存时间(Time to Live,TTL,单位秒),380秒
00 04:资源长度,4个字节,表示接下来的4个字节是资源的实际内容
7b 7d 72 90:资源内容,其实就是IP地址,123.125.114.144
c0 0c ...:同上
从上面的DNS应答报文看,关注7b7d7290、dcb56f55、dcb56f56即可,分别对应三个IP地址:123.125.114.144、220.181.111.85、220.181.111.86
DNS报文拦截实现
了解了DNS报文的内容,下面需要做的就是,监听DNS端口,构造自己的报文返回即可,由于权限问题,一般Android的App是无法监听53端口的,这里可以监听53530端口,再通过iptables设置防火墙,将53端口的报文转发到53530端口即可,注意DNS是UDP包,代码参考如下
byte[] requestBuffer = new byte[256];
byte[] responseBuffer = new byte[256];
byte[] ipBuffer = { (byte) 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00,
0x00, 0x01, 0x7c, 0x00, 0x04, 0x01, 0x01, 0x01, 0x01 };
datagramSocket = new DatagramSocket(53530);
DatagramPacket requestPacket = new DatagramPacket(requestBuffer,requestBuffer.length);
while (!Thread.currentThread().isInterrupted()) {
datagramSocket.receive(requestPacket);
int requestLength = requestPacket.getLength();
System.arraycopy(requestBuffer, 0, responseBuffer, 0, requestLength);
System.arraycopy(ipBuffer, 0, responseBuffer, requestLength, ipBuffer.length);
responseBuffer[2] = (byte) 0x81;
responseBuffer[3] = (byte) 0x80;
responseBuffer[6] = (byte) 0x00;
responseBuffer[7] = (byte) 0x01;
DatagramPacket response = new DatagramPacket(responseBuffer, requestLength + ipBuffer.length, requestPacket.getAddress(), requestPacket.getPort());
datagramSocket.send(response);
} catch (Exception e) {
e.printStackTrace();
这样,所有的DNS解析请求都被转到1.1.1.1这个IP地址了。
这个一般由Web服务器决定,Android有款ijetty,是开源的
可看看其中的源代码,修改其中的Handler就搞定了。
已发表评论数()
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
没有分页内容
图片无法显示
视频无法显示
与原文不一致5013人阅读
Android(49)
手机的AP和BP根据上下文可以指代硬件和软件两种意思.&
1) 大多数的手机都含有两个处理器。操作系统、用户界面和应用程序都在Application Processor(AP)上执行,AP一般采用ARM芯片的CPU。而手机射频通讯控制软件,则运行在另一个分开的CPU上,这个CPU称为Baseband Processor(BP)。&
把射频功能放在BP上执行的主要原因是:射频控制函数(信号调制、编码、射频位移等)都是高度时间相关的。最好的办法就是把这些函数放在一个主CPU上执行,并且这个主CPU是运行实时操作系统的。&
另外一个使用BP的好处是一旦它被设计和认证为好了的,不管你采用的操作系统和应用软件怎么变化,它都可以正确的执行功能(它的通讯功能)。另外,操作系统和驱动的bug也不会导致设备发送灾难性的数据到移动网络中。(FCC要求的)&
由于AP和BP是分开的设备,手机设计者可以更加自由的设计用户界面和应用软件。&
2)手机开发商,比如摩托罗拉,会将开发的手机软件包分为AP和BP两部分, 运行在Application Processor(AP)的软件包称为AP包,包括操作系统、用户界面和应用程序等; 与Baseband Processor(BP)相关的软件包称为BP包, 包括baseband modem的通信控制软件等. 相应地, 所谓的刷新手机AP和BP文件即是将这两个软件包更新到手机上.
为方便刷机, 也有将AP,BP文件和flex文件(手机的参数配置文件)作在一起的一体包.
AP+BP二者之间通过共享内存来通信!!!!!
/thread-.html
从功能上讲对于智能手机的一个粗略的概括是,智能手机 == 电脑 + 移动网卡,或者更准确地说,智能手机的硬件结构分为应用程序处理器AP,和基带处理器BP两个部分。这里隐含着两个问题,
1. BP部分与AP部分的集成。
2. 传统的功能手机只配备了出厂时预装的应用软件,而不允许用户自主下载并安装第三方应用软件,而智能手机突破了这一限制,因此智能手机的AP部分,必须有相应的开放机制,方便第三方软件的开发与安装,同时尽可能降低第三方软件造成对整个系统,包括其它软件的恶意伤害。更进一步说,智能手机的开放机制,不仅针对第三方软件,而且也针对手机生产厂家,允许手机生产厂家更换手机系统的部分硬件设备,或者增设其它外设硬件设备,做到一个通用平台可以出货多个手机型号,帮助手机生产厂家尽可能降低手机研发费用。
对于第一个问题,BP部分如何与AP部分集成,解决方案的思路很简单。翻开任何一本操作系统教科书,都可以看到标准的分层结构,应用软件 && 操作系统 && 驱动器 && 硬件。不妨把BP与AP的集成,与操作系统中的文件系统的构成相比较。
文件系统通常包括虚拟文件系统(Virtual File System,VFS)与实际存储设备(Storage Device)两部分。实际存储设备包括闪存或者硬盘等等存储硬件,以及相应驱动器。虚拟文件系统通过驱动器操纵存储硬件,在这个基础上实现文件和文件夹的建立与删除,文件读写等等功能。虚拟文件系统之所以被称为虚拟,是因为应用软件通过标准的接口(APIs),来调用虚拟文件系统实现的文件和文件夹的功能,而与实际存储设备究竟用的是哪一家厂商出品的硬件和驱动器无关[1]。
如果把文件系统中的实际存储系统类比成智能手机的BP部分,那么虚拟文件系统相对应的是AP部分中的Telephony Stack。Telephony Stack提供三个功能,
1. 与BP部分的系统间通讯(Inter-Processor Communication,IPC),给BP部分下达指令,建立通信通道,发送及接受语音和数据信息。IPC的实现方式可以是通过传递AT-Command,也可以是利用共享内存来实现数据交换。
2. 围绕BP部分提供的三大基础功能,即语音通话,短信等数据通信,以及SIM卡管理,加上与之密切相关的电话本(Address Book),提供以下服务,
&&- 拨打电话:发起或接受语音电话。
&&- 短信管理:编辑短信,发送短信,接受短信,删除,回复或者转发短信等等。
&&- 通话历史。
&&- 电话本。
&&- 手机振铃及振动设置。
&&- SIM卡管理。
3. 提供标准的调用接口(Telephony APIs, TAPI),方便应用软件调用上述服务。
Figure 13-1描述的是WinMobile 6的AP系统中,Telephony Stack的内部结构。图中紫色部分的模块,严格来说,并不属于Telephony Stack,它们是应用软件,它们通过调用Telephony APIs来使用黄色部分模块的功能。黄色部分的模块,负责实现拨打电话,短信管理,SIM卡管理,通话历史等等功能,称作cellcore,由 cellcore.dll提供,手机设计厂家不可以更改cellcore。蓝色部分模块,主要是RIL(Radio Interface Layer),它负责AP部分与BP部分之间的系统间通讯。RIL部分是硬件相关的,由手机Design
House或者BP部分生产厂家完成
Figure 13-1. WinMobile Telephony Stack.
第一个问题,BP与AP的集成,比较容易解决。第二个问题,AP的开放机制,提供调用系统资源的标准接口,既方便第三方软件的开发与安装,同时也尽可能降低开放的风险,这个问题不太容易解决。什么方式的调用接口才算方便,什么程度的风险控制才算安全,这两个指标都缺乏公认的衡量准则。在当前情况下我们能做的,或许是比较几个智能手机的AP部分的设计,分析一下谁更方便更安全。
Figure 13-2描述的是,Telephony Stack在整个WinMobile系统中的位置,由红色方框界定。WinMobile为第三方软件提供了Win32 APIs,Win32 APIs不仅提供了分配内存,控制进程与线程,读写文件,连接网络等等基本功能的调用接口(APIs),也提供了开启和关闭窗口,以及控制窗口控件的GUI相关的APIs。
Figure 13-2. WinMobile Architecture.
Win32 APIs功能全面,但是使用难度大。很多APIs附带的参数很多,很多重复性的工作没有被封装,导致应用软件的开发,不仅代码量大,而且容易出错。有鉴于此,微软把纯C的Win32 APIs,用VC++重新包装,形成MFC(Microsoft Foundation Classes)。作为一种Object-Oriented语言,VC++具有封装(Encapsulation),多态(Polymorphism),继承(Inheritage)等等特性。MFC利用 VC++这些特性,大大简化了对Win32 APIs的调用方式,程序员可以用更精简的代码,完成应用软件的开发。
微软把MFC称为一种Application Framework。Application Framework这个概念的兴起,源于寻求降低GUI开发的难度。GUI的开发,涉及图形,布局,事件捕捉与响应,消息传递等等诸多技术,不仅入门难,而且容易出错。Application Framework借助多种编程环境(IDE),工具集,和软件系统定式,例如MVC定式,不仅简化了编程的复杂度,而且通过规范编程方式,降低了出错的风险[2]。
MFC中的Object,可以直接分配内存,所以当清除Object时,需要手工清除内存分配,不留残余。防范内存泄漏,不仅是应用软件开发过程中的难点,也是容易出现bug。如果把MFC中的Object,称为原生态的Object(Native Object),那么Jave和C#/.NET中的Object,是受管制的Object(Managed Object)。所谓受管制,主要体现在Virtual Machine中的垃圾收集器(Garbage Collector)负责管理它们占用的内存空间,而不需要编程者手工分配内存,与清除内存。
Google的智能手机OS,Android,把Telephony功能封装成Java Object,Telephony Manager。依此类推,把GPS功能也封装成Java Object,Location Manager,此外还有Resource Manager等等。通过这些Manager Java Object,把外设硬件(peripheral)的功能封装起来,提供简单的调用接口,降低了应用软件开发的难度,提高了程序员的生产力。同时,还提供 Activity Manager,Window Manager,Content
Provider,View System,Notification Manager等等,简化并规范GUI的开发[3,4]。
这些Java Object运行在Virtual Machine上,它们的内存占用受Garbage Collector管制,从而降低了内存泄露的风险。另外,Android给每个应用软件都分配了独立的VM实体,如果某个应用软件出错,导致支撑其运行的VM实体崩溃,但是通常不会殃及运行其它应用软件的VM实体,从而提高了系统的整体安全。
与MFC相比,Android的 Application Framework,更方便,更安全。当然也有代价,代价是损耗了运行速度。
Figure 13-3. Android Architecture [4].
Android 的开放机制,不仅体现在Application Framework,而且还体现在Hardware Abstraction Layer(HAL)。关于设置HAL的意义,Google有三点说明[4],
1. 为各种硬件器件制订标准的驱动器接口。
2. 由于Android的内核是开源的,服从GPL许可。而有些硬件器件厂商不愿意开源他们的驱动器程序,有了HAL这个隔离带,就可以解决开源的内核与不开源的硬件驱动器之间的矛盾。
3. Android对于硬件驱动器有一定要求。
这三点说明涉及手机制造产业链上的三个参与者,
1. 如果有标准的驱动器接口,最大的受益者是手机生产厂商。只要硬件外设生产商按照标准接口提供相应的硬件驱动程序,手机生产商就可以自由选择各种配件,大大简化了手机的集成的难度和时间。
2. 不必开源的驱动器程序,受益者是硬件器件生产厂商,而且不给手机生产厂商制造困扰。
3. 比较难以理解的是Android对硬件驱动器会有哪些要求,Android为什么要提出这些要求。为了理解这个问题,不妨分析一个实例,看看Android HAL是如何处理Telephony的。
Figure 13-4描述的是与Telephony相关的各个层次之间的协作关系。我们关心的HAL,在图中以Libraries(User Space)命名,Telephony HAL的内部结构以绿色标注,包含两个构件,Radio Daemon和Vendor RIL。
1. Radio Daemon,它是由Android提供的,不随BP硬件的生产厂家和型号而改变。在Android启动时,Radio Daemon就被激活,并一直处于运行状态,直到Android关闭[4]。
2. Vendor RIL(Radio Interface Layer)。Vendor RIL由BP部分生产厂家提供,不同品牌的BP,以及不同型号的BP,绑定不同的Vendor RIL。Vendor RIL的存在形式是一个函数库文件,文件命名必须服从约定的规范,libril-&companyname&-&RIL version&.so,方便Radio Daemon查找可用的Vendor RIL[5]。
在实时运行时,应用软件调用Telephony Stack,而Telephony Stack指示Radio Daemon去发现当前可用的Vendor RIL,并动态载入相应的.so函数库。也就是说,让Radio Daemon去实现热拔插(Plug-and-Play)的功能。Vendor RIL函数库负责AP与BP之间的IPC。至此,从应用软件,到Telephony Stack,到HAL中的Radio Daemon和Vendor RIL,到BP部分的硬件和驱动器,全线贯通。全线贯通后,应用软件就可以处理拨打电话,发送短信等等通信业务了[4,5,6]。
虽然Figure 13-4仅仅描述了与Telephony相关的各个层次之间的协作关系,但是对于其它功能,各个层次之间的协作关系也大致相仿,例如音响控制,和电源管理等等。
Android HAL隐含的意义在于,允许Android手机外接其它硬件设备,例如温度计,扩大手机的功能。
Figure 13-4. Android Telephony system architecture [5].
总结一下,智能手机AP部分与BP部分集成,类似于文件系统中通用的VFS与不同厂家提供的Storage Device的集成。BP部分提供基础的通话,数据通信,和SIM卡功能。而AP部分围绕这些基础功能,提供丰富的服务,例如通话记录,短信的编辑回复和转发等等。这些服务,囊括在Telephony Stack函数库中。
为了方便第三方软件的安装和运行,Android提供了Application Framework,它以Java Object的形式,封装了Telephony Stack函数库的功能,GUI功能,和其它外设硬件设备的功能。Application Framework不仅降低了第三方应用软件的开发难度,而且降低了第三方应用软件出错的可能性,另外还降低了万一第三方应用软件出错,所造成的对整个系统的破坏。
为了方便集成来源广泛的硬件设备,Android提供了Hardware Abstraction Layer。与文件系统中VFS与Storage Device的协作方式类似,一方面,HAL提炼出不同硬件厂商都必须提供的共同的功能,把它们囊括进通用的模块,例如Radio Daemon,通用的模块与硬件的品牌和型号无关。另一方面,HAL要求硬件厂商提供符合Android规范的IPC函数库,例如Vendor RIL,以便建立起通用的模块与不同品牌和型号的硬件设备之间的通讯渠道。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:124587次
积分:1646
积分:1646
排名:第15768名
原创:43篇
转载:14篇
评论:10条
(1)(2)(3)(2)(1)(5)(2)(2)(1)(1)(1)(3)(1)(1)(2)(7)(4)(7)(11)

我要回帖

更多关于 idemo 的文章

 

随机推荐