예제 #1
0
        public IntPtr EvaluatePointer(IntPtr address, IEnumerable <Int32> offsets)
        {
            IntPtr finalAddress = address;

            if (!offsets.IsNullOrEmpty())
            {
                // Add and trace offsets
                foreach (Int32 offset in offsets.Take(offsets.Count() - 1))
                {
                    Boolean success;
                    if (EngineCore.GetInstance().Processes.IsOpenedProcess32Bit())
                    {
                        finalAddress = (this.Read <UInt32>(finalAddress + offset, out success).ToInt64()).ToIntPtr();
                    }
                    else
                    {
                        finalAddress = (this.Read <UInt64>(finalAddress, out success).ToInt64() + offset).ToIntPtr();
                    }
                }

                // The last offset is added, but not traced
                finalAddress = finalAddress.Add(offsets.Last());
            }

            return(finalAddress);
        }
예제 #2
0
        /// <summary>
        /// Determines if a process is 32 bit
        /// </summary>
        /// <param name="process">The process to check</param>
        /// <returns>Returns true if the process is 32 bit, otherwise false</returns>
        public Boolean IsProcess32Bit(NormalizedProcess process)
        {
            Boolean isWow64;

            // First do the simple check if seeing if the OS is 32 bit, in which case the process wont be 64 bit
            if (EngineCore.GetInstance().OperatingSystemAdapter.IsOperatingSystem32Bit())
            {
                return(true);
            }

            // No process provided, assume 32 bit
            if (process == null)
            {
                return(true);
            }

            try
            {
                if (this.SystemProcess == null || !Native.NativeMethods.IsWow64Process(this.SystemProcess.Handle, out isWow64))
                {
                    // Error, assume 32 bit
                    return(true);
                }
            }
            catch
            {
                // Error, assume 32 bit
                return(true);
            }

            return(isWow64);
        }
예제 #3
0
        /// <summary>
        /// Creates a new snapshot of memory in the target process. Will not read any memory.
        /// </summary>
        /// <returns>The snapshot of memory taken in the target process.</returns>
        private Snapshot CreateSnapshotFromSettings()
        {
            MemoryProtectionEnum requiredPageFlags = SettingsViewModel.GetInstance().GetRequiredProtectionSettings();
            MemoryProtectionEnum excludedPageFlags = SettingsViewModel.GetInstance().GetExcludedProtectionSettings();
            MemoryTypeEnum       allowedTypeFlags  = SettingsViewModel.GetInstance().GetAllowedTypeSettings();

            IntPtr startAddress, endAddress;

            if (SettingsViewModel.GetInstance().IsUserMode)
            {
                startAddress = IntPtr.Zero;
                endAddress   = EngineCore.GetInstance().VirtualMemory.GetMaxUsermodeAddress().ToIntPtr();
            }
            else
            {
                startAddress = SettingsViewModel.GetInstance().StartAddress.ToIntPtr();
                endAddress   = SettingsViewModel.GetInstance().EndAddress.ToIntPtr();
            }

            List <ReadGroup> memoryRegions = new List <ReadGroup>();
            IEnumerable <NormalizedRegion> virtualPages = EngineCore.GetInstance().VirtualMemory.GetVirtualPages(
                requiredPageFlags,
                excludedPageFlags,
                allowedTypeFlags,
                startAddress,
                endAddress);

            // Convert each virtual page to a snapshot region
            foreach (NormalizedRegion virtualPage in virtualPages)
            {
                memoryRegions.Add(new ReadGroup(virtualPage.BaseAddress, virtualPage.RegionSize));
            }

            return(new Snapshot(null, memoryRegions));
        }
예제 #4
0
        /// <summary>
        /// Creates a snapshot from modules in the selected process.
        /// </summary>
        /// <returns>The created snapshot.</returns>
        private Snapshot CreateSnapshotFromModules()
        {
            IEnumerable <ReadGroup> moduleGroups = EngineCore.GetInstance().VirtualMemory.GetModules().Select(region => new ReadGroup(region.BaseAddress, region.RegionSize));
            Snapshot moduleSnapshot = new Snapshot(null, moduleGroups);

            return(moduleSnapshot);
        }
