在Root的手机上开启ViewServer,使得HierachyViewer能够连接

前期准备:

关于什么是Hierarchy Viewer,请查看官方文档:http://developer.android.com/tools/debugging/debugging-ui.html。个人理解:Hierarchy Viewer能获得当前手机实时的UI信息,给界面设计人员和自动化测试人员带来极大的便利。

在Android的官方文档中提到:

To preserve security, Hierarchy Viewer can only connect to devices running a developer version of the Android system.

即:出于安全考虑,Hierarchy Viewer只能连接Android开发版手机或是模拟器(准确地说,只有ro.secure参数等于0且ro.debuggable等于1的android系统)。Hierarchy Viewer在连接手机时,手机上必须启动一个叫View Server的客户端与其进行socket通信。而在商业手机上,是无法开启View Server的,故Hierarchy Viewer是无法连接到普通的商业手机。

Android源码实现这一限制的地方在:

ANDROID源码根目录\frameworks\base\services\java\com\android\server\wm\WindowManageService.java

中的一段:

=====================================================================================

public boolean startViewServer(int port) {
    if (isSystemSecure()) {
        return false;
    }

if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
        return false;
    }

....

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

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的手机,通过修改手机上/system/framework中的某些文件,就可以开启。本文参考了http://blog.apkudo.com/tag/viewserver/,以下是具体步骤(本人基于Windows,若你是Linux的操作系统,直接看原帖吧):

前提是:你的手机已经获得ROOT权限,且有BUSYBOX

另外:请仔细阅读本帖的评论,或许你会有新的收获。


1.将商业手机通过USB连接PC,确保adb服务运行正常

2.备份手机上/system/framework/中的文件至PC。备份的时候请确保PC上保存备份文件的文件夹结构与手机中的/system/framework相同

例如:新建 ANDROID_SDK_ROOT\system\framework文件夹 (本文出现的ANDROID_SDK_ROOT指你安装Android SDK的根目录)

接着在cmd中跳转至ANDROID_SDK_ROOT\platform-tools文件夹下,输入以下代码进行备份:

adb pull /system/framework  ANDROID_SDK_ROOT\system\framework

3.进入adb shell,输出BOOTCLASSPATH:

推荐的做法:

1. 在adb shell中echo $BOOTCLASSPATH > /sdcard/bootclasspath.txt

2. 退回到windows cmd中,输入adb pull /sdcard/bootclasspath.txt

3. bootclasspath.txt将会保存在C:\Users\你的用户名 文件夹下

在第十五步中将会用到这个txt中的内容。

4.下载baksmali 和smali工具。这两个工具是用来反编译和编译odex文件的。

下载地址:

https://dl.dropboxusercontent.com/u/5055823/baksmali-1.4.2.jar

https://dl.dropboxusercontent.com/u/5055823/smali-1.4.2.jar

假设我将这两个jar都下载到了ANDROID SDK根目录下。

5.运行baksmali反编译\system\framework下的services.odex文件:

java -jar ANDROID_SDK_ROOT\baksmali-1.4.2.jar -a 17 -x ANDROID_SDK_ROOT\system\framework\services.odex -d ANDROID_SDK_ROOT\system\framework

参数解释:https://code.google.com/p/smali/wiki/DeodexInstructions

想特别说明的是“-a”后跟的数字,表示你系统的API Level(与你的系统版本有关)。系统版本和API Level的对照关系如下:

(另外,你不会连java -jar都不能运行吧?快去装jdk!)

此步成功的话,在同文件夹下(对于我,就是ANDROID_SDK_ROOT),会有个out文件夹生成

这里顺便解释一下odex文件和dex文件。

dex文件:Dex是Dalvik VM executes的全称,即Android Dalvik执行程序,并非Java的字节码而是Dalvik字节码,16进制机器指令。

odex文件:将dex文件依据具体机型而优化,形成的optimized dex文件,提高软件运行速度,减少软件运行时对RAM的占用。

smali文件:将dex文件变为可读易懂的代码形式,反编译出文件的一般格式。

6.用Eclipse打开out\com\android\server\wm\WindowManagerService.smali文件

查找.method private isSystemSecure()Z这个函数

================================================================

.method private isSystemSecure()Z

.registers 4

.prologue

.line 5965

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

================================================================

在这段代码的倒数7,8行“:goto_21”和“return v0”之间加入"const/4 v0, 0x0"一行.这样,就使得v0返回的值永远为0x0,即false,这样就跳过了WindowManagerService.java里对isSystemSecure的判断。

.method private isSystemSecure()Z函数最后变为:

================================================================

