Example #1
0
        private void CreateSection(ModuleWriter writer)
        {
            // move some PE parts to separate section to prevent it from being hashed
            var peSection = new PESection("", 0x60000020);
            bool moved = false;
            uint alignment;
            if (writer.StrongNameSignature != null) {
                alignment = writer.TextSection.Remove(writer.StrongNameSignature).Value;
                peSection.Add(writer.StrongNameSignature, alignment);
                moved = true;
            }
            if (writer.ImportAddressTable != null) {
                alignment = writer.TextSection.Remove(writer.ImportAddressTable).Value;
                peSection.Add(writer.ImportAddressTable, alignment);
                moved = true;
            }
            if (writer.StartupStub != null) {
                alignment = writer.TextSection.Remove(writer.StartupStub).Value;
                peSection.Add(writer.StartupStub, alignment);
                moved = true;
            }
            if (moved)
                writer.Sections.Add(peSection);

            // create section
            var nameBuffer = new byte[8];
            nameBuffer[0] = (byte)(name1 >> 0);
            nameBuffer[1] = (byte)(name1 >> 8);
            nameBuffer[2] = (byte)(name1 >> 16);
            nameBuffer[3] = (byte)(name1 >> 24);
            nameBuffer[4] = (byte)(name2 >> 0);
            nameBuffer[5] = (byte)(name2 >> 8);
            nameBuffer[6] = (byte)(name2 >> 16);
            nameBuffer[7] = (byte)(name2 >> 24);
            var newSection = new PESection(Encoding.ASCII.GetString(nameBuffer), 0xE0000040);
            writer.Sections.Insert(random.NextInt32(writer.Sections.Count), newSection);

            // random padding at beginning to prevent revealing hash key
            newSection.Add(new ByteArrayChunk(random.NextBytes(0x10)), 0x10);

            // create index
            var bodyIndex = new JITBodyIndex(methods.Select(method => writer.MetaData.GetToken(method).Raw));
            newSection.Add(bodyIndex, 0x10);

            // move initialization away from module initializer
            cctorRepl.Body = cctor.Body;
            cctor.Body = new CilBody();
            cctor.Body.Instructions.Add(Instruction.Create(OpCodes.Call, initMethod));
            cctor.Body.Instructions.Add(Instruction.Create(OpCodes.Call, cctorRepl));
            cctor.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));

            // save methods
            foreach (MethodDef method in methods.WithProgress(context.Logger)) {
                if (!method.HasBody)
                    continue;

                MDToken token = writer.MetaData.GetToken(method);

                var jitBody = new JITMethodBody();
                var bodyWriter = new JITMethodBodyWriter(writer.MetaData, method.Body, jitBody, random.NextUInt32(), writer.MetaData.KeepOldMaxStack || method.Body.KeepOldMaxStack);
                bodyWriter.Write();
                jitBody.Serialize(token.Raw, key, fieldLayout);
                bodyIndex.Add(token.Raw, jitBody);

                method.Body = NopBody;
                writer.MetaData.TablesHeap.MethodTable[token.Rid].ImplFlags |= (ushort)MethodImplAttributes.NoInlining;
                context.CheckCancellation();
            }
            bodyIndex.PopulateSection(newSection);

            // padding to prevent bad size due to shift division
            newSection.Add(new ByteArrayChunk(new byte[4]), 4);
        }
Example #2
0
        private void EncryptSection(ModuleWriter writer)
        {
            Stream stream = writer.DestinationStream;
            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;
            for (int i = 0; i < sections; i++) {
                uint 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);
                }
                stream.Position += 16;
            }

            uint[] key = DeriveKey();
            encSize >>= 2;
            stream.Position = encLoc;
            var result = new uint[encSize];
            for (uint i = 0; i < encSize; i++) {
                uint data = reader.ReadUInt32();
                result[i] = data ^ key[i & 0xf];
                key[i & 0xf] = (key[i & 0xf] ^ data) + 0x3dbb2819;
            }
            var byteResult = new byte[encSize << 2];
            Buffer.BlockCopy(result, 0, byteResult, 0, byteResult.Length);
            stream.Position = encLoc;
            stream.Write(byteResult, 0, byteResult.Length);
        }
Example #3
0
        private void CreateSections(ModuleWriter writer)
        {
            var nameBuffer = new byte[8];
            nameBuffer[0] = (byte)(name1 >> 0);
            nameBuffer[1] = (byte)(name1 >> 8);
            nameBuffer[2] = (byte)(name1 >> 16);
            nameBuffer[3] = (byte)(name1 >> 24);
            nameBuffer[4] = (byte)(name2 >> 0);
            nameBuffer[5] = (byte)(name2 >> 8);
            nameBuffer[6] = (byte)(name2 >> 16);
            nameBuffer[7] = (byte)(name2 >> 24);
            var newSection = new PESection(Encoding.ASCII.GetString(nameBuffer), 0xE0000040);
            writer.Sections.Insert(0, newSection); // insert first to ensure proper RVA

            uint alignment;

            alignment = writer.TextSection.Remove(writer.MetaData).Value;
            writer.TextSection.Add(writer.MetaData, alignment);

            alignment = writer.TextSection.Remove(writer.NetResources).Value;
            writer.TextSection.Add(writer.NetResources, alignment);

            alignment = writer.TextSection.Remove(writer.Constants).Value;
            newSection.Add(writer.Constants, alignment);

            // move some PE parts to separate section to prevent it from being hashed
            var peSection = new PESection("", 0x60000020);
            bool moved = false;
            if (writer.StrongNameSignature != null) {
                alignment = writer.TextSection.Remove(writer.StrongNameSignature).Value;
                peSection.Add(writer.StrongNameSignature, alignment);
                moved = true;
            }
            if (writer.ImportAddressTable != null) {
                alignment = writer.TextSection.Remove(writer.ImportAddressTable).Value;
                peSection.Add(writer.ImportAddressTable, alignment);
                moved = true;
            }
            if (writer.StartupStub != null) {
                alignment = writer.TextSection.Remove(writer.StartupStub).Value;
                peSection.Add(writer.StartupStub, alignment);
                moved = true;
            }
            if (moved)
                writer.Sections.Add(peSection);

            // move encrypted methods
            var encryptedChunk = new MethodBodyChunks(writer.TheOptions.ShareMethodBodies);
            newSection.Add(encryptedChunk, 4);
            foreach (MethodDef method in methods) {
                if (!method.HasBody)
                    continue;
                MethodBody body = writer.MetaData.GetMethodBody(method);
                bool ok = writer.MethodBodies.Remove(body);
                encryptedChunk.Add(body);
            }

            // padding to prevent bad size due to shift division
            newSection.Add(new ByteArrayChunk(new byte[4]), 4);
        }