Я столкнулся со странной проблемой, касающейся ловли. У меня есть процедура, которая действует как перехваченная процедура в C ++ / CLI, после SendMessage она не может перехватить процедуру, хотя это не поведение при отладке процесса в режиме отладки, когда перехваченный процесс успешно присоединен, все настройки HookedProc будет наблюдаться как выполненный.
Я не могу найти правильное поведение.
Такое поведение нежелательно, так как я должен доставить процесс и использовать процесс без использования VS.
Код:
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
::SendMessage((HWND)hWnd.ToPointer(), WM_INVOKEREMOTE, 0, 0);
TCHAR tValue[100];
memset(tValue,0,100);
DWORD ReturnValue = GetLastError();
_stprintf(tValue,L"%d",ReturnValue);
String^ strRetVal = gcnew String(tValue);
::UnhookWindowsHookEx(messageHookHandle);
Object^ retVal = Deserialize();
return retVal;
}
и следующий - процедура подключения
int __stdcall MessageHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
try
{
if (nCode == HC_ACTION)
{
try
{
if (pCW->message == WM_INVOKEREMOTE)
{
String^ assemblyFile = "";
Assembly^ assembly = nullptr;
AppDomain^ currentDomain = AppDomain::CurrentDomain;
currentDomain->AssemblyResolve += gcnew ResolveEventHandler(HelperClass::ResolveRequestMessageAssembly);
RequestMessage^ msg = (RequestMessage^)Deserialize();
currentDomain->AssemblyResolve -= gcnew ResolveEventHandler(HelperClass::ResolveRequestMessageAssembly);
assemblyFile = Path::Combine(Path::GetDirectoryName(Assembly::GetExecutingAssembly()->Location), msg->AssemblyFile);
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(Exception^ ex)
{
System::Windows::Forms::MessageBox::Show( ex->InnerException->ToString(), L"PAUSE", System::Windows::Forms::MessageBoxButtons::OK);
}
}
}
catch(Object^ ex)
{
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);
}