From 5245bef0059f1eb23ed4345e670c7d877824cacf Mon Sep 17 00:00:00 2001 From: CLand Date: Mon, 7 Jun 2021 04:49:33 -0700 Subject: [PATCH 01/10] v3 Version Pump. --- Echo/Echo.Concrete.dll | Bin 0 -> 46592 bytes Echo/Echo.Concrete.xml | 1983 +++++++++ Echo/Echo.ControlFlow.dll | Bin 0 -> 110080 bytes Echo/Echo.ControlFlow.xml | 2843 ++++++++++++ Echo/Echo.Core.dll | Bin 0 -> 35328 bytes Echo/Echo.Core.xml | 1444 ++++++ Echo/Echo.DataFlow.dll | Bin 0 -> 43008 bytes Echo/Echo.DataFlow.xml | 1087 +++++ Echo/Echo.Platforms.AsmResolver.deps.json | 339 ++ Echo/Echo.Platforms.AsmResolver.dll | Bin 0 -> 106496 bytes Echo/Echo.Platforms.AsmResolver.xml | 3910 +++++++++++++++++ UnSealer.CLI/ConsoleLogger.cs | 31 + UnSealer.CLI/Program.cs | 43 + UnSealer.CLI/UnSealer.CLI.csproj | 17 + UnSealer.Core/ArgumentsParser.cs | 34 + UnSealer.Core/Context.cs | 63 + UnSealer.Core/ILogger.cs | 48 + UnSealer.Core/Pipeline.cs | 71 + UnSealer.Core/PipelineStage.cs | 20 + UnSealer.Core/PluginDiscovery.cs | 36 + UnSealer.Core/Protection.cs | 26 + UnSealer.Core/ProtectionPhase.cs | 37 + UnSealer.Core/ProtectionTargets.cs | 32 + UnSealer.Core/UnSealer.Core.csproj | 11 + UnSealer.Core/UnSealerEngine.cs | 60 + UnSealer.Core/Utilities.cs | 188 + .../Devirtualizer/CawkVM/CawkVM.cs | 50 + .../Devirtualizer/CawkVM/Disassembler.cs | 183 + .../Devirtualizer/CawkVM/DiscoveryPhase.cs | 45 + .../Devirtualizer/CawkVM/RestorationPhase.cs | 60 + UnSealer.Protections/Misc/CalliFixer.cs | 47 + .../Misc/ConfuserStringDecrypter.cs | 146 + .../Misc/L2Field/AnalyzePhase.cs | 45 + .../Misc/L2Field/L2FieldProtection.cs | 27 + .../Misc/L2Field/RestorationPhase.cs | 54 + UnSealer.Protections/Misc/OutlinerFixer.cs | 54 + UnSealer.Protections/Misc/ProxyFixer.cs | 48 + .../Mutations/Purifier/ArithmeticPurifier.cs | 87 + .../Mutations/Purifier/MathPurifier.cs | 82 + .../Mutations/Purifier/MutationPurifier.cs | 34 + .../Mutations/Purifier/NopPurifier.cs | 30 + .../Mutations/Purifier/SizeOfPurifier.cs | 32 + .../UnSealer.Protections.csproj | 29 + UnSealer.sln | 37 + 44 files changed, 13413 insertions(+) create mode 100644 Echo/Echo.Concrete.dll create mode 100644 Echo/Echo.Concrete.xml create mode 100644 Echo/Echo.ControlFlow.dll create mode 100644 Echo/Echo.ControlFlow.xml create mode 100644 Echo/Echo.Core.dll create mode 100644 Echo/Echo.Core.xml create mode 100644 Echo/Echo.DataFlow.dll create mode 100644 Echo/Echo.DataFlow.xml create mode 100644 Echo/Echo.Platforms.AsmResolver.deps.json create mode 100644 Echo/Echo.Platforms.AsmResolver.dll create mode 100644 Echo/Echo.Platforms.AsmResolver.xml create mode 100644 UnSealer.CLI/ConsoleLogger.cs create mode 100644 UnSealer.CLI/Program.cs create mode 100644 UnSealer.CLI/UnSealer.CLI.csproj create mode 100644 UnSealer.Core/ArgumentsParser.cs create mode 100644 UnSealer.Core/Context.cs create mode 100644 UnSealer.Core/ILogger.cs create mode 100644 UnSealer.Core/Pipeline.cs create mode 100644 UnSealer.Core/PipelineStage.cs create mode 100644 UnSealer.Core/PluginDiscovery.cs create mode 100644 UnSealer.Core/Protection.cs create mode 100644 UnSealer.Core/ProtectionPhase.cs create mode 100644 UnSealer.Core/ProtectionTargets.cs create mode 100644 UnSealer.Core/UnSealer.Core.csproj create mode 100644 UnSealer.Core/UnSealerEngine.cs create mode 100644 UnSealer.Core/Utilities.cs create mode 100644 UnSealer.Protections/Devirtualizer/CawkVM/CawkVM.cs create mode 100644 UnSealer.Protections/Devirtualizer/CawkVM/Disassembler.cs create mode 100644 UnSealer.Protections/Devirtualizer/CawkVM/DiscoveryPhase.cs create mode 100644 UnSealer.Protections/Devirtualizer/CawkVM/RestorationPhase.cs create mode 100644 UnSealer.Protections/Misc/CalliFixer.cs create mode 100644 UnSealer.Protections/Misc/ConfuserStringDecrypter.cs create mode 100644 UnSealer.Protections/Misc/L2Field/AnalyzePhase.cs create mode 100644 UnSealer.Protections/Misc/L2Field/L2FieldProtection.cs create mode 100644 UnSealer.Protections/Misc/L2Field/RestorationPhase.cs create mode 100644 UnSealer.Protections/Misc/OutlinerFixer.cs create mode 100644 UnSealer.Protections/Misc/ProxyFixer.cs create mode 100644 UnSealer.Protections/Mutations/Purifier/ArithmeticPurifier.cs create mode 100644 UnSealer.Protections/Mutations/Purifier/MathPurifier.cs create mode 100644 UnSealer.Protections/Mutations/Purifier/MutationPurifier.cs create mode 100644 UnSealer.Protections/Mutations/Purifier/NopPurifier.cs create mode 100644 UnSealer.Protections/Mutations/Purifier/SizeOfPurifier.cs create mode 100644 UnSealer.Protections/UnSealer.Protections.csproj create mode 100644 UnSealer.sln diff --git a/Echo/Echo.Concrete.dll b/Echo/Echo.Concrete.dll new file mode 100644 index 0000000000000000000000000000000000000000..d90d318c828cb0264eb35b27a846405f6f9c7fed GIT binary patch literal 46592 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 + + + 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 0000000000000000000000000000000000000000..795854837d924cd8048debb95b565e6aa17138cc GIT binary patch literal 110080 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 + + + 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 0000000000000000000000000000000000000000..fadc5c31be059427ec91b0edee8fc87fc8b474be GIT binary patch literal 35328 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 C6#gOr literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..42b0a2ffa6019763a1a151cd72b5ff6f02d41fc4 GIT binary patch literal 43008 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..6ad83dbc47ae0f118ee6471819c1abdefa3e8178 GIT binary patch literal 106496 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�i)}Ta(Xs?~NYlY2G2ek3OA3yBJ_gDS>CuD_Z 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 qdPtalkfMHpbM!LQm?P`I|NX5!aF2mVK!^ + + + 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/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..50dfdf2 --- /dev/null +++ b/UnSealer.CLI/Program.cs @@ -0,0 +1,43 @@ + +#region Usings +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using static UnSealer.Core.UnSealerEngine; +using UnSealer.Core; +#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); + Banner(); + Protections = PluginDiscovery.GetCurrentDirPlugins(ConsoleLogger); + 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); + } + } + 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..f6db37a --- /dev/null +++ b/UnSealer.Protections/Misc/ConfuserStringDecrypter.cs @@ -0,0 +1,146 @@ + +#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 + 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 From 84491ca779a9b72436c658a9c67b62e6625a9704 Mon Sep 17 00:00:00 2001 From: CLand <75072673+CursedLand@users.noreply.github.com> Date: Mon, 7 Jun 2021 04:52:15 -0700 Subject: [PATCH 02/10] Create LICENSE --- LICENSE | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE 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 +. From c54a8a13ffcf31c8f67ddcd503a1cd7e98aedbce Mon Sep 17 00:00:00 2001 From: CLand <75072673+CursedLand@users.noreply.github.com> Date: Mon, 7 Jun 2021 05:23:05 -0700 Subject: [PATCH 03/10] Create README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..d0d532b --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# UnSealer + From 04a3c367b078e2744adf7379ebc16dc33f98c35a Mon Sep 17 00:00:00 2001 From: CLand <75072673+CursedLand@users.noreply.github.com> Date: Mon, 7 Jun 2021 05:46:37 -0700 Subject: [PATCH 04/10] Add files via upload --- CLIPreview.PNG | Bin 0 -> 8600 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 CLIPreview.PNG diff --git a/CLIPreview.PNG b/CLIPreview.PNG new file mode 100644 index 0000000000000000000000000000000000000000..599bc86891a440a2564ac966ca790573e39871cc GIT binary patch literal 8600 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 literal 0 HcmV?d00001 From c1db718d2b87345a4d30ba99490bcf243595f4d1 Mon Sep 17 00:00:00 2001 From: CLand <75072673+CursedLand@users.noreply.github.com> Date: Mon, 7 Jun 2021 05:53:46 -0700 Subject: [PATCH 05/10] Update README.md --- README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.md b/README.md index d0d532b..761fb30 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,29 @@ # 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) From 88bc5436f465eedb4b10b0f9af01069783b59ae4 Mon Sep 17 00:00:00 2001 From: CLand <75072673+CursedLand@users.noreply.github.com> Date: Mon, 7 Jun 2021 06:07:44 -0700 Subject: [PATCH 06/10] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 761fb30..8196f72 100644 --- a/README.md +++ b/README.md @@ -27,3 +27,7 @@ dotnet build # CLI-Preview ![alt text](https://github.com/CursedLand/UnSealer/blob/master/CLIPreview.PNG) + +# Credits +- [AsmResolver](https://github.com/Washi1337/AsmResolver) +- [Echo](https://github.com/Washi1337/Echo) From 8de69a59053a1c746e0e07a5f9d76ec191637011 Mon Sep 17 00:00:00 2001 From: CLand <75072673+CursedLand@users.noreply.github.com> Date: Tue, 8 Jun 2021 13:09:16 +0200 Subject: [PATCH 07/10] Credit Update. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8196f72..823145f 100644 --- a/README.md +++ b/README.md @@ -29,5 +29,5 @@ dotnet build ![alt text](https://github.com/CursedLand/UnSealer/blob/master/CLIPreview.PNG) # Credits -- [AsmResolver](https://github.com/Washi1337/AsmResolver) -- [Echo](https://github.com/Washi1337/Echo) +- [AsmResolver](https://github.com/Washi1337/AsmResolver) - (Washi) +- [Echo](https://github.com/Washi1337/Echo) - (Washi) From 6ccba46bd9876d5a24d6424c580a25088f3a9c64 Mon Sep 17 00:00:00 2001 From: CLand Date: Wed, 9 Jun 2021 04:44:13 -0700 Subject: [PATCH 08/10] Update ConfuserStringDecrypter. --- UnSealer.Protections/Misc/ConfuserStringDecrypter.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UnSealer.Protections/Misc/ConfuserStringDecrypter.cs b/UnSealer.Protections/Misc/ConfuserStringDecrypter.cs index f6db37a..aadea05 100644 --- a/UnSealer.Protections/Misc/ConfuserStringDecrypter.cs +++ b/UnSealer.Protections/Misc/ConfuserStringDecrypter.cs @@ -95,6 +95,8 @@ Instr.Operand is MethodSpecification GenericMethod && /* .Decode */ S = 0U; #endregion #endregion + /* Assume Fake Parameter. */ + if (S == default) S = Convert.ChangeType(default, PType); IOSlot[Count] = S; } try { From 56c5c901b7276515b6b7f786279fbd871a1e32a3 Mon Sep 17 00:00:00 2001 From: CLand Date: Wed, 9 Jun 2021 04:57:29 -0700 Subject: [PATCH 09/10] Update ConfuserStringDecrypter. --- UnSealer.Protections/Misc/ConfuserStringDecrypter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UnSealer.Protections/Misc/ConfuserStringDecrypter.cs b/UnSealer.Protections/Misc/ConfuserStringDecrypter.cs index aadea05..b20acd3 100644 --- a/UnSealer.Protections/Misc/ConfuserStringDecrypter.cs +++ b/UnSealer.Protections/Misc/ConfuserStringDecrypter.cs @@ -96,7 +96,7 @@ Instr.Operand is MethodSpecification GenericMethod && /* .Decode */ #endregion #endregion /* Assume Fake Parameter. */ - if (S == default) S = Convert.ChangeType(default, PType); + if (S == default) S = Convert.ChangeType(new object(), PType); IOSlot[Count] = S; } try { From b006b2ecb163ab3e27c5e51a1803067518c8a1cb Mon Sep 17 00:00:00 2001 From: Zebo Li Date: Sat, 17 Jul 2021 23:13:32 +0800 Subject: [PATCH 10/10] Add function to print usage and loaded plugin's information. --- UnSealer.CLI/Program.cs | 72 +++++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 13 deletions(-) diff --git a/UnSealer.CLI/Program.cs b/UnSealer.CLI/Program.cs index 50dfdf2..3b1b65d 100644 --- a/UnSealer.CLI/Program.cs +++ b/UnSealer.CLI/Program.cs @@ -5,23 +5,32 @@ using System.Diagnostics.CodeAnalysis; using static UnSealer.Core.UnSealerEngine; using UnSealer.Core; +using System.Diagnostics; #endregion -namespace UnSealer.CLI { - internal class Program { +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) { + [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); - Banner(); + Protections = PluginDiscovery.GetCurrentDirPlugins(ConsoleLogger); - if (args.Length <= 0) { + + Banner(); + PrintUsage(Protections); + + if (args.Length <= 0) + { Console.Write("[~] Enter Arguments : "); var pargs = Console.ReadLine()!.Replace("\"", string.Empty).Split(' '); Console.Clear(); @@ -29,15 +38,52 @@ static void Main(string[] args) { var ParsedArgs = new ArgumentsParser(Protections, pargs).Result; ExecuteEngine(ParsedArgs, ConsoleLogger); } - else { + else + { var ArgsParsed = new ArgumentsParser(Protections, args).Result; ExecuteEngine(ArgsParsed, ConsoleLogger); } } - 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; - } - } + + /// + /// 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