首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
逆向工程
发新帖
11
6
[原创]修补微信Windows隐藏的深色模式
发表于: 2024-7-21 02:04
17535
[原创]修补微信Windows隐藏的深色模式
GhHei
1
2024-7-21 02:04
17535
# 用逆向做点正向 macOS版本的微信在2021年已经支持深色模式  Windows版本的微信到2024年还没有深色模式 看到下面链接说到:眼睛畏光的低视力人一直在反馈 <a href="elink@fd4K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0K6i4K6u0W2N6$3g2A6P5r3W2F1i4K6u0W2M7i4q4Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3#2E0N6h3&6A6N6s2W2Q4x3V1k6V1k6i4k6W2L8r3!0H3i4K6u0r3j5i4u0@1K9h3y4D9k6g2)9J5c8X3c8G2j5#2)9J5c8U0l9H3x3o6R3J5j5h3g2S2k6U0m8U0j5e0b7H3x3o6W2T1y4U0t1H3k6h3x3K6y4$3f1$3j5U0R3I4x3H3`.`.">期盼尽快更新Windows版本(PC版本)微信深色模式(暗色、黑暗、暗夜、黑夜模式)</a> 试着用逆向去实现Windows版本的微信也支持深色模式 发现微信其实隐藏了深色模式,可惜不完善,修补之后效果如下  --- # 隐藏的深色模式 先试着用IDA搜素深色模式的关键词dark 发现确实有深色模式:'weui\theme\dark\theme.xml'  交叉索引一下引用字符串的地方 ```c++ int sub_1F35D30() sub_1F33C40(dword_32C5500, L"weui\\theme\\dark\\theme.xml"); sub_1F33C40(dword_32C54F4, L"Theme\\dark\\theme_dark.xml"); ``` 再看下sub_1F35D30调用的地方 dword_32C5500便是深色模式的资源路径 ```c++ int sub_1F35D00() if ( !dword_32C5500 ) sub_1F35D30(); return dword_32C5500; ``` 再看下sub_1F35D00调用的地方 可以看出byte_32B5474控制是否用深色模式 ```c++ int __thiscall sub_1EF62E0(_DWORD *this) if ( byte_32B5474 ) sub_1F35D00(); else sub_1F35CF0(); ``` 交叉索引byte_32B5474,有两个地方写入byte_32B5474 ```c++ 01EBC2ED 8A47 61 mov al, [edi+61h] 01EBC2F2 A2 74542B03 mov byte_32B5474, al 01EBCCE3 C605 74542B03 00 mov byte_32B5474, 0 ``` 在X86dbg上修改一下汇编 ```c++ 7A47C2ED | B0 01 | mov al,1 | 7A47C2EF | 90 | nop | 7A47CCE3 | C605 7454877B 01 | mov byte ptr ds:[7B875474],1 ``` 修改之后还是浅色模式 但个人名片从白色是黑色 说明深色模式有效且不完善  --- # 深色模式的原理 为了了解为什么深色模式不完善 需要梳理一下深色模式的底层原理 1、微信里面有两个主题模式 ```c++ 浅色:theme\default\theme.xml 深色:theme\dark\theme.xml ``` 2、不同主题模式的颜色配置文件不同 ```c++ 浅色:theme\default\theme.xml <!-- color --> <IncludeTheme source="weui/Theme/default/colors.xml" /> 深色:theme\dark\theme.xml <!-- color --> <IncludeTheme source="weui/Theme/dark/colors.xml" /> ``` 3、同id不同主题模式下,具体值不同 ```c++ 浅色:theme\default\theme.xml <!-- color --> <IncludeTheme source="weui/Theme/default/colors.xml" /> <!-- 文字颜色 --> <Color id="Text_1" opacity="1" color="#161616" /> // 浅色模式的文字比较深 深色:theme\dark\theme.xml <!-- color --> <IncludeTheme source="weui/Theme/dark/colors.xml" /> <!-- 文字颜色 --> <Color id="Text_1" opacity="1" color="#F7F7F7" /> // 深色模式的文字比较浅 ``` 4、界面的属性值改为从固定值变成变量值 ```c++ textcolor="#FF000000" 改成 textcolor="@color:Text_1" ``` 可以看出微信的底层已经有一套更换模式的基建 而深色模式之所以不完善是因为深色资源文件不完整 ```plain theme\default\colors.xml 5150 字节 theme\dark\colors.xml 4370 字节 ``` --- # 修改界面的资源 如果要完善深色模式,就需要修改界面资源 先了解一下原生Duilib生成界面的流程 1、界面生成从OnCreate开始 ```c++ LRESULT WindowImplBase::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) switch (GetResourceType()) case UILIB_ZIP: m_pm.SetResourceZip(GetZIPFileName().GetData(), true); CControlUI* pRoot = builder.Create(xml, _T("xml"), this, &m_pm); ``` 2、builder.Create加载界面资源 ```c++ CControlUI* CDialogBuilder::Create(STRINGorID xml, LPCTSTR type, IDialogBuilderCallback* pCallback, CPaintManagerUI* pManager, CControlUI* pParent) if( !m_xml.Load(xml.m_lpstr) ) return NULL; if( !m_xml.LoadFromFile(xml.m_lpstr) ) return NULL; if( !m_xml.LoadFromMem((BYTE*)::LockResource(hGlobal), ::SizeofResource(dll_instence, hResource) )) return NULL; return Create(pCallback, pManager, pParent); bool CMarkup::LoadFromMem(BYTE* pByte, DWORD dwSize, int encoding) DWORD nWide = ::MultiByteToWideChar( CP_UTF8, 0, (LPCSTR)pByte, dwSize, NULL, 0 ); ::MultiByteToWideChar( CP_UTF8, 0, (LPCSTR)pByte, dwSize, m_pstrXML, nWide ); ``` 3、最后是解析界面资源的内容 ```c++ CControlUI* CDialogBuilder::Create(IDialogBuilderCallback* pCallback, CPaintManagerUI* pManager, CControlUI* pParent) CMarkupNode root = m_xml.GetRoot(); for( CMarkupNode node = root.GetChild() ; node.IsValid(); node = node.GetSibling() ) "linkhoverfontcolor" ``` 根据这个流程,就可以定位微信Duilib对应的函数 1、搜索关键词"linkhoverfontcolor" ```c++ int __thiscall sub_1EDDBE0(_DWORD *this, int pCallback, int pManager, int pParent) "linkhoverfontcolor" ``` 2、再查看sub_1EDDBE0的引用 ```c++ int __thiscall sub_1EDDB80(_DWORD *this, wchar_t *Source, int a3, int a4, int a5, int a6) wcXMLData = sub_1F20210(wcXMLPath, 1); if ( wcXMLData && sub_1EE0BE0(this, *(wcXMLData + 0x2000), *(wcXMLData + 0x2004), v8) ) return sub_1EDDBE0(this, a4, a5, a6); ``` 3、sub_1F20210就是CMarkup::LoadFromMem 把界面资源的路径(wcXMLPath)变成界面资源的内容(wcXMLData ) ```c++ char __thiscall sub_1EE0BE0(WCHAR **this, LPCCH lpMultiByteStr, unsigned int cbMultiByte, int a4) v6 = MultiByteToWideChar(65001u, 0, v5, v4, 0, 0);// CP_UTF8 MultiByteToWideChar(65001u, 0, v5, cbMultiByte, v7, v6); ``` 用Frida的js脚本拦截修改(需要修改很多地方),就可以实现深色模式 ```c++ const targetFunctionAddress = WeChatWin.add(0x1F20210); Interceptor.attach(targetFunctionAddress, ... ModifyAttribute(this.wsXMLDataArray, '', 'bkcolor', '#FF000000'); ```  --- # 修改业务的代码 修改资源的属性,发现了一个问题:编辑框的文字属性修改无效 原本是是白色背景加黑色字体,现在是黑色背景加黑色字体,看不清 这就意味着:控件的属性,不是完全依赖界面资源,还需要修改业务代码 1、修改字体颜色的接口是SetAttribute ```c++ void CRichEditUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) if( _tcscmp(pstrName, _T("textcolor")) == 0 ) if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue); DWORD clrColor = _tcstoul(pstrValue, &pstr, 16); SetTextColor(clrColor); void CRichEditUI::SetTextColor(DWORD dwTextColor) m_pTwh->SetColor(dwTextColor); void CTxtWinHost::SetColor(DWORD dwColor) cf.crTextColor = RGB(GetBValue(dwColor), GetGValue(dwColor), GetRValue(dwColor)); pserv->OnTxPropertyBitsChange(TXTBIT_CHARFORMATCHANGE, TXTBIT_CHARFORMATCHANGE); ``` 注入DLL调用SetAttribute确实能改变字体颜色 但再编辑编辑框RichEdit的文本,颜色又变成黑色 ```c++ DWORD pControl = 0x15a72bb8; const wchar_t* wcAttr = L"textcolor"; const wchar_t* wcValue = L"#FFFFFFFF"; // 白色 SetAttribute(pControl, wcAttr, wcValue); ``` 2、修改字体颜色的另一接口是SetSelectionCharFormat ```c++ #define WM_USER 0x0400 #define EM_GETCHARFORMAT (WM_USER + 58) // 0x43A #define EM_SETCHARFORMAT (WM_USER + 68) // 0x444 #define SCF_SELECTION 0x0001 DWORD CRichEditUI::GetSelectionCharFormat(CHARFORMAT2 &cf) const cf.cbSize = sizeof(CHARFORMAT2); TxSendMessage(EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf, &lResult); bool CRichEditUI::SetSelectionCharFormat(CHARFORMAT2 &cf) cf.cbSize = sizeof(CHARFORMAT2); TxSendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf, &lResult); HRESULT CRichEditUI::TxSendMessage(UINT msg, WPARAM wparam, LPARAM lparam, LRESULT *plresult) const return m_pTwh->GetTextServices()->TxSendMessage(msg, wparam, lparam, plresult); ``` X86dbg对TxSendMessage下条件断点并打印参数  发现编辑文本的时候调用了GetSelectionCharFormat ```c++ #define EM_GETCHARFORMAT (WM_USER + 58) // 0x43A CRichEditUI::TxSendMessage this=15AA51E0 msg=43A wparam=1 ``` 添加暂停条件:[esp+4]==0x43A 看下哪里调用GetSelectionCharFormat  发现确实调用了SetSelectionCharFormat ```c++ #define EM_GETCHARFORMAT (WM_USER + 58) 0x43A #define EM_SETCHARFORMAT (WM_USER + 68) 0x444 #define SCF_SELECTION 0x0001 int __thiscall sub_1F02FA0(int *this, _DWORD *pColor, int dwBegin, int dwEnd) // GetSelectionCharFormat (*(*this + 724))(this, 0x43A, 1, pcf, v10); // SetSelectionCharFormat (*(*this + 724))(this, 0x444, 1, pcfNew, v10); ``` 再看下调用sub_1F02FA0的地方 发现微信在代码上直接写死成黑色 ```c++ void __thiscall sub_9FF580(int *this) NewColor(pColor, 0xFF000000); // 写死黑色 sub_1F02FA0(this, pColor, 0, TextLength); ``` 再看下调用sub_9FF580的上级函数 发现确实是有更新的时候修改字体颜色 ```c++ void __thiscall sub_01F03D70(char *this, unsigned int iNotify, int a3) // #define EN_UPDATE 0x0400 if ( iNotify == 0x400 ) //GetManager()->SendNotify(this, DUI_MSGTYPE_TEXTCHANGED); sub_1EC0390(*(this + 22), this, L"textchanged", 0, 0, this[3820]); (*(*this + 740))(this); // sub_9FF580 ``` 简单的绕过方法就是修改一个字节:0x400改变成0x401 ```c++ 7A4C3DBE | 81FB 00040000 | cmp ebx,400 | 改成 7A4C3DBE | 81FB 01040000 | cmp ebx,401 ``` 
登录后可查看完整内容
传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!
最后于
2024-7-21 11:34 被GhHei编辑 ,原因:
#调试逆向
收藏
・
11
点赞
・
6
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
PLEBFE
感谢你的贡献,论坛因你而更加精彩!
2024-9-4 03:31
青眼白龙
感谢你的贡献,论坛因你而更加精彩!
2024-8-13 19:46
sonyps
为你点赞~
2024-8-1 09:21
mb_shzsxtje
你的分享对大家帮助很大,非常感谢!
2024-7-24 13:16
mb_uailolfl
感谢你的贡献,论坛因你而更加精彩!
2024-7-23 21:15
joker陈
感谢你分享这么好的资源!
2024-7-23 20:49
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
5
)
joker陈
雪 币:
12258
活跃值:
(4415)
能力值:
( LV5,RANK:71 )
在线值:
发帖
19
回帖
368
粉丝
4
关注
私信
joker陈
2
楼
感谢分享
2024-7-23 20:49
0
我想你了
雪 币:
785
活跃值:
(761)
能力值:
( LV2,RANK:10 )
在线值:
发帖
0
回帖
33
粉丝
3
关注
私信
我想你了
3
楼
学习了。可以根据这个来弄一个从外部加载的主题。
2024-7-24 14:32
0
小桃红
雪 币:
13
活跃值:
(135)
能力值:
( LV2,RANK:10 )
在线值:
发帖
15
回帖
86
粉丝
2
关注
私信
小桃红
4
楼
可以搞个sandboxies插件,把微信跑沙箱里面,顺便就把主题改了
2024-8-1 09:03
1
mb_khfykbqu
雪 币:
0
能力值:
( LV1,RANK:0 )
在线值:
发帖
0
回帖
1
粉丝
0
关注
私信
mb_khfykbqu
5
楼
老哥这个深色要怎么搞,有打包好的吗,还是有插件吗
2024-8-13 18:18
0
mb_cizqyhuh
雪 币:
2
能力值:
( LV1,RANK:0 )
在线值:
发帖
0
回帖
81
粉丝
1
关注
私信
mb_cizqyhuh
6
楼
这个发现真巧妙!原来微信底层自带完整的深色模式框架,只需修改变量byte_32B5474就能激活。详细的实现原理我整理成了
思维导图
。
2025-11-4 15:41
0
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
GhHei
1
15
发帖
34
回帖
100
RANK
关注
私信
他的文章
[原创]企业微信隐藏的配置:屏蔽AI+IM窗口
3991
[原创]Android-SO复杂VMP的分析思路
12973
[原创]微信版本检测新漏洞分析
21676
[原创]企业微信对远程控制的检测和绕过
29037
[原创]企业微信Duilib奇怪的RecyclerView
4795
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部