undebel / NoFuserEx

Free deobfuscator for ConfuserEx.
MIT License
396 stars 98 forks source link

Trying understanding Anti-Tampering of ConfuserEx #7

Closed GrimSmiler closed 8 years ago

GrimSmiler commented 8 years ago

Hey!

Sorry to bother Your again. I am trying to understand how Anti-Tampering works in ConfuserEx. It seems that it encrypts the CIL commands and decrypts them at runtime (key and calculation are inserted in the module static constructor). But i cannot fully understand how it encrypts the code.

Is there a chance You would be willing to shed a bit of light on this mystery for me?

SlowLogicBoy commented 8 years ago

https://github.com/yck1509/ConfuserEx/blob/3c9c29d9daf2f1259edf69054c5693d5d225a980/Confuser.Runtime/AntiTamper.Normal.cs#L8 Basically they use this.

GrimSmiler commented 8 years ago

Thanks @SlowLogicBoy !

Debugging a anti-tampering process gut me to this code here

From my understnading, ConfuserEx first adds some calculation of pointers/values to the Initializer of the module (static constructor) (see public void HandleInject at line 28)

When ConfuserEx is done with injecting the new code into the constructor, in public void HandleMD at line 98, ConfuserEx adds a listening event that does 2 things:

  1. Create Sections
  2. Encrypt the Sections

The questions that came to my mind are the follwoing:

  1. What is happening in the Constructor method? (public void HandleInject at line 28)
  2. How does the program get the dencrypted CIL commands at runtime?
  3. Why/What for does the Anti-Tampering protection creates section? (void CreateSections(ModuleWriterBase writer) line 112)
  4. What happens in void EncryptSection(ModuleWriterBase writer) at line 175, between lines 176 and 213 (see code below).

I understand that I am asking for too much detail, but any smallest hint would be very appriciated. Sadly my knowledge of CIL level work and dll architecture is very close to 0.

Code of method in question 4.

`Stream stream = writer.DestinationStream; //line 176 var reader = new BinaryReader(writer.DestinationStream); stream.Position = 0x3C; stream.Position = reader.ReadUInt32();

        stream.Position += 6;
        ushort sections = reader.ReadUInt16();
        stream.Position += 0xc;
        ushort optSize = reader.ReadUInt16();
        stream.Position += 2 + optSize;

        uint encLoc = 0, encSize = 0;
        int origSects = -1;
        if (writer is NativeModuleWriter && writer.Module is ModuleDefMD)
            origSects = ((ModuleDefMD)writer.Module).MetaData.PEImage.ImageSectionHeaders.Count;
        for (int i = 0; i < sections; i++) {
            uint nameHash;
            if (origSects > 0) {
                origSects--;
                stream.Write(new byte[8], 0, 8);
                nameHash = 0;
            }
            else
                nameHash = reader.ReadUInt32() * reader.ReadUInt32();
            stream.Position += 8;
            if (nameHash == name1 * name2) {
                encSize = reader.ReadUInt32();
                encLoc = reader.ReadUInt32();
            }
            else if (nameHash != 0) {
                uint sectSize = reader.ReadUInt32();
                uint sectLoc = reader.ReadUInt32();
                Hash(stream, reader, sectLoc, sectSize);
            }
            else
                stream.Position += 8;
            stream.Position += 16;
        }// line 213`