自写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跟几步就看到了


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值