/*************************************** *
Test JS
Tooltip
WINXP SP2 user32.dll validatehandle (hwnd H)
OK. If you see this article, you should draft it now.
**************************************** */
Validatehandlemacro (PCI, pobj, H, btype);/* This is a macro function defined in WoW. C. Detailed Implementation
# Define validatehandlemacro (PCI, pobj, H, btype )/
Startvalidatehandlemacro (h )/
Beginalivevalidatehandlemacro ()/
Begintypevalidatehandlemacro (pobj, btype )/
Desktopvalidate (PCI, pobj )/
Endtypevalidatehandlemacro/
Endalivevalidatehandlemacro ()/
Endvalidatehandlemacro
Note that the order of the above macros cannot be changed because of their implementation methods.
Then, analyze the data one by one.
*/
/* First, explain the sources of PCI, pobj, H, and btype variables.
The following is the source code snippet of user32.dll parsed by IDA.
. Text: 77d18520 mov eax, large FS: 18 h; eax = Teb
. Text: 77d18526 mov ECx, dword_77d70080; ECx = gpsi
. Text: 77d1852c Lea EBX, [eax + 6cch]; EBX = Teb. win32clientinfo;
FS: 18 has been explained in many posts. It is the address of Teb.
There is a big gap between the structures of Teb and windows of different versions. If you see some so-called Teb structures in any post and the structure given is not classified into different versions like # If ver_productbuild> XXXX, do not take them seriously. After all, I have read many posts. The above Teb + 6cch exists in gdi_teb_batch gditebbatch, a large member. I 've been confused for a long time. I recommend here: http://www.acc.umu.se /~ Bosse/ntifs. H <-this is the Teb structure in reactos. Here is Teb. win32clientinfo. That is, PCI in the macro function. (PCI: pointer of clientinfo)
Gpsi is a global variable of Type pserverinfo. Its address exists in 77d70080. Defined in globals. h. One member variable in gpsi, chandlesentries, is the number of handle entries. Checking the handle is important in validatehandlemacro.
# Define startvalidatehandlemacro (h )/
{
PHE Phe;
DWORD dwindex;
Word uniq;
Dwindex = hmindexfromhandle (h );
If (dwindex <gpsi-> chandleentries ){
PHE = & gsharedinfo. ahelist [dwindex];
Uniq = hmuniqfromhandle (h );
If (uniq = phe-> wuniq | uniq = 0 | uniq = hmuniqbits)
{
/* Macro end */
/*
MoV eax, EDI; eax = hwnd
And eax, 0 ffffh; dwindex = eax = hmindexfromhandle (hwnd );
The above code is */
Dwindex = hmindexfromhandle (h );
/*
CMP eax, [ECx + 8]
JNB short loc_77d1858b; dwindex> = gpsi-> chandleentries?
; Goto 77d1858b
The above code is */
If (dwindex <gpsi-> chandleentries)
{
/* Followed:
MoV ECx, dword_77d700a4; 77d700a4 = & gsharedinfo. ahelist;
Lea eax, [eax + eax * 2]; because the size of ahelist is three Dwords, this statement uses Lea
; The eax * 3 operation is completed. Multiplication is not used here because
; Lea is short. It should be the credit of a smart Compiler :-)
Lea ECx, [ECx + eax * 4]; phe = & gsharedinfo. ahelist [dwindex];
; ECx = Phe = ahelist + sizeof (handleentry) * dwindex;
The above code is */
PHE = & gsharedinfo. ahelist [dwindex];
MoV eax, EDI; eax = hwnd;
SHR eax, 10 h; uniq = eax = (hiword) hwnd
The above code is */
Uniq = hmuniqfromhandle (h );
/*
CMP ax, [ECx + 0ah]; CMP uniq PHE. wuniq
Jnz loc_77d1e5d0; If (uniq! = PHE. wuniq)
Goto 77d1e5d0
........
. Text: 77d1e5d0 test ax, ax; If (AX = 0)
JZ loc_77d18559; goto 77d18559
CMP ax, 0 ffffh; If (ax! = 0 xFFFF)
Jnz loc_77d1858b; goto 77d1858b
JMP loc_77d18559
The above code is */
If (uniq = phe-> wuniq | uniq = 0 | uniq = hmuniqbits)
{
The above is the source code of startvalidatehandlemacro (h. You can see from the source code why these macros cannot change the order.
Next let's take a look.
Beginalivevalidatehandlemacro ()
# Define beginalivevalidatehandlemacro ()/
/*
Test byte PTR [ECx + 9], 1; if (PHE. bflags! = Handlef_destroy)
Jnz short loc_77d1858b; goto 77d1858b;
The above code is */
If (! (Phe-> bflags & handlef_destroy ))
{
This is a very simple macro function.
Which of the following is
Begintypevalidatehandlemacro (pobj, btype)
# Define begintypevalidatehandlemacro (pobj, btypetest )/
/*
MoV Al, [ECx + 8]; Al = PHE. btype;
CMP Al, DL; If (PHE. btype! = Btype ){
Jnz loc_77d1db7f; goto 77d1db7f;
The above code is */
If (Phe-> btype = btypetest) |/
(Btypetest = type_generic & phe-> btype! = Type_free )){/
/
/*/
* Instead of try/retry t we use the heap range check/
* Mechanic to verify that the given 'pwnd' belongs/
* The default desktop. We also have to do a Win 3.1 like/
* Check to make sure the window is not deleted/
* See nt bug 12242 kitchen app. Also 6479/
*/
* Test10000op returns the handle if the handle is valid/
* In the current desktop/
*//
Pobj = phe-> phead ;/
{
Typdef _ Teb
{
Nit nit;
.......
W32clientinfo clientinfo;
......
} Teb;
Typedef struct tagserverinfo {// Si
Word wripflags; // ripf _ flags
Word wsrviflags; // srvif _ flags
Word wrippid; // PID of process to apply rip flags to (zero means all)
Word wriperror; // error to break on (zero means all errors are treated equal)
Kernel_ulong_ptr chandleentries; // count of handle entries in array/* 0x08 */
........
} Serverinfo;
Test
Test2
. Text: 77d18559 test byte PTR [ECx + 9], 1; if (PHE. bflags! = Handlef_destroy ){
. Text: 77d1855d jnz short loc_77d1858b; goto 77d1858b;
. Text: 77d1855d ;}
. Text: 77d1855f mov Al, [ECx + 8]; Al = PHE. btype;
. Text: 77d181_cmp Al, DL; If (PHE. btype! = Btype ){
. Text: 77d18564 jnz loc_77d1db7f; goto 77d1db7f;
. Text: 77d18564 ;}
Typedef struct tagsharedinfo {
Pserverinfo PSI;
PHE ahelist;/* handle table pointer ......
} Sharedinfo, * PSHA