| 以下为引用的内容: #include "stdafx.h"#include "Injector.h"
 #include <vcclr.h>
 using namespace ManagedInjector;
 //defines a new window message that is guaranteed to be unique throughout the system.
 //The message value can be used when sending or posting messages.
 static unsigned int WM_GOBABYGO = ::RegisterWindowMessage(L"Injector_GOBABYGO!");
 static HHOOK _messageHookHandle;
 //-----------------------------------------------------------------------------
 //Spying Process functions follow
 //-----------------------------------------------------------------------------
 void Injector::Launch(System::IntPtr windowHandle, System::Reflection::Assembly^ assembly, System::String^ className, System::String^ methodName) {
 System::String^ assemblyClassAndMethod = assembly->Location + "$" + className + "$" + methodName;
 //convert String to local wchar_t* or char*
 pin_ptr<const wchar_t> acmLocal = PtrToStringChars(assemblyClassAndMethod);
 //Maps the specified executable module into the address space of the calling process.
 HINSTANCE hinstDLL = ::LoadLibrary((LPCTSTR) _T("ManagedInjector.dll"));
 if (hinstDLL)
 {
 DWORD processID = 0;
 //get the process id and thread id
 DWORD threadID = ::GetWindowThreadProcessId((HWND)windowHandle.ToPointer(), &processID);
 if (processID)
 {
 //get the target process object (handle)
 HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
 if (hProcess)
 {
 int buffLen = (assemblyClassAndMethod->Length + 1) * sizeof(wchar_t);
 //Allocates physical storage in memory or in the paging file on disk for the specified reserved memory pages.
 //The function initializes the memory to zero.
 //The return value is the base address of the allocated region of pages.
 void* acmRemote = ::VirtualAllocEx(hProcess, NULL, buffLen, MEM_COMMIT, PAGE_READWRITE);
 if (acmRemote)
 {
 //copies the data(the assemblyClassAndMethod string)
 //from the specified buffer in the current process
 //to the address range of the target process
 ::WriteProcessMemory(hProcess, acmRemote, acmLocal, buffLen, NULL);
 
 //Retrieves the address of MessageHookProc method from the hintsDLL
 HOOKPROC procAddress = (HOOKPROC)GetProcAddress(hinstDLL, "MessageHookProc");
 //install a hook procedure to the target thread(before the system sends the messages to the destination window procedure)
 _messageHookHandle = ::SetWindowsHookEx(WH_CALLWNDPROC, procAddress, hinstDLL, threadID);
 if (_messageHookHandle)
 {
 //send our custom message to the target window of the target process
 ::SendMessage((HWND)windowHandle.ToPointer(), WM_GOBABYGO, (WPARAM)acmRemote, 0);
 //removes the hook procedure installed in a hook chain by the SetWindowsHookEx function.
 ::UnhookWindowsHookEx(_messageHookHandle);
 }
 //removes a hook procedure installed in a hook chain by the SetWindowsHookEx function.
 ::VirtualFreeEx(hProcess, acmRemote, buffLen, MEM_RELEASE);
 }
 ::CloseHandle(hProcess);
 }
 }
 //Decrements the reference count of the loaded DLL
 ::FreeLibrary(hinstDLL);
 }
 }
 __declspec( dllexport )
 // The procedure for hooking, this will be called back after hooked
 int __stdcall MessageHookProc(int nCode, WPARAM wparam, LPARAM lparam) {
 //HC_ACTION: indicate that there are argments in wparam and lparam
 if (nCode == HC_ACTION)
 {
 CWPSTRUCT* msg = (CWPSTRUCT*)lparam;
 //when the target window received our custom message
 if (msg != NULL && msg->message == WM_GOBABYGO)
 {
 //get the argument passed by the message
 //actually, the argument is the base address (a pointer)
 //of the assemblyClassAndMethod string in the target process memory
 wchar_t* acmRemote = (wchar_t*)msg->wParam;
 //gcnew: creates an instance of a managed type (reference or value type) on the garbage collected heap
 System::String^ acmLocal = gcnew System::String(acmRemote);
 //split the string into substring array with $. Under this context:
 //acmSplit[0]:the assembly‘s location
 //acmSplit[1]:className;
 //acmSplit[2]:methodName
 //we use these infomation to reflect the method in the source assembly, and invoke it in the target process
 cli::array<System::String^>^ acmSplit = acmLocal->Split(‘$‘);
 //refect the method, and invoke it
 System::Reflection::Assembly^ assembly = System::Reflection::Assembly::LoadFile(acmSplit[0]);
 if (assembly != nullptr)
 {
 System::Type^ type = assembly->GetType(acmSplit[1]);
 if (type != nullptr)
 {
 System::Reflection::MethodInfo^ methodInfo =
 type->GetMethod(acmSplit[2], System::Reflection::BindingFlags::Static | System::Reflection::BindingFlags::Public);
 if (methodInfo != nullptr)
 {
 methodInfo->Invoke(nullptr, nullptr);
 }
 }
 }
 }
 }
 return CallNextHookEx(_messageHookHandle, nCode, wparam, lparam);
 }
 |