EDN Admin
Well-known member
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-spacere try
<span style="white-spacere {
<span style="white-spacere if (nCode == HC_ACTION)
<span style="white-spacere {
<span style="white-spacere if (pCW->message == WM_INVOKEREMOTE)
<span style="white-spacere {
<span style="white-spacere // NOTE: This libary is probably loaded by Windows using some "LoadFrom"
<span style="white-spacere // resembling approach when the hook is installed. Appearantly, this causes
<span style="white-spacere // the CLR to be unable to find it when deserializing (even though we are
<span style="white-spacere // actually executing it in this moment!), so we need to help it. See
<span style="white-spacere // http://discuss.develop.com/archives/wa.exe?A2=ind0303a&L=dotnet-clr&D=0&T=0&P=10291
<span style="white-spacere AppDomain^ currentDomain = AppDomain::CurrentDomain;
<span style="white-spacere currentDomain->AssemblyResolve += gcnew ResolveEventHandler(HelperClass::ResolveRequestMessageAssembly);
<span style="white-spacere RequestMessage^ msg = (RequestMessage^)Deserialize();
<span style="white-spacere currentDomain->AssemblyResolve -= gcnew ResolveEventHandler(HelperClass::ResolveRequestMessageAssembly);
<span style="white-spacere // 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-spacere String^ assemblyFile = Path::Combine(Path::GetDirectoryName(Assembly::GetExecutingAssembly()->Location), msg->AssemblyFile);
<span style="white-spacere Assembly^ assembly = Assembly::LoadFrom(assemblyFile);
<span style="white-spacere
<span style="white-spacere Type^ type = assembly->GetType(msg->TypeName);
<span style="white-spacere
<span style="white-spacere Object^ retVal = type->InvokeMember(msg->MethodName, BindingFlags::Static | BindingFlags:ublic | BindingFlags::InvokeMethod, nullptr, nullptr, msg->Args);
<span style="white-spacere //Serialize(retVal);
<span style="white-spacere }
<span style="white-spacere }
<span style="white-spacere }
<span style="white-spacere catch(Object^ ex)
<span style="white-spacere {
<span style="white-spacere // No need to make a reference to System.Windows.Forms assembly just to show a
<span style="white-spacere // messagebox, we just need to make a string conversion
<span style="white-spacere IntPtr ptr = Marshal::StringToHGlobalUni(ex->ToString());
<span style="white-spacere LPCTSTR error = reinterpret_cast<LPCTSTR>(ptr.ToPointer());
<span style="white-spacere ::MessageBox(NULL, error, L"InvokeRemote Failed", MB_ICONERROR | MB_OK);
<span style="white-spacere Marshal::FreeHGlobal(ptr);
<span style="white-spacere Serialize(nullptr);
<span style="white-spacere }
<span style="white-spacere 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-spacere RequestMessage^ msg = gcnew RequestMessage();
<span style="white-spacere msg->AssemblyFile = assemblyFile;
<span style="white-spacere msg->TypeName = typeName;
<span style="white-spacere msg->MethodName = methodName;
<span style="white-spacere msg->Args = args;
<span style="white-spacere ::Serialize(msg);
<span style="white-spacere HINSTANCE hinstDLL = LoadLibrary((LPCTSTR) _T("InjectLib.dll"));
<span style="white-spacere DWORD threadID = GetWindowThreadProcessId((HWND)hWnd.ToPointer(), NULL);
<span style="white-spacere HOOKPROC procAddress = (HOOKPROC)GetProcAddress(hinstDLL, "MessageHookProc");
<span style="white-spacere HHOOK messageHookHandle = SetWindowsHookEx(WH_CALLWNDPROC, procAddress, hinstDLL, threadID);
<span style="white-spacere // This forces it to be loaded into the target adress space
<span style="white-spacere // CALLS ACTUALLY THE HOOK PROCEDURE BY SENDING MESSAGE TO MAIN WINDOW OF HOOKED PROCESSS.
// ==========================================================================
<span style="white-spacere SendMessage((HWND)hWnd.ToPointer(), WM_INVOKEREMOTE, 0, 0);
<span style="white-spacere ::UnhookWindowsHookEx(messageHookHandle);
//<span style="white-spacere Object^ retVal = Deserialize();
<span style="white-spacere 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
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-spacere try
<span style="white-spacere {
<span style="white-spacere if (nCode == HC_ACTION)
<span style="white-spacere {
<span style="white-spacere if (pCW->message == WM_INVOKEREMOTE)
<span style="white-spacere {
<span style="white-spacere // NOTE: This libary is probably loaded by Windows using some "LoadFrom"
<span style="white-spacere // resembling approach when the hook is installed. Appearantly, this causes
<span style="white-spacere // the CLR to be unable to find it when deserializing (even though we are
<span style="white-spacere // actually executing it in this moment!), so we need to help it. See
<span style="white-spacere // http://discuss.develop.com/archives/wa.exe?A2=ind0303a&L=dotnet-clr&D=0&T=0&P=10291
<span style="white-spacere AppDomain^ currentDomain = AppDomain::CurrentDomain;
<span style="white-spacere currentDomain->AssemblyResolve += gcnew ResolveEventHandler(HelperClass::ResolveRequestMessageAssembly);
<span style="white-spacere RequestMessage^ msg = (RequestMessage^)Deserialize();
<span style="white-spacere currentDomain->AssemblyResolve -= gcnew ResolveEventHandler(HelperClass::ResolveRequestMessageAssembly);
<span style="white-spacere // 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-spacere String^ assemblyFile = Path::Combine(Path::GetDirectoryName(Assembly::GetExecutingAssembly()->Location), msg->AssemblyFile);
<span style="white-spacere Assembly^ assembly = Assembly::LoadFrom(assemblyFile);
<span style="white-spacere
<span style="white-spacere Type^ type = assembly->GetType(msg->TypeName);
<span style="white-spacere
<span style="white-spacere Object^ retVal = type->InvokeMember(msg->MethodName, BindingFlags::Static | BindingFlags:ublic | BindingFlags::InvokeMethod, nullptr, nullptr, msg->Args);
<span style="white-spacere //Serialize(retVal);
<span style="white-spacere }
<span style="white-spacere }
<span style="white-spacere }
<span style="white-spacere catch(Object^ ex)
<span style="white-spacere {
<span style="white-spacere // No need to make a reference to System.Windows.Forms assembly just to show a
<span style="white-spacere // messagebox, we just need to make a string conversion
<span style="white-spacere IntPtr ptr = Marshal::StringToHGlobalUni(ex->ToString());
<span style="white-spacere LPCTSTR error = reinterpret_cast<LPCTSTR>(ptr.ToPointer());
<span style="white-spacere ::MessageBox(NULL, error, L"InvokeRemote Failed", MB_ICONERROR | MB_OK);
<span style="white-spacere Marshal::FreeHGlobal(ptr);
<span style="white-spacere Serialize(nullptr);
<span style="white-spacere }
<span style="white-spacere 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-spacere RequestMessage^ msg = gcnew RequestMessage();
<span style="white-spacere msg->AssemblyFile = assemblyFile;
<span style="white-spacere msg->TypeName = typeName;
<span style="white-spacere msg->MethodName = methodName;
<span style="white-spacere msg->Args = args;
<span style="white-spacere ::Serialize(msg);
<span style="white-spacere HINSTANCE hinstDLL = LoadLibrary((LPCTSTR) _T("InjectLib.dll"));
<span style="white-spacere DWORD threadID = GetWindowThreadProcessId((HWND)hWnd.ToPointer(), NULL);
<span style="white-spacere HOOKPROC procAddress = (HOOKPROC)GetProcAddress(hinstDLL, "MessageHookProc");
<span style="white-spacere HHOOK messageHookHandle = SetWindowsHookEx(WH_CALLWNDPROC, procAddress, hinstDLL, threadID);
<span style="white-spacere // This forces it to be loaded into the target adress space
<span style="white-spacere // CALLS ACTUALLY THE HOOK PROCEDURE BY SENDING MESSAGE TO MAIN WINDOW OF HOOKED PROCESSS.
// ==========================================================================
<span style="white-spacere SendMessage((HWND)hWnd.ToPointer(), WM_INVOKEREMOTE, 0, 0);
<span style="white-spacere ::UnhookWindowsHookEx(messageHookHandle);
//<span style="white-spacere Object^ retVal = Deserialize();
<span style="white-spacere 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