public CLRDirectoryEntry(CLRDirectory directory)
     : base(directory.Name)
 {
     foreach (KeyValuePair <Streams, Stream> current in directory.Metadata.Streams)
     {
         this.Children.Add(Entry.Create(current.Value));
     }
 }
Пример #2
0
        private CLRDirectory GetClrDirectory(PeFile PE)
        {
            DataDirectoryEntry entry = (from t in PE.OptionalHeader.DataDirectories where t.Type == DataDirectoryType.CLR select t).FirstOrDefault();

            entry.Reload();
            CLRDirectory dir = entry.GetComponent() as CLRDirectory;

            dir.Load(new VirtualReader(PE.SectionHeaders.GetVirtualStream()));
            return(dir);
        }
Пример #3
0
        private void CopyData(CLRDirectory datas, IntPtr hinstance, PeFile PE)
        {
            VirtualStream vs = PE.SectionHeaders.GetVirtualStream();

            foreach (CLRData data in datas.Datas)
            {
                vs.Seek(data.Address, SeekOrigin.Begin);
                Marshal.Copy((IntPtr)(data.Address.Value + hinstance.ToInt32()), data.Data, 0, data.Data.Length);
                vs.Write(data.Data, 0, data.Data.Length);
            }
        }
Пример #4
0
 private Rva GetRvaFromToken(uint token, CLRDirectory dir)
 {
     try
     {
         MetadataRow  metarow = (from row in (dir.Metadata[MetadataStreamType.Tables].Heap as TablesHeap)[TableType.MethodDef].Rows where row.Token == token select row).FirstOrDefault();
         MetadataRoot root    = metarow.Container.Heap.Stream.Root;
         return(root.Directory.Datas[(Rva)metarow["Rva"]].Address);
     }
     catch
     {
         return(new Rva(0));
     }
 }
Пример #5
0
        /// <summary>
        /// Factory method for instantiating different directories from the file
        /// </summary>
        /// <param name="directory">The type of directory to create</param>
        /// <param name="fileContents">The contents of the file being read</param>
        /// <param name="address">The address of the directory</param>
        /// <returns></returns>
        public static Directory Create(DataDirectories directory, byte[] fileContents, uint address)
        {
            Directory createdDirectory = null;

            switch (directory)
            {
            case DataDirectories.CommonLanguageRuntimeHeader:
                createdDirectory = new CLRDirectory(fileContents, address);
                break;

            default:
                createdDirectory = new Directory();
                break;
            }

            createdDirectory.Name = directory.ToString();

            return(createdDirectory);
        }
Пример #6
0
 public static Entry Create(object forItem)
 {
     if (forItem is string)
     {
         return(new Entry(forItem as string));
     }
     else if (forItem is MetadataStream)
     {
         return(new MetadataStreamEntry(forItem as MetadataStream));
     }
     else if (forItem is CLRDirectory)
     {
         CLRDirectory directory = forItem as CLRDirectory;
         return(new CLRDirectoryEntry(directory));
     }
     else if (forItem is Directory)
     {
         Directory directory = forItem as Directory;
         return(new Entry(directory.Name));
     }
     else if (forItem is StringStream)
     {
         StringStream stringStream = forItem as StringStream;
         return(new StringStreamEntry(stringStream));
     }
     else if (forItem is GuidStream)
     {
         GuidStream stringStream = forItem as GuidStream;
         return(new GuidStreamEntry(stringStream));
     }
     else if (forItem is Stream)
     {
         Stream stream = forItem as Stream;
         return(new Entry(stream.Name));
     }
     else
     {
         throw new NotImplementedException();
     }
 }
Пример #7
0
        private void BuildNodesForDirectory(DataDirectories type, Directory directory, Entry parent)
        {
            switch (type)
            {
            case DataDirectories.CommonLanguageRuntimeHeader:
                CLRDirectory      clrDirectory      = directory as CLRDirectory;
                MetadataDirectory metadataDirectory = clrDirectory.Metadata;

                // Metadata
                Entry metadataEntry = new Entry("Metadata");
                parent.Children.Add(metadataEntry);

                // Streams
                Entry streamsEntry = new Entry("Streams");
                foreach (KeyValuePair <Streams, Stream> currentStream in metadataDirectory.Streams)
                {
                    Entry streamEntry = new Entry(currentStream.Value.Name);
                    streamsEntry.Children.Add(streamEntry);
                }
                parent.Children.Add(streamsEntry);
                break;
            }
        }
