public bool GetInstructions(uint aAddress, TArmInstructionSet aInstructionSet, int aCount, out IArmInstruction[] aInstructions)
        {
            bool valid = false;

            aInstructions = new IArmInstruction[0];

            // We need the code and the instruction converter
            if (IsCodeAvailable && IfaceInstructionConverter != null)
            {
                // Check range is valid
                AddressRange range = new AddressRange(iBaseAddress, 0);
                range.UpdateMax(range.Min + iCode.Length);
                uint extent = aAddress + ((uint)aCount * (uint)aInstructionSet);
                //
                valid = range.Contains(aAddress) && range.Contains(extent);
                if (valid)
                {
                    List <uint> rawInstructions = new List <uint>();
                    //
                    using (SymbianStreamReaderLE reader = SymbianStreamReaderLE.New(new MemoryStream(iCode)))
                    {
                        uint address = aAddress - iBaseAddress;
                        reader.Seek(address);
                        //
                        for (int i = 0; i < aCount; i++)
                        {
                            uint value = 0;
                            //
                            switch (aInstructionSet)
                            {
                            case TArmInstructionSet.ETHUMB:
                                value = reader.ReadUInt16();
                                break;

                            case TArmInstructionSet.EARM:
                                value = reader.ReadUInt32();
                                break;

                            default:
                            case TArmInstructionSet.EJAZELLE:
                                throw new NotSupportedException("Jazelle is not supported");
                            }
                            //
                            rawInstructions.Add(value);
                            address += (uint)aInstructionSet;
                        }
                    }
                    //
                    aInstructions = iInstructionConverter.ConvertRawValuesToInstructions(aInstructionSet, rawInstructions.ToArray(), aAddress);
                }
            }

            // Return empty array if not valid
            return(valid);
        }
        private CIRegisterVisBitRange AddBitRange(CIRegisterVisualization aVisualization, uint aStart, uint aEnd, string aCategory)
        {
            // Make the mask
            AddressRange  range = new AddressRange(aStart, aEnd);
            StringBuilder mask  = new StringBuilder();

            mask.Append(string.Empty.PadLeft(32, '#'));
            for (int i = 31; i >= 0; i--)
            {
                if (range.Contains(i))
                {
                    int index = 31 - i;
                    mask[index] = '1';
                }
            }

            // Reserved
            uint value = aVisualization.Register.Value;

            CIRegisterVisBitRange bitRange = new CIRegisterVisBitRange(Container, aStart, aEnd, aCategory);

            bitRange.ExtractBits(value, mask.ToString());
            aVisualization.AddChild(bitRange);

            return(bitRange);
        }
        public override void Check(CIContainer aContainer)
        {
            CISummarisableEntityList list = aContainer.Summaries;

            foreach (CISummarisableEntity entry in list)
            {
                bool stackAvailable = entry.IsAvailable(CISummarisableEntity.TElement.EElementStack);
                bool regsAvailable  = entry.IsAvailable(CISummarisableEntity.TElement.EElementRegisters);
                if (stackAvailable && regsAvailable)
                {
                    CIStack stack = entry.Stack;
                    //
                    bool pointerAvailable = stack.Registers.Contains(TArmRegisterType.EArmReg_SP);
                    if (pointerAvailable)
                    {
                        CIRegister   regSP          = stack.Pointer;
                        AddressRange stackDataRange = stack.RawDataRange;
                        //
                        if (!stackDataRange.Contains(regSP))
                        {
                            base.CreateWarning(aContainer, stack,
                                               LibResources.CPIDStackDataValidator_Title,
                                               string.Format(LibResources.CPIDStackDataValidator_Description, base.CreateIdentifierText(entry))
                                               );
                        }
                    }
                }
            }
        }
Example #4
0
        public void TestSatisfiableRange()
        {
            using (var ctx = new Context())
            {
                IPAddress low   = IPAddress.Parse("127.0.0.1");
                IPAddress high  = IPAddress.Parse("127.0.0.10");
                var       range = new AddressRange
                {
                    Low  = low,
                    High = high
                };

                string     variableName = "address";
                BitVecExpr variable     = ctx.MkConst(variableName, ctx.MkBitVecSort(32)) as BitVecExpr;
                Assert.IsNotNull(variable);
                Solver s = ctx.MkSolver();
                s.Assert(range.Contains(ctx, variable));
                Status result = s.Check();
                Assert.AreEqual(Status.SATISFIABLE, result);
                IPAddress binding;
                Assert.IsTrue(RetrieveModelValue.TryRetrieveAddress(variableName, s.Model, out binding));
                Assert.IsTrue(AddressRangeTest.CompareAddresses(low, binding) >= 0);
                Assert.IsTrue(AddressRangeTest.CompareAddresses(high, binding) <= 0);
            }
        }