.method private isSystemSecure()Z

.registers 4

.prologue

.line 6276

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

const/4 v0, 0x0

return v0

:cond_22

const/4 v0, 0x0

goto :goto_21

.end method

=====================================================================================

7. 现在运行smali,重新编译:

java -jar smali-1.4.2.jar -o classes.dex

这时候,应该在ANDROID_SDK_ROOT文件夹中出现了classes.dex文件

8. 下载windows下的zip工具:

https://dl.dropboxusercontent.com/u/5055823/zip.exe

假设,我也把zip.exe放进了ANDROID_SDK_ROOT文件夹

9.确认当前cmd命令行运行目录为ANDROID_SDK_ROOT,运行:

zip.exe services_hacked.jar ./classes.dex

这时候在ANDROID_SDK_ROOT文件夹下,出现了打包好的services_hacked.jar

10.进入adb shell,输入su获得ROOT权限

11.重新挂载/system,并更改/system权限

参考步骤(仅供参考,请确保使用相适应于自己手机的正确方法。请参考下面的"galfordq的blog"用户的回复):

a. 输入mount,查看哪个分区挂载了/system,例如我的是:

b. 输入以下命令重新挂载/system,并更改/system权限(请将“/dev/block/mmcblk0p25”替换成你的/system挂载分区):

mount -o rw,remount -t yaffs2 /dev/block/mmcblk0p25

chmod -R 777 /system 使得/system 可以被我们任意修改

这一步的作用,主要是为了第17步能够将/system/framework里的services.odex替换掉。这一步若不成功,在第17步的时候可能出现权限不够,无法替换的错误(Read-Only File System)

12.下载dexopt-wrapper文件

https://dl.dropboxusercontent.com/u/5055823/dexopt-wrapper

我们也将dexopt-wrapper文件放在ANDROID_SDK_ROOT文件夹中

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

adb push ANDROID_SDK_ROOT/services_hacked.jar /data/local/tmp

adb push ANDROID_SDK_ROOT/dexopt-wrapper /data/local/tmp

14.进入adb shell,输入su后,将dexopt-wrapper的权限改为777

chmod 777 /data/local/tmp/dexopt-wrapper

15.在adb shell中cd到/data/local/tmp文件夹下,运行:

./dexopt-wrapper ./services_hacked.jar ./services_hacked.odex <本帖第三步存的地址,但是要删除其中的":/system/framework/services.jar">

这一步就是将第七部生成dex文件最终优化成了odex文件。

===================================================================================================

例如我的命令是:./dexopt-wrapper ./services_hacked.jar ./services_hacked.odex /system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/

framework.jar:/system/framework/framework2.jar:/system/framework/android.policy.jar:/system/

framework/apache-xml.jar:/system/framework/HTCDev.jar:/system/framework/HTCExtension.jar:/system/

framework/filterfw.jar:/system/framework/com.htc.android.bluetooth.jar:/system/framework/wimax.jar:

/system/framework/usbnet.jar:/system/framework/com.orange.authentication.simcard.jar

===================================================================================================

这样,便在/data/local/tmp文件夹中生成了我们自己的odex:services_hacked.odex

16.给我们自己生成的services_hacked.odex签名:

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

参数解释:

if = input file

of = output file

bs = block size (1 byte)

count = number of blocks

skip = input file offset

seek = output file offset

conv=notrunc – don’t truncate the output file.

17.将/system/framework里的services.odex替换成我们自己制作的services_hacked.odex吧!

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

这一步运行后,过一小会儿(1分钟以内)手机就自动重启了!稍等片刻吧!

18.成功重启后,用以下命令打开View Server:

adb shell service call window 1 i32 4939

用以下命令查看View Server是否打开:

adb shell service call window 3

返回的值若是Result: Parcel(00000000 00000001   ‘........‘),那么你就起了!

