private void Button_Click(object sender, RoutedEventArgs e) { IntPtr hModule; StartButton.IsEnabled = false; //Serialize configuration XML. var eradstyle = XmlSerializationHelper.Deserialize <config>("config.xml"); //Make a List of ffxiv process IDs for later use. var pidList = Process.GetProcessesByName("ffxiv").Select(p => p.Id).ToList(); //Check if we found any ffxiv processes running. if (!pidList.Any()) { MessageBox.Show("No FFXIV process is active."); StartButton.IsEnabled = true; return; } //Set our current pid. var pid = pidList[ProcessListBox.SelectedIndex]; //Get handle for the selected ffxiv process. var hProc = _mapper.OpenHan(0x001F0FFF, pid); //Check if the CLR is already loaded into the selected process. if (Process.GetProcessById(pid).Modules.Cast <ProcessModule>().Any(mod => mod.ModuleName == "clr.dll")) { hModule = eradstyle.MemInfo.First(id => id.ID == pid).hModule; } //CLR not loaded. Map new instance of the CLR, into the ffxiv process. else { hModule = _mapper.Inject(Properties.Resources.Link, hProc); if (hModule == IntPtr.Zero) { MessageBox.Show("Something blocked Bolter from loading, Check any Virus Scanners, or Windows Restrictions"); StartButton.IsEnabled = true; return; } } var mainNamespace = MainNamespaceOfPlugin(PluginsBox.SelectedItem.ToString()); var pInfo = new PassInfo { DomainName = mainNamespace, FilePath = string.Format("{0}\\{1}.dll", Directory.GetCurrentDirectory(), PluginsBox.SelectedItem), Raw = 0, InterProcClass = string.Format("{0}.InterProcessCom", mainNamespace) }; var ppInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PassInfo))); Marshal.StructureToPtr(pInfo, ppInfo, true); // Allocate memory in ffxiv to hold the parameters struct. var pathPtr = _mapper.AllocMem(hProc, (uint)Marshal.SizeOf(typeof(PassInfo)), 0x1000 | 0x2000, 0x04); SigScan.WriteProcessMemory(hProc, pathPtr, ppInfo, (uint)Marshal.SizeOf(typeof(PassInfo)), new UIntPtr()); Marshal.FreeHGlobal(ppInfo); // Get pointer for the Load Assembly function, inside our unmanaged CLR host DLL. var routinePtr = _mapper.GetFuncPointer(hProc, hModule, "LoadIt"); // Remove old pids eradstyle.MemInfo.RemoveAll(pe => !pidList.Contains(pe.ID) || pe.ID == pid); // Add current pid. eradstyle.MemInfo.Add(new PastProcess { ID = pid, hModule = hModule }); // Save configuration. XmlSerializationHelper.Serialize("config.xml", eradstyle); // Create remote thread in the selected ffxiv process starting at the Load Assembly routine. var ntThread = _mapper.CreateThread(hProc, routinePtr, pathPtr); // Wait for completion or 2000ms. _mapper.WaitForEvent(ntThread, 2000); // Close handles. _mapper.CloseHan(ntThread); _mapper.CloseHan(hProc); StartButton.IsEnabled = true; }
public void LoadPluginIntoProcess() { IntPtr hModule; //Serialize configuration XML. var eradstyle = XmlSerializationHelper.Deserialize<config>("launcher.xml"); //Get handle for the selected ffxiv process. var hProc = _mapper.OpenHan(0x001F0FFF, _pid); //Check if the CLR is already loaded into the selected process. if (Process.GetProcessById(_pid).Modules.Cast<ProcessModule>().Any(mod => mod.ModuleName == "clr.dll")) { hModule = eradstyle.MemInfo.First(id => id.ID == _pid).hModule; } //CLR not loaded. Map new instance of the CLR, into the ffxiv process. else { hModule = _mapper.Inject(Properties.Resources.Link, hProc); if (hModule == IntPtr.Zero) { MessageBox.Show("Something blocked Bolter from loading, Check any Virus Scanners, or Windows Restrictions"); StartButton.IsEnabled = true; return; } } var mainNamespace = MainNamespaceOfPlugin(SelectedpluginName); var pInfo = new PassInfo { DomainName = mainNamespace, FilePath = string.Format("{0}\\Plugins\\{1}.dll", Directory.GetCurrentDirectory(), SelectedpluginName), }; var ppInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PassInfo))); Marshal.StructureToPtr(pInfo, ppInfo, true); // Allocate memory in ffxiv to hold the parameters struct. var pathPtr = _mapper.AllocMem(hProc, (uint)Marshal.SizeOf(typeof(PassInfo)), 0x1000 | 0x2000, 0x04); SigScan.WriteProcessMemory(hProc, pathPtr, ppInfo, (uint)Marshal.SizeOf(typeof(PassInfo)), new UIntPtr()); Marshal.FreeHGlobal(ppInfo); // Get pointer for the Load Assembly function, inside our unmanaged CLR host DLL. var routinePtr = _mapper.GetFuncPointer(hProc, hModule, "LoadIt"); // Remove old pids eradstyle.MemInfo.RemoveAll( pe => !Process.GetProcessesByName("ffxiv").Select(p => p.Id).Contains(pe.ID) || pe.ID == _pid); // Add current pid. eradstyle.MemInfo.Add(new PastProcess { ID = _pid, hModule = hModule }); // Save configuration. XmlSerializationHelper.Serialize("launcher.xml", eradstyle); // Create remote thread in the selected ffxiv process starting at the Load Assembly routine. var ntThread = _mapper.CreateThread(hProc, routinePtr, pathPtr); // Wait for completion or 2000ms. Dispatcher.BeginInvoke(new Action(delegate { DebugButton.Visibility = Visibility.Hidden; LoadingText.Visibility = Visibility.Visible; })); eHandle.WaitOne(); Dispatcher.BeginInvoke(new Action(delegate { DebugButton.Visibility = Visibility.Visible; LoadingText.Visibility = Visibility.Hidden; })); // Close handles. _mapper.CloseHan(ntThread); _mapper.CloseHan(hProc); }