Example #5
0
 private bool CheckSafeToActivate(CodeSegDefinition aCodeSegment)
 {
     lock ( iActivationLUT )
     {
         bool alreadyExists = iActivationLUT.ContainsKey(aCodeSegment);
         if (alreadyExists)
         {
             // Specified code segment already activated
             return(false);
         }
         else
         {
             // We must check that there's no overlap in activation ranges between code segments.
             foreach (KeyValuePair <CodeSegDefinition, SymSourceAndCollection> kvp in iActivationLUT)
             {
                 AddressRange range = kvp.Key;
                 if (range.Contains(aCodeSegment))
                 {
                     // Overlaps with existing activated code segment
                     return(false);
                 }
             }
         }
         //
         return(true);
     }
 }
Example #6
0
        /// <summary>
        /// Gets a <see cref="VirtualFile"/> ready for reading given an offset and requested read length.
        /// </summary>
        /// <param name="offset">Offset of the file.</param>
        /// <param name="length">Length of the file.</param>
        /// <param name="file">The file, ready for reading.</param>
        public bool TryFindFile(int offset, int length, out VirtualFile file)
        {
            // O(1) if read is at known offset. Most likely to occur.
            if (Files.ContainsKey(offset))
            {
                // Cache for reading.
                _recentOffsets[_lastOffsetIndex++] = offset;
                _lastOffsetIndex %= _recentOffsets.Length;

                // Return offsets :P
                file = Files[offset];
                file = file.SliceUpTo(0, length);
                return(true);
            }

            // Try O(LastOffetsNum) in very likely probability chunk recent file requested.
            var requestedReadRange = new AddressRange(offset, offset + length);

            foreach (var recentOffset in _recentOffsets)
            {
                if (Files.ContainsKey(recentOffset))
                {
                    var lastFile = Files[recentOffset];

                    var entryReadRange = new AddressRange(recentOffset, RoundUp(recentOffset + lastFile.Length, Alignment));
                    if (entryReadRange.Contains(ref requestedReadRange))
                    {
                        return(ReturnFoundFile(entryReadRange, out file));
                    }
                }
            }

            // Otherwise search one by one in O(N) fashion.
            if (AfsFileViewer.TryFromMemory(HeaderPtr, out var fileViewer))
            {
                foreach (var entry in fileViewer.Entries)
                {
                    var entryReadRange = new AddressRange(entry.Offset, RoundUp(entry.Offset + entry.Length, Alignment));
                    if (entryReadRange.Contains(ref requestedReadRange))
                    {
                        return(ReturnFoundFile(entryReadRange, out file));
                    }
                }
            }

            // Returns a file if it has been found.
            bool ReturnFoundFile(AddressRange entryReadRange, out VirtualFile returnFile)
            {
                int readOffset = requestedReadRange.Start - entryReadRange.Start;
                int readLength = length;

                returnFile = Files[entryReadRange.Start];
                returnFile = returnFile.SliceUpTo(readOffset, readLength);
                return(true);
            }

            file = null;
            return(false);
        }
        public bool IsInstructionAddressValid(uint aAddress)
        {
            bool valid = false;

            //
            if (IsCodeAvailable)
            {
                AddressRange range = new AddressRange(this.BaseAddress, 0);
                range.UpdateMax(range.Min + iCode.Length);
                //
                valid = range.Contains(aAddress);
            }
            //
            return(valid);
        }
Example #8
0
            public int Compare(Symbol aLeft, Symbol aRight)
            {
                int ret = -1;
                //
                AddressRange lr = aLeft.AddressRange;
                AddressRange rr = aRight.AddressRange;

                //
                if (lr.Contains(rr) || rr.Contains(lr))
                {
                    ret = 0;
                }
                else
                {
                    ret = lr.CompareTo(rr);
                }
                //
                return(ret);
            }
Example #9
0
            public int Compare(AddressCollectionPair aLeft, AddressCollectionPair aRight)
            {
                int ret = -1;
                //
                AddressRange lr = aLeft.Range;
                AddressRange rr = aRight.Range;

                //
                if (lr.Contains(rr) || rr.Contains(lr))
                {
                    ret = 0;
                }
                else
                {
                    ret = lr.CompareTo(rr);
                }
                //
                return(ret);
            }
