View Single Post
  #4  
Old 02-12-2015, 22:24
BlackWhite BlackWhite is offline
Friend
 
Join Date: Apr 2013
Posts: 85
Rept. Given: 4
Rept. Rcvd 14 Times in 6 Posts
Thanks Given: 14
Thanks Rcvd at 56 Times in 25 Posts
BlackWhite Reputation: 14
Quote:
Originally Posted by bilbo View Post
I now see your problem: you must not intercept the first WM_NOTIFY which arrives, with notify code NM_CLICK (0xFFFFFFFE), but the following WM_NOTIFY, with notify code TVN_SELCHANGED (0xFFFFFE6E in ascii version, 0xFFFFFE3D in Unicode version)!

Best regards
bilbo
Yes, I wish I could intercept WM_NOTIFY with code TVN_SELCHANGED
instead of NM_CLICK, but that program was not written by myself. It
stubbornly sticks to NM_CLICK.

I have done several experiments to defy GetMessagePos(), but got
no success:

Experiment1: It did not trigger the WM_NOTIFY event processing.
And if I change hWnd to hTreeView itself instead of its father,
the result is the same.
Code:
   POINT ap={0x0027, 0x0289}, cp={0x0025, 0x00AE};
   SetFocus(GetParent((HWND)hTreeView));
   SetCursorPos(ap.x, ap.y);
   ScreenToClient(GetParent((HWND)hTreeView), &ap);
   cp = ap;
   PostMessage(GetParent((HWND)hTreeView), WM_LBUTTONDOWN, MK_LBUTTON, cp.y<<16 | cp.x);
Experiment2: It triggered the WM_NOTIFY event processing,
but GetMessagePos() got the wrong coordinates.
Code:
   POINT ap={0x0027, 0x0289}, cp={0x0025, 0x00AE};
   SetFocus(GetParent((HWND)hTreeView));
   SetCursorPos(ap.x, ap.y);
   ScreenToClient(GetParent((HWND)hTreeView), &ap);
   cp = ap;
   PostMessage(GetParent((HWND)hTreeView), WM_LBUTTONDOWN, MK_LBUTTON, cp.y<<16 | cp.x);
   NMHDR notify;
   notify.hwndFrom = (HWND)hTreeView;
   notify.idFrom = 0xE901; 
   notify.code = NM_CLICK; // 0xFFFFFFFE
   SendMessage(GetParent((HWND)hTreeView), WM_NOTIFY, 0xE901, (long)&notify);
Experiment3: It did not triggered the WM_NOTIFY event processing.
Code:
   TV_ITEM ti;
   POINT ap={0x0027, 0x0289}, cp={0x0025, 0x00AE};
   ti.hItem = (HTREEITEM)hLstRetract;     
   ti.mask = TVIF_HANDLE | TVIF_STATE | TVIF_PARAM;   
   ti.stateMask = TVIF_HANDLE | TVIF_STATE | TVIF_PARAM;
   SendMessage((HWND)hTreeView, TVM_GETITEM, 0, (long)&ti);
   NM_TREEVIEW tvnm;
   memset(&tvnm, 0, sizeof(tvnm));
   tvnm.itemNew = ti;          
   tvnm.action = TVC_BYMOUSE; // by mouse click
   tvnm.ptDrag.x = cp.x; // client 
   tvnm.ptDrag.y = cp.y; // coordinates
   tvnm.hdr.hwndFrom = (HWND)hTreeView;
   tvnm.hdr.idFrom = 0xE901;
   tvnm.hdr.code = TVN_SELCHANGED;
   SendMessage(GetParent((HWND)hTreeView), WM_NOTIFY, 0xE901, (long)&tvnm);
I have traced that program by using OllyDbg & Soft-ICE to figure out
why Experiment3 failed:
Code:
73D322C3    FF75 08         push    dword ptr [ebp+8]
73D322C6    FF75 0C         push    dword ptr [ebp+C]
73D322C9    53              push    ebx
73D322CA    FF76 04         push    dword ptr [esi+4]
73D322CD    E8 DDFEFFFF     call    #AfxFindMessageEntry_1145;[!]=>*73D321AF
73D322D2    85C0            test    eax, eax; in simulating case, EAX=0
73D322D4    75 0F           jnz     short 73D322E5; in physical click case, EAX=4471860h
this_is_bad:
...
that_is_good:
73D322E5    FF75 14         push    dword ptr [ebp+14]
73D322E8    FF70 10         push    dword ptr [eax+10]; 0x26
73D322EB    FF75 10         push    dword ptr [ebp+10]
73D322EE    FF70 14         push    dword ptr [eax+14]; 0x442D470=message_processing_function_ptr
73D322F1    FF75 0C         push    dword ptr [ebp+C]
73D322F4    FF75 08         push    dword ptr [ebp+8]
73D322F7    57              push    edi
73D322F8    E8 6E000000     call    73D3236B; [!]
73D322FD  ^ EB DF           jmp     short 73D322DE
   || 
  \||/
   \/