Пример #8
0
        void ReadRvaData(MetadataTable tbl, MetadataReader mdRdr, List <Rva> rvas, MetadataRowCollection rows)
        {
            List <Rva> sorted = new List <Rva>(rvas);

            sorted.Sort();
            for (int i = 0; i < rvas.Count; i++)
            {
                Rva           rva = rvas[i];
                MetadataRow   r   = rows[i + 1];
                byte[]        dat = null;
                VirtualReader rdr = new VirtualReader(mdRdr.BaseStream.File.SectionHeaders.GetVirtualStream());
                if (tbl.Type == TableType.FieldRVA)
                {
                    MetadataRoot root = tbl.Heap.Stream.Root;
                    rdr.SetPosition(rva);
                    MetadataRow     fd     = (r["Field"] as TableToken).ResolveRow();
                    FieldSig        sig    = new FieldSig();
                    SignatureReader sigRdr = new SignatureReader(new MetadataReader(root[MetadataStreamType.Blob]));
                    sigRdr.BaseStream.Position = (fd["Signature"] as BlobToken).Token.Index;
                    sig.Read(sigRdr);
                    int c = 0;
                    switch (sig.Type.Element)
                    {
                    case ElementType.Boolean:
                    case ElementType.UInt8:
                    case ElementType.Int8:
                        c = 1; break;

                    case ElementType.UInt16:
                    case ElementType.Int16:
                    case ElementType.Char:
                        c = 2; break;

                    case ElementType.UInt32:
                    case ElementType.Int32:
                    case ElementType.Single:
                        c = 4; break;

                    case ElementType.UInt64:
                    case ElementType.Int64:
                    case ElementType.Double:
                        c = 8; break;

                    case ElementType.ValueType:
                        TableToken vt = (sig.Type as VALUETYPE).Type;
                        foreach (MetadataRow cl in tbl.Heap[TableType.ClassLayout])
                        {
                            if (cl["Parent"] == vt)
                            {
                                c = (int)cl["ClassSize"];
                                break;
                            }
                        }
                        break;

                    default:
                        throw new InvalidOperationException("ReadRvaData");
                    }
                    dat = rdr.ReadBytes(c);
                }
                else if (tbl.Type == TableType.MethodDef && rva != 0)
                {
                    //MethodBody bdy;
                    //if (((MethodImplAttributes)r["ImplFlags"] & MethodImplAttributes.Native) == MethodImplAttributes.Native)
                    //{
                    //    bdy = new NativeMethodBody(r);
                    //}
                    //else
                    //{
                    //    bdy = new ManagedMethodBody(r);
                    //}
                    //rdr.SetPosition(rva);
                    //bdy.Load(rdr);
                    //rdr.SetPosition(rva);
                    //dat = rdr.ReadBytes((int)bdy.Size);
                    int idx;
                    Rva next;
                    if ((idx = sorted.IndexOf(rva)) == sorted.Count - 1)
                    {
                        CLRDirectory root = tbl.Heap.Stream.Root.Directory;
                        Rva          now;
                        next = uint.MaxValue;
                        rdr.SetPosition(root.Location.Address);
                        rdr.BaseStream.Seek(0x8, System.IO.SeekOrigin.Current);
                        if ((now = rdr.ReadRva()) < next && now != 0 && now > rva)
                        {
                            next = now;
                        }
                        rdr.BaseStream.Seek(0xC, System.IO.SeekOrigin.Current);
                        if ((now = rdr.ReadRva()) < next && now != 0 && now > rva)
                        {
                            next = now;
                        }
                        rdr.BaseStream.Seek(0x4, System.IO.SeekOrigin.Current);
                        if ((now = rdr.ReadRva()) < next && now != 0 && now > rva)
                        {
                            next = now;
                        }
                        rdr.BaseStream.Seek(0x4, System.IO.SeekOrigin.Current);
                        if ((now = rdr.ReadRva()) < next && now != 0 && now > rva)
                        {
                            next = now;
                        }
                        rdr.BaseStream.Seek(0x4, System.IO.SeekOrigin.Current);
                        if ((now = rdr.ReadRva()) < next && now != 0 && now > rva)
                        {
                            next = now;
                        }
                        rdr.BaseStream.Seek(0x4, System.IO.SeekOrigin.Current);
                        if ((now = rdr.ReadRva()) < next && now != 0 && now > rva)
                        {
                            next = now;
                        }
                        rdr.BaseStream.Seek(0x4, System.IO.SeekOrigin.Current);
                        if ((now = rdr.ReadRva()) < next && now != 0 && now > rva)
                        {
                            next = now;
                        }
                    }
                    else
                    {
                        next = sorted[idx + 1];
                    }
                    rdr.SetPosition(rva);
                    dat = rdr.ReadBytes((int)(next - rva));
                }
                if (!tbl.Heap.Stream.Root.Directory.Datas.ContainsAddress(rva) && dat != null)
                {
                    tbl.Heap.Stream.Root.Directory.Datas.Add(new CLRData()
                    {
                        Address = rva, Data = dat
                    });
                }
            }
        }