Example #10
0
            public int Compare(RVCTDisassemblyFunction aLeft, RVCTDisassemblyFunction aRight)
            {
                int ret = -1;
                //
                AddressRange lr = aLeft.AddressRange;
                AddressRange rr = aRight.AddressRange;

                //
                if (lr.Contains(rr) || rr.Contains(lr))
                {
                    ret = 0;
                }
                else
                {
                    ret = lr.CompareTo(rr);
                }
                //
                return(ret);
            }
Example #11
0
        public void TestUnsatisfiableRange()
        {
            using (var ctx = new Context())
            {
                IPAddress low   = IPAddress.Parse("192.168.0.1");
                IPAddress high  = IPAddress.Parse("192.0.100.0");
                var       range = new AddressRange
                {
                    Low  = low,
                    High = high
                };

                string     variableName = "address";
                BitVecExpr variable     = ctx.MkConst(variableName, ctx.MkBitVecSort(32)) as BitVecExpr;
                Solver     s            = ctx.MkSolver();
                s.Assert(range.Contains(ctx, variable));
                Status result = s.Check();
                Assert.AreEqual(Status.UNSATISFIABLE, result);
            }
        }
Example #12
0
        /// <summary>
        /// Searches unmanaged memory for pre-existing <see cref="MemoryBuffer"/>s that satisfy
        /// the given size requirements and address range.
        /// </summary>
        /// <param name="size">The amount of bytes a buffer must have minimum.</param>
        /// <param name="minimumAddress">The maximum pointer a <see cref="MemoryBuffer"/> can occupy.</param>
        /// <param name="maximumAddress">The minimum pointer a <see cref="MemoryBuffer"/> can occupy.</param>
        /// <param name="useCache">See <see cref="MemoryBufferSearcher.GetBuffers"/></param>
        /// <returns></returns>
        public MemoryBuffer[] FindBuffers(int size, IntPtr minimumAddress, IntPtr maximumAddress, bool useCache = true)
        {
            // Get buffers already existing in process.
            var buffers = _bufferSearcher.GetBuffers(size, useCache);

            // Get all MemoryBuffers where their raw data range fits into the given minimum and maximum address.
            AddressRange allowedRange  = new AddressRange((long)minimumAddress, (long)maximumAddress);
            var          memoryBuffers = new List <MemoryBuffer>(buffers.Length);

            foreach (var buffer in buffers)
            {
                var bufferHeader       = buffer.Properties;
                var bufferAddressRange = new AddressRange((long)bufferHeader.DataPointer, (long)(bufferHeader.DataPointer + bufferHeader.Size));
                if (allowedRange.Contains(ref bufferAddressRange))
                {
                    memoryBuffers.Add(buffer);
                }
            }

            return(memoryBuffers.ToArray());
        }
Example #13
0
        public void TestSingle()
        {
            using (var ctx = new Context())
            {
                IPAddress single = IPAddress.Parse("192.168.0.1");
                var       range  = new AddressRange
                {
                    Low  = single,
                    High = single
                };

                string     variableName = "address";
                BitVecExpr variable     = ctx.MkConst(variableName, ctx.MkBitVecSort(32)) as BitVecExpr;
                Solver     s            = ctx.MkSolver();
                s.Assert(range.Contains(ctx, variable));
                Status result = s.Check();
                Assert.AreEqual(Status.SATISFIABLE, result);
                IPAddress binding;
                Assert.IsTrue(RetrieveModelValue.TryRetrieveAddress(variableName, s.Model, out binding));
                Assert.AreEqual(single, binding);
            }
        }
