自写API绕过R3下所有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里面其实又调用了USER32!InternalFindWindowExW,这个函数接收5个参数,第三个是类名,第四个是标题,其他参数不用管,跟进去看下
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
这里面调用的是USER32!NtUserFindWindowEx,这个函数也是接收5个参数,第三个是类名,第四个是标题,其他参数同样不用管,不过这里为什么实际数据跟堆栈中不同呢,例如第三个参数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 user32!FindWindowW跟几步就看到了


你可能感兴趣的:(c,api,String,user,null,hook)