private void FillTextureUsingLockRectangle() { if (doubleBuffer.LockFrontBufferForReading(500)) { try { //if device already updated, don't do it again, this should only happen in case we're using dx9ex shared textures List <Device> devicesDone = new List <Device>(); foreach (Device d in device2DoubleTexture.Keys) { //Log( LogType.Debug, "[FillTextureUsingLockRectangle] " + "TEXTURE on device " + d.ComPointer.ToInt64() + " SHOULD BE updated..." ); } foreach (DoubleTexture t2 in device2DoubleTexture.Values) { //Log( LogType.Debug, " fill doubletexture " + t2.GetBackTexture().ComPointer.ToInt64() + "\n" ); try { if (t2.LockBackTextureForWriting(100)) { if (t2.GetBackTexture() == null) { Log(LogType.Error, "[FillTextureUsingLockRectangle ERROR] " + "TEXTURE == null !!!"); } else if (t2.GetBackTexture() != null && t2.GetBackTexture().Disposed) { Log(LogType.Error, "[FillTextureUsingLockRectangle ERROR] " + "TEXTURE disposed !!!"); } else if (t2.GetWidth() != doubleBuffer.GetWidth() || t2.GetHeight() != doubleBuffer.GetHeight()) { textureNeedsResizingOnEvaluate = true; //Log( LogType.Debug, "[FillTextureUsingLockRectangle WARNING] " + "TEXTURE size wrong !" ); } else if (devicesDone.Contains(t2.GetDevice())) { Log(LogType.Debug, "[FillTextureUsingLockRectangle] " + "TEXTURE on device " + t2.GetDevice().ComPointer.ToInt64() + " already updated, don't do it again..."); } else { //DataRectangle rDst = t2.GetBackTexture().LockRectangle(0, LockFlags.Discard); //rDst.Data.WriteRange( GetReadPixelPlane(), t2.GetPitch() * t2.GetHeight() ); //t2.GetBackTexture().UnlockRectangle(0); bool err = false; DataRectangle rDst = null; try { rDst = t2.GetBackTexture().LockRectangle(0, LockFlags.Discard); } catch { err = true; Log(LogType.Error, "[FillTextureUsingLockRectangle ERROR] lockrectangle failed"); } try { if (t2.GetPitch() == t2.GetWidth() * 4) { rDst.Data.WriteRange(doubleBuffer.GetFrontBuffer(), t2.GetPitch() * t2.GetHeight()); } else { //writing line per line IntPtr fb = doubleBuffer.GetFrontBuffer(); int width = doubleBuffer.GetWidth() * 4; int rest = t2.GetPitch() - width; for (int line = 0; line < t2.GetHeight(); line++) { rDst.Data.WriteRange(IntPtr.Add(fb, line * width), width); rDst.Data.Position += rest; //rDst.Data.WriteRange( IntPtr.Add( fb, line * width ), rest ); } } } catch { err = true; Log(LogType.Error, "[FillTextureUsingLockRectangle ERROR] writerange failed"); } try { t2.GetBackTexture().UnlockRectangle(0); } catch { err = true; Log(LogType.Error, "[FillTextureUsingLockRectangle ERROR] UNlockrectangle failed"); } t2.UnlockBackTexture(); if (t2.ToggleFrontBack()) { deviceDataNeedsUpdatingOnEvaluate = true; } if (!err) { devicesDone.Add(t2.GetDevice()); } } t2.UnlockBackTexture(); } } catch (Exception e) { Log(LogType.Error, "[FillTextureUsingLockRectangle ERROR] " + e.Message); } } } catch (Exception e) { Log(LogType.Error, "[FillTextureUsingLockRectangle ERROR] (source) " + e.Message); } doubleBuffer.UnlockFrontBuffer(); } }
public SCRIPTING_METHOD_PARAMS_Wraper(SCRIPTING_METHOD_PARAMS prms) { name = Marshal.PtrToStringAnsi(prms.name); args = new SciterValue[prms.argc]; result = SciterValue.Undefined; for (int i = 0; i < prms.argc; i++) { args[i] = new SciterValue((SciterXValue.VALUE)Marshal.PtrToStructure(IntPtr.Add(prms.argv, i * Marshal.SizeOf(typeof(SciterXValue.VALUE))), typeof(SciterXValue.VALUE))); } }
public void UpdateWowObjects() { IsWorldLoaded = UpdateGlobalVar <int>(WowInterface.OffsetList.IsWorldLoaded) == 1; if (!IsWorldLoaded) { return; } PlayerGuid = UpdateGlobalVar <ulong>(WowInterface.OffsetList.PlayerGuid); TargetGuid = UpdateGlobalVar <ulong>(WowInterface.OffsetList.TargetGuid); LastTargetGuid = UpdateGlobalVar <ulong>(WowInterface.OffsetList.LastTargetGuid); PetGuid = UpdateGlobalVar <ulong>(WowInterface.OffsetList.PetGuid); PlayerBase = UpdateGlobalVar <IntPtr>(WowInterface.OffsetList.PlayerBase); MapId = UpdateGlobalVar <MapId>(WowInterface.OffsetList.MapId); ZoneId = UpdateGlobalVar <int>(WowInterface.OffsetList.ZoneId); if (WowInterface.XMemory.Read(WowInterface.OffsetList.ZoneText, out IntPtr zoneNamePointer)) { ZoneName = UpdateGlobalVarString(zoneNamePointer); } if (WowInterface.XMemory.Read(WowInterface.OffsetList.ZoneSubText, out IntPtr zoneSubNamePointer)) { ZoneSubName = UpdateGlobalVarString(zoneSubNamePointer); } GameState = UpdateGlobalVarString(WowInterface.OffsetList.GameState); WowObjects.Clear(); // get the current objectmanager // TODO: maybe cache it WowInterface.XMemory.Read(WowInterface.OffsetList.ClientConnection, out IntPtr clientConnection); WowInterface.XMemory.Read(IntPtr.Add(clientConnection, WowInterface.OffsetList.CurrentObjectManager.ToInt32()), out IntPtr currentObjectManager); // read the first object WowInterface.XMemory.Read(IntPtr.Add(currentObjectManager, WowInterface.OffsetList.FirstObject.ToInt32()), out IntPtr activeObjectBaseAddress); WowInterface.XMemory.Read(IntPtr.Add(activeObjectBaseAddress, WowInterface.OffsetList.WowObjectType.ToInt32()), out int activeObjectType); while (IsWorldLoaded && (activeObjectType <= 7 && activeObjectType > 0)) { WowObjectType wowObjectType = (WowObjectType)activeObjectType; WowObject obj = wowObjectType switch { WowObjectType.Container => ReadWowContainer(activeObjectBaseAddress, wowObjectType), WowObjectType.Corpse => ReadWowCorpse(activeObjectBaseAddress, wowObjectType), WowObjectType.Item => ReadWowItem(activeObjectBaseAddress, wowObjectType), WowObjectType.Dynobject => ReadWowDynobject(activeObjectBaseAddress, wowObjectType), WowObjectType.Gameobject => ReadWowGameobject(activeObjectBaseAddress, wowObjectType), WowObjectType.Player => ReadWowPlayer(activeObjectBaseAddress, wowObjectType), WowObjectType.Unit => ReadWowUnit(activeObjectBaseAddress, wowObjectType), _ => ReadWowObject(activeObjectBaseAddress, wowObjectType), }; if (obj != null) { WowObjects.Add(obj); // set the global unit properties if a guid matches it if (obj.Guid == TargetGuid) { Target = (WowUnit)obj; } if (obj.Guid == PetGuid) { Pet = (WowUnit)obj; } if (obj.Guid == LastTargetGuid) { LastTarget = (WowUnit)obj; } } WowInterface.XMemory.Read(IntPtr.Add(activeObjectBaseAddress, WowInterface.OffsetList.NextObject.ToInt32()), out activeObjectBaseAddress); WowInterface.XMemory.Read(IntPtr.Add(activeObjectBaseAddress, WowInterface.OffsetList.WowObjectType.ToInt32()), out activeObjectType); } // read the party/raid leaders guid and if there is one, the group too PartyleaderGuid = ReadPartyLeaderGuid(); if (PartyleaderGuid > 0) { PartymemberGuids = ReadPartymemberGuids(); } OnObjectUpdateComplete?.Invoke(WowObjects); }
private static void ApplyAllPatches(IntPtr processHandle, IntPtr baseAddress) { // NOTE: you can make a 'patches.txt' file, using the format '0x1234:9090' where 0x1234 indicates the offset (game.exe+0x1234) and 9090 indicates the patch value (nop nop) string patchesContent = ""; if (File.Exists("patches.txt")) { patchesContent = File.ReadAllText("patches.txt"); } if (patchesContent == "") { ConsolePrint("WARNING: Not patches are beeing loaded. (If this is unexpected, double check your 'patches.txt' file!)", ConsoleColor.Yellow); return; } string[] split = patchesContent.Split('\n'); int[] addr = new int[split.Length]; byte[][] patch = new byte[split.Length][]; // init arrays for (int i = 0; i < split.Length; i++) { string[] data = split[i].Split(':'); if (data.Length < 2) { continue; // probs empty line } addr[i] = Convert.ToInt32(data[0], 0x10); if (addr[i] == 0) { continue; } if (data[1][0] == '+') { // offset patch string offset = data[1].Substring(1); //byte[] buf = new byte[offset.Length / 2]; // amount of bytes in patch len? byte[] buf = new byte[8]; // qword if (!ReadProcessMemory(processHandle, IntPtr.Add(baseAddress, addr[i]), buf, buf.Length, out _)) { ConsolePrint("Error, failed read patch location!", ConsoleColor.Yellow); continue; // non critical, just skip } patch[i] = BitConverter.GetBytes(BitConverter.ToInt64(buf, 0) + Convert.ToInt64(offset, 0x10)); } else { // normal patch patch[i] = new byte[data[1].Length / 2]; for (int j = 0; j < patch[i].Length; j++) { patch[i][j] = Convert.ToByte(data[1].Substring(j * 2, 2), 0x10); } } } // patch arrays for (int i = 0; i < split.Length; i++) { if (addr[i] == 0) { continue; } if (patch[i] == null) { ConsolePrint($"Invalid patch at line {i+1}!", ConsoleColor.Yellow); continue; } ConsolePrint($"Patching 0x{(baseAddress+addr[i]).ToString("X8")}"); if (!WriteProcessMemory(processHandle, IntPtr.Add(baseAddress, addr[i]), patch[i], patch[i].Length, out IntPtr bWritten1) || (int)bWritten1 != patch[i].Length) { ConsolePrint($"Patch {i} failed!!", ConsoleColor.Red); } } }
public unsafe override JObject GetJobSpecificData(EntityJob job) { if (!HasProcess() || job_data_outer_addr_ == IntPtr.Zero) { return(null); } IntPtr job_inner_ptr = ReadIntPtr(job_data_outer_addr_); if (job_inner_ptr == IntPtr.Zero) { // The pointer can be null when not logged in. return(null); } job_inner_ptr = IntPtr.Add(job_inner_ptr, kJobDataInnerStructOffset); fixed(byte *p = Read8(job_inner_ptr, kJobDataInnerStructSize)) { if (p == null) { return(null); } else { switch (job) { case EntityJob.RDM: return(JObject.FromObject(*(RedMageJobMemory *)&p[0])); case EntityJob.WAR: return(JObject.FromObject(*(WarriorJobMemory *)&p[0])); case EntityJob.DRK: return(JObject.FromObject(*(DarkKnightJobMemory *)&p[0])); case EntityJob.PLD: return(JObject.FromObject(*(PaladinJobMemory *)&p[0])); case EntityJob.GNB: return(JObject.FromObject(*(GunbreakerJobMemory *)&p[0])); case EntityJob.BRD: return(JObject.FromObject(*(BardJobMemory *)&p[0])); case EntityJob.DNC: return(JObject.FromObject(*(DancerJobMemory *)&p[0])); case EntityJob.DRG: return(JObject.FromObject(*(DragoonJobMemory *)&p[0])); case EntityJob.NIN: return(JObject.FromObject(*(NinjaJobMemory *)&p[0])); case EntityJob.THM: return(JObject.FromObject(*(ThaumaturgeJobMemory *)&p[0])); case EntityJob.BLM: return(JObject.FromObject(*(BlackMageJobMemory *)&p[0])); case EntityJob.WHM: return(JObject.FromObject(*(WhiteMageJobMemory *)&p[0])); case EntityJob.ACN: return(JObject.FromObject(*(ArcanistJobMemory *)&p[0])); case EntityJob.SMN: return(JObject.FromObject(*(SummonerJobMemory *)&p[0])); case EntityJob.SCH: return(JObject.FromObject(*(ScholarJobMemory *)&p[0])); case EntityJob.MNK: return(JObject.FromObject(*(MonkJobMemory *)&p[0])); case EntityJob.MCH: return(JObject.FromObject(*(MachinistJobMemory *)&p[0])); case EntityJob.AST: return(JObject.FromObject(*(AstrologianJobMemory *)&p[0])); case EntityJob.SAM: return(JObject.FromObject(*(SamuraiJobMemory *)&p[0])); case EntityJob.SGE: return(JObject.FromObject(*(SageJobMemory *)&p[0])); case EntityJob.RPR: return(JObject.FromObject(*(ReaperJobMemory *)&p[0])); } return(null); } } }
public UInt32 get_status_action() { return((UInt32)Marshal.ReadInt32(IntPtr.Add(raw_addr, 4))); }
public void copy_send_event_data(byte[] dest, int dest_index) { Marshal.Copy(IntPtr.Add(raw_addr, 8), dest, dest_index, get_send_event_size()); }
public string ReadStringUnicode(string Module, int pOffset, int pSize) { return(this.CutString(Encoding.Unicode.GetString(this.ReadMem(IntPtr.Add(this.DllImageAddress(Module), pOffset), pSize)))); }
public uint ReadUInt(string Module, int pOffset) { return(BitConverter.ToUInt32(this.ReadMem(IntPtr.Add(this.DllImageAddress(Module), pOffset), 4), 0)); }
public long ReadLong(string Module, int pOffset) { return(BitConverter.ToInt64(this.ReadMem(IntPtr.Add(this.DllImageAddress(Module), pOffset), 8), 0)); }
public short ReadShort(string Module, int pOffset) { return(BitConverter.ToInt16(this.ReadMem(IntPtr.Add(this.DllImageAddress(Module), pOffset), 2), 0)); }
public float ReadFloat(string Module, int pOffset) { return(BitConverter.ToSingle(this.ReadMem(IntPtr.Add(this.DllImageAddress(Module), pOffset), 4), 0)); }
public byte ReadByte(string Module, int pOffset) { byte[] buffer = new byte[1]; ReadProcessMemory(this.processHandle, IntPtr.Add(this.DllImageAddress(Module), pOffset), buffer, 1, 0); return(buffer[0]); }
public Bitmap getScreenDX() { if (System.Windows.Forms.Screen.AllScreens[0].Bounds.Width != LEDSetup.SCREEN_W) { return(null); } try { SharpDX.DXGI.Resource screenResource; OutputDuplicateFrameInformation duplicateFrameInformation; // Try to get duplicated frame within given time duplicatedOutput.AcquireNextFrame(1000, out duplicateFrameInformation, out screenResource); // copy resource into memory that can be accessed by the CPU using (var screenTexture2D = screenResource.QueryInterface <Texture2D>()) device.ImmediateContext.CopyResource(screenTexture2D, screenTexture); // Get the desktop capture texture var mapSource = device.ImmediateContext.MapSubresource(screenTexture, 0, MapMode.Read, SharpDX.Direct3D11.MapFlags.None); // Create Drawing.Bitmap var bitmap = new System.Drawing.Bitmap(LEDSetup.SCREEN_W, LEDSetup.SCREEN_H, PixelFormat.Format32bppArgb); var boundsRect = new System.Drawing.Rectangle(0, 0, LEDSetup.SCREEN_W, LEDSetup.SCREEN_H); // Copy pixels from screen capture Texture to GDI bitmap var mapDest = bitmap.LockBits(boundsRect, ImageLockMode.WriteOnly, bitmap.PixelFormat); var sourcePtr = mapSource.DataPointer; var destPtr = mapDest.Scan0; for (int y = 0; y < LEDSetup.SCREEN_H; y++) { // Copy a single line Utilities.CopyMemory(destPtr, sourcePtr, LEDSetup.SCREEN_W * 4); // Advance pointers sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch); destPtr = IntPtr.Add(destPtr, mapDest.Stride); } // Release source and dest locks bitmap.UnlockBits(mapDest); device.ImmediateContext.UnmapSubresource(screenTexture, 0); // Save the output //bitmap.Save(outputFileName, ImageFormat.Png); // Capture done screenResource.Dispose(); duplicatedOutput.ReleaseFrame(); invalid_calls = 0; return(bitmap); } catch (SharpDXException e) { if (e.ResultCode.Code != SharpDX.DXGI.ResultCode.WaitTimeout.Result.Code)// && e.ResultCode != SharpDX.DXGI.ResultCode.InvalidCall.Result.Code) { if (e.ResultCode.Code == SharpDX.DXGI.ResultCode.AccessLost.Result.Code) { Logger.QueueLine("Device access lost, reinitializing duplication"); setupDX(); System.Threading.Thread.Sleep(200); } else if (e.ResultCode.Code == SharpDX.DXGI.ResultCode.DeviceRemoved.Code) { Logger.QueueLine("Device removed, reinitializing duplication"); setupDX(); System.Threading.Thread.Sleep(200); } else if (e.ResultCode.Code == SharpDX.DXGI.ResultCode.InvalidCall.Code) { invalid_calls++; if (invalid_calls >= 10) { Logger.QueueLine("Too many invalid calls, reinitializing duplication"); setupDX(); } System.Threading.Thread.Sleep(200); } else { throw e; } } } catch (Exception e) { } return(null); }
private bool GetPointerAddress() { if (!memory.IsValid()) { return(false); } // Don't scan too often to avoid excessive CPU load if ((DateTime.Now - lastSigScan) < TimeSpan.FromSeconds(5)) { return(false); } lastSigScan = DateTime.Now; bool success = true; bool bRIP = true; List <string> fail = new List <string>(); /// CHARMAP List <IntPtr> list = memory.SigScan(charmapSignature, 0, bRIP); if (list != null && list.Count > 0) { charmapAddress = list[0] + charmapSignatureOffset; } else { charmapAddress = IntPtr.Zero; fail.Add(nameof(charmapAddress)); success = false; } // ENMITY list = memory.SigScan(enmitySignature, 0, bRIP); if (list != null && list.Count > 0) { enmityAddress = IntPtr.Add(list[0], enmitySignatureOffset); aggroAddress = IntPtr.Add(list[0], aggroEnmityOffset); } else { enmityAddress = IntPtr.Zero; aggroAddress = IntPtr.Zero; fail.Add(nameof(enmityAddress)); fail.Add(nameof(aggroAddress)); success = false; } /// TARGET list = memory.SigScan(targetSignatureH1, 0, bRIP); if (list == null || list.Count == 0) { list = memory.SigScan(targetSignatureH0, 0, bRIP); } if (list != null && list.Count > 0) { targetAddress = list[0] + targetSignatureOffset; } else { targetAddress = IntPtr.Zero; fail.Add(nameof(targetAddress)); success = false; } logger.Log(LogLevel.Debug, "charmapAddress: 0x{0:X}", charmapAddress.ToInt64()); logger.Log(LogLevel.Debug, "enmityAddress: 0x{0:X}", enmityAddress.ToInt64()); logger.Log(LogLevel.Debug, "aggroAddress: 0x{0:X}", aggroAddress.ToInt64()); logger.Log(LogLevel.Debug, "targetAddress: 0x{0:X}", targetAddress.ToInt64()); Combatant c = GetSelfCombatant(); if (c != null) { logger.Log(LogLevel.Debug, "MyCharacter: '{0}' (0x{1:X})", c.Name, c.ID); } if (!success) { logger.Log(LogLevel.Error, "Failed to memory scan 5.2: {0}.", String.Join(",", fail)); } else { logger.Log(LogLevel.Info, "Found enmity memory for 5.2."); } return(success); }
public void WriteByte(string Module, int pOffset, byte pBytes) { this.WriteMem(IntPtr.Add(this.DllImageAddress(Module), pOffset), BitConverter.GetBytes((short)pBytes)); }
public equ8_err get_error_code() { return(equ8_err.create((UInt64)Marshal.ReadInt64(IntPtr.Add(raw_addr, 4)))); }
public void WriteStringUnicode(string Module, int pOffset, string pBytes) { this.WriteMem(IntPtr.Add(this.DllImageAddress(Module), pOffset), Encoding.Unicode.GetBytes(pBytes + "\0")); }
public int get_send_event_size() { return((int)Marshal.ReadInt32(IntPtr.Add(raw_addr, 4))); }
public void WriteUInt(string Module, int pOffset, uint pBytes) { this.WriteMem(IntPtr.Add(this.DllImageAddress(Module), pOffset), BitConverter.GetBytes(pBytes)); }
/// <summary> /// IOCTL_ATA_PASS_THROUGH IOCTL ( https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntddscsi/ni-ntddscsi-ioctl_ata_pass_through ) /// </summary> /// <param name="IoControl"></param> /// <param name="Header"></param> /// <param name="Data"></param> /// <param name="AtaFlags"></param> /// <param name="PathId"></param> /// <param name="TargetId"></param> /// <param name="Lun"></param> /// <param name="ReservedAsUchar"></param> /// <param name="TimeOutValue"></param> /// <param name="ReservedAsUlong"></param> /// <param name="Feature"></param> /// <param name="SectorCouont"></param> /// <param name="SectorNumber"></param> /// <param name="Cylinder"></param> /// <param name="DeviceHead"></param> /// <param name="Command"></param> /// <param name="Reserved"></param> /// <param name="DataSize"></param> /// <returns></returns> public static bool AtaPassThrough(this IoControl IoControl, out IAtaPassThroughEx Header, out byte[] Data, AtaFlags AtaFlags, byte PathId = default, byte TargetId = default, byte Lun = default, byte ReservedAsUchar = default, uint TimeOutValue = default, uint ReservedAsUlong = default, ushort Feature = default, ushort SectorCouont = default, ushort SectorNumber = default, uint Cylinder = default, byte DeviceHead = default, byte Command = default, ushort Reserved = default, uint DataSize = default) { var _Size = Marshal.SizeOf <AtaPassThroughEx>(); var DataTransferLength = DataSize; var DataBufferOffset = DataSize == 0 ? 0 : _Size; Header = IntPtr.Size == 8 ? (IAtaPassThroughEx) new AtaPassThroughEx( AtaFlags: AtaFlags, PathId: PathId, TargetId: TargetId, Lun: Lun, ReservedAsUchar: ReservedAsUchar, TimeOutValue: TimeOutValue, ReservedAsUlong: ReservedAsUlong, Feature: Feature, SectorCouont: SectorCouont, SectorNumber: SectorNumber, Cylinder: Cylinder, DeviceHead: DeviceHead, Command: Command, Reserved: Reserved, DataTransferLength: DataTransferLength, DataBufferOffset: DataBufferOffset ): IntPtr.Size == 4 ? new AtaPassThroughEx32( AtaFlags: AtaFlags, PathId: PathId, TargetId: TargetId, Lun: Lun, ReservedAsUchar: ReservedAsUchar, TimeOutValue: TimeOutValue, ReservedAsUlong: ReservedAsUlong, Feature: Feature, SectorCouont: SectorCouont, SectorNumber: SectorNumber, Cylinder: Cylinder, DeviceHead: DeviceHead, Command: Command, Reserved: Reserved, DataTransferLength: DataTransferLength, DataBufferOffset: DataBufferOffset ): throw new NotSupportedException(); var Size = (uint)(_Size + DataSize); var Ptr = Marshal.AllocCoTaskMem((int)Size); using (Disposable.Create(() => Marshal.FreeCoTaskMem(Ptr))) { Marshal.StructureToPtr(Header, Ptr, false); var result = IoControl.DeviceIoControl(IOControlCode.AtaPassThrough, Ptr, Size, out var _); Header = result ? (AtaPassThroughEx)Marshal.PtrToStructure(Ptr, typeof(AtaPassThroughEx)) : default; if (DataSize > 0) { Data = new byte[DataSize]; Marshal.Copy(IntPtr.Add(Ptr, _Size), Data, 0, Data.Length); } else { Data = default; } return(result); } }
public IntPtr ImageAddress(int pOffset) { this.myProcessModule = this.MyProcess[0].MainModule; this.BaseAddress = this.myProcessModule.BaseAddress; return(IntPtr.Add(this.BaseAddress, pOffset)); }
internal override void ReadSignatures() { List <IntPtr> p; // TODO: for now, support multiple matches on charmap signature. // This sig returns two matches that are identical for many, many characters. // They both point to the same spot, so verify these have the same value. p = SigScan(kCharmapSignature, kCharmapSignatureOffset, kCharmapSignatureRIP); if (p.Count == 0) { logger_.Log(LogLevel.Error, Strings.CharmapSignatureFoundMultipleMatchesErrorMessage, p.Count); } else { IntPtr player_ptr_value = IntPtr.Zero; foreach (IntPtr ptr in p) { IntPtr addr = IntPtr.Add(ptr, kCharmapStructOffsetPlayer); IntPtr value = ReadIntPtr(addr); if (player_ptr_value == IntPtr.Zero || player_ptr_value == value) { player_ptr_value = value; player_ptr_addr_ = addr; } else { logger_.Log(LogLevel.Error, Strings.CharmapSignatureConflictingMatchErrorMessage); } } } p = SigScan(kJobDataSignature, kJobDataSignatureOffset, kJobDataSignatureRIP); if (p.Count != 1) { logger_.Log(LogLevel.Error, Strings.JobSignatureFoundMultipleMatchesErrorMessage, p.Count); } else { job_data_outer_addr_ = IntPtr.Add(p[0], kJobDataOuterStructOffset); } p = SigScan(kInCombatSignature, kInCombatSignatureOffset, kInCombatSignatureRIP, kInCombatRipOffset); if (p.Count != 1) { logger_.Log(LogLevel.Error, Strings.InCombatSignatureFoundMultipleMatchesErrorMessage, p.Count); } else { in_combat_addr_ = p[0]; } p = SigScan(kBaitSignature, kBaitBaseOffset, kBaitBaseRIP); if (p.Count != 1) { logger_.Log(LogLevel.Error, Strings.BaitSignatureFoundMultipleMatchesErrorMessage, p.Count); } else { bait_addr_ = p[0]; } }
public IntPtr CreateCodeCave(IntPtr address, int targetBytesCount, string[] cavemnemonics, Classes.DetourType detourType = Classes.DetourType.JMP, bool x64Process = false) { int finalDetourMethodType = 1; /* * 1: 32Bit Jmp - Relative Address (5 bytes) * 2: 32Bit Push, Ret (6 bytes) * 3: 64bit Jmp Relative Address (12 bytes) * 4: 64bit Push "XCHG" Absolute Address (16 bytes) */ int BYTES_NEEDED = 5; Classes.RemoteMemory codecave = _mainReference.Allocator.AllocateMemory(0x10000); if (!codecave.IsValid) { return(IntPtr.Zero); } if (x64Process) { if (detourType == Classes.DetourType.JMP) { IntPtr relAddressCheck = new IntPtr(codecave.BaseAddress.ToInt64() - address.ToInt64() - BYTES_NEEDED); if (relAddressCheck.ToInt64() > Classes.TWO_GIGABYTES || relAddressCheck.ToInt64() < -Classes.TWO_GIGABYTES) { finalDetourMethodType = 4; BYTES_NEEDED = 16; } else { finalDetourMethodType = 3; BYTES_NEEDED = 12; } } } else { finalDetourMethodType = detourType == Classes.DetourType.JMP ? 1 : 2; if (detourType == Classes.DetourType.JMP) { finalDetourMethodType = 1; BYTES_NEEDED = 5; } else { finalDetourMethodType = 2; BYTES_NEEDED = 6; } } if (targetBytesCount < BYTES_NEEDED) { return(IntPtr.Zero); } int NOPS_NEEDED = targetBytesCount - BYTES_NEEDED; List <string> nops = new List <string>(); for (int i = 0; i < NOPS_NEEDED; i++) { nops.Add("nop"); } IntPtr relAddressToCodeCave32Bit = IntPtr.Zero; IntPtr relAddressToCodeCave64Bit = IntPtr.Zero; List <string> jumpInMnemonics = new List <string>(); switch (finalDetourMethodType) { case 1: // 32Bit Jmp (5 bytes) relAddressToCodeCave32Bit = IntPtr.Subtract(codecave.BaseAddress, address.ToInt32() - BYTES_NEEDED); jumpInMnemonics.InsertRange(0, new string[] { "use32", $"jmp 0x{relAddressToCodeCave32Bit.ToInt32():X}" }); jumpInMnemonics.AddRange(nops); break; case 2: // 32Bit PushRet (6 bytes) jumpInMnemonics.InsertRange(0, new string[] { "use32", $"push 0x{codecave.BaseAddress.ToInt32():X}", "ret" }); jumpInMnemonics.AddRange(nops); break; case 3: case 4: // 64Bit PushRet (16 bytes) jumpInMnemonics.InsertRange(0, new string[] { "use64", "push rax", $"mov rax, 0x{codecave.BaseAddress.ToInt64():X}", "xchg rax, [rsp]", "ret" }); jumpInMnemonics.AddRange(nops); break; } byte[] jumpInBytes = _mainReference.Assembler.Assemble(jumpInMnemonics.ToArray()); List <string> jumpOutMnemonics = new List <string>() { (x64Process ? "use64" : "use32"), "<cavemnemonics>", "<jmpout>" }; jumpOutMnemonics.InsertRange(jumpOutMnemonics.IndexOf("<cavemnemonics>"), cavemnemonics); jumpOutMnemonics.RemoveAt(jumpOutMnemonics.IndexOf("<cavemnemonics>")); if (x64Process) { jumpOutMnemonics.InsertRange(jumpOutMnemonics.IndexOf("<jmpout>"), new string[] { "push rax", $"mov rax, 0x{IntPtr.Add(address, targetBytesCount + NOPS_NEEDED).ToInt64():X}", "xchg rax, [rsp]", "ret" }); jumpOutMnemonics.RemoveAt(jumpOutMnemonics.IndexOf("<jmpout>")); } else { jumpOutMnemonics.InsertRange(jumpOutMnemonics.IndexOf("<jmpout>"), new string[] { $"push 0x{IntPtr.Add(address, targetBytesCount + NOPS_NEEDED).ToInt32():X}", "ret" }); jumpOutMnemonics.RemoveAt(jumpOutMnemonics.IndexOf("<jmpout>")); } byte[] originalBytes = _mainReference.Reader.ReadBytes(address, new IntPtr(targetBytesCount)); // Read Original Bytes _mainReference.Writer.WriteBytes(codecave.BaseAddress, originalBytes); // Write original bytes top of code cave byte[] jmpOutBytes = _mainReference.Assembler.Assemble(jumpOutMnemonics.ToArray()); // Assemble Codecave bytes _mainReference.Writer.WriteBytes(IntPtr.Add(codecave.BaseAddress, originalBytes.Length), jmpOutBytes); // WriteCodeCave bytes _mainReference.Writer.WriteBytes(address, jumpInBytes, Classes.MemoryProtection.ExecuteReadWrite); // write jump in bytes to target address return(codecave.BaseAddress); }
public override int CaptureWithCursor(FrameInfo frame) { var res = new Result(-1); var wasCaptured = false; try { //Try to get the duplicated output frame within given time. res = DuplicatedOutput.TryAcquireNextFrame(0, out var info, out var resource); //Checks how to proceed with the capture. It could have failed, or the screen, cursor or both could have been captured. if ((res.Failure || resource == null) && info.TotalMetadataBufferSize == 0 && info.LastMouseUpdateTime == 0) { //Somehow, it was not possible to retrieve the resource, frame or metadata. resource?.Dispose(); return(FrameCount); } else if (FrameCount == 0 && info.TotalMetadataBufferSize == 0 && info.LastMouseUpdateTime > 0) { //Sometimes, the first frame has cursor info, but no screen changes. GetCursor(null, info, frame); resource?.Dispose(); return(FrameCount); } #region Process changes //Something on screen was moved or changed. if (info.TotalMetadataBufferSize > 0 && resource != null) { //Copies the screen data into memory that can be accessed by the CPU. using (var screenTexture = resource.QueryInterface <Texture2D>()) { #region Moved rectangles var movedRectangles = new OutputDuplicateMoveRectangle[info.TotalMetadataBufferSize]; DuplicatedOutput.GetFrameMoveRects(movedRectangles.Length, movedRectangles, out var movedRegionsLength); for (var movedIndex = 0; movedIndex < movedRegionsLength / Marshal.SizeOf(typeof(OutputDuplicateMoveRectangle)); movedIndex++) { //Crop the destination rectangle to the scree area rectangle. var left = Math.Max(movedRectangles[movedIndex].DestinationRect.Left, Left); var right = Math.Min(movedRectangles[movedIndex].DestinationRect.Right, Left + Width); var top = Math.Max(movedRectangles[movedIndex].DestinationRect.Top, Top); var bottom = Math.Min(movedRectangles[movedIndex].DestinationRect.Bottom, Top + Height); //Copies from the screen texture only the area which the user wants to capture. if (right > left && bottom > top) { //Limit the source rectangle to the available size within the destination rectangle. var sourceWidth = movedRectangles[movedIndex].SourcePoint.X + (right - left); var sourceHeight = movedRectangles[movedIndex].SourcePoint.Y + (bottom - top); Device.ImmediateContext.CopySubresourceRegion(screenTexture, 0, new ResourceRegion(movedRectangles[movedIndex].SourcePoint.X, movedRectangles[movedIndex].SourcePoint.Y, 0, sourceWidth, sourceHeight, 1), BackingTexture, 0, left - Left, top - Top); wasCaptured = true; } } #endregion #region Dirty rectangles var dirtyRectangles = new RawRectangle[info.TotalMetadataBufferSize]; DuplicatedOutput.GetFrameDirtyRects(dirtyRectangles.Length, dirtyRectangles, out var dirtyRegionsLength); for (var dirtyIndex = 0; dirtyIndex < dirtyRegionsLength / Marshal.SizeOf(typeof(RawRectangle)); dirtyIndex++) { //Crop screen positions and size to frame sizes. var left = Math.Max(dirtyRectangles[dirtyIndex].Left, Left); var right = Math.Min(dirtyRectangles[dirtyIndex].Right, Left + Width); var top = Math.Max(dirtyRectangles[dirtyIndex].Top, Top); var bottom = Math.Min(dirtyRectangles[dirtyIndex].Bottom, Top + Height); //Copies from the screen texture only the area which the user wants to capture. if (right > left && bottom > top) { Device.ImmediateContext.CopySubresourceRegion(screenTexture, 0, new ResourceRegion(left, top, 0, right, bottom, 1), BackingTexture, 0, left - Left, top - Top); wasCaptured = true; } } #endregion } } //Copy the captured desktop texture into a staging texture, in order to show the mouse cursor and not make the captured texture dirty with it. Device.ImmediateContext.CopyResource(BackingTexture, StagingTexture); //Gets the cursor image and merges with the staging texture. if (!GetCursor(StagingTexture, info, frame) && !wasCaptured) { //Nothing was changed within the capture region, so ignore this frame. resource?.Dispose(); return(FrameCount); } //Saves the most recent capture time. LastProcessTime = Math.Max(info.LastPresentTime, info.LastMouseUpdateTime); #endregion #region Gets the image data //Get the desktop capture texture. var data = Device.ImmediateContext.MapSubresource(StagingTexture, 0, MapMode.Read, MapFlags.None); if (data.IsEmpty) { Device.ImmediateContext.UnmapSubresource(StagingTexture, 0); resource?.Dispose(); return(FrameCount); } var bitmap = new System.Drawing.Bitmap(Width, Height, PixelFormat.Format32bppArgb); var boundsRect = new System.Drawing.Rectangle(0, 0, Width, Height); //Copy pixels from screen capture Texture to the GDI bitmap. var mapDest = bitmap.LockBits(boundsRect, ImageLockMode.WriteOnly, bitmap.PixelFormat); var sourcePtr = data.DataPointer; var destPtr = mapDest.Scan0; for (var y = 0; y < Height; y++) { //Copy a single line. Utilities.CopyMemory(destPtr, sourcePtr, Width * 4); //Advance pointers. sourcePtr = IntPtr.Add(sourcePtr, data.RowPitch); destPtr = IntPtr.Add(destPtr, mapDest.Stride); } //Releases the source and dest locks. bitmap.UnlockBits(mapDest); //Set frame details. FrameCount++; frame.Path = $"{Project.FullPath}{FrameCount}.png"; frame.Delay = FrameRate.GetMilliseconds(); frame.Image = bitmap; BlockingCollection.Add(frame); #endregion Device.ImmediateContext.UnmapSubresource(StagingTexture, 0); resource?.Dispose(); return(FrameCount); } catch (SharpDXException se) when(se.ResultCode.Code == SharpDX.DXGI.ResultCode.WaitTimeout.Result.Code) { return(FrameCount); } catch (SharpDXException se) when(se.ResultCode.Code == SharpDX.DXGI.ResultCode.DeviceRemoved.Result.Code || se.ResultCode.Code == SharpDX.DXGI.ResultCode.DeviceReset.Result.Code) { //When the device gets lost or reset, the resources should be instantiated again. DisposeInternal(); Initialize(); return(FrameCount); } catch (Exception ex) { LogWriter.Log(ex, "It was not possible to finish capturing the frame with DirectX."); MajorCrashHappened = true; OnError.Invoke(ex); return(FrameCount); } finally { try { //Only release the frame if there was a success in capturing it. if (res.Success) { DuplicatedOutput.ReleaseFrame(); } } catch (Exception e) { LogWriter.Log(e, "It was not possible to release the frame."); } } }
public override IntPtr[] InjectAll(string[] dllPaths, IntPtr hProcess) { Exception exception; this.ClearErrors(); try { if (hProcess.IsNull() || hProcess.Compare(-1L)) { throw new ArgumentException("Invalid process handle.", "hProcess"); } int processId = WinAPI.GetProcessId(hProcess); if (processId == 0) { throw new ArgumentException("Provided handle doesn't have sufficient permissions to inject", "hProcess"); } Process processById = Process.GetProcessById(processId); if (processById.Threads.Count == 0) { throw new Exception("Target process has no targetable threads to hijack."); } ProcessThread thread = SelectOptimalThread(processById); IntPtr ptr = WinAPI.OpenThread(0x1a, false, thread.Id); if (ptr.IsNull() || ptr.Compare(-1L)) { throw new Exception("Unable to obtain a handle for the remote thread."); } IntPtr zero = IntPtr.Zero; IntPtr lpAddress = IntPtr.Zero; IntPtr ptr4 = this.CreateMultiLoadStub(dllPaths, hProcess, out zero, 1); IntPtr[] ptrArray = null; if (!ptr4.IsNull()) { if (WinAPI.SuspendThread(ptr) == uint.MaxValue) { throw new Exception("Unable to suspend the remote thread"); } try { uint lpNumberOfBytesRead = 0; WinAPI.CONTEXT pContext = new WinAPI.CONTEXT { ContextFlags = 0x10001 }; if (!WinAPI.GetThreadContext(ptr, ref pContext)) { throw new InvalidOperationException("Cannot get the remote thread's context"); } byte[] array = REDIRECT_STUB; IntPtr ptr5 = WinAPI.VirtualAllocEx(hProcess, IntPtr.Zero, (uint)array.Length, 0x3000, 0x40); if (ptr5.IsNull()) { throw new InvalidOperationException("Unable to allocate memory in the remote process."); } BitConverter.GetBytes(ptr4.Subtract(ptr5.Add(((long)7L))).ToInt32()).CopyTo(array, 3); BitConverter.GetBytes((uint)(pContext.Eip - ((uint)ptr5.Add(((long)array.Length)).ToInt32()))).CopyTo(array, (int)(array.Length - 4)); if (!(WinAPI.WriteProcessMemory(hProcess, ptr5, array, array.Length, out lpNumberOfBytesRead) && (lpNumberOfBytesRead == array.Length))) { throw new InvalidOperationException("Unable to write stub to the remote process."); } pContext.Eip = (uint)ptr5.ToInt32(); WinAPI.SetThreadContext(ptr, ref pContext); } catch (Exception exception1) { exception = exception1; this.SetLastError(exception); ptrArray = null; WinAPI.VirtualFreeEx(hProcess, zero, 0, 0x8000); WinAPI.VirtualFreeEx(hProcess, ptr4, 0, 0x8000); WinAPI.VirtualFreeEx(hProcess, lpAddress, 0, 0x8000); } WinAPI.ResumeThread(ptr); if (this.GetLastError() == null) { Thread.Sleep(100); ptrArray = new IntPtr[dllPaths.Length]; byte[] buffer2 = WinAPI.ReadRemoteMemory(hProcess, zero, ((uint)dllPaths.Length) << 2); if (buffer2 != null) { for (int i = 0; i < ptrArray.Length; i++) { ptrArray[i] = Win32Ptr.Create((long)BitConverter.ToInt32(buffer2, i << 2)); } } } WinAPI.CloseHandle(ptr); } return(ptrArray); } catch (Exception exception2) { exception = exception2; this.SetLastError(exception); return(null); } }
public GbmDisplay(string drmDevice) { _drmFd = LibC.Open(drmDevice, LibC.O_RDWR); IntPtr resourcesPtr = Drm.ModeGetResources(_drmFd); Drm.ModeRes resources = System.Runtime.InteropServices.Marshal.PtrToStructure <Drm.ModeRes>(resourcesPtr); for (int i = 0; i < resources.countConnectors; ++i) { uint connectorId = (uint)System.Runtime.InteropServices.Marshal.ReadInt32(resources.connectors, i * sizeof(uint)); IntPtr connectorPtr = Drm.ModeGetConnector(_drmFd, connectorId); Drm.ModeConnector connector = System.Runtime.InteropServices.Marshal.PtrToStructure <Drm.ModeConnector>(connectorPtr); if (connector.connection == Drm.MODE_CONNECTED) { _drmConnectorId = connector.connectorId; int SizeOfDrmModeModeInfo = System.Runtime.InteropServices.Marshal.SizeOf <Drm.ModeModeInfo>(); for (int j = 0; j < connector.countModes; ++j) { _drmMode = System.Runtime.InteropServices.Marshal.PtrToStructure <Drm.ModeModeInfo>(IntPtr.Add(connector.modes, j * SizeOfDrmModeModeInfo)); if ((_drmMode.type & Drm.MODE_TYPE_PREFERRED) != 0) { _width = _drmMode.hdisplay; _height = _drmMode.vdisplay; break; } } for (int j = 0; j < resources.countEncoders; ++j) { uint encoderId = (uint)System.Runtime.InteropServices.Marshal.ReadInt32(resources.encoders, j * sizeof(uint)); IntPtr encoderPtr = Drm.ModeGetEncoder(_drmFd, encoderId); Drm.ModeEncoder encoder = System.Runtime.InteropServices.Marshal.PtrToStructure <Drm.ModeEncoder>(encoderPtr); if (encoder.encoderId == connector.encoderId) { _drmEncoderCrtcId = encoder.crtcId; break; } Drm.ModeFreeEncoder(encoderPtr); } break; } Drm.ModeFreeConnector(connectorPtr); } Drm.ModeFreeResources(resourcesPtr); Drm.SetClientCap(_drmFd, Drm.CLIENT_CAP_UNIVERSAL_PLANES, 1); _gbmDevice = Gbm.CreateDevice(_drmFd); _gbmSurface = Gbm.SurfaceCreate(_gbmDevice, (uint)_width, (uint)_height, Drm.FORMAT_ARGB8888, Gbm.BO_USE_SCANOUT | Gbm.BO_USE_RENDERING); _gbmBoToDrmFb = new Dictionary <IntPtr, uint>(); LibEvdev.KeyDown += OnKeyDown; LibEvdev.KeyUp += OnKeyUp; LibEvdev.TouchDown += OnTouchDown; LibEvdev.TouchUp += OnTouchUp; LibEvdev.TouchMove += OnTouchMove; }
private bool GetPointerAddress() { if (!memory.IsValid()) { return(false); } // Don't scan too often to avoid excessive CPU load if ((DateTime.Now - lastSigScan) < TimeSpan.FromSeconds(5)) { return(false); } lastSigScan = DateTime.Now; bool success = true; bool bRIP = true; List <string> fail = new List <string>(); /// CHARMAP List <IntPtr> list = memory.SigScan(charmapSignature, 0, bRIP); if (list != null && list.Count > 0) { charmapAddress = list[0] + charmapSignatureOffset; } else { charmapAddress = IntPtr.Zero; fail.Add(nameof(charmapAddress)); success = false; } // ENMITY list = memory.SigScan(enmitySignature, 0, bRIP); if (list != null && list.Count > 0) { enmityAddress = IntPtr.Add(list[0], enmitySignatureOffset); aggroAddress = IntPtr.Add(list[0], aggroEnmityOffset); } else { enmityAddress = IntPtr.Zero; aggroAddress = IntPtr.Zero; fail.Add(nameof(enmityAddress)); fail.Add(nameof(aggroAddress)); success = false; } /// TARGET list = memory.SigScan(targetSignatureH1, 0, bRIP); if (list == null || list.Count == 0) { list = memory.SigScan(targetSignatureH0, 0, bRIP); } if (list != null && list.Count > 0) { targetAddress = list[0] + targetSignatureOffset; } else { targetAddress = IntPtr.Zero; fail.Add(nameof(targetAddress)); success = false; } /// IN COMBAT // The in combat address is set from a combination of two values, a base address and an offset. // They are found adjacent to the same signature, but at different offsets. var baseList = memory.SigScan(inCombatSignature, inCombatSignatureBaseOffset, bRIP); // SigScan returns pointers, but the offset is a 32-bit immediate value. Do not use RIP. var offsetList = memory.SigScan(inCombatSignature, inCombatSignatureOffsetOffset, false); if (baseList != null && baseList.Count > 0 && offsetList != null && offsetList.Count > 0) { var baseAddress = baseList[0]; var offset = (int)(((UInt64)offsetList[0]) & 0xFFFFFFFF); inCombatAddress = IntPtr.Add(baseAddress, offset); } else { inCombatAddress = IntPtr.Zero; fail.Add(nameof(inCombatAddress)); success = false; } logger.Log(LogLevel.Debug, "charmapAddress: 0x{0:X}", charmapAddress.ToInt64()); logger.Log(LogLevel.Debug, "enmityAddress: 0x{0:X}", enmityAddress.ToInt64()); logger.Log(LogLevel.Debug, "aggroAddress: 0x{0:X}", aggroAddress.ToInt64()); logger.Log(LogLevel.Debug, "targetAddress: 0x{0:X}", targetAddress.ToInt64()); logger.Log(LogLevel.Debug, "inCombatAddress: 0x{0:X}", inCombatAddress.ToInt64()); Combatant c = GetSelfCombatant(); if (c != null) { logger.Log(LogLevel.Debug, "MyCharacter: '{0}' (0x{1:X})", c.Name, c.ID); } if (!success) { if (loggedScanErrors < 10) { logger.Log(LogLevel.Error, "Failed to find enmity memory for 5.3: {0}.", String.Join(",", fail)); loggedScanErrors++; if (loggedScanErrors == 10) { logger.Log(LogLevel.Error, "Further enmity errors won't be logged."); } } } else { logger.Log(LogLevel.Info, "Found enmity memory for 5.3."); loggedScanErrors = 0; } return(success); }
private static string[] GetOSXCommandLineArguments() { // The following logic is based on https://gist.github.com/nonowarn/770696 // Set up the mib array and the query for process maximum args size var mib = new int[3]; int mibLength = 2; mib[0] = MACOS_CTL_KERN; mib[1] = MACOS_KERN_ARGMAX; int size = IntPtr.Size / 2; int argmax = 0; var argv = new List <string>(); var mibHandle = GCHandle.Alloc(mib, GCHandleType.Pinned); try { var mibPtr = mibHandle.AddrOfPinnedObject(); // Get the process args size SysCtl(mibPtr, mibLength, ref argmax, ref size, IntPtr.Zero, 0); // Get the PID so we can query this process' args var pid = Process.GetCurrentProcess().Id; // Now read the process args into the allocated space IntPtr procargs = Marshal.AllocHGlobal(argmax); try { mib[0] = MACOS_CTL_KERN; mib[1] = MACOS_KERN_PROCARGS2; mib[2] = pid; mibLength = 3; SysCtl(mibPtr, mibLength, procargs, ref argmax, IntPtr.Zero, 0); // The memory block we're reading is a series of null-terminated strings // that looks something like this: // // | argc | <int> is always 4 bytes long even on 64bit architectures // | exec_path | ... \0\0\0\0 * ? // | argv[0] | ... \0 // | argv[1] | ... \0 // | argv[2] | ... \0 // ... // | env[0] | ... \0 (VALUE = SOMETHING\0) // Read argc var argc = Marshal.ReadInt32(procargs); // Skip over argc var argvPtr = IntPtr.Add(procargs, sizeof(int)); // Skip over exec_path var offset = 0; while (Marshal.ReadByte(argvPtr, offset) != 0) { offset++; } while (Marshal.ReadByte(argvPtr, offset) == 0) { offset++; } argvPtr = IntPtr.Add(argvPtr, offset); // Start reading argv for (var i = 0; i < argc; i++) { offset = 0; // Keep reading bytes until we find a null-terminated string while (Marshal.ReadByte(argvPtr, offset) != 0) { offset++; } var arg = Marshal.PtrToStringAnsi(argvPtr, offset); argv.Add(arg); // Move pointer to the start of the next arg (= currentArg + \0) argvPtr = IntPtr.Add(argvPtr, offset + sizeof(byte)); } } finally { Marshal.FreeHGlobal(procargs); } } finally { mibHandle.Free(); } return(argv.ToArray()); }
static void Main(string[] args) { Process[] wargames = Process.GetProcessesByName("wargame3"); //pray there isnt another program called wargame3.exe if (wargames.Length < 1) { Console.WriteLine("Wargame needs to be running first."); return; } Process wargame = wargames[0]; //just pick the first instance. IntPtr handle = OpenProcess(PROCESS_WM_READ, false, wargame.Id); IntPtr bytesRead; byte[] buffer = new byte[4]; IntPtr baseAddr = wargame.MainModule.BaseAddress; int p1Kills = 0; int p2Kills = 0; int newKills = 0; bool shouldRefresh = true; while (true) { IntPtr kills = IntPtr.Add(baseAddr, 0x1D1FE0C); ReadProcessMemory(handle, kills, buffer, buffer.Length, out bytesRead); IntPtr p1KillsPPP = IntPtr.Add(IntPtr.Zero, BitConverter.ToInt32(buffer, 0) + 0x10); ReadProcessMemory(handle, p1KillsPPP, buffer, buffer.Length, out bytesRead); IntPtr p1KillsPP = IntPtr.Add(IntPtr.Zero, BitConverter.ToInt32(buffer, 0) + 0x134); ReadProcessMemory(handle, p1KillsPP, buffer, buffer.Length, out bytesRead); IntPtr p1KillsP = IntPtr.Add(IntPtr.Zero, BitConverter.ToInt32(buffer, 0) + 0x30); ReadProcessMemory(handle, p1KillsP, buffer, buffer.Length, out bytesRead); newKills = BitConverter.ToInt32(buffer, 0); if (newKills != p1Kills) { p1Kills = newKills; shouldRefresh = true; } ReadProcessMemory(handle, kills, buffer, buffer.Length, out bytesRead); //read the mem addr pointed at by "kills" back into the buffer IntPtr p2KillsPPP = IntPtr.Add(IntPtr.Zero, BitConverter.ToInt32(buffer, 0) + 0x14); ReadProcessMemory(handle, p2KillsPPP, buffer, buffer.Length, out bytesRead); IntPtr p2KillsPP = IntPtr.Add(IntPtr.Zero, BitConverter.ToInt32(buffer, 0) + 0x134); ReadProcessMemory(handle, p2KillsPP, buffer, buffer.Length, out bytesRead); IntPtr p2KillsP = IntPtr.Add(IntPtr.Zero, BitConverter.ToInt32(buffer, 0) + 0x30); ReadProcessMemory(handle, p2KillsP, buffer, buffer.Length, out bytesRead); newKills = BitConverter.ToInt32(buffer, 0); if (newKills != p2Kills) { p2Kills = newKills; shouldRefresh = true; } if (shouldRefresh) { Console.Clear(); Console.WriteLine("P1 Kills: " + p1Kills); Console.WriteLine("P2 Kills: " + p2Kills); } shouldRefresh = false; Thread.Sleep(100); } }