diff --git a/CLIPreview.PNG b/CLIPreview.PNG
new file mode 100644
index 0000000..599bc86
Binary files /dev/null and b/CLIPreview.PNG differ
diff --git a/Echo/Echo.Concrete.dll b/Echo/Echo.Concrete.dll
new file mode 100644
index 0000000..d90d318
Binary files /dev/null and b/Echo/Echo.Concrete.dll differ
diff --git a/Echo/Echo.Concrete.xml b/Echo/Echo.Concrete.xml
new file mode 100644
index 0000000..4189c92
--- /dev/null
+++ b/Echo/Echo.Concrete.xml
@@ -0,0 +1,1983 @@
+
+
+
+ Echo.Concrete
+
+
+
+
+ Represents an exception that occurs during the dispatch phase of a virtual machine.
+
+
+
+
+ Creates a new instance of the class.
+
+
+
+
+ Creates a new instance of the class, with the provided message.
+
+ The error message.
+
+
+
+ Creates a new instance of the class, with the provided message.
+
+ The error message.
+ The inner cause of the error.
+
+
+
+
+
+
+ Represents a result produced after dispatching an instruction to an operation code handler.
+
+
+
+
+ Creates a new dispatch result indicating a successful dispatch and execution of the instruction.
+
+ The dispatch result.
+
+
+
+ Creates a new dispatch result indicating an invalid program was detected.
+
+ The dispatch result.
+
+
+
+ Creates a new dispatch result with the provided exception.
+
+ The exception that occured during the execution of the instruction.
+
+
+
+ Gets or sets a value indicating whether the execution of the program was terminated.
+
+
+
+
+ Gets a value indicating the execution of an instruction was successful.
+
+
+
+
+ Gets or sets the exception that was thrown during the dispatch of the instruction (if any).
+
+
+
+
+ Represents the exception that is thrown when a virtual machine encounters an error.
+
+
+
+
+ Creates a new instance of the class.
+
+
+
+
+ Creates a new instance of the class, with the provided message.
+
+ The error message.
+
+
+
+ Creates a new instance of the class, with the provided message
+ and inner exception.
+
+ The error message.
+ The inner cause of the exception.
+
+
+
+
+
+
+ Represents an aggregation of results that were produced during the execution of a virtual machine.
+
+
+
+
+ Gets a value indicating whether the execution finished successfully.
+
+
+
+
+ Gets or sets the exception that was thrown during the execution of the program (if any).
+
+
+
+
+ Gets or sets the return value that was produced (if any).
+
+
+ A value of null indicates no value was produced.
+
+
+
+
+ Provides arguments for describing the event that is fired upon the termination of a virtual machine.
+
+
+
+
+ Creates a new instance of the class.
+
+ The results produced during the execution.
+
+
+
+ Gets the results that were produced during the execution of the virtual machine.
+
+
+
+
+ Provides an interface to an emulation of a computer system.
+
+ The type of instructions to emulate.
+
+
+
+ Represents the event that occurs when the execution of the virtual machine has ended.
+
+
+
+
+ Gets a value indicating the current status of the virtual machine.
+
+
+
+
+ Executes the instructions until completion.
+
+ The cancellation token to use for aborting the execution.
+ The produced result.
+
+ Occurs when an internal error occurs within the virtual machine.
+
+
+ This method consumes any exception that might be thrown by the user-code. In such an event, the exception
+ is put into the property of the return value of this method.
+
+
+
+
+ Represents the exception that occurs upon the execution of an undefined instruction.
+
+
+
+
+ Creates a new instance of the .
+
+
+
+
+ Creates a new instance of the .
+
+ The offset of the undefined instruction.
+
+
+
+ Creates a new instance of the .
+
+ The error message
+
+
+
+ Creates a new instance of the .
+
+ The error message
+ The inner cause of the exception.
+
+
+
+
+
+
+ Gets the offset of the undefined instruction that was attempted to be executed.
+
+
+
+
+ Provides members describing all possible states a virtual machine can be in.
+
+
+
+
+ Indicates the virtual machine is idle and is not executing any instructions.
+
+
+
+
+ Indicates the virtual machine is running.
+
+
+
+
+ A simple data structure to manipulate individual bits
+
+
+
+
+ Creates a new with the given
+
+ The value to initialize the with
+
+
+
+ Gets the bit at the
+
+ The index to get the bit at
+
+
+
+ Performs a bitwise NOT operation on
+
+
+
+
+ Performs a bitwise AND operation between two 's
+
+ The right side of the expression
+
+
+
+ Performs a bitwise OR operation between two 's
+
+ The right side of the expression
+
+
+
+ Performs a bitwise XOR operation between two 's
+
+ The right side of the expression
+
+
+
+ Compares two 's
+
+
+ This overload exists to avoid a nasty boxing allocation
+
+ The to compare to
+ Whether the two 's are equal
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a base for all virtualized concrete values.
+
+
+
+
+ Gets a value indicating whether the object is passed on by value or by reference.
+
+
+
+
+ Determines whether the value is null or consists of only zeroes.
+
+
+
+
+ Determines whether the value is not null or contains at least a single one in its bit string.
+
+
+
+
+ Determines whether the value contains a positive value.
+
+
+
+
+ Determines whether the value contains a negative value.
+
+
+
+
+ Provides memory read/write operations on a concrete value.
+
+
+
+
+ Reads raw contents of the memory block.
+
+ The offset to start reading.
+ The memory buffer to copy data to.
+
+ This method has undefined behaviour if the memory contains unknown bits.
+
+
+
+
+ Reads raw contents of the memory block.
+
+ The offset to start reading.
+ The memory buffer to copy data to.
+ The buffer to copy the known bitmask to.
+
+
+
+ Writes raw data to the memory block as fully known bytes.
+
+ The offset to start writing.
+ The data to write.
+
+
+
+ Writes raw data to the memory block.
+
+ The offset to start writing.
+ The data to write.
+
+ The bitmask indicating the bits that are known within the data referenced by .
+
+
+
+
+ Reads a single 8 bit integer at the provided offset.
+
+ The offset to start reading.
+ The read integer.
+
+ Occurs when the offset does not fall within the memory range.
+
+
+
+
+ Reads a single 16 bit integer at the provided offset.
+
+ The offset to start reading.
+ The read integer.
+
+ Occurs when the offset does not fall within the memory range.
+
+
+
+
+ Reads a single 32 bit integer at the provided offset.
+
+ The offset to start reading.
+ The read integer.
+
+ Occurs when the offset does not fall within the memory range.
+
+
+
+
+ Reads a single 64 bit integer at the provided offset.
+
+ The offset to start reading.
+ The read integer.
+
+ Occurs when the offset does not fall within the memory range.
+
+
+
+
+ Reads a single 32 bit floating point number at the provided offset.
+
+ The offset to start reading.
+ The read number.
+
+ Occurs when the offset does not fall within the memory range.
+
+
+
+
+ Reads a single 64 bit floating point number at the provided offset.
+
+ The offset to start reading.
+ The read number.
+
+ Occurs when the offset does not fall within the memory range.
+
+
+
+
+ Writes a single 8 bit integer at the provided offset.
+
+ The offset to start writing at.
+ The value to write.
+
+ Occurs when the offset does not fall within the memory range.
+
+
+
+
+ Writes a single 16 bit integer at the provided offset.
+
+ The offset to start writing at.
+ The value to write.
+
+ Occurs when the offset does not fall within the memory range.
+
+
+
+
+ Writes a single 32 bit integer at the provided offset.
+
+ The offset to start writing at.
+ The value to write.
+
+ Occurs when the offset does not fall within the memory range.
+
+
+
+
+ Writes a single 64 bit integer at the provided offset.
+
+ The offset to start writing at.
+ The value to write.
+
+ Occurs when the offset does not fall within the memory range.
+
+
+
+
+ Writes a single 32 bit floating point number at the provided offset.
+
+ The offset to start writing at.
+ The value to write.
+
+ Occurs when the offset does not fall within the memory range.
+
+
+
+
+ Writes a single 64 bit floating point number at the provided offset.
+
+ The offset to start writing at.
+ The value to write.
+
+ Occurs when the offset does not fall within the memory range.
+
+
+
+
+ Provides extension methods for the interface.
+
+
+
+
+ Creates a new pointer to the memory.
+
+ The memory to reference.
+ Indicates whether the pointer is 32 or 64 bits wide.
+ The constructed pointer.
+
+
+
+ Creates a new pointer to an offset within the memory.
+
+ The memory to reference.
+ The offset within the memory.
+ Indicates whether the pointer is 32 or 64 bits wide.
+ The constructed pointer.
+
+
+
+ Represents a fixed-size collection of values that is passed on by reference.
+
+
+
+
+ Creates a new empty array.
+
+
+
+
+ Creates a new array filled with copies of the provided default value.
+
+ The length of the array.
+ The value to fill in the array with.
+
+
+
+ Wraps a collection of elements into an array value.
+
+
+
+
+ Gets the length of the array.
+
+
+
+
+ Gets or sets the value of an element at the provided index.
+
+ The index of the element.
+ Occurs when the set value is null.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Returns an enumerator that enumerates through all elements in the array.
+
+ The enumerator.
+
+
+
+ Provides an implementation for an enumerator of the class.
+
+
+
+
+ Creates a new instance of the structure.
+
+ The array to enumerate.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a pointer value.
+
+
+
+
+ Gets a value indicating whether the pointer is 32 bit or 64 bit wide.
+
+
+
+
+ Represents a simple reference to an object.
+
+
+
+
+ Creates a new null object reference value.
+
+ Indicates whether the reference to the object is 32 or 64 bits wide.
+ The null reference.
+
+
+
+ Creates a new fully known reference to an object.
+
+ The referenced object.
+ Indicates the pointer to the referenced object is 32 or 64 bits wide.
+
+
+
+ Creates a new reference to an object.
+
+ The referenced object.
+ Indicates the referenced object is known.
+ Indicates the pointer to the referenced object is 32 or 64 bits wide.
+
+
+
+ Gets the value of the object that is referenced.
+
+
+
+
+ Gets a value indicating whether the reference to the object is 32 or 64 bits wide.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Determines whether the object reference is equal to the provided object.
+
+ The other object.
+ true if the object are equal, false if not, and
+ null if the conclusion of the comparison is not certain.
+
+
+
+ Determines whether the current object reference is considered greater than the provided object reference.
+
+ The other object reference.
+ true if the current value is greater than the provided value, false otherwise.
+
+ This method is only really reliable when one of the values is the null value.
+
+
+
+
+ Determines whether the current object reference is considered less than the provided object reference.
+
+ The other object reference.
+ true if the current value is less than the provided value, false otherwise.
+
+ This method is only really reliable when one of the values is the null value.
+
+
+
+
+ Determines whether the provided object references are considered equal.
+
+ The other object reference.
+ true if the object references are equal, false otherwise.
+
+ This method verifies whether the actual contents of this object reference is equal to other.
+ This includes the case where both values are unknown, it returns true.
+ This method should not be used within an emulation context to test whether two virtual object references
+ are equal during the execution of a virtual machine.
+
+
+
+
+
+
+
+
+
+
+ Represents a pointer that is relative to a base pointer.
+
+
+
+
+ Creates a new null or unknown pointer value.
+
+ Indicates whether the pointer is known.
+ Indicates the pointer is 32 or 64 bits wide.
+
+
+
+ Creates a new known relative pointer value.
+
+ The base memory pointer.
+ Indicates the pointer is 32 or 64 bits wide.
+
+
+
+ Creates a new known relative pointer value.
+
+ The base memory pointer.
+ The offset relative to the base po[inter.
+ Indicates the pointer is 32 or 64 bits wide.
+
+
+
+ Gets the base memory pointer.
+
+
+
+
+ Gets or sets the current offset relative to the base pointer.
+
+
+
+
+ Gets a value indicating whether the pointer is 32 bit or 64 bit wide.
+
+
+
+
+
+
+
+
+ This property represents the size of the pointer, and not the size of the memory chunk that is referenced.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Moves the relative pointer a certain amount of bytes up in the address space.
+
+ The number of bytes to move up.
+
+
+
+ Moves the relative pointer a certain amount of bytes down in the address space.
+
+ The number of bytes to move down.
+
+
+
+
+
+
+ Represents the fully unknown value.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a fully known concrete 32 bit floating point numerical value.
+
+
+
+
+ Wraps a 32 bit floating point number into an instance of .
+
+ The 32 bit floating point number to wrap.
+ The concrete 32 bit floating point numerical value.
+
+
+
+ Creates a new fully known concrete 32 bit floating point numerical value.
+
+ The raw 32 bit value.
+
+
+
+ Gets or sets the raw floating point value.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a fully known concrete 64 bit floating point numerical value.
+
+
+
+
+ Wraps a 64 bit floating point number into an instance of .
+
+ The 64 bit floating point number to wrap.
+ The concrete 64 bit floating point numerical value.
+
+
+
+ Creates a new fully known concrete 64 bit floating point numerical value.
+
+ The raw 64 bit value.
+
+
+
+ Gets or sets the raw floating point value.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a (partially) known concrete 16 bit integral value.
+
+
+
+
+ Wraps an unsigned 16 bit integer into a fully concrete and known instance of .
+
+ The 16 bit integer to wrap.
+ The concrete 16 bit integer.
+
+
+
+ Wraps a signed 16 bit integer into a fully concrete and known instance of .
+
+ The 16 bit integer to wrap.
+ The concrete 16 bit integer.
+
+
+
+ Parses a (partially) known bit string into an 16 bit integer.
+
+ The bit string to parse.
+ The 16 bit integer.
+
+
+
+ Represents the bitmask that is used for a fully known concrete 16 bit integral value.
+
+
+
+
+ Creates a new, fully known concrete 16 bit integral value.
+
+ The raw 16 bit value.
+
+
+
+ Creates a new, fully known concrete 16 bit integral value.
+
+ The raw 16 bit value.
+
+
+
+ Creates a new, partially known concrete 16 bit integral value.
+
+ The raw 16 bit value.
+ The bit mask indicating the bits that are known.
+
+
+
+ Creates a new, partially known concrete 16 bit integral value.
+
+ The raw 16 bit value.
+ The bit mask indicating the bits that are known.
+
+
+
+ Parses a (partially) known bit string into an 16 bit integer.
+
+ The bit string to parse.
+
+
+
+
+
+
+
+
+
+
+
+
+ Gets the signed representation of this 16 bit value.
+
+
+
+
+ Gets the unsigned representation of this 16 bit value.
+
+
+
+
+ Gets a value indicating which bits in the integer are known.
+ If bit at location i equals 1, bit i in and is known,
+ and unknown otherwise.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a (partially) known concrete 32 bit integral value.
+
+
+
+
+ Wraps an unsigned 32 bit integer into a fully concrete and known instance of .
+
+ The 32 bit integer to wrap.
+ The concrete 32 bit integer.
+
+
+
+ Wraps a signed 32 bit integer into a fully concrete and known instance of .
+
+ The 32 bit integer to wrap.
+ The concrete 32 bit integer.
+
+
+
+ Parses a (partially) known bit string into an 32 bit integer.
+
+ The bit string to parse.
+ The 32 bit integer.
+
+
+
+ Represents the bitmask that is used for a fully known concrete 32 bit integral value.
+
+
+
+
+ Creates a new, fully known concrete 32 bit integral value.
+
+ The raw 32 bit value.
+
+
+
+ Creates a new, fully known concrete 32 bit integral value.
+
+ The raw 32 bit value.
+
+
+
+ Creates a new, partially known concrete 32 bit integral value.
+
+ The raw 32 bit value.
+ The bit mask indicating the bits that are known.
+
+
+
+ Creates a new, partially known concrete 32 bit integral value.
+
+ The raw 32 bit value.
+ The bit mask indicating the bits that are known.
+
+
+
+ Parses a (partially) known bit string into an 32 bit integer.
+
+ The bit string to parse.
+
+
+
+
+
+
+
+
+
+
+
+
+ Gets the signed representation of this 32 bit value.
+
+
+
+
+ Gets the unsigned representation of this 32 bit value.
+
+
+
+
+ Gets a value indicating which bits in the integer are known.
+ If bit at location i equals 1, bit i in and is known,
+ and unknown otherwise.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a (partially) known concrete 64 bit integral value.
+
+
+
+
+ Wraps an unsigned 64 bit integer into a fully concrete and known instance of .
+
+ The 64 bit integer to wrap.
+ The concrete 64 bit integer.
+
+
+
+ Wraps a signed 64 bit integer into a fully concrete and known instance of .
+
+ The 64 bit integer to wrap.
+ The concrete 64 bit integer.
+
+
+
+ Parses a (partially) known bit string into an 64 bit integer.
+
+ The bit string to parse.
+ The 64 bit integer.
+
+
+
+ Represents the bitmask that is used for a fully known concrete 64 bit integral value.
+
+
+
+
+ Creates a new, fully known concrete 64 bit integral value.
+
+ The raw 64 bit value.
+
+
+
+ Creates a new, fully known concrete 64 bit integral value.
+
+ The raw 64 bit value.
+
+
+
+ Creates a new, partially known concrete 64 bit integral value.
+
+ The raw 64 bit value.
+ The bit mask indicating the bits that are known.
+
+
+
+ Creates a new, partially known concrete 64 bit integral value.
+
+ The raw 64 bit value.
+ The bit mask indicating the bits that are known.
+
+
+
+ Parses a (partially) known bit string into an 64 bit integer.
+
+ The bit string to parse.
+
+
+
+
+
+
+
+
+
+
+
+
+ Gets the signed representation of this 64 bit value.
+
+
+
+
+ Gets the unsigned representation of this 64 bit value.
+
+
+
+
+ Gets a value indicating which bits in the integer are known.
+ If bit at location i equals 1, bit i in and is known,
+ and unknown otherwise.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a (partially) known concrete 8 bit integral value.
+
+
+
+
+ Wraps an unsigned 8 bit integer into a fully concrete and known instance of .
+
+ The 8 bit integer to wrap.
+ The concrete 8 bit integer.
+
+
+
+ Wraps a signed 8 bit integer into a fully concrete and known instance of .
+
+ The 8 bit integer to wrap.
+ The concrete 8 bit integer.
+
+
+
+ Parses a (partially) known bit string into an 8 bit integer.
+
+ The bit string to parse.
+ The 8 bit integer.
+
+
+
+ Represents the bitmask that is used for a fully known concrete 8 bit integral value.
+
+
+
+
+ Creates a new, fully known concrete 8 bit integral value.
+
+ The raw 8 bit value.
+
+
+
+ Creates a new, fully known concrete 8 bit integral value.
+
+ The raw 8 bit value.
+
+
+
+ Creates a new, partially known concrete 8 bit integral value.
+
+ The raw 8 bit value.
+ The bit mask indicating the bits that are known.
+
+
+
+ Creates a new, partially known concrete 8 bit integral value.
+
+ The raw 8 bit value.
+ The bit mask indicating the bits that are known.
+
+
+
+ Parses a (partially) known bit string into an 8 bit integer.
+
+ The bit string to parse.
+
+
+
+
+
+
+
+
+
+
+
+
+ Gets the signed representation of this 8 bit value.
+
+
+
+
+ Gets the unsigned representation of this 8 bit value.
+
+
+
+
+ Gets a value indicating which bits in the integer are known.
+ If bit at location i equals 1, bit i in and is known,
+ and unknown otherwise.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a (partially) known fixed size integer value.
+
+
+
+
+ Creates a new zero integer.
+
+ The number of bytes to use for encoding this integer.
+
+
+
+ Creates a fully known new integer from a bit array.
+
+ The raw bits of the integer.
+
+
+
+ Creates a partially known new integer from a bit array and a known bit mask.
+
+ The raw bits of the integer.
+ The known bit mask.
+
+
+
+ Parses a (partially) known bit string into an integer.
+
+ The bit string to parse.
+
+
+
+ Returns the rented array to
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a primitive integral value that might contain unknown bits.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Gets the most significant bit of the integer value.
+
+
+
+
+
+ Reads a single bit value at the provided index.
+
+ The index of the bit to read.
+ The read bit, or null if the bit value is unknown.
+ Occurs when an invalid index was provided.
+
+
+
+ Writes a single bit value at the provided index.
+
+ The index of the bit to write.
+ The new value of the bit to write. null indicates an unknown bit value.
+ Occurs when an invalid index was provided.
+
+
+
+
+
+
+
+
+
+
+
+
+ Parses a (partially) known bit string and sets the contents of integer to the parsed result.
+
+ The bit string to parse.
+
+
+
+
+
+
+
+
+
+
+ Performs a bitwise not operation on the (partially) known integer value.
+
+
+
+
+ Performs a bitwise and operation with another (partially) known integer value.
+
+
+
+
+ Performs a bitwise inclusive or operation with another (partially) known integer value.
+
+
+
+
+ Performs a bitwise exclusive or operation with another (partially) known integer value.
+
+
+
+
+ Performs a bitwise shift to the left on this (partially) known integer.
+
+ The number of bits to shift.
+
+
+
+ Performs a bitwise shift to the right on this (partially) known integer.
+
+ The number of bits to shift.
+ Indicates whether the sign bit should be extended or should always be filled
+ in with zeroes.
+
+
+
+ Adds a second (partially) known integer to the current integer.
+
+ The integer to add.
+ Occurs when the sizes of the integers do not match.
+
+
+
+ Transforms the (partially) known integer into its twos complement.
+
+
+
+
+ Subtracts a second (partially) known integer from the current integer.
+
+ The integer to subtract.
+ Occurs when the sizes of the integers do not match.
+
+
+
+ Multiplies the current integer with a second (partially) known integer.
+
+ The integer to multiply with.
+ Occurs when the sizes of the integers do not match.
+
+
+
+ Divides the current integer with a second (partially) known integer.
+
+ The integer to divide with
+ Occurs when the sizes of the integers do not match or there is dividing by zero.
+
+
+
+ Divides the current integer with a second (partially) known integer and returns remainder of division.
+
+ The integer to divide with
+ Occurs when the sizes of the integers do not match or there is dividing by zero.
+
+
+
+ Determines whether the integer is equal to the provided integer.
+
+ The other integer.
+ true if the integers are equal, false if not, and
+ null if the conclusion of the comparison is not certain.
+
+
+
+ Determines whether the integer is greater than the provided integer.
+
+ The other integer.
+ Indicates the integers should be interpreted as signed or unsigned integers.
+ true if the current integer is greater than the provided integer, false if not, and
+ null if the conclusion of the comparison is not certain.
+
+
+
+ Determines whether the integer is less than the provided integer.
+
+ The other integer.
+ Indicates the integers should be interpreted as signed or unsigned integers.
+ true if the current integer is less than the provided integer, false if not, and
+ null if the conclusion of the comparison is not certain.
+
+
+
+ Extends the integer value to a bigger bit length.
+
+ The new bit length to extend the integer to.
+ Indicates whether the sign bit should be extended.
+
+ The extended integer. If the provided size is either 8, 16, 32 or 64, this method will return an integer
+ using the specialized , ,
+ or types.
+
+
+ Occurs when the new bit length is shorter than the current bit length.
+
+
+
+
+ Truncates the integer value to a smaller bit length.
+
+ The new bit length to truncate the integer to.
+
+ The truncated integer. If the provided size is either 8, 16, 32 or 64, this method will return an integer
+ using the specialized , ,
+ or types.
+
+
+ Occurs when the new bit length is larger than the current bit length.
+
+
+
+
+ Marks all bits in the integer value as unknown.
+
+
+
+
+
+
+
+
+
+
+ Represents an object that is passed on by-value.
+
+
+
+
+ Gets the raw bits of the primitive value.
+
+ The buffer to write the raw bits to.
+
+ The bits returned by this method assume the value is known entirely. Any bit that is marked unknown will be
+ set to 0.
+
+
+
+
+ Gets the bit mask indicating the bits that are known.
+
+ The buffer to write the raw mask to.
+
+ If bit at location i equals 1, bit i is known, and unknown otherwise.
+
+
+
+
+ Replaces the raw contents of the integer with the provided bits and known mask.
+
+ The new bit values.
+ The new bit mask indicating the known bits.
+
+
+
+ Represents a chunk of memory.
+
+
+
+
+ Creates a new uninitialized block of memory.
+
+ The size of the memory.
+
+
+
+ Creates a new block of memory.
+
+ The size of the memory.
+ Determines whether the block should be initialized with zeroes or not.
+
+
+
+ Creates a new fully known memory block.
+
+ The referenced memory.
+
+
+
+ Creates a new memory block.
+
+ The referenced memory.
+ The bit mask indicating the known and unknown bits.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Echo/Echo.ControlFlow.dll b/Echo/Echo.ControlFlow.dll
new file mode 100644
index 0000000..7958548
Binary files /dev/null and b/Echo/Echo.ControlFlow.dll differ
diff --git a/Echo/Echo.ControlFlow.xml b/Echo/Echo.ControlFlow.xml
new file mode 100644
index 0000000..345686c
--- /dev/null
+++ b/Echo/Echo.ControlFlow.xml
@@ -0,0 +1,2843 @@
+
+
+
+ Echo.ControlFlow
+
+
+
+
+ Represents a dominator tree, where each tree node corresponds to one node in a graph, and each
+ is immediately dominated by its parent.
+
+
+
+
+ Constructs a dominator tree from a control flow graph.
+
+ The control flow graph to turn into a dominator tree.
+ The constructed dominator tree.
+
+
+
+ Computes the dominator tree of a control flow graph, defined by its entrypoint.
+
+ The entrypoint of the control flow graph.
+ A dictionary mapping all the nodes to their immediate dominator.
+
+ The algorithm used is based on the one engineered by Lengauer and Tarjan.
+ https://www.cs.princeton.edu/courses/archive/fall03/cs528/handouts/a%20fast%20algorithm%20for%20finding.pdf
+ https://www.cl.cam.ac.uk/~mr10/lengtarj.pdf
+
+
+
+
+ Constructs a dominator tree from the control flow graph.
+
+ The constructed tree. Each node added to the tree is linked to a node in the original graph by
+ its name.
+
+
+
+ Gets the root of the dominator tree. That is, the tree node that corresponds to the entrypoint of the
+ control flow graph.
+
+
+
+
+ Gets the dominator tree node associated to the given control flow graph node.
+
+ The control flow graph node to get the tree node from.
+
+
+
+ Determines whether one control flow graph node dominates another node. That is, whether execution of the
+ dominated node means the dominator node has to be executed.
+
+ The node that dominates.
+ The node that is potentially dominated.
+
+ True if the node in indeed dominates the provided control flow
+ node in , false otherwise.
+
+
+
+
+ Determines the dominance frontier of a specific node. That is, the set of all nodes where the dominance of
+ the specified node stops.
+
+ The node to obtain the dominance frontier from.
+ A collection of nodes representing the dominance frontier.
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a single node in a dominator tree of a graph.
+
+
+ It stores the original control flow graph node from which this tree node was inferred, as well a reference to its
+ immediate dominator, and the node it immediate dominates.
+
+
+
+
+
+
+
+ Gets the node that this tree node was derived from.
+
+
+
+
+ Gets the children of the current node.
+
+
+
+
+
+
+
+ Gets a collection of children representing all nodes that were dominated by the original node, as well as an
+ immediate successor of the original node.
+
+ The children, represented by the dominator tree nodes.
+
+
+
+ Gets a collection of children representing all nodes that were dominated by the original node, but were not
+ an immediate successor of the original node.
+
+ The children, represented by the dominator tree nodes.
+
+
+
+ Gets all the nodes that are dominated by this control flow graph node.
+
+ The nodes that are dominated by this node.
+
+ Because of the nature of dominator analysis, this also includes the current node.
+
+
+
+
+ Represents one basic block in a control flow graph, consisting of a list of instructions (or statements).
+
+ The type of instructions that the basic block contains.
+
+
+
+ Creates a new, empty basic block.
+
+
+
+
+ Creates a new, empty basic block, with the provided offset.
+
+ The offset to assign to the basic block.
+
+
+
+ Creates a new basic block with the provided instructions.
+
+ The instructions to add to the basic block.
+ Occurs when is null.
+
+
+
+ Creates a new basic block with the provided offset and list of instructions.
+
+ The offset to assign to the basic block.
+ The instructions to add to the basic block.
+ Occurs when is null.
+
+
+
+ Gets or sets the offset (or identifier) of this basic block.
+
+
+
+
+ Gets a collection of isntructions that are executed in sequence when this basic block is executed.
+
+
+
+
+ Gets a value indicating whether the basic block contains any instruction.
+
+
+
+
+ Gets the first instruction that is evaluated when this basic block is executed.
+
+
+
+
+ Gets the last instruction that is evaluated when this basic block is executed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a mechanism for formatting a tree of blocks into an indented string representation.
+
+ The type of instructions stored in the block.
+
+
+
+ Formats a block into an indented string representation.
+
+ The block to format.
+ The indented string.
+
+
+
+ Creates a new block formatter.
+
+ The string to use when indenting a block.
+
+
+
+ Obtains the raw string output.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides an empty base implementation for a block listener.
+
+ The type of instructions in the blocks.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a mechanism for traversing a scoped block tree in order.
+
+
+
+
+
+ Creates a new block walker.
+
+ The object that responds to traversal events.
+
+
+
+ Traverses a block tree and notifies the listener with traversal events.
+
+ The root of the block tree to traverse.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a block of region that is protected by a set of exception handler blocks.
+
+ The type of instructions stored in the blocks.
+
+
+
+ Gets the protected block.
+
+
+
+
+ Gets a collection of handler blocks.
+
+
+
+
+ Gets or sets a user-defined tag that is assigned to this block.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a single handler block in an .
+
+ The type of instructions that this block contains.
+
+
+
+ Gets or sets the prologue block that gets executed before the main handler block (if available).
+
+
+
+
+ Gets the main scope block that forms the code for the handler block.
+
+
+
+
+ Gets or sets the epilogue block that gets executed after the main handler block (if available).
+
+
+
+
+ Gets or sets a user-defined tag that is assigned to this block.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a single block in structured program code.
+
+ The type of instructions that this block contains.
+
+
+
+ Gets an ordered collection of all basic blocks that can be found in this block.
+
+ The ordered basic blocks.
+
+
+
+ Gets the first basic block that appears in the ordered list of blocks.
+
+ The first basic block, or null if the block contains no basic blocks..
+
+
+
+ Gets the last basic block that appears in the ordered list of blocks.
+
+ The last basic block, or null if the block contains no basic blocks..
+
+
+
+ Visit the current block using the provided visitor.
+
+ The visitor to accept.
+
+
+
+ Provides members for listening to events raised by the class.
+
+ The type of instructions in the blocks.
+
+
+
+ Visits a basic block.
+
+ The block.
+
+
+
+ Enters a scope block.
+
+ The block.
+
+
+
+ Exits a scope block.
+
+ The block.
+
+
+
+ Enters an exception handler block.
+
+ The block.
+
+
+
+ Exits an exception handler block.
+
+ The block.
+
+
+
+ Enters the protected region of an exception handler block.
+
+ The block.
+
+
+
+ Exits the protected region of an exception handler block.
+
+ The block.
+
+
+
+ Enters a handler region of an exception handler block.
+
+ The block.
+ The index of the handler that was entered.
+
+
+
+ Exits a handler region of an exception handler block.
+
+ The block.
+ The index of the handler that was exit.
+
+
+
+ Enters the prologue region of a handler block.
+
+ The parent handler block this prologue is added to.
+
+
+
+ Exits the prologue region of a handler block.
+
+ The parent handler block this prologue is added to.
+
+
+
+ Enters the epilogue region of a handler block.
+
+ The parent handler block this epilogue is added to.
+
+
+
+ Exits the epilogue region of a handler block.
+
+ The parent handler block this epilogue is added to.
+
+
+
+ Enters the main code of a handler block.
+
+ The parent handler block this scope is added to.
+
+
+
+ Exits the main code of a handler block.
+
+ The parent handler block this scope is added to.
+
+
+
+ Provides members for visiting blocks in a scoped block tree.
+
+ The type of instructions in the blocks.
+
+
+
+ Visits a basic block.
+
+ The block.
+
+
+
+ Visits a scope block.
+
+ The block.
+
+
+
+ Visits an exception handler block.
+
+ The block.
+
+
+
+ Visits a handler block inside an .
+
+ The block.
+
+
+
+ Represents a collection of blocks grouped together into one single block.
+
+ The type of instructions that this block contains.
+
+
+
+ Gets an ordered, mutable collection of blocks that are present in this scope.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a collection of edges originating from a single node.
+
+ The type of data that each node stores.
+
+
+
+
+
+
+
+
+
+ Gets the type of edges that are stored in this collection.
+
+
+
+
+ Gets the node that all edges are originating from.
+
+
+
+
+ Creates and adds a edge to the node with the provided address.
+
+ The address of the new neighbouring node.
+ The created edge.
+
+
+
+ Creates and adds a edge to the provided node.
+
+ The new neighbouring node.
+ The created edge.
+
+
+
+ Adds an edge to the adjacency collection.
+
+ The edge to add.
+ The edge that was added.
+
+ Occurs when the provided edge cannot be added to this collection because of an invalid source node or edge type.
+
+
+
+
+
+
+
+
+
+
+ Determines whether a node is a neighbour of the current node. That is, determines whether there exists
+ at least one edge between the current node and the provided node.
+
+ The node to check.
+ True if the provided node is a neighbour, false otherwise.
+
+
+
+
+
+
+
+
+
+ Removes all edges originating from the current node to the neighbour with the provided address.
+
+ The address of the neighbour to cut ties with.
+ True if at least one edge was removed, false otherwise.
+
+
+
+ Removes all edges originating from the current node to the provided neighbour.
+
+ The neighbour to cut ties with.
+ True if at least one edge was removed, false otherwise.
+
+
+
+
+
+
+ Obtains all edges to the provided neighbour, if any.
+
+ The neighbouring node.
+ The edges.
+
+
+
+ Obtains an enumerator that enumerates all nodes in the collection.
+
+
+
+
+
+ Represents an enumerator that enumerates all nodes in a control flow graph.
+
+
+
+
+ Creates a new instance of the structure.
+
+ The collection to enumerate.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a mutable collection of nodes present in a graph.
+
+ The type of data that is stored in each node.
+
+
+
+
+
+
+
+
+
+ Gets a node by its offset.
+
+ The node offset.
+
+
+
+
+
+
+ Adds a collection of nodes to the graph.
+
+ The nodes to add.
+
+ Occurs when at least one node in the provided collection is already added to another graph.
+
+
+
+
+
+
+
+ Determines whether a node with a specific offset was added to the collection.
+
+ The offset to the node.
+ true if there exists a node with the provided offset, false otherwise.
+
+
+
+
+
+
+
+
+
+ Removes a node by its offset.
+
+ The offset. of the node to remove.
+ true if the collection contained a node with the provided offset., and the node was removed
+ successfully, false otherwise.
+
+
+
+
+
+
+ Synchronizes all offsets of each node and basic blocks with the underlying instructions.
+
+ Occurs when one or more basic blocks referenced by the nodes
+ are in a state that new offsets cannot be determined. This includes empty basic blocks and duplicated header
+ offsets.
+
+
+ Because updating offsets is a relatively expensive task, calls to this method should be delayed as much as
+ possible.
+
+
+ This method will invalidate any enumerators that are enumerating this collection of nodes.
+
+
+
+
+
+ Obtains an enumerator that enumerates all nodes in the collection.
+
+
+
+
+
+ Represents an enumerator that enumerates all nodes in a control flow graph.
+
+
+
+
+ Creates a new instance of the structure.
+
+ The collection to enumerate.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a collection of regions found in a control flow graph.
+
+ The type of data that each node in the graph stores.
+ The type of the region to store.
+
+
+
+ Creates a new instance of the class.
+
+ The owner of the sub regions.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a collection of nodes that are put into a control flow region.
+
+ The type of data that each node in the graph stores.
+
+
+
+ Creates a new instance of the class.
+
+ The region owning the collection of nodes.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adds a collection of nodes to the node collection.
+
+ The nodes to add.
+
+
+
+ Provides a base for control flow graph builders that depend on a single traversal of the instructions.
+
+ The type of instructions to store in the control flow graph.
+
+
+
+
+
+
+
+
+
+ Traverses the instructions and records block headers and successor information about each traversed instruction.
+
+ The address of the first instruction to traverse.
+ A list of known block headers that should be included in the traversal.
+ An object containing the result of the traversal, including the block headers and successors of
+ each instruction.
+
+
+
+ Provides members for building a control flow graph, starting at a specific entrypoint address.
+
+ The type of instructions that the control flow graph will contain.
+
+
+
+ Gets the architecture of the instructions to graph.
+
+
+
+
+ Constructs a control flow graph, starting at the provided entrypoint address.
+
+ The address of the first instruction to traverse.
+ A list of known block headers that should be included in the traversal.
+
+ The constructed control flow graph, with the entrypoint set to the node containing the entrypoint address
+ provided in .
+
+
+
+
+ Provides extensions to control flow graph builder implementations.
+
+
+
+
+ Constructs a control flow graph, starting at the provided entrypoint address.
+
+ The control flow graph builder to use.
+ The address of the first instruction to traverse.
+
+ The constructed control flow graph, with the entrypoint set to the node containing the entrypoint address
+ provided in .
+
+
+
+
+ Constructs a control flow graph from a collection of instructions, starting at the provided entrypoint address.
+
+ The control flow graph builder to use.
+ The address of the first instruction to traverse.
+ The set of exception handler ranges.
+
+ The constructed control flow graph, with the entrypoint set to the node containing the entrypoint address
+ provided in .
+
+
+
+
+ Provides members for describing a traversal of a collection of instructions.
+
+ The type of instructions that were traversed.
+
+
+
+ Determines whether an offset was marked as a block header during the traversal.
+
+ The offset to check.
+ true if the offset was a block header, false otherwise.
+
+
+
+ Determines whether an offset was traversed and interpreted as an instruction.
+
+ The offset to check.
+ true if the offset was traversed, false otherwise.
+
+
+
+ Obtains all instruction records that were collected during the traversal.
+
+ The instructions and their metadata.
+
+
+
+ Obtains the number of successors of an instruction that were found during the traversal.
+
+ The offset of the instruction.
+ The number of successors.
+
+
+
+ Obtains the registered successors of an instruction.
+
+ The offset.
+ The buffer to write the successors into.
+ The number of successors.
+
+
+
+ Provides a default implementation of the interface,
+ using a dictionary and a set to store the instructions and block header offsets.
+
+ The type of instructions that were traversed.
+
+
+
+ Creates a new instance of the class.
+
+ The architecture.
+
+
+
+
+
+
+ Gets a collection of recorded block headers.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adds a single instruction to the traversal result.
+
+ The instruction to add.
+
+
+
+
+
+
+
+
+
+ Clears all registered successors for the provided instruction.
+
+ The instruction.
+
+
+
+ Registers a successor for the provided instruction.
+
+ The instruction.
+ The successor information.
+
+
+
+ Provides members for resolving the static successors of a single instruction. That is, resolve any successor
+ that is encoded within an instruction either explicitly or implicitly.
+
+ The type of instruction to resolve the successors from.
+
+
+ This interface is meant for components within the Echo project that require information about the successors
+ of an individual instruction. These are typically control flow graph builders, such as the
+ class.
+
+
+
+ Successors are either directly encoded within the instruction (e.g. as an operand),
+ or implied by the default flow control of the provided instruction:
+
+ -
+
+ For a typical instruction, the method simply returns a collection with only a reference to the
+ fall through instruction that appears right after it in the sequence.
+
+
+ -
+
+ For branching instructions, however, this method returns a collection of all branch targets,
+ as well as any potential fall through successors if the branching instruction is conditional.
+
+
+
+
+
+
+ This interface provides members for extracting these successors from the provided instruction.
+
+
+
+
+
+ Gets the number of successors of the provided instruction.
+
+ The instruction to resolve the successors from.
+ The number of successors.
+
+
+
+ Gets a collection of references that represent the successors of the provided instruction.
+
+ The instruction to resolve the successors from.
+ The buffer to write the successors into.
+ The extracted successor references.
+
+
+
+ Provides an implementation of a control flow graph builder that traverses the instructions in a recursive manner,
+ and determines for each instruction the successors by looking at the general flow control of each instruction.
+
+ The type of instructions to store in the control flow graph.
+
+ This flow graph builder does not do any emulation or data flow analysis. Therefore, this flow
+ graph builder can only be reliably used when the instructions to graph do not contain any indirect branching
+ instructions. For example, if we target x86, the instruction jmp 12345678h is possible to process using
+ this graph builder, but jmp eax is not.
+
+
+
+
+ Creates a new static graph builder using the provided instruction successor resolver.
+
+ The architecture of the instructions.
+ The instructions to traverse.
+ The object used to determine the successors of a single instruction.
+ Occurs when any of the arguments is null.
+
+
+
+ Creates a new static graph builder using the provided instruction successor resolver.
+
+ The instructions to traverse.
+ The object used to determine the successors of a single instruction.
+ Occurs when any of the arguments is null.
+
+
+
+ Gets the instructions to traverse.
+
+
+
+
+
+
+
+ Gets the object used to determine the successors of a single instruction.
+
+
+
+
+
+
+
+ Represents a reference to an instruction that is the successor of another instruction.
+
+
+
+
+ Creates a new successor reference.
+
+ The address of the successor instruction.
+ The type of control flow transfer that has to be made to go to this successor.
+
+
+
+ Gets the address of the successor instruction.
+
+
+
+
+ Gets the type of edge that would be introduced if this control flow transfer was included in a
+ control flow graph.
+
+
+
+
+ Gets whether the edge is a real edge (not ).
+
+
+
+
+
+
+
+ Provides members for resolving the next possible states of a program after the execution of an instruction.
+
+ The type of instruction that is being executed.
+
+
+ This interface is meant for components within the Echo project that require information about the transitions
+ that an individual instruction might apply to a given program state. These are typically control flow graph
+ builders, such as the class.
+
+
+
+
+
+ Gets the initial state of the program at a provided entry point address.
+
+ The entry point address.
+ The object representing the initial state of the program.
+
+
+
+ Gets the number of transitions the current program state might transition into.
+
+ The current state of the program.
+ The instruction to evaluate.
+ The number of transitions that the provided instruction might apply.
+
+
+
+ Resolves all possible program state transitions that the provided instruction can apply.
+
+ The current state of the program.
+ The instruction to evaluate.
+ The output buffer to write the transitions that the instruction might apply.
+ The number of transitions that were written into .
+
+
+
+ Provides members for obtaining instructions based on the current state of a program.
+
+ The type of instructions that this collection provides.
+
+
+
+ Gets the architecture describing the instructions exposed by this instruction provider.
+
+
+
+
+ Gets the current instruction to be evaluated; that is, the instruction at the current value
+ of the program counter stored in the provided program state.
+
+ The current state of the program.
+ The instruction.
+
+
+
+ Represents an object that encodes the transition from one program state to another after an instruction was executed.
+
+ The type of instruction that was executed.
+
+
+
+ Creates a new program state transition.
+
+ The new program state.
+ The type of edge that was taken.
+
+
+
+ Gets the new program state after the instruction was executed.
+
+
+
+
+ Gets the type of edge that was taken by the instruction.
+
+
+
+
+ Gets whether the edge is a real edge (not ).
+
+
+
+
+
+
+
+ Provides a base implementation for a state transition resolver, that maintains a data flow graph (DFG) for
+ resolving each program state transition an instruction might apply.
+
+ The type of instructions to evaluate.
+
+
+
+ Initializes the base implementation of the state state transition resolver.
+
+ The architecture that describes the instruction set.
+
+
+
+ Gets the architecture for which this transition resolver is built.
+
+
+
+
+ Gets the data flow graph that was constructed during the resolution of all transitions.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Applies the default fallthrough transition on a symbolic program state.
+
+ The current program state to be transitioned.
+ The instruction invoking the state transition.
+
+
+
+ Gets or adds a new a data flow graph node in the current data flow graph (DFG) that is linked to the
+ provided instruction.
+
+ The instruction.
+ The data flow graph
+
+
+
+ Provides an implementation of an adapter that maps a
+ to a , by using the program counter stored in the
+ program state as an offset to look up the current instruction.
+
+ The type of instructions that this collection provides.
+
+
+
+ Creates a new instance of the adapter.
+
+ The architecture of the instructions.
+ The instructions.
+
+
+
+ Creates a new instance of the adapter.
+
+ The instructions.
+
+
+
+ Gets the underlying static instructions provider.
+
+
+
+
+
+
+
+
+
+
+ Provides an implementation of a control flow graph builder that traverses the instructions in a recursive manner,
+ and maintains an symbolic program state to determine all possible branch targets of any indirect branching instruction.
+
+ The type of instructions to store in the control flow graph.
+
+
+
+ Creates a new symbolic control flow graph builder using the provided program state transition resolver.
+
+ The architecture of the instructions.
+ The instructions to traverse.
+ The transition resolver to use for inferring branch targets.
+
+
+
+ Creates a new symbolic control flow graph builder using the provided program state transition resolver.
+
+ The instructions to traverse.
+ The transition resolver to use for inferring branch targets.
+
+
+
+ Creates a new symbolic control flow graph builder using the provided program state transition resolver.
+
+ The instructions to traverse.
+ The transition resolver to use for inferring branch targets.
+
+
+
+ Gets the instructions to traverse.
+
+
+
+
+
+
+
+ Gets the object responsible for resolving every transition in the program state that an instruction might introduce.
+
+
+
+
+
+
+
+ Provides an implementation for a single edge in a control flow graph, including the source and target node,
+ and the type of edge.
+
+
+ If an edge is in between two nodes, it means that control might be transferred from the one node to the other
+ during the execution of the program that is encoded by the control flow graph.
+
+ The type of contents that the connected nodes store.
+
+
+
+ Creates a new fallthrough edge between two nodes.
+
+ The node to start the edge at.
+ The node to use as destination for the edge.
+
+
+
+ Creates a new edge between two nodes.
+
+ The node to start the edge at.
+ The node to use as destination for the edge.
+ The type of the edge to create.
+
+
+
+ Gets the graph that contains this edge.
+
+
+
+
+ Gets the node that this edge originates from.
+
+
+
+
+ Gets the node that this edge targets.
+
+
+
+
+ Gets the type of the edge.
+
+
+
+
+
+
+
+ Provides all possible edge types that are supported in a control flow graph.
+
+
+
+
+ Indicates the edge is not actually a real edge, but a new node was found at the target.
+
+
+
+
+ Indicates the edge is the default fallthrough edge of a node, and is traversed when no other edge is traversed.
+
+
+
+
+ Indicates the edge is traversed as a result from an unconditional jump instruction.
+
+
+
+
+ Indicates the edge is only traversed when a specific condition is met.
+
+
+
+
+ Indicates the edge is only traversed in abnormal circumstances, typically when an exception occurs.
+
+
+
+
+ Provides a generic base implementation of a control flow graph that contains for each node a user predefined
+ object in a type safe manner.
+
+ The type of data that each node in the graph stores.
+
+
+
+ Creates a new empty graph.
+
+ The architecture description of the instructions stored in the control flow graph.
+
+
+
+ Gets or sets the node that is executed first in the control flow graph.
+
+
+
+
+ Gets the architecture of the instructions that are stored in the control flow graph.
+
+
+
+
+ Gets a collection of all basic blocks present in the graph.
+
+
+
+
+ Gets a collection of top-level regions that this control flow graph defines.
+
+
+
+
+
+
+
+
+
+
+ Gets a collection of all edges that transfer control from one block to the other in the graph.
+
+ The edges.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Serializes the control flow graph to the provided output stream, in graphviz dot format.
+
+ The output stream.
+ To customize the layout of the final graph, use the class.
+
+
+
+ Represents a node in a control flow graph, containing a basic block of instructions that are to be executed
+ in a sequence.
+
+ The type of data to store in the node.
+
+
+
+ Creates a new control flow graph node with an empty basic block, to be added to the graph.
+
+ The offset of the node.
+
+
+
+ Creates a new control flow node containing the provided basic block of instructions, to be added to the graph.
+
+ The offset of the node.
+ The basic block to store in the node.
+
+
+
+ Creates a new control flow node containing the provided basic block of instructions, to be added to the graph.
+
+ The offset of the node.
+ The basic block to store in the node.
+
+
+
+ Creates a new control flow node containing the provided basic block of instructions, to be added to the graph.
+
+ The offset of the node.
+ The basic block to store in the node.
+
+
+
+ Gets the graph that contains this node, or null if the node is not added to any graph yet.
+
+
+
+
+ Gets the graph region that contains this node, or null if the node is not added to any graph yet.
+
+
+
+
+ Gets the offset of the node.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Gets the user-defined contents of this node.
+
+
+
+
+ Gets or sets the neighbour to which the control is transferred to after execution of this block and no
+ other condition is met.
+
+
+
+
+ Gets or sets the edge to the neighbour to which the control is transferred to after execution of this block
+ and no other condition is met.
+
+
+
+
+ Gets a collection of conditional edges that originate from this source.
+
+
+ These edges are typically present when a node is a basic block encoding the header of an if statement
+ or a loop.
+
+
+
+
+ Gets a collection of abnormal edges that originate from this source.
+
+
+ These edges are typically present when a node is part of a region of code protected by an exception handler.
+
+
+
+
+ Provides a record of all incoming edges.
+
+
+ This property is automatically updated by the adjacency lists and the fall through edge property associated
+ to all nodes that might connect themselves to the current node. Do not change it in this class.
+
+
+
+
+ Connects the node to the provided neighbour using a fallthrough edge.
+
+ The node to connect to.
+ The edge that was used to connect the two nodes together.
+ Occurs when is null.
+ Occurs when the node already contains a fallthrough edge to another node.
+
+
+
+ Connects the node to the provided neighbour.
+
+ The node to connect to.
+ The type of edge to use for connecting to the other node.
+ The edge that was used to connect the two nodes together.
+ Occurs when is null.
+
+ Occurs when equals , and the node
+ already contains a fallthrough edge to another node.
+
+ Occurs when an invalid edge type was provided.
+
+
+
+ Splits the node and its embedded basic block in two nodes at the provided index, and connects the two
+ resulting nodes with a fallthrough edge.
+
+ The index of the instruction
+ The two resulting nodes.
+ Occurs when the node cannot be split any further.
+
+ Occurs when the provided index falls outside the range of the instructions in the embedded basic block.
+
+
+
+
+ Merges the current node with its fallthrough predecessor, by combining the two basic blocks together,
+ connecting the predecessor with the successors of the current node. and finally removing the current node.
+
+
+ Occurs when the node could not be merged because it has no fallthrough predecessor, has multiple predecessors,
+ or the predecessor has multiple successors which prohibit merging.
+
+
+
+
+ Merges the current node with its fallthrough neighbour, by combining the two basic blocks together,
+ connecting the node with the successors of the neighbour. and finally removing the neighbour node.
+
+
+ Occurs when the node could not be merged because it has no fallthrough neighbour, or has multiple successors.
+
+
+
+
+ Gets a collection of all edges that target this node.
+
+ The incoming edges.
+
+
+
+ Gets a collection of all outgoing edges originating from this node.
+
+ The outgoing edges.
+
+
+
+ Gets a collection of nodes that precede this node. This includes any node that might transfer control to
+ node this node in the complete control flow graph, regardless of edge type.
+
+ The predecessor nodes.
+
+
+
+ Gets a collection of nodes that might be executed after this node. This includes any node that this node
+ might transfer control to, regardless of edge type.
+
+ The successor nodes.
+
+
+
+ Determines whether another node is a predecessor of this node.
+
+ The potential predecessor.
+ True if the provided node is a predecessor, false otherwise.
+ Occurs when the provided predecessor is null
+
+
+
+ Determines whether another node is a successor of this node.
+
+ The potential successor.
+ True if the provided node is a successor, false otherwise.
+ Occurs when the provided successor is null
+
+
+
+ Removes all incident edges (both incoming and outgoing edges) from the node, effectively isolating the node
+ in the graph.
+
+
+
+
+ Removes the node out of any sub region in the graph.
+
+
+
+
+ Moves the node from its current region (if any) into the provided sub region.
+
+ The region to move the node to.
+
+
+
+ Obtains the parent exception handler region that this node resides in (if any).
+
+
+ The parent exception handler region, or null if the node is not part of any exception handler.
+
+
+
+
+ Obtains the parent handler region that this node resides in (if any).
+
+
+ The parent handler region, or null if the node is not part of any handler.
+
+
+
+
+ Traverses the region tree upwards and collects all regions this node is situated in.
+
+ The regions this node is situated in, starting with the inner-most regions.
+
+
+
+ Gets a value indicating whether the node is in the provided region.
+
+ The region.
+ true if the node is within the region, false otherwise.
+
+
+
+
+
+
+ Represents an action that edits a control flow graph by adding an edge from one node to another.
+
+ The type of instructions stored in the control flow graph.
+
+
+
+ Creates a new instance of the class.
+
+ The offset to the branching instruction that is the origin of the edge.
+ The offset to the neighbour that the new edge targets.
+ The type of edge.
+
+ Occurs when equals
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a workspace for editing a control flow graph.
+
+ The type of instructions stored in the control flow graph.
+
+
+
+ Creates a new instance of the class.
+
+ The graph to edit.
+
+
+
+ Gets the graph to be edited.
+
+
+
+
+ Rebuilds the index of nodes and their offsets.
+
+
+ This method is supposed to be called every time a node is manually added or removed from the
+ control flow graph.
+
+
+
+
+ Removes a node from the index.
+
+ The node offset.
+
+ Occurs when the provided offset does not exist in the current node index.
+
+
+
+
+ Finds the node that contains the provided instruction offset.
+
+ The offset of the instruction.
+ The node.
+
+ Occurs when there is no node in the graph containing an instruction with the provided offset.
+
+
+
+ This method can only work properly if the node index is up-to-date. Consider calling
+ before using this method.
+
+
+
+
+
+ Finds the node that contains the provided instruction offset, and splits the node into two halves if the
+ instruction is not a header of the found node.
+
+ The offset of the instruction.
+ Indicates whether the node was split up or not.
+ The node.
+
+ Occurs when there is no node in the graph containing an instruction with the provided offset.
+
+
+
+ This method can only work properly if the node index is up-to-date. Make sure that
+ was called before using this method.
+
+
+ When this method splits a node, the node index is updated automatically, and it is not needed to call
+ again.
+
+
+
+
+
+ Represents a sequence of edits to be applied to a control flow graph.
+
+ The type of instructions stored in the control flow graph.
+
+
+
+ Gets the number of actions that will be performed.
+
+
+
+
+ Gets a value indicating whether all the edits were applied successfully.
+
+
+
+
+ Adds an edit action to the end of the sequence.
+
+ The action to add.
+
+
+
+ Applies all edits to the control flow graph.
+
+ The graph to apply the transaction on.
+ Occurs when the transaction was already applied.
+
+ When an exception occurs within one of the edits, all edits previously applied will be reverted.
+
+
+
+
+
+
+
+ Represents a reversible action that modifies a control flow graph.
+
+ The type of instructions stored in the control flow graph.
+
+
+
+ Applies the edit.
+
+ The workspace, including the graph to edit, to use.
+
+ Occurs when the edit was already applied.
+
+
+ This method should only be called once. Calling this method a second time should happen after a call to
+ was made.
+
+
+
+
+ Reverts the edit.
+
+ The workspace, including the graph to edit, to use.
+
+ Occurs when the edit was not applied yet.
+
+
+ This method should only be called after the method was called.
+
+
+
+
+ Represents an action that edits a control flow graph by removing an edge from one node to another.
+
+ The type of instructions stored in the control flow graph.
+
+
+
+ Creates a new instance of the class.
+
+ The offset to the branching instruction that is the origin of the edge to remove.
+ The offset to the neighbour that the edge to remove targets.
+ The type of edge.
+
+ Occurs when equals
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents an action that edits a control flow graph by splitting a node into two halves.
+
+ The type of instructions stored in the control flow graph.
+
+
+
+ Creates a new instance of the class.
+
+ The offset to split at.
+
+
+
+ Gets the offset to split the node at.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides extensions for pulling updates from basic blocks into a control flow graph. This includes splitting
+ and merging nodes where necessary, as well as adding or removing any edges.
+
+
+
+
+ Pulls any updates from the basic block embedded in the node, and updates the parent control flow graph
+ accordingly.
+
+ The node to pull updates from.
+ The object to use for resolving successors of a single instruction.
+ The type of instructions stored in the control flow graph.
+ true if any changes were made, false otherwise.
+
+
+
+ Pulls any updates from the basic block embedded in the node, and updates the parent control flow graph
+ accordingly.
+
+ The node to pull updates from.
+ The object to use for resolving successors of a single instruction.
+ Flags indicating several options for updating the control flow graph.
+ The type of instructions stored in the control flow graph.
+ true if any changes were made, false otherwise.
+
+
+
+ Traverses all nodes in the control flow graph, and synchronizes the structure of the graph with the contents
+ of each basic block within the traversed nodes.
+
+ The graph to synchronize.
+ The object to use for resolving successors of a single instruction.
+ The type of instructions stored in the control flow graph.
+ true if any changes were made, false otherwise.
+
+
+
+ Traverses all nodes in the control flow graph, and synchronizes the structure of the graph with the contents
+ of each basic block within the traversed nodes.
+
+ The graph to synchronize.
+ The object to use for resolving successors of a single instruction.
+ Flags indicating several options for updating the control flow graph.
+ The type of instructions stored in the control flow graph.
+ true if any changes were made, false otherwise.
+
+
+
+ Provides flags that dictate the strategy used for pulling updates of a basic block into a control flow graph.
+
+
+
+
+ Indicates the synchronizer should only look at changes in the footer of a node in a control flow graph.
+
+
+
+
+ Indicates the synchronizer should traverse the entire basic block of a node in a control flow graph.
+
+
+
+
+ Provides a mechanism for pulling updates from basic blocks into a control flow graph. This includes splitting
+ and merging nodes where necessary, as well as adding or removing any edges.
+
+ The type of instructions the graph contains.
+
+
+
+ Creates a new instance of the class.
+
+ The control flow graph to update.
+ The object responsible for resolving successors of a single instruction.
+ The flags that dictate the strategy used for pulling basic block updates into a control flow graph.
+
+
+
+ Gets the control flow graph that needs to be updated.
+
+
+
+
+ Gets the object responsible for resolving successors of a single instruction.
+
+
+
+
+ Gets the flags that dictate the strategy used for pulling basic block updates into a control flow graph.
+
+
+
+
+ Traverses all nodes in the control flow graph, and synchronizes the structure of the graph with the contents
+ of each basic block within the traversed nodes.
+
+
+
+
+ Pulls any updates from the provided node into the structure of the control flow graph.
+
+ The node.
+
+
+
+ Represents an action that edits a control flow graph by updating one of the adjacency collections of a single
+ node.
+
+ The type of instructions stored in the control flow graph.
+
+
+
+ Initializes the base class.
+
+ The offset of the branch instruction representing the origin of the edge.
+ The offset of the neighbour that the edge targets.
+ The type of edge.
+
+
+
+ Gets the offset of the branching instruction representing the origin of the edge.
+
+
+
+
+ Gets the offset of the neighbour that the edge targets.
+
+
+
+
+ Gets the type of edge.
+
+
+
+
+
+
+
+ Applies the update to the adjacency list of the node.
+
+ The editing context.
+
+ This method is guaranteed to be called before .
+
+
+
+
+
+
+
+ Reverts the update to the adjacency list of the node.
+
+ The editing context.
+
+ This method is guaranteed to be called after .
+
+
+
+
+ Represents an action that edits a control flow graph by updating the fallthrough edge of a single node.
+
+ The type of instructions stored in the control flow graph.
+
+
+
+ Creates a new instance of the class.
+
+ The offset of the branching instruction.
+ The offset to the new fallthrough neighbour, or null to remove the fallthrough edge.
+
+
+
+ Gets the offset to the branching instruction responsible for the fallthrough edge.
+
+
+
+
+ Gets the offset to the new fallthrough neighbour. When this value is null, the removal of the
+ fallthrough edge is indicated.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a base implementation for a region in a control flow graph.
+
+ The type of data that each node in the graph stores.
+
+
+
+
+
+
+
+
+
+ Gets or sets a user-defined tag that is assigned to this region.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents an address range of code that is protected from exceptions by a handler block.
+
+
+
+
+ Creates a new instance of the structure.
+
+ The range indicating the code that is protected by the handler.
+ The range indicating the handler code.
+
+
+
+ Creates a new instance of the structure.
+
+ The range indicating the code that is protected by the handler.
+ The range indicating the prologue range that precedes the handler.
+ The range indicating the handler code.
+
+
+
+ Creates a new instance of the structure.
+
+ The range indicating the code that is protected by the handler.
+ The range indicating the prologue range that precedes the handler.
+ The range indicating the handler code.
+ A user defined tag that is added to the exception handler.
+
+
+
+ Creates a new instance of the structure.
+
+ The range indicating the code that is protected by the handler.
+ The range indicating the prologue range that precedes the handler.
+ The range indicating the handler code.
+ The range indicating the epilogue range that proceeds the handler.
+
+
+
+ Creates a new instance of the structure.
+
+ The range indicating the code that is protected by the handler.
+ The range indicating the prologue range that precedes the handler.
+ The range indicating the handler code.
+ The range indicating the epilogue range that proceeds the handler.
+ A user defined tag that is added to the exception handler.
+
+
+
+ Creates a new instance of the structure.
+
+ The range indicating the code that is protected by the handler.
+ The range indicating the handler code.
+ A user defined tag that is added to the exception handler.
+
+
+
+ Gets the address range indicating the start and end of the code that is protected by a handler.
+
+
+
+
+ Gets the address range indicating the start and end of the code that is executed before transferring
+ control to the .
+
+ A good example would be exception filters in CIL.
+
+
+
+ Gets the address range indicating the start and end of the handler code.
+
+
+
+
+ Gets the address range indicating the start and end of the code that is
+ executed after the .
+
+
+
+
+ Gets a user defined tag that is added to the exception handler.
+
+
+
+
+ Determines whether two exception handlers are considered equal.
+
+ The other exception handler.
+ true if the handler is equal, false otherwise.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides methods for detecting exception handler regions in a control flow graph by providing address ranges
+ indicating the protected and handler regions.
+
+
+
+
+ Creates new exception handler regions in the provided control flow graph, based on a collection of address
+ ranges indicating exception handlers.
+
+ The control flow graph to create regions in.
+ The exception handler address ranges.
+ The type of instructions stored in the control flow graph.
+
+
+
+ Represents a region in a control flow graph that is protected by an exception handler block.
+
+ The type of data that each node in the graph stores.
+
+
+
+ Creates a new instance of the class.
+
+
+
+
+ Gets the region of nodes that is protected by the exception handler.
+
+
+
+
+ Gets the regions that form the handler blocks.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a single handler region in an exception handler block.
+
+ The type of data that each node in the graph stores.
+
+
+
+ Creates a new instance of the class without
+ an explicit prologue and epilogue set.
+
+
+
+
+ Gets the region of nodes that form the code that precedes the handler.
+
+
+ This region is often used for filter clauses of the exception handler.
+
+
+
+
+ Gets the region of nodes that form the code of the handler block.
+
+
+
+
+ Gets the region of nodes that form the code that proceeds the handler.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides members for describing a region in a control flow graph.
+
+ The type of data that each node in the graph stores.
+
+
+
+ Gets the parent graph this region is part of.
+
+
+
+
+ Gets the parent region that this region is part of.
+
+
+ When this property is set to null this region is the root.
+
+
+
+
+ Obtains the first node that is executed in the region (if available).
+
+ The node, or null if no entrypoint was specified..
+
+
+
+ Gets a collection of all nested regions defined in this region.
+
+ The sub regions.
+
+
+
+ Gets a collection of all nodes in the control flow graph region. This includes all nodes in the nested
+ regions.
+
+ The nodes.
+
+
+
+ Searches for a node in the control flow graph with the provided offset or identifier.
+
+ The offset of the node to find.
+ The node.
+
+
+
+ Removes the node from the region.
+
+ The node to remove.
+ true if the node was found and removed, false otherwise.
+
+
+
+ Gets the nodes that are immediate successors of any node in this region.
+
+ The nodes.
+
+
+
+ Provides extensions to the interface.
+
+
+
+
+ Obtains the parent exception handler region that this region resides in (if any).
+
+
+ The parent exception handler region, or null if the region is not part of any exception handler.
+
+
+
+
+ Obtains the parent handler region that this region resides in (if any).
+
+
+ The parent exception handler region, or null if the region is not part of any exception handler.
+
+
+
+
+ Obtains the parent region of a specific type that this region resides in (if any).
+
+
+ The parent region, or null if the region is not part of any region of type .
+
+
+
+
+ Represents a simple unordered region defining an inner scope in the control flow graph.
+
+ The type of data that each node in the graph stores.
+
+
+
+ Creates a new instance of the class.
+
+
+
+
+ Gets or sets the first node that is executed in the region.
+
+
+
+
+ Gets a collection of top-level nodes that this region consists of.
+
+
+ This collection does not include any nodes in the nested sub regions.
+
+
+
+
+ Gets a collection of nested sub regions that this region defines.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a mechanism for transforming a control flow graph into a tree of scopes and basic blocks.
+
+
+
+
+ Constructs the tree of scopes and basic blocks based on the provided control flow graph.
+
+ The control flow graph .
+ The type of instructions stored in the graph.
+ The root scope.
+
+
+
+ Represents an exception that occurs during the sorting of nodes in a control flow graph.
+
+
+
+
+ Creates a new instance of the class.
+
+
+
+
+ Creates a new instance of the class.
+
+ The message.
+
+
+
+ Creates a new instance of the class.
+
+ The message.
+ The inner cause of the exception.
+
+
+
+ Provides a mechanism for ordering nodes in control flow graph, based on the outgoing edges of every node.
+
+
+
+
+ Determines an ordering of nodes in the control flow graph in such a way that the basic blocks can be
+ concatenated together in sequence, and still result in a valid execution of the original program.
+
+ The control flow graph to pull the nodes from.
+ The type of instructions stored in the graph.
+ The ordering.
+
+
+
+ Provides an implementation of a stack of which the elements can be accessed by index.
+
+ The type of elements in the stack.
+
+
+
+
+
+
+
+
+
+ Returns the top element of the stack.
+
+ The top element.
+
+
+
+ Returns the n-th top-most element of the stack.
+
+ The element.
+
+
+
+ Pops a single element from the stack.
+
+ The popped element.
+
+
+
+ Pushes a single element onto the stack.
+
+
+
+
+
+ Represents an adorner that styles edges in a control flow graph.
+
+ The type of instructions the nodes contain.
+
+
+
+ Gets or sets the edge style to use for normal fallthrough edges.
+
+
+
+
+ Gets or sets the edge style to use for unconditional branch edges.
+
+
+
+
+ Gets or sets the edge style to use for any fallthrough edge originating from a branching node.
+
+
+
+
+ Gets or sets the edge style to use for any conditional edge.
+
+
+
+
+ Gets or sets the edge style to use for any abnormal edge.
+
+
+
+
+
+
+
+ Represents an adorner that adds the string representation of the embedded instructions to a node in a graph.
+
+ The type of instructions the nodes contain.
+
+
+
+ Creates a new with the default formatter.
+
+
+
+
+ Creates a new with
+ the specified .
+
+ The to format instructions with.
+
+
+
+ Gets or sets the shape of the node.
+
+
+
+
+ Gets or sets a value indicating whether the adorner should add block headers to every node.
+
+
+
+
+ Gets or sets a value indicating whether the adorner should add the block instructions to every node.
+
+
+
+
+ Gets or sets a value indicating the format of block headers. This is a format string with one
+ parameter containing the value of .
+
+
+
+
+ Gets or sets the formatter that will be used to format the instructions.
+
+
+
+
+
+
+
+ Provides a default implementation for .
+
+ The type of the instruction to create a formatter of.
+
+
+
+
+
+
+ Represents an adorner that adds styles to regions in control flow graphs.
+
+ The type of instructions the nodes contain.
+
+
+
+ Gets or sets the style of an enclosing exception handler region.
+
+
+
+
+ Gets or sets the label of an enclosing exception handler region.
+
+
+
+
+ Gets or sets the style of the protected region in an exception handler region.
+
+
+
+
+ Gets or sets the label of the protected region in an exception handler region.
+
+
+
+
+ Gets or sets the style of a handler region in an exception handler region.
+
+
+
+
+ Gets or sets the label of a handler region in an exception handler region.
+
+
+
+
+ Gets or sets the style of a prologue region in an exception handler region.
+
+
+
+
+ Gets or sets the label of the prologue region in an exception handler region.
+
+
+
+
+ Gets or sets the default style of a control flow region.
+
+
+
+
+ Gets or sets the label of a contents region in a handler of an exception handler region.
+
+
+
+
+ Gets or sets the style of an epilogue region in an exception handler region.
+
+
+
+
+ Gets or sets the label of an epilogue region in an exception handler region.
+
+
+
+
+ Gets or sets the default style of a control flow region.
+
+
+
+
+
+
+
+
+
+
+ Allows the user to format instructions in the .
+
+ The type of instructions the nodes contain.
+
+
+
+ Formats a given .
+
+ The to format.
+ The formatted .
+
+
+
+ Provides an implementation of the interface, that returns the offset of the basic
+ block as unique identifiers.
+
+ The type of instructions stored in the basic block.
+
+
+
+ Provides a default instance of the class.
+
+
+
+
+
+
+
diff --git a/Echo/Echo.Core.dll b/Echo/Echo.Core.dll
new file mode 100644
index 0000000..fadc5c3
Binary files /dev/null and b/Echo/Echo.Core.dll differ
diff --git a/Echo/Echo.Core.xml b/Echo/Echo.Core.xml
new file mode 100644
index 0000000..e833d00
--- /dev/null
+++ b/Echo/Echo.Core.xml
@@ -0,0 +1,1444 @@
+
+
+
+ Echo.Core
+
+
+
+
+ Represents an address range in memory.
+
+
+
+
+ A range that starts and ends at index 0.
+
+
+
+
+ Determines whether two address ranges are considered equal.
+
+ The first range.
+ The second range.
+ true if the ranges are considered equal, false otherwise.
+
+
+
+ Determines whether two address ranges are not considered equal.
+
+ The first range.
+ The second range.
+ true if the ranges are not considered equal, false otherwise.
+
+
+
+ Creates a new address range.
+
+ The starting address.
+ The exclusive ending address.
+
+
+
+ Gets the address of the first byte in the address range.
+
+
+
+
+ Gets the address where this address range stops. This address is exclusive.
+
+
+
+
+ Gets the total length of the address range.
+
+
+
+
+ Determines whether the provided address falls within the address range.
+
+ The address.
+ true if the address falls within the range, false otherwise.
+
+
+
+ Determines whether the address range contains the provided sub range.
+
+ The address range.
+ true if the sub range falls within the range, false otherwise.
+
+
+
+ Determines whether the range is considered equal with the provided range.
+
+ The other range.
+ true if the ranges are considered equal, false otherwise.
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides members for describing an instruction set.
+
+ The type of the instruction model this architecture describes.
+
+
+
+ Gets the offset of an instruction.
+
+ The instruction to get the offset from.
+ The offset.
+
+
+
+ Gets the size in bytes of an instruction.
+
+ The instruction to measure.
+ The size.
+
+
+
+ Gets attributes associated to the flow control behaviour of the provided instruction.
+
+ The instruction to get the attributes from.
+ The flow control attributes.
+
+
+
+ Gets a value indicating the number of values an instruction pushes on the stack.
+
+ The instruction to get the stack push count from.
+ The number of stack slots the instruction pushes.
+
+
+
+ Gets a value indicating the number of values an instruction pops from the stack.
+
+ The instruction to get the stack pop count from.
+ The number of stack slots the instruction pops.
+
+
+
+ Gets the number of variables that the provided instruction reads from.
+
+ The instruction to get the number of read variables from.
+ The number of variables.
+
+
+
+ Gets a collection of variables that an instruction reads from.
+
+ The instruction to get the variables from.
+ The output buffer to write the read variables into.
+ The number of variables that were written into .
+
+
+
+ Gets the number of variables that the provided instruction writes to.
+
+ The instruction to get the number of written variables from.
+ The number of variables.
+
+
+
+ Gets a collection of variables that an instruction writes to.
+
+ The instruction to get the variables from.
+ The output buffer to write the written variables into.
+ The number of variables that were written into .
+
+
+
+ Provides members for describing various flow control properties of an instruction.
+
+
+
+
+ Indicates the instruction does not have any specific attributes assigned to it.
+
+
+
+
+ Indicates the instruction might branch out from the normal control flow to a different instruction.
+
+
+
+
+ Indicates the instruction terminates the current execution path.
+
+
+
+
+ Provides members for describing the purity of instructions.
+
+ The type of instructions.
+
+
+
+ Gets a value indicating whether a particular instruction is considered pure, that is, has no side effects.
+
+ The instruction to classify.
+ true if the instruction is pure, false if not, and if
+ this could not be determined.
+
+
+
+ Represents a collection of instructions that can be accessed by their offset.
+
+ The type of instructions that this collection provides.
+
+
+
+ Gets the architecture describing the instructions exposed by this instruction provider.
+
+
+
+
+ Gets the instruction at the provided address.
+
+ The address of the instruction to get.
+ The instruction at the provided address.
+
+
+
+ Represents a single variable in a virtual machine.
+
+
+
+
+ Gets the name of the variable.
+
+
+
+
+ Wraps a simple collection of instructions in a basic implementation of an .
+
+ The type of instructions to store.
+
+
+
+ Creates a new wrapper for a sequence of instructions.
+
+ The instruction architecture.
+ The instructions to put into the wrapper.
+ Occurs when there are multiple instructions with the same offset.
+ Occurs when the provided instruction sequence is null.
+
+
+
+
+
+
+
+
+
+ Represents a snapshot of the stack at a particular point in time during an execution of a program.
+
+ The type to use to model the slots in the stack.
+
+
+
+ Gets the top value of the stack.
+
+
+
+
+ Gets the number of elements on the stack.
+
+
+
+
+ Gets the value at the provided index.
+
+ The index.
+
+
+
+ Gets an ordered collection of all slots that are in use.
+
+ The collection of slots, ordered from top to bottom.
+
+
+
+ Pushes a single value onto the stack.
+
+ The value to push.
+
+
+
+ Pushes a collection of values onto the stack.
+
+ The values to push.
+ True indicates whether the collection of values should be pushed in reversed order.
+
+
+
+ Pops a single value from the top of the stack.
+
+ The value that was popped from the stack.
+
+
+
+ Pops a collection of values from the stack.
+
+ The number of values to pop from the stack.
+ True indicates whether the collection of values should be returned in reversed order.
+ The popped values.
+
+
+
+ Creates a copy of the stack state. This also copies all values inside the stack.
+
+ The copied stack state.
+
+
+
+ Removes all slots from the stack.
+
+
+
+
+ Provides a base for all virtualized values.
+
+
+
+
+ Gets a value indicating whether all bits of the value are fully known or not.
+
+
+
+
+ Gets the number of bytes this value uses to represent itself in memory.
+
+
+
+
+ Creates a shallow copy of the value.
+
+ The copied value.
+
+
+
+ Represents a snapshot of all variables and their values at a particular point in time during the execution
+ of a program.
+
+
+
+
+
+ Gets or sets the value currently assigned to a variable.
+
+ The variable.
+
+
+
+ Obtains a list of all recorded variables in this snapshot.
+
+ The recorded variables.
+
+
+
+ Creates a copy of the snapshot. This also copies all registered values for each variable.
+
+ The copied variable state.
+
+
+
+ Removes recorded variable.
+
+ The variable.
+ if the variable is successfully found and removed; otherwise, .
+
+
+
+ Removes all variables.
+
+
+
+
+ The exception that is thrown when an inconsistency in the size of the stack was detected. Typically this
+ exception occurs when two or more converging control flow paths have inconsistent stack sizes, or when
+ either an insufficient or excessive amount of values were pushed onto the stack.
+
+
+
+
+ Creates a new stack imbalance exception.
+
+
+
+
+ Creates a new stack imbalance exception.
+
+ The offset where the stack inconsistency was detected.
+
+
+
+ Creates a new stack imbalance exception.
+
+ The message of the error that occured.
+
+
+
+ Creates a new stack imbalance exception.
+
+ The message of the error that occured.
+ The inner cause of the exception.
+
+
+
+ Gets the offset where the stack inconsistency was detected.
+
+
+
+
+ Provides a base implementation of a stack state snapshot.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Gets an ordered list of items allocated on the stack. The last item in the list represents the top of the stack.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Creates a copy of the stack state. This also copies all values inside the stack.
+
+ The copied stack state.
+
+
+
+
+
+
+ Provides a base implementation of a variable state, that initially assigns for every variable a default value.
+
+
+
+
+ Creates a new variable state snapshot, using the provided default value.
+
+ The default value for all variables.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Creates a copy of the snapshot. This also copies all registered values for each variable.
+
+ The copied variable state.
+
+
+
+ Provides utility members for finding connected components within a graph.
+
+
+
+
+ Finds all strongly connected components in the provided graph.
+
+ The graph to get the components from.
+ A collection of sets representing the strongly connected components.
+
+
+
+ Represents the error that occurs when a cycle was found in a graph that is supposed to be acyclic.
+
+
+
+
+ Initializes a new instance of the class.
+
+
+
+
+ Initializes a new instance of the class.
+
+ The error message.
+
+
+
+ Initializes a new instance of the class.
+
+ The error message.
+ The inner exception that was the cause of this exception.
+
+
+
+ Provides a mechanism for sorting nodes in a graph, such that for every edge from node A to node B in the graph we
+ have that node A comes before node B in the final ordering, also known as a topological sorting of the graph.
+
+ The type of nodes to sort.
+
+
+
+ Represents the method that obtains an ordered list of children of a node in a graph.
+
+ The node to list the children for.
+
+
+
+ Creates a new instance of the class.
+
+ The method to call when obtaining an ordered list of children of a node.
+
+
+
+ Creates a new instance of the class.
+
+ The method to call when obtaining an ordered list of children of a node.
+ Determines whether the algorithm should ignore any back-edges.
+
+
+
+ Gets the method to call when obtaining an ordered list of children of a node.
+
+
+
+
+ Gets or sets a value indicating whether the algorithm should ignore any back-edges.
+
+
+
+
+ Obtains the topological sorting of a graph, using the provided node as the root.
+
+ The root of the graph.
+ An ordered list of nodes, such that any node A appears before any other node B if the edge A to B
+ exists in the graph.
+ Occurs when there was a cycle detected in the graph, and
+ is set to false.
+
+
+
+ Represents a depth-first node traversal of a graph.
+
+
+
+
+
+
+
+
+
+
+ Creates a new depth first traversal.
+
+
+
+
+ Creates a new depth first traversal.
+
+
+ True if the traversal should traverse the graph in a reversed manner.
+ That is, whether the traversal should treat each edge as if it was reversed.
+
+
+
+
+ Gets a value indicating the traversal algorithm should traverse either outgoing or incoming edges.
+
+
+
+
+
+
+
+ Fires and handles the node discovered event.
+
+ The event arguments.
+
+
+
+ Fires and handles the traversal completed event.
+
+
+
+
+ Provides a base for a discovery event that occurs while traversing a graph.
+
+
+
+
+ Gets or sets a value indicating whether the traversal should continue exploring the current path.
+
+
+
+
+ Gets or sets a value indicating whether the traversal should be aborted or not.
+
+
+
+
+ Provides members for traversing a graph.
+
+
+
+
+ Fires when a node is about to be traversed by the traversal.
+
+
+
+
+ Fires when the traversal is completed.
+
+
+
+
+ Performs the traversal algorithm.
+
+ The starting node.
+
+
+
+ Provides information about a node discovery during a traversal of a graph.
+
+
+
+
+ Creates a new node discovery event.
+
+ The node that was discovered.
+ The edge that was traversed to discover the node.
+
+
+
+ Gets the node that was discovered.
+
+
+
+
+ Gets the edge that was traversed that resulted in the node to be discovered.
+
+
+
+
+ Provides a mechanism to record all parent nodes during a traversal.
+
+
+ A node is a parent of another node if it is the parent in the search tree.
+
+
+
+
+ Creates a new parent recorder.
+
+ The traversal to hook into.
+ Occurs when the provided traversal is null.
+
+
+
+ Gets the edge that was traversed when discovering the provided node.
+
+ The node to get the edge to its parent from.
+ The edge originating from the parent node, or null if the node was the first node to be discovered.
+
+
+
+ Gets the parent of the provided node in the search tree that was recorded.
+
+ The node to get the parent node from.
+ The parent node in the search tree, or null if the node was the first node to be discovered.
+
+
+
+ Provides a mechanism for recording a post traversal order.
+
+
+
+
+ Creates a new post traversal order and hooks into the provided traversal object.
+
+ The traversal object to hook into.
+
+
+
+ Gets the final post-order of nodes that was recorded.
+
+
+
+
+
+ Provides a mechanism to record the order in which each node in the graph was traversed by a traversal algorithm.
+
+
+
+
+ Creates a new traversal order recorder and hooks into the provided traversal object.
+
+ The traversal object to hook into.
+
+
+
+ Gets a collection of all the nodes that were discovered during the traversal.
+
+
+
+
+ Gets the index of the node during the traversal.
+
+ The node to get the index from.
+ The index.
+
+
+
+ Gets the full traversal as an ordered list of nodes.
+
+ The traversal.
+
+
+
+ Provides a basic implementation of an edge in a graph.
+
+
+
+
+ Creates a new edge in a graph.
+
+ The node that this edge starts at in the directed graph.
+ The node that this edge points to in the directed graph.
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a single edge that connects two nodes together in a directed graph.
+
+
+
+
+ Gets the node that this edge starts at in the directed graph.
+
+
+
+
+ Gets the node that this edge points to in the directed graph.
+
+
+
+
+ Provides utility methods that further extend the graph model classes.
+
+
+
+
+ Given an edge and one of the nodes that this edge connects with, gets the other end of the edge.
+
+ The edge.
+ One of the nodes of the edge.
+ The other end of the edge.
+
+
+
+ Provides members to model a directed graph-like structure.
+
+
+
+
+ Gets a collection of all directed edges (or arcs) that connect nodes in the directed graph.
+
+ The edges.
+
+
+
+ Represents a node that is tagged with an identification number.
+
+
+
+
+ Gets the unique identifier of the node.
+
+
+
+
+ Represents a single node in a generic directed graph.
+
+
+
+
+ Gets a value indicating the number of incoming edges that this node is incident to.
+
+
+
+
+ Gets a value indicating the number of outgoing edges that this node is incident to.
+
+
+
+
+ Gets a collection of all edges that target this node.
+
+ The incoming edges.
+
+
+
+ Gets a collection of all outgoing edges originating from this node.
+
+ The outgoing edges.
+
+
+
+ Gets a collection of nodes that precede this node.
+
+ The predecessor nodes.
+
+
+
+ Gets a collection of nodes that can be reached from this node by following one of the incident edges.
+
+ The successor nodes.
+
+
+
+ Determines whether the provided node precedes the current node.
+
+ The node to check.
+ True if the node is a predecessor, false otherwise.
+
+
+
+ Determines whether the provided node can be reached from this node by following one of the incident edges.
+
+ The node to check.
+ True if the node is a successor, false otherwise.
+
+
+
+ Represents a region of a graph, comprising of a subset of nodes of the full graph.
+
+
+
+
+ Gets a collection of nodes that this segment contains.
+
+ The nodes.
+
+
+
+ Gets a collection of sub graphs that this segment contains (if any).
+
+ The sub graphs.
+
+
+
+ Defines a tuple of style properties for an entity in a control flow graph.
+
+
+
+
+ Creates a new style for an entity.
+
+ The color of the entity.
+ The line drawing style of the entity.
+
+
+
+ Gets the color of the entity.
+
+
+
+
+ Gets the line drawing style of the entity.
+
+
+
+
+ Provides a mechanism for writing graphs to a character stream using the dot file format.
+
+
+
+
+ Creates a new dot writer.
+
+ The writer responsible for writing the output.
+
+
+
+ Gets the writer that is used to write textual data to the output stream.
+
+
+
+
+ Gets or sets a value indicating whether nodes in the output file should be explicitly defined before the
+ edges are defined.
+
+
+
+
+ Gets or sets a value indicating whether statements in the output file should be separated by semicolons.
+
+
+
+
+ Gets or sets the object responsible for assigning unique identifiers to nodes in a graph.
+
+
+
+
+ Gets or sets the adorner to use for adorning the nodes in the final output.
+
+
+ When this property is set to null, no adornments will be added.
+
+
+
+
+ Gets or sets the adorner to use for adorning the edges in the final output.
+
+
+ When this property is set to null, no adornments will be added.
+
+
+
+
+ Gets or sets the adorner to use for adorning the sub graphs in the final output.
+
+
+ When this property is set to null, no adornments will be added.
+
+
+
+
+ Writes a graph to the character stream.
+
+ The graph to write.
+
+
+
+ Appends the header of a new graph to the output stream.
+
+
+
+
+ Appends the footer of a graph to the output stream.
+
+
+
+
+ Appends a single node definition to the output stream.
+
+ The node to append.
+
+
+
+ Appends an edge to the output stream.
+
+ The edge to append.
+
+
+
+ Appends a single identifier to the output stream.
+
+ The identifier to write.
+
+
+
+ Appends a semicolon to the output stream, depending on the value of .
+
+
+
+
+ Determines whether an identifier requires escaping.
+
+ The identifier to test.
+ True if the identifier needs escaping, false otherwise.
+
+
+
+ Appends a single character to the output stream, and escapes it when necessary.
+
+ The character to write.
+
+
+
+ Provides an implementation of the interface, that returns the hash code of the
+ node object as unique identifiers.
+
+
+
+
+ Provides a default instance of the class.
+
+
+
+
+
+
+
+ Represents a node adorner that adds a label to a node containing the hexadecimal representation of the
+ property.
+
+
+
+
+ Gets or sets the string to prepend to the identifier of the node.
+
+
+
+
+ Gets or sets the string to append to the identifier of the node.
+
+
+
+
+ Gets or sets the minimal number of digits to use in the label.
+
+
+
+
+
+
+
+ Provides an implementation of the interface, that returns the value of
+ .
+
+
+
+
+ Provides a default instance of the class.
+
+
+
+
+
+
+
+ Provides members for adorning an edge in a graph.
+
+
+
+
+ Obtains the adornments that should be added to the edge.
+
+ The edge to adorn.
+ The identifier assigned to the source node.
+ The identifier assigned to the target node.
+ The adornments.
+
+
+
+ Provides members for adorning a node in a graph.
+
+
+
+
+ Obtains the adornments that should be added to the node.
+
+ The node to adorn.
+ The identifier assigned to the node.
+ The adornments.
+
+
+
+ Provides members for adorning a sub graph.
+
+
+
+
+ Determines the name of the provided sub graph.
+
+ The sub graph.
+
+
+
+
+ Obtains the adornments that should be added to the sub graph.
+
+ The sub graph to adorn.
+ The adornments.
+
+
+
+ Provides an implementation of the interface, that maintains a counter
+ that is increased every time a new node is assigned an identifier.
+
+
+
+
+
+
+
+ Provides members for obtaining unique identifiers to a node.
+
+
+
+
+ Gets the identifier assigned to the node.
+
+ The node.
+ The identifier.
+
+
+
+ Provides a base contract for nodes that will be used in a tree
+
+
+
+
+ The parent of this
+
+
+
+
+
+
+
+
+
+
+ Gets the children of the current .
+
+ The children.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Updates the value and the parent of the node.
+
+ The child element to update.
+ The new value to assign to the .
+ When the node already has a parent.
+
+
+
+ Represents a collection of tree node children
+
+ The type of the parent
+ The node to create a collection of
+
+
+
+ Creates a new tree node collection with the specified
+
+ The owner whose children this collection represents
+
+
+
+ Asserts that the provided node is not already added to another tree node.
+
+ The node to verify.
+ Occurs if the node is already added to another node.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a ternary boolean (true, false or unknown) value.
+
+
+
+
+ Represents the true value.
+
+
+
+
+ Represents the false value.
+
+
+
+
+ Represents the unknown value.
+
+
+
+
+ Creates a new trilean.
+
+ The boolean value.
+
+
+
+ Creates a new trilean.
+
+ The trilean value.
+
+
+
+ Creates a new trilean.
+
+
+ The nullable boolean value. If the value is null, will be assumed.
+
+
+
+
+ Gets the raw integer representation of the trilean value.
+
+
+
+
+ Gets a value indicating whether the value is known (either true or false).
+
+
+
+
+ Gets a value indicating whether the value is unknown.
+
+
+
+
+ When the trilean value is known, obtains the boolean value.
+
+ The boolean value.
+
+
+
+ When the trilean value is known, obtains the boolean value, otherwise returns false.
+
+ The boolean value.
+
+
+
+ Converts the trilean to a nullable boolean, where null indicates the unknown state.
+
+ The nullable boolean.
+
+
+
+ Creates a new trilean.
+
+ The boolean value.
+
+
+
+ Creates a new trilean.
+
+ The trilean value.
+
+
+
+ Creates a new trilean.
+
+ The trilean value.
+
+
+
+ Determines whether the trilean is true.
+
+ The trilean.
+ true if the property is , false otherwise.
+
+
+
+ Determines whether the trilean is false.
+
+ The trilean.
+ false if the property is , false otherwise.
+
+
+
+ Determines whether this trilean is exactly equal to the specified trilean.
+
+ The left hand side of the comparison.
+ The right hand side of the comparison.
+
+ true if the property of both trileans are equal, false otherwise.
+
+
+
+
+ Determines whether this trilean is not equal to the specified trilean.
+
+ The left hand side of the comparison.
+ The right hand side of the comparison.
+
+ true if the property of both trileans are different, false otherwise.
+
+
+
+
+ Determines whether this trilean is exactly equal to the specified trilean.
+
+ The other trilean.
+
+ true if the property of both trileans are equal, false otherwise.
+
+
+
+
+
+
+
+
+
+
+ Inverts the trilean value.
+
+ The value to invert.
+
+ Returns true if the value is false, and vice versa. If unknown, the return value is also unknown.
+
+
+
+
+ Inverts the trilean value.
+
+
+ Returns true if the value is false, and vice versa. If unknown, the return value is also unknown.
+
+
+
+
+ Calculates the index within a binary operator lookup table.
+
+ The row.
+ The column.
+ The index.
+
+
+
+ Computes the and between two trilean values.
+
+ The left hand side of the binary operator.
+ The right hand side of the binary operator.
+ Returns true if both values are true. If not, returns unknown if at
+ least one is true or unknown and the other is unknown, and false otherwise.
+
+
+
+ Computes the and between two trilean values.
+
+ The other trilean value.
+ Returns true if both values are true. If not, returns unknown if at
+ least one is true or unknown and the other is unknown, and false otherwise.
+
+
+
+ Computes the inclusive or between two trilean values.
+
+ The left hand side of the binary operator.
+ The right hand side of the binary operator.
+ Returns true if at least one of the values is true. If neither are true, returns unknown if at
+ least one is unknown, and false otherwise.
+
+
+
+ Computes the inclusive or between two trilean values.
+
+ The other trilean value.
+ Returns true if at least one of the values is true. If neither are true, returns unknown if at
+ least one is unknown, and false otherwise.
+
+
+
+ Computes the exclusive or between two trilean values.
+
+ The left hand side of the binary operator.
+ The right hand side of the binary operator.
+ Returns true if the two trilean values are different. If at least one is unknown,
+ the result is unknown.
+
+
+
+ Computes the exclusive or between two trilean values.
+
+ The other trilean value.
+ Returns true if the two trilean values are different. If at least one is unknown,
+ the result is unknown.
+
+
+
+
+
+
+ Provides members for all possible values in a ternary number system.
+
+
+
+
+ Indicates the true value.
+
+
+
+
+ Indicates the false value.
+
+
+
+
+ Indicates the unknown value.
+
+
+
+
diff --git a/Echo/Echo.DataFlow.dll b/Echo/Echo.DataFlow.dll
new file mode 100644
index 0000000..42b0a2f
Binary files /dev/null and b/Echo/Echo.DataFlow.dll differ
diff --git a/Echo/Echo.DataFlow.xml b/Echo/Echo.DataFlow.xml
new file mode 100644
index 0000000..e744da9
--- /dev/null
+++ b/Echo/Echo.DataFlow.xml
@@ -0,0 +1,1087 @@
+
+
+
+ Echo.DataFlow
+
+
+
+
+ Represents the exception that occurs when a cyclic dependency was detected in a data flow graph.
+
+
+
+
+ Initializes a new instance of the class.
+
+
+
+
+ Initializes a new instance of the class, with the specified message.
+
+ The error message.
+
+
+
+ Initializes a new instance of the class, with the specified message
+ and inner exception that is the cause of this exception.
+
+ The error message.
+ The inner exception that was the cause of this exception.
+
+
+
+ Provides members for collecting data dependencies in a data flow graph.
+
+
+
+
+ Collects all dependency nodes recursively, and sorts them in a topological order such that the final collection
+ of nodes can be executed sequentially.
+
+ The node to find all dependencies for.
+ The type of contents that each node contains.
+ The topological ordering of all dependencies of the node.
+ Occurs when there is a cyclic dependency in the graph.
+
+
+
+ Collects all dependency nodes recursively, and sorts them in a topological order such that the final collection
+ of nodes can be executed sequentially.
+
+ The node to find all dependencies for.
+ Flags that influence the behaviour of the algorithm.
+ The type of contents that each node contains.
+ The topological ordering of all dependencies of the node.
+ Occurs when there is a cyclic dependency in the graph.
+
+
+
+ Provides flags that influence the behaviour of the class.
+
+
+
+
+ Indicates stack dependency edges should be traversed during the collection.
+
+
+
+
+ Indicates variable dependency edges should be traversed during the collection.
+
+
+
+
+ Indicates all edges should be traversed during the collection.
+
+
+
+
+ Represents a mutable collection of nodes present in a data flow graph.
+
+ The type of data that is stored in each node.
+
+
+
+
+
+
+
+
+
+ Gets a node by its identifier.
+
+ The node identifier.
+
+
+
+ Creates and adds a new node to the collection of data flow nodes.
+
+ The unique identifier of the node.
+ The contents of the node.
+ The created node.
+
+
+
+
+
+
+ Adds a collection of nodes to the graph.
+
+ The nodes to add.
+
+ Occurs when at least one node in the provided collection is already added to another graph.
+
+
+
+
+
+
+
+ Determines whether a node with a specific offset was added to the collection.
+
+ The offset to the node.
+ true if there exists a node with the provided offset, false otherwise.
+
+
+
+
+
+
+
+
+
+ Removes a node by its offset.
+
+ The offset. of the node to remove.
+ true if the collection contained a node with the provided offset., and the node was removed
+ successfully, false otherwise.
+
+
+
+ Synchronizes all offsets of each node with the underlying instructions.
+
+ Occurs when one or more nodes are in a state that new offsets
+ cannot be determined. This includes duplicated offsets.
+
+
+ Because updating offsets is a relatively expensive task, calls to this method should be delayed as much as
+ possible.
+
+
+ This method will invalidate any enumerators that are enumerating this collection of nodes.
+
+
+
+
+
+
+
+
+
+
+
+ Represents a collection of dependencies allocated on a stack for a node in a data flow graph.
+
+ The type of contents to put in each node.
+
+
+
+ Creates a new dependency collection for a node.
+
+ The owner node.
+
+
+
+ Gets the total number of edges that are stored in this dependency collection.
+
+
+
+
+ Ensures the node has the provided amount of stack dependencies.
+
+ The new amount of dependencies.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Gets the enumerator for this stack dependency collection.
+
+
+
+
+
+ Represents an enumerator for a stack dependency collection.
+
+
+
+
+ Creates a new instance of the structure.
+
+ The collection to enumerate.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a collection of variables and their symbolic values that a node in a data flow graph depends on.
+
+ The type of contents to put in each node.
+
+
+
+ Gets or sets the variable dependency assigned to the variable.
+
+ The variable
+
+
+
+
+
+
+
+
+
+ Gets the total number of edges that are stored in this dependency collection.
+
+
+
+
+
+
+
+ Attempts to get the dependency assigned to the provided variable.
+
+ The variable.
+ When this function returns true, contains the dependency.
+ true if the variable was registered as a dependency, false otherwise.
+
+
+
+ Adds a variable dependency to the node.
+
+ The dependency to add.
+
+
+
+
+
+
+
+
+
+ Determines whether the provided variable is registered as a dependency.
+
+ The dependency.
+
+
+
+
+
+
+
+ Unregisters a variable as a dependency.
+
+ The variable to unregister.
+ true if the variable was registered before and is now unregistered, false otherwise.
+
+
+
+ Obtains a collection of variables that are registered in the dependency.
+
+ The variables.
+
+
+
+ Obtains an enumerator that enumerates all recorded variable dependencies in this collection.
+
+ The enumerator.
+
+
+
+ Represents an enumerator that enumerates all entries in a variable dependencies collection.
+
+
+
+
+ Creates a new instance of the class.
+
+ The collection to enumerate.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a base for data dependencies of a node in a data flow graph, which is a set of one or more data flow
+ nodes where the owner node might pull data from.
+
+ The type of data source that this dependency uses.
+ The type of contents to put in a data flow node.
+
+
+
+
+
+
+
+
+
+ Gets a value indicating whether the data dependency has any known data sources.
+
+
+
+
+ Gets the node that owns the dependency.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Removes all data sources that are incident with the provided node.
+
+ The node.
+ true if at least one edge was removed, false otherwise.
+
+
+
+
+
+
+
+
+
+ Gets a collection of data flow edges that encode the stored data sources.
+
+ The edges.
+
+
+
+ Gets a collection of nodes that are possible data sources for the dependency.
+
+
+
+
+
+ Provides members for describing types of dependencies between nodes in a data flow graph.
+
+
+
+
+ Indicates the dependency is a stack dependency.
+
+
+
+
+ Indicates the dependency is a variable dependency.
+
+
+
+
+ Represents an edge between two nodes in a data flow graph (DFG). The origin of the node represents the dependant,
+ and the target of the node represents the dependency.
+
+ The type of information to store in each data flow node.
+
+
+
+ Creates a new dependency edge between two nodes.
+
+ The dependent node.
+ The dependency node.
+
+
+
+ Gets node that depends on the data source.
+
+
+
+
+ Gets the data source this data flow edge points to.
+
+
+
+
+ Represents a graph that encodes data dependencies between objects. An edge (A, B) indicates node A depends on
+ the evaluation of node B.
+
+ The type of contents to store for each node.
+
+
+
+ Creates a new data flow graph.
+
+
+
+
+ Gets the architecture of the instructions that are stored in the data flow graph.
+
+
+
+
+ Gets a collection of nodes that are present in the graph.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Serializes the data flow graph to the provided output text writer using the dot file format.
+
+ The output stream.
+
+ To customize the look of the resulting dot file graph, use the class
+ instead of this function.
+
+
+
+
+ Represents a single node in a data flow graph.
+
+ The type of contents to store in the node.
+
+
+
+ Creates a new data flow graph node.
+
+ A unique identifier for the node that can be used for indexing the node.
+ The contents of the node.
+
+
+
+ Gets the data flow graph this node is a part of.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Gets a value indicating whether the data flow node represents an external data source.
+
+
+
+
+ Gets the contents of the node.
+
+
+
+
+ Gets a collection of values allocated on a stack that this node depends on.
+
+
+
+
+ Gets a collection of values that are assigned to variables that this node depends on.
+
+
+
+
+ Obtains a collection of edges that refer to dependent nodes.
+
+ The edges.
+
+
+
+ Obtains a collection of edges encoding all the dependencies that this node has.
+
+ The edges.
+
+
+
+ Obtains a collection of nodes that depend on this node.
+
+ The dependant nodes.
+
+
+
+ Removes all incident edges (both incoming and outgoing edges) from the node, effectively isolating the node
+ in the graph.
+
+
+
+
+
+
+
+ Represents a data source in a data flow graph.
+
+ The type of data stored in each data flow node.
+
+
+
+ Creates a new data source.
+
+ The node producing the data.
+
+
+
+ Gets the data flow node that produced the data.
+
+
+
+
+ Gets the type of data dependency that this data source encodes.
+
+
+
+
+ Determines whether the data sources are considered equal.
+
+ The other data source.
+
+
+
+
+
+
+
+
+
+ Determines whether the data sources are considered equal.
+
+ The first data source.
+ The second data source.
+ true if they are considered equal, false otherwise.
+
+
+
+ Determines whether the data sources are not considered equal.
+
+ The first data source.
+ The second data source.
+ true if they are not considered equal, false otherwise.
+
+
+
+ Represents an immutable snapshot of a program state that is fully symbolic.
+
+ The type of instructions.
+
+
+
+ Gets an empty program state.
+
+
+
+
+ Creates a new empty program state, initialized at the provided program counter.
+
+ The initial program counter.
+
+
+
+ Creates a new empty program state, initialized at the provided program counter.
+
+ The initial program counter.
+ The initial stack state.
+
+
+
+ Creates a new empty program state, initialized at the provided program counter.
+
+ The initial program counter.
+ The initial state of the variables.
+
+
+
+ Creates a new empty program state, initialized at the provided program counter.
+
+ The initial program counter.
+ The initial stack state.
+ The initial state of the variables.
+
+
+
+ Gets the current value of the program counter that points to the instruction to be executed next.
+
+
+
+
+ Gets the current stack state of the program.
+
+
+
+
+ Gets the current variable state of the program.
+
+
+
+
+ Copies the current state and moves the program counter of the copy to the provided address.
+
+ The new program counter.
+ The new program state.
+
+
+
+ Copies the current state and replaces the stack state with a new one.
+
+ The new stack state.
+ The new program state.
+
+
+
+ Copies the current state and replaces the variables state with a new one.
+
+ The new variables state.
+ The new program state.
+
+
+
+ Copies the current state and pushes a new value onto the stack.
+
+ The new value.
+ The new program state.
+
+
+
+ Copies the current state and pops the top value from the stack.
+
+ The popped value.
+ Occurs when the stack is empty.
+ The new program state.
+
+
+
+ Merges two program states together, combining all data sources.
+
+ The other program state to merge with.
+ The newly created state.
+ true if the state has changed, false otherwise.
+ Occurs when the program counters do not match.
+ Occurs when the stack heights do not match.
+
+
+
+
+
+
+ Represents a symbolic value that resides in memory.
+
+
+
+
+ Creates a new symbolic value with no data sources.
+
+
+
+
+ Creates a new symbolic value with a single data source.
+
+ The data source of the symbolic value.
+
+
+
+ Creates a new symbolic value with the provided data sources.
+
+ The data sources of the symbolic value.
+
+
+
+ Merges two data dependencies into one symbolic value.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Gets a value indicating whether the data dependency has any known data sources.
+
+
+
+
+ Creates a new symbolic value referencing the first stack value produced by the provided node.
+
+ The node producing the value.
+ The symbolic value.
+
+
+
+ Creates a new symbolic value referencing a stack value produced by the provided node.
+
+ The node producing the value.
+ The index of the stack value that was produced by the node.
+ The symbolic value.
+
+
+
+ Creates a new symbolic value referencing a variable value assigned by the provided node.
+
+ The node assigning the value.
+ The variable that was assigned a value.
+ The symbolic value.
+
+
+
+ Interprets the symbolic value as a collection of stack data sources.
+
+ The stack data sources.
+
+
+
+ Interprets the symbolic value as a collection of variable data sources.
+
+ The variable data sources.
+
+
+
+ Creates an exact copy of the value.
+
+ The copied value.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Removes all data sources that are related to the specified node.
+
+ The node to remove all data sources from.
+ true if any data source was removed, false otherwise.
+
+
+
+
+
+
+ Gets a collection of nodes that were referenced by all data sources in this data dependency.
+
+
+
+
+
+
+
+ Returns an enumerator that iterates over all data sources the data dependency defines.
+
+ The enumerator.
+
+
+
+ Provides a mechanism for enumerating all data sources within a single symbolic value.
+
+
+
+
+ Creates a new instance of the structure.
+
+ The data dependency to enumerate the data sources for.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents an external data source in a data flow graph.
+
+ The type of contents to store in the node.
+
+
+
+ Creates a new external data source.
+
+ The unique identifier of the data source. This should be a negative number.
+ The display name of the external data source.
+
+
+
+ Creates a new external data source.
+
+ The unique identifier of the data source. This should be a negative number.
+ The display name of the external data source.
+ The contents of the data flow node.
+
+
+
+ Gets the name of the auxiliary data flow node.
+
+
+
+
+
+
+
+
+
+
+ Represents an adorner that styles edges in a data flow graph.
+
+ The type of contents the nodes contain.
+
+
+
+ Gets or sets the edge style to use for edges representing stack dependencies.
+
+
+
+
+ Gets or sets a value indicating whether edges representing stack dependencies should be annotated
+ with the stack slot index.
+
+
+
+
+ Gets or sets the edge style to use for edges representing variable dependencies.
+
+
+
+
+ Gets or sets a value indicating whether edges representing variable dependencies should be annotated
+ with the variable that was referenced.
+
+
+
+
+
+
+
+ Represents an adorner that adds the string representation of the embedded instructions to a node in a graph.
+
+ The type of instructions the nodes contain.
+
+
+
+ Gets or sets the shape of the node.
+
+
+
+
+
+
+
+ Represents a data source that refers to a stack value produced by a node in a data flow graph.
+
+ The type of data stored in each data flow node.
+
+
+
+ Creates a new stack data source, referencing the first stack value produced by the provided node.
+
+ The node producing the value.
+
+
+
+ Creates a new stack data source, referencing a stack value produced by the provided node.
+
+ The node producing the value.
+ The index of the stack value that was produced by the node.
+
+
+
+ Gets a value indicating the stack slot index that was pushed by the instruction referenced in .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a collection of data sources for a single stack slot dependency of a node.
+
+ The type of contents to put in a data flow node.
+
+
+
+ Adds a data source to the dependency, referencing the first stack value produced by the provided node.
+
+ The node producing the value.
+ The stack data source.
+
+
+
+ Adds a data source to the dependency, referencing a stack value produced by the provided node.
+
+ The node producing the value.
+ The index of the stack value that was produced by the node.
+ The stack data source.
+
+
+
+ Represents a data source that refers to a variable value assigned by a node in a data flow graph.
+
+ The type of data stored in each data flow node.
+
+
+
+ Creates a new variable data source referencing a variable value assigned by the provided node.
+
+ The node assigning the value.
+ The variable that was assigned a value.
+
+
+
+ Gets the variable that was referenced by .
+
+
+
+
+
+
+
+
+
+
+ Represents a collection of data sources for a single variable dependency of a node.
+
+ The type of contents to put in a data flow node.
+
+
+
+ Creates a new variable dependency.
+
+ The variable to depend on.
+
+
+
+ Gets the variable that is depended upon.
+
+
+
+
+ Adds a data source to the dependency, referencing a variable value assigned by the provided node.
+
+ The node assigning the value.
+ The variable data source.
+
+
+
diff --git a/Echo/Echo.Platforms.AsmResolver.deps.json b/Echo/Echo.Platforms.AsmResolver.deps.json
new file mode 100644
index 0000000..e515b22
--- /dev/null
+++ b/Echo/Echo.Platforms.AsmResolver.deps.json
@@ -0,0 +1,339 @@
+{
+ "runtimeTarget": {
+ "name": ".NETStandard,Version=v2.0/",
+ "signature": ""
+ },
+ "compilationOptions": {},
+ "targets": {
+ ".NETStandard,Version=v2.0": {},
+ ".NETStandard,Version=v2.0/": {
+ "Echo.Platforms.AsmResolver/0.9.0-alpha.1": {
+ "dependencies": {
+ "AsmResolver.DotNet": "4.6.0",
+ "Echo.Concrete": "0.9.0-alpha.1",
+ "Echo.ControlFlow": "0.9.0-alpha.1",
+ "Echo.Core": "0.9.0-alpha.1",
+ "NETStandard.Library": "2.0.3"
+ },
+ "runtime": {
+ "Echo.Platforms.AsmResolver.dll": {}
+ }
+ },
+ "AsmResolver/4.6.0": {
+ "runtime": {
+ "lib/netstandard2.0/AsmResolver.dll": {
+ "assemblyVersion": "4.6.0.0",
+ "fileVersion": "4.6.0.0"
+ }
+ }
+ },
+ "AsmResolver.DotNet/4.6.0": {
+ "dependencies": {
+ "AsmResolver.PE": "4.6.0",
+ "System.Text.Json": "5.0.0"
+ },
+ "runtime": {
+ "lib/netstandard2.0/AsmResolver.DotNet.dll": {
+ "assemblyVersion": "4.6.0.0",
+ "fileVersion": "4.6.0.0"
+ }
+ }
+ },
+ "AsmResolver.PE/4.6.0": {
+ "dependencies": {
+ "AsmResolver.PE.File": "4.6.0"
+ },
+ "runtime": {
+ "lib/netstandard2.0/AsmResolver.PE.dll": {
+ "assemblyVersion": "4.6.0.0",
+ "fileVersion": "4.6.0.0"
+ }
+ }
+ },
+ "AsmResolver.PE.File/4.6.0": {
+ "dependencies": {
+ "AsmResolver": "4.6.0"
+ },
+ "runtime": {
+ "lib/netstandard2.0/AsmResolver.PE.File.dll": {
+ "assemblyVersion": "4.6.0.0",
+ "fileVersion": "4.6.0.0"
+ }
+ }
+ },
+ "Microsoft.Bcl.AsyncInterfaces/5.0.0": {
+ "dependencies": {
+ "System.Threading.Tasks.Extensions": "4.5.4"
+ },
+ "runtime": {
+ "lib/netstandard2.0/Microsoft.Bcl.AsyncInterfaces.dll": {
+ "assemblyVersion": "5.0.0.0",
+ "fileVersion": "5.0.20.51904"
+ }
+ }
+ },
+ "Microsoft.NETCore.Platforms/1.1.0": {},
+ "NETStandard.Library/2.0.3": {
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.1.0"
+ }
+ },
+ "System.Buffers/4.5.1": {
+ "runtime": {
+ "lib/netstandard2.0/System.Buffers.dll": {
+ "assemblyVersion": "4.0.3.0",
+ "fileVersion": "4.6.28619.1"
+ }
+ }
+ },
+ "System.Collections.Immutable/1.7.1": {
+ "dependencies": {
+ "System.Memory": "4.5.4"
+ },
+ "runtime": {
+ "lib/netstandard2.0/System.Collections.Immutable.dll": {
+ "assemblyVersion": "1.2.5.0",
+ "fileVersion": "4.700.20.21406"
+ }
+ }
+ },
+ "System.Memory/4.5.4": {
+ "dependencies": {
+ "System.Buffers": "4.5.1",
+ "System.Numerics.Vectors": "4.5.0",
+ "System.Runtime.CompilerServices.Unsafe": "5.0.0"
+ },
+ "runtime": {
+ "lib/netstandard2.0/System.Memory.dll": {
+ "assemblyVersion": "4.0.1.1",
+ "fileVersion": "4.6.28619.1"
+ }
+ }
+ },
+ "System.Numerics.Vectors/4.5.0": {
+ "runtime": {
+ "lib/netstandard2.0/System.Numerics.Vectors.dll": {
+ "assemblyVersion": "4.1.4.0",
+ "fileVersion": "4.6.26515.6"
+ }
+ }
+ },
+ "System.Runtime.CompilerServices.Unsafe/5.0.0": {
+ "runtime": {
+ "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll": {
+ "assemblyVersion": "5.0.0.0",
+ "fileVersion": "5.0.20.51904"
+ }
+ }
+ },
+ "System.Text.Encodings.Web/5.0.0": {
+ "dependencies": {
+ "System.Memory": "4.5.4"
+ },
+ "runtime": {
+ "lib/netstandard2.0/System.Text.Encodings.Web.dll": {
+ "assemblyVersion": "5.0.0.0",
+ "fileVersion": "5.0.20.51904"
+ }
+ }
+ },
+ "System.Text.Json/5.0.0": {
+ "dependencies": {
+ "Microsoft.Bcl.AsyncInterfaces": "5.0.0",
+ "System.Buffers": "4.5.1",
+ "System.Memory": "4.5.4",
+ "System.Numerics.Vectors": "4.5.0",
+ "System.Runtime.CompilerServices.Unsafe": "5.0.0",
+ "System.Text.Encodings.Web": "5.0.0",
+ "System.Threading.Tasks.Extensions": "4.5.4"
+ },
+ "runtime": {
+ "lib/netstandard2.0/System.Text.Json.dll": {
+ "assemblyVersion": "5.0.0.0",
+ "fileVersion": "5.0.20.51904"
+ }
+ }
+ },
+ "System.Threading.Tasks.Extensions/4.5.4": {
+ "dependencies": {
+ "System.Runtime.CompilerServices.Unsafe": "5.0.0"
+ },
+ "runtime": {
+ "lib/netstandard2.0/System.Threading.Tasks.Extensions.dll": {
+ "assemblyVersion": "4.2.0.1",
+ "fileVersion": "4.6.28619.1"
+ }
+ }
+ },
+ "Echo.Concrete/0.9.0-alpha.1": {
+ "dependencies": {
+ "Echo.Core": "0.9.0-alpha.1",
+ "System.Memory": "4.5.4",
+ "System.Runtime.CompilerServices.Unsafe": "5.0.0"
+ },
+ "runtime": {
+ "Echo.Concrete.dll": {}
+ }
+ },
+ "Echo.ControlFlow/0.9.0-alpha.1": {
+ "dependencies": {
+ "Echo.Core": "0.9.0-alpha.1",
+ "Echo.DataFlow": "0.9.0-alpha.1",
+ "System.Memory": "4.5.4"
+ },
+ "runtime": {
+ "Echo.ControlFlow.dll": {}
+ }
+ },
+ "Echo.Core/0.9.0-alpha.1": {
+ "dependencies": {
+ "System.Memory": "4.5.4"
+ },
+ "runtime": {
+ "Echo.Core.dll": {}
+ }
+ },
+ "Echo.DataFlow/0.9.0-alpha.1": {
+ "dependencies": {
+ "Echo.Core": "0.9.0-alpha.1",
+ "System.Collections.Immutable": "1.7.1"
+ },
+ "runtime": {
+ "Echo.DataFlow.dll": {}
+ }
+ }
+ }
+ },
+ "libraries": {
+ "Echo.Platforms.AsmResolver/0.9.0-alpha.1": {
+ "type": "project",
+ "serviceable": false,
+ "sha512": ""
+ },
+ "AsmResolver/4.6.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-/rGykz817njDGi5wwEmetjfSMfBtmCe5zBkiU7XJK+H1DcygXjQcd9ODZJ4wCkhSL65tel2s3D+hLAbn8vXzVQ==",
+ "path": "asmresolver/4.6.0",
+ "hashPath": "asmresolver.4.6.0.nupkg.sha512"
+ },
+ "AsmResolver.DotNet/4.6.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-hiyKAIHrOurIVCN/H5IXFSLKtwqkky0+xjlvvntZLjM3Yk+jD/DpZ3qitRMjxQdW0bJ7sUp3gupOnlYHvlDa+A==",
+ "path": "asmresolver.dotnet/4.6.0",
+ "hashPath": "asmresolver.dotnet.4.6.0.nupkg.sha512"
+ },
+ "AsmResolver.PE/4.6.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-5E5oDWOkJNBTJ8815/lpG3hjif/3XgsX9UelCG8GYsyZbyVFdnAfr0KohgY2hYbrWrYi5vgOdL6mSAM8tH+cVg==",
+ "path": "asmresolver.pe/4.6.0",
+ "hashPath": "asmresolver.pe.4.6.0.nupkg.sha512"
+ },
+ "AsmResolver.PE.File/4.6.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-M8ytebaNAH+C8kGOyxhGhDoH0K3I2Pop0gr1YVP69/dRyUGnPRTDzcPX0cxVU0DA4mAXMxcs0cEIyui+WZAHOA==",
+ "path": "asmresolver.pe.file/4.6.0",
+ "hashPath": "asmresolver.pe.file.4.6.0.nupkg.sha512"
+ },
+ "Microsoft.Bcl.AsyncInterfaces/5.0.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
+ "path": "microsoft.bcl.asyncinterfaces/5.0.0",
+ "hashPath": "microsoft.bcl.asyncinterfaces.5.0.0.nupkg.sha512"
+ },
+ "Microsoft.NETCore.Platforms/1.1.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==",
+ "path": "microsoft.netcore.platforms/1.1.0",
+ "hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512"
+ },
+ "NETStandard.Library/2.0.3": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
+ "path": "netstandard.library/2.0.3",
+ "hashPath": "netstandard.library.2.0.3.nupkg.sha512"
+ },
+ "System.Buffers/4.5.1": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==",
+ "path": "system.buffers/4.5.1",
+ "hashPath": "system.buffers.4.5.1.nupkg.sha512"
+ },
+ "System.Collections.Immutable/1.7.1": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-B43Zsz5EfMwyEbnObwRxW5u85fzJma3lrDeGcSAV1qkhSRTNY5uXAByTn9h9ddNdhM+4/YoLc/CI43umjwIl9Q==",
+ "path": "system.collections.immutable/1.7.1",
+ "hashPath": "system.collections.immutable.1.7.1.nupkg.sha512"
+ },
+ "System.Memory/4.5.4": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==",
+ "path": "system.memory/4.5.4",
+ "hashPath": "system.memory.4.5.4.nupkg.sha512"
+ },
+ "System.Numerics.Vectors/4.5.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==",
+ "path": "system.numerics.vectors/4.5.0",
+ "hashPath": "system.numerics.vectors.4.5.0.nupkg.sha512"
+ },
+ "System.Runtime.CompilerServices.Unsafe/5.0.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA==",
+ "path": "system.runtime.compilerservices.unsafe/5.0.0",
+ "hashPath": "system.runtime.compilerservices.unsafe.5.0.0.nupkg.sha512"
+ },
+ "System.Text.Encodings.Web/5.0.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-EEslUvHKll1ftizbn20mX3Ix/l4Ygk/bdJ2LY6/X6FlGaP0RIhKMo9nS6JIGnKKT6KBP2PGj6JC3B9/ZF6ErqQ==",
+ "path": "system.text.encodings.web/5.0.0",
+ "hashPath": "system.text.encodings.web.5.0.0.nupkg.sha512"
+ },
+ "System.Text.Json/5.0.0": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-+luxMQNZ2WqeffBU7Ml6njIvxc8169NW2oU+ygNudXQGZiarjE7DOtN7bILiQjTZjkmwwRZGTtLzmdrSI/Ustw==",
+ "path": "system.text.json/5.0.0",
+ "hashPath": "system.text.json.5.0.0.nupkg.sha512"
+ },
+ "System.Threading.Tasks.Extensions/4.5.4": {
+ "type": "package",
+ "serviceable": true,
+ "sha512": "sha512-zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
+ "path": "system.threading.tasks.extensions/4.5.4",
+ "hashPath": "system.threading.tasks.extensions.4.5.4.nupkg.sha512"
+ },
+ "Echo.Concrete/0.9.0-alpha.1": {
+ "type": "project",
+ "serviceable": false,
+ "sha512": ""
+ },
+ "Echo.ControlFlow/0.9.0-alpha.1": {
+ "type": "project",
+ "serviceable": false,
+ "sha512": ""
+ },
+ "Echo.Core/0.9.0-alpha.1": {
+ "type": "project",
+ "serviceable": false,
+ "sha512": ""
+ },
+ "Echo.DataFlow/0.9.0-alpha.1": {
+ "type": "project",
+ "serviceable": false,
+ "sha512": ""
+ }
+ }
+}
\ No newline at end of file
diff --git a/Echo/Echo.Platforms.AsmResolver.dll b/Echo/Echo.Platforms.AsmResolver.dll
new file mode 100644
index 0000000..6ad83db
Binary files /dev/null and b/Echo/Echo.Platforms.AsmResolver.dll differ
diff --git a/Echo/Echo.Platforms.AsmResolver.xml b/Echo/Echo.Platforms.AsmResolver.xml
new file mode 100644
index 0000000..46f330c
--- /dev/null
+++ b/Echo/Echo.Platforms.AsmResolver.xml
@@ -0,0 +1,3910 @@
+
+
+
+ Echo.Platforms.AsmResolver
+
+
+
+
+ Provides extension methods to AsmResolver models.
+
+
+
+
+ Converts an instance of to an .
+
+ The handler to convert.
+ The converted handler.
+
+
+
+ Converts a collection of instances to a collection of
+ instances.
+
+ The handlers to convert.
+ The converted handlers.
+
+
+
+ Constructs a control flow graph from a CIL method body.
+
+ The method body.
+ The control flow graph.
+
+
+
+ Constructs a control flow graph and a data flow graph from a CIL method body.
+
+ The method body.
+ The constructed data flow graph.
+ The control flow graph.
+
+
+
+ Provides a description of the CIL instruction set architecture (ISA) that is modelled by AsmResolver.
+
+
+
+
+ Creates a new CIL architecture description based on a CIL method body.
+
+ The method body.
+
+
+
+ Gets the method body that was encapsulated.
+
+
+
+
+ Gets the default static successor resolution engine for this architecture.
+
+
+
+
+ Gets the Echo symbol for the provided instance.
+
+ The local variable.
+ The Echo symbol representing the local variable.
+
+
+
+ Gets the Echo symbol for the provided instance.
+
+ The parameter.
+ The Echo symbol representing the parameter.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a custom formatter for s.
+
+
+
+
+
+
+
+ Represents a parameter that is declared and can be referenced within a CIL method.
+
+
+
+
+ Creates a new CIL parameter.
+
+ The underlying parameter
+
+
+
+ Gets the underlying parameter object.
+
+
+
+
+
+
+
+
+
+
+ Provides an implementation for the interface that determines
+ whether CIL instructions are considered pure or have side effects.
+
+
+
+
+ Creates a new instance of the class.
+
+
+
+
+ Gets or sets a value indicating whether writes to local variables should be considered pure or not.
+
+
+
+
+ Gets or sets a value indicating whether writes to arrays should be considered pure or not.
+
+
+
+
+ Gets or sets a value indicating whether writes to pointers should be considered pure or not.
+
+
+
+
+ Gets or sets a value indicating whether field read accesses should be considered pure or not by default.
+
+
+
+
+ Gets or sets a value indicating whether writes to field should be considered pure or not by default.
+
+
+
+
+ Gets or sets a value indicating whether method accesses (e.g. reading method pointers) should be
+ considered pure or not by default.
+
+
+
+
+ Gets or sets a value indicating whether method calls should be considered pure or not by default.
+
+
+
+
+ Gets or sets a value indicating whether indirect method calls should be considered pure or not by default.
+
+
+
+
+ Gets or sets a value indicating whether type access (e.g. pushing type tokens) should be considered pure
+ or not by default.
+
+
+
+
+ Gets a mutable collection of known methods that should be considered pure.
+
+
+
+
+ Gets a mutable collection of known methods that should be considered impure and guaranteed have side-effects.
+
+
+
+
+
+
+
+ Provides an implementation of a state transition resolver for the CIL instruction set.
+
+
+
+
+ Creates a new instance of the class.
+
+ The CIL architecture variant to compute state transitions for.
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides an implementation of
+
+
+
+
+ Gets a reusable singleton instance of the static successor resolver for the CIL architecture.
+
+
+
+
+
+
+
+
+
+
+ Represents a variable that is declared and can be referenced within a CIL method body.
+
+
+
+
+ Creates a new CIL variable.
+
+ The underlying variable object.
+
+
+
+ Gets the underlying local variable object.
+
+
+
+
+
+
+
+
+
+
+ Provides a context for executing instructions within a virtual machine.
+
+
+
+
+ Creates a new instance of the class.
+
+ The object providing additional services to the emulator.
+ The current state of the program.
+ The cancellation token to use for cancelling the execution.
+
+
+
+ Gets the current state of the program.
+
+
+
+
+ Gets the cancellation token to use for cancelling the execution.
+
+
+
+
+ Gets or sets a value indicating the execution should terminate.
+
+
+
+
+ Gets the final result of the execution of the program.
+
+
+
+
+
+
+
+ Gets the service object of the specified type.
+
+ The type of the service.
+ The service object.
+
+
+
+ Represents a snapshot of the state of the program in a particular point of execution of a CIL method body.
+
+
+
+
+ Creates a new empty instance of the class.
+
+
+
+
+ Gets the offset to the current instruction to be executed.
+
+
+
+
+ Gets the current state of the evaluation stack.
+
+
+
+
+ Gets the current state of all variables defined in the method body.
+
+
+
+
+ Provides an implementation of a variable state in a CIL environment, that initially assigns for every
+ variable a default value using an instance of the interface.
+
+
+
+
+ Creates a new variable state snapshot, using the provided default value.
+
+ The factory responsible for creating the default value for all variables.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a dispatcher based implementation for a virtual machine, capable of emulating a single managed method
+ body implemented using the CIL instruction set.
+
+
+
+
+
+
+
+ Creates a new instance of the .
+
+ The method body to emulate.
+ Indicates whether the virtual machine should run in 32-bit mode or in 64-bit mode.
+
+
+
+ Creates a new instance of the .
+
+ The module in which the CIL runs in.
+ The instructions to emulate..
+ Indicates whether the virtual machine should run in 32-bit mode or in 64-bit mode.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Gets or sets the dispatcher used for the execution of instructions.
+
+
+
+
+
+
+
+ Invoked when the execution of the virtual machine is terminated.
+
+ The arguments describing the event.
+
+
+
+
+
+
+ Provides arguments for describing an event that fires after an instruction was dispatched and executed.
+
+
+
+
+ Creates a new instance of the class.
+
+ The context in which the instruction was executed.
+ The instruction that was executed.
+ The produced result.
+
+
+
+ Gets the result that was produced after dispatching.
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a base handler for instructions with any variant of the operation codes.
+
+
+
+
+
+
+
+ Obtains the value in the array using the provided operation code.
+
+ The context in which the instruction is being executed in.
+ The instruction that is being executed.
+ The array to get the element from.
+ The index of the element to get.
+ The value.
+
+
+
+ Creates a fully unknown value that was read from the array.
+
+ The context in which the instruction is being executed in.
+ The instruction that is being executed.
+ The value.
+
+ This method is called when either the array or the index of the requested element is not fully known.
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a base handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a base handler for instructions with any variant of the operation codes.
+
+
+
+
+
+
+
+ Stores an element in the provided array using the instruction's operation code.
+
+ The execution context the instruction is being executed in.
+ The instruction that is being executed.
+ The array to store the value in.
+ The index to store the element at.
+ The value of the element.
+
+
+
+ Provides a base handler for instructions with one of the macro operation codes.
+
+
+
+
+
+
+
+
+
+
+ Provides arguments for describing an event that fires before an instruction is dispatched and executed.
+
+
+
+
+ Creates a new instance of the class.
+
+ The context in which the instruction is being executed.
+ The instruction that is being executed.
+
+
+
+ Gets or sets a value indicating whether the instruction is handled and should not be dispatched to the
+ default operation handler.
+
+
+ When this property is set to true, the property will be used as the
+ final emulation result.
+
+
+
+
+ Gets or sets the dispatch result when this instruction is handled externally.
+
+
+ This value is ignored when the property is set to false.
+
+
+
+
+ Provides a default implementation for a CIL operation code handler dispatcher.
+
+
+
+
+
+
+
+
+
+
+ Creates a new CIL dispatcher using the handlers defined in the current module.
+
+
+
+
+ Creates a new CIL dispatcher using the handlers defined in the provided module.
+
+
+
+
+ Gets the used dispatcher table.
+
+
+
+
+
+
+
+ Obtains the operation code handler for the provided instruction.
+
+ The instruction to get the handler for.
+ The operation code handler.
+ Occurs when the instruction is invalid or unsupported.
+
+
+
+ Invoked when an instruction is about to be dispatched.
+
+ The arguments describing the event.
+
+
+
+ Invoked when an instruction is about to be dispatched.
+
+ The arguments describing the event.
+
+
+
+ Provides a handler for instructions with any variant of the operation codes.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the and
+ operation codes.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the , ,
+ , or operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the , ,
+ , or operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a base for all branching operation codes that pop two arguments from the stack.
+
+
+
+
+
+
+
+
+
+
+ Determines whether the branch condition has been met, based on two integer values.
+
+ The context in which the instruction is being executed in.
+ The instruction that is being executed.
+ The left operand of the comparison.
+ The right operand of the comparison.
+ true if the branch should be taken, false if not, and
+ if the conclusion is unknown.
+
+
+
+ Determines whether the branch condition has been met, based on two floating point values.
+
+ The context in which the instruction is being executed in.
+ The instruction that is being executed.
+ The left operand of the comparison.
+ The right operand of the comparison.
+ true if the branch should be taken, false if not, and
+ if the conclusion is unknown.
+
+
+
+ Determines whether the branch condition has been met, based on two object references.
+
+ The context in which the instruction is being executed in.
+ The instruction that is being executed.
+ The left operand of the comparison.
+ The right operand of the comparison.
+ true if the branch should be taken, false if not, and
+ if the conclusion is unknown.
+
+
+
+ Provides a handler for instructions with the , ,
+ , or operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the , ,
+ , or operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the and
+ operation codes.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the and
+ operation codes.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a base for all branching operation codes.
+
+
+
+
+
+
+
+ Gets the number of arguments the branch pops from the stack.
+
+
+
+
+
+
+
+ Determines whether the branch condition has been met.
+
+ The context in which the instruction is being executed in.
+ The instruction that is being executed.
+ true if the branch should be taken, false if not, and
+ if the conclusion is unknown.
+
+
+
+ Provides a handler for instructions with the and
+ operation codes.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the and
+ operation codes.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a base for all handlers that target fallthrough operation codes.
+
+
+
+
+
+
+
+
+
+
+ Provides members for dispatching instructions for a certain architecture.
+
+
+
+
+ Represents the event that is fired before an instruction is dispatched to an operation code handler.
+
+
+
+
+ Represents the event that is fired after an instruction is dispatched and executed.
+
+
+
+
+ Dispatches the provided instruction to an operation code handler.
+
+ The context to execute the instruction in.
+ The instruction to evaluate.
+ The dispatch result.
+
+
+
+ Represents an operation code handler executing an instruction in a virtual machine.
+
+
+
+
+ Gets a collection of operation codes that are supported by this handler.
+
+
+
+
+ Executes an instruction in the provided context.
+
+ The context to execute the instruction in.
+ The instruction to execute.
+ A result.
+
+
+
+ Provides arguments for describing events related to instruction dispatch.
+
+
+
+
+ Creates a new instance of the class.
+
+ The context in which the instruction is executed.
+ The instruction to execute.
+
+
+
+ Gets the context in which the instruction is or was executed.
+
+
+
+
+ Gets the instruction that was executed or to execute.
+
+
+
+
+ Provides a handler for instructions with the CKFINITE operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the DUP operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the NOP operation code.
+
+
+
+
+
+
+
+ Provides a handler for instructions with the POP operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a base for operation code handlers that call procedures outside of the method body.
+
+
+
+
+
+
+
+ Devirtualizes the method referenced by the provided instruction, and infers the actual method
+ implementing the referenced method that was called.
+
+ The call instruction.
+ The arguments of the method call.
+ The result of the devirtualization process.
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides information about the result of a method devirtualization process.
+
+
+
+
+ Creates a new successful method devirtualization result.
+
+ The resolved method.
+
+
+
+ Creates a new successful method devirtualization result.
+
+ The resolved Method Signature.
+
+
+
+ Creates a new unsuccessful method devirtualization result.
+
+ The exception that occurred during the method devirtualization.
+
+
+
+ When successful, gets the resulting devirtualized method.
+
+
+
+
+ When successful, gets the resulting devirtualized method signature.
+
+
+
+
+ When unsuccessful, gets the exception thrown during the devirtualization process.
+
+
+
+
+ Gets a value indicating whether the devirtualization process of the referenced method was successful.
+
+
+
+
+ Gets a value indicating whether the devirtualization process could not be completed due to an unknown
+ object that was dereferenced.
+
+
+
+
+ Gets the method signature of the method that was resolved.
+
+ The signature.
+ Occurs when the dispatch was unsuccessful.
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handle for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a base for all binary numeric operation codes.
+
+
+ Handlers that inherit from this class evaluate instructions with two operands and follow table III.1.2 in
+ the ECMA-335, 6th edition (June 2012).
+
+
+
+
+
+
+
+
+
+
+ Performs the operation on the two pushed floating point values.
+
+ The context to execute the instruction in.
+ The instruction that is being executed.
+ The left side of the operation.
+ The right side of the operation.
+ The result of the operation.
+
+
+
+ Performs the operation on the two pushed integers.
+
+ The context to execute the instruction in.
+ /// The instruction that is being executed.
+ The left side of the operation.
+ The right side of the operation.
+ The result of the operation.
+
+
+
+ Performs the operation on the two pushed object references.
+
+ The context to execute the instruction in.
+ /// The instruction that is being executed.
+ The left side of the operation.
+ The right side of the operation.
+ The result of the operation.
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the or
+ operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the or
+ operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a base for all comparison operation codes.
+
+
+
+
+ Converts the provided trilean to an I4 stack value, pushes it onto the stack and returns the success
+ dispatcher result.
+
+ The current execution context.
+ The trilean value.
+ The dispatch result.
+
+
+
+ Provides a handler for instructions with any variant of the Conv operation codes.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a base for all integer shift operation codes.
+
+
+ Handlers that inherit from this class evaluate instructions with two operands and follow table III.1.6 in
+ the ECMA-335, 6th edition (June 2012).
+
+
+
+
+
+
+
+
+
+
+ Performs the operation on the two pushed integers.
+
+ The context to execute the instruction in.
+ The instruction that is being executed.
+ The pushed integer value to shift
+ The amount to shift the value with.
+ The result of the operation.
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the and
+ operation codes.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a base for all unary numeric operation codes.
+
+
+ Handlers that inherit from this class evaluate instructions with two operands and follow table III.1.3 in
+ the ECMA-335, 6th edition (June 2012).
+
+
+
+
+
+
+
+
+
+
+ Performs the operation on the pushed floating point value.
+
+ The context to execute the instruction in.
+ The pushed value to perform the operation on.
+ The result of the operation.
+
+
+
+ Performs the operation on the pushed integer value.
+
+ The context to execute the instruction in.
+ The pushed value to perform the operation on.
+ The result of the operation.
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with a variation of the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with a variation of the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with one of the LDIND operation codes.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with a variation of the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with one of the STIND operation codes.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with a variation of the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with a variation of the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with a variation of the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with a variation of the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides a handler for instructions with a variation of the operation code.
+
+
+
+
+
+
+
+
+
+
+ Provides members for describing an environment that a .NET virtual machine runs in.
+
+
+
+
+ Gets the architecture description of the instructions to execute.
+
+
+
+
+ Gets a value indicating whether the virtual machine runs in 32-bit mode or in 64-bit mode.
+
+
+
+
+ Gets the module that this execution context is part of.
+
+
+
+
+ Gets the object responsible for marshalling concrete values to values that can be put
+ on the evaluation stack and back.
+
+
+
+
+ Gets the object responsible for making calls to procedures outside of the method body.
+
+
+
+
+ Gets the object responsible for maintaining static fields within the virtual machine.
+
+
+
+
+ Gets the object responsible for constructing new virtual values.
+
+
+
+
+ Provides members for calling methods within a CIL virtual machine.
+
+
+
+
+ Invokes a method definition and returns the result.
+
+ The method to invoke.
+ The arguments passed onto the method.
+
+ The return value of the method, or null if the method returned .
+
+
+
+
+ Invokes a function pointer and returns the result.
+
+ The method pointer.
+ The method signature.
+ The arguments passed onto the method.
+
+ The return value of the method, or null if the method returned .
+
+
+
+
+ Provides an implementation for an that always returns an unknown value when the
+ called method is non-void.
+
+
+
+
+ Creates a new instance of the class.
+
+ The factory responsible for constructing the unknown values.
+
+
+
+ Gets the factory that is responsible for constructing the unknown values.
+
+
+
+
+
+
+
+
+
+
+ Creates the return value of a method signature.
+
+ Method Signature
+
+
+
+
+ Provides an adapter for static fields represented by a to an instance
+ of the interface.
+
+
+
+
+ Creates a new instance of the class.
+
+ The field to encapsulate
+
+
+
+
+
+
+ Gets the static field that was encapsulated.
+
+
+
+
+ Gets or sets the value assigned to the static field.
+
+
+
+
+
+
+
+ Provides a mechanism for creating and storing static fields within an instance of a .NET virtual machine.
+
+
+
+
+ Creates a new instance of the class.
+
+ The factory responsible for creating unknown values.
+
+
+
+ Gets or creates an instance of a static field.
+
+ The field to encapsulate.
+ The static field.
+
+
+
+ Provides members for describing all different types of values that can be stored
+ on the evaluation stack of the Common Language Infrstructure (CLI).
+
+
+
+
+ Indicates the value is a 32 bit integer.
+
+
+
+
+ Indicates the value is a 64 bit integer.
+
+
+
+
+ Indicates the value is a native integer.
+
+
+
+
+ Indicates the value is a floating point number type F.
+
+
+
+
+ Indicates the value is an object reference type O.
+
+
+
+
+ Indicates the value is a managed pointer type &.
+
+
+
+
+ Indicates the value is an unmanaged pointer type *.
+
+
+
+
+ Indicates the value is a custom structure.
+
+
+
+
+ Represents a floating point numerical value on the evaluation stack of the Common Language Infrastructure (CLI).
+
+
+
+
+ Creates a new fully known concrete floating point numerical value.
+
+ The raw 64 bit value.
+
+
+
+
+
+
+ Determines whether the floating point value is considered greater than the provided floating point value.
+
+ The other floating point value.
+ Determines the return value when one of the values is NaN.
+ true if the current value is greater than the provided value, false otherwise.
+
+
+
+ Determines whether the floating point value is considered less than the provided floating point value.
+
+ The other floating point value.
+ Determines the return value when one of the values is NaN.
+ true if the current value is less than the provided value, false otherwise.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a 32 bit integer value on the evaluation stack of the Common Language Infrastructure (CLI).
+
+
+
+
+ Creates a new, fully known concrete 32 bit integral value.
+
+ The raw 32 bit value.
+
+
+
+ Creates a new, partially known concrete 32 bit integral value.
+
+ The raw 32 bit value.
+ The bit mask indicating the bits that are known.
+
+
+
+ Parses a (partially) known bit string into an 32 bit integer.
+
+ The bit string to parse.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a 64 bit integer value on the evaluation stack of the Common Language Infrastructure (CLI).
+
+
+
+
+ Creates a new, fully known concrete 64 bit integral value.
+
+ The raw 32 bit value.
+
+
+
+ Creates a new, partially known concrete 64 bit integral value.
+
+ The raw 32 bit value.
+ The bit mask indicating the bits that are known.
+
+
+
+ Parses a (partially) known bit string into an 64 bit integer.
+
+ The bit string to parse.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a value on the evaluation stack of the Common Language Infrastructure (CLI).
+
+
+
+
+ Gets the CLI type classification of the value.
+
+
+
+
+ Interprets the bits stored in the value as a signed native integer.
+
+ Determines whether the native integer is 32 bits or 64 bits wide.
+ The signed native integer.
+
+ Occurs when the size of the CLI value is too small for it to be interpretable as a native integer.
+
+
+ When this CLI value is already a native integer, the same instance is returned.
+
+
+
+
+ Interprets the bits stored in the value as an unsigned native integer.
+
+ Determines whether the native integer is 32 bits or 64 bits wide.
+ The signed native integer.
+
+ Occurs when the size of the CLI value is too small for it to be interpretable as a native integer.
+
+
+ When this CLI value is already a native integer, the same instance is returned.
+
+
+
+
+ Interprets the bits stored in the value as a signed 8 bit integer.
+
+ The signed 8 bit integer.
+
+ Occurs when the size of the CLI value is too small for it to be interpretable as an 8 bit integer.
+
+
+ When this CLI value is already an 8 bit integer, the same instance is returned.
+
+
+
+
+ Interprets the bits stored in the value as an unsigned 8 bit integer.
+
+ The unsigned 8 bit integer.
+
+ Occurs when the size of the CLI value is too small for it to be interpretable as an 8 bit integer.
+
+
+ When this CLI value is already an 8 bit integer, the same instance is returned.
+
+
+
+
+ Interprets the bits stored in the value as a signed 16 bit integer.
+
+ The signed 16 bit integer.
+
+ Occurs when the size of the CLI value is too small for it to be interpretable as a 16 bit integer.
+
+
+ When this CLI value is already a 16 bit integer, the same instance is returned.
+
+
+
+
+ Interprets the bits stored in the value as an unsigned 16 bit integer.
+
+ The unsigned 16 bit integer.
+
+ Occurs when the size of the CLI value is too small for it to be interpretable as a 16 bit integer.
+
+
+ When this CLI value is already a 16 bit integer, the same instance is returned.
+
+
+
+
+ Interprets the bits stored in the value as a signed 32 bit integer.
+
+ The signed 32 bit integer.
+
+ Occurs when the size of the CLI value is too small for it to be interpretable as a 32 bit integer.
+
+
+ When this CLI value is already a 32 bit integer, the same instance is returned.
+
+
+
+
+ Interprets the bits stored in the value as an unsigned 32 bit integer.
+
+ The unsigned 32 bit integer.
+
+ Occurs when the size of the CLI value is too small for it to be interpretable as a 32 bit integer.
+
+
+ When this CLI value is already a 32 bit integer, the same instance is returned.
+
+
+
+
+ Interprets the bits stored in the value as a signed 64 bit integer.
+
+ The signed 64 bit integer.
+
+ Occurs when the size of the CLI value is too small for it to be interpretable as a 64 bit integer.
+
+
+ When this CLI value is already a 64 bit integer, the same instance is returned.
+
+
+
+
+ Interprets the bits stored in the value as a 32 bit floating point number.
+
+ The 32 bit floating point number.
+
+ Occurs when the size of the CLI value is too small for it to be interpretable as a 32 bit floating point number.
+
+
+ When this CLI value is already a 32 bit floating point number, the same instance is returned.
+
+
+
+
+ Interprets the bits stored in the value as a 64 bit floating point number.
+
+ The 64 floating point number.
+
+ Occurs when the size of the CLI value is too small for it to be interpretable as a 64 bit floating point number.
+
+
+ When this CLI value is already a 64 bit floating point number, the same instance is returned.
+
+
+
+
+ Interprets the bits stored in the value as an object reference.
+
+ Indicates whether the reference to the object should be 32 bits or 64 bits wide.
+ The object reference.
+
+ Occurs when the size of the CLI value is too small for it to be interpretable as an object reference.
+
+
+ When this CLI value is already an object reference, the same instance is returned.
+
+
+
+
+ Converts the CLI value to a signed native integer.
+
+ Indicates whether the native integer should be 32 bits or 64 bits wide.
+ Indicates whether the value to convert should be treated as an unsigned number or not.
+ Indicates the conversion resulted in an overflow.
+ The converted value.
+
+
+
+ Converts the CLI value to an unsigned native integer.
+
+ Indicates whether the native integer should be 32 bits or 64 bits wide.
+ Indicates whether the value to convert should be treated as an unsigned number or not.
+ Indicates the conversion resulted in an overflow.
+ The converted value.
+
+
+
+ Converts the CLI value to a signed 8 bit integer.
+
+ Indicates whether the value to convert should be treated as an unsigned number or not.
+ Indicates the conversion resulted in an overflow.
+ The converted value.
+
+
+
+ Converts the CLI value to a signed 8 bit integer.
+
+ Indicates whether the value to convert should be treated as an unsigned number or not.
+ Indicates the conversion resulted in an overflow.
+ The converted value.
+
+
+
+ Converts the CLI value to a signed 16 bit integer.
+
+ Indicates whether the value to convert should be treated as an unsigned number or not.
+ Indicates the conversion resulted in an overflow.
+ The converted value.
+
+
+
+ Converts the CLI value to a signed 16 bit integer.
+
+ Indicates whether the value to convert should be treated as an unsigned number or not.
+ Indicates the conversion resulted in an overflow.
+ The converted value.
+
+
+
+ Converts the CLI value to a signed 32 bit integer.
+
+ Indicates whether the value to convert should be treated as an unsigned number or not.
+ Indicates the conversion resulted in an overflow.
+ The converted value.
+
+
+
+ Converts the CLI value to a signed 32 bit integer.
+
+ Indicates whether the value to convert should be treated as an unsigned number or not.
+ Indicates the conversion resulted in an overflow.
+ The converted value.
+
+
+
+ Converts the CLI value to a signed 64 bit integer.
+
+ Indicates whether the value to convert should be treated as an unsigned number or not.
+ Indicates the conversion resulted in an overflow.
+ The converted value.
+
+
+
+ Converts the CLI value to a signed 64 bit integer.
+
+ Indicates whether the value to convert should be treated as an unsigned number or not.
+ Indicates the conversion resulted in an overflow.
+ The converted value.
+
+
+
+ Converts the CLI value to a 32 bit floating point number.
+
+ The converted value.
+
+
+
+ Converts the CLI value to a 64 floating point number.
+
+ The converted value.
+
+
+
+ Interprets the CLI value as an unsigned integer and converts it to a native sized floating point number.
+
+ The converted value.
+
+
+
+ Represents a native integer that is either 32-bits or 64-bits long, depending on the architecture the program
+ is running on.
+
+
+
+
+ Creates a fully known native integer value.
+
+ The known integer value.
+ Indicates whether the integer should be resized to 32-bits or 64-bits.
+
+
+
+ Creates a partially known native integer value.
+
+ The integer value.
+ The bitmask indicating the known bits of .
+ Indicates whether the integer should be resized to 32-bits or 64-bits.
+
+
+
+ Parses a (partially) known bit string into an integer.
+
+ The bit string to parse.
+ Indicates whether the integer should be resized to 32-bits or 64-bits.
+
+
+
+ Converts the provided (partially) known integer value to a native integer.
+
+ The partially known integer value.
+ Indicates whether the integer should be resized to 32-bits or 64-bits.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ When the value is fully known, gets the raw integer value stored in this native integer as an int64.
+
+ The integer, sign extended to a 64 bit integer.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents an object reference on the evaluation stack of the Common Language Infrastructure (CLI).
+
+
+
+
+ Creates a new null object reference value.
+
+ Indicates whether the reference to the object is 32 or 64 bits wide.
+ The null reference.
+
+
+
+ Creates a new object reference value.
+
+ The referenced value.
+ Indicates whether the value is known.
+ Indicates whether the reference to the object is 32 or 64 bits wide.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a pointer on the evaluation stack of the Common Language Infrastructure (CLI).
+
+
+
+
+ Creates a new null pointer value.
+
+ Indicates whether the pointer is known.
+ Indicates the pointer is 32 or 64 bits wide.
+
+
+
+ Creates a new pointer value.
+
+ The base pointer value.
+ Indicates the pointer is 32 or 64 bits wide.
+
+
+
+ Creates a new pointer value.
+
+ The base pointer value.
+ The offset relative to the base pointer.
+ Indicates the pointer is 32 or 64 bits wide.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a structure on the evaluation stack of the Common Language Infrastructure (CLI).
+
+
+
+
+ Creates a new structure value.
+
+ The object responsible for memory management in the virtual machine.
+ The type of the object.
+ The raw contents of the structure.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a default implementation of the interface, which marshals concrete values
+ put into variables and fields within a .NET program to values on the evaluation stack of the CLI and vice versa.
+
+
+
+
+ Creates a new instance of the class.
+
+ The factory responsible for constructing concrete values.
+
+
+
+ Gets the factory responsible for constructing concrete values.
+
+
+
+
+
+
+
+
+
+
+ Converts the provided (partially) known 8 bit integer value to an I4 value.
+
+ The value to marshal.
+ Indicates whether the value is originally a signed or an unsigned integer.
+ The marshalled value.
+
+ This method implements the conversion rules for 8 bit integers to 32 bit integers as described in the
+ ECMA-335 III.1.1.1, and therefore sign extends the value when the integer is signed. This also holds when
+ the sign bit is marked unknown. In such a case, all the remaining 24 bits will be marked unknown.
+
+
+
+
+ Converts the provided (partially) known 16 bit integer value to an I4 value.
+
+ The value to marshal.
+ Indicates whether the value is originally a signed or an unsigned integer.
+ The marshalled value.
+
+ This method implements the conversion rules for 16 bit integers to 32 bit integers as described in the
+ ECMA-335 III.1.1.1, and therefore sign extends the value when the integer is signed. This also holds when
+ the sign bit is marked unknown. In such a case, all the remaining 16 bits will be marked unknown.
+
+
+
+
+ Converts the provided (partially) known boolean value to an I4 value.
+
+ The value to marshal.
+ The marshalled value.
+
+
+
+ Converts the provided (partially) known 32 bit integer value to an I4 value.
+
+ The value to marshal.
+ The marshalled value.
+
+
+
+ Converts the provided (partially) known 64 bit integer value to an I8 value.
+
+ The value to marshal.
+ The marshalled value.
+
+
+
+ Converts the provided (partially) known integer value to a native sized integer value.
+
+ The value to marshal.
+ The marshalled value.
+
+
+
+ Converts the provided (partially) known 32 bit floating point number to an F value.
+
+ The value to marshal.
+ The marshalled value.
+
+
+
+ Converts the provided (partially) known 64 bit floating point number to an F value.
+
+ The value to marshal.
+ The marshalled value.
+
+
+
+ Converts the provided value-typed object into a struct value.
+
+ The value to marshal.
+ The original type of the object.
+ The marshalled value.
+
+
+
+ Converts the provided object value to a type O object reference.
+
+ The value to marshal.
+ The marshalled value.
+
+
+
+ Converts the provided object value to a type O object reference.
+
+ The value to marshal.
+ The marshalled value.
+
+
+
+
+
+
+ Provides a default implementation of the interface.
+
+
+
+
+ Creates a new instance of the class.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a high level representation of a sequence of values.
+
+
+
+
+ Creates a new array value.
+
+ The object used to create default elements with.
+ The type of the elements stored in the array.
+ The number of elements stored in the array.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Gets the type of the elements stored int the array.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides a high level implementation of a structure that consists of a collection of fields.
+
+
+ This class is not meant to be used as an object reference. Instances of the
+ class are passed on by-value. They are used for representing instances of value
+ types, or the object referenced in an object reference, not the object reference itself.
+
+
+
+
+ Creates a new instance of a compound object.
+
+ The object responsible for creating instances of values in a field.
+ The type of the object.
+ Indicates whether the object should be initialized with zeroes.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides members for marshalling concrete values put into variables and fields within a .NET program to
+ values on the evaluation stack of the Common Language Infrastructure (CLI) and vice versa.
+
+
+
+
+ Gets a value indicating this marshaller assumes a 32 bit or a 64 bit architecture.
+
+
+
+
+ Wraps a concrete value into a CLI value.
+
+ The value to marshal.
+ The original type of the value as it is stored in a variable or field.
+ The CLI value.
+
+
+
+ Unwraps the CLI value into a concrete value that can be stored in a variable or field.
+
+ The CLI value to unpack.
+ The target type to marshal the value to.
+ The unpacked value.
+
+
+
+ Represents an array-like value that can be used in the context of executing CIL code.
+
+
+
+
+ Gets the length of the array structure.
+
+
+
+
+ Loads an element of a particular element type from the array.
+
+ The index of the element to read.
+ The marshaller to use for converting the raw value to a value the CLI operates on.
+ The type layout to read.
+ The element.
+
+
+
+ Loads an element of the array as a native sized integer.
+
+ The index of the element to read.
+ The marshaller to use for converting the raw value to a value the CLI operates on.
+ The element.
+
+
+
+ Loads an element of the array as a signed 8 bit integer.
+
+ The index of the element to read.
+ The marshaller to use for converting the raw value to a value the CLI operates on.
+ The element.
+
+
+
+ Loads an element of the array as a signed 16 bit integer.
+
+ The index of the element to read.
+ The marshaller to use for converting the raw value to a value the CLI operates on.
+ The element.
+
+
+
+ Loads an element of the array as a signed 32 bit integer.
+
+ The index of the element to read.
+ The marshaller to use for converting the raw value to a value the CLI operates on.
+ The element.
+
+
+
+ Loads an element of the array as a signed 64 bit integer.
+
+ The index of the element to read.
+ The marshaller to use for converting the raw value to a value the CLI operates on.
+ The element.
+
+
+
+ Loads an element of the array as an unsigned 8 bit integer.
+
+ The index of the element to read.
+ The marshaller to use for converting the raw value to a value the CLI operates on.
+ The element.
+
+
+
+ Loads an element of the array as an unsigned 16 bit integer.
+
+ The index of the element to read.
+ The marshaller to use for converting the raw value to a value the CLI operates on.
+ The element.
+
+
+
+ Loads an element of the array as an unsigned 32 bit integer.
+
+ The index of the element to read.
+ The marshaller to use for converting the raw value to a value the CLI operates on.
+ The element.
+
+
+
+ Loads an element of the array as a 32 bit floating point number.
+
+ The index of the element to read.
+ The marshaller to use for converting the raw value to a value the CLI operates on.
+ The element.
+
+
+
+ Loads an element of the array as a 64 bit floating point number.
+
+ The index of the element to read.
+ The marshaller to use for converting the raw value to a value the CLI operates on.
+ The element.
+
+
+
+ Loads an element of the array as an object reference.
+
+ The index of the element to read.
+ The marshaller to use for converting the raw value to a value the CLI operates on.
+ The element.
+
+
+
+ Replaces an element of a particular element type in the array.
+
+ The index of the element to read.
+ The value to replace the element with.
+ The marshaller to use for converting the raw value to a value the CLI operates on.
+ The type layout to write.
+
+
+
+ Replaces an element in the array with the provided native sized integer.
+
+ The index of the element to replace.
+ The value to replace the element with.
+ The marshaller to use for converting the raw value to a value the CTS operates on.
+
+
+
+ Replaces an element in the array with the provided signed 8 bit integer.
+
+ The index of the element to replace.
+ The value to replace the element with.
+ The marshaller to use for converting the raw value to a value the CTS operates on.
+
+
+
+ Replaces an element in the array with the provided signed 16 bit integer.
+
+ The index of the element to replace.
+ The value to replace the element with.
+ The marshaller to use for converting the raw value to a value the CTS operates on.
+
+
+
+ Replaces an element in the array with the provided signed 32 bit integer.
+
+ The index of the element to replace.
+ The value to replace the element with.
+ The marshaller to use for converting the raw value to a value the CTS operates on.
+
+
+
+ Replaces an element in the array with the provided signed 64 bit integer.
+
+ The index of the element to replace.
+ The value to replace the element with.
+ The marshaller to use for converting the raw value to a value the CTS operates on.
+
+
+
+ Replaces an element in the array with the provided unsigned 8 bit integer.
+
+ The index of the element to replace.
+ The value to replace the element with.
+ The marshaller to use for converting the raw value to a value the CTS operates on.
+
+
+
+ Replaces an element in the array with the provided unsigned 16 bit integer.
+
+ The index of the element to replace.
+ The value to replace the element with.
+ The marshaller to use for converting the raw value to a value the CTS operates on.
+
+
+
+ Replaces an element in the array with the provided unsigned 32 bit integer.
+
+ The index of the element to replace.
+ The value to replace the element with.
+ The marshaller to use for converting the raw value to a value the CTS operates on.
+
+
+
+ Replaces an element in the array with the provided 32 bit floating point number
+
+ The index of the element to replace.
+ The value to replace the element with.
+ The marshaller to use for converting the raw value to a value the CTS operates on.
+
+
+
+ Replaces an element in the array with the provided 64 bit floating point number.
+
+ The index of the element to replace.
+ The value to replace the element with.
+ The marshaller to use for converting the raw value to a value the CTS operates on.
+
+
+
+ Replaces an element in the array with the provided object reference.
+
+ The index of the element to replace.
+ The value to replace the element with.
+ The marshaller to use for converting the raw value to a value the CTS operates on.
+
+
+
+ Represents an object consisting of a collection of fields.
+
+
+
+
+ Gets the value of a field stored in the object.
+
+ The field to get the value from.
+ The field value.
+
+
+
+ Sets the value of a field stored in the object.
+
+ The field to set the value for.
+ The new value.
+
+
+
+ Provides members for describing a value in a managed .NET environment.
+
+
+
+
+ Gets the type of the value.
+
+
+
+
+ Provides factory members for constructing values by type.
+
+
+
+
+ Gets a value indicating whether a single pointer returned by this value factory is 32-bits or 64-bits wide.
+
+
+
+
+ Creates a value for the provided type that is optionally initialized with zeroes.
+
+ The type.
+ Indicates whether the bits in the created object should be initialized to zero.
+ The default value.
+
+
+
+ Creates an object reference to a value for the provided type that is optionally initialized with zeroes.
+
+ The type.
+ /// Indicates whether the bits in the created object should be initialized to zero.
+ The default value.
+
+
+
+ Allocates a chunk of addressable memory on the virtual heap, and returns a pointer value to the start of
+ the memory chunk.
+
+ The size of the region to allocate.
+ Indicates the memory region should be initialized with zeroes.
+ A pointer to the memory.
+
+
+
+ Allocates an array on the virtual heap.
+
+ The type of elements to store in the array.
+ The number of elements.
+ The array.
+
+
+
+ Allocates a structure.
+
+ The type of object to allocate.
+ Indicates the memory region should be initialized with zeroes.
+ The allocated object.
+
+
+
+ Gets the string value for the fully known string literal.
+
+ The string literal.
+ The string value.
+
+
+
+ Gets the raw memory layout of a type within the virtual machine.
+
+ The type.
+ The memory layout.
+
+
+
+ Represents a low level implementation of a structure.
+
+
+ This class is not meant to be used as an object reference. Instances of the
+ class are passed on by-value. They are used for representing instances of value
+ types, or the object referenced in an object reference, not the object reference itself.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Creates a new low level emulated object.
+
+ The object responsible for memory management in the virtual machine.
+ The type of the object.
+ The raw contents of the object.
+
+
+
+ Gets the value factory that was used to create this structure.
+
+
+
+
+ Indicates the value was constructed in a 32 or 64 bit environment.
+
+
+
+
+
+
+
+ Gets the raw data of the object.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides extension methods that allow for reading and writing .NET structures from a pointer value.
+
+
+
+
+ Reads a single .NET structure at the provided offset.
+
+ The base pointer value to read from.
+ The offset to start reading.
+ The memory allocator responsible for managing type layouts.
+ The type layout to read.
+ The read structure.
+
+ Occurs when the offset does not fall within the memory range.
+
+
+
+
+ Writes a single .NET structure at the provided offset.
+
+ The base pointer to write to.
+ The offset to start writing at.
+ The memory allocator responsible for managing type layouts.
+ The structure type to write.
+ The value to write.
+
+ Occurs when the offset does not fall within the memory range.
+
+
+
+
+ Represents an unicode string value.
+
+
+
+
+ Creates a new string value.
+
+ The string type signature.
+ The raw contents of the string.
+
+ Occurs when the memory block referenced by is of an invalid size.
+
+
+
+
+
+
+
+ Gets the number of characters stored in the string.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Gets a single character stored in the string.
+
+ The character index.
+ The character.
+
+
+
+ Gets the string representation of the (partially) known string.
+
+ The character used for indicating an unknown character in the string.
+ The string.
+
+
+
+
+
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..f288702
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..823145f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,33 @@
+# UnSealer
+- UnSealer Is Deobfuscator Written In C# And Using [AsmResolver](https://github.com/Washi1337/AsmResolver) To Read Assemblies.
+- UnSealer Is Open Sourced & Licensed Under GPLv3.
+
+# How To Use
+- `UnSealer.CLI.exe filepath -protectionid -protectionid`
+- Example Executing Confuser String Decrypter `UnSealer.CLI.exe unpackme.exe -cfexconst`
+
+# Compiling
+- Using `dotnet`
+```cmd
+dotnet restore
+dotnet build
+```
+- Using IDE (e.g. Visual Studio, Jetbrains Rider)
+- Open Solution.
+- Restore Nuget Packages.
+- Rebuild Solution.
+
+# Features
+- Devirualizing Code.
+- Decrypting Constants.
+- Fix Outlined Methods.
+- Fix Call Proxies.
+- Restoring Fields From Global Type without Module Corrupting.
+- And Many More in Future!
+
+# CLI-Preview
+
+
+# Credits
+- [AsmResolver](https://github.com/Washi1337/AsmResolver) - (Washi)
+- [Echo](https://github.com/Washi1337/Echo) - (Washi)
diff --git a/UnSealer.CLI/ConsoleLogger.cs b/UnSealer.CLI/ConsoleLogger.cs
new file mode 100644
index 0000000..6434bf9
--- /dev/null
+++ b/UnSealer.CLI/ConsoleLogger.cs
@@ -0,0 +1,31 @@
+
+#region Usings
+using Serilog;
+using Serilog.Core;
+using Serilog.Events;
+using Serilog.Sinks.SystemConsole.Themes;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.CLI {
+ public class ConsoleLogger : Core.ILogger {
+ private readonly Logger _logger = new LoggerConfiguration().WriteTo.Console(LogEventLevel.Verbose, "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}", null, null, null, AnsiConsoleTheme.Literate).CreateLogger();
+
+ public void Debug(string m)
+ => _logger.Debug(m);
+ public void DebugFormat(string m, params object[] f)
+ => _logger.Debug(m, f);
+ public void Error(string m)
+ => _logger.Error(m);
+ public void ErrorFormat(string m, params object[] f)
+ => _logger.Error(m, f);
+ public void Info(string m)
+ => _logger.Information(m);
+ public void InfoFormat(string m, params object[] f)
+ => _logger.Information(m, f);
+ public void Warn(string m)
+ => _logger.Warning(m);
+ public void WarnFormat(string m, params object[] f)
+ => _logger.Warning(m, f);
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.CLI/Program.cs b/UnSealer.CLI/Program.cs
new file mode 100644
index 0000000..3b1b65d
--- /dev/null
+++ b/UnSealer.CLI/Program.cs
@@ -0,0 +1,89 @@
+
+#region Usings
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using static UnSealer.Core.UnSealerEngine;
+using UnSealer.Core;
+using System.Diagnostics;
+#endregion
+
+namespace UnSealer.CLI
+{
+ internal class Program
+ {
+
+ private static ILogger ConsoleLogger = new ConsoleLogger();
+ private static IList Protections;
+
+ [SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "")]
+ static void Main(string[] args)
+ {
+ Console.Clear();
+ Console.Title = "UnSealer - v" + UnSealerVersion;
+ Console.SetWindowSize(83, 33);
+ Console.SetBufferSize(83, 9001);
+
+ Protections = PluginDiscovery.GetCurrentDirPlugins(ConsoleLogger);
+
+ Banner();
+ PrintUsage(Protections);
+
+ if (args.Length <= 0)
+ {
+ Console.Write("[~] Enter Arguments : ");
+ var pargs = Console.ReadLine()!.Replace("\"", string.Empty).Split(' ');
+ Console.Clear();
+ Banner();
+ var ParsedArgs = new ArgumentsParser(Protections, pargs).Result;
+ ExecuteEngine(ParsedArgs, ConsoleLogger);
+ }
+ else
+ {
+ var ArgsParsed = new ArgumentsParser(Protections, args).Result;
+ ExecuteEngine(ArgsParsed, ConsoleLogger);
+ }
+ }
+
+ ///
+ /// Print usage and loaded plugin's information
+ ///
+ /// Loaded plugins
+ internal static void PrintUsage(IList protections)
+ {
+ if (protections == null || protections.Count <= 0)
+ {
+ Console.ForegroundColor = ConsoleColor.DarkYellow;
+ Console.WriteLine($"No plugins found !{Environment.NewLine}");
+ Console.ForegroundColor = ConsoleColor.White;
+ return;
+ };
+
+ var processName = Process.GetCurrentProcess().ProcessName;
+
+ Console.ForegroundColor = ConsoleColor.Magenta;
+ Console.WriteLine("Usage:");
+ Console.ForegroundColor = ConsoleColor.Green;
+ Console.WriteLine($"{processName}.exe [your assembly full path] -{protections[0].Id}{Environment.NewLine}");
+
+ Console.ForegroundColor = ConsoleColor.Magenta;
+ Console.WriteLine("Plugin Loaded:");
+ Console.ForegroundColor = ConsoleColor.Green;
+
+ foreach (var protection in protections)
+ {
+ Console.WriteLine($"Option: -{protection.Id}");
+ Console.WriteLine($"\t{protection.Name} : {protection.Description} {Environment.NewLine}");
+ }
+
+ Console.ForegroundColor = ConsoleColor.White;
+ }
+
+ internal static void Banner()
+ {
+ Console.ForegroundColor = ConsoleColor.Blue;
+ Console.WriteLine("\r\n\r\n __ __ ____ __ \r\n / / / /__ / __/__ ___ _/ /__ ____\r\n / /_/ / _ \\_\\ \\/ -_) _ `/ / -_) __/\r\n \\____/_//_/___/\\__/\\_,_/_/\\__/_/ \r\n\r\n ");
+ Console.ForegroundColor = ConsoleColor.White;
+ }
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.CLI/UnSealer.CLI.csproj b/UnSealer.CLI/UnSealer.CLI.csproj
new file mode 100644
index 0000000..f95dbb3
--- /dev/null
+++ b/UnSealer.CLI/UnSealer.CLI.csproj
@@ -0,0 +1,17 @@
+
+
+
+ Exe
+ net5.0
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UnSealer.Core/ArgumentsParser.cs b/UnSealer.Core/ArgumentsParser.cs
new file mode 100644
index 0000000..904f614
--- /dev/null
+++ b/UnSealer.Core/ArgumentsParser.cs
@@ -0,0 +1,34 @@
+
+#region Usings
+using System;
+using System.Collections.Generic;
+using System.Linq;
+#endregion
+
+namespace UnSealer.Core {
+ public class ArgumentsParser {
+
+ #region Private Fields.
+ private string[] _args;
+ private IList _protections;
+ #endregion
+
+ public ArgumentsParserResult Result {
+ get => new() { Path = _args[0], Protections = _protections };
+ }
+ public ArgumentsParser(IList protections, string[] args) {
+ if (args.Length < 2) throw new Exception($"Arguments Must Be More Than {args.Length}.");
+ _args = args;
+ _protections = new List();
+ for (var i = 1; i < _args.Length; i++) {
+ Protection protection = protections.FirstOrDefault(x => x.Id == _args[i].Replace("-", ""));
+ if (protection != null)
+ _protections.Add(protection);
+ }
+ }
+ }
+ public struct ArgumentsParserResult {
+ public string Path { get; set; }
+ public IList Protections { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Core/Context.cs b/UnSealer.Core/Context.cs
new file mode 100644
index 0000000..8e02168
--- /dev/null
+++ b/UnSealer.Core/Context.cs
@@ -0,0 +1,63 @@
+
+#region Usings
+using System;
+using System.IO;
+using System.Reflection;
+using AsmResolver.DotNet;
+using AsmResolver.DotNet.Builder;
+#endregion
+
+namespace UnSealer.Core {
+ public class Context {
+ ///
+ /// Initialization Of Context.
+ ///
+ /// Module Path.
+ /// Logger Used In Context.
+ public Context(string path, ILogger logger) {
+ ModulePath = path;
+ Logger = logger;
+ try {
+ Module = ModuleDefinition.FromFile(ModulePath, new(Path.GetDirectoryName(ModulePath)));
+ Factory = new();
+ ImageBuilder = new(Factory);
+ Importer = new(Module);
+ Mscorlib = Module.CorLibTypeFactory.CorLibScope.GetAssembly().Resolve().ManifestModule;
+ }
+ catch (BadImageFormatException) {
+ Logger.ErrorFormat("{0} Is Not .NET File!", Path.GetFileNameWithoutExtension(ModulePath));
+ }
+ catch (Exception e) {
+ Logger.ErrorFormat("Error Happened While Loading Module : {0}", e.Message);
+ }
+ try {
+ var Stream = new MemoryStream();
+ var TempModule = ModuleDefinition.FromFile(ModulePath);
+ TempModule.IsILOnly = true;
+ TempModule.Write(Stream, new ManagedPEImageBuilder((MetadataBuilderFlags)0x1FFFF));
+ ReflectionCorlib = Assembly.Load(Stream.ToArray()).ManifestModule;
+ }
+ catch {
+ Logger.Warn("Corlib Reflection Module Can't Load.");
+ }
+ try {
+ ReflectionModule = Assembly.UnsafeLoadFrom(ModulePath).ManifestModule;
+ }
+ catch {
+ Logger.Warn("Reflection Module Can't Load.");
+ }
+ }
+ public ReferenceImporter Importer { get; }
+ public bool IsReflectionSafe => ReflectionModule != null;
+ public bool IsReflectionCorlibSafe => ReflectionCorlib != null;
+ public DotNetDirectoryFactory Factory { get; }
+ public ManagedPEImageBuilder ImageBuilder { get; }
+ public Pipeline Pipeline { get; set; }
+ public ModuleDefinition Module { get; set; }
+ public ModuleDefinition Mscorlib { get; }
+ public Module ReflectionModule { get; }
+ public Module ReflectionCorlib { get; }
+ public string ModulePath { get; }
+ public ILogger Logger { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Core/ILogger.cs b/UnSealer.Core/ILogger.cs
new file mode 100644
index 0000000..9903506
--- /dev/null
+++ b/UnSealer.Core/ILogger.cs
@@ -0,0 +1,48 @@
+namespace UnSealer.Core {
+ public interface ILogger {
+ ///
+ /// Normal Debug Message.
+ ///
+ /// Message.
+ void Debug(string m);
+ ///
+ /// Debug Formatted Message.
+ ///
+ /// Message.
+ /// Format Params.
+ void DebugFormat(string m, params object[] f);
+ ///
+ /// Normal Error Message.
+ ///
+ /// Message.
+ void Error(string m);
+ ///
+ /// Error Formatted Message.
+ ///
+ /// Message.
+ /// Format Params.
+ void ErrorFormat(string m, params object[] f);
+ ///
+ /// Normal Warn Message.
+ ///
+ /// Message.
+ void Warn(string m);
+ ///
+ /// Warn Formatted Message.
+ ///
+ /// Message.
+ /// Format Params.
+ void WarnFormat(string m, params object[] f);
+ ///
+ /// Normal Info Message.
+ ///
+ /// Message.
+ void Info(string m);
+ ///
+ /// Info Formatted Message.
+ ///
+ /// Message.
+ /// Format Params.
+ void InfoFormat(string m, params object[] f);
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Core/Pipeline.cs b/UnSealer.Core/Pipeline.cs
new file mode 100644
index 0000000..60e0044
--- /dev/null
+++ b/UnSealer.Core/Pipeline.cs
@@ -0,0 +1,71 @@
+
+#region Usings
+using System;
+using System.Collections.Generic;
+using AsmResolver.DotNet;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.Core {
+ public class Pipeline {
+ private Dictionary> _prestages;
+ private Dictionary> _poststages;
+ ///
+ /// Initialization Of Pipeline.
+ ///
+ public Pipeline() {
+ _prestages = new Dictionary>();
+ _poststages = new Dictionary>();
+ PipelineStage[] array = (PipelineStage[])Enum.GetValues(typeof(PipelineStage));
+ foreach (PipelineStage key in array)
+ {
+ _prestages[key] = new List();
+ _poststages[key] = new List();
+ }
+ }
+ ///
+ /// Insert Post ProtectionPhase() PipelineStage().
+ ///
+ /// PipelineStage That Get Added.
+ /// Phase Will Added Into Specified Stage.
+ public void InsertPostStage(PipelineStage Stage, ProtectionPhase ProtectionPhase)
+ => _poststages[Stage].Add(ProtectionPhase);
+ ///
+ /// Insert Pre ProtectionPhase() PipelineStage().
+ ///
+ /// PipelineStage That Get Added.
+ /// Phase Will Added Into Specified Stage.
+ public void InsertPreStage(PipelineStage Stage, ProtectionPhase ProtectionPhase)
+ => _prestages[Stage].Add(ProtectionPhase);
+ ///
+ /// Insert Post ProtectionPhases() PipelineStage().
+ ///
+ /// PipelineStage That Get Added.
+ /// Phases Will Added Into Specified Stage.
+ public void InsertPostStage(PipelineStage Stage, IEnumerable ProtectionsPhases)
+ => _poststages[Stage].AddRange(ProtectionsPhases);
+ ///
+ /// Insert Post ProtectionPhases() PipelineStage().
+ ///
+ /// PipelineStage That Get Added.
+ /// Phases Will Added Into Specified Stage.
+ public void InsertPreStage(PipelineStage Stage, IEnumerable ProtectionsPhases)
+ => _prestages[Stage].AddRange(ProtectionsPhases);
+ ///
+ /// Execute All Phases Stored Into PipelineStage().
+ ///
+ /// Stage That Get Executed.
+ /// MetadataMembers That Accessed In Phases.
+ /// Action Happen Between PreStages And PostStages.
+ /// Context.
+ public void ExecutePipeLineStage(PipelineStage Stage, IEnumerable Targets, Action Invoke, Context Context) {
+ var PreStages = _prestages[Stage].ToArray();
+ foreach (var Prephase in PreStages)
+ Prephase.Execute(Context, Prephase.PhaseTargets.Purify(Targets));
+ Invoke(Context);
+ var PostStages = _poststages[Stage].ToArray();
+ foreach (var PostPhase in PostStages)
+ PostPhase.Execute(Context, PostPhase.PhaseTargets.Purify(Targets));
+ }
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Core/PipelineStage.cs b/UnSealer.Core/PipelineStage.cs
new file mode 100644
index 0000000..2b4d22f
--- /dev/null
+++ b/UnSealer.Core/PipelineStage.cs
@@ -0,0 +1,20 @@
+namespace UnSealer.Core {
+ public enum PipelineStage {
+ ///
+ /// Expanding Module Stage.
+ ///
+ BeginModule,
+ ///
+ /// Processing Module Stage.
+ ///
+ ProcessModule,
+ ///
+ /// Optimizing Module Stage.
+ ///
+ OptimizeModule,
+ ///
+ /// Module Writing Stage.
+ ///
+ WriteModule
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Core/PluginDiscovery.cs b/UnSealer.Core/PluginDiscovery.cs
new file mode 100644
index 0000000..950600b
--- /dev/null
+++ b/UnSealer.Core/PluginDiscovery.cs
@@ -0,0 +1,36 @@
+
+#region Usings
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+#endregion
+
+namespace UnSealer.Core {
+ public static class PluginDiscovery {
+ public static IList GetCurrentDirPlugins(ILogger Logger)
+ {
+ var PluginsAsm = new List();
+ var files = Directory.GetFiles(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "*.dll");
+ foreach (string path in files.Where(x => !x.Contains("AsmResolver") && !x.Contains("Echo"))) /* Linq is Real Love. */ {
+ try {
+ var Plugin = Assembly.UnsafeLoadFrom(path);
+ PluginsAsm.Add(Plugin);
+ Logger.DebugFormat("Plugin Loaded {0}.",
+ Plugin.ManifestModule.Name);
+ }
+ catch { }
+ }
+ var LoadedProtections = new List();
+ foreach (var Plugin in PluginsAsm) {
+ foreach (var Type in Plugin.GetTypes().Where(_type => !_type.IsAbstract && typeof(Protection).IsAssignableFrom(_type))) {
+ LoadedProtections.Add(Activator.CreateInstance(Type) as Protection);
+ }
+ }
+ return LoadedProtections;
+ }
+ }
+}
diff --git a/UnSealer.Core/Protection.cs b/UnSealer.Core/Protection.cs
new file mode 100644
index 0000000..71167c5
--- /dev/null
+++ b/UnSealer.Core/Protection.cs
@@ -0,0 +1,26 @@
+namespace UnSealer.Core {
+ public abstract class Protection {
+ ///
+ /// Protection Name.
+ ///
+ public abstract string Name { get; }
+ ///
+ /// Protection Description.
+ ///
+ public abstract string Description { get; }
+ ///
+ /// Protection Id.
+ ///
+ public abstract string Id { get; }
+ ///
+ /// Author Of The Protection.
+ ///
+ public abstract string Author { get; }
+ ///
+ /// Pipeline Initialization.
+ ///
+ /// Context.
+ /// Pipeline Instance.
+ public abstract void InitPipeline(Context context, Pipeline pipeline);
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Core/ProtectionPhase.cs b/UnSealer.Core/ProtectionPhase.cs
new file mode 100644
index 0000000..c88909a
--- /dev/null
+++ b/UnSealer.Core/ProtectionPhase.cs
@@ -0,0 +1,37 @@
+
+#region Usings
+using AsmResolver.DotNet;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+#endregion
+
+namespace UnSealer.Core {
+ public abstract class ProtectionPhase {
+ ///
+ /// Base Protection Instance.
+ ///
+ public Protection Base { get; internal set; }
+ ///
+ /// Initialization Of ProtectionPhase.
+ ///
+ /// Protection Parent.
+ public ProtectionPhase(Protection ParentBase)
+ => Base = ParentBase;
+ ///
+ /// Phase Name.
+ ///
+ public abstract string Name { get; }
+ ///
+ /// Members Required For The Phase.
+ ///
+ public abstract ProtectionTargets PhaseTargets { get; }
+ ///
+ /// Execution Of The Phase.
+ ///
+ /// Context.
+ /// Targeted Members.
+ public abstract void Execute(Context context, IEnumerable targets);
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Core/ProtectionTargets.cs b/UnSealer.Core/ProtectionTargets.cs
new file mode 100644
index 0000000..e619270
--- /dev/null
+++ b/UnSealer.Core/ProtectionTargets.cs
@@ -0,0 +1,32 @@
+namespace UnSealer.Core {
+ public enum ProtectionTargets {
+ ///
+ /// Get No Members.
+ ///
+ None,
+ ///
+ /// Get All Type Members.
+ ///
+ Types,
+ ///
+ /// Get All Methods Members.
+ ///
+ Methods,
+ ///
+ /// Get All Fields Members.
+ ///
+ Fields,
+ ///
+ /// Get All Event Members.
+ ///
+ Events,
+ ///
+ /// Get All Property Members.
+ ///
+ Properties,
+ ///
+ /// Get All Members.
+ ///
+ AllDefinitions
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Core/UnSealer.Core.csproj b/UnSealer.Core/UnSealer.Core.csproj
new file mode 100644
index 0000000..a65356d
--- /dev/null
+++ b/UnSealer.Core/UnSealer.Core.csproj
@@ -0,0 +1,11 @@
+
+
+
+ net5.0
+
+
+
+
+
+
+
diff --git a/UnSealer.Core/UnSealerEngine.cs b/UnSealer.Core/UnSealerEngine.cs
new file mode 100644
index 0000000..09a019e
--- /dev/null
+++ b/UnSealer.Core/UnSealerEngine.cs
@@ -0,0 +1,60 @@
+
+#region Usings
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+#endregion
+
+namespace UnSealer.Core {
+ public static class UnSealerEngine {
+
+ public static readonly string UnSealerVersion = ((AssemblyFileVersionAttribute)typeof(UnSealerEngine).Assembly.GetCustomAttributes(typeof(AssemblyFileVersionAttribute), inherit: false)[0]).Version;
+
+ public static void ExecuteEngine(ArgumentsParserResult args, ILogger logger) {
+ IList protections = args.Protections;
+ Context context = new Context(args.Path, logger) {
+ Pipeline = new()
+ };
+ context.Logger.InfoFormat("Loaded {0} Protections", protections.Count);
+ context.Logger.InfoFormat("UnSealer v{0} (C) CLand - 2021", UnSealerVersion);
+ context.Logger.Info("Constructing Pipeline ...");
+ foreach (var Protection in protections) {
+ context.Logger.InfoFormat("Executing {0} Protection", Protection.Name);
+ Protection.InitPipeline(context, context.Pipeline);
+ }
+ RunPipelinePhase(context);
+ }
+
+ private static void RunPipelinePhase(Context Context) {
+ Context.Pipeline.ExecutePipeLineStage(PipelineStage.BeginModule,
+ Context.Module.GetDefs(),
+ new Action(BeginModule), Context);
+ Context.Pipeline.ExecutePipeLineStage(PipelineStage.ProcessModule,
+ Context.Module.GetDefs(),
+ new Action(ProcessModule), Context);
+ Context.Pipeline.ExecutePipeLineStage(PipelineStage.OptimizeModule,
+ Context.Module.GetDefs(),
+ new Action(OptimizeModule), Context);
+ Context.Pipeline.ExecutePipeLineStage(PipelineStage.WriteModule,
+ Context.Module.GetDefs(),
+ new Action(WriteModule), Context);
+ }
+
+ #region PipelineStages
+ private static void BeginModule(Context Context) {
+ foreach (var Type in Context.Module.GetAllTypes())
+ foreach (var Method in Type.Methods.Where(Method => Method.HasMethodBody))
+ Method.CilMethodBody.Instructions.ExpandMacros();
+ }
+ private static void ProcessModule(Context Context) { }
+ private static void OptimizeModule(Context Context) {
+ foreach (var Type in Context.Module.GetAllTypes())
+ foreach (var Method in Type.Methods.Where(Method => Method.HasMethodBody))
+ Method.CilMethodBody.Instructions.OptimizeMacros();
+ }
+ private static void WriteModule(Context Context)
+ => Context.Module.Write(Context.ModulePath.Insert(Context.ModulePath.Length - 4, "UnSealed"), Context.ImageBuilder);
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Core/Utilities.cs b/UnSealer.Core/Utilities.cs
new file mode 100644
index 0000000..f39d75d
--- /dev/null
+++ b/UnSealer.Core/Utilities.cs
@@ -0,0 +1,188 @@
+
+#region Usings
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Security.Cryptography;
+using AsmResolver.DotNet;
+using AsmResolver.DotNet.Code.Cil;
+using AsmResolver.DotNet.Signatures.Types;
+using AsmResolver.PE.DotNet.Cil;
+using AsmResolver.PE.DotNet.Metadata.Tables.Rows;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.Core
+{
+ public static class Utilities {
+ #region Extensions
+ public static IEnumerable GetBranches(this CilMethodBody body) {
+ var Branchs = new List();
+ var IL = body.Instructions;
+ foreach (var i in IL.Where(x => x.OpCode.OperandType == CilOperandType.InlineBrTarget || x.OpCode.OperandType == CilOperandType.InlineSwitch || x.OpCode.OperandType == CilOperandType.ShortInlineBrTarget)) {
+ if (i.OpCode.OperandType == CilOperandType.InlineSwitch)
+ Branchs.AddRange((i.Operand as IList).Select(x => IL.GetByOffset(x.Offset)));
+ else
+ Branchs.Add(IL.GetByOffset((i.Operand as ICilLabel).Offset));
+ }
+ foreach (var Handler in body.ExceptionHandlers) {
+ if (Handler.FilterStart != null) Branchs.Add(IL.GetByOffset(Handler.FilterStart.Offset));
+ if (Handler.HandlerEnd != null) Branchs.Add(IL.GetByOffset(Handler.HandlerEnd.Offset));
+ if (Handler.HandlerStart != null) Branchs.Add(IL.GetByOffset(Handler.HandlerStart.Offset));
+ if (Handler.TryEnd != null) Branchs.Add(IL.GetByOffset(Handler.TryEnd.Offset));
+ if (Handler.TryStart != null) Branchs.Add(IL.GetByOffset(Handler.TryStart.Offset));
+ }
+ return Branchs;
+ }
+ public static bool IsProxy(this MethodDefinition Method, out CilInstruction inlinemethod) {
+ inlinemethod = null;
+ if (!Method.HasMethodBody)
+ return false;
+ if (Method.CilMethodBody == null)
+ return false;
+ if (Method.CilMethodBody.Instructions.Count == 0)
+ return false;
+ var instructions = Method.CilMethodBody.Instructions;
+ int ParametersCount = Method.Signature.GetTotalParameterCount();
+ if (instructions.Count != ParametersCount + 2)
+ return false;
+ var InlineMethodInstr = instructions[ParametersCount];
+ if (InlineMethodInstr.IsCode(CilCode.Call) ||
+ InlineMethodInstr.IsCode(CilCode.Callvirt) ||
+ InlineMethodInstr.IsCode(CilCode.Newobj)) {
+ inlinemethod = InlineMethodInstr;
+ return true;
+ }
+ return false;
+ }
+ public static IEnumerable Purify(this ProtectionTargets NeededTargets, IEnumerable Targets)
+ => NeededTargets switch {
+ ProtectionTargets.None => null,
+ ProtectionTargets.AllDefinitions => Targets,
+ ProtectionTargets.Events => Targets.Where(Target => Target is EventDefinition),
+ ProtectionTargets.Fields => Targets.Where(Target => Target is IFieldDescriptor),
+ ProtectionTargets.Methods => Targets.Where(Target => Target is IMethodDefOrRef),
+ ProtectionTargets.Properties => Targets.Where(Target => Target is PropertyDefinition),
+ ProtectionTargets.Types => Targets.Where(Target => Target is ITypeDescriptor || Target is ITypeDefOrRef),
+ _ => throw new ArgumentOutOfRangeException(nameof(NeededTargets)),
+ };
+ public static IEnumerable GetDefs(this ModuleDefinition Module) {
+ foreach (var Type in Module.GetAllTypes()) {
+ yield return Type;
+ foreach (var Method in Type.Methods)
+ yield return Method;
+ foreach (var Field in Type.Fields)
+ yield return Field;
+ foreach (var Property in Type.Properties)
+ yield return Property;
+ foreach (var Event in Type.Events)
+ yield return Event;
+ }
+ }
+ public static ITypeDefOrRef GetFromCorlib(this Context context, string ns, string name)
+ => context.Mscorlib.GetAllTypes().SingleOrDefault(x => x.Name == name && x.Namespace == ns);
+ public static bool IsFromElement(this TypeSignature signature, ElementType elementType)
+ => signature.ElementType == elementType;
+ public static bool IsCode(this CilInstruction instruction, CilCode code)
+ => instruction.OpCode.Code == code;
+ public static bool IsArithmetic(this CilInstruction i)
+ => i.IsCode(CilCode.Add) ||
+ i.IsCode(CilCode.And) ||
+ i.IsCode(CilCode.Sub) ||
+ i.IsCode(CilCode.Mul) ||
+ i.IsCode(CilCode.Div) ||
+ i.IsCode(CilCode.Rem) ||
+ i.IsCode(CilCode.Neg) ||
+ i.IsCode(CilCode.Not) ||
+ i.IsCode(CilCode.Xor) ||
+ i.IsCode(CilCode.Shl) ||
+ i.IsCode(CilCode.Shr) ||
+ i.IsCode(CilCode.Shr_Un) ||
+ i.IsCode(CilCode.Or);
+ public static bool IsMethod(this CilInstruction instruction, string ClassName, string MethodName)
+ => instruction.ToString().Contains(ClassName + "::" + MethodName);
+ public static bool IsFromNS(this CilInstruction instruction, string NS, string TypeName)
+ => instruction.Operand is IMethodDescriptor && ((IMethodDescriptor)instruction.Operand).DeclaringType.Namespace == NS && ((IMethodDescriptor)instruction.Operand).DeclaringType.Name == TypeName;
+ public static void Nop(this IEnumerable instructions) {
+ foreach (var i in instructions)
+ i.Nop();
+ }
+ public static void Nop(this CilInstruction instruction) {
+ instruction.OpCode = CilOpCodes.Nop;
+ instruction.Operand = null;
+ }
+ public static bool Is32Module(this ModuleDefinition module)
+ => module.IsBit32Preferred || module.IsBit32Required;
+ #endregion
+ #region Cryptography
+ public static byte[] DecryptXor(byte[] EncryptedArray)
+ {
+ Random random = new Random(23546654);
+ byte[] array = new byte[EncryptedArray.Length];
+ for (int i = 0; i < EncryptedArray.Length; i++)
+ {
+ array[i] = (byte)(EncryptedArray[i] ^ random.Next(0, 250));
+ }
+ return array;
+ }
+ private static byte[] DecryptBytes(SymmetricAlgorithm alg, byte[] message)
+ {
+ if (message == null || message.Length == 0)
+ {
+ return message;
+ }
+ if (alg == null)
+ {
+ throw new ArgumentNullException("alg is null");
+ }
+ byte[] result;
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ using ICryptoTransform transform = alg.CreateDecryptor();
+ using CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write);
+ cryptoStream.Write(message, 0, message.Length);
+ cryptoStream.FlushFinalBlock();
+ result = memoryStream.ToArray();
+ }
+ return result;
+ }
+ public static byte[] Decrypt(byte[] key, byte[] message)
+ {
+ using RijndaelManaged rijndaelManaged = new RijndaelManaged();
+ rijndaelManaged.Key = key;
+ rijndaelManaged.IV = key;
+ return DecryptBytes(rijndaelManaged, message);
+ }
+ private static byte[] XorB(byte[] toEncrypt, int len)
+ {
+ string text = "HCP";
+ for (int i = 0; i < len; i++)
+ {
+ toEncrypt[i] = (byte)(toEncrypt[i] ^ text[i % text.Length]);
+ }
+ return toEncrypt;
+ }
+ public static byte[] BDerive(byte[] data, int datalen, byte[] key, int keylen)
+ {
+ int num = 12;
+ int num2 = 14;
+ int num3 = 258;
+ for (int i = 0; i < keylen; i++)
+ {
+ num3 += num3 % (key[i] + 1);
+ }
+ for (int j = 0; j < datalen; j++)
+ {
+ num3 = key[j % keylen] + num3;
+ num = (num3 + 5) * (num & 0xFF) + (num >> 8);
+ num2 = (num3 + 7) * (num2 & 0xFF) + (num2 >> 8);
+ num3 = ((num << 8) + num2) & 0xFF;
+ data[j] = (byte)(data[j] ^ num3);
+ }
+ return XorB(data, datalen);
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Protections/Devirtualizer/CawkVM/CawkVM.cs b/UnSealer.Protections/Devirtualizer/CawkVM/CawkVM.cs
new file mode 100644
index 0000000..c086ca2
--- /dev/null
+++ b/UnSealer.Protections/Devirtualizer/CawkVM/CawkVM.cs
@@ -0,0 +1,50 @@
+
+#region Usings
+using AsmResolver.DotNet;
+using System.Collections.Generic;
+using System.Linq;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.Protections.Devirtualizer.CawkVM
+{
+ public class CawkVM : Protection {
+ public static DevirtualizationContext CawkKey;
+ public override string Name => "CawkVM Devirtualizer";
+
+ public override string Description => "Devirtualize Modules Protect With CawkVM";
+
+ public override string Id => "cawkvm";
+
+ public override string Author => "CLand";
+
+ public override void InitPipeline(Context context, Pipeline pipeline) {
+ if (!context.Module.Resources.Any(r => r.Name == "Eddy^CZ_")) {
+ context.Logger.Warn("Not CawkVm.");
+ return;
+ }
+ pipeline.InsertPreStage(PipelineStage.BeginModule,
+ new DiscoveryPhase(this));
+ pipeline.InsertPreStage(PipelineStage.ProcessModule,
+ new RestorationPhase(this));
+ }
+ }
+ public class DevirtualizationContext {
+ public IList VirtualizatedMethods { set; get; }
+ public byte[] Data { set; get; }
+ }
+ public struct MethodInfo {
+ public MethodInfo(MethodDefinition Method,
+ int Position, int Size, int ID)
+ {
+ Parent = Method;
+ this.Position = Position;
+ this.Size = Size;
+ this.ID = ID;
+ }
+ public MethodDefinition Parent { get; }
+ public int Position { get; }
+ public int Size { get; }
+ public int ID { get; }
+ }
+}
diff --git a/UnSealer.Protections/Devirtualizer/CawkVM/Disassembler.cs b/UnSealer.Protections/Devirtualizer/CawkVM/Disassembler.cs
new file mode 100644
index 0000000..f52e872
--- /dev/null
+++ b/UnSealer.Protections/Devirtualizer/CawkVM/Disassembler.cs
@@ -0,0 +1,183 @@
+
+#region Usings
+using AsmResolver.DotNet;
+using AsmResolver.DotNet.Code.Cil;
+using AsmResolver.PE.DotNet.Cil;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.Protections.Devirtualizer.CawkVM {
+ public class Disassembler
+ {
+ ///
+ /// Initalize Disassembler.
+ ///
+ /// Method That Get Disassembled.
+ /// Raw Cawk Code.
+ public Disassembler(MethodDefinition owner,
+ byte[] source)
+ {
+ Owner = owner ?? throw new ArgumentNullException("OwnerMethod is Required.");
+ Data = source ?? throw new ArgumentNullException("Main Data Must Be Not Null.");
+ _reader = new(new MemoryStream(Data));
+ _importer = new(Owner.Module);
+ _body = new CilMethodBody(Owner);
+ }
+ ///
+ /// Build New Disassemblied CilBody
+ ///
+ /// New Method Body.
+ public CilMethodBody BeginRead()
+ {
+ foreach (var Local in Owner.CilMethodBody.LocalVariables.Take(Owner.CilMethodBody.LocalVariables.Count - 2)) /* Skiping Locals Madden By CawkVM */ {
+ _body.LocalVariables.Add(new(_importer.ImportTypeSignature(Local.VariableType)));
+ }
+ int ExceptionHandlersCount = _reader.ReadInt32();
+ ExceptionClause[] Claues = new ExceptionClause[ExceptionHandlersCount];
+ /* ExceptionHandler Restoration. */
+ for (int x = 0; x < ExceptionHandlersCount; x++) {
+ uint TypeToken = (uint)_reader.ReadInt32();
+ int StartFilter = _reader.ReadInt32();
+ int HandlerEnd = _reader.ReadInt32();
+ int HandlerStart = _reader.ReadInt32();
+ byte HandlerType = _reader.ReadByte();
+ int TryEnd = _reader.ReadInt32();
+ int TryStart = _reader.ReadInt32();
+ Claues[x] = new ExceptionClause() {
+ HandlerType = HandlerType switch
+ {
+ 1 => CilExceptionHandlerType.Exception,
+ 2 => null, // No Duplicates.
+ 3 => CilExceptionHandlerType.Fault,
+ 4 => CilExceptionHandlerType.Filter,
+ 5 => CilExceptionHandlerType.Finally,
+ _ => throw new Exception("Unknown HandlerType.")
+ },
+ HandlerEnd = HandlerEnd,
+ FilterStart = StartFilter,
+ HandlerStart = HandlerStart,
+ CatchType = (int)TypeToken == -1
+ ? null /* catch { } */
+ : _importer.ImportType((ITypeDefOrRef)Owner.Module.LookupMember(new(TypeToken))), /* catch(...) { } */
+ TryEnd = TryEnd,
+ TryStart = TryStart
+ };
+ }
+ int InstructionsCount = _reader.ReadInt32();
+ for (int q = 0; q < InstructionsCount; q++) {
+ _body.Instructions.Add(new CilInstruction(CilOpCodes.Nop));
+ _body.Instructions.CalculateOffsets();
+ }
+ /* Instruction Restoration. */
+ for (int i = 0; i < InstructionsCount; i++) {
+ var OpCode = ((CilCode)_reader.ReadInt16()).ToOpCode(); // Read OpCode by their Short Value.
+ switch (_reader.ReadByte())
+ {
+ case 0: _body.Instructions[i] = new(OpCode); break; // Inline None.
+ case 1: _body.Instructions[i] = new(OpCode, _importer.ImportMethod((IMethodDescriptor)Owner.Module.LookupMember(new((uint)_reader.ReadInt32())))); break; // Inline Method
+ case 2: _body.Instructions[i] = new(OpCode, _reader.ReadString()); break; // InlineString
+ case 3: _body.Instructions[i] = new(OpCode, _reader.ReadInt32()); break; // InlineI
+ case 5: _body.Instructions[i] = new(OpCode, _importer.ImportField((IFieldDescriptor)Owner.Module.LookupMember(new((uint)_reader.ReadInt32())))); break; // Inline Field
+ case 6: _body.Instructions[i] = new(OpCode, _importer.ImportType((ITypeDefOrRef)Owner.Module.LookupMember(new((uint)_reader.ReadInt32())))); break; // Inline Type
+ case 7: int Index = _reader.ReadInt32(); _body.Instructions[i] = new(OpCode, Index); break; // ShortInlineBrTarget;
+ case 8: _body.Instructions[i] = new(OpCode, _reader.ReadByte()); break; // ShortInline
+ case 9:
+ int Count = _reader.ReadInt32();
+ int[] Labels = new int[Count];
+ for (int x = 0; x < Count; x++)
+ {
+ int SIndex = _reader.ReadInt32();
+ Labels[x] = SIndex;
+ }
+ _body.Instructions[i] = new(OpCode, Labels);
+ break; // Inline Switch
+ case 10: int BIndex = _reader.ReadInt32(); _body.Instructions[i] = new(OpCode, BIndex); break; // InlineBrTarget
+ case 11:
+ int Token = _reader.ReadInt32();
+ byte Prefix = _reader.ReadByte();
+ switch (Prefix)
+ {
+ case 0: _body.Instructions[i] = new(OpCode, _importer.ImportField((IFieldDescriptor)Owner.Module.LookupMember(new((uint)Token)))); break; // fieldof(...)
+ case 1: _body.Instructions[i] = new(OpCode, _importer.ImportType((ITypeDefOrRef)Owner.Module.LookupMember(new((uint)Token)))); break; // typeof(...)
+ case 2: _body.Instructions[i] = new(OpCode, _importer.ImportMethod((IMethodDescriptor)Owner.Module.LookupMember(new((uint)Token)))); break; // methodof(...)
+ }
+ break; // InlineTok.
+ case 13: _body.Instructions[i] = new(OpCode, BitConverter.ToSingle(_reader.ReadBytes(4), 0)); break; // ShortInline
+ case 14: _body.Instructions[i] = new(OpCode, _reader.ReadDouble()); break; // InlineR
+ case 15: _body.Instructions[i] = new(OpCode, _reader.ReadInt64()); break; // InlineI8
+ case 4:
+ case 12:
+ int PIndex = _reader.ReadInt32();
+ if (_reader.ReadByte() == 0)
+ {
+ _body.Instructions[i] = new(OpCode, _body.LocalVariables[PIndex]);
+ }
+ else
+ {
+ _body.Instructions[i] = new(OpCode, PIndex == 0 && Owner.Signature.HasThis ? Owner.Parameters.ThisParameter : Owner.Parameters[Owner.Signature.HasThis ? PIndex - 1 : PIndex]);
+ }
+
+ break; // (Inline/Short)Var
+
+ }
+ }
+ /* Branch Fixing. */
+ for (int v = 0; v < InstructionsCount; v++) {
+ switch (_body.Instructions[v].OpCode.OperandType) {
+ case CilOperandType.InlineSwitch: /* switch(...) */
+ int[] Labels = (int[])_body.Instructions[v].Operand;
+ List NewLabels = new List();
+ foreach (int l in Labels)
+ NewLabels.Add(_body.Instructions[l].CreateLabel());
+ _body.Instructions[v].Operand = NewLabels;
+ break;
+ case CilOperandType.ShortInlineBrTarget: /* br_s , bgt_s , etc. */
+ case CilOperandType.InlineBrTarget: /* brfalse , brtrue , etc. */
+ ICilLabel Label = _body.Instructions[(int)_body.Instructions[v].Operand].CreateLabel();
+ _body.Instructions[v].Operand = Label;
+ break;
+ }
+ }
+ /* ExceptionHandlers Setting. */
+ for (int z = 0; z < ExceptionHandlersCount; z++) {
+ ExceptionClause Clause = Claues[z];
+ CilExceptionHandler EhHandler = new CilExceptionHandler()
+ {
+ ExceptionType = Clause.CatchType,
+ FilterStart = Clause.FilterStart == -1 ? null : _body.Instructions[Clause.FilterStart].CreateLabel(),
+ HandlerStart = _body.Instructions[Clause.HandlerStart].CreateLabel(),
+ HandlerEnd = _body.Instructions[Clause.HandlerEnd].CreateLabel(),
+ TryStart = _body.Instructions[Clause.TryStart].CreateLabel(),
+ HandlerType = Clause.HandlerType.Value,
+ TryEnd = _body.Instructions[Clause.TryEnd].CreateLabel()
+ };
+ _body.ExceptionHandlers.Add(EhHandler);
+ }
+ _body.Instructions.CalculateOffsets(); // Calculate New Offsets.
+ _body.Instructions.ExpandMacros();
+ _body.Instructions.OptimizeMacros(); // Serialize Body.
+ return _body;
+ }
+ public byte[] Data { get; }
+ public MethodDefinition Owner { get; }
+
+ #region PrivateFields
+ private CilMethodBody _body;
+ private BinaryReader _reader;
+ private ReferenceImporter _importer;
+ #endregion
+ }
+ internal struct ExceptionClause {
+ public ITypeDefOrRef CatchType;
+ public int FilterStart;
+ public int HandlerEnd;
+ public int HandlerStart;
+ public CilExceptionHandlerType? HandlerType;
+ public int TryEnd;
+ public int TryStart;
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Protections/Devirtualizer/CawkVM/DiscoveryPhase.cs b/UnSealer.Protections/Devirtualizer/CawkVM/DiscoveryPhase.cs
new file mode 100644
index 0000000..ee93c50
--- /dev/null
+++ b/UnSealer.Protections/Devirtualizer/CawkVM/DiscoveryPhase.cs
@@ -0,0 +1,45 @@
+
+#region Usings
+using AsmResolver;
+using AsmResolver.DotNet;
+using AsmResolver.PE.DotNet.Cil;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.Protections.Devirtualizer.CawkVM {
+ public class DiscoveryPhase : ProtectionPhase {
+ public DiscoveryPhase(Protection ParentBase)
+ : base(ParentBase) { }
+
+ public override string Name => "Discovery Phase.";
+
+ public override ProtectionTargets PhaseTargets => ProtectionTargets.Methods;
+
+ public override void Execute(Context context, IEnumerable targets)
+ {
+ CawkVM.CawkKey = new DevirtualizationContext() {
+ Data = Utilities.DecryptXor(((DataSegment)context.Module.Resources.Single(m => m.Name == "Eddy^CZ_").EmbeddedDataSegment).Data),
+ VirtualizatedMethods = new List()
+ };
+ foreach (var Method in targets.OfType().Where(m => m.CilMethodBody is not null)) {
+ var Instructions = Method.CilMethodBody.Instructions;
+ for (int x = 0; x < Instructions.Count; x++) {
+ if (Instructions[x].IsLdcI4() && // Position
+ Instructions[x + 1].IsLdcI4() && // Size
+ Instructions[x + 2].IsLdcI4() && // ID
+ Instructions[x + 4].IsCode(CilCode.Call) &&
+ Instructions[x + 4].IsMethod("ConvertBack", "Runner")) {
+ var (Position, Size, ID) = (Instructions[x].GetLdcI4Constant(), Instructions[x + 1].GetLdcI4Constant(), Instructions[x + 2].GetLdcI4Constant());
+ // Add Virtualized Method Into Context.
+ CawkVM.CawkKey.VirtualizatedMethods.Add(new(Method, Position, Size, ID));
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Protections/Devirtualizer/CawkVM/RestorationPhase.cs b/UnSealer.Protections/Devirtualizer/CawkVM/RestorationPhase.cs
new file mode 100644
index 0000000..175e55d
--- /dev/null
+++ b/UnSealer.Protections/Devirtualizer/CawkVM/RestorationPhase.cs
@@ -0,0 +1,60 @@
+
+#region Usings
+using AsmResolver;
+using AsmResolver.DotNet;
+using AsmResolver.PE.DotNet.Cil;
+using AsmResolver.PE.DotNet.Metadata.Tables;
+using AsmResolver.PE.DotNet.Metadata.Tables.Rows;
+using AsmResolver.PE.File;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.Protections.Devirtualizer.CawkVM {
+ public class RestorationPhase : ProtectionPhase {
+ public RestorationPhase(Protection ParentBase)
+ : base(ParentBase) { }
+
+ public override string Name => "Restoration Phase";
+
+ public override ProtectionTargets PhaseTargets => ProtectionTargets.Methods;
+
+ public override void Execute(Context context, IEnumerable targets) {
+ var MethodsTables = context.Module.DotNetDirectory.Metadata
+ .GetStream()
+ .GetTable(); // Methods Rows in .Net Binary that Get Access to Rawbytes of Methods without reflection Usage.
+ foreach (var VirualizedMethod in CawkVM.CawkKey.VirtualizatedMethods) {
+ try {
+ #region Decryption
+ byte[] RawBytes = CawkVM.CawkKey.Data.Skip(VirualizedMethod.Position).Take(VirualizedMethod.Size).ToArray();
+ byte[] HashKey = MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(VirualizedMethod.Parent.Name));
+ var ReaderRef = MethodsTables.GetByRid(VirualizedMethod.Parent.MetadataToken.Rid).Body as PESegmentReference?;
+ var Reader = ReaderRef.Value.CreateReader();
+ byte[] RawBody = ((DataSegment)CilRawMethodBody.FromReader(null, ref Reader).Code).Data;
+ Utilities.BDerive(RawBytes, RawBytes.Length, RawBody, RawBody.Length);
+ #endregion
+ var Disassembler = new Disassembler(VirualizedMethod.Parent, Utilities.Decrypt(HashKey, RawBytes));
+ VirualizedMethod.Parent.CilMethodBody = Disassembler.BeginRead();
+ context.Logger.InfoFormat("Done Restoring {0} Instruction.",
+ VirualizedMethod.Parent.CilMethodBody.Instructions.Count);
+ }
+ catch (Exception) /* It will not but maybe ¯\_(ツ)_/¯ */ {
+ context.Logger.WarnFormat("Method {0} Failed Devirtualizaing.", VirualizedMethod.Parent.Name);
+ }
+ }
+ var Resources = new List() {
+ "Eddy^CZ",
+ "Eddy^CZ_",
+ "RT",
+ "X64",
+ "X86"
+ };
+ foreach (var Resource in context.Module.Resources.Where(x => Resources.Contains(x.Name)).ToArray())
+ context.Module.Resources.Remove(Resource);
+ }
+ }
+}
diff --git a/UnSealer.Protections/Misc/CalliFixer.cs b/UnSealer.Protections/Misc/CalliFixer.cs
new file mode 100644
index 0000000..5b844a5
--- /dev/null
+++ b/UnSealer.Protections/Misc/CalliFixer.cs
@@ -0,0 +1,47 @@
+
+#region Usings
+using AsmResolver.DotNet;
+using AsmResolver.PE.DotNet.Cil;
+using System.Collections.Generic;
+using System.Linq;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.Protections.Misc {
+ public class CalliFixer : Protection {
+ public override string Name => "Calli Fixer";
+
+ public override string Description => "Removes Basic Calli OpCode Usage."; /* Using Ldftn is basic. */
+
+ public override string Id => "calli";
+
+ public override string Author => "CLand";
+
+ public override void InitPipeline(Context context, Pipeline pipeline) {
+ pipeline.InsertPreStage(PipelineStage.ProcessModule,
+ new CalliPhase(this));
+ }
+ }
+ public class CalliPhase : ProtectionPhase {
+ public CalliPhase(Protection ParentBase)
+ : base(ParentBase) { }
+
+ public override string Name => "Calli Phase.";
+
+ public override ProtectionTargets PhaseTargets => ProtectionTargets.Methods;
+
+ public override void Execute(Context context, IEnumerable targets) {
+ foreach (var Method in targets.OfType().Where(x => x.CilMethodBody is not null)) {
+ var IL = Method.CilMethodBody.Instructions;
+ for (int x = 0; x < IL.Count; x++) {
+ if (IL[x].IsCode(CilCode.Ldftn) &&
+ IL[x + 1].IsCode(CilCode.Calli)) {
+ IL[x].Operand = context.Importer.ImportMethod(IL[x].Operand as IMethodDescriptor); /* Import Org Call Method */
+ IL[x].OpCode = CilOpCodes.Call; /* Convert it To Call Instruction */
+ IL.RemoveAt(x + 1); /* Remove Calli's Instruction. */
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Protections/Misc/ConfuserStringDecrypter.cs b/UnSealer.Protections/Misc/ConfuserStringDecrypter.cs
new file mode 100644
index 0000000..b20acd3
--- /dev/null
+++ b/UnSealer.Protections/Misc/ConfuserStringDecrypter.cs
@@ -0,0 +1,148 @@
+
+#region Usings
+using AsmResolver.DotNet;
+using AsmResolver.PE.DotNet.Cil;
+using Echo.DataFlow.Analysis;
+using Echo.Platforms.AsmResolver;
+using Echo.Platforms.AsmResolver.Emulation;
+using Echo.Platforms.AsmResolver.Emulation.Values;
+using Echo.Platforms.AsmResolver.Emulation.Values.Cli;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+using System.Reflection.Emit;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.Protections.Misc {
+ public class ConfuserStringDecrypter : Protection {
+ public override string Name => "Confuser String Decrypter";
+
+ public override string Description => "Decrypt ConfuserEx Constants In Advanced Way.";
+
+ public override string Id => "cfexconst";
+
+ public override string Author => "CLand";
+
+ public override void InitPipeline(Context context, Pipeline pipeline) {
+ pipeline.InsertPreStage(PipelineStage.ProcessModule,
+ new CSDPhase(this));
+ }
+ }
+ public class CSDPhase : ProtectionPhase
+ {
+ public CSDPhase(Protection ParentBase)
+ : base(ParentBase) { }
+
+ public override string Name => "Confuser String Decrypter Phase.";
+
+ public override ProtectionTargets PhaseTargets => ProtectionTargets.Methods;
+
+ public override void Execute(Context context, IEnumerable targets) {
+ if (!context.IsReflectionSafe) return; // Sadly Only Reflection To Get Value.
+ foreach (var Method in targets.OfType().Where(x => x.CilMethodBody is not null)) {
+ var IL = Method.CilMethodBody.Instructions;
+ IL.CalculateOffsets(); /* DataFlowGraphs React nani... */
+ Method.CilMethodBody.ConstructSymbolicFlowGraph(out var dfg); /* Constructing DataFlowGraph. */
+ for (int x = 0; x < IL.Count; x++) {
+ var Instr = IL[x];
+ if (Instr.IsCode(CilCode.Call) &&
+ Instr.Operand is MethodSpecification GenericMethod && /* .Decode */
+ GenericMethod.Signature.TypeArguments.Count == 1 &&
+ GenericMethod.Signature.TypeArguments[0] == context.Module.CorLibTypeFactory.String) { /* T is string. (i.e. .Decode(params)) */
+ var vm = new CilVirtualMachine(Method.CilMethodBody, context.Module.Is32Module()); /* Define CilEmulator. */
+ var ex = new CilExecutionContext(vm, vm.CurrentState, default);
+ if (!dfg.Nodes.Contains(Instr.Offset)) continue; /* Maybe Some Time it fails to Make DFG for that Instruction Who Knows Hidden Features ?! */
+ var StackDeps = dfg.Nodes[Instr.Offset]
+ .GetOrderedDependencies(DependencyCollectionFlags.IncludeStackDependencies)
+ .ToList(); /* Get Stack Dependencies For Constants Call.*/
+ StackDeps.Remove(StackDeps.Last()); /* Remove Call Instruction (Decoder Call). */
+ var BackUp = new List();
+ foreach (var Dep in StackDeps) {
+ var EmuInstr = Dep.Contents; /* Store Instruction Into Variable To Eumlate it.. */
+ BackUp.Add(new(EmuInstr.OpCode, EmuInstr.Operand ?? null));
+ vm.Dispatcher.Execute(ex, EmuInstr);
+ EmuInstr.Nop(); /* Nop That Instr. */
+ }
+ var ReflectionMethod = context.ReflectionModule.ResolveMethod(GenericMethod.MetadataToken.ToInt32());
+ var RefParams = ReflectionMethod.GetParameters();
+ var Count = RefParams.Length;
+ var IOSlot = new object[Count];
+ for (int i = 0; i < RefParams.Length; i++) {
+ object S = default;
+ var Value = vm.CurrentState.Stack.Pop();
+ var PType = RefParams[--Count].ParameterType;
+ #region Yandere Code (Close Eyes Please 🙃)
+ // Since I never saw anything using any value else so that is good (for now).
+ #region Ldstr-Handling
+ if (PType == typeof(string) && Value is StringValue @string)
+ S = @string.ToString();
+ else if (Value is not StringValue && PType == typeof(string))
+ S = string.Empty; // Hey Skids :DD
+ #endregion
+ #region I32-Handling
+ if (PType == typeof(int) && Value is I4Value @i32)
+ S = @i32.I32;
+ else if (Value is not I4Value && PType == typeof(int))
+ S = 0;
+ #endregion
+ #region U32-Handling
+ if (PType == typeof(uint) && Value is I4Value @u32)
+ S = @u32.U32;
+ else if (Value is not I4Value && PType == typeof(uint))
+ S = 0U;
+ #endregion
+ #endregion
+ /* Assume Fake Parameter. */
+ if (S == default) S = Convert.ChangeType(new object(), PType);
+ IOSlot[Count] = S;
+ }
+ try {
+ object Result = default;
+ if (GenericMethod.Method.Resolve().CilMethodBody.Instructions.Any(q => q.ToString().Contains(nameof(Assembly)) || q.ToString().Contains(nameof(StackTrace))))
+ Result = DynamicInvocation((MethodInfo)ReflectionMethod, Method.Name, context.ReflectionModule, IOSlot);
+ else
+ Result = ReflectionMethod.Invoke(null, IOSlot);
+
+ Instr.OpCode = CilOpCodes.Ldstr; /* Changing Call To Ldstr. */
+ Instr.Operand = Result as string /* Cast Value As String. */
+ ?? string.Empty; /* if its null i dont want AsmResolver Throw Errors.... */
+ }
+ catch {
+ // Restore instructions if their an problem (i.e. TargetInvocationException).
+ for (int i = 0; i < BackUp.Count; i++) {
+ CilInstruction Back = BackUp[i];
+ CilInstruction Org = StackDeps[i].Contents;
+ Org.OpCode = Back.OpCode;
+ Org.Operand = Back.Operand;
+ }
+ }
+ }
+ }
+ }
+ object DynamicInvocation(MethodInfo method, string invokename, Module module, object[] mparams) {
+ var pT = new List();
+
+ foreach (ParameterInfo x in method.GetParameters())
+ pT.Add(x.ParameterType);
+
+ var dMethod = new DynamicMethod(invokename, typeof(string),
+ pT.ToArray(), module,
+ true);
+
+ var ILGen = dMethod.GetILGenerator();
+
+ for (int i = 0; i < mparams.Length; i++)
+ ILGen.Emit(OpCodes.Ldarg, i);
+
+ ILGen.Emit(OpCodes.Call, method);
+
+ ILGen.Emit(OpCodes.Ret);
+
+ return dMethod.Invoke(null, mparams);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Protections/Misc/L2Field/AnalyzePhase.cs b/UnSealer.Protections/Misc/L2Field/AnalyzePhase.cs
new file mode 100644
index 0000000..6a1d2b2
--- /dev/null
+++ b/UnSealer.Protections/Misc/L2Field/AnalyzePhase.cs
@@ -0,0 +1,45 @@
+
+#region Usings
+using AsmResolver.DotNet;
+using AsmResolver.PE.DotNet.Cil;
+using System.Collections.Generic;
+using System.Linq;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.Protections.Misc.L2Field {
+ public class AnalyzePhase : ProtectionPhase {
+ public AnalyzePhase(Protection ParentBase)
+ : base(ParentBase) { }
+
+ public override string Name => "Analyzing Phase.";
+
+ public override ProtectionTargets PhaseTargets => ProtectionTargets.Methods;
+
+ public override void Execute(Context context, IEnumerable targets) {
+ var Storage = new Dictionary>();
+ foreach (var Method in targets.OfType().Where(x => x.CilMethodBody is not null)) {
+ Storage[Method] = new();
+ var IL = Method.CilMethodBody.Instructions;
+ for (int x = 0; x < IL.Count; x++) {
+ var Instr = IL[x];
+ if (!(Instr.IsCode(CilCode.Ldsfld) || Instr.IsCode(CilCode.Ldsflda) || Instr.IsCode(CilCode.Stsfld)))
+ continue;
+ var Field = Instr.Operand as FieldDefinition;
+ if (!(Field.IsStatic && Field.IsPublic && Field.DeclaringType == context.Module.GetModuleType())) /* Field Is From type & static and public. */
+ continue;
+ var STemp = Storage.Values.ToList();
+ STemp.Remove(Storage[Method]); // If The Field Is From Same Method its okey...
+ if (!STemp.Any(q => q.Contains(Field))) { /* Get Sure If It Used In Another Method. */
+ if (!Storage[Method].Contains(Field)) Storage[Method].Add(Field);
+ }
+ else {
+ List> CList = Storage.Values.Where(l => l.Contains(Field)).ToArray().ToList();
+ CList.ForEach(cl => cl.ToArray().ToList().ForEach(lc => cl.Remove(lc))); // :)
+ }
+ }
+ }
+ L2FieldProtection.L2FKey = Storage;
+ }
+ }
+}
diff --git a/UnSealer.Protections/Misc/L2Field/L2FieldProtection.cs b/UnSealer.Protections/Misc/L2Field/L2FieldProtection.cs
new file mode 100644
index 0000000..120c402
--- /dev/null
+++ b/UnSealer.Protections/Misc/L2Field/L2FieldProtection.cs
@@ -0,0 +1,27 @@
+
+#region Usings
+using AsmResolver.DotNet;
+using System.Collections.Generic;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.Protections.Misc.L2Field {
+ public class L2FieldProtection : Protection {
+ public static IDictionary> L2FKey;
+
+ public override string Name => "Local To Field Fixer";
+
+ public override string Description => "Fixs L2F Protection.";
+
+ public override string Id => "l2f";
+
+ public override string Author => "CLand";
+
+ public override void InitPipeline(Context context, Pipeline pipeline) {
+ pipeline.InsertPreStage(PipelineStage.BeginModule,
+ new AnalyzePhase(this));
+ pipeline.InsertPreStage(PipelineStage.ProcessModule,
+ new RestorationPhase(this));
+ }
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Protections/Misc/L2Field/RestorationPhase.cs b/UnSealer.Protections/Misc/L2Field/RestorationPhase.cs
new file mode 100644
index 0000000..10b7d82
--- /dev/null
+++ b/UnSealer.Protections/Misc/L2Field/RestorationPhase.cs
@@ -0,0 +1,54 @@
+
+#region Usings
+using AsmResolver.DotNet;
+using AsmResolver.DotNet.Code.Cil;
+using AsmResolver.PE.DotNet.Cil;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.Protections.Misc.L2Field {
+ public class RestorationPhase : ProtectionPhase {
+ public RestorationPhase(Protection ParentBase)
+ : base(ParentBase) { }
+
+ public override string Name => "L2F Restoration Phase.";
+
+ public override ProtectionTargets PhaseTargets => ProtectionTargets.None;
+
+ public override void Execute(Context context, IEnumerable targets) {
+ foreach (var Pairs in L2FieldProtection.L2FKey) {
+ var Cache = new Dictionary();
+ var IL = Pairs.Key.CilMethodBody.Instructions;
+ for (int x = 0; x < IL.Count; x++) {
+ CilInstruction Instr = IL[x];
+ if ((Instr.IsCode(CilCode.Ldsfld) ||
+ Instr.IsCode(CilCode.Stsfld) ||
+ Instr.IsCode(CilCode.Ldsflda)) &&
+ Pairs.Value.Contains(Instr.Operand as IFieldDescriptor)) {
+ IFieldDescriptor Field = Pairs.Value.SingleOrDefault(q => q == Instr.Operand as IFieldDescriptor); /* Thanks Linq :^) */
+ if (Field == null) continue;
+ var NewLocal = new CilLocalVariable(context.Importer.ImportTypeSignature(Field.Signature.FieldType));
+ Instr.OpCode = Instr.OpCode.Code switch {
+ CilCode.Ldsfld => CilOpCodes.Ldloc,
+ CilCode.Stsfld => CilOpCodes.Stloc,
+ CilCode.Ldsflda => CilOpCodes.Ldloca,
+ _ => throw new ArgumentOutOfRangeException(nameof(Instr.OpCode))
+ };
+ if (!Cache.ContainsKey(Field)) {
+ Pairs.Key.CilMethodBody.LocalVariables.Add(NewLocal);
+ Cache.Add(Field, NewLocal);
+ }
+ else {
+ NewLocal = Cache[Field];
+ }
+ Instr.Operand = NewLocal;
+ }
+ }
+ Pairs.Value.ToArray().ToList().ForEach(x => ((TypeDefinition)x.DeclaringType)?.Fields?.Remove(x.Resolve() ?? (FieldDefinition)x)); /* Performance Is Meh. */
+ }
+ }
+ }
+}
diff --git a/UnSealer.Protections/Misc/OutlinerFixer.cs b/UnSealer.Protections/Misc/OutlinerFixer.cs
new file mode 100644
index 0000000..50a661b
--- /dev/null
+++ b/UnSealer.Protections/Misc/OutlinerFixer.cs
@@ -0,0 +1,54 @@
+
+#region Usings
+using AsmResolver.DotNet;
+using AsmResolver.PE.DotNet.Cil;
+using System.Collections.Generic;
+using System.Linq;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.Protections.Misc {
+ public class OutlinerFixer : Protection {
+ public override string Name => "Outliner Fixer";
+
+ public override string Description => "Fixes Proxies Method That Outlines Strings/Ints";
+
+ public override string Id => "inliner";
+
+ public override string Author => "CLand";
+
+ public override void InitPipeline(Context context, Pipeline pipeline) {
+ pipeline.InsertPreStage(PipelineStage.ProcessModule,
+ new InlinerPhase(this));
+ }
+ }
+ public class InlinerPhase : ProtectionPhase {
+ public InlinerPhase(Protection ParentBase)
+ : base(ParentBase) { }
+
+ public override string Name => "Inline Phase.";
+
+ public override ProtectionTargets PhaseTargets => ProtectionTargets.Methods;
+
+ public override void Execute(Context context, IEnumerable targets) {
+ foreach (var Method in targets.OfType().Where(x => x.CilMethodBody is not null)) {
+ var IL = Method.CilMethodBody.Instructions;
+ for (int x = 0; x < IL.Count; x++) {
+ var Instr = IL[x];
+ if ((Instr.IsCode(CilCode.Call) || Instr.IsCode(CilCode.Callvirt)) &&
+ Instr.Operand is MethodDefinition OutlineMethod &&
+ OutlineMethod.Parameters.Count <= 0 &&
+ OutlineMethod.CilMethodBody is not null &&
+ OutlineMethod.CilMethodBody.Instructions.Count <= 2 &&
+ OutlineMethod.CilMethodBody.Instructions[1].IsCode(CilCode.Ret) &&
+ (OutlineMethod.CilMethodBody.Instructions[0].IsCode(CilCode.Ldstr) || OutlineMethod.CilMethodBody.Instructions[0].IsLdcI4())) {
+ var OutLined = OutlineMethod.CilMethodBody.Instructions[0];
+ Instr.OpCode = OutLined.OpCode;
+ Instr.Operand = OutLined.Operand;
+ OutlineMethod?.DeclaringType?.Methods?.Remove(OutlineMethod);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/UnSealer.Protections/Misc/ProxyFixer.cs b/UnSealer.Protections/Misc/ProxyFixer.cs
new file mode 100644
index 0000000..22abb31
--- /dev/null
+++ b/UnSealer.Protections/Misc/ProxyFixer.cs
@@ -0,0 +1,48 @@
+
+#region Usings
+using AsmResolver.DotNet;
+using AsmResolver.PE.DotNet.Cil;
+using System.Collections.Generic;
+using System.Linq;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.Protections.Misc {
+ internal class ProxyFixer : Protection {
+ public override string Name => "Proxy Fixer";
+
+ public override string Description => "Inlines Calls That Get Outlined By Some Obfuscators.";
+
+ public override string Id => "proxy";
+
+ public override string Author => "CLand";
+
+ public override void InitPipeline(Context context, Pipeline pipeline) {
+ pipeline.InsertPreStage(PipelineStage.BeginModule,
+ new ProxyInlinerPhase(this));
+ }
+ }
+ internal class ProxyInlinerPhase : ProtectionPhase {
+ public ProxyInlinerPhase(Protection ParentBase)
+ : base(ParentBase) { }
+
+ public override string Name => "Inline Phase";
+
+ public override ProtectionTargets PhaseTargets => ProtectionTargets.Methods;
+
+ public override void Execute(Context context, IEnumerable targets) {
+ var Cache = new List();
+ foreach (var Method in targets.OfType().Where(x => x.CilMethodBody is not null)) {
+ var IL = Method.CilMethodBody.Instructions;
+ for (var x = 0; x < IL.Count; x++) {
+ if (!(IL[x].IsCode(CilCode.Call) && IL[x].Operand is MethodDefinition ProxyMethod
+ && ProxyMethod.IsProxy(out var callinstr))) continue; // Check If Its Proxy.
+ IL[x].OpCode = callinstr.OpCode;
+ IL[x].Operand = context.Importer.ImportMethod((IMethodDescriptor)callinstr.Operand);
+ lock (Cache) Cache.Add(ProxyMethod);
+ }
+ }
+ Cache.ForEach(x => x?.DeclaringType?.Methods?.Remove(x)); // Nullables is love :3
+ }
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Protections/Mutations/Purifier/ArithmeticPurifier.cs b/UnSealer.Protections/Mutations/Purifier/ArithmeticPurifier.cs
new file mode 100644
index 0000000..a130107
--- /dev/null
+++ b/UnSealer.Protections/Mutations/Purifier/ArithmeticPurifier.cs
@@ -0,0 +1,87 @@
+
+#region Usings
+using AsmResolver.DotNet;
+using AsmResolver.PE.DotNet.Cil;
+using Echo.DataFlow;
+using Echo.DataFlow.Analysis;
+using Echo.Platforms.AsmResolver;
+using Echo.Platforms.AsmResolver.Emulation;
+using Echo.Platforms.AsmResolver.Emulation.Values.Cli;
+using System.Collections.Generic;
+using System.Linq;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.Protections.Mutations.Purifier {
+ public class ArithmeticPurifier : ProtectionPhase {
+ public ArithmeticPurifier(Protection ParentBase)
+ : base(ParentBase) { }
+
+ public override string Name => "Arithmetic Cleaning Phase";
+
+ public override ProtectionTargets PhaseTargets => ProtectionTargets.Methods;
+
+ public override void Execute(Context context, IEnumerable targets) {
+ // i dont really recommend to execute this code since Echo have some problems i have discovered while i was coding on my own samples.
+ /*foreach (MethodDefinition Method in targets.OfType().Where(x => x.CilMethodBody is not null)) {
+ var IL = Method.CilMethodBody.Instructions;
+ IL.CalculateOffsets(); *//* nani. *//*
+ DataFlowGraph dfg = null;
+ try {
+ Method.CilMethodBody.ConstructSymbolicFlowGraph(out dfg); *//* Constructing DataFlow Graph. *//*
+ }
+ catch *//* There An Problem While i Was Coding This In Echo DataFlowGraph Constructing in Some Sample Methods... *//* {
+ continue;
+ }
+ var vm = new CilVirtualMachine(Method.CilMethodBody, context.Module.Is32Module()); *//* Assigning Emulator. *//*
+ var ex = new CilExecutionContext(vm, vm.CurrentState, default);
+ for (int x = 0; x < IL.Count; x++)
+ {
+ vm.CurrentState.Stack.Clear(); *//* Clear Values In Stack To Began New Calcualtion. *//*
+ CilInstruction Instr = IL[x];
+ if (!Instr.IsArithmetic())
+ {
+ continue; *//* Check if Its An Arithmetic Operator. (ex : +,-,*,^,<<,>>,~,%,/). *//*
+ }
+ if (!dfg.Nodes.Contains(Instr.Offset))
+ {
+ continue; *//* Check If That Arithmetic Node Assigned In DataflowGraph. *//*
+ }
+ var Deps = dfg.Nodes[Instr.Offset]
+ .GetOrderedDependencies(DependencyCollectionFlags.IncludeStackDependencies)
+ .ToList(); *//* get Depndency By Stack Order. *//*
+ foreach (var Dep in Deps) {
+ CilInstruction CInstr = Dep.Contents;
+ vm.Dispatcher.Execute(ex, CInstr);
+ }
+ if (!vm.CurrentState.Stack.Top.IsKnown)
+ continue; *//* if the value is known we will replace it. *//*
+ for (int i = 0; i < Deps.Count - 1; i++)
+ Deps[i].Contents.Nop(); *//* Nop Useless Instructions. *//*
+ switch (vm.CurrentState.Stack.Top)
+ {
+ case FValue FV:
+ Instr.OpCode = CilOpCodes.Ldc_R8;
+ Instr.Operand = FV.F64;
+ break;
+ case I8Value I8V:
+ Instr.OpCode = CilOpCodes.Ldc_I8;
+ Instr.Operand = I8V.I64;
+ break;
+ case NativeIntegerValue IPtrV:
+ Instr.OpCode = CilOpCodes.Ldc_I4;
+ Instr.Operand = IPtrV.InterpretAsI4().I32;
+ IL.Insert(x + 1, new CilInstruction(CilOpCodes.Conv_I)); *//* Cast To IntPtr. *//*
+ ++x;
+ break;
+ case I4Value I4V:
+ Instr.OpCode = CilOpCodes.Ldc_I4;
+ Instr.Operand = I4V.I32;
+ break;
+ }
+ vm.CurrentState.Stack.Clear(); *//* Clear Values In Stack To Began New Calcualtion. *//*
+ }
+ }*/
+ }
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Protections/Mutations/Purifier/MathPurifier.cs b/UnSealer.Protections/Mutations/Purifier/MathPurifier.cs
new file mode 100644
index 0000000..1fed5cb
--- /dev/null
+++ b/UnSealer.Protections/Mutations/Purifier/MathPurifier.cs
@@ -0,0 +1,82 @@
+
+#region Usings
+using AsmResolver.DotNet;
+using AsmResolver.PE.DotNet.Cil;
+using AsmResolver.PE.DotNet.Metadata.Tables.Rows;
+using Echo.Concrete.Values.ValueType;
+using Echo.DataFlow.Analysis;
+using Echo.Platforms.AsmResolver;
+using Echo.Platforms.AsmResolver.Emulation;
+using Echo.Platforms.AsmResolver.Emulation.Values.Cli;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.Protections.Mutations.Purifier {
+ public class MathPurifier : ProtectionPhase {
+ public MathPurifier(Protection ParentBase)
+ : base(ParentBase) { }
+
+ public override string Name => "Math Cleaning Phase";
+
+ public override ProtectionTargets PhaseTargets => ProtectionTargets.Methods;
+
+ public override void Execute(Context context, IEnumerable targets) {
+ if (!context.IsReflectionCorlibSafe) return;
+ foreach (var Method in targets.OfType().Where(m => m.CilMethodBody is not null)) {
+ var Instructions = Method.CilMethodBody.Instructions;
+ Method.CilMethodBody.ConstructSymbolicFlowGraph(out var DFG); /* Dfg Constructing. */
+ for (int x = 0; x < Instructions.Count; x++) {
+ var Instr = Instructions[x]; /* Some People Make It Callvirt To Deafet Public tools :p */
+ if ((Instr.IsCode(CilCode.Call) || Instr.IsCode(CilCode.Callvirt)) &&
+ Instr.IsFromNS("System", "Math") && DFG.Nodes.Contains(Instr.Offset)) {
+
+ var CallNode = DFG.Nodes[Instr.Offset]
+ .GetOrderedDependencies(DependencyCollectionFlags.IncludeStackDependencies)
+ .ToList();
+
+ if (CallNode.Any(x => x.Contents.OpCode.OperandType == CilOperandType.InlineMethod)) continue;
+
+ var vm = new CilVirtualMachine(Method.CilMethodBody,
+ context.Module.Is32Module());
+ var ex = new CilExecutionContext(vm, vm.CurrentState, default);
+
+ foreach (var Dep in CallNode) {
+ var CInstr = Dep.Contents;
+ vm.Dispatcher.Execute(ex, CInstr);
+ CInstr.Nop();
+ }
+ var ISlot = new object[((IMethodDescriptor)Instr.Operand)
+ .Signature.GetTotalParameterCount()];
+ for (int i = 0; i < ISlot.Length; i++) {
+ var Value = vm.CurrentState.Stack.Pop();
+ ISlot[i] = Value switch {
+ I4Value I4 => I4.I32,
+ I8Value I8 => I8.I64,
+ FValue F => F.F64,
+ Float32Value F32 => F32.F32,
+ Float64Value F64 => F64.F64,
+ Integer16Value I6 => I6.I16,
+ Integer32Value I32 => I32.I32,
+ Integer64Value I64 => I64.I64,
+ _ => throw new NotSupportedException(nameof(Value))
+ };
+ }
+ var InvocationValue = context.ReflectionCorlib.ResolveMethod(((IMethodDescriptor)Instr.Operand).MetadataToken.ToInt32())
+ .Invoke(null, ISlot);
+ Instr.OpCode = ((IMethodDescriptor)Instr.Operand).Signature.ReturnType.ElementType switch {
+ ElementType.I4 => CilOpCodes.Ldc_I4,
+ ElementType.I8 => CilOpCodes.Ldc_I8,
+ ElementType.R4 => CilOpCodes.Ldc_R4,
+ ElementType.R8 => CilOpCodes.Ldc_R8,
+ _ => CilOpCodes.Ldc_I4,
+ };
+ Instr.Operand = InvocationValue;
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Protections/Mutations/Purifier/MutationPurifier.cs b/UnSealer.Protections/Mutations/Purifier/MutationPurifier.cs
new file mode 100644
index 0000000..74189fe
--- /dev/null
+++ b/UnSealer.Protections/Mutations/Purifier/MutationPurifier.cs
@@ -0,0 +1,34 @@
+
+#region Usings
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.Protections.Mutations.Purifier {
+ public class MutationPurifier : Protection {
+ public override string Name => "Mutation Purifier";
+
+ public override string Description => "Purify Arithmetics & Operators & Other Mutations.";
+
+ public override string Id => "mpure";
+
+ public override string Author => "CLand";
+
+ public override void InitPipeline(Context context, Pipeline pipeline) {
+ pipeline.InsertPostStage(PipelineStage.BeginModule, new ProtectionPhase[] {
+ new MathPurifier(this),
+ new NopPurifier(this),
+ /* new ArithmeticPurifier(this), */
+ new NopPurifier(this),
+ new SizeOfPurifier(this),
+ new NopPurifier(this),
+ new MathPurifier(this),
+ new NopPurifier(this),
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Protections/Mutations/Purifier/NopPurifier.cs b/UnSealer.Protections/Mutations/Purifier/NopPurifier.cs
new file mode 100644
index 0000000..ded6cfd
--- /dev/null
+++ b/UnSealer.Protections/Mutations/Purifier/NopPurifier.cs
@@ -0,0 +1,30 @@
+
+#region Usings
+using AsmResolver.DotNet;
+using AsmResolver.PE.DotNet.Cil;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.Protections.Mutations.Purifier {
+ public class NopPurifier : ProtectionPhase {
+ public NopPurifier(Protection ParentBase)
+ : base(ParentBase) { }
+
+ public override string Name => "Nop Cleaning Phase.";
+
+ public override ProtectionTargets PhaseTargets => ProtectionTargets.Methods;
+
+ public override void Execute(Context context, IEnumerable targets) {
+ foreach (var Method in targets.OfType().Where(x => x.CilMethodBody is not null)) {
+ var IL = Method.CilMethodBody.Instructions;
+ var Branches = Method.CilMethodBody.GetBranches();
+ foreach (var Instr in IL.Where(x => x.IsCode(CilCode.Nop) && !Branches.Contains(x)).ToArray())
+ IL.Remove(Instr);
+ IL.CalculateOffsets();
+ }
+ }
+ }
+}
diff --git a/UnSealer.Protections/Mutations/Purifier/SizeOfPurifier.cs b/UnSealer.Protections/Mutations/Purifier/SizeOfPurifier.cs
new file mode 100644
index 0000000..ac563f5
--- /dev/null
+++ b/UnSealer.Protections/Mutations/Purifier/SizeOfPurifier.cs
@@ -0,0 +1,32 @@
+
+#region Usings
+using AsmResolver.DotNet;
+using AsmResolver.DotNet.Memory;
+using AsmResolver.PE.DotNet.Cil;
+using System.Collections.Generic;
+using System.Linq;
+using UnSealer.Core;
+#endregion
+
+namespace UnSealer.Protections.Mutations.Purifier {
+ public class SizeOfPurifier : ProtectionPhase {
+ public SizeOfPurifier(Protection ParentBase)
+ : base(ParentBase) { }
+
+ public override string Name => "SizeOf Cleaning Phase";
+
+ public override ProtectionTargets PhaseTargets => ProtectionTargets.Methods;
+
+ public override void Execute(Context context, IEnumerable targets) {
+ foreach (var Method in targets.OfType().Where(x => x.CilMethodBody is not null)) {
+ var Instructions = Method.CilMethodBody.Instructions;
+ foreach (var SizeOfInstr in Instructions.Where(x => x.IsCode(CilCode.Sizeof) && x.Operand is not TypeSpecification /* No Generics. */)) {
+ var Size = (SizeOfInstr.Operand as ITypeDefOrRef).GetImpliedMemoryLayout(context.Module.Is32Module()).Size;
+ var NewInstr = CilInstruction.CreateLdcI4((int)Size);
+ SizeOfInstr.OpCode = NewInstr.OpCode;
+ SizeOfInstr.Operand = NewInstr.Operand;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/UnSealer.Protections/UnSealer.Protections.csproj b/UnSealer.Protections/UnSealer.Protections.csproj
new file mode 100644
index 0000000..d23414f
--- /dev/null
+++ b/UnSealer.Protections/UnSealer.Protections.csproj
@@ -0,0 +1,29 @@
+
+
+
+ net5.0
+
+
+
+
+
+
+
+
+ ..\Echo\Echo.Concrete.dll
+
+
+ ..\Echo\Echo.ControlFlow.dll
+
+
+ ..\Echo\Echo.Core.dll
+
+
+ ..\Echo\Echo.DataFlow.dll
+
+
+ ..\Echo\Echo.Platforms.AsmResolver.dll
+
+
+
+
diff --git a/UnSealer.sln b/UnSealer.sln
new file mode 100644
index 0000000..095a3d1
--- /dev/null
+++ b/UnSealer.sln
@@ -0,0 +1,37 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31321.278
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnSealer.CLI", "UnSealer.CLI\UnSealer.CLI.csproj", "{CC7E49F5-32C3-4350-8B0D-BBBA1683646B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnSealer.Core", "UnSealer.Core\UnSealer.Core.csproj", "{D1E24FA3-032D-457B-8669-0E8D7DF5F38E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnSealer.Protections", "UnSealer.Protections\UnSealer.Protections.csproj", "{2DD16FE1-FF72-4734-8CE5-AEEC2B61D37E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {CC7E49F5-32C3-4350-8B0D-BBBA1683646B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CC7E49F5-32C3-4350-8B0D-BBBA1683646B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CC7E49F5-32C3-4350-8B0D-BBBA1683646B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CC7E49F5-32C3-4350-8B0D-BBBA1683646B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D1E24FA3-032D-457B-8669-0E8D7DF5F38E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D1E24FA3-032D-457B-8669-0E8D7DF5F38E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D1E24FA3-032D-457B-8669-0E8D7DF5F38E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D1E24FA3-032D-457B-8669-0E8D7DF5F38E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2DD16FE1-FF72-4734-8CE5-AEEC2B61D37E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2DD16FE1-FF72-4734-8CE5-AEEC2B61D37E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2DD16FE1-FF72-4734-8CE5-AEEC2B61D37E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2DD16FE1-FF72-4734-8CE5-AEEC2B61D37E}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {AA3D0139-3E29-4FC8-BB24-5318E0D1300E}
+ EndGlobalSection
+EndGlobal