让友商电脑兼容了一下华为系专属的多屏协同功能
笔者注:文中出现的大写C
,请轻声念出北京大爷的口头禅。
更新:目前可以完美支持美版华为电脑使用Huawei Share、一碰传等。
华为刚发布多屏协同功能的时候,我就被种草了。
后来一天在微博看到@Navis-MDT发布的一个体验视频,果然碉堡了。
华为多频协同体验视频
瞬间有点想从“米boy”转为“花粉”用户,这...当然是不可能的了。
翻看微博回复,看到华为手机副总裁@李小龙Bruce_Lee也转发了该视频,并回复网友“为啥不面向非华为电脑”说:“不是故意不做其他品牌的电脑,是电脑上WIFI/蓝牙硬件和驱动太乱了,我们没精力搞定兼容性问题。大神们想破解我们也不会拦着。”
对啊,怎么忘了自己也是“大神”啊(羞涩~~)。
既然主人家都不反对,那我帮他们兼容一下,脑子开始发热,迅速准备搞一搞。
是的,脑子非常热,导致前期资讯准备不足,后面踩了很多坑。
下面且听我一一道来。
1
视频中提到华为电脑中需要使用“电脑管家”(视频中没看清界面),然后手机扫描连接即可。
听到“电脑管家”第一反应就是华为多屏协同怎么还跟腾讯合作?懵逼,腾讯NB。
后来一想不对,应该是华为自己的软件“电脑管家”,类似于小米笔记本上的“小米游戏盒子”之类的软件。
没有华为电脑,先去搜搜看是否能下载到软件。
果然有,华为官网很友好的给出了操作提示,果然是为客户着想的好公司。
版本挺多,下一个最新的。然后我选择了9.1.6.33
,因为我看到日期是2019-11-01
。(请仔细看图,并记住这里)
2
OK,软件下回来了,接着就开始干正事了。
习惯性地把软件拉入了虚拟机运行,结果双击后没反应,以为是鼠标出问题或者虚拟机太卡,连续试了好几次依然没反应。
一瞬间,脑子里翻江倒海,难道华为加了反虚拟机、反调试、反...C
直接上windbg吧,一运行,直接退出,才发现是乌龙。
因为这两天在测试DLL劫持,留了个DLL在桌面,华为的“电脑管家”很不幸中枪了,被劫持,然后直接退出。(划重点)
删掉DLL,终于有了反应,但是...提示只支持64位系统,而我用的是Win7 x86...C
换呗,还能咋办,切到Win7 x64虚拟机,问题又来了。
好吧,我错了,我直接本机win10安装吧,一分钟不到,终于装好了。
但是从下载到装好时间已经过去了30分钟,都是自己作的。
3
点击立即体验,看看界面长啥样。
结果又退出了,退出了...出了...了
咋回事?难道是直接验证到不是华为电脑,直接退出?
继续windbg启动软件,看到如下信息:
Util!HttpUtil::OnDebug+0x13f8:
00007fff`0aa7a2c8 cc int 3
0:000> kv
# Child-SP RetAddr : Args to Child : Call Site
00 00000042`558fed10 00007fff`0aa78d2f : 00000219`596f44a0 00000042`558ff339 00000042`558ff2f4 00000042`558ff2f4 : Util!HttpUtil::OnDebug+0x13f8
01 00000042`558fee30 00007fff`0ab05616 : 00000042`558fefe0 00000219`596f44a0 00007fff`0aa60000 00000219`59660000 : Util!mba::util::UrlsManager::ParseXml+0x63f
02 00000042`558fee70 00007fff`0ab04879 : 00000000`00000006 00000000`00000006 00000042`558ff2f4 00000042`558ff339 : Util!CWMI::GetOutPutUIntByString+0x3bb6
03 00000042`558ff1b0 00007fff`0ab04af2 : 00000000`00000000 00000000`00000000 00000042`558ff3c0 00000000`00000000 : Util!CWMI::GetOutPutUIntByString+0x2e19
04 00000042`558ff2d0 00007fff`0aaf53df : 00000000`00000000 7fffffff`ffffffff 00000000`00000000 00000000`00000000 : Util!CWMI::GetOutPutUIntByString+0x3092
05 00000042`558ff3a0 00007ff6`fa838ff3 : 7fffffff`ffffffff 00000000`00000000 7fffffff`ffffffff 00000000`00000000 : Util!SMBIOSHelper::IsSupportDevice+0x1f
06 00000042`558ff400 00007ff6`fa852223 : 00000000`00000000 00000000`0000000a 00000000`00000000 00000000`00000000 : PCManager!SMBIOSHelper::operator=+0xa93
07 00000042`558ffc20 00007fff`4f6f7bd4 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : PCManager!Compression::Compression+0x3b93
08 00000042`558ffc60 00007fff`5150ced1 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x14
09 00000042`558ffc90 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21
0:000> g
ntdll!NtTerminateProcess+0x14:
00007fff`5153c644 c3 ret
咋还出现int3了呢,难道这里就是检查是不是华为电脑的位置。
使用IDA开始粗略分析,进入int3的位置。一处异常,看不出什么东西。
往上回溯两层,看到很重要的信息SystemEnvironment::GetSupportMachineList
,确实很像是检查的地方。
对sub_180018D00
下断,查看参数。发现第三个参数指向一个xml配置文件路径,看名字很明显是表示支持的机器类型列表。
0:000> db 000001f0`587329b0
000001f0`587329c0 5c bb aa ce aa 5c 50 43-4d 61 6e 61 67 65 72 5f \....\PCManager_
000001f0`587329d0 53 65 74 75 70 5f 39 2e-31 2e 36 2e 33 33 5c 48 Setup_9.1.6.33\H
000001f0`587329e0 75 61 77 65 69 5c 50 43-4d 61 6e 61 67 65 72 5c uawei\PCManager\
000001f0`587329f0 5c 63 6f 6e 66 69 67 5c-4d 61 63 68 69 6e 65 54 \config\MachineT
000001f0`58732a00 79 70 65 4c 69 73 74 2e-78 6d 6c 00 ee fe ee ab ypeList.xml.....
打开一看,加密了。
那看看附近代码,应该是先解密,可以把数据dump出来。
通过IDA翻看了一下后面的函数,看到另一个特征rapidxml::parse_error::
vftable`,这是用了rapidxml开源库来解析xml文档。
把rapidxml的源码下回来,通过对比(一些log字符特征)来确认函数的功能。
基本弄清楚xml解密到解析的过程,对sub_180014EA0
下断,查看参数。果然拿到解密后的xml文件。
0:000> dq 000000315e6feb48
00000031`5e6feb48 000001ec`051970b0 00000000`00000000
0:000> db 000001ec`051970b0
000001ec`051970b0 3c 3f 78 6d 6c 20 76 65-72 73 69 6f 6e 3d 22 31 .. ...
xml数据长这样。
看到这里,其实已经有一个思路了,就是把自己电脑的品牌加入xml文件,重新加密回去,就能够就能够使用华为电脑管家了。
不过分析解密、拿品牌信息、加密等挺麻烦的,再看看还有方法吗?
比如直接patch比较品牌的函数,绕过检查。
继续分析,一堆xml的node的解析比较,因为华为在编译rapidxml时基本都是内联函数,导致跟源码结构并不是很一致,增加了分析难度。
经过一段数据的比较,还没有找到绕过的点。
我停了下来,看了看调用栈。
0:000> kv
# Child-SP RetAddr : Args to Child : Call Site
00 00000031`5e6fea20 00007fff`11184879 : 00000000`00000006 00000000`00000006 00000031`5e6feea4 00000031`5e6feee9 : Util!CWMI::GetOutPutUIntByString+0x4075
01 00000031`5e6fed60 00007fff`11184af2 : 00000000`00000000 00000000`00000000 00000031`5e6fef70 00000000`00000000 : Util!CWMI::GetOutPutUIntByString+0x2e19
02 00000031`5e6fee80 00007fff`111753df : 00000000`00000000 7fffffff`ffffffff 00000000`00000000 00000000`00000000 : Util!CWMI::GetOutPutUIntByString+0x3092
03 00000031`5e6fef50 00007ff7`70a18ff3 : 7fffffff`ffffffff 00000000`00000000 7fffffff`ffffffff 00000000`00000000 : Util!SMBIOSHelper::IsSupportDevice+0x1f
04 00000031`5e6fefb0 00007ff7`70a32223 : 00000000`00000000 00000000`0000000a 00000000`00000000 00000000`00000000 : PCManager!SMBIOSHelper::operator=+0xa93
05 00000031`5e6ff7d0 00007fff`4f6f7bd4 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : PCManager!Compression::Compression+0x3b93
06 00000031`5e6ff810 00007fff`5150ced1 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x14
07 00000031`5e6ff840 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21
才看到被我忽略的一个很重要的信息Util!SMBIOSHelper::IsSupportDevice
,这个函数名太明显了。
只需要修改这个返回值,基本应该就绕过检查了。
BOOL8 __fastcall SMBIOSHelper::IsSupportDevice(SMBIOSHelper *this)
{
return 1; //patch
}
是的,我好像又掉坑里,浪费了挺多时间。
4
但是前面为什么会出现异常呢,导致我掉进了一个确实是对的但又有点坑的位置呢。
想到xml的路径,此时我终于反应过来哪个异常可能是什么了。
因为我把软件放在了中文目录中,而软件对中文处理貌似有问题。(我没有深究了)
D:\华为\PCManager_Setup_9.1.6.33
果然,去掉中文目录后,再没有上面看到的int3。
所以,这又是个坑。C
本来正常的分析逻辑是这样的。
0:000> g
ntdll!NtTerminateProcess+0x14:
00007fff`5153c644 c3 ret
0:000> kv
# Child-SP RetAddr : Args to Child : Call Site
00 00000042`558ffb38 00007fff`5150a9b8 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!NtTerminateProcess+0x14
01 00000042`558ffb40 00007fff`4f6fcd8a : 00000000`00000000 00000000`00000000 00007fff`4ecb9b68 00000000`00000000 : ntdll!RtlExitUserProcess+0xb8
02 00000042`558ffb70 00007fff`4ec1ae38 : 00000000`00000000 00000000`00000000 00000042`558ffbf8 00007fff`4ecebc20 : KERNEL32!ExitProcessImplementation+0xa
03 00000042`558ffba0 00007fff`4ec186ef : 00000000`00000000 00000000`00000000 00000000`00000000 00000042`558ffbf0 : ucrtbase!exit_or_terminate_process+0x44
04 00000042`558ffbd0 00007ff6`fa852235 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000001 : ucrtbase!common_exit+0x6f
05 00000042`558ffc20 00007fff`4f6f7bd4 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : PCManager!Compression::Compression+0x3ba5
06 00000042`558ffc60 00007fff`5150ced1 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x14
07 00000042`558ffc90 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21
看到exit进程,回溯到调用位置,看看做了什么判断。
.text:000000014003221E call WinMain
.text:0000000140032223 mov ebx, eax
.text:0000000140032225 call __scrt_is_managed_app
.text:000000014003222A test al, al
.text:000000014003222C jnz short loc_140032235
.text:000000014003222E mov ecx, ebx ; Code
.text:0000000140032230 call exit
.text:0000000140032235 ; ---------------------------------------------------------------------------
.text:0000000140032235
.text:0000000140032235 loc_140032235: ; CODE XREF: __scrt_common_main_seh(void)+120↑j
.text:0000000140032235 test dil, dil
是在WinMain中正常退出的,所以判断就是在WinMain中。在IDA翻看一下,很容就找到了重要提示。
在往上看,正主来了。
这样简单太多了,已经不记得是第几次被中文路径坑了,又想用英文系统了。
5
把Util!SMBIOSHelper::IsSupportDevice
修正一番,替换原始的utlil.dll,直接运行软件,在华为的友商电脑中成功启动。
开始尝试连接手机。
点击我的手机->扫码连接,提示需使用华为浏览器扫描。
因为我不是华为手机,所以是不是下载一个华为浏览器就OK了呢。
一番搜索,在华为市场找到了华为浏览器的app。
兴致勃勃地装到了我的小米手机上,嗯,友商之间很友好,并没有出现什么异常情况。
打开浏览器,点开二维码扫描,扫描软件管家二维码,提示需要安装华为移动服务,ok,安装。
安装完成之后,啥也没提示,就光秃秃一个网页页面,电脑助手。
懵逼中,再次扫描,同样地情况。
脑筋一转,把链接复制发到了电脑,浏览器打开,看到了下载按钮。
第三个app了,继续把华为电脑助手安卓版装入了小米,瞬间感觉MIUI好像被华为全家桶强X了一下ε(┬┬﹏┬┬)3。
重新扫描,这次果然不一样了,浏览器跳转到了助手页面,提示配对。
这中间又出现了n多问题
(怀疑蓝牙服务不正常、二维码生成不正常、电脑管家是否对手机校验、分析是否还有check...)
不想细说了,反正经过一番折腾,终于手机和电脑连上了。
但是这也没有多屏协同啊,就一个手机助手啊。
难道我哪里又弄错了?
去搜了搜多屏协同的帖子,算是找到了问题。
TMD,原来下载的软件版本低了,而我还眼瞎地没看到上面的下载列表的10.0.2.59版本。
真是被自己蠢哭了。
下载最新版,重新修正了util.dll,这次连上果然不一样了。
但是,最终还是没能用上多屏协同,尽管我已经安装了3个华为的app,但就是手机不支持(EMUI系统功能)。
看到这些条件,我真是感到心累,“这是对冲动最好的惩罚”。
6
是的,虽然折腾了这么久,最后也没用上这个牛逼的功能,但是我很充实(哭)。
因为我为其他拥有华为手机但没有华为电脑然后想体验华为多屏协同功能的大伙做出了我的贡献。
我满足了。
哎,卑微的我去咸鱼看看二手的华为手机,或者去问问华为EMUI适配不适配友商的手机了。
或者哪位大佬有换代的华为手机邮我一个,地址是:XXXX。
哎,曾经的我没钱买华为,现在的我依然没钱买华为。
申明:虽然华为手机副总裁已经说过不反对破解,但这里还是郑重申明,文章仅仅是做技术研究,如侵删,谢谢。
最后,小声地说,如果想体验的朋友,请到https://github.com/anhkgg/Huawei_PCManager_NB下载试用,务必阅后即焚。