关于 Windows 任务栏透明原理的探索

概述

Windows 10 的任务栏非常简约,扁平的半透明阴影,但是却没有提供原生的设置透明度的方式,为了实现这个功能已经有了如 TranslucentTB 这类优秀的软件。但笔者依然对其原理有些好奇。本来打算看 TranslucentTB 的源码,无奈看起来费劲,先看看能不能蒙出来。

目前进度如下:

  • 修改注册表键值(需重启 explorer.exe)
  • 直接修改 explorer.exe 的内存(进行中)
  • 反汇编时发现的一个未公开的 Win32 API

注册表键值

通过查阅资料发现透明度可以通过修改注册表键值实现。

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced下的TaskbarAcrylicOpacity键,类型是DWORD,默认不存在。取值范围$[0,255]$,表示透明度。

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced下的UseOLEDTaskbarTransparency键,如果存在则修改为 0,或者删除。

修改完成后重启 explorer.exe 即可看到效果。

直接修改 explorer.exe 的内存(进行中)

TaskbarAcrylicOpacity设置为 200。


使用 CE 搜索这个值,发现透明度存储在explorer.exe + 0x30E9D0,修改后可立即生效。


explorer.exe + 0x30E9D0下访问断点后动态调式,发现入口为explorer.exe + 0x76424的函数读取了这个代表透明度的值。

explorer.exe+76424 - 40 53                 - push rbx
explorer.exe+76426 - 48 83 EC 20           - sub rsp,20 { 32 }
explorer.exe+7642A - 80 3D 7B832900 00     - cmp byte ptr [explorer.exe+30E7AC],00 { (1),0 }
explorer.exe+76431 - 8B D9                 - mov ebx,ecx
explorer.exe+76433 - 74 0C                 - je explorer.exe+76441
explorer.exe+76435 - 8A 05 95852900        - mov al,[explorer.exe+30E9D0] { (200) }
explorer.exe+7643B - 48 83 C4 20           - add rsp,20 { 32 }
explorer.exe+7643F - 5B                    - pop rbx
explorer.exe+76440 - C3                    - ret 

通过 callstack 发现入口为explorer.exe + 0x7629C的函数调用了上文提到的入口为explorer.exe + 0x76424的函数,并且读取了UseOLEDTaskbarTransparency键。