(若某一步失败,需要恢复系统,请参考http://blog.apkudo.com/tag/viewserver/中的Step 16或联系我的邮箱进一步讨论:[email protected])

接下来,就在Eclipse下编译运行HierarchyViewer来查看手机实时的UI树吧。

请参考:http://maider.blog.sohu.com/255485243.html

时间: 2024-11-14 12:59:27

在Root的手机上开启ViewServer,使得HierachyViewer能够连接的相关文章

如何在Root的手机上开启ViewServer,使得HierachyViewer能够连接(转)

前期准备: 关于什么是Hierarchy Viewer,请查看官方文档:http://developer.android.com/tools/debugging/debugging-ui.html.个人理解:Hierarchy Viewer能获得当前手机实时的UI信息,给界面设计人员和自动化测试人员带来极大的便利. 在Android的官方文档中提到: To preserve security, Hierarchy Viewer can only connect to devices runnin

如何在Root的手机上开启ViewServer,使得HierachyViewer能够连接

实现原理 Hierarchy Viewer:获得当前手机实时的UI信息,方便用于手机的自动化测试: python中的subprocess.Popen():调用系统命令: uiautomator工具:获取界面控件信息: adb命令:对手机进行操作: 测试环境 1.HierarchyViewer将把下一台Android设备的4939端口映射到PC的4939端口 adb devices  查看手机设备号 adb -s 手机设备号 forward tcp:4939 tcp:4939 2.判断手机是否开启

vsftp服务器上开启防火墙后发现ftp连接不上

vsftp服务器上开启防火墙后发现ftp连接不上提示:错误: 连接超时 错误: 读取目录列表失败 状态: 正在连接 192.168.10.28:1070...状态: 连接建立,等待欢迎消息...状态: 不安全的服务器,不支持 FTP over TLS.状态: 已登录状态: 读取目录列表...命令: PWD响应: 257 "/"命令: TYPE I响应: 200 Switching to Binary mode.命令: PASV响应: 227 Entering Passive Mode

从NDK在非Root手机上的调试原理探讨Android的安全机制(转载)

从NDK在非Root手机上的调试原理探讨Android的安全机制 最近都在忙着研究Android的安全攻防技术,好长一段时间没有写博客了,准备回归老本行中--Read the funcking android source code.这两天在看NDK文档的时候,看到一句话"Native debugging ... does not require root or privileged access, aslong as your application is debuggable".咦

从NDK在非Root手机上的调试原理探讨Android的安全机制

最近都在忙着研究Android的安全攻防技术,好长一段时间没有写博客了,准备回归老本行中--Read the funcking android source code.这两天在看NDK文档的时候,看到一句话"Native debugging ... does not require root or privileged access, aslong as your application is debuggable".咦,NDK调试不就是通过ptrace来实现调试的么?在非Root的手

在安卓手机上学习C语言 - 安卓手机C/C++编译环境的搭建 : 程序世界的创建

   在安卓手机上学习C语言           安卓手机C/C++编译环境的搭建 : 程序世界的创建 在电脑上运行的QQ,手机上的QQ都是程序, 这些通电就能用的神奇玩意, 如果我说它们都是程序员用一个一个英文字母,数字,奇奇怪怪的符号创造出来的,我想那些没有任何概念的朋友可能会感到惊讶. 是的, 在没有揭开程序世界的神秘面纱之前, 一切都是那么神奇. 实际上, 程序确实是用一个一个英文字母(或者说拼音字母...)来写出来的, 就和写小说一样写出来的. 但是并不是写完之后把写出来的内容保存到一

昨天晚上被 Android 手机上的广告程序折磨了

也不是知道是哪个程序中的广告,被按下了(可能是一个视频播放软件),导致广告软件被安装到手机上. 然后,广告栏就一直显示,包括系统的主菜单界面和其它应用程序界面.这个广告栏的关闭按键是有,但太小!想关它,很容易就点击了广告,不是下载安装软件.就是弹出广告页面. 烦...... 我也不想去追究是怎么被安装的,现在只想怎么能卸载掉它! 先试着安装了腾讯的手机管家,不行! 上网去查找,有一个方法我觉得可以一试.就是使用 LBE 安全大师,先设置为任何软件上网都必须经过允许.这样,广告软件访问网络时不就知

cocos2dx 遮罩层 android 手机上 失败

1.CCClippingNode使用(在模拟器上ok,在手机上不行),实现多个剪切区域 local layer=CCLayerColor:create(ccc4(0,0,0,110)) --/*创建剪裁节点*/ local pClip=CCClippingNode:create() pClip:setInverted(true)--;//设置是否反向,将决定画出来的圆是透明的还是黑色的 pClip:setAlphaThreshold(0.0) self:addChild(pClip) --/*注

在Android手机上安装Git服务器

[安装环境]? ? ? ?手机端:Android 2.3以上版本? ? ? ?电脑端:Ubuntu 16.04 64位桌面版?[安装前准备]? ? ? ?下载好手机上的Git服务器软件:gidder.源代码地址是:gidder源代码,看上去是Android Studio的项目,会用的朋友可以从这里下载编译.直接下载安装包,可在百度网盘下载地址:gidder安装包.这里向代码作者antoniy和CSDN上的TaylorPotter致谢.?[安装设置步骤]? ? ? ?1.在手机上安装gidder.