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编辑
,原因: