Есть ли способ вернуть пользовательские объекты или список пользовательских объектов из подключенной процедуры в C++/CLI?

Я подключаю простой управляемый процесс и внедряю динамическую SPY DLL в этот процесс для сбора информации от него, и мне также нужно отправить эту информацию другим процессам.

Для этой цели я использую одну библиотеку инжектора, которая может отправлять сообщение процедуре главного окна управляемого процесса. Мне нужно получить список всех элементов управления в виде списка, который находится внутри этих подключенных процессов. Для этого моя процедура ловушки не может вернуть какой-либо «Объект», кроме. Вот мой код процедуры ловушки инжектора и вызывающая сторона этой процедуры ловушки.

Object^ MessageHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    try
    {
        if (nCode == HC_ACTION)
        {
            if (pCW->message == WM_INVOKEREMOTE)
            {
                // NOTE: This libary is probably loaded by Windows using some "LoadFrom"
                // resembling approach when the hook is installed. Appearantly, this causes
                // the CLR to be unable to find it when deserializing (even though we are
                // actually executing it in this moment!), so we need to help it. See
                // http://discuss.develop.com/archives/wa.exe?A2=ind0303a&L=dotnet-clr&D=0&T=0&P=10291
                AppDomain^ currentDomain = AppDomain::CurrentDomain;
                currentDomain->AssemblyResolve += gcnew ResolveEventHandler(HelperClass::ResolveRequestMessageAssembly);
                RequestMessage^ msg = (RequestMessage^)Deserialize();
                currentDomain->AssemblyResolve -= gcnew ResolveEventHandler(HelperClass::ResolveRequestMessageAssembly);

                // We need the path, otherwise the assembly have to be in the search path for the application in which it is injected
                String^ assemblyFile = Path::Combine(Path::GetDirectoryName(Assembly::GetExecutingAssembly()->Location), msg->AssemblyFile);
                Assembly^ assembly = Assembly::LoadFrom(assemblyFile);

                Type^ type = assembly->GetType(msg->TypeName);

                Object^ retVal = type->InvokeMember(msg->MethodName, BindingFlags::Static | BindingFlags::Public | BindingFlags::InvokeMethod, nullptr, nullptr, msg->Args);
                //Serialize(retVal);
            }
        }
    }
    catch(Object^ ex)
    {
        // No need to make a reference to System.Windows.Forms assembly just to show a
        // messagebox, we just need to make a string conversion
        IntPtr ptr = Marshal::StringToHGlobalUni(ex->ToString());
        LPCTSTR error = reinterpret_cast<LPCTSTR>(ptr.ToPointer());
        ::MessageBox(NULL, error, L"InvokeRemote Failed", MB_ICONERROR | MB_OK);
        Marshal::FreeHGlobal(ptr);
        Serialize(nullptr);
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

ВЫЗЫВАЮЩИЙ К MessageHookProc

====================

Object^ Injector::InvokeRemote(IntPtr hWnd, String^ assemblyFile, String^ typeName, String^ methodName, array<Object^>^ args)
{
    RequestMessage^ msg = gcnew RequestMessage();
    msg->AssemblyFile = assemblyFile;
    msg->TypeName = typeName;
    msg->MethodName = methodName;
    msg->Args = args;
    ::Serialize(msg);

    HINSTANCE hinstDLL = LoadLibrary((LPCTSTR) _T("InjectLib.dll"));
    DWORD threadID = GetWindowThreadProcessId((HWND)hWnd.ToPointer(), NULL);
    HOOKPROC procAddress = (HOOKPROC)GetProcAddress(hinstDLL, "MessageHookProc");
    HHOOK messageHookHandle = SetWindowsHookEx(WH_CALLWNDPROC, procAddress, hinstDLL, threadID);

    // This forces it to be loaded into the target adress space
    // CALLS ACTUALLY THE HOOK PROCEDURE BY SENDING MESSAGE TO MAIN WINDOW OF HOOKED PROCESSS.
    // ==========================================================================
    SendMessage((HWND)hWnd.ToPointer(), WM_INVOKEREMOTE, 0, 0);   

    ::UnhookWindowsHookEx(messageHookHandle);
    // Object^ retVal = Deserialize();
    return retVal;
}

Итак, здесь я не хочу, чтобы объекты были сериализованы таким образом, они должны быть ВОЗВРАЩЕНЫ из процедуры ловушки, и этот вызывающий объект должен затем иметь возможность передавать эти объекты в какой-либо другой модуль или процессы.

С уважением
Усман


person Usman    schedule 19.05.2011    source источник


Ответы (1)


Вам нужно сериализовать данные в некоторую кодировку, которая не использует указатели, потому что эти указатели не имеют значения ни в каком другом процессе. Затем вы можете использовать любую форму IPC, например. именованный канал для передачи закодированных данных другому процессу.

person Ben Voigt    schedule 20.05.2011