문제

snoop, SPY 유틸리티는 실행중인 WPF 응용 프로그램을 검사하기 위해 일부 강력한 기술 (아마도 일종의 반사)을 사용합니다.SNNOP는 전체 객체 구조를 읽을 수있는 사실입니다.

며칠 전 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에서 주입 능력을 제공하기 위해 사용되는 기본 코드 위치를 발견했습니다.코드가 작성된 것 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를 검사하지 않습니다.응용 프로그램에 주입하고 실제로 확대 또는 스눕 창을 추가합니다.그게 또한 스눕을 빠져 나올 때 검사 창은 실제로 열려 있습니다.

그래서 '검사'코드는 단순히 원하는 창을 검사하고 모든 Avaible WPF 기능을 사용할 수 있도록 사용할 수 있습니다.여기에 언급 한 바와 같이 VisualTreeHelper와 LogicalTreeHelper와 마찬가지로

작은 테스트 프레임 워크의 경우 i를 빌드하여 작은 프록시 오브젝트를 추가하여 응용 프로그램을 쉽게 제어 할 수 있도록 (버튼, 값 변경, ViewModels에서 기능 실행 기능을 눌러) 할 수 있습니다.

위의 대답은 나를 위해 작동하지 않습니다.조금 모호한 것 같습니다.이 코드로 조금 받아 들여지는 답변을 받아 들였습니다.

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

이 답변은 더 완전 해져서 받아 들여지는 답변이 누구에게나 작동하는 경우 다른 사람들을 위해 일할 것입니다.그러나이 코드의 마지막 줄은 나에게 null을 반환합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top