;[!]*73D3236B
73D3236B    55              push    ebp
73D3236C    8BEC            mov     ebp, esp
73D3236E    8B45 20         mov     eax, [ebp+20]
73D32371    53              push    ebx
73D32372    33DB            xor     ebx, ebx
73D32374    43              inc     ebx
73D32375    85C0            test    eax, eax
73D32377    74 12           je      short 73D3238B
...
73D323C2    8B45 18         mov     eax, [ebp+18]
73D323C5    FF30            push    dword ptr [eax]
73D323C7    8B4D 08         mov     ecx, [ebp+8]
73D323CA    FF70 04         push    dword ptr [eax+4]
73D323CD    FF55 14         call    [ebp+14]; [!]=>*0x442D470=message_processing_function_ptr
73D323D0    E9 97000000     jmp     73D3246C
   || 
  \||/
   \/
;[!]73D321AF;#AfxFindMessageEntry_1145
73D321AF >  55              push    ebp
73D321B0    8BEC            mov     ebp, esp
73D321B2    53              push    ebx
73D321B3    8B5D 08         mov     ebx, [ebp+8]; EBX=4471848h->MessageMap
73D321B6    8B45 0C         mov     eax, [ebp+C]; EAX=EventCodePrefix=0xBC4E
73D321B9    8B55 10         mov     edx, [ebp+10]; EDX=EventCode=TVN_SELCHANGED=0xFE6E
73D321BC    8B4D 14         mov     ecx, [ebp+14]
73D321BF    837B 10 00      cmp     dword ptr [ebx+10], 0; is_it_null_message_map_item
73D321C3    74 1D           je      short 73D321E2; has reached the end of message map
73D321C5    3B03            cmp     eax, [ebx]; check EventCodePrefix
73D321C7    74 05           je      short 73D321CE
73D321C9    83C3 18         add     ebx, 18; EBX->next_message_map_item
73D321CC  ^ EB F1           jmp     short 73D321BF
73D321CE    3B53 04         cmp     edx, [ebx+4]; check EventCode
73D321D1  ^ 75 F6           jnz     short 73D321C9
73D321D3    3B4B 08         cmp     ecx, [ebx+8]
73D321D6  ^ 72 F1           jb      short 73D321C9
73D321D8    3B4B 0C         cmp     ecx, [ebx+C]
73D321DB  ^ 77 EC           ja      short 73D321C9
73D321DD    895D 08         mov     [ebp+8], ebx; save message_map_item_ptr
73D321E0    EB 05           jmp     short 73D321E7
73D321E2    33C0            xor     eax, eax
73D321E4    8945 08         mov     [ebp+8], eax
73D321E7    8B45 08         mov     eax, [ebp+8]; EAX=message_map_item_ptr
73D321EA    5B              pop     ebx         ; [EAX+14h]=message_processing_function_ptr
73D321EB    5D              pop     ebp
73D321EC    C2 1000         retn    10

;This is the message map. It contains 3 items. Every item holds 18h bytes.
04471848  64 03 00 00 00 00 00 00  00 00 00 00 00 00 00 00
04471858  0C 00 00 00 40 D4 42 04  4E BC 00 00 FE FF 00 00
04471868  00 00 00 00 00 00 00 00  26 00 00 00 70 D4 42 04
04471878  0F 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
04471888  0C 00 00 00 90 D5 42 04  00 00 00 00 00 00 00 00
04471898  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
According to the above analysis, that program's message map does not
contain an item related to TVN_SELCHANGED.

So I have fallen into a dilemma. If I PostMessage(WM_LBUTTON), that
will not trigger WM_NOTIFY's processing; If I SendMessage(WM_NOTIFY),
that program gets the wrong coordinates.

Do you have any good idea to defeat that damn program?
Reply With Quote