Example #14
0
        /// <summary>
        /// Checks if a buffer can be created within a given set of pages described by pageInfo
        /// satisfying the given size, minimum and maximum memory location.
        /// </summary>
        /// <param name="pageInfo">Contains the information about a singular memory page.</param>
        /// <param name="bufferSize">The size that a <see cref="MemoryBuffer"/> would occupy. Pre-aligned to page-size.</param>
        /// <param name="minimumPtr">The maximum pointer a <see cref="MemoryBuffer"/> can occupy.</param>
        /// <param name="maximumPtr">The minimum pointer a <see cref="MemoryBuffer"/> can occupy.</param>
        /// <returns>Zero if the operation fails; otherwise positive value.</returns>
        private IntPtr GetBufferPointerInPageRange(ref MEMORY_BASIC_INFORMATION pageInfo, int bufferSize, IntPtr minimumPtr, IntPtr maximumPtr)
        {
            // Fast return if page is not free.
            if (pageInfo.State != (uint)MEM_ALLOCATION_TYPE.MEM_FREE)
            {
                return(IntPtr.Zero);
            }

            // This is valid in both 32bit and 64bit Windows.
            // We can call GetSystemInfo to get this but that's a waste; these are constant for x86 and x64.
            int allocationGranularity = 65536;

            // Do not align page start/end to allocation granularity yet.
            // Align it when we map the possible buffer ranges in the pages.
            long pageStart = (long)pageInfo.BaseAddress;
            long pageEnd   = (long)pageInfo.BaseAddress + (long)pageInfo.RegionSize;

            // Get range for page and min-max region.
            var minMaxRange = new AddressRange((long)minimumPtr, (long)maximumPtr);
            var pageRange   = new AddressRange(pageStart, pageEnd);

            if (!pageRange.Overlaps(ref minMaxRange))
            {
                return(IntPtr.Zero);
            }

            /* Three possible cases here:
             * 1. Page fits entirely inside min-max range and is smaller.
             * 2. Min-max range is inside page (i.e. page is bigger than the range)
             * 3. Page and min-max intersect, e.g. first half of pages in end of min-max
             *    or second half of pages in start of min-max.
             *
             * Below we will build a set of possible buffer allocation ranges
             * and check if they satisfy our conditions.
             */

            /* Try placing range at start and end of page boundaries.
             * Since we are allocating in page boundaries, we must compare against Min-Max. */

            // Note: We are rounding page boundary addresses up/down, possibly beyond the original ends/starts of page.
            //       We need to validate that we are still in the bounds of the actual page itself.

            var allocPtrPageMaxAligned = Mathematics.RoundDown(pageRange.EndPointer - bufferSize, allocationGranularity);
            var allocRangePageMaxStart = new AddressRange(allocPtrPageMaxAligned, allocPtrPageMaxAligned + bufferSize);

            if (pageRange.Contains(ref allocRangePageMaxStart) && minMaxRange.Contains(ref allocRangePageMaxStart))
            {
                return((IntPtr)allocRangePageMaxStart.StartPointer);
            }

            var allocPtrPageMinAligned = Mathematics.RoundUp(pageRange.StartPointer, allocationGranularity);
            var allocRangePageMinStart = new AddressRange(allocPtrPageMinAligned, allocPtrPageMinAligned + bufferSize);

            if (pageRange.Contains(ref allocRangePageMinStart) && minMaxRange.Contains(ref allocRangePageMinStart))
            {
                return((IntPtr)allocRangePageMinStart.StartPointer);
            }

            /* Try placing range at start and end of given minimum-maximum.
             * Since we are allocating in Min-Max, we must compare against Page Boundaries. */

            // Note: Remember that rounding is dangerous and could potentially cause max and min to cross as usual,
            //       must check proposed page range against both given min-max and page memory range.

            var allocPtrMaxAligned = Mathematics.RoundDown((long)maximumPtr - bufferSize, allocationGranularity);
            var allocRangeMaxStart = new AddressRange(allocPtrMaxAligned, allocPtrMaxAligned + bufferSize);

            if (pageRange.Contains(ref allocRangeMaxStart) && minMaxRange.Contains(ref allocRangeMaxStart))
            {
                return((IntPtr)allocRangeMaxStart.StartPointer);
            }

            var allocPtrMinAligned = Mathematics.RoundUp((long)minimumPtr, allocationGranularity);
            var allocRangeMinStart = new AddressRange(allocPtrMinAligned, allocPtrMinAligned + bufferSize);

            if (pageRange.Contains(ref allocRangeMinStart) && minMaxRange.Contains(ref allocRangeMinStart))
            {
                return((IntPtr)allocRangeMinStart.StartPointer);
            }

            return(IntPtr.Zero);
        }