예제 #5
0
        /// <summary>
        /// Loads the instructions to display.
        /// </summary>
        private void LoadInstructions()
        {
            Byte[] bytes = EngineCore.GetInstance().VirtualMemory.ReadBytes(this.BaseAddress.ToIntPtr(), 200, out _);

            if (bytes.IsNullOrEmpty())
            {
                return;
            }

            Boolean isProcess32Bit = EngineCore.GetInstance().Processes.IsOpenedProcess32Bit();

            // Disassemble instructions
            IEnumerable <NormalizedInstruction> disassembledInstructions = this.Disassembler.Disassemble(bytes, isProcess32Bit, this.BaseAddress.ToIntPtr());
            IList <InstructionItem>             instructions             = new List <InstructionItem>();

            foreach (NormalizedInstruction disassembledInstruction in disassembledInstructions)
            {
                String moduleName;
                UInt64 address = AddressResolver.GetInstance().AddressToModule(disassembledInstruction.Address, out moduleName);

                instructions.Add(new InstructionItem(address.ToIntPtr(), moduleName, disassembledInstruction.Instruction, disassembledInstruction.Bytes));
            }

            this.Instructions = new FullyObservableCollection <InstructionItem>(instructions);
        }
예제 #6
0
        /// <summary>
        /// Processes all pages, computing checksums to determine chunks of virtual pages that have changed.
        /// </summary>
        private void ProcessPages()
        {
            Boolean isOpenedProcess32Bit             = EngineCore.GetInstance().Processes.IsOpenedProcess32Bit();
            dynamic invalidPointerMin                = isOpenedProcess32Bit ? (UInt32)UInt16.MaxValue : (UInt64)UInt16.MaxValue;
            dynamic invalidPointerMax                = isOpenedProcess32Bit ? Int32.MaxValue : Int64.MaxValue;
            ConcurrentHashSet <IntPtr> foundPointers = new ConcurrentHashSet <IntPtr>();

            // Add static bases
            List <SnapshotRegion> baseRegions = new List <SnapshotRegion>();

            foreach (NormalizedModule normalizedModule in EngineCore.GetInstance().OperatingSystemAdapter.GetModules())
            {
                baseRegions.Add(new SnapshotRegion(normalizedModule.BaseAddress, normalizedModule.RegionSize));
            }

            ((dynamic)this.PrefilteredSnapshot).AddSnapshotRegions(baseRegions);

            lock (this.RegionLock)
            {
                List <SnapshotRegion> pointerRegions = new List <SnapshotRegion>();

                foreach (IntPtr pointer in PointerCollector.GetInstance().GetFoundPointers())
                {
                    pointerRegions.Add(new SnapshotRegion(pointer.Subtract(ShallowPointerPrefilter.PointerRadius), ShallowPointerPrefilter.PointerRadius * 2));
                }

                ((dynamic)this.PrefilteredSnapshot).AddSnapshotRegions(pointerRegions);
                this.processedCount = Math.Max(this.processedCount, this.PrefilteredSnapshot.GetRegionCount());
            }
        }
예제 #7
0
        /// <summary>
        /// Resolves the address of an address, pointer, or managed object.
        /// </summary>
        /// <returns>The base address of this object.</returns>
        protected override IntPtr ResolveAddress()
        {
            IntPtr  pointer        = AddressResolver.GetInstance().ResolveModule(this.ModuleName);
            Boolean successReading = true;

            pointer = pointer.Add(this.ModuleOffset);

            if (this.PointerOffsets == null || this.PointerOffsets.Count() == 0)
            {
                return(pointer);
            }

            foreach (Int32 offset in this.PointerOffsets)
            {
                if (EngineCore.GetInstance().Processes.IsOpenedProcess32Bit())
                {
                    pointer = EngineCore.GetInstance().VirtualMemory.Read <Int32>(pointer, out successReading).ToIntPtr();
                }
                else
                {
                    pointer = EngineCore.GetInstance().VirtualMemory.Read <Int64>(pointer, out successReading).ToIntPtr();
                }

                if (pointer == IntPtr.Zero || !successReading)
                {
                    pointer = IntPtr.Zero;
                    break;
                }

                pointer = pointer.Add(offset);
            }

            return(pointer);
        }
예제 #8
0
        /// <summary>
        /// Update event for this project item. Resolves addresses and values.
        /// </summary>
        /// <returns>True if update was made, otherwise false.</returns>
        public override Boolean Update()
        {
            this.CalculatedAddress = this.ResolveAddress();

            if (this.IsActivated)
            {
                // Freeze current value if this entry is activated
                Object value = this.AddressValue;
                if (value != null && value.GetType() == this.DataType)
                {
                    this.WriteValue(value);
                }
            }
            else
            {
                // Otherwise we read as normal (bypass value setter and set value directly to avoid a write-back to memory)
                Boolean readSuccess;
                Object  oldValue = addressValue;

                this.addressValue = EngineCore.GetInstance()?.VirtualMemory?.Read(this.DataType, this.CalculatedAddress, out readSuccess);

                if (this.AddressValue?.ToString() != oldValue?.ToString())
                {
                    this.RaisePropertyChanged(nameof(this.AddressValue));
                    return(true);
                }
            }

            return(false);
        }
