今天想通过HierarchyViewer分析一下Android应用的布局,但是发现无法连接上真机,错误如下:

 
 
1
2
3
4
5
[hierarchyviewer]Unable to get view server version from device 00856cd5d08d2409
[hierarchyviewer]Unable to get view server protocol version from device 00856cd5d08d2409
[ViewServerDevice]Unable to debug device: lge-nexus_4-00856cd5d08d2409
[hierarchyviewer]Missing forwarded port for 00856cd5d08d2409
[hierarchyviewer]Unable to get the focused window from device 00856cd5d08d2409

原理

Android系统出于安全考虑,Hierarchy Viewer只能连接开发版手机或模拟器,我们普通的商业手机是无法连上的(老版本的Hierarchy Viewer可以),这一限制在
frameworks/base/services/java/com/android/server/wm/WindowManageService.java

 
 
 
 
 

Java

 
1
2
3
4
5
6
7
8
9
10
public boolean startViewServer(int port) {
    if (isSystemSecure()) {
        return false;
    }
 
    if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
        return false;
    }
    //……
}

我们要做的就是,修改并替换掉这个文件,使其通过判断。

检验一台手机是否开启了View Server的办法为:

 
 
 
 
 

Shell

 
1
adb shell service call window 3

若返回值是:Result: Parcel(00000000 00000000 '........') 说明View Server处于关闭状态
若返回值是:Result: Parcel(00000000 00000001 '........') 说明View Server处于开启状态

若是一台可以打开View Server的手机(Android开发版手机 、模拟器or 按照本帖步骤给系统打补丁的手机),我们可以使用以下命令打开View Server:
adb shell service call window 1 i32 4939
使用以下命令关闭View Server:
adb shell service call window 2 i32 4939

听说小米手机可以直接打开,如果你的是小米手机,可以试一下。

下面开始是解决方案,使用本方法的前提是:

- 手机已root
- 手机安装了BusyBox(没有的去装一个)

1.拷贝数据

约定当前使用的工作目录是/home/feelyou/hierarchyviewer

打开终端切换到工作目录,新建文件夹存放数据。通过usb连接上手机,执行:

 
 
 
 
 

Shell

 
1
2
3
mkdir ./system
mkdir ./system/framework
adb pull /system/framework/ ./system/framework/

2.获取bootclasspath

 
 
 
 
 

Shell

 
1
2
3
4
adb shell
echo $BOOTCLASSPATH
#将输出的内容复制出来,随意保存到一个文本文件里,后面要用到。
exit

3.反编译odex文件

这里要下载2个小工具,官方地址是https://bitbucket.org/JesusFreke/smali/downloads,下载最新版的smali-xxx.jar和baksmali-xxx.jar,比如我这里下载的是smali-2.0.3.jar和baksmali-2.0.3.jar,将这两个文件下载到工作目录。
然后在终端执行:

 
 
 
 
 
 

Shell

 
1
java -jar baksmali-2.0.3.jar -a 19 -x ./system/framework/services.odex -d ./system/framework/

注意,-a 后面的参数19,是你的手机当前的版本API Level,不知道的自己查一下。我的Nexus 4 是4.2.2,所以是19。执行成功了之后,在当前目录会有个out文件夹。

4.修改smail文件

