private WriteProcessMemory ( int hProcess, int lpBaseAddress, byte buffer, int size, int lpNumberOfBytesWritten ) : bool | ||
hProcess | int | |
lpBaseAddress | int | |
buffer | byte | |
size | int | |
lpNumberOfBytesWritten | int | |
return | bool |
public void WriteProcessMemory_T() { IntPtr baseAddress = Marshal.AllocHGlobal(4); const int buffer = 1337; Marshal.WriteInt32(baseAddress, 0); IntPtr handle = ProcessMemory.OpenProcess(ProcessAccessFlags.All, _processId); Assert.IsFalse(handle == IntPtr.Zero); Assert.IsTrue(ProcessMemory.WriteProcessMemory(handle, baseAddress, buffer)); Assert.IsTrue(Marshal.ReadInt32(baseAddress) == buffer); Marshal.WriteInt32(baseAddress, 0); IntPtr bytesWritten = IntPtr.Zero; Assert.IsTrue(ProcessMemory.WriteProcessMemory(handle, baseAddress, buffer, ref bytesWritten)); Assert.IsTrue(Marshal.ReadInt32(baseAddress) == buffer); Assert.IsTrue(bytesWritten == (IntPtr)4); Assert.IsTrue(ProcessMemory.CloseHandle(handle)); Marshal.FreeHGlobal(baseAddress); }
public static InjectResult Inject(Process process, string dllPath, TimeSpan timeout) { InjectResult result = InjectResult.None; //Get the full path of the DLL. string fullPath = Path.GetFullPath(dllPath); //Return if the DLL is not found. if (!File.Exists(fullPath)) { return(InjectResult.Dll_Not_Found); } //Process modules aren't automatically updated in a stored process variable. //Grab the updated process. Process updatedProcess = Process.GetProcessById(process.Id); //Sometimes randomly fails due to 64-bit OS accessing 32-bit process ProcessMemory... //Try again if fails. bool success = false; string pathCompare = fullPath.ToLower(); while (!success) { try { foreach (ProcessModule pm in updatedProcess.Modules) { if (pm.FileName.ToLower() == pathCompare) //Return if the DLL is found to //prevent injecting duplicates. { return(InjectResult.Dll_Already_Jnjected); } } success = true; } catch { } } //Open handle with all permissions to avoid any unexpected access violation errors... IntPtr hProcess = ProcessMemory.OpenProcess(ProcessAccessFlags.All, true, process.Id); //Return if the handle is 0. This is an invalid result. if (hProcess == IntPtr.Zero) { return(InjectResult.Process_Handle_Invalid); } //Get the handle for kernel32.dll. IntPtr hKernel = ProcessMemory.GetModuleHandle("kernel32.dll"); //Return if the handle is 0. This is an invalid result. if (hKernel == IntPtr.Zero) { return(InjectResult.Kernel_Module_Not_Found); } //Get the address for LoadLibraryA, which is used to load a process //module into a process and calls the DllMain entry point. IntPtr hLoadLibraryA = ProcessMemory.GetProcAddress(hKernel, "LoadLibraryA"); //Return if the address is 0. This is an invalid result. if (hLoadLibraryA == IntPtr.Zero) { return(InjectResult.Load_Library_A_Not_Found); } //Allocation space for the full path of the module and //+1 for the null terminator (0x00) of the string. int allocationSize = fullPath.Length + 1; //Allocate memory space in the process and store the address //the allocation was made at. IntPtr allocatedAddr = ProcessMemory.VirtualAllocEx(hProcess, IntPtr.Zero, (IntPtr)allocationSize, AllocationType.Commit | AllocationType.Reserve, MemoryProtection.ExecuteReadWrite); //Return if the address is 0. Allocation was not made. if (allocatedAddr == IntPtr.Zero) { return(InjectResult.Memory_Allocation_Failed); } //Convert the full path string into bytes. byte[] buffer = Encoding.UTF8.GetBytes(fullPath); IntPtr numWritten; //Write the bytes to the space we allocated within the process. if (!ProcessMemory.WriteProcessMemory(hProcess, allocatedAddr, buffer, buffer.Length, out numWritten)) { //Writing to memory failed if WriteProcessMemory returned false. result = InjectResult.Memory_Write_Failed; //Free the memory we allocated into the process. //dwSize must be 0 to free all pages allocated by VirtualAllocEx. if (!ProcessMemory.VirtualFreeEx(hProcess, allocatedAddr, 0, FreeType.Release)) { //Freeing the allocated memory failed if VirtualFreeEx returned false. result |= InjectResult.Memory_Release_Failed; } //Return due to failing to write the bytes to ProcessMemory. return(result); } //Create a new remote thread, calling the LoadLibraryA function in our target //process with the address we allocated our string bytes at as the parameter. //This will load the DLL into the process using the full path to the DLL that //was specified and call the DLL's DllMain entry point. IntPtr threadId; IntPtr hThread = ProcessMemory.CreateRemoteThread(hProcess, IntPtr.Zero, 0, hLoadLibraryA, allocatedAddr, 0, out threadId); if (hThread == IntPtr.Zero) { //The remote thread failed to create if the thread handle is is 0. result = InjectResult.Thread_Creation_Failed; //Free the memory we allocated into the process. //dwSize must be 0 to free all pages allocated by VirtualAllocEx. if (!ProcessMemory.VirtualFreeEx(hProcess, allocatedAddr, 0, FreeType.Release)) { //Freeing the allocated memory failed if VirtualFreeEx returned false. result |= InjectResult.Memory_Release_Failed; } //Return due to failing to create the remote thread. return(result); } //Wait for the thread to finish, with specified timeout if it never finishes. ProcessMemory.WaitForSingleObject(hThread, (uint)timeout.TotalMilliseconds); //Free the memory we allocated into the process. //dwSize must be 0 to free all pages allocated by VirtualAllocEx. if (!ProcessMemory.VirtualFreeEx(hProcess, allocatedAddr, 0, FreeType.Release)) { //Freeing the allocated memory failed if VirtualFreeEx returned false. result |= InjectResult.Memory_Release_Failed; } //Close the handle created by CreateRemoteThread. if (!ProcessMemory.CloseHandle(hThread)) { result |= InjectResult.Thread_Close_Failed; } //Close the handle created by OpenProcess. if (!ProcessMemory.CloseHandle(hProcess)) { result |= InjectResult.Process_Handle_Close_Failed; } return(result |= InjectResult.Success); }
public void Debug(object obj, Type type = null) { try { if (obj == null) { ImGui.TextColored(Color.Red.ToImguiVec4(), $"Null"); return; } if (type == null) { type = obj.GetType(); } if (Convert.GetTypeCode(obj) == TypeCode.Object) { var methodInfo = type.GetMethod("ToString", Type.EmptyTypes); if (methodInfo != null && (methodInfo.Attributes & MethodAttributes.VtableLayoutMask) == 0) { var toString = methodInfo?.Invoke(obj, null); if (toString != null) { ImGui.TextColored(Color.Orange.ToImguiVec4(), toString.ToString()); } } } if (type.BaseType == typeof(MulticastDelegate) && type.GenericTypeArguments.Length == 1) { ImGui.TextColored(Color.Lime.ToImguiVec4(), type.GetMethod("Invoke")?.Invoke(obj, null).ToString()); return; } //IEnumerable from start var isEnumerable = IsEnumerable(type); if (isEnumerable) { var collection = obj as ICollection; if (collection != null) { var index = 0; foreach (var col in collection) { var colType = col.GetType(); string colName; switch (col) { case Entity e: colName = e.Path; break; default: colName = colType.Name; break; } var methodInfo = colType.GetMethod("ToString", Type.EmptyTypes); if (methodInfo != null && (methodInfo.Attributes & MethodAttributes.VtableLayoutMask) == 0) { var toString = methodInfo?.Invoke(col, null); if (toString != null) { colName = $"{toString}"; } } if (ImGui.TreeNode($"[{index}] {colName}")) { Debug(col, colType); ImGui.TreePop(); } index++; } ImGui.TreePop(); return; } var enumerable = obj as IEnumerable; if (enumerable != null) { var index = 0; foreach (var col in enumerable) { var colType = col.GetType(); string colName; switch (col) { case Entity e: colName = e.Path; break; default: colName = colType.Name; break; } var methodInfo = colType.GetMethod("ToString", Type.EmptyTypes); if (methodInfo != null && (methodInfo.Attributes & MethodAttributes.VtableLayoutMask) == 0) { var toString = methodInfo?.Invoke(col, null); if (toString != null) { colName = $"{toString}"; } } if (ImGui.TreeNode($"[{index}] {colName}")) { Debug(col, colType); ImGui.TreePop(); } index++; } ImGui.TreePop(); return; } } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(KeyValuePair <,>)) { var key = type.GetProperty("Key").GetValue(obj, null); var value = type.GetProperty("Value").GetValue(obj, null); var valueType = value.GetType(); if (IsEnumerable(valueType)) { var count = valueType.GetProperty("Count").GetValue(value, null); if (ImGui.TreeNode($"{key} {count}")) { Debug(value); ImGui.TreePop(); } } } var isMemoryObject = obj as RemoteMemoryObject; if (isMemoryObject != null && isMemoryObject.Address == 0) { ImGui.TextColored(Color.Red.ToImguiVec4(), $"Address 0. Cant read this object."); return; } ImGui.Indent(); ImGui.BeginTabBar($"Tabs##{obj.GetHashCode()}"); if (ImGui.BeginTabItem("Properties")) { if (isMemoryObject != null) { ImGui.Text("Address: "); ImGui.SameLine(); ImGui.PushStyleColor(ImGuiCol.Text, new ImGuiVector4(1, 0.647f, 0, 1)); ImGui.PushStyleColor(ImGuiCol.Button, new ImGuiVector4(0, 0, 0, 0)); ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new ImGuiVector4(0.25f, 0.25f, 0.25f, 1)); ImGui.PushStyleColor(ImGuiCol.ButtonActive, new ImGuiVector4(1, 1, 1, 1)); if (ImGui.SmallButton($"{((RemoteMemoryObject) obj).Address:X}")) { ImGui.SetClipboardText($"{((RemoteMemoryObject) obj).Address:X}"); } ImGui.PopStyleColor(4); var asComponent = isMemoryObject as Component; if (asComponent != null) { ImGui.Text("OwnerAddress: "); ImGui.SameLine(); ImGui.PushStyleColor(ImGuiCol.Text, new ImGuiVector4(1, 0.647f, 0, 1)); ImGui.PushStyleColor(ImGuiCol.Button, new ImGuiVector4(0, 0, 0, 0)); ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new ImGuiVector4(0.25f, 0.25f, 0.25f, 1)); ImGui.PushStyleColor(ImGuiCol.ButtonActive, new ImGuiVector4(1, 1, 1, 1)); if (ImGui.SmallButton($"{asComponent.OwnerAddress:X}")) { ImGui.SetClipboardText($"{asComponent.OwnerAddress:X}"); } ImGui.PopStyleColor(4); } switch (obj) { case Entity e: if (ImGui.TreeNode($"Components: {e.CacheComp.Count}##e{e.Address}")) { foreach (var component in e.CacheComp) { var componentType = Type.GetType("PoEMemory.Components." + component.Key + ",Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"); if (componentType == null) { ImGui.Text($"{component.Key}: Not implemented."); ImGui.SameLine(); ImGui.PushStyleColor(ImGuiCol.Text, new ImGuiVector4(1, 0.647f, 0, 1)); ImGui.PushStyleColor(ImGuiCol.Button, new ImGuiVector4(0, 0, 0, 0)); ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new ImGuiVector4(0.25f, 0.25f, 0.25f, 1)); ImGui.PushStyleColor(ImGuiCol.ButtonActive, new ImGuiVector4(1, 1, 1, 1)); if (ImGui.SmallButton($"{component.Value:X}")) { ImGui.SetClipboardText($"{component.Value:X}"); } ImGui.PopStyleColor(4); continue; } if (!genericMethodCache.TryGetValue(component.Key, out var generic)) { generic = GetComponentMethod.MakeGenericMethod(componentType); genericMethodCache[component.Key] = generic; } var g = generic.Invoke(e, null); if (ImGui.TreeNode($"{component.Key} ##{e.Address}")) { Debug(g); ImGui.TreePop(); } } ImGui.TreePop(); } if (e.HasComponent <Base>()) { if (ImGui.TreeNode($"Item info##{e.Address}")) { var BIT = GameController.Files.BaseItemTypes.Translate(e.Path); Debug(BIT); ImGui.TreePop(); } } break; } } var properties = type.GetProperties(Flags).Where(x => x.GetIndexParameters().Length == 0) .OrderBy(x => x.PropertyType.GetInterface("IEnumerable") != null).ThenBy(x => x.Name); foreach (var property in properties) { if (isMemoryObject != null && IgnoredPropertioes.Contains(property.Name)) { continue; } var propertyValue = property.GetValue(obj); if (propertyValue == null) { ImGui.Text($"{property.Name}: "); ImGui.SameLine(); ImGui.TextColored(Color.Red.ToImguiVec4(), "Null"); continue; } //Draw primitives if (IsSimpleType(property.PropertyType)) { ImGui.Text($"{property.Name}: "); ImGui.SameLine(); ImGui.PushStyleColor(ImGuiCol.Text, new ImGuiVector4(1, 0.647f, 0, 1)); ImGui.PushStyleColor(ImGuiCol.Button, new ImGuiVector4(0, 0, 0, 0)); ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new ImGuiVector4(0.25f, 0.25f, 0.25f, 1)); ImGui.PushStyleColor(ImGuiCol.ButtonActive, new ImGuiVector4(1, 1, 1, 1)); if (ImGui.SmallButton(propertyValue.ToString())) { ImGui.SetClipboardText(propertyValue.ToString()); } ImGui.PopStyleColor(4); } else { //Draw enumrable isEnumerable = IsEnumerable(property.PropertyType); if (isEnumerable) { var collection = propertyValue as ICollection; if (collection == null) { continue; } if (collection.Count > 0) { ImGui.TextColored(Color.OrangeRed.ToImguiVec4(), $"[{collection.Count}]"); var isElementEnumerable = property.PropertyType.GenericTypeArguments.Length == 1 && (property.PropertyType.GenericTypeArguments[0] == typeof(Element) || property.PropertyType.GenericTypeArguments[0].IsSubclassOf(typeof(Element))); if (isElementEnumerable) { if (ImGui.IsItemHovered()) { var index = 0; foreach (var el in collection) { if (el is Element e) { var clientRectCache = e.GetClientRectCache; Graphics.DrawFrame(clientRectCache, ColorSwaper.Value, 1); Graphics.DrawText(index.ToString(), clientRectCache.Center); index++; } } } } ImGui.SameLine(); var strId = $"{property.Name} ##{type.FullName}"; if (ImGui.TreeNode(strId)) { var skipId = $"{strId} {obj.GetHashCode()}"; if (Skips.TryGetValue(skipId, out var skip)) { ImGui.InputInt("Skip", ref skip, 1, 100); Skips[skipId] = skip; } else { Skips[skipId] = 0; } var index = -1; foreach (var col in collection) { index++; if (index < skip) { continue; } if (col == null) { ImGui.TextColored(Color.Red.ToImguiVec4(), "Null"); continue; } var colType = col.GetType(); string colName; switch (col) { case Entity e: colName = e.Path; break; case Inventory e: colName = $"{e.InvType} Count: ({e.ItemCount}) Box:{e.TotalBoxesInInventoryRow}"; break; case Element e when e.Text?.Length > 0: colName = $"{e.Text}##{index}"; break; case Element e: colName = $"{colType.Name}"; break; default: colName = $"{colType.Name}"; break; } if (IsSimpleType(colType)) { ImGui.TextUnformatted(col.ToString()); } else { Element element = null; if (isElementEnumerable) { element = col as Element; // colName += $" ({element.ChildCount})"; ImGui.Text($" ({element.ChildCount})"); ImGui.SameLine(); } else { var methodInfo = colType.GetMethod("ToString", Type.EmptyTypes); if (methodInfo != null && (methodInfo.Attributes & MethodAttributes.VtableLayoutMask) == 0) { var toString = methodInfo?.Invoke(col, null); if (toString != null) { colName = $"{toString}"; } } } if (ImGui.TreeNode($"[{index}] {colName} ##{col.GetHashCode()}")) { if (element != null && ImGui.IsItemHovered()) { if (element.Width > 0 && element.Height > 0) { Graphics.DrawFrame(element.GetClientRectCache, ColorSwaper.Value, 2); } } Debug(col, colType); ImGui.TreePop(); } if (isElementEnumerable && element != null) { if (ImGui.IsItemHovered()) { if (element.Width > 0 && element.Height > 0) { Graphics.DrawFrame(element.GetClientRectCache, ColorSwaper.Value, 2); } } } } if (index - skip > Settings.LimitForCollection) { ImGui.TreePop(); break; } } ImGui.TreePop(); } } else { ImGui.Indent(); ImGui.TextColored(Color.Red.ToImguiVec4(), $"{property.Name} [Empty]"); ImGui.Unindent(); } } //Debug others objects else { if (property.Name.Equals("Value")) { Debug(propertyValue); } else { string name; var isMemoryObj = propertyValue is RemoteMemoryObject; if (isMemoryObj) { name = $"{property.Name} [{((RemoteMemoryObject) propertyValue).Address:X}]##{type.FullName}"; } else { name = $"{property.Name} ##{type.FullName}"; } if (ImGui.TreeNode(name)) { Debug(propertyValue); ImGui.TreePop(); } if (isMemoryObj) { switch (propertyValue) { case Element e: if (ImGui.IsItemHovered()) { if (e.Width > 0 && e.Height > 0) { Graphics.DrawFrame(e.GetClientRectCache, ColorSwaper.Value, 2); } } break; } } } } } } ImGui.EndTabItem(); } if (ImGui.BeginTabItem("Fields")) { /*var strId = $"Fields##{obj.GetHashCode()}"; * if (ImGui.TreeNode(strId)) * {*/ var fields = type.GetFields(Flags); foreach (var field in fields) { var fieldValue = field.GetValue(obj); if (IsSimpleType(field.FieldType)) //if(Convert.GetTypeCode(fieldValue) != TypeCode.Object) { ImGui.Text($"{field.Name}: "); ImGui.SameLine(); ImGui.PushStyleColor(ImGuiCol.Text, new ImGuiVector4(1, 0.647f, 0, 1)); ImGui.PushStyleColor(ImGuiCol.Button, new ImGuiVector4(0, 0, 0, 0)); ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new ImGuiVector4(0.25f, 0.25f, 0.25f, 1)); ImGui.PushStyleColor(ImGuiCol.ButtonActive, new ImGuiVector4(1, 1, 1, 1)); if (ImGui.SmallButton($"{fieldValue}")) { ImGui.SetClipboardText($"{fieldValue}"); } ImGui.PopStyleColor(4); } else { if (ImGui.TreeNode($"{field.Name} {type.FullName}")) { Debug(fieldValue); ImGui.TreePop(); } } } /*ImGui.TreePop(); * }*/ ImGui.EndTabItem(); } if (isMemoryObject != null && ImGui.BeginTabItem("Dynamic")) { var remoteMemoryObject = (RemoteMemoryObject)obj; ImGui.TextColored(Color.GreenYellow.ToImguiVec4(), $"Address: "); if (ImGui.IsItemClicked()) { ImGui.SetClipboardText(remoteMemoryObject.Address.ToString()); } ImGui.SameLine(); ImGui.PushStyleColor(ImGuiCol.Text, new ImGuiVector4(1, 0.647f, 0, 1)); ImGui.PushStyleColor(ImGuiCol.Button, new ImGuiVector4(0, 0, 0, 0)); ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new ImGuiVector4(0.25f, 0.25f, 0.25f, 1)); ImGui.PushStyleColor(ImGuiCol.ButtonActive, new ImGuiVector4(1, 1, 1, 1)); if (ImGui.SmallButton($"{remoteMemoryObject.Address:X}")) { ImGui.SetClipboardText(remoteMemoryObject.Address.ToString()); } ImGui.PopStyleColor(4); ImGui.EndTabItem(); switch (remoteMemoryObject) { case Entity e: var key = $"{e.Address}{e.Id}{e.Path}"; if (e.GetComponent <Render>() != null) { if (ImGui.TreeNode($"World position##{remoteMemoryObject.Address}")) { var pos = e.Pos; var renderComponentBounds = e.GetComponent <Render>().Bounds; var toScreen = GameController.IngameState.Camera.WorldToScreen(pos); ImGui.Text($"Position: {pos}"); ImGui.Text($"To Screen: {toScreen}"); Graphics.DrawFrame(toScreen.ToVector2Num(), toScreen.TranslateToNum(renderComponentBounds.X, -renderComponentBounds.Y), Color.Orange, 0, 1, 0); } } break; case Element e: var keyForOffsetFinder = $"{e.Address}{e.GetHashCode()}"; if (OffsetFinder.TryGetValue(keyForOffsetFinder, out var offset)) { ImGui.TextColored(Color.Aqua.ToImguiVec4(), $"Offset: {offset:X}"); } else { var parent = e.Parent; if (parent != null) { var pointers = e.M.ReadPointersArray(parent.Address, parent.Address + 8000 * 0x8); var found = false; for (var index = 0; index < pointers.Count; index++) { var p = pointers[index]; if (p == e.Address) { OffsetFinder[keyForOffsetFinder] = index * 0x8; found = true; break; } } if (!found) { OffsetFinder[keyForOffsetFinder] = -1; } } else { OffsetFinder[keyForOffsetFinder] = -1; } } if (ImGui.Button($"Change Visible##{e.GetHashCode()}")) { var currentState = e.IsVisibleLocal; var offsetELementIsVivible = Extensions.GetOffset <ElementOffsets>(nameof(ElementOffsets.IsVisibleLocal)); var b = (byte)(currentState ? 19 : 23); var writeProcessMemory = ProcessMemory.WriteProcessMemory(e.M.OpenProcessHandle, new IntPtr(e.Address + offsetELementIsVivible), b); } break; } } ImGui.EndTabBar(); ImGui.Unindent(); } catch (Exception e) { LogError($"{Name} -> {e}"); } }