GithubHelp home page GithubHelp logo

puff / eazydevirt Goto Github PK

View Code? Open in Web Editor NEW
139.0 5.0 31.0 9.36 MB

A tool for automatically reconstructing IL code from an assembly virtualized with Eazfuscator.NET

License: GNU General Public License v3.0

C# 100.00%
devirtualizer eazfuscator

eazydevirt's People

Contributors

puff avatar thehelltower avatar void-stack avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

eazydevirt's Issues

VM structs' field read order different across samples.

As with #4, this is because field order changes across samples, likely due to different Eazfuscator.NET versions being used.
This is an issue because reading the fields increments the position by the amount of bytes read. Since the amount of bytes read varies per field, this can result in invalid data or a crash.

The VM structs' fields need to be pattern matched where they are used and cross referenced with where they are set.

Stind and Stobj

The stind (and stobj) opcode handlers all use the same method, however the method has no parameters, therefore having no way of differentiating them through pattern matching, unless we match each VMOperandType as well.

An alternative to pattern matching could be to iterate through the devirtualized instructions and determine the stind type from stack analysis. This can probably be done with Echo.

Resolver issues

The resolver is slow, fails to handle some types, and is hard to read and navigate. It has problems with nested types and types/methods using generics in particular.

It would be good to completely rewrite it. There are many useful helpers in AsmResolver that could be utilized like TypeNameParser, SignatureComparer, GenericContext, TypeDescriptorExtensions.

VMInlineOperandData may also need to be rewritten. Having it recursively read the data of each VMInlineOperand property in it (DeclaringType, GenericArguments, etc) would be helpful, especially when resolving methods utilizing type generics.

Some Unknown Issues

