I'm trying to find a WndProc from explorer.exe that is handling these messages, I've found with Spy++:

<000001> 00000000000B01C8 P message:0xC02B [Registered:"SHELLHOOK"] wParam:00000025 lParam:000F0184
<000002> 00000000000B01C8 P message:0xC02B [Registered:"SHELLHOOK"] wParam:00008006 lParam:000F0184

I'm trying to prevent explorer.exe from flashing the task bar button, it's ruining my Windows 10 experience. In Windows 10 the flashing task bar buttons appear in all desktops, and it's just maddening when focusing on a work on another virtual desktop. Not a feature I want. The above messages are sent to Task switcher in explorer.exe, if I can prevent them being handled I can beat this.

I've wealth of knowledge about the WndProc which I want to see, and modify from Spy++, following windows are Property Inspector of Spy++ (64 bit version):

(Note: the 32bit version of Spy++ does not show Window Proc at all, just (Unavailable)(Unicode)

Window Proc address?

Thread ID

And in x64dbg I have the thread open:

x64dbg open on the same thread

But I just can't figure out how can I find the Window Proc in x64dbg?

  • have you been able to find the answer for `x64dgb? – T.Todua Dec 1 '18 at 11:09
  • @T.Todua yes, I have also written a AHK script that gets the WndProc address (see my script here it also does other things, but one part is WndProc). The correct solution below does work somewhat correctly. – Ciantic Dec 2 '18 at 12:03

the spy++ is showing the wndproc in your screen shot (it is probably subclassed you may need to trace but wndproc is shown in your screenshot as 361c9880 i dont know what the command is in x64 dbg but if you were on ollydbg you simply do ctrl+g (goto) keyin the address as shown in spy++ and break and log the messages for filtering

a screen shot of calc.exe -> backspace button windows wndproc in comctl32.dll (32 bits and 64 bits shouldn't matter much on concept level) enter image description here

an entry by raymond chen talks about cokies being returned instead of wndproc

if all else fails assemble GetWindowLongPtrW in place to fetch the actual WndProc

suspend the process (f12 or esc)   
use ctrl+g to goto user32.GetWindowLongPtrW     
right click set new origin here   (save the rip prior this)   
save the state of register somewhere    
modify rcx and plop the handle into rcx   
(which was b01c8 in your screen shot)   
use the latest window handle as shown by spy++     
for the existing session do not put 0xb01c8  
modify edx to hold -4 (index of GWLP_WNDPROC)    
step through the Function     
before the function returns rax should hold the actual WndProc   
save or set a bp on the Wndproc   
restore registers and rip to pristine state and continue exploring   

downloaded x64dbg and ran 64 bit calc.exe spy++ 32 bit doesn't show wndproc cooked a script to alloc a page in process memory of calc.exe and assembled a detour using the script language and fetched the actual WndProc

a screen shot below

enter image description here

the debuggee must be in paused state

the script allocates memory in debuggees address space using alloc
after tabbing once the status bar should show the newly allocated address
also variables $lastalloc $result should hold the newly allocated memory address
if you do d address a bunch of 00 00 should stare at you

confirm the allocation
if the memory is allocated tab one step in the script
push rcx should be assembled in the newly allocated address
use d address or d $lastalloc to confirm
like wise assemble all the instruction use the proper handle value in ecx (stale or reused window handles may provide incorrect information confirm you assemble mov rcx , HWND right
now you need to ensure you put the right address in eax the address should be of user32.GetWindowLongPtrW assemble all the cleanup instructions one you have done this save the existing rip some where (write it down in a paper) right click and select the first instruction in the newly allocated address and set it as origin ( new origin here) the rip will be changed to the newly allocated address

hit f8 and execute the instructions on by one when call eax is done eax will hold the Wndproc save this (write it in paper )

execute the cleanup instruction

hit ctrl+g and enter the old RIP right click -> new origin here ( RIP will now point to the old value when you paused the debuggee

that is it now you have Wndproc in a paper and you have returnd to the original state

this is a detour (making an intentional bypass in the code flow of debuggee to do some extra work and return back to the place where bypass was done as if nothing was done to continue the original flow)

use bp to set a breakpoint in the wndproc you have on paper

| improve this answer | |
  • Awesome! Thanks again. Got it working with the script now I get solid result even if I change instances which I think must mean it worked: 00007FF6361C9880. Before this I must have run the 'raw' GetWindowLogPtrW incorrectly all the time. Deleting the messages again. – Ciantic Oct 31 '15 at 18:40
  • i added details about how to use the script as a detour – blabb Oct 31 '15 at 18:46
  • it's in the explorer.exe. And! I've first time prevented FlashWindow from doing it's evil thing in the Task Switcher! I just zeroed the message C02B each time it got there and boom! Now I'm investigating how to make a memory patch I can run on my computer so I can live patch my explorer.exe – Ciantic Oct 31 '15 at 19:00
  • 1
    FYI, I'm chronicling the creation of in-memory patch here: ciantic.blogspot.fi/2015/10/… – Ciantic Oct 31 '15 at 20:14
  • nice entry yes you can dump the script and assemble anywhere in the module itself if you don't need reuse – blabb Nov 2 '15 at 9:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.