Какую технику использует Snoop для проверки приложения WPF

StackOverflow https://stackoverflow.com//questions/24045183

  •  21-12-2019
  •  | 
  •  

Вопрос

Snoop, Spy Utility, использует некоторую мощную технику (вероятно, какое-то отражение) для проверки запущенного приложения WPF.Самое интересное - это тот факт, что SNNOP может считать всю структуру объекта.

Несколько дней назад я загрузил исходный код Snoop и провел некоторое время на изучение внутреннего поведения.К сожалению, я не мог узнать, как Snoop делает эти вещи, поэтому я надеюсь, что кто-нибудь может помочь мне.

На работе я в настоящее время пишу код тестирования закодированных пользовательских интерфейсов, и было бы фантастическим, если бы у меня был доступ к объектам приложения, потому что это позволит мне не только утверждать состояние UI.

Обновление:

Это код необходим:

string filePath = "WpfApp.exe";
AppDomain appDomain = AppDomain.CurrentDomain;
byte[] bytes = System.IO.File.ReadAllBytes(filePath);
Assembly ass = appDomain.Load(bytes);
ass.EntryPoint.Invoke(null, new object[] { });
IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;
Window w = System.Windows.Interop.HwndSource.FromHwnd(handle).RootVisual as Window;
.

Это уже большая помощь для меня, но также интересно выяснить, как Snoop вводит себя в другой процесс.

Это было полезно?

Решение

Вы можете выполнить то, что Snoop делает, используя WPF VisualTreehehelper и / или логикателера.Как только вы получите удержание любого визуального элемента, вы можете в значительной степени пройти все это визуальное дерево, чтобы увидеть все элементы, которые он содержит.Visual Tree Helper здесь

Так что в вашем тесте на интернет-интерфейс, возьмите главное окно и пересечь его визуальное дерево, чтобы найти любой элемент, который вы хотите, а затем выполните любые проверки или операции, которые вы хотите на этом элементе.

Кроме того, вы можете использовать System.diagnostics.process.mainwindowhandle, чтобы получить обрабатывать Windows из существующего процесса, а затем использовать ручку окна для создания окна WPF.Это было некоторое время, поэтому я не помню специфику, не делая больше исследований.Код ниже может помочь:

Window window = (Window)System.Windows.Interop.HwndSource.FromHwnd(process.MainWindowHandle).RootVisual;
.

Другие советы

Обновление:

Хорошо, я нашел основное местоположение кода, которое используется Snoop, чтобы обеспечить способность инъекции.К моему удивлению, этот код написан C. Вероятно, есть причина.

и это код (я надеюсь, что это в порядке, чтобы опубликовать его здесь):

//-----------------------------------------------------------------------------
//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<const wchar_t> 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);
    }
}
.

snoop не проверяет WPF снаружи.Он вводит себя в приложение и фактически добавляет окно увелича или Snoop.Это также почему, когда вы выходите на Snoop, окна проверки на самом деле остаются открытыми.

Так что код «проверки» просто проверяет окно, которое он хочет, и он может использовать все операторы WPF для этого.Как визуальный элемент и логикатреннее, как упомянуто здесь ранее.

Для небольшой тестовой структуры, которую я строит, я вводил код, чтобы добавить небольшой прокси-объект, чтобы я мог легко управлять приложением (нажмите кнопки, изменять значения, выполнять функции на ViewModels и т. Д.).

Ответ выше не работает для меня.Кажется немного расплывчатым.Я немного расширился на принятый ответ с этим кодом:

    var allProcesses = Process.GetProcesses();
    var filteredProcess = allProcesses.Where(p => p.ProcessName.Contains(ProcessSearchText)).First();
    var windowHandle = filteredProcess.MainWindowHandle;
    var hwndSource = HwndSource.FromHwnd(windowHandle);
.

Этот ответ кажется более полным и будет работать для других, если у кого-либо работает принятый ответ.Однако эта последняя строка этого кода возвращает нуль для меня.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top