public CLRDirectoryEntry(CLRDirectory directory) : base(directory.Name) { foreach (KeyValuePair <Streams, Stream> current in directory.Metadata.Streams) { this.Children.Add(Entry.Create(current.Value)); } }
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); }
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); } }
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)); } }
/// <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); }
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(); } }
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; } }
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 }); } } }
public VTableFixups(CLRDirectory md) { d = md; }
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); }
public MetadataRoot(CLRDirectory md) { d = md; }