예제 #1
0
        /// <summary>
        /// Creates a <see cref="BytePattern"/> for the given address range.
        /// </summary>
        /// <param name="process">The process to use.</param>
        /// <param name="start">The start of the address range.</param>
        /// <param name="size">The size of the address range.</param>
        /// <returns>A <see cref="BytePattern"/> describing the address range.</returns>
        public static BytePattern CreatePatternFromCode(RemoteProcess process, IntPtr start, int size)
        {
            var data = new List <Tuple <byte, bool> >();

            var buffer = process.ReadRemoteMemory(start, size);

            var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);

            try
            {
                var eip = handle.AddrOfPinnedObject();

                process.CoreFunctions.DisassembleCode(eip, size, IntPtr.Zero, true, (ref InstructionData instruction) =>
                {
                    for (var i = 0; i < instruction.Length; ++i)
                    {
                        data.Add(Tuple.Create(instruction.Data[i], i >= instruction.StaticInstructionBytes));
                    }
                    return(true);
                });
            }
            finally
            {
                if (handle.IsAllocated)
                {
                    handle.Free();
                }
            }

            return(BytePattern.From(data));
        }
예제 #2
0
        /// <summary>
        /// Searchs for the <see cref="BytePattern"/> in the specified <see cref="Section"/>.
        /// </summary>
        /// <param name="pattern">The pattern to search.</param>
        /// <param name="process">The process to read from.</param>
        /// <param name="section">The section of the process.</param>
        /// <returns>The address of the pattern or <see cref="IntPtr.Zero"/> if the pattern was not found.</returns>
        public static IntPtr FindPattern(BytePattern pattern, RemoteProcess process, Section section)
        {
            Contract.Requires(pattern != null);
            Contract.Requires(process != null);
            Contract.Requires(section != null);

            return(FindPattern(pattern, process, section.Start, section.Size.ToInt32()));
        }
예제 #3
0
        /// <summary>
        /// Searchs for the <see cref="BytePattern"/> in the specified <see cref="Module"/>.
        /// </summary>
        /// <param name="pattern">The pattern to search.</param>
        /// <param name="process">The process to read from.</param>
        /// <param name="module">The module of the process.</param>
        /// <returns>The address of the pattern or <see cref="IntPtr.Zero"/> if the pattern was not found.</returns>
        public static IntPtr FindPattern(BytePattern pattern, RemoteProcess process, Module module)
        {
            Contract.Requires(pattern != null);
            Contract.Requires(process != null);
            Contract.Requires(module != null);

            return(FindPattern(pattern, process, module.Start, module.Size.ToInt32()));
        }
예제 #4
0
        public static BytePattern From(IEnumerable <Tuple <byte, bool> > data)
        {
            var pattern = new BytePattern();

            foreach (var i in data)
            {
                var pb = i.Item2 ? PatternByte.AsWildcard() : PatternByte.AsByte(i.Item1);

                pattern.pattern.Add(pb);
            }

            return(pattern);
        }
예제 #5
0
        /// <summary>
        /// Searchs for the <see cref="BytePattern"/> in the specified address range.
        /// </summary>
        /// <param name="pattern">The pattern to search.</param>
        /// <param name="process">The process to read from.</param>
        /// <param name="start">The start address.</param>
        /// <param name="size">The size of the address range.</param>
        /// <returns>The address of the pattern or <see cref="IntPtr.Zero"/> if the pattern was not found.</returns>
        public static IntPtr FindPattern(BytePattern pattern, RemoteProcess process, IntPtr start, int size)
        {
            Contract.Requires(pattern != null);
            Contract.Requires(process != null);

            var moduleBytes = process.ReadRemoteMemory(start, size);

            var offset = FindPattern(pattern, moduleBytes);

            if (offset == -1)
            {
                return(IntPtr.Zero);
            }

            return(start + offset);
        }
예제 #6
0
        /// <summary>
        /// Searchs for the <see cref="BytePattern"/> in the specified data.
        /// </summary>
        /// <param name="pattern">The pattern to search.</param>
        /// <param name="data">The data to scan.</param>
        /// <returns>The index in data where the pattern was found or -1 otherwise.</returns>
        public static int FindPattern(BytePattern pattern, byte[] data)
        {
            Contract.Requires(pattern != null);
            Contract.Requires(data != null);

            var limit = data.Length - pattern.Length;

            for (var i = 0; i < limit; ++i)
            {
                if (pattern.Equals(data, i))
                {
                    return(i);
                }
            }

            return(-1);
        }
예제 #7
0
        /// <summary>
        /// Creates a <see cref="BytePattern"/> for the given address range.
        /// </summary>
        /// <param name="process">The process to use.</param>
        /// <param name="start">The start of the address range.</param>
        /// <param name="size">The size of the address range.</param>
        /// <returns>A <see cref="BytePattern"/> describing the address range.</returns>
        public static BytePattern CreatePatternFromCode(RemoteProcess process, IntPtr start, int size)
        {
            var data = new List <Tuple <byte, bool> >();

            var buffer = process.ReadRemoteMemory(start, size);

            var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);

            try
            {
                var eip = handle.AddrOfPinnedObject();
                var end = eip + size;

                while (eip.CompareTo(end) == -1)
                {
                    var res = process.CoreFunctions.DisassembleCode(eip, end.Sub(eip).ToInt32() + 1, IntPtr.Zero, true, out var instruction);
                    if (!res)
                    {
                        break;
                    }

                    for (var i = 0; i < instruction.Length; ++i)
                    {
                        data.Add(Tuple.Create(instruction.Data[i], i >= instruction.StaticInstructionBytes));
                    }

                    eip += instruction.Length;
                }
            }
            finally
            {
                if (handle.IsAllocated)
                {
                    handle.Free();
                }
            }

            return(BytePattern.From(data));
        }
예제 #8
0
        /// <summary>
        /// Parses the provided string for a byte pattern. Wildcards are supported by nibble.
        /// </summary>
        /// <example>
        /// Valid patterns:
        /// AA BB CC DD
        /// AABBCCDD
        /// aabb CCdd
        /// A? ?B ?? DD
        /// </example>
        /// <exception cref="ArgumentException">Thrown if the provided string doesn't contain a valid byte pattern.</exception>
        /// <param name="value">The byte pattern in hex format.</param>
        /// <returns>The corresponding <see cref="BytePattern"/>.</returns>
        public static BytePattern Parse(string value)
        {
            Contract.Requires(!string.IsNullOrEmpty(value));
            Contract.Ensures(Contract.Result <BytePattern>() != null);

            var pattern = new BytePattern();

            using (var sr = new StringReader(value))
            {
                var pb = new PatternByte();
                while (pb.TryRead(sr))
                {
                    pattern.pattern.Add(pb);
                }

                // Check if we are not at the end of the stream
                if (sr.Peek() != -1)
                {
                    throw new ArgumentException($"'{value}' is not a valid byte pattern.");
                }
            }

            return(pattern);
        }