// Game memory init public static void GetGameMemory( GameContext gameContext, ref NewChildrenEventArgs gameAddress) { using (WindowsApi.ProcessMemory mem = new WindowsApi.ProcessMemory(gameContext.ProcessId)) { gameAddress.ThisGameAddress = mem.ReadUInt32((IntPtr)gameContext.ThisGameAddress); if (gameAddress.ThisGameAddress != 0) { gameAddress.ThisGameMemoryAddress = mem.ReadUInt32((IntPtr) unchecked (gameAddress.ThisGameAddress + 0xC)); if (gameAddress.ThisGameMemoryAddress == 0xFFFFFFFF) { gameAddress.ThisGameMemoryAddress = 0; } } if (gameAddress.ThisGameAddress == 0 || gameAddress.ThisGameMemoryAddress == 0) { gameAddress.ThisGameMemoryAddress = 0; gameAddress.ThisUnitAddress = 0; gameAddress.AttackAttributesAddress = 0; gameAddress.HeroAttributesAddress = 0; } } }
public string GetUnitName() { using (WindowsApi.ProcessMemory mem = new WindowsApi.ProcessMemory(_gameContext.ProcessId)) { return(mem.ReadChar4((IntPtr) unchecked (_newChildrenArgs.ThisUnitAddress + 0x30))); } }
// Game memory extract algorithm 2 // Used in MoveSpeed public static UInt32 ReadGameValue2( WindowsApi.ProcessMemory mem, GameContext gameContext, NewChildrenEventArgs gameAddress, Int32 index) { if (gameAddress.ThisGameMemoryAddress == 0) { return(0); } UInt32 tmpValue = ReadFromGameMemory( mem, gameContext, gameAddress, index); if (0 == mem.ReadUInt32((IntPtr) unchecked (tmpValue + 0x20))) { return(mem.ReadUInt32((IntPtr) unchecked (tmpValue + 0x54))); } else { System.Windows.Forms.MessageBox.Show( "Bug detected in ReadGameValue2().", "Bug check"); // Copy sub_6F468A20() again, set breakpoint at 6F0776F6 return(0); } }
public override void CreateChildren() { using (WindowsApi.ProcessMemory mem = new WindowsApi.ProcessMemory(_gameContext.ProcessId)) { // Get ESI of each selected unit UInt32 selectedUnitList = mem.ReadUInt32((IntPtr)_gameContext.UnitListAddress); UInt16 a2 = mem.ReadUInt16((IntPtr) unchecked (selectedUnitList + 0x28)); UInt32 tmpAddress; tmpAddress = mem.ReadUInt32((IntPtr) unchecked (selectedUnitList + 0x58 + 4 * a2)); tmpAddress = mem.ReadUInt32((IntPtr) unchecked (tmpAddress + 0x34)); UInt32 listHead = mem.ReadUInt32((IntPtr) unchecked (tmpAddress + 0x1F0)); // UInt32 listEnd = mem.ReadUInt32((IntPtr)unchecked(tmpAddress + 0x1F4)); UInt32 listLength = mem.ReadUInt32((IntPtr) unchecked (tmpAddress + 0x1F8)); UInt32 nextNode = listHead; // UInt32 nextNodeNot = ~listHead; for (int selectedUnitIndex = 0; selectedUnitIndex < listLength; selectedUnitIndex++) { _newChildrenArgs.ThisUnitAddress = mem.ReadUInt32((IntPtr) unchecked (nextNode + 8)); // nextNodeNot = mem.ReadUInt32((IntPtr)unchecked(NextNode + 4)); nextNode = mem.ReadUInt32((IntPtr) unchecked (nextNode + 0)); base.CreateChild(TrainerNodeType.OneSelectedUnit, NodeIndex); } } }
private string GetItemName() { using (WindowsApi.ProcessMemory mem = new WindowsApi.ProcessMemory(_gameContext.ProcessId)) { return(mem.ReadChar4((IntPtr) unchecked (_newChildrenArgs.CurrentItemPackAddress + 0x30))); } }
private void FillAddressList(int functionNodeId) { // To set the right window viewData.Items.Clear(); foreach (IAddressNode addressLine in _mainTrainer.GetAddressList()) { if (addressLine.ParentIndex != functionNodeId) { continue; } viewData.Items.Add(new ListViewItem( new string[] { addressLine.Caption, // Caption "", // Original value "" // Modified value })); viewData.Items[viewData.Items.Count - 1].Tag = addressLine; } // To get memory content using (WindowsApi.ProcessMemory mem = new WindowsApi.ProcessMemory(_currentGameContext.ProcessId)) { foreach (ListViewItem currentItem in viewData.Items) { IAddressNode addressLine = currentItem.Tag as IAddressNode; if (addressLine == null) { continue; } Object itemValue; switch (addressLine.ValueType) { case AddressListValueType.Integer: itemValue = mem.ReadInt32((IntPtr)addressLine.Address) / addressLine.ValueScale; break; case AddressListValueType.Float: itemValue = mem.ReadFloat((IntPtr)addressLine.Address) / addressLine.ValueScale; break; case AddressListValueType.Char4: itemValue = mem.ReadChar4((IntPtr)addressLine.Address); break; default: itemValue = ""; break; } currentItem.SubItems[1].Text = itemValue.ToString(); } } }
// Game memory extract algorithm 1 // Used in Intelligence public static UInt32 ReadGameValue1( WindowsApi.ProcessMemory mem, GameContext gameContext, NewChildrenEventArgs gameAddress, Int32 index) { if (gameAddress.ThisGameMemoryAddress == 0) { return(0); } return(unchecked (0x78 + ReadFromGameMemory( mem, gameContext, gameAddress, index))); }
public static UInt32 ReadFromGameMemory( WindowsApi.ProcessMemory mem, GameContext gameContext, NewChildrenEventArgs gameAddress, Int32 index) { System.Diagnostics.Debug.Assert(index >= 0); if (gameAddress.ThisGameMemoryAddress == 0) { return(0); } return(mem.ReadUInt32((IntPtr) unchecked (gameAddress.ThisGameMemoryAddress + index * 8 + 4))); }
public override void CreateChildren() { CreateAddress(new NewAddressListEventArgs(_nodeIndex, "经验值", unchecked (_newChildrenArgs.HeroAttributesAddress + 0x8C), AddressListValueType.Integer)); CreateAddress(new NewAddressListEventArgs(_nodeIndex, "力量", unchecked (_newChildrenArgs.HeroAttributesAddress + 0x94), AddressListValueType.Integer)); CreateAddress(new NewAddressListEventArgs(_nodeIndex, "敏捷", unchecked (_newChildrenArgs.HeroAttributesAddress + 0xA8), AddressListValueType.Integer)); using (WindowsApi.ProcessMemory mem = new WindowsApi.ProcessMemory(_gameContext.ProcessId)) { UInt32 tmpAddress1; Int32 tmpValue1; tmpValue1 = mem.ReadInt32((IntPtr) unchecked (_newChildrenArgs.HeroAttributesAddress + 0x7C + 2 * 4)); tmpAddress1 = War3Common.ReadGameValue1( mem, _gameContext, _newChildrenArgs, tmpValue1); CreateAddress(new NewAddressListEventArgs(_nodeIndex, "智力", tmpAddress1, AddressListValueType.Integer)); } CreateAddress(new NewAddressListEventArgs(_nodeIndex, "可用技能点", unchecked (_newChildrenArgs.HeroAttributesAddress + 0x90), AddressListValueType.Integer)); for (UInt32 LearningAbilityIndex = 1; LearningAbilityIndex <= 5; LearningAbilityIndex++) { CreateAddress(new NewAddressListEventArgs(_nodeIndex, "学习技能" + LearningAbilityIndex.ToString() + " - 名称", unchecked (_newChildrenArgs.HeroAttributesAddress + 0xF0 + LearningAbilityIndex * 4), AddressListValueType.Char4)); CreateAddress(new NewAddressListEventArgs(_nodeIndex, "学习技能" + LearningAbilityIndex.ToString() + " - 等级", unchecked (_newChildrenArgs.HeroAttributesAddress + 0x108 + LearningAbilityIndex * 4), AddressListValueType.Integer)); CreateAddress(new NewAddressListEventArgs(_nodeIndex, "学习技能" + LearningAbilityIndex.ToString() + " - 要求", unchecked (_newChildrenArgs.HeroAttributesAddress + 0x120 + LearningAbilityIndex * 4), AddressListValueType.Integer)); } }
// To apply the modifications private void ApplyModify() { using (WindowsApi.ProcessMemory mem = new WindowsApi.ProcessMemory(_currentGameContext.ProcessId)) { foreach (ListViewItem currentItem in viewData.Items) { string itemValueString = currentItem.SubItems[2].Text; if (String.IsNullOrEmpty(itemValueString)) { // Not modified continue; } IAddressNode addressLine = currentItem.Tag as IAddressNode; if (addressLine == null) { continue; } switch (addressLine.ValueType) { case AddressListValueType.Integer: Int32 intValue; if (!Int32.TryParse(itemValueString, out intValue)) { intValue = 0; } intValue = unchecked (intValue * addressLine.ValueScale); mem.WriteInt32((IntPtr)addressLine.Address, intValue); break; case AddressListValueType.Float: float floatValue; if (!float.TryParse(itemValueString, out floatValue)) { floatValue = 0; } floatValue = unchecked (floatValue * addressLine.ValueScale); mem.WriteFloat((IntPtr)addressLine.Address, floatValue); break; case AddressListValueType.Char4: mem.WriteChar4((IntPtr)addressLine.Address, itemValueString); break; } currentItem.SubItems[2].Text = ""; } } }
public override void CreateChildren() { UInt32 upperAddress; using (WindowsApi.ProcessMemory mem = new WindowsApi.ProcessMemory(_gameContext.ProcessId)) { upperAddress = War3Common.ReadFromGameMemory( mem, _gameContext, _newChildrenArgs, 1) & 0xFFFF0000; } if (upperAddress == 0) { return; } UInt32[] playerSourceBaseAddress = new UInt32[] { 0, // To skip index 0 0x0190, 0x1410, 0x26A0, 0x3920, 0x4BB0, 0x5E30, 0x70C0, 0x8350, 0x95D0, 0xA860, 0xBAE0, 0xCD70 }; for (int i = 1; i <= 12; i++) { CreateAddress(new NewAddressListEventArgs(_nodeIndex, "P" + i.ToString() + " - 金", unchecked (upperAddress + playerSourceBaseAddress[i] + 0), AddressListValueType.Integer, 10)); CreateAddress(new NewAddressListEventArgs(_nodeIndex, "P" + i.ToString() + " - 木", unchecked (upperAddress + playerSourceBaseAddress[i] + 0x80), AddressListValueType.Integer, 10)); CreateAddress(new NewAddressListEventArgs(_nodeIndex, "P" + i.ToString() + " - 最大人口", unchecked (upperAddress + playerSourceBaseAddress[i] + 0x180), AddressListValueType.Integer)); CreateAddress(new NewAddressListEventArgs(_nodeIndex, "P" + i.ToString() + " - 当前人口", unchecked (upperAddress + playerSourceBaseAddress[i] + 0x200), AddressListValueType.Integer)); } }
/************************************************************************/ /* Debug */ /************************************************************************/ private void menuDebug1_Click(object sender, EventArgs e) { string strIndex = Microsoft.VisualBasic.Interaction.InputBox( "nIndex = 0x?", "War3Common.ReadFromGameMemory(nIndex)", "0", -1, -1); if (String.IsNullOrEmpty(strIndex)) { return; } Int32 nIndex; if (!Int32.TryParse( strIndex, System.Globalization.NumberStyles.HexNumber, System.Globalization.NumberFormatInfo.InvariantInfo, out nIndex)) { nIndex = 0; } try { UInt32 result = 0; using (WindowsApi.ProcessMemory mem = new WindowsApi.ProcessMemory(_currentGameContext.ProcessId)) { NewChildrenEventArgs args = new NewChildrenEventArgs(); War3Common.GetGameMemory( _currentGameContext, ref args); result = War3Common.ReadFromGameMemory( mem, _currentGameContext, args, nIndex); } MessageBox.Show( "0x" + result.ToString("X"), "War3Common.ReadFromGameMemory(0x" + strIndex + ")"); } catch (WindowsApi.BadProcessIdException ex) { ReportProcessIdFailure(ex.ProcessId); } }
public override void CreateChildren() { using (WindowsApi.ProcessMemory mem = new WindowsApi.ProcessMemory(_gameContext.ProcessId)) { Int32 list = mem.ReadInt32((IntPtr) unchecked (_newChildrenArgs.ThisUnitAddress + _gameContext.ItemsListOffset)); if (list != 0) { for (Int32 itemIndex = 0; itemIndex < 6; itemIndex++) { UInt32 currentItem = 0; // We assume ItemIndex never go out of bounds to the List Int32 tmpValue1 = mem.ReadInt32((IntPtr) unchecked (list + 0xC * itemIndex + 0x70)); if (tmpValue1 > 0) { UInt32 RawItem = War3Common.ReadFromGameMemory( mem, _gameContext, _newChildrenArgs, tmpValue1); if (RawItem != 0) { UInt32 tmpValue2 = mem.ReadUInt32((IntPtr) unchecked (RawItem + 0x20)); if (tmpValue2 == 0) { currentItem = mem.ReadUInt32((IntPtr) unchecked (RawItem + 0x54)); } } if (currentItem != 0) { _newChildrenArgs.CurrentItemPackAddress = currentItem; base.CreateChild(TrainerNodeType.OneItem, NodeIndex); } } } // foreach items } // Item list exists } // mem } // CreateChildren()
public override void CreateChildren() { using (WindowsApi.ProcessMemory mem = new WindowsApi.ProcessMemory(_gameContext.ProcessId)) { _newChildrenArgs.AttackAttributesAddress = mem.ReadUInt32((IntPtr) unchecked (_newChildrenArgs.ThisUnitAddress + _gameContext.AttackAttributesOffset)); _newChildrenArgs.HeroAttributesAddress = mem.ReadUInt32((IntPtr) unchecked (_newChildrenArgs.ThisUnitAddress + _gameContext.HeroAttributesOffset)); if (_newChildrenArgs.AttackAttributesAddress > 0) { base.CreateChild(TrainerNodeType.AttackAttributes, NodeIndex); // base.CreateChild(TrainerNodeType.UnitAbility, NodeIndex); base.CreateChild(TrainerNodeType.AllItems, NodeIndex); } if (_newChildrenArgs.HeroAttributesAddress > 0) { base.CreateChild(TrainerNodeType.HeroAttributes, NodeIndex); } // Unit self propety(s) CreateAddress(new NewAddressListEventArgs(_nodeIndex, "单位名称", unchecked (_newChildrenArgs.ThisUnitAddress + 0x30), AddressListValueType.Char4)); UInt32 tmpAddress1, tmpAddress2; Int32 tmpValue1, tmpValue2; tmpValue1 = mem.ReadInt32((IntPtr) unchecked (_newChildrenArgs.ThisUnitAddress + 0x98 + 0x8)); tmpAddress1 = War3Common.ReadFromGameMemory( mem, _gameContext, _newChildrenArgs, tmpValue1); tmpAddress1 = unchecked (tmpAddress1 + 0x84); CreateAddress(new NewAddressListEventArgs(_nodeIndex, "HP - 目前", unchecked (tmpAddress1 - 0xC), AddressListValueType.Float)); CreateAddress(new NewAddressListEventArgs(_nodeIndex, "HP - 最大", tmpAddress1, AddressListValueType.Float)); CreateAddress(new NewAddressListEventArgs(_nodeIndex, "HP - 回复率", unchecked (_newChildrenArgs.ThisUnitAddress + 0xB0), AddressListValueType.Float)); tmpValue1 = mem.ReadInt32((IntPtr) unchecked (_newChildrenArgs.ThisUnitAddress + 0x98 + 0x28)); tmpAddress1 = War3Common.ReadFromGameMemory( mem, _gameContext, _newChildrenArgs, tmpValue1); tmpAddress1 = unchecked (tmpAddress1 + 0x84); CreateAddress(new NewAddressListEventArgs(_nodeIndex, "MP - 目前", unchecked (tmpAddress1 - 0xC), AddressListValueType.Float)); CreateAddress(new NewAddressListEventArgs(_nodeIndex, "MP - 最大", tmpAddress1, AddressListValueType.Float)); CreateAddress(new NewAddressListEventArgs(_nodeIndex, "MP - 回复率", unchecked (_newChildrenArgs.ThisUnitAddress + 0xD4), AddressListValueType.Float)); CreateAddress(new NewAddressListEventArgs(_nodeIndex, "盔甲 - 数量", unchecked (_newChildrenArgs.ThisUnitAddress + 0xE0), AddressListValueType.Float)); CreateAddress(new NewAddressListEventArgs(_nodeIndex, "盔甲 - 种类", unchecked (_newChildrenArgs.ThisUnitAddress + 0xE4), AddressListValueType.Integer)); // Move speed tmpAddress1 = unchecked (_newChildrenArgs.ThisUnitAddress + _gameContext.MoveSpeedOffset - 0x24); do { tmpValue1 = mem.ReadInt32((IntPtr) unchecked (tmpAddress1 + 0x24)); tmpAddress1 = War3Common.ReadGameValue2( mem, _gameContext, _newChildrenArgs, tmpValue1); tmpAddress2 = mem.ReadUInt32((IntPtr) unchecked (tmpAddress1 + 0)); tmpValue1 = mem.ReadInt32((IntPtr) unchecked (tmpAddress1 + 0x24)); tmpValue2 = mem.ReadInt32((IntPtr) unchecked (tmpAddress1 + 0x28)); // Note: If new game version released, set breakpoint here // and check tmpAddress2. Set this value as War3AddressMoveSpeed tmpAddress2 = mem.ReadUInt32((IntPtr) unchecked (tmpAddress2 + 0x2D4)); if (_gameContext.MoveSpeedAddress == tmpAddress2) { CreateAddress(new NewAddressListEventArgs(_nodeIndex, "移动速度", unchecked (tmpAddress1 + 0x70), // +70 or +78 are both OK AddressListValueType.Float)); } } while (tmpValue1 > 0 && tmpValue2 > 0); // Coordinate tmpValue1 = mem.ReadInt32((IntPtr) unchecked (_newChildrenArgs.ThisUnitAddress + 0x164 + 8)); tmpAddress1 = War3Common.ReadGameValue1( mem, _gameContext, _newChildrenArgs, tmpValue1); CreateAddress(new NewAddressListEventArgs(_nodeIndex, "坐标 - X", tmpAddress1, AddressListValueType.Float)); CreateAddress(new NewAddressListEventArgs(_nodeIndex, "坐标 - Y", unchecked (tmpAddress1 + 4), AddressListValueType.Float)); } }