Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data Virtualization #10

Open
puff opened this issue May 26, 2023 · 0 comments
Open

Data Virtualization #10

puff opened this issue May 26, 2023 · 0 comments
Labels
enhancement New feature or request

Comments

@puff
Copy link
Owner

puff commented May 26, 2023

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. TODO: Check if custom getter/setters are compatible. Using access modifiers could help optimize this, for example, by only checking methods in the current type for private fields.

@puff puff added the enhancement New feature or request label May 26, 2023
@puff puff changed the title Support Data Virtualization Data Virtualization Jan 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant