public static async Task <ulong> GetPointerAddressFromExpression(ISwitchConnectionAsync sw, string pointerExpression, CancellationToken token) { // Regex pattern to get operators and offsets from pointer expression. const string pattern = @"(\+|\-)([A-Fa-f0-9]+)"; Regex regex = new(pattern); Match match = regex.Match(pointerExpression); // Get first offset from pointer expression and read address at that offset from main start. var ofs = Convert.ToUInt64(match.Groups[2].Value, 16); var address = BitConverter.ToUInt64(await sw.ReadBytesMainAsync(ofs, 0x8, token).ConfigureAwait(false), 0); match = match.NextMatch(); // Matches the rest of the operators and offsets in the pointer expression. while (match.Success) { // Get operator and offset from match. string opp = match.Groups[1].Value; ofs = Convert.ToUInt64(match.Groups[2].Value, 16); // Add or subtract the offset from the current stored address based on operator in front of offset. switch (opp) { case "+": address += ofs; break; case "-": address -= ofs; break; } // Attempt another match and if successful read bytes at address and store the new address. match = match.NextMatch(); if (!match.Success) { continue; } byte[] bytes = await sw.ReadBytesAbsoluteAsync(address, 0x8, token).ConfigureAwait(false); address = BitConverter.ToUInt64(bytes, 0); } return(address); }
public async Task <ulong> FollowMainPointer(long[] jumps, bool canSolveOnSysmodule, CancellationToken token) //include the last jump here { // 1.7+ sys-botbase can solve entire pointer if (canSolveOnSysmodule) { var jumpsWithoutLast = jumps.Take(jumps.Length - 1); byte[] command = Encoding.UTF8.GetBytes($"pointer{string.Concat(jumpsWithoutLast.Select(z => $" {z}"))}\r\n"); byte[] socketReturn = await Connection.ReadRaw(command, sizeof(ulong) * 2 + 1, token).ConfigureAwait(false); var bytes = Base.Decoder.ConvertHexByteStringToBytes(socketReturn); bytes = bytes.Reverse().ToArray(); var offset = (ulong)((long)BitConverter.ToUInt64(bytes, 0) + jumps[jumps.Length - 1]); return(offset); } // solve pointer manually var ofs = (ulong)jumps[0]; // won't work with negative first jump var address = BitConverter.ToUInt64(await Connection.ReadBytesMainAsync(ofs, 0x8, token).ConfigureAwait(false), 0); for (int i = 1; i < jumps.Length - 1; ++i) { await Task.Delay(0_008, token).ConfigureAwait(false); // 1/4 frame var jump = jumps[i]; if (jump > 0) { address += (ulong)jump; } else { address -= (ulong)Math.Abs(jump); } byte[] bytes = await Connection.ReadBytesAbsoluteAsync(address, 0x8, token).ConfigureAwait(false); address = BitConverter.ToUInt64(bytes, 0); } return(address + (ulong)jumps[jumps.Length - 1]); }