explorer.exe+7629C - 40 55                 - push rbp
explorer.exe+7629E - 53                    - push rbx
explorer.exe+7629F - 57                    - push rdi
explorer.exe+762A0 - 48 8B EC              - mov rbp,rsp
explorer.exe+762A3 - 48 83 EC 40           - sub rsp,40 { 64 }
explorer.exe+762A7 - 48 8D 55 20           - lea rdx,[rbp+20]
explorer.exe+762AB - 48 8D 4D 38           - lea rcx,[rbp+38]
explorer.exe+762AF - E8 1C070000           - call explorer.exe+769D0
explorer.exe+762B4 - 33 FF                 - xor edi,edi
explorer.exe+762B6 - B0 FF                 - mov al,-01 { 255 }
explorer.exe+762B8 - 40 38 7D 20           - cmp [rbp+20],dil
explorer.exe+762BC - 0F84 93000000         - je explorer.exe+76355
explorer.exe+762C2 - 48 8D 45 30           - lea rax,[rbp+30]
explorer.exe+762C6 - 89 7D 28              - mov [rbp+28],edi
explorer.exe+762C9 - 48 89 44 24 30        - mov [rsp+30],rax
explorer.exe+762CE - 4C 8D 05 8BC32100     - lea r8,[explorer.exe+292660] { ("UseOLEDTaskbarTransparency") }
explorer.exe+762D5 - 48 8D 45 20           - lea rax,[rbp+20]
explorer.exe+762D9 - C7 45 30 04000000     - mov [rbp+30],00000004 { 4 }
explorer.exe+762E0 - 48 89 44 24 28        - mov [rsp+28],rax
explorer.exe+762E5 - 48 8D 15 D4C22100     - lea rdx,[explorer.exe+2925C0] { ("SOFTWARE\Microsoft\Windows\Curr") }
explorer.exe+762EC - 48 8D 45 28           - lea rax,[rbp+28]
explorer.exe+762F0 - 41 B9 12000010        - mov r9d,10000012 { 268435474 }
explorer.exe+762F6 - 48 C7 C1 02000080     - mov rcx,FFFFFFFF80000002 { -2147483646 }
explorer.exe+762FD - 48 89 44 24 20        - mov [rsp+20],rax
explorer.exe+76302 - 48 FF 15 A7002100     - call qword ptr [explorer.exe+2863B0] { ->KERNELBASE.RegGetValueW }
explorer.exe+76309 - 0F1F 44 00 00         - nop dword ptr [rax+rax+00]
explorer.exe+7630E - 8D 4F 0D              - lea ecx,[rdi+0D]
explorer.exe+76311 - 85 C0                 - test eax,eax
explorer.exe+76313 - 74 48                 - je explorer.exe+7635D
explorer.exe+76315 - 3D EA000000           - cmp eax,000000EA { 234 }
explorer.exe+7631A - 0F44 C1               - cmove eax,ecx
explorer.exe+7631D - 8B C8                 - mov ecx,eax
explorer.exe+7631F - 85 C0                 - test eax,eax
explorer.exe+76321 - 7E 09                 - jle explorer.exe+7632C
explorer.exe+76323 - 0FB7 C9               - movzx ecx,cx
explorer.exe+76326 - 81 C9 00000780        - or ecx,80070000 { -2147024896 }
explorer.exe+7632C - 8B 45 20              - mov eax,[rbp+20]
explorer.exe+7632F - 85 C9                 - test ecx,ecx
explorer.exe+76331 - 0FB6 D8               - movzx ebx,al
explorer.exe+76334 - 0F48 DF               - cmovs ebx,edi
explorer.exe+76337 - E8 58010000           - call explorer.exe+76494
explorer.exe+7633C - 84 C0                 - test al,al
explorer.exe+7633E - 74 3A                 - je explorer.exe+7637A
explorer.exe+76340 - 8B 4D 38              - mov ecx,[rbp+38]
explorer.exe+76343 - E8 DC000000           - call explorer.exe+76424
explorer.exe+76348 - 84 DB                 - test bl,bl
explorer.exe+7634A - 0FB6 C0               - movzx eax,al
explorer.exe+7634D - B9 99000000           - mov ecx,00000099 { 153 }
explorer.exe+76352 - 0F45 C1               - cmovne eax,ecx
explorer.exe+76355 - 48 83 C4 40           - add rsp,40 { 64 }
explorer.exe+76359 - 5F                    - pop rdi
explorer.exe+7635A - 5B                    - pop rbx
explorer.exe+7635B - 5D                    - pop rbp

通过 callstack 发现入口为explorer.exe + 0x761D4的函数调用了上文提到的入口为explorer.exe + 0x7629C的函数,并且调用了一个 Win32 API:SetWindowCompositionAttribute。通过查阅资料发现这是一个未公开的 API。

