What technique does Snoop uses to inspect a WPF application

前端 未结 4 1884
一向
一向 2021-02-06 01:15

Snoop, the spy utility, uses some powerful technique (probably some sort of reflection) to inspect a running WPF application. Most interesting is the fact, that Snnop is able to

4条回答
  •  猫巷女王i
    2021-02-06 01:37

    UPDATE:

    Okay, I found the basic code location, that is used by Snoop to provide the injection ability. To my astonishment that code is written C++/CLI. Probably there is a reason for.

    And that is the code (I hope that it is okay to post it here):

    //-----------------------------------------------------------------------------
    //Spying Process functions follow
    //-----------------------------------------------------------------------------
    void Injector::Launch(System::IntPtr windowHandle, System::String^ assembly, System::String^ className, System::String^ methodName)
    {
        System::String^ assemblyClassAndMethod = assembly + "$" + className + "$" + methodName;
        pin_ptr acmLocal = PtrToStringChars(assemblyClassAndMethod);
    
        HINSTANCE hinstDLL; 
    
        if (::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)&MessageHookProc, &hinstDLL))
        {
            LogMessage("GetModuleHandleEx successful", true);
            DWORD processID = 0;
            DWORD threadID = ::GetWindowThreadProcessId((HWND)windowHandle.ToPointer(), &processID);
    
            if (processID)
            {
                LogMessage("Got process id", true);
                HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
                if (hProcess)
                {
                    LogMessage("Got process handle", true);
                    int buffLen = (assemblyClassAndMethod->Length + 1) * sizeof(wchar_t);
                    void* acmRemote = ::VirtualAllocEx(hProcess, NULL, buffLen, MEM_COMMIT, PAGE_READWRITE);
    
                    if (acmRemote)
                    {
                        LogMessage("VirtualAllocEx successful", true);
                        ::WriteProcessMemory(hProcess, acmRemote, acmLocal, buffLen, NULL);
    
                        _messageHookHandle = ::SetWindowsHookEx(WH_CALLWNDPROC, &MessageHookProc, hinstDLL, threadID);
    
                        if (_messageHookHandle)
                        {
                            LogMessage("SetWindowsHookEx successful", true);
                            ::SendMessage((HWND)windowHandle.ToPointer(), WM_GOBABYGO, (WPARAM)acmRemote, 0);
                            ::UnhookWindowsHookEx(_messageHookHandle);
                        }
    
                        ::VirtualFreeEx(hProcess, acmRemote, 0, MEM_RELEASE);
                    }
    
                    ::CloseHandle(hProcess);
                }
            }
            ::FreeLibrary(hinstDLL);
        }
    }
    

提交回复
热议问题