/// <summary> /// ネイティブのDLLメソッドを対象プロセスに実行させる。 /// </summary> /// <param name="processHandle">プロセスのハンドル。</param> /// <param name="dllPath">DLL。</param> /// <param name="function">関数名称。</param> /// <param name="args">引数。</param> /// <returns>実行したメソッドの戻り値</returns> internal static uint ExecuteRemoteFunction(IntPtr processHandle, string dllPath, string function, string args) { IntPtr pArgs = IntPtr.Zero; IntPtr hThreadInTarget = IntPtr.Zero; uint resultVlaue = 0; try { //引数を相手プロセスに書き込む List <byte> startInfoTmp = new List <byte>(Encoding.Unicode.GetBytes(args)); startInfoTmp.Add(0);//null終端を足す byte[] startInfo = startInfoTmp.ToArray(); pArgs = NativeMethods.VirtualAllocEx(processHandle, IntPtr.Zero, new IntPtr(startInfo.Length), NativeMethods.AllocationType.Commit, NativeMethods.MemoryProtection.ReadWrite); if (pArgs == IntPtr.Zero || !NativeMethods.WriteProcessMemory(processHandle, pArgs, startInfo, new IntPtr((int)startInfo.Length), IntPtr.Zero)) { throw new FriendlyOperationException(ResourcesLocal.Instance.ErrorProcessOperation); } { //実行関数取得 IntPtr pFunc = DllInjector.GetTargetProcAddress(processHandle, dllPath, function); if (pFunc == IntPtr.Zero) { throw new FriendlyOperationException(ResourcesLocal.Instance.ErrorFriendlySystem); } //対象プロセスでメソッドを実行 IntPtr tid; hThreadInTarget = NativeMethods.CreateRemoteThread(processHandle, IntPtr.Zero, IntPtr.Zero, pFunc, pArgs, 0, out tid); if (hThreadInTarget == IntPtr.Zero) { throw new FriendlyOperationException(ResourcesLocal.Instance.ErrorProcessOperation); } NativeMethods.WaitForSingleObject(hThreadInTarget, NativeMethods.INFINITE); //戻り値を取得 if (NativeMethods.GetExitCodeThread(hThreadInTarget, out var ret)) { resultVlaue = ret; } } } finally { if (hThreadInTarget != IntPtr.Zero) { NativeMethods.CloseHandle(hThreadInTarget); } if (pArgs != IntPtr.Zero) { NativeMethods.VirtualFreeEx(processHandle, pArgs, IntPtr.Zero, NativeMethods.FreeType.Release); } } return(resultVlaue); }
/// <summary> /// プロセスでシステムを起動させる。 /// </summary> /// <param name="processHandle">対象プロセス操作ハンドル。</param> /// <param name="processId">プロセスID。</param> /// <param name="dllName">サーバー側で動作させるDLL名称。</param> /// <param name="assemblyStep">踏み台用アセンブリのパス。</param> /// <param name="clrVersion">CLRのバージョン。</param> /// <param name="initializeThreadWindowHandle">初期化を実行させるスレッドに属するウィンドウのハンドル。</param> /// <returns>システムコントローラー。</returns> static SystemController StartInApp(IntPtr processHandle, int processId, string dllName, string assemblyStep, string clrVersion, IntPtr initializeThreadWindowHandle) { return(StartInApp(clrVersion, assemblyStep, processId, initializeThreadWindowHandle, e => { Debug.Trace("Call InitializeFriendly."); DllInjector.ExecuteRemoteFunction(processHandle, dllName, "InitializeFriendly", e); Debug.Trace("InitializeFriendly Finished."); })); }
/// <summary> /// ネイティブのDLLメソッドを対象プロセスに実行させる。 /// </summary> /// <param name="processHandle">プロセスのハンドル。</param> /// <param name="dllPath">DLL。</param> /// <param name="function">関数名称。</param> /// <param name="args">引数。</param> internal static void ExecuteRemoteFunction(IntPtr processHandle, string dllPath, string function, string args) { IntPtr pArgs = IntPtr.Zero; IntPtr hThreadServerOpen = IntPtr.Zero; try { //受信ウィンドウハンドルを対象プロセス内にメモリを確保して書き込む longを文字列化して書き込む List <byte> startInfoTmp = new List <byte>(Encoding.Unicode.GetBytes(args)); startInfoTmp.Add(0);//null終端を足す byte[] startInfo = startInfoTmp.ToArray(); pArgs = NativeMethods.VirtualAllocEx(processHandle, IntPtr.Zero, new IntPtr(startInfo.Length), NativeMethods.AllocationType.Commit, NativeMethods.MemoryProtection.ReadWrite); if (pArgs == IntPtr.Zero || !NativeMethods.WriteProcessMemory(processHandle, pArgs, startInfo, new IntPtr((int)startInfo.Length), IntPtr.Zero)) { throw new FriendlyOperationException(ResourcesLocal.Instance.ErrorProcessOperation); } { //実行関数取得 IntPtr pFunc = DllInjector.GetTargetProcAddress(processHandle, dllPath, function); if (pFunc == IntPtr.Zero) { throw new FriendlyOperationException(ResourcesLocal.Instance.ErrorFriendlySystem); } //対象プロセスでサーバー開始メソッドを実行 IntPtr tid; hThreadServerOpen = NativeMethods.CreateRemoteThread(processHandle, IntPtr.Zero, IntPtr.Zero, pFunc, pArgs, 0, out tid); if (hThreadServerOpen == IntPtr.Zero) { throw new FriendlyOperationException(ResourcesLocal.Instance.ErrorProcessOperation); } NativeMethods.WaitForSingleObject(hThreadServerOpen, NativeMethods.INFINITE); } } finally { if (hThreadServerOpen != IntPtr.Zero) { NativeMethods.CloseHandle(hThreadServerOpen); } if (pArgs != IntPtr.Zero) { NativeMethods.VirtualFreeEx(processHandle, pArgs, IntPtr.Zero, NativeMethods.FreeType.Release); } } }
/// <summary> /// 起動。 /// </summary> /// <param name="process">対象プロセス。</param> /// <param name="clrVersion">CLRバージョン名称。</param> /// <param name="initializeThreadWindowHandle">初期化を実行させるスレッドに属するウィンドウのハンドル。</param> /// <returns>システムコントローラー。</returns> internal static SystemController Start(Process process, string clrVersion, IntPtr initializeThreadWindowHandle) { //念のためProcessがメッセージを受け付けるのを確認する NativeMethods.SendMessage(initializeThreadWindowHandle, 0, IntPtr.Zero, IntPtr.Zero); //必要な権限でプロセスを開く int processId = process.Id; IntPtr processHandle = NativeMethods.OpenProcess( NativeMethods.ProcessAccessFlags.CreateThread | NativeMethods.ProcessAccessFlags.VMOperation | NativeMethods.ProcessAccessFlags.VMRead | NativeMethods.ProcessAccessFlags.VMWrite | NativeMethods.ProcessAccessFlags.QueryInformation, false, processId); if (processHandle == IntPtr.Zero) { throw new FriendlyOperationException(ResourcesLocal.Instance.ErrorProcessOperation); } try { if (!CpuTargetCheckUtility.IsSameCpu(process)) { throw new FriendlyOperationException(ResourcesLocal.Instance.ErrorTargetCpuDifference); } //PCにDLLインストール string injectionDllPath = DllInstaller.InitializeCodeerFriendlyWindowsNative(); string assemblyStepPath = DllInstaller.InitializeCodeerFriendlyWindowsStep(); //対象プロセスにDLLをロードする Debug.Trace("Dll Loading."); DllInjector.LoadDll(processHandle, injectionDllPath); Debug.Trace("Dll Loaded."); //初期化処理 return(StartInApp(processHandle, processId, injectionDllPath, assemblyStepPath, Debug.ReadDebugMark(clrVersion), initializeThreadWindowHandle)); } finally { NativeMethods.CloseHandle(processHandle); GC.KeepAlive(process); } }
static string TryGetCoreClrDllPath(IntPtr processHandle, string injectionForDotNetFramewrokDllPath) { try { foreach (var e in DllInjector.GetProcessModules(processHandle)) { var sb = new StringBuilder((1024 + 1) * 8); NativeMethods.GetModuleFileNameEx(processHandle, e, sb, sb.Capacity); var path = sb.ToString().ToLower(); if (path.Contains("coreclr.dll") && DllInjector.ExecuteRemoteFunction(processHandle, injectionForDotNetFramewrokDllPath, "HasGetCLRRuntimeHost", path) != 0) { return(path); } } return(string.Empty); } catch { } return(string.Empty); }