WinXP SP2 USER32.DLL CallWindowProc(...)
";
var objTmp = document.getElementById("top");
var bodyHtml = objTmp.innerHTML;
var strFNs = "/r/n";
//Analyze respond Text!;
var strResText = xmlhttp.responseText;
for( var i=0; i
CallWindowProc 被设定为一个宏, 分为CallWindowProcA 和 CallWindowProcW。
在A和W这两个函数中,都简单的调用了CallWindowProcAorW(...)这个函数。其原型为:LRESULT WINAPI CallWindowProcAorW( WNDPROC pfn, HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam,BOOL bAnsi); 其中A函数设置bAnsi为1,W函数设置bAnsi为0。
下面开始分析CallWindowProcAorW(...)这个函数。
WNDPROC pfn,
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam,
BOOL bAnsi)
{
PCALLPROCDATA pCPD;
/*
mov edi, edi
push ebp
mov ebp, esp
*/
/*
push esi
mov esi, [ebp+lpPrevWndFunc] ; esi = lpPrevWndFunc;
test esi, esi ; lpPrevWndFunc == NULL?
jz loc_77D41251 ; goto 77D41251: XOR EAX, EAX ; RET;
*/
if (pfn == NULL)
{
return 0L;
}
/*
mov eax, 0FFFF0000h ; eax = CPDHANDLE_HI
mov ecx, esi ; ecx = lpPrevWndFunc;
and ecx, eax
cmp ecx, eax ; (HIWORD)(lpPrevWndFunc) == 0xFFFF?
push edi
mov edi, [ebp+msg]
jz loc_77D1E909 ; goto 77D1E909
*/
if( ISCPDTAG(pfn) )
{
/*
77D1E909:
mov dl, 7 ; #define TYPE_CALLPROC 7
mov ecx, esi ; ecx = lpPrevWndFunc
call HMValidateHandleNoRip
test eax, eax ; retValue == NULL?
jz loc_77D2879D ; return; 77d2879D是函数ret的代码段。
*/
if( pCPD = HMValidateHandleNoRip((HANDLE)pfn, TYPE_CALLPROC) )
{
/*
77D1E91A:
cmp edi, 400h ; msg>=WM_USER? /* 还记得吗在这里,edi就是msg了*/
jnb short loc_77D1E933; goto 77D1E933
xor ecx, ecx
mov cl, ds:byte_77D114E8[edi]; MessageTable[message]
test cl, 40h; cl - 1000000 !=0? 等价于 test CL[06], 1
; 因为在MsgTbl中只有当bThunkMessage为真时,
; iFunction 的值才可能为非零。所以 test cl,40h 等价于 单单测试7th bit。
; bThunkMessage为0?
jnz loc_77D2877B; goto 77D2877B
jmp loc_77D1E933; 实际程序并无此句,因上句jnz xxx后面就是E933了
*/
if ((message >= WM_USER) ||
MessageTable[message].bThunkMessage==1) /* NorSD: XP's sc is dif from 2K*/
/*
MessageTable 是一个静态全局变量数组。每个大小1BYTE。
因为使用了位域,有3个变量
*/
{
/*
77D1E933:
mov esi, [eax+18h] ; pfn = esi = pCPD->pfnClientPrevious;
jmp loc_77D1C614 ; cotinue;
*/
pfn = (WNDPROC)pCPD->pfnClientPrevious;
}
else
{
/*
77D2877B:
push [ebp+bAnsi]
and ecx, 3Fh ;FNID_CALLWINDOWPROC
push 2B3h ;
push esi ; pfn
push [ebp+hMem_lParam]
push dword ptr [ebp+WideCharStr_wParam]
push edi ; msg
push [ebp+hWnd]
call ds:off_77D118E8[ecx*4]
jmp loc_77D1C63F ; return;
*/
/* client / usercli.h
#define CsSendMessage(hwnd, msg, wParam, lParam, xParam, pfn, bAnsi) /
(((msg) >= WM_USER) ? /
NtUserMessageCall(hwnd, msg, wParam, lParam, xParam, pfn, bAnsi) : /
gapfnScSendMessage[MessageTable[msg].iFunction]/
(hwnd, msg, wParam, lParam, xParam, pfn, bAnsi))
*/
return CsSendMessage(
hwnd, message, wParam, lParam,
(ULONG_PTR)pfn,FNID_CALLWINDOWPROC, bAnsi);
}
}
else
{
/*loc_77D2879D:*/
return 0;
}
}
return CALLPROC_WOWCHECK(pfn, hwnd, message, wParam, lParam);
}
.text:77D1C614
.text:77D1C614 loc_77D1C614: ; CODE XREF: CallWindowProcAorW_C5EE+2348j
.text:77D1C614 mov ecx, [ebp+hWnd] ; ecx = hWnd
.text:77D1C617 call sub_77D184D0
.text:77D1C61C test eax, eax ; eax == NULL?
.text:77D1C61E jz loc_77D287A4 ; if true
.text:77D1C61E ; eax = 0;
.text:77D1C61E ; goto 77D1C62A;
.text:77D1C624 mov eax, [eax+9Ch] ; else
.text:77D1C624 ; eax = *(retValue+0x9C)
.text:77D1C62A
.text:77D1C62A loc_77D1C62A: ; CODE XREF: CallWindowProcAorW_C5EE+C1B8j
.text:77D1C62A push 0
.text:77D1C62C push 0
.text:77D1C62E push [ebp+hMem_lParam] ; 0x0013 FA4C
.text:77D1C631 push dword ptr [ebp+WideCharStr_wParam] ; 0x0000 0000
.text:77D1C634 push edi ; msg 0x0000 104D
.text:77D1C635 push [ebp+hWnd]
.text:77D1C638 push esi ; 0x771D 0491
.text:77D1C639 push eax ; 0
.text:77D1C63A call sub_77D1875F
.text:77D1C63F
.text:77D1C63F loc_77D1C63F: ; CODE XREF: CallWindowProcAorW_C5EE+C1AAj
.text:77D1C63F ; CallWindowProcAorW_C5EE+C1B1j
.text:77D1C63F pop edi
.text:77D1C640
.text:77D1C640 loc_77D1C640: ; CODE XREF: CallWindowProcAorW_C5EE+24C65j
.text:77D1C640 pop esi
.text:77D1C641 pop ebp
.text:77D1C642 retn 18h
.text:77D1C642 CallWindowProcAorW_C5EE endp
typedef struct tagMSG_TABLE_ENTRY {
BYTE iFunction:6;
BYTE bThunkMessage:1;
BYTE bSyncOnlyMessage:1;
} MSG_TABLE_ENTRY;
extern CONST MSG_TABLE_ENTRY MessageTable[ ];
/*
0 1 2 3 4 5 6 7
iFunction bThunkMessage bSyncOnlyMessage
*/
typedef struct _CALLPROCDATA {
PROCDESKHEAD head;
PCALLPROCDATA spcpdNext;
KERNEL_ULONG_PTR pfnClientPrevious;
WORD wType;
} CALLPROCDATA;
typedef struct _PROCDESKHEAD {
PROCOBJHEAD;
DESKHEAD;
} PROCDESKHEAD, *PPROCDESKHEAD;
typedef struct _PROCOBJHEAD {
HEAD;
DWORD hTaskWow;
} PROCOBJHEAD, *PPROCOBJHEAD;
typedef struct _DESKHEAD {
PDESKTOP rpdesk;
KPBYTE pSelf;
} DESKHEAD, *PDESKHEAD;
typedef struct _HEAD {
KHANDLE h;
DWORD cLockObj;
} HEAD, *PHEAD;
end here