Class VirtualMemoryUtil

java.lang.Object
com.pnfsoftware.jeb.core.units.code.asm.memory.VirtualMemoryUtil

public class VirtualMemoryUtil extends Object
Utility methods for virtual memory classes.

Methods of this class do not raise MemoryException. Instead, they return a boolean value to notify success or failure of the operation.

  • Constructor Details

    • VirtualMemoryUtil

      public VirtualMemoryUtil()
  • Method Details

    • createMemory

      public static IVirtualMemory createMemory(int spaceBits, int pageBits, Endianness standardEndianness)
      Facade factory method returning a concrete, private implementation of an efficient page-based virtual memory.
      Parameters:
      spaceBits -
      pageBits -
      standardEndianness -
      Returns:
    • isPageAllocated

      public static boolean isPageAllocated(IVirtualMemory mem, long address)
      Verify if a page was allocated (regardless of protection rights on the page).
      Parameters:
      mem -
      address -
      Returns:
    • findAvailableRange

      public static long findAvailableRange(IVirtualMemory mem, long start, int size)
      Search for an available memory range.
      Parameters:
      mem -
      start - soft start address, a hint
      size - range size
      Returns:
      the range start address, -1 on error
    • allocate

      public static long allocate(IVirtualMemory mem, long start, int size, int protection)
      Search an available range and allocate at least the requested amount of bytes. Do not confuse this method with IVirtualMemory.allocate(long, int, int).
      Parameters:
      mem -
      start - soft start address, considered a hint by this allocator routine; if you wish to allocate at a fixed, given address, use IVirtualMemory.allocate(long, int, int)
      size - range size
      protection -
      Returns:
      the base address of the allocated memory range; -1 on error
    • allocateFillGaps

      public static int allocateFillGaps(IVirtualMemory mem, long address, int size, int protection)
      Allocate a memory range, filling gaps in between already allocated pages if needed. (The given range [address, address + size) may have already allocated pages. Those pages will not be re-allocated.) When the method returns, the range [address, address + size) is guaranteed to be allocated.
      Parameters:
      address -
      size -
      protection -
      Returns:
      the number of pages that were actually allocated
    • deallocate

      public static boolean deallocate(IVirtualMemory mem, long addr, int size)
      Free a range previously allocated with allocate.
      Parameters:
      mem -
      addr - range start address
      size - range size
      Returns:
      success indicator
    • readBytesSafe

      public static int readBytesSafe(IVirtualMemory mem, long address, int size, byte[] dst, int dstOffset, int protection)
      Safely read at most the requested amount of bytes.
      Parameters:
      mem - the memory
      address - target address
      size - requested read size
      dst - destination buffer
      dstOffset - position within the destination buffer
      protection - the requested protection level, must contain at least IVirtualMemory.ACCESS_READ
      Returns:
      the number of bytes read; may be less than requested. -1 if an unknown error occurs
    • readBytesSafe

      public static int readBytesSafe(IVirtualMemory mem, long address, int size, byte[] dst, int dstOffset, boolean bypassProtection)
      Safely read at most the requested amount of bytes.
      Parameters:
      mem - the memory
      address - target address
      size - requested read size
      dst - destination buffer
      dstOffset - position within the destination buffer
      bypassProtection - if true, all pages will be read, including non-resable pages; else, only readable pages will be read
      Returns:
      the number of bytes read; may be less than requested. -1 if an unknown error occurs
    • convertSegmentFlagsToVMFlags

      public static int convertSegmentFlagsToVMFlags(int segmentFlags)
    • read

      public static int read(IVirtualMemory mem, long address)
      Read a single byte and perform a zero-extension. This method does not raise MemoryException; on error, -1 is returned.
      Parameters:
      mem -
      address -
      Returns:
      the byte, zero-extended over 32-bit; in other words, an integer in [0, 255]. On error, -1 is returned.
    • readSafe

      public static boolean readSafe(IVirtualMemory mem, long address, byte[] data)
      Read an array of bytes from memory (this method does not raise MemoryException).
      Parameters:
      mem -
      address -
      data -
      Returns:
      success indicator
    • readByteSafe

      public static boolean readByteSafe(IVirtualMemory mem, long address, byte[] out)
      Read a byte safely (this method does not raise MemoryException).
      Parameters:
      mem - virtual memory
      address - memory address
      out - single-element array that will receive the result of the read operation
      Returns:
      success indicator
    • readLEShortSafe

      public static boolean readLEShortSafe(IVirtualMemory mem, long address, short[] out)
      Read a little-endian 16-bit integer.
      Parameters:
      mem - virtual memory
      address - memory address
      out - single-element array that will receive the result of the read operation
      Returns:
      success indicator
    • readLEIntSafe

      public static boolean readLEIntSafe(IVirtualMemory mem, long address, int[] out)
      Read a little-endian 32-bit integer.
      Parameters:
      mem - virtual memory
      address - memory address
      out - single-element array that will receive the result of the read operation
      Returns:
      success indicator
    • readLELongSafe

      public static boolean readLELongSafe(IVirtualMemory mem, long address, long[] out)
      Read a little-endian 64-bit integer.
      Parameters:
      mem - virtual memory
      address - memory address
      out - single-element array that will receive the result of the read operation
      Returns:
      success indicator
    • readBEShortSafe

      public static boolean readBEShortSafe(IVirtualMemory mem, long address, short[] out)
      Read a big-endian 16-bit integer.
      Parameters:
      mem - virtual memory
      address - memory address
      out - single-element array that will receive the result of the read operation
      Returns:
      success indicator
    • readBEIntSafe

      public static boolean readBEIntSafe(IVirtualMemory mem, long address, int[] out)
      Read a big-endian 32-bit integer.
      Parameters:
      mem - virtual memory
      address - memory address
      out - single-element array that will receive the result of the read operation
      Returns:
      success indicator
    • readBELongSafe

      public static boolean readBELongSafe(IVirtualMemory mem, long address, long[] out)
      Read a big-endian 64-bit integer.
      Parameters:
      mem - virtual memory
      address - memory address
      out - single-element array that will receive the result of the read operation
      Returns:
      success indicator
    • writeSafe

      public static boolean writeSafe(IVirtualMemory mem, long address, byte[] data)
      Write an array of bytes to memory (this method does not raise MemoryException).
      Parameters:
      mem -
      address -
      data -
      Returns:
      success indicator
    • writeByteSafe

      public static boolean writeByteSafe(IVirtualMemory mem, long address, byte v)
      Write an 8-bit integer.
      Parameters:
      mem - virtual memory
      address - memory address
      v - value to be written
      Returns:
      success indicator
    • writeLEShortSafe

      public static boolean writeLEShortSafe(IVirtualMemory mem, long address, short v)
      Write a little-endian 16-bit integer.
      Parameters:
      mem - virtual memory
      address - memory address
      v - value to be written
      Returns:
      success indicator
    • writeLEIntSafe

      public static boolean writeLEIntSafe(IVirtualMemory mem, long address, int v)
      Write a little-endian 32-bit integer.
      Parameters:
      mem - virtual memory
      address - memory address
      v - value to be written
      Returns:
      success indicator
    • writeLELongSafe

      public static boolean writeLELongSafe(IVirtualMemory mem, long address, long v)
      Write a little-endian 64-bit integer.
      Parameters:
      mem - virtual memory
      address - memory address
      v - value to be written
      Returns:
      success indicator
    • readShortSafe

      public static boolean readShortSafe(Endianness end, IVirtualMemory mem, long address, short[] out)
      Read a little-endian 16-bit integer using a specific byte ordering.
      Parameters:
      end - wanted endianness (little or big)
      mem - virtual memory
      address - memory address
      out - single-element array that will receive the result of the read operation
      Returns:
      success indicator
    • readIntSafe

      public static boolean readIntSafe(Endianness end, IVirtualMemory mem, long address, int[] out)
      Read a little-endian 32-bit integer using a specific byte ordering.
      Parameters:
      end - wanted endianness (little or big)
      mem - virtual memory
      address - memory address
      out - single-element array that will receive the result of the read operation
      Returns:
      success indicator
    • readLongSafe

      public static boolean readLongSafe(Endianness end, IVirtualMemory mem, long address, long[] out)
      Read a little-endian 64-bit integer using a specific byte ordering.
      Parameters:
      end - wanted endianness (little or big)
      mem - virtual memory
      address - memory address
      out - single-element array that will receive the result of the read operation
      Returns:
      success indicator
    • writeShortSafe

      public static boolean writeShortSafe(Endianness end, IVirtualMemory mem, long address, short v)
      Write a little-endian 16-bit integer using a specific byte ordering.
      Parameters:
      end - wanted endianness (little or big)
      mem - virtual memory
      address - memory address
      v - value to be written
      Returns:
      success indicator
    • writeIntSafe

      public static boolean writeIntSafe(Endianness end, IVirtualMemory mem, long address, int v)
      Write a little-endian 32-bit integer using a specific byte ordering.
      Parameters:
      end - wanted endianness (little or big)
      mem - virtual memory
      address - memory address
      v - value to be written
      Returns:
      success indicator
    • writeLongSafe

      public static boolean writeLongSafe(Endianness end, IVirtualMemory mem, long address, long v)
      Write a little-endian 64-bit integer using a specific byte ordering.
      Parameters:
      end - wanted endianness (little or big)
      mem - virtual memory
      address - memory address
      v - value to be written
      Returns:
      success indicator
    • writeBooleans

      public static boolean writeBooleans(IVirtualMemory mem, long address, boolean[] array, int offset, int count)
      Write an array of booleans to memory. Each entry occupies 1 byte whose value will be set to 0(false) or 1(true).
      Parameters:
      mem - virtual memory
      address - memory address
      array - array
      offset - start offset in the array
      count - count of elements to write
      Returns:
      success indicator
    • readBooleans

      public static boolean readBooleans(IVirtualMemory mem, long address, boolean[] array, int offset, int count)
      Read an array of booleans from memory. Each entry occupies 1 byte of memory, the lower-significant bit of the byte indicates false(0) or true(1).
      Parameters:
      mem - virtual memory
      address - memory address
      array - array
      offset - start offset in the array
      count - count of elements to write
      Returns:
      success indicator
    • writeBytes

      public static boolean writeBytes(IVirtualMemory mem, long address, byte[] array, int offset, int count)
      Write an array of bytes to memory.
      Parameters:
      mem - virtual memory
      address - memory address
      array - array
      offset - start offset in the array
      count - count of elements to write
      Returns:
      success indicator
    • readBytes

      public static boolean readBytes(IVirtualMemory mem, long address, byte[] array, int offset, int count)
      Read an array of bytes from memory.
      Parameters:
      mem - virtual memory
      address - memory address
      array - array
      offset - start offset in the array
      count - count of elements to write
      Returns:
      success indicator
    • writeChars

      public static boolean writeChars(IVirtualMemory mem, long address, char[] array, int offset, int count)
      Write an array of chars to memory. Each entry occupies 2 bytes of memory. Byte ordering is determined from the virtual memory endianness setting.
      Parameters:
      mem - virtual memory
      address - memory address
      array - array
      offset - start offset in the array
      count - count of elements to write
      Returns:
      success indicator
    • readChars

      public static boolean readChars(IVirtualMemory mem, long address, char[] array, int offset, int count)
      Read an array of chars from memory. Each entry occupies 2 bytes of memory. Byte ordering is determined from the virtual memory endianness setting.
      Parameters:
      mem - virtual memory
      address - memory address
      array - array
      offset - start offset in the array
      count - count of elements to write
      Returns:
      success indicator
    • writeShorts

      public static boolean writeShorts(IVirtualMemory mem, long address, short[] array, int offset, int count)
      Write an array of shorts to memory. Each entry occupies 2 bytes of memory. Byte ordering is determined from the virtual memory endianness setting.
      Parameters:
      mem - virtual memory
      address - memory address
      array - array
      offset - start offset in the array
      count - count of elements to write
      Returns:
      success indicator
    • readShorts

      public static boolean readShorts(IVirtualMemory mem, long address, short[] array, int offset, int count)
      Read an array of shorts from memory. Each entry occupies 2 bytes of memory. Byte ordering is determined from the virtual memory endianness setting.
      Parameters:
      mem - virtual memory
      address - memory address
      array - array
      offset - start offset in the array
      count - count of elements to write
      Returns:
      success indicator
    • writeInts

      public static boolean writeInts(IVirtualMemory mem, long address, int[] array, int offset, int count)
      Write an array of ints to memory. Each entry occupies 4 bytes of memory. Byte ordering is determined from the virtual memory endianness setting.
      Parameters:
      mem - virtual memory
      address - memory address
      array - array
      offset - start offset in the array
      count - count of elements to write
      Returns:
      success indicator
    • readInts

      public static boolean readInts(IVirtualMemory mem, long address, int[] array, int offset, int count)
      Read an array of ints from memory. Each entry occupies 4 bytes of memory. Byte ordering is determined from the virtual memory endianness setting.
      Parameters:
      mem - virtual memory
      address - memory address
      array - array
      offset - start offset in the array
      count - count of elements to write
      Returns:
      success indicator
    • writeLongs

      public static boolean writeLongs(IVirtualMemory mem, long address, long[] array, int offset, int count)
      Write an array of longs to memory. Each entry occupies 8 bytes of memory. Byte ordering is determined from the virtual memory endianness setting.
      Parameters:
      mem - virtual memory
      address - memory address
      array - array
      offset - start offset in the array
      count - count of elements to write
      Returns:
      success indicator
    • readLongs

      public static boolean readLongs(IVirtualMemory mem, long address, long[] array, int offset, int count)
      Read an array of longs from memory. Each entry occupies 8 bytes of memory. Byte ordering is determined from the virtual memory endianness setting.
      Parameters:
      mem - virtual memory
      address - memory address
      array - array
      offset - start offset in the array
      count - count of elements to write
      Returns:
      success indicator
    • writeFloats

      public static boolean writeFloats(IVirtualMemory mem, long address, float[] array, int offset, int count)
      Write an array of floats to memory. Each entry occupies 4 bytes of memory. The encoding used is IEEE754. Byte ordering is determined from the virtual memory endianness setting.
      Parameters:
      mem - virtual memory
      address - memory address
      array - array
      offset - start offset in the array
      count - count of elements to write
      Returns:
      success indicator
    • readFloats

      public static boolean readFloats(IVirtualMemory mem, long address, float[] array, int offset, int count)
      Read an array of floats from memory. Each entry occupies 4 bytes of memory. Byte ordering is determined from the virtual memory endianness setting.
      Parameters:
      mem - virtual memory
      address - memory address
      array - array
      offset - start offset in the array
      count - count of elements to write
      Returns:
      success indicator
    • writeDoubles

      public static boolean writeDoubles(IVirtualMemory mem, long address, double[] array, int offset, int count)
      Write an array of doubles to memory. Each entry occupies 8 bytes of memory. The encoding used is IEEE754. Byte ordering is determined from the virtual memory endianness setting.
      Parameters:
      mem - virtual memory
      address - memory address
      array - array
      offset - start offset in the array
      count - count of elements to write
      Returns:
      success indicator
    • readDoubles

      public static boolean readDoubles(IVirtualMemory mem, long address, double[] array, int offset, int count)
      Read an array of doubles from memory. Each entry occupies 8 bytes of memory. Byte ordering is determined from the virtual memory endianness setting.
      Parameters:
      mem - virtual memory
      address - memory address
      array - array
      offset - start offset in the array
      count - count of elements to write
      Returns:
      success indicator
    • readNullTerminatedStringSafe

      public static String readNullTerminatedStringSafe(IVirtualMemory mem, long address, int maxSize)
      Read from memory a series of ASCII characters, terminated by a null byte, and build the corresponding String. If no null-byte is found, the search stops at the provided maxSize.

      This method does not raise MemoryException.

      Parameters:
      mem - a VM
      address - memory address
      maxSize - maximum string length in ascii characters
      Returns:
      the string or null if a failure happened (e.g. string is too long, memory error occurred, etc.)
    • getCopyOnWriteShim

      public static IVirtualMemoryShim getCopyOnWriteShim(IVirtualMemory mem)
      Create a copy-on-write shim of the provided virtual memory, if possible. The shim can be used to perform safe memory writes, that will not impact the underlying memory. Using a shim yields better performance than copying the entire source VM and working on the full copy.
      Parameters:
      mem - a VM
      Returns:
      the shim VM
      Throws:
      IllegalArgumentException - if the provided VM object does not support the creation of a shim
    • findByte

      public static long findByte(IVirtualMemory mem, long address, long lastAddress, int val)
      Search for a single byte of memory. Similar as memchr or memrchr (if `lastAddress` is less than `address`).
      Parameters:
      mem -
      address -
      lastAddress -
      val -
      Returns:
    • findBytes

      public static long findBytes(IVirtualMemory mem, boolean bypassProtection, long address, long lastAddress, byte[] pattern, byte[] patternMask)
      Search for bytes in memory, with an optional binary mask. The search can either be forward (default), in which case the resulting found address will be either -1 or ≥ the start address, or backward, in which case the resulting found address will be either -1 or ≤ the start address.
      Parameters:
      mem - memory to be searched
      bypassProtection - if true, memory page protection is disregarded, in which case all pages, including non-readable ones, will be searched
      address - start address for the search (this value is treated as unsigned)
      lastAddress - end address (the value is treated as unsigned); may be less than the start address, in which case a reverse search will be performed
      pattern - bytes to search for; the maximum allowed length is the memory's page size
      patternMask - optional binary mask for a wildcard search; if non-null, must be the same length as the pattern's
      Returns:
      -1 if not found, else, the resulting address
    • readAsLongSafe

      public static Long readAsLongSafe(IVirtualMemory mem, long address, int size)
      Read an integer (byte, short, int or long) and converts it to Long. Standard memory byte ordering is used for decoding.
      Parameters:
      mem - the virtual memory
      address - memory address of the data
      size - any of 1, 2, 4, or 8
      Returns:
      the long value or null on error
    • readAsLongSafe

      public static Long readAsLongSafe(IVirtualMemory mem, Endianness endianness, long address, int size)
    • readAsUnsignedLongSafe

      public Long readAsUnsignedLongSafe(IVirtualMemory mem, long address, int size)
      Read an integer (byte, short, int or long) and zero extend it to Long. Standard memory byte ordering is used for decoding. Note that if a signed long is read, the value may be negative (overflow should be appreciated by caller).
      Parameters:
      mem - the virtual memory
      address - memory address of the data
      size - any of 1, 2, 4, or 8
      Returns:
      the long value or null on error
    • readAsUnsignedLongSafe

      public static Long readAsUnsignedLongSafe(IVirtualMemory mem, Endianness endianness, long address, int size)
    • dump

      public static byte[] dump(IVirtualMemory vm, long addr, long addrEnd)
      Dump a contiguous memory range of memory to a byte array. Illegal pages (non-allocated) are dumped as empty pages (all bytes are zero).
      Parameters:
      vm - virtual memory
      addr - start address
      addrEnd - end address
      Returns:
      the byte buffer holding the dumped data
    • dump

      public static void dump(IVirtualMemory vm, long addr, long addrEnd, byte[] dst, int dstOffset)
      Dump a contiguous memory range of memory to a buffer. Illegal pages (non-allocated) are dumped as empty pages (all bytes are zero).
      Parameters:
      vm - virtual memory
      addr - start address
      addrEnd - end address
      dst - destination buffer
      dstOffset - offset in the destination
    • dumpToImageFiles

      public static void dumpToImageFiles(IVirtualMemory vm, File folder) throws IOException
      Dump a virtual memory to files in a folder. The files will be named as the start of the memory range (in hex) they contain.
      Parameters:
      vm - virtual memory
      folder - destination folder; if it does not exist, a new folder will be created
      Throws:
      IOException
    • dumpToImageFiles

      public static void dumpToImageFiles(IVirtualMemory vm, File folder, String pfx, String sfx) throws IOException
      Dump a virtual memory to files in a folder. The files will be named [PREFIX][MEMORY_RANGE_START][SUFFIX].
      Parameters:
      vm - virtual memory
      folder - destination folder; if it does not exist, a new folder will be created
      pfx - optional prefix for the filenames
      sfx - optional suffix for the filenames
      Throws:
      IOException