使用文本编辑器打开out/com/android/server/wm/WindowManagerService.smali文件,搜索isSystemSecure(),第一个找到的目标,应该就是我们要的,这段代码如下(不用细看,我写这么多只是为了让你找到这个方法):

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
.method private isSystemSecure()Z
    .registers 4
 
    .prologue
    .line 6164
    const-string v0, "1"
 
    const-string v1, "ro.secure"
 
    const-string v2, "1"
 
    invoke-static {v1, v2}, Landroid/os/SystemProperties;->get(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 
    move-result-object v1
 
    invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
 
    move-result v0
 
    if-eqz v0, :cond_22
 
    const-string v0, "0"
 
    const-string v1, "ro.debuggable"
 
    const-string v2, "0"
 
    invoke-static {v1, v2}, Landroid/os/SystemProperties;->get(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 
    move-result-object v1
 
    invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
 
    move-result v0
 
    if-eqz v0, :cond_22
 
    const/4 v0, 0x1
 
    :goto_21
    return v0
 
    :cond_22
    const/4 v0, 0x0
 
    goto :goto_21
.end method

这里注意,我们要在第41~42行之间,也就是:goto_21return v0之间加入const/4 v0, 0x0,使他变成

 
 
1
2
3
4
5
6
7
8
9
    :goto_21
    const/4 v0, 0x0
    return v0
 
    :cond_22
    const/4 v0, 0x0
 
    goto :goto_21
.end method

保存。

5.重新编译成dex文件

将out文件夹的内容编译并压缩。然后我们会得到一个叫做feelyou_services_hacked.jar的文件,后面要用到。

 
 
 
 
 

Shell

 
1
2
java -jar smali-2.0.3.jar ./out -o classes.dex
zip feelyou_services_hacked.jar ./classes.dex

6.获取/system挂载信息

这一步我们要获取/system挂载信息,并获取写入权限,因为后面要复制东西进来

 
 
 
 
 

Shell

 
1
2
3
adb shell
su
mount

然后出来一堆东西,查找一下哪个分区挂载了/system,例如我的是/dev/block/platform/msm_sdcc.1/by-name/system

接着,输入以下命令重新挂载/system,并更改/system权限(请将/dev/block/platform/msm_sdcc.1/by-name/system替换成你的/system挂载分区):

 
 
 
 
 

Shell

 
1
2
mount -o rw,remount -t yaffs2 /dev/block/platform/msm_sdcc.1/by-name/system
chmod -R 777 /system

这样我们就可以修改/system的内容了。

7.复制所需文件到手机

首先需要下载dexopt-wrapper,连接为https://dl.dropboxusercontent.com/u/5055823/dexopt-wrapper(英文原文章的连接已经失效),下载后依然放到当前工作目录。

将feelyou_services_hacked.jar和dexopt-wrapper复制到手机的/data/local/tmp文件夹中

 
 
 
 
 

Shell

 
1
2
adb push ./feelyou_services_hacked.jar /data/local/tmp
adb push ./dexopt-wrapper /data/local/tmp

给dexopt-wrapper运行权限

 
 
 
 
 

Shell

 
1
2
3
adb shell
su
chmod 777 /data/local/tmp/dexopt-wrapper

8.生成odex文件

注意!关键步骤!在adb shell中cd到/data/local/tmp文件夹下,运行:

 
 
 
 
 
 

Shell

 
1
./dexopt-wrapper ./feelyou_services_hacked.jar ./feelyou_services_hacked.odex [这里替换成之前获取到的BOOTCLASSPATH路径,但是注意!删除其中的":/system/framework/services.jar",当然,不包括中括号]

比如最后我的是这样:

 
 
 
 
 
 

Shell

 
1
./dexopt-wrapper ./feelyou_services_hacked.jar ./feelyou_services_hacked.odex /system/framework/core.jar:/system/framework/conscrypt.jar:/system/framework/okhttp.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/framework2.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/mms-common.jar:/system/framework/android.policy.jar:/system/framework/apache-xml.jar:/system/framework/webviewchromium.jar

这样就生成了一个feelyou_services_hacked.odex文件,等下我们要用它来替换系统原有的odex文件。

执行完了是这样的显示:

9.给生成的odex文件签名

还是在adb shell,su,执行:

 
 
 
 
 
 

Shell

 
1
busybox dd if=/system/framework/services.odex of=/data/local/tmp/feelyou_services_hacked.odex bs=1 count=20 skip=52 seek=52 conv=notrunc

10.替换系统odex

最后一步,将/system/framework里的services.odex替换成我们自己制作的feelyou_services_hacked.odex。

 
 
 
 
 

Shell

 
1
dd if=/data/local/tmp/feelyou_services_hacked.odex of=/system/framework/services.odex

替换完成后手机会立刻重启。如果执行这一步,这个时候提示是只读,说明/system没有获取到写入权限,请重复第6步。

11.打开服务

成功重启后,用以下命令打开View Server:
adb shell service call window 1 i32 4939
用以下命令查看View Server是否打开:
adb shell service call window 3
返回的值若是Result: Parcel(00000000 00000001 '........'),那就搞定了!

参考文章:

解决HierarchyViewer不能连接真机的问题的更多相关文章

  1. Android配置----DDMS 连接真机(己ROOT),用file explore看不到data/data文件夹的解决办法

    Android DDMS 连接真机(己ROOT),用file explore看不到data/data文件夹,问题在于data文件夹没有权限,用360手机助手或豌豆荚也是看不见的. 有以下两种解决方法: ...

  2. android DDMS 连接真机(己ROOT),用file explore看不到data/data文件夹的解决办法

    android DDMS 连接真机(己ROOT),用file explore看不到data/data文件夹的解决办法 问题是没有权限,用360手机助手或豌豆荚也是看不见的. 简单的办法是用RE文件管理 ...

  3. XE6 & IOS开发之免证书真机调试(2):连接真机并运行App(有图有真相)

    网上能找到的关于Delphi XE系列的移动开发的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 连接真机前,请先确保真机 ...

  4. Appium 小白从零安装 ,Appium连接真机测试。

    以下是我个人在初次安装使用Appium时的过程,过程中遇到了一些问题,在这里也一一给出解决办法. Appium安装过程 先安装了 Node.js.在node的官网上下载的exe安装文件. 在node的 ...

  5. Android Studio软件技术基础 —Android项目描述---1-类的概念-android studio 组件属性-+标志-Android Studio 连接真机不识别其他途径

    学习android对我来说,就是兴趣,所以我以自己的兴趣写出的文章,希望各位多多支持!多多点赞,评论讨论加关注. 最近有点忙碌,对于我来说,学习Android开发,是对于我的考验,最近一位大佬发给我一 ...

  6. APPium连接真机输入框中输入的内容与代码中不一致

    今天解决了上一个问题,又碰到了一个新的问题. 问题:连接真机输入框中输入的内容与代码中不一致. 描述: 想实现登录页面输入用户名和密码自动登录,可是在输入用户名和密码的框中输入的内容总是与代码中的不一 ...

  7. Python+Appium自动化测试(2)-appium连接真机启动app

    app自动化测试的第一步,是启动被测app.appium环境搭建好后,我们就可以连接真机启动app了.环境为windows,Appium1.18.0,Android手机,被测app为今日头条app,让 ...

  8. Unity3D连接真机调试教程,可抓断点

    源地址:http://www.unity蛮牛.com/thread-19586-1-1.html <ignore_js_op> 未标题-1.jpg (52.33 KB, 下载次数: 0) ...

  9. appium通过WiFi连接真机进行测试

    http://www.th7.cn/Program/Android/201507/514602.shtml appium通过WiFi连接真机进行测试   2015-07-24 19:43:07CSDN ...

随机推荐

  1. 【转】c# 解析JSON的几种办法

    http://www.cnblogs.com/ambar/archive/2010/07/13/parse-json-via-csharp.html 刚开始只是想找一个转换JSON数组的方法,结果在M ...

  2. Summary of java stream classes

    Java’s stream classes are good for streaming sequences of bytes, but they’re not good for streaming ...

  3. Cloudera CDH 、Impala本地通过Parcel安装配置详解及什么是Parcel

    本文引用自:Cloudera CDH .Impala本地通过Parcel安装配置详解及什么是Parcelhttp://www.aboutyun.com/forum.php?mod=viewthread ...

  4. 《linux内核设计与实现》读书笔记第五章——系统调用

    第5章 系统调用 操作系统提供接口主要是为了保证系统稳定可靠,避免应用程序恣意妄行. 5.1 与内核通信 系统调用在用户空间进程和硬件设备之间添加了一个中间层. 该层主要作用有三个: 为用户空间提供了 ...

  5. linux configure

    Linux环境下的软件安装,并不是一件容易的事情;如果通过源代码编译后在安装,当然事情就更为复杂一些;现在安装各种软件的教程都非常普遍;但万变不离其中,对基础知识的扎实掌握,安装各种软件的问题就迎刃而 ...

  6. 大数据下的java client连接JDBC

    1.前提 启动hiveserver2服务 url,username,password 2.程序 3.结果 emp的第一列与第二列

  7. 在大数据中,关于native包的编译步骤

    一.问题的由来: 二.解决问题的方法(所有的操作在root下完成): 1.前期需要的环境,下面的已经在伪分布式中配置好,不再重复 配置好jdk 配置好hadoop 2.上传还需要包 apache-ma ...

  8. zepto源码--qsa--学习笔记

    zepto内部选择器qsa方法的实现. 简述实现原理: 通过判断传入的参数类型: 如果是'#id',则使用getElementById(id)来获取元素,并且将结果包装成数组形式: 如果是'.clas ...

  9. 几个简单的html+css+js题目

    1.页面中有一图片,请在下划线处添加代码能够实现隐藏该图片的功能 <img id="pic" src="door.jpg" width="200 ...

  10. OO之美3

    面向对象和基于对象 基于对象:所以基于对象,就是一种对数据类型的抽象,封装一个结构包含了数据和函数,然后以对象为目标进行操作.构建的基础是对象,但是操作对象并不体现出面向对象的继承性,也就是基于对象局 ...