Example #15
0
        protected override void PerformOperation()
        {
            // Get the source data we need to reconstruct and signal we're about to start
            StackSourceData sourceData = base.SourceData;

            // Get the output data sink
            StackOutputData outputData = base.OutputData;

            outputData.Clear();
            outputData.AlgorithmName = Name;

            // Get the address range of the stack pointer data
            AddressRange pointerRange         = base.Engine.AddressInfo.StackPointerRange;
            AddressRange pointerRangeExtended = base.Engine.AddressInfo.StackPointerRangeWithExtensionArea;

            // Indicates if we added LR and PC to the call stack
            bool addedLRandPC = false;

            // Get registers
            ArmRegisterCollection regs = base.Engine.Registers;

            foreach (DataBufferUint sourceEntry in sourceData.GetUintEnumerator())
            {
                // Check if it is within the stack domain, taking into account
                // our extended range
                if (pointerRangeExtended.Contains(sourceEntry.Address))
                {
                    StackOutputEntry outputEntry = new StackOutputEntry(sourceEntry.Address, sourceEntry.Uint, base.DebugEngineView);

                    // Is it the element tht corresponds to the current value of SP?
                    bool isCurrentSPEntry = (outputEntry.AddressRange.Contains(base.Engine.AddressInfo.Pointer));
                    outputEntry.IsCurrentStackPointerEntry = isCurrentSPEntry;

                    // Is it within the pure 'stack pointer' address range?
                    bool outsidePureStackPointerRange = !pointerRange.Contains(sourceEntry.Address);
                    outputEntry.IsOutsideCurrentStackRange = outsidePureStackPointerRange;

                    // These are never accurate, but neither are they ghosts
                    outputEntry.IsAccurate = false;
                    outputEntry.IsGhost    = false;

                    // Save entry
                    EmitElement(outputEntry);

                    // If we're inside the stack address range, then poke in the PC and LR values
                    if (isCurrentSPEntry)
                    {
                        System.Diagnostics.Debug.Assert(!addedLRandPC);
                        addedLRandPC = AddLRAndPC();
                    }
                }
                else
                {
                    // Nope, ignore it...
                }

                NotifyEvent(TEvent.EReadingProgress);
                ++iDWordIndex;
            }

            // If the stack overflowed, then SP might be outside of the stack range. Therefore
            // LR and PC will not be added yet.
            if (!addedLRandPC)
            {
                AddLRAndPC();
            }
        }
        private void CreateStackOutput()
        {
            // Get the source data we need to reconstruct and signal we're about to start
            StackSourceData sourceData = base.SourceData;

            // Get the output data sink
            StackOutputData outputData = base.OutputData;

            outputData.Clear();
            outputData.AlgorithmName = Name;

            // Get the address range of the stack pointer data
            AddressRange pointerRange         = base.Engine.AddressInfo.StackPointerRange;
            AddressRange pointerRangeExtended = base.Engine.AddressInfo.StackPointerRangeWithExtensionArea;

            foreach (DataBufferUint sourceEntry in sourceData.GetUintEnumerator())
            {
                // Check if it is within the stack domain, taking into account
                // our extended range
                if (pointerRangeExtended.Contains(sourceEntry.Address))
                {
                    StackOutputEntry outputEntry = new StackOutputEntry(sourceEntry.Address, sourceEntry.Uint, base.DebugEngineView);

                    // Is it the element that corresponds to the current value of SP?
                    bool isCurrentSPEntry = (outputEntry.AddressRange.Contains(base.Engine.AddressInfo.Pointer));

                    // Is it within the pure 'stack pointer' address range?
                    bool outsidePureStackPointerRange = !pointerRange.Contains(sourceEntry.Address);
                    outputEntry.IsOutsideCurrentStackRange = outsidePureStackPointerRange;

                    // Is it a ghost?
                    if (outputEntry.Symbol != null)
                    {
                        ArmStackFrame realStackFrame = FrameByStackAddress(sourceEntry.Address);
                        outputEntry.IsAccurate = (realStackFrame != null);
                        outputEntry.IsGhost    = (realStackFrame == null);
                    }

                    // Save entry
                    EmitElement(outputEntry);

                    // If we're inside the stack address range, then poke in the PC and LR values
                    if (isCurrentSPEntry)
                    {
                        outputEntry.IsCurrentStackPointerEntry = true;

                        // Working bottom up, so LR should go on the stack first
                        ArmStackFrame stackFrameLR = FrameByRegisterType(TArmRegisterType.EArmReg_LR);
                        if (stackFrameLR != null)
                        {
                            StackOutputEntry entryLR = new StackOutputEntry(0, stackFrameLR.Data, base.DebugEngineView);
                            entryLR.IsRegisterBasedEntry       = true;
                            entryLR.IsOutsideCurrentStackRange = true;
                            entryLR.AssociatedRegister         = stackFrameLR.AssociatedRegister;
                            EmitElement(entryLR);
                        }

                        // Then the PC...
                        ArmStackFrame stackFramePC = FrameByRegisterType(TArmRegisterType.EArmReg_PC);
                        if (stackFramePC != null)
                        {
                            StackOutputEntry entryPC = new StackOutputEntry(0, stackFramePC.Data, base.DebugEngineView);
                            entryPC.IsRegisterBasedEntry       = true;
                            entryPC.IsOutsideCurrentStackRange = true;
                            entryPC.AssociatedRegister         = stackFramePC.AssociatedRegister;
                            EmitElement(entryPC);
                        }
                    }
                }
                else
                {
                    // Nope, ignore it...
                }

                NotifyEvent(TEvent.EReadingProgress);
                ++iDWordIndex;
            }
        }