概述
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
未完待续
最新版本的win11系统中,注册表方式好像已经失效了,TaskbarAcrylicOpacity没有这个项目,新建后也无用