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)) ); } } } } }
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); } }
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); } }
/// <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); }
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); }
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); }
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); }
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); } }
/// <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()); }
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); } }
/// <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); }
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; } }