Я подключаю простой управляемый процесс и внедряю динамическую библиотеку SPY DLL в этот процесс, чтобы собирать информацию из него, и мне необходимо также отправить эту информацию другим процессам.
Для этой цели я использую одну библиотеку инжектора, которая может отправить сообщение в процедуру главного окна управляемого процесса. Мне нужно получить список всех элементов управления в виде списка, которые находятся внутри подключенных процессов. Для этого моя подключаемая процедура не может вернуть какой-либо «объект», кроме. Вот мой код процедуры Hook инжектора и вызывающая сторона для этой процедуры хука.
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;
}
Так что здесь я не хочу, чтобы объекты сериализовались таким образом, они должны быть ВОЗВРАЩЕНЫ из подключаемой процедуры, и тогда этот вызывающий объект сможет передавать эти объекты в какой-то другой модуль или процессы.
Привет
Усман