explorer.exe+761D4 - 48 89 5C 24 10        - mov [rsp+10],rbx
explorer.exe+761D9 - 48 89 74 24 18        - mov [rsp+18],rsi
explorer.exe+761DE - 57                    - push rdi
explorer.exe+761DF - 48 83 EC 60           - sub rsp,60 { 96 }
explorer.exe+761E3 - 48 8B 05 7E522900     - mov rax,[explorer.exe+30B468] { (2.66) }
explorer.exe+761EA - 48 33 C4              - xor rax,rsp
explorer.exe+761ED - 48 89 44 24 50        - mov [rsp+50],rax
explorer.exe+761F2 - 48 8B F1              - mov rsi,rcx
explorer.exe+761F5 - 48 8D 54 24 20        - lea rdx,[rsp+20]
explorer.exe+761FA - 33 C9                 - xor ecx,ecx
explorer.exe+761FC - E8 CF070000           - call explorer.exe+769D0
explorer.exe+76201 - 80 7C 24 20 00        - cmp byte ptr [rsp+20],00 { 0 }
explorer.exe+76206 - BF 01000000           - mov edi,00000001 { 1 }
explorer.exe+7620B - 74 0F                 - je explorer.exe+7621C
explorer.exe+7620D - E8 82020000           - call explorer.exe+76494
explorer.exe+76212 - F6 D8                 - neg al
explorer.exe+76214 - 1B FF                 - sbb edi,edi
explorer.exe+76216 - 83 E7 02              - and edi,02 { 2 }
explorer.exe+76219 - 83 C7 02              - add edi,02 { 2 }
explorer.exe+7621C - E8 7B000000           - call explorer.exe+7629C
explorer.exe+76221 - 0FB6 D8               - movzx ebx,al
explorer.exe+76224 - E8 0B050000           - call explorer.exe+76734
explorer.exe+76229 - 83 64 24 4C 00        - and dword ptr [rsp+4C],00 { 0 }
explorer.exe+7622E - 25 FFFFFF00           - and eax,00FFFFFF { 16777215 }
explorer.exe+76233 - 8B D3                 - mov edx,ebx
explorer.exe+76235 - 89 7C 24 40           - mov [rsp+40],edi
explorer.exe+76239 - C1 E2 18              - shl edx,18 { 24 }
explorer.exe+7623C - 48 8B CE              - mov rcx,rsi
explorer.exe+7623F - 0B C2                 - or eax,edx
explorer.exe+76241 - C7 44 24 38 10000000  - mov [rsp+38],00000010 { 16 }
explorer.exe+76249 - 89 44 24 48           - mov [rsp+48],eax
explorer.exe+7624D - 48 8D 54 24 28        - lea rdx,[rsp+28]
explorer.exe+76252 - B8 13000000           - mov eax,00000013 { 19 }
explorer.exe+76257 - 89 44 24 44           - mov [rsp+44],eax
explorer.exe+7625B - 89 44 24 28           - mov [rsp+28],eax
explorer.exe+7625F - 48 8D 44 24 40        - lea rax,[rsp+40]
explorer.exe+76264 - 48 89 44 24 30        - mov [rsp+30],rax
explorer.exe+76269 - 48 FF 15 08F82000     - call qword ptr [explorer.exe+285A78] { ->user32.SetWindowCompositionAttribute }
explorer.exe+76270 - 0F1F 44 00 00         - nop dword ptr [rax+rax+00]
explorer.exe+76275 - 48 8B 4C 24 50        - mov rcx,[rsp+50]
explorer.exe+7627A - 48 33 CC              - xor rcx,rsp
explorer.exe+7627D - E8 4E2F0200           - call explorer.exe+991D0
explorer.exe+76282 - 4C 8D 5C 24 60        - lea r11,[rsp+60]
explorer.exe+76287 - 49 8B 5B 18           - mov rbx,[r11+18]
explorer.exe+7628B - 49 8B 73 20           - mov rsi,[r11+20]
explorer.exe+7628F - 49 8B E3              - mov rsp,r11
explorer.exe+76292 - 5F                    - pop rdi
explorer.exe+76293 - C3                    - ret 

一个未公开的 Win32 API

未完待续

本文作者:ADD-SP
本文链接https://www.addesp.com/archives/343
版权声明:本博客所有文章除特别声明外,均默认采用 CC-BY-NC-SA 4.0 许可协议。

评论

  1. kz
    1年前
    2022-12-15 11:35:04

    最新版本的win11系统中,注册表方式好像已经失效了,TaskbarAcrylicOpacity没有这个项目,新建后也无用

发送评论 编辑评论


上一篇
下一篇