Is there any way out to return Custom objects or List of Custom objects from hooke procedure in C++/

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
Hello,
I am hooking simple managed process and injecting a dynamic SPY DLL into theat process to collect information from it and needs to send this information to other processes as well.
For this purpose I am using one injector library which can send the message to managed processs main window procedure. I need to get the list of all controls as list<Controls> which are inside that hooked processes. For that my hook procedure cannot
return some "Object" except. Heres my injector Hook procedure code and caller to this hook procedure.


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

<span style="white-space:pre // We need the path, otherwise the assembly have to be in the search path for the application in which it is injected
<span style="white-space:pre String^ assemblyFile = Path::Combine(Path::GetDirectoryName(Assembly::GetExecutingAssembly()->Location), msg->AssemblyFile);
<span style="white-space:pre Assembly^ assembly = Assembly::LoadFrom(assemblyFile);
<span style="white-space:pre
<span style="white-space:pre Type^ type = assembly->GetType(msg->TypeName);
<span style="white-space:pre
<span style="white-space:pre Object^ retVal = type->InvokeMember(msg->MethodName, BindingFlags::Static | BindingFlags::Public | BindingFlags::InvokeMethod, nullptr, nullptr, msg->Args);
<span style="white-space:pre //Serialize(retVal);
<span style="white-space:pre }
<span style="white-space:pre }
<span style="white-space:pre }
<span style="white-space:pre catch(Object^ ex)
<span style="white-space:pre {
<span style="white-space:pre // No need to make a reference to System.Windows.Forms assembly just to show a
<span style="white-space:pre // messagebox, we just need to make a string conversion
<span style="white-space:pre IntPtr ptr = Marshal::StringToHGlobalUni(ex->ToString());
<span style="white-space:pre LPCTSTR error = reinterpret_cast<LPCTSTR>(ptr.ToPointer());
<span style="white-space:pre ::MessageBox(NULL, error, L"InvokeRemote Failed", MB_ICONERROR | MB_OK);
<span style="white-space:pre Marshal::FreeHGlobal(ptr);
<span style="white-space:pre Serialize(nullptr);
<span style="white-space:pre }
<span style="white-space:pre return CallNextHookEx(NULL, nCode, wParam, lParam);
}

CALLER TO MessageHookProc
====================

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

<span style="white-space:pre HINSTANCE hinstDLL = LoadLibrary((LPCTSTR) _T("InjectLib.dll"));
<span style="white-space:pre DWORD threadID = GetWindowThreadProcessId((HWND)hWnd.ToPointer(), NULL);
<span style="white-space:pre HOOKPROC procAddress = (HOOKPROC)GetProcAddress(hinstDLL, "MessageHookProc");
<span style="white-space:pre HHOOK messageHookHandle = SetWindowsHookEx(WH_CALLWNDPROC, procAddress, hinstDLL, threadID);

<span style="white-space:pre // This forces it to be loaded into the target adress space

<span style="white-space:pre // CALLS ACTUALLY THE HOOK PROCEDURE BY SENDING MESSAGE TO MAIN WINDOW OF HOOKED PROCESSS.
// ==========================================================================
<span style="white-space:pre SendMessage((HWND)hWnd.ToPointer(), WM_INVOKEREMOTE, 0, 0);

<span style="white-space:pre ::UnhookWindowsHookEx(messageHookHandle);

//<span style="white-space:pre Object^ retVal = Deserialize();
<span style="white-space:pre return retVal;
}

So here I dont want objects to be serialized in this manner, they must be RETUNRED from hook procedure and this caller should then be able to transfer those objects to some other module or processs.
Regards
USman

View the full article
 
Back
Top