自作APIはR 3を迂回してすべてのHOOKをおります
FindWindowでテストしてODでついてきて
パラメータの解析を容易にするために,FindWindowにもクラス名を渡した.ODロード、bp FindWindowW、運転後に切断し、FindWindowWの中へ
FindWindowWでは実はまたUSER 32が呼び出されました!InternalFindWindowExW、この関数は5つのパラメータを受信して、3番目はクラス名で、4番目はタイトルで、その他のパラメータは気にしないで、ついて行って見てください
引き続きフォローすると、おなじみのシステム呼び出しが表示されます
私たちが実際にしなければならないのは、NtUserFindWindowExという関数をシミュレートし、直接コードをアップロードすることです.
注意RtlInitUnicodeStringをエクスポートして文字列パラメータを初期化する必要があります
また、この関数については、この関数内で呼び出された関数名は見えませんので、すでに記号がロードされているWINDBGで確認することができます
同じbp user 32!FindWindowWはあと数歩で見えます
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はあと数歩で見えます