예제 #9
0
        /// <summary>
        /// Creates a new snapshot of memory in the target process. Will not read any memory.
        /// </summary>
        /// <returns>The snapshot of memory taken in the target process.</returns>
        public Snapshot CreateSnapshotFromSettings()
        {
            MemoryProtectionEnum requiredPageFlags = SettingsViewModel.GetInstance().GetRequiredProtectionSettings();
            MemoryProtectionEnum excludedPageFlags = SettingsViewModel.GetInstance().GetExcludedProtectionSettings();
            MemoryTypeEnum       allowedTypeFlags  = SettingsViewModel.GetInstance().GetAllowedTypeSettings();

            IntPtr startAddress, endAddress;

            if (SettingsViewModel.GetInstance().IsUserMode)
            {
                startAddress = IntPtr.Zero;
                endAddress   = EngineCore.GetInstance().VirtualMemory.GetUserModeRegion().EndAddress;
            }
            else
            {
                startAddress = SettingsViewModel.GetInstance().StartAddress.ToIntPtr();
                endAddress   = SettingsViewModel.GetInstance().EndAddress.ToIntPtr();
            }

            List <SnapshotRegion>          memoryRegions = new List <SnapshotRegion>();
            IEnumerable <NormalizedRegion> virtualPages  = EngineCore.GetInstance().VirtualMemory.GetVirtualPages(
                requiredPageFlags,
                excludedPageFlags,
                allowedTypeFlags,
                startAddress,
                endAddress);

            // Convert each virtual page to a snapshot region (a more condensed representation of the information)
            foreach (NormalizedRegion virtualPage in virtualPages)
            {
                memoryRegions.Add(new SnapshotRegion(virtualPage.BaseAddress, virtualPage.RegionSize));
            }

            return(new Snapshot(memoryRegions));
        }
        private IntPtr ResolvePointer(Tuple <IntPtr, List <Int32> > fullPointer)
        {
            IntPtr       pointer = fullPointer.Item1;
            List <Int32> offsets = fullPointer.Item2;

            if (offsets == null || offsets.Count == 0)
            {
                return(pointer);
            }

            Boolean successReading = true;

            foreach (Int32 offset in offsets)
            {
                pointer = EngineCore.GetInstance().OperatingSystemAdapter.Read <IntPtr>(pointer, out successReading);
                pointer = pointer.Add(offset);

                if (!successReading)
                {
                    break;
                }
            }

            return(pointer);
        }
예제 #11
0
        /// <summary>
        /// Injects instructions at the specified location, overwriting following instructions. This will nop-fill.
        /// </summary>
        /// <param name="address">The injection address.</param>
        /// <param name="assembly">The assembly code to disassemble and inject into the code cave.</param>
        /// <returns>The address of the code cave.</returns>
        public UInt64 InjectCode(UInt64 address, String assembly)
        {
            this.PrintDebugTag();

            assembly = this.ResolveKeywords(assembly);

            Int32 assemblySize = this.GetAssemblySize(assembly, address);

            Byte[] originalBytes = this.CollectOriginalBytes(address, assemblySize);

            if (originalBytes == null)
            {
                throw new Exception("Could not gather original bytes");
            }

            // Determine number of no-ops to fill dangling bytes
            String noOps = (originalBytes.Length - assemblySize > 0 ? "db " : String.Empty) + String.Join(" ", Enumerable.Repeat("0x90,", originalBytes.Length - assemblySize)).TrimEnd(',');

            Byte[] injectionBytes = this.GetAssemblyBytes(assembly + "\n" + noOps, address);
            EngineCore.GetInstance().VirtualMemory.WriteBytes(address.ToIntPtr(), injectionBytes);

            CodeCave codeCave = new CodeCave(address, 0, originalBytes);

            this.CodeCaves.Add(codeCave);

            return(address);
        }
예제 #12
0
        /// <summary>
        /// Update event for this project item. Resolves addresses and values.
        /// </summary>
        public override void Update()
        {
            this.CalculatedAddress = this.ResolveAddress();

            // Freeze current value if this entry is activated
            if (this.IsActivated)
            {
                Object value = this.AddressValue;

                if (value != null && value.GetType() == this.DataType)
                {
                    this.WriteValue(value);
                }
            }
            else
            {
                Object previousValue = this.AddressValue;

                // Otherwise we read as normal (bypass assigning setter and set value directly to avoid a write-back to memory)
                this.addressValue = EngineCore.GetInstance()?.VirtualMemory?.Read(this.DataType, this.CalculatedAddress, out _);

                if (!(this.AddressValue?.Equals(previousValue) ?? false))
                {
                    this.RaisePropertyChanged(nameof(this.AddressValue));
                    this.RaisePropertyChanged(nameof(this.DisplayValue));
                }
            }
        }
