首页
社区
课程
招聘
[原创]修补微信Windows隐藏的深色模式
发表于: 2024-7-21 02:04 9477

[原创]修补微信Windows隐藏的深色模式

2024-7-21 02:04
9477

macOS版本的微信在2021年已经支持深色模式
图片描述
Windows版本的微信到2024年还没有深色模式
看到下面链接说到:眼睛畏光的低视力人一直在反馈
期盼尽快更新Windows版本(PC版本)微信深色模式(暗色、黑暗、暗夜、黑夜模式)
试着用逆向去实现Windows版本的微信也支持深色模式
发现微信其实隐藏了深色模式,可惜不完善,修补之后效果如下
图片描述

先试着用IDA搜素深色模式的关键词dark
发现确实有深色模式:'weui\theme\dark\theme.xml'
图片描述
交叉索引一下引用字符串的地方

再看下sub_1F35D30调用的地方
dword_32C5500便是深色模式的资源路径

再看下sub_1F35D00调用的地方
可以看出byte_32B5474控制是否用深色模式

交叉索引byte_32B5474,有两个地方写入byte_32B5474

在X86dbg上修改一下汇编

修改之后还是浅色模式
但个人名片从白色是黑色
说明深色模式有效且不完善
图片描述

为了了解为什么深色模式不完善
需要梳理一下深色模式的底层原理

1、微信里面有两个主题模式

2、不同主题模式的颜色配置文件不同

3、同id不同主题模式下,具体值不同

4、界面的属性值改为从固定值变成变量值

可以看出微信的底层已经有一套更换模式的基建
而深色模式之所以不完善是因为深色资源文件不完整

如果要完善深色模式,就需要修改界面资源
先了解一下原生Duilib生成界面的流程

1、界面生成从OnCreate开始

2、builder.Create加载界面资源

3、最后是解析界面资源的内容

根据这个流程,就可以定位微信Duilib对应的函数

1、搜索关键词"linkhoverfontcolor"

2、再查看sub_1EDDBE0的引用

3、sub_1F20210就是CMarkup::LoadFromMem
把界面资源的路径(wcXMLPath)变成界面资源的内容(wcXMLData )

用Frida的js脚本拦截修改(需要修改很多地方),就可以实现深色模式

图片描述

修改资源的属性,发现了一个问题:编辑框的文字属性修改无效
原本是是白色背景加黑色字体,现在是黑色背景加黑色字体,看不清
这就意味着:控件的属性,不是完全依赖界面资源,还需要修改业务代码

1、修改字体颜色的接口是SetAttribute

注入DLL调用SetAttribute确实能改变字体颜色
但再编辑编辑框RichEdit的文本,颜色又变成黑色

2、修改字体颜色的另一接口是SetSelectionCharFormat

X86dbg对TxSendMessage下条件断点并打印参数
图片描述
发现编辑文本的时候调用了GetSelectionCharFormat

添加暂停条件:[esp+4]==0x43A
看下哪里调用GetSelectionCharFormat
图片描述

发现确实调用了SetSelectionCharFormat

再看下调用sub_1F02FA0的地方
发现微信在代码上直接写死成黑色

再看下调用sub_9FF580的上级函数
发现确实是有更新的时候修改字体颜色

简单的绕过方法就是修改一个字节:0x400改变成0x401

图片描述

int sub_1F35D30()
    sub_1F33C40(dword_32C5500, L"weui\\theme\\dark\\theme.xml");
    sub_1F33C40(dword_32C54F4, L"Theme\\dark\\theme_dark.xml");
int sub_1F35D30()
    sub_1F33C40(dword_32C5500, L"weui\\theme\\dark\\theme.xml");
    sub_1F33C40(dword_32C54F4, L"Theme\\dark\\theme_dark.xml");
int sub_1F35D00()
    if ( !dword_32C5500 ) sub_1F35D30();
    return dword_32C5500;
int sub_1F35D00()
    if ( !dword_32C5500 ) sub_1F35D30();
    return dword_32C5500;
int __thiscall sub_1EF62E0(_DWORD *this)
    if ( byte_32B5474 ) sub_1F35D00();
    else sub_1F35CF0();
int __thiscall sub_1EF62E0(_DWORD *this)
    if ( byte_32B5474 ) sub_1F35D00();
    else sub_1F35CF0();
01EBC2ED 8A47 61            mov al, [edi+61h]
01EBC2F2 A2 74542B03        mov byte_32B5474, al
 
01EBCCE3 C605 74542B03 00   mov byte_32B5474, 0
01EBC2ED 8A47 61            mov al, [edi+61h]
01EBC2F2 A2 74542B03        mov byte_32B5474, al
 
01EBCCE3 C605 74542B03 00   mov byte_32B5474, 0
7A47C2ED | B0 01                | mov al,1                                 |
7A47C2EF | 90                   | nop                                      |
 
7A47CCE3 | C605 7454877B 01     | mov byte ptr ds:[7B875474],1 
7A47C2ED | B0 01                | mov al,1                                 |
7A47C2EF | 90                   | nop                                      |
 
7A47CCE3 | C605 7454877B 01     | mov byte ptr ds:[7B875474],1 
浅色:theme\default\theme.xml
 
深色:theme\dark\theme.xml
浅色:theme\default\theme.xml
 
深色:theme\dark\theme.xml
浅色:theme\default\theme.xml
<!-- color -->
<IncludeTheme source="weui/Theme/default/colors.xml" />
 
深色:theme\dark\theme.xml
<!-- color -->
<IncludeTheme source="weui/Theme/dark/colors.xml" />
浅色:theme\default\theme.xml
<!-- color -->
<IncludeTheme source="weui/Theme/default/colors.xml" />
 
深色:theme\dark\theme.xml
<!-- color -->
<IncludeTheme source="weui/Theme/dark/colors.xml" />
浅色: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" /> // 深色模式的文字比较浅
浅色: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" /> // 深色模式的文字比较浅
textcolor="#FF000000"
改成
textcolor="@color:Text_1"
textcolor="#FF000000"
改成
textcolor="@color:Text_1"
theme\default\colors.xml    5150 字节
theme\dark\colors.xml       4370 字节
theme\default\colors.xml    5150 字节
theme\dark\colors.xml       4370 字节
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);
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);
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 );
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 );
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"
CControlUI* CDialogBuilder::Create(IDialogBuilderCallback* pCallback, CPaintManagerUI* pManager, CControlUI* pParent)
    CMarkupNode root = m_xml.GetRoot();

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2024-7-21 11:34 被GhHei编辑 ,原因:
收藏
免费 6
支持
分享
最新回复 (4)
雪    币: 10960
活跃值: (2920)
能力值: ( LV5,RANK:71 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2024-7-23 20:49
0
雪    币: 761
活跃值: (628)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
学习了。可以根据这个来弄一个从外部加载的主题。
2024-7-24 14:32
0
雪    币: 13
活跃值: (59)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
可以搞个sandboxies插件,把微信跑沙箱里面,顺便就把主题改了 
2024-8-1 09:03
1
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
老哥这个深色要怎么搞,有打包好的吗,还是有插件吗
2024-8-13 18:18
0
游客
登录 | 注册 方可回帖
返回
//