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;
}