예제 #13
0
        /// <summary>
        /// Reads the value at the given address.
        /// </summary>
        /// <typeparam name="T">The data type to read.</typeparam>
        /// <param name="address">The address of the read.</param>
        /// <returns>The value read from memory.</returns>
        public T Read <T>(UInt64 address)
        {
            this.PrintDebugTag(address.ToString("x"));

            Boolean readSuccess;

            return(EngineCore.GetInstance().OperatingSystemAdapter.Read <T>(address.ToIntPtr(), out readSuccess));
        }
예제 #14
0
        public void OnDeserialized(StreamingContext streamingContext)
        {
            this.LastActivated   = DateTime.MinValue;
            this.ActivationDelay = KeyboardHotkey.DefaultActivationDelay;
            this.AccessLock      = new object();

            this.Subscription = EngineCore.GetInstance().Input?.GetKeyboardCapture().WeakSubscribe(this);
        }
예제 #15
0
        /// <summary>
        /// Reads the value at the given address.
        /// </summary>
        /// <typeparam name="T">The data type to read.</typeparam>
        /// <param name="address">The address of the read.</param>
        /// <returns>The value read from memory.</returns>
        public T Read <T>(UInt64 address)
        {
            this.PrintDebugTag(address.ToString("x"));

            Boolean readSuccess;

            return(EngineCore.GetInstance().VirtualMemory.Read <T>(address.ToIntPtr(), out readSuccess));
        }
예제 #16
0
        private void CleanUp()
        {
            this.Snapshot = null;

            EngineCore.GetInstance().Input?.GetKeyboardCapture().Unsubscribe(this);
            EngineCore.GetInstance().Input?.GetControllerCapture().Unsubscribe(this);
            EngineCore.GetInstance().Input?.GetMouseCapture().Unsubscribe(this);
        }
예제 #17
0
        /// <summary>
        /// Reads the array of bytes of the specified count at the given address.
        /// </summary>
        /// <param name="address">The address of the read.</param>
        /// <param name="count">The number of bytes to read.</param>
        /// <returns>The bytes read at the address.</returns>
        public Byte[] Read(UInt64 address, Int32 count)
        {
            this.PrintDebugTag(address.ToString("x"), count.ToString());

            Boolean readSuccess;

            return(EngineCore.GetInstance().VirtualMemory.ReadBytes(address.ToIntPtr(), count, out readSuccess));
        }
예제 #18
0
        public UInt64 EvaluatePointer(UInt64 address, IEnumerable <Int32> offsets)
        {
            this.PrintDebugTag();

            UInt64 finalAddress = EngineCore.GetInstance().VirtualMemory.EvaluatePointer(address.ToIntPtr(), offsets).ToUInt64();

            return(finalAddress);
        }
예제 #19
0
        /// <summary>
        /// Searches for the first address that matches the array of bytes.
        /// </summary>
        /// <param name="bytes">The array of bytes to search for.</param>
        /// <returns>The address of the first first array of byte match.</returns>
        public UInt64 SearchAob(Byte[] bytes)
        {
            this.PrintDebugTag();

            UInt64 address = EngineCore.GetInstance().OperatingSystemAdapter.SearchAob(bytes).ToUInt64();

            return(address);
        }
예제 #20
0
        /// <summary>
        /// Searches for the first address that matches the array of bytes.
        /// </summary>
        /// <param name="bytes">The array of bytes to search for.</param>
        /// <returns>The address of the first first array of byte match.</returns>
        public UInt64 SearchAob(Byte[] bytes)
        {
            this.PrintDebugTag();

            UInt64 address = EngineCore.GetInstance().VirtualMemory.SearchAob(bytes).ToUInt64();

            return(address);
        }
예제 #21
0
        /// <summary>
        /// Searches for all addresses that match the given array of byte pattern.
        /// </summary>
        /// <param name="pattern">The array of bytes to search for.</param>
        /// <returns>The addresses of all matches.</returns>
        public UInt64[] SearchAllAob(String pattern)
        {
            this.PrintDebugTag(pattern);
            List <IntPtr> aobResults    = new List <IntPtr>(EngineCore.GetInstance().VirtualMemory.SearchllAob(pattern));
            List <UInt64> convertedAobs = new List <UInt64>();

            aobResults.ForEach(x => convertedAobs.Add(x.ToUInt64()));
            return(convertedAobs.ToArray());
        }