Пример #9
0
 public VTableFixups(CLRDirectory md)
 {
     d = md;
 }
Пример #10
0
        public bool DumpMethodsOf(string target)
        {
            excpetion = null;
            Dumped    = new List <IntPtr>();
            bool         found = false;
            StreamWriter log   = null;

            try
            {
                string output;
                string logpath;
                string dumpPath = Path.GetDirectoryName(target) + "\\DumpedAsms\\";
                if (Path.HasExtension(target))
                {
                    output  = Path.ChangeExtension(target, "DumpedMethods" + Path.GetExtension(target));
                    logpath = Path.ChangeExtension(target, "log.txt");
                }
                else
                {
                    output  = target + ".DumpedMethods";
                    logpath = target + ".log.txt";
                }
                log = File.CreateText(logpath);
                Assembly asm = Assembly.LoadFrom(target);

                PeFile       PE  = PeFileFactory.Read(target, PeFileType.Image);
                CLRDirectory dir = GetClrDirectory(PE);

                ConstructorInfo       ctor  = (ConstructorInfo)asm.ManifestModule.ResolveMethod(0x06000001);
                InstructionCollection insts = Disassembler.Disassemble(ctor.GetMethodBody().GetILAsByteArray());
                foreach (Instruction inst in from instr in insts where instr.OpCode == OpCodes.Call select instr)
                {
                    uint token = (inst.Operand.Value as MetadataToken).Value;
                    try
                    {
                        MethodBase method = asm.ManifestModule.ResolveMethod((int)token);
                        if (isDecryptMethod(method))
                        {
                            log.WriteLine("Decryption method found, token : 0x{0:x8}, rva : 0x{1:x8}", token, GetRvaFromToken(token, dir).Value);
                            log.WriteLine("Decryption called from \"<Module>.ctor\" at {0}", inst.GetOffsetString());
                            try
                            {
                                method.Invoke(null, null);
                            }
                            catch { }
                            found = true;
                        }
                    }
                    catch { }
                }
                if (found)
                {
                    log.WriteLine("Copying code");
                    CopyData(dir, Marshal.GetHINSTANCE(asm.ManifestModule), PE);
                    PeFileFactory.Save(output, PE);
                    log.WriteLine("Dump done, try deobfuscate with de4dot");
                }
                else
                {
                    log.WriteLine("Can't find decryption method, maybe not obfuscated with confuser 1.9");
                }
            }
            catch (Exception ex)
            {
                excpetion = ex;
                log.WriteLine(ex.Message);
            }
            log.Close();
            return(found);
        }
Пример #11
0
 public MetadataRoot(CLRDirectory md)
 {
     d = md;
 }