[*] Executing ResourceParsing...
[!] Failed to find VM resource stream getter method.
[!] Failed to find VM resource stream initialization method.
[!] Failed to find valid VM resource modulus string method. Have strings been decrypted?
Unhandled exception: System.NullReferenceException: Object reference not set to an instance of an object.
   at EazyDevirt.Devirtualization.Pipeline.ResourceParsing.Init() in D:\GitHub\EazyDevirt\src\EazyDevirt\Devirtualization\Pipeline\ResourceParsing.cs:line 98
   at EazyDevirt.Devirtualization.Pipeline.ResourceParsing.Run() in D:\GitHub\EazyDevirt\src\EazyDevirt\Devirtualization\Pipeline\ResourceParsing.cs:line 106
   at EazyDevirt.Devirtualization.Devirtualizer.Run() in D:\GitHub\EazyDevirt\src\EazyDevirt\Devirtualization\Devirtualizer.cs:line 28
   at EazyDevirt.Program.Run(DevirtualizationOptions options) in D:\GitHub\EazyDevirt\src\EazyDevirt\Program.cs:line 32
   at System.CommandLine.Handler.<>c__DisplayClass2_0`1.<SetHandler>b__0(InvocationContext context)
   at System.CommandLine.Invocation.AnonymousCommandHandler.Invoke(InvocationContext context)
   at System.CommandLine.Invocation.AnonymousCommandHandler.InvokeAsync(InvocationContext context)
   at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass17_0.<<UseParseErrorReporting>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass12_0.<<UseHelp>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass22_0.<<UseVersionOption>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass19_0.<<UseTypoCorrections>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__18_0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<UseParseDirective>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__5_0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass8_0.<<UseExceptionHandler>b__0>d.MoveNext()
   

File : WRobot.zip

Vendor : https://wrobot.eu/

VM BinaryReader endianness different across samples.

Need to implement a way to parse the VMBinaryReader methods. This is because the endianness of the VM resource stream changes across samples, likely due to different Eazfuscator.NET versions being used.
The order of the OR operators doesn't matter, it's the index of the byte array for each OR operation that matters.

Also need this for the VMMemoryStream's special ReadInt32 for opcodes/operands.

Instead of parsing, the VMBinaryReader endianness could be implemented using emulation, possibly from the Echo library.

Error

Hi!
Can you help me understand error?
When I try to run with sample there is an error
Unhandled exception: System.Exception: Failed to get VM Declaring type!

If you need more tool output info just ask

Resolver does not support types from other assemblies

The type resolver will not resolve types from assemblies other than the current one, and runtime assemblies.

This causes issues with resolving methods especially, as the declaring type is always null in these cases.

eaz Engine

It looks like eaz will decrypt part of the real VM Engine with Real Names.
Check it here:
image
image
image
image
image
I think it will be very helpful to handle OpCodeMapping stage.

Inefficient VM reading logic

Since we need to decrypt the entire VM resource, it might be more efficient to decrypt it fully once instead of decrypting it via a stream like the current implementation (VMCipherStream).

Data Virtualization

Currently, this project does not support devirtualizing data virtualization. This isn't high priority though, as you can still see the plain data when analyzing statically.

Data virtualization replaces the fields with a structure, and setting/getting the variable with a method in the struct:
image

SetValue() encrypts the value and stores it in a field in the struct.
GetValue() returns the decrypted value.

From analysis, it seems these structs all share at least two things:

  1. Using internal access modifier
  2. A constructor with a single string argument (it's never called anywhere)
    2.a. Primitive:
    image
    2.b. Reference:
    image

From Eazfuscator's documentation, only primitive types, one-dimensional arrays of primitive types, and the following types are supported:

  • System.DateTime
  • System.Enum
  • System.Guid
  • System.String
  • System.TimeSpan

For detection of this, we could first look through the fields and find any that are structs. Then, look at that struct's constructor to check if it matches either the primitive constructor or reference constructor (see above screenshots).

Next, we would have to map the type with the struct.
For primitive types, we can either find GetValue() or use the field set in the constructor to get the type.
For reference types, this would have to be done by either finding GetValue() and using its' return type or finding SetValue() and using its only argument's type.

To find the GetValue() method, iterate through the struct's methods where the return type is not void and the instructions contain an ldfld to the encrypted field (which is always the field set in the constructor).
For the SetValue() method, search for a method in the struct where the return type is void, and contains a single argument. Then check if the instructions contain an stfld to the encrypted field (which is always the field set in the constructor).

Finally, once we've found the original type, it's as simple as replacing the field type and iterating through every method's instructions and replacing calls to GetValue and SetValue on these field structs. Using access modifiers could help optimize this, for example, by only checking methods in the current type for private fields.

Homomorphic Encryption

Currently, this project does not support decrypting branches encrypted with homomorphic encryption.

Here's a basic representation of how HM works in eaz:

// pretend this is virtualized code
var input = int.Parse(Console.ReadLine());
if (Encrypt(input) == encryptedConstant)
{
  // Homomorphic Encryption Start VM OpCode
  var oldReader = VM.VMInstructionsReader;
  VM.VMInstructionsReader = new VMInstructionsReader(decryptionKey: input);

  // next instructions will be decrypted with the new key
  Console.WriteLine("homomorphic encryption woah");
  
  // Homomorphic Encryption End VM OpCode
  VM.VMInstructionsReader = oldReader;
}
// next instructions will be decrypted with the original decryption key
Console.WriteLine("this uses the original instructions reader");

Untested but looks like it can be nested too.

Support using as a library

Currently, everything is built into a standalone executable. It would be nice to be able to use the project as a library to allow a more extensible pipeline.

Tasks to be done:

  • Split Core into separate projects.
  • Make Core completely separated from the pipeline.
    - For example, IO namespace uses DevirtualizationContext from the pipeline. We should move IO away from the Core namespace.
  • Fix the internal access modifier spam.
  • Split MethodDevirtualizer stage into MethodDisassembler and MethodRecompiler stages.
    - Decouple VMMethod and other VM architecture from CIL and keep them more VMIL.
    - Allows other stages to modify instructions before recompilation (i.e. Fixers or Data Devirtualization)
  • Move Devirtualization namespace to its own project and implement an IPipeline.
    - Decentralizes the pipeline and allow for more pipelines to be created and used.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.