예제 #22
0
        /// <summary>
        /// Writes a value to the computed address of this item.
        /// </summary>
        /// <param name="newValue">The value to write.</param>
        private void WriteValue(dynamic newValue)
        {
            if (newValue == null)
            {
                return;
            }

            EngineCore.GetInstance()?.OperatingSystemAdapter?.Write(this.ElementType, this.EffectiveAddress, newValue);
        }
예제 #23
0
        /// <summary>
        /// Writes a value to the computed address of this item.
        /// </summary>
        /// <param name="newValue">The value to write.</param>
        protected virtual void WriteValue(Object newValue)
        {
            if (newValue == null)
            {
                return;
            }

            EngineCore.GetInstance()?.VirtualMemory?.Write(this.DataType, this.CalculatedAddress, newValue);
        }
예제 #24
0
        public void Update(NormalizedProcess process)
        {
            if (process != null)
            {
                this.BaseAddress = EngineCore.GetInstance().VirtualMemory.GetModules().FirstOrDefault()?.BaseAddress.ToUInt64() ?? 0UL;

                this.LoadInstructions();
            }
        }
        /// <summary>
        /// Prevents a default instance of the <see cref="ChunkLinkedListPrefilter" /> class from being created.
        /// </summary>
        private ChunkLinkedListPrefilter() : base("Prefilter", isRepeated: true, trackProgress: true)
        {
            this.ChunkList   = new LinkedList <RegionProperties>();
            this.ChunkLock   = new Object();
            this.ElementLock = new Object();

            // Subscribe to process events (async call as to avoid locking on GetInstance() if engine is being constructed)
            Task.Run(() => { EngineCore.GetInstance().Processes.Subscribe(this); });
        }
예제 #26
0
        /// <summary>
        /// Initializes a new instance of the <see cref="KeyboardHotkey" /> class.
        /// </summary>
        /// <param name="callBackFunction">The callback function for this hotkey.</param>
        /// <param name="activationKeys">Initial activation keys.</param>
        public KeyboardHotkey(Action callBackFunction = null, params Key[] activationKeys) : base(callBackFunction)
        {
            this.ActivationKeys  = new HashSet <Key>(activationKeys);
            this.LastActivated   = DateTime.MinValue;
            this.ActivationDelay = KeyboardHotkey.DefaultActivationDelay;
            this.AccessLock      = new object();

            this.Subscription = EngineCore.GetInstance().Input?.GetKeyboardCapture().WeakSubscribe(this);
        }
        /// <summary>
        /// Makes the target process selection.
        /// </summary>
        /// <param name="process">The process being selected.</param>
        private void SelectProcess(NormalizedProcess process)
        {
            if (process == null)
            {
                return;
            }

            EngineCore.GetInstance().Processes.OpenProcess(process);
            this.IsVisible = false;
        }
예제 #28
0
        /// <summary>
        /// Determines if the opened process is 32 bit
        /// </summary>
        /// <returns>Returns true if the opened process is 32 bit, otherwise false</returns>
        public Boolean IsOpenedProcess32Bit()
        {
            // First do the simple check if seeing if the OS is 32 bit, in which case the process wont be 64 bit
            if (EngineCore.GetInstance().OperatingSystemAdapter.IsOperatingSystem32Bit())
            {
                return(true);
            }

            return(EngineCore.GetInstance().OperatingSystemAdapter.IsProcess32Bit(this.OpenedProcess));
        }
예제 #29
0
        /// <summary>
        /// Allocates memory in the target process, and returns the address of the new memory.
        /// </summary>
        /// <param name="size">The size of the allocation.</param>
        /// <returns>The address of the allocated memory.</returns>
        public UInt64 Allocate(Int32 size)
        {
            this.PrintDebugTag();

            UInt64 address = EngineCore.GetInstance().OperatingSystemAdapter.AllocateMemory(size).ToUInt64();

            this.RemoteAllocations.Add(address);

            return(address);
        }
예제 #30
0
        /// <summary>
        /// Allocates memory in the target process, and returns the address of the new memory.
        /// </summary>
        /// <param name="size">The size of the allocation.</param>
        /// <param name="allocAddress">The rough address of where the allocation should take place.</param>
        /// <returns>The address of the allocated memory.</returns>
        public UInt64 Allocate(Int32 size, UInt64 allocAddress)
        {
            this.PrintDebugTag();

            UInt64 address = EngineCore.GetInstance().VirtualMemory.AllocateMemory(size, allocAddress.ToIntPtr()).ToUInt64();

            this.RemoteAllocations.Add(address);

            return(address);
        }