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 +![alt text](https://github.com/CursedLand/UnSealer/blob/master/CLIPreview.PNG) + +# 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