自作APIはR 3を迂回してすべてのHOOKをおります


FindWindowでテストしてODでついてきて
HWND hWnd=::FindWindow(_T("SciCalc"),_T("   "));
::SendMessage(hWnd,WM_CLOSE,NULL,NULL);

パラメータの解析を容易にするために,FindWindowにもクラス名を渡した.ODロード、bp FindWindowW、運転後に切断し、FindWindowWの中へ
77D2C9C5    55              PUSH EBP
77D2C9C6    8BEC            MOV EBP,ESP
77D2C9C8    33C0            XOR EAX,EAX
77D2C9CA    50              PUSH EAX
77D2C9CB    FF75 0C         PUSH DWORD PTR SS:[EBP+C]
77D2C9CE    FF75 08         PUSH DWORD PTR SS:[EBP+8]
77D2C9D1    50              PUSH EAX
77D2C9D2    50              PUSH EAX
77D2C9D3    E8 8AFFFFFF     CALL USER32.77D2C962
77D2C9D8    5D              POP EBP
77D2C9D9    C2 0800         RETN 8

FindWindowWでは実はまたUSER 32が呼び出されました!InternalFindWindowExW、この関数は5つのパラメータを受信して、3番目はクラス名で、4番目はタイトルで、その他のパラメータは気にしないで、ついて行って見てください
77D2C964    55              PUSH EBP
77D2C965    8BEC            MOV EBP,ESP
77D2C967    83EC 20         SUB ESP,20
77D2C96A    8D45 F0         LEA EAX,DWORD PTR SS:[EBP-10]
77D2C96D    56              PUSH ESI
77D2C96E    8B35 D814D177   MOV ESI,DWORD PTR DS:[<&ntdll.RtlInitUni>; ntdll.RtlInitUnicodeString
77D2C974    8945 F8         MOV DWORD PTR SS:[EBP-8],EAX
77D2C977    8B45 10         MOV EAX,DWORD PTR SS:[EBP+10]
77D2C97A    57              PUSH EDI
77D2C97B    33FF            XOR EDI,EDI
77D2C97D    A9 0000FFFF     TEST EAX,FFFF0000
77D2C982    897D EC         MOV DWORD PTR SS:[EBP-14],EDI
77D2C985    897D FC         MOV DWORD PTR SS:[EBP-4],EDI
77D2C988    0F84 F0540000   JE USER32.77D31E7E
77D2C98E    50              PUSH EAX
77D2C98F    8D45 F0         LEA EAX,DWORD PTR SS:[EBP-10]
77D2C992    50              PUSH EAX
77D2C993    FFD6            CALL ESI
77D2C995    FF75 14         PUSH DWORD PTR SS:[EBP+14]
77D2C998    8D45 E0         LEA EAX,DWORD PTR SS:[EBP-20]
77D2C99B    50              PUSH EAX
77D2C99C    897D EC         MOV DWORD PTR SS:[EBP-14],EDI
77D2C99F    8945 E8         MOV DWORD PTR SS:[EBP-18],EAX
77D2C9A2    FFD6            CALL ESI
77D2C9A4    FF75 18         PUSH DWORD PTR SS:[EBP+18]
77D2C9A7    FF75 E8         PUSH DWORD PTR SS:[EBP-18]
77D2C9AA    FF75 F8         PUSH DWORD PTR SS:[EBP-8]
77D2C9AD    FF75 0C         PUSH DWORD PTR SS:[EBP+C]
77D2C9B0    FF75 08         PUSH DWORD PTR SS:[EBP+8]
77D2C9B3    E8 F4FDFFFF     CALL USER32.77D2C7AC
77D2C9B8    5F              POP EDI
77D2C9B9    5E              POP ESI
77D2C9BA    C9              LEAVE
77D2C9BB    C2 1400         RETN 14
この中で呼び出されたのはUSER 32です!NtUserFindWindowEx、この関数も5つのパラメータを受信し、3つ目はクラス名、4つ目はタイトル、他のパラメータも同様に管理しないが、ここではなぜ実際のデータがスタックと異なるのか、例えば3つ目のパラメータPUSH DWORD PTR SS:[EBP-8]、スタック内のクラス名の位置はEBP-Cなのに..編集菜鳥を教えてください
引き続きフォローすると、おなじみのシステム呼び出しが表示されます
77D2C7AC    B8 7A110000     MOV EAX,117A
77D2C7B1    BA 0003FE7F     MOV EDX,7FFE0300
77D2C7B6    FF12            CALL DWORD PTR DS:[EDX]
77D2C7B8    C2 1400         RETN 14
7C92E510 >  8BD4            MOV EDX,ESP
7C92E512    0F34            SYSENTER
7C92E514 >  C3              RETN

私たちが実際にしなければならないのは、NtUserFindWindowExという関数をシミュレートし、直接コードをアップロードすることです.
#pragma pack(1)
typedef struct _UNICODE_STRING{		
	USHORT Length;
	USHORT MaximumLength;  
	PWSTR  Buffer; 
} UNICODE_STRING,*PUNICODE_STRING;
#pragma pack()

typedef VOID (__stdcall *PRtlInitUnicodeString)(IN OUT PUNICODE_STRING  DestinationString,
										   IN PCWSTR  SourceString);
PRtlInitUnicodeString  RtlInitUnicodeString=(PRtlInitUnicodeString)GetProcAddress(GetModuleHandle(_T("ntdll.dll")),"RtlInitUnicodeString");

__declspec(naked) VOID __stdcall kiFastSystemCall()//  kiFastSystemCall
{
	__asm
	{
		mov edx,esp;
       _EMIT 0x0F
	   _EMIT 0x34 
	}
}

__declspec(naked) HWND __stdcall MyFindWindow(int a,
											  int b,
											  PUNICODE_STRING puClassName,
											  PUNICODE_STRING puCaption,
											  int d
											  )
{
	__asm
	{
		mov eax,0x117A;
		call kiFastSystemCall;
		retn 0x14;
	}

}
呼び出し
UNICODE_STRING pu_className,pu_Caption;
RtlInitUnicodeString(&pu_className,_T("SciCalc"));
RtlInitUnicodeString(&pu_Caption,_T("   "));
HWND hWnd=MyFindWindow(NULL,NULL,&pu_className,&pu_Caption,NULL);
::SendMessage(hWnd,WM_CLOSE,NULL,NULL);	

注意RtlInitUnicodeStringをエクスポートして文字列パラメータを初期化する必要があります
また、この関数については、この関数内で呼び出された関数名は見えませんので、すでに記号がロードされているWINDBGで確認することができます
同じbp user 32!FindWindowWはあと数歩で見えます