//wicky.patch.start: add support to read directly from bytes, contributed by HaRpy public CodeReader(MethodDefinition method, byte[] bytes):base(bytes) { this.method = method; this.reader = method.DeclaringType.Module.reader; this.code_section = null; //code_section could be null for obfuscated assembly this.isReadFromBytes = true; }
public CodeReader(Section section, MetadataReader reader, Dictionary<uint, DumpedMethod> dumpedMethods = null) : base(section.Data) { this.code_section = section; this.reader = reader; this.dumpedMethods = dumpedMethods; }
public void MoveTo (int rva) { if (!IsInSection (rva)) { code_section = reader.image.GetSectionAtVirtualAddress ((uint) rva); Reset (code_section.Data); } base.position = rva - (int) code_section.VirtualAddress; }
void ReadSectionData(Section section) { var position = BaseStream.Position; MoveTo (section.PointerToRawData); var length = (int) section.SizeOfRawData; var data = new byte [length]; int offset = 0, read; // If the file is on the network, and we read more than 2MB, this Read() call will // read data from the wrong offset in the file! Tested: VMware 8, Win7 x64. while ((read = Read (data, offset, System.Math.Min (0x200000, length - offset))) > 0) offset += read; section.Data = data; BaseStream.Position = position; }
void ReadSections(ushort count) { var sections = new Section [count]; for (int i = 0; i < count; i++) { var section = new Section (); // Name section.Name = ReadZeroTerminatedString (8); // VirtualSize 4 Advance (4); // VirtualAddress 4 section.VirtualAddress = ReadUInt32 (); // SizeOfRawData 4 section.SizeOfRawData = ReadUInt32 (); // PointerToRawData 4 section.PointerToRawData = ReadUInt32 (); // PointerToRelocations 4 // PointerToLineNumbers 4 // NumberOfRelocations 2 // NumberOfLineNumbers 2 // Characteristics 4 Advance (16); sections [i] = section; ReadSectionData (section); } image.Sections = sections; }
private void WriteOptionalHeaders() { base.WriteUInt16((ushort)((!pe64) ? 267 : 523)); base.WriteUInt16(module.linker_version); base.WriteUInt32(text.SizeOfRawData); base.WriteUInt32(((reloc != null) ? reloc.SizeOfRawData : 0) + ((rsrc != null) ? rsrc.SizeOfRawData : 0)); base.WriteUInt32(0u); Range range = text_map.GetRange(TextSegment.StartupStub); base.WriteUInt32((range.Length != 0) ? range.Start : 0); base.WriteUInt32(8192u); if (!pe64) { base.WriteUInt32(0u); base.WriteUInt32(4194304u); } else { base.WriteUInt64(4194304uL); } base.WriteUInt32(8192u); base.WriteUInt32(512u); base.WriteUInt16(4); base.WriteUInt16(0); base.WriteUInt16(0); base.WriteUInt16(0); base.WriteUInt16(4); base.WriteUInt16(0); base.WriteUInt32(0u); Section section = LastSection(); base.WriteUInt32(section.VirtualAddress + Align(section.VirtualSize, 8192u)); base.WriteUInt32(text.PointerToRawData); base.WriteUInt32(0u); base.WriteUInt16(GetSubSystem()); base.WriteUInt16((ushort)module.Characteristics); if (!pe64) { base.WriteUInt32(1048576u); base.WriteUInt32(4096u); base.WriteUInt32(1048576u); base.WriteUInt32(4096u); } else { base.WriteUInt64(1048576uL); base.WriteUInt64(4096uL); base.WriteUInt64(1048576uL); base.WriteUInt64(4096uL); } base.WriteUInt32(0u); base.WriteUInt32(16u); WriteZeroDataDirectory(); base.WriteDataDirectory(text_map.GetDataDirectory(TextSegment.ImportDirectory)); if (rsrc != null) { base.WriteUInt32(rsrc.VirtualAddress); base.WriteUInt32(rsrc.VirtualSize); } else { WriteZeroDataDirectory(); } WriteZeroDataDirectory(); WriteZeroDataDirectory(); base.WriteUInt32((reloc != null) ? reloc.VirtualAddress : 0); base.WriteUInt32((reloc != null) ? reloc.VirtualSize : 0); if (text_map.GetLength(TextSegment.DebugDirectory) > 0) { base.WriteUInt32(text_map.GetRVA(TextSegment.DebugDirectory)); base.WriteUInt32((uint)(debug_header.Entries.Length * 28)); } else { WriteZeroDataDirectory(); } WriteZeroDataDirectory(); WriteZeroDataDirectory(); WriteZeroDataDirectory(); WriteZeroDataDirectory(); WriteZeroDataDirectory(); base.WriteDataDirectory(text_map.GetDataDirectory(TextSegment.ImportAddressTable)); WriteZeroDataDirectory(); base.WriteDataDirectory(text_map.GetDataDirectory(TextSegment.CLIHeader)); WriteZeroDataDirectory(); }
public BlobHeap(Section section, uint start, uint size) : base(section, start, size) { }
void ReadMetadataStream(Section section) { // Offset 4 uint start = metadata.VirtualAddress - section.VirtualAddress + ReadUInt32 (); // relative to the section start // Size 4 uint size = ReadUInt32 (); var name = ReadAlignedString (16); switch (name) { case "#~": case "#-": image.TableHeap = new TableHeap (section, start, size); break; case "#Strings": image.StringHeap = new StringHeap (section, start, size); break; case "#Blob": image.BlobHeap = new BlobHeap (section, start, size); break; case "#GUID": image.GuidHeap = new GuidHeap (section, start, size); break; case "#US": image.UserStringHeap = new UserStringHeap (section, start, size); break; } }
void MoveToRVA(Section section, RVA rva) { BaseStream.Seek (section.PointerToRawData + rva - section.VirtualAddress, SeekOrigin.Begin); }
void WriteSection(Section section, uint characteristics) { var name = new byte [8]; var sect_name = section.Name; for (int i = 0; i < sect_name.Length; i++) name [i] = (byte) sect_name [i]; WriteBytes (name); WriteUInt32 (section.VirtualSize); WriteUInt32 (section.VirtualAddress); WriteUInt32 (section.SizeOfRawData); WriteUInt32 (section.PointerToRawData); WriteUInt32 (0); // PointerToRelocations WriteUInt32 (0); // PointerToLineNumbers WriteUInt16 (0); // NumberOfRelocations WriteUInt16 (0); // NumberOfLineNumbers WriteUInt32 (characteristics); }
public void MoveTo(int rva) { if (!IsInSection (rva)) { var new_section = reader.image.GetSectionAtVirtualAddress ((uint) rva); if (new_section == null) throw new ArgumentException (); code_section = new_section; Reset (code_section.Data); } base.position = rva - (int) code_section.VirtualAddress; }
void BuildSections() { var has_win32_resources = win32_resources != null; if (has_win32_resources) sections++; text = CreateSection (".text", text_map.GetLength (), null); var previous = text; if (has_win32_resources) { rsrc = CreateSection (".rsrc", (uint) win32_resources.length, previous); PatchWin32Resources (win32_resources); previous = rsrc; } if (has_reloc) reloc = CreateSection (".reloc", 12u, previous); }
static void PatchResourceDirectoryTable(ByteBuffer resources, Section old, Section @new) { resources.Advance(12); int num = resources.ReadUInt16() + resources.ReadUInt16(); for (int i = 0; i < num; i++) { PatchResourceDirectoryEntry(resources, old, @new); } }
public uint ResolveVirtualAddressInSection(RVA rva, Section section) { return rva + section.PointerToRawData - section.VirtualAddress; }
static void PatchResourceDirectoryEntry(ByteBuffer resources, Section old, Section @new) { resources.Advance(4); uint num = resources.ReadUInt32(); int position = resources.Position; resources.Position = ((int)num) & 0x7fffffff; if ((num & 0x80000000) != 0) { PatchResourceDirectoryTable(resources, old, @new); } else { PatchResourceDataEntry(resources, old, @new); } resources.Position = position; }
static void PatchResourceDataEntry(ByteBuffer resources, Section old, Section @new) { uint num = resources.ReadUInt32(); resources.Position -= 4; resources.WriteUInt32(num - old.VirtualAddress + @new.VirtualAddress); }
protected string[] ProtectStub(AssemblyDefinition asm) { string tmp = Path.GetTempPath() + "\\" + Path.GetRandomFileName() + "\\"; Directory.CreateDirectory(tmp); ModuleDefinition modDef = this.cr.settings.Single(_ => _.IsMain).Assembly.MainModule; asm.MainModule.TimeStamp = modDef.TimeStamp; byte[] mvid = new byte[0x10]; Random.NextBytes(mvid); asm.MainModule.Mvid = new Guid(mvid); MetadataProcessor psr = new MetadataProcessor(); Section oldRsrc = null; foreach (Section s in modDef.GetSections()) if (s.Name == ".rsrc") { oldRsrc = s; break; } if (oldRsrc != null) { psr.ProcessImage += accessor => { Section sect = null; foreach (Section s in accessor.Sections) if (s.Name == ".rsrc") { sect = s; break; } if (sect == null) { sect = new Section() { Name = ".rsrc", Characteristics = 0x40000040 }; foreach (Section s in accessor.Sections) if (s.Name == ".text") { accessor.Sections.Insert(accessor.Sections.IndexOf(s) + 1, sect); break; } } sect.VirtualSize = oldRsrc.VirtualSize; sect.SizeOfRawData = oldRsrc.SizeOfRawData; int idx = accessor.Sections.IndexOf(sect); sect.VirtualAddress = accessor.Sections[idx - 1].VirtualAddress + ((accessor.Sections[idx - 1].VirtualSize + 0x2000U - 1) & ~(0x2000U - 1)); sect.PointerToRawData = accessor.Sections[idx - 1].PointerToRawData + accessor.Sections[idx - 1].SizeOfRawData; for (int i = idx + 1; i < accessor.Sections.Count; i++) { accessor.Sections[i].VirtualAddress = accessor.Sections[i - 1].VirtualAddress + ((accessor.Sections[i - 1].VirtualSize + 0x2000U - 1) & ~(0x2000U - 1)); accessor.Sections[i].PointerToRawData = accessor.Sections[i - 1].PointerToRawData + accessor.Sections[i - 1].SizeOfRawData; } ByteBuffer buff = new ByteBuffer(oldRsrc.Data); PatchResourceDirectoryTable(buff, oldRsrc, sect); sect.Data = buff.GetBuffer(); }; } psr.Process(asm.MainModule, tmp + Path.GetFileName(modDef.FullyQualifiedName), new WriterParameters() { StrongNameKeyPair = this.cr.sn, WriteSymbols = this.cr.param.Project.Debug }); Confuser cr = new Confuser(); ConfuserProject proj = new ConfuserProject(); proj.Seed = Random.Next().ToString(); proj.Debug = this.cr.param.Project.Debug; foreach (var i in this.cr.param.Project.Rules) proj.Rules.Add(i); proj.Add(new ProjectAssembly() { Path = tmp + Path.GetFileName(modDef.FullyQualifiedName) }); proj.OutputPath = tmp; foreach (var i in this.cr.param.Project.Plugins) proj.Plugins.Add(i); proj.SNKeyPath = this.cr.param.Project.SNKeyPath; ConfuserParameter par = new ConfuserParameter(); par.Project = proj; par.ProcessMetadata = PostProcessMetadata; par.ProcessImage = PostProcessImage; cr.Confuse(par); return Directory.GetFiles(tmp); }
public MetadataStream(Section section, uint start, uint size, string name) : base(section, start, size) { this.Name = name; }
void MoveToRVA(Section section, RVA rva) { BaseStream.Seek(section.PointerToRawData + rva - section.VirtualAddress, SeekOrigin.Begin); }
public StringHeap(Mono.Cecil.PE.Section section, uint start, uint size) : base(section, start, size) { }
internal Section CreateSection(string name, uint size, uint characteristics, Section previous) { return new Section { Name = name, VirtualAddress = previous != null ? previous.VirtualAddress + Align (previous.VirtualSize, section_alignment) : text_rva, VirtualSize = size, PointerToRawData = previous != null ? previous.PointerToRawData + previous.SizeOfRawData : 0, SizeOfRawData = Align (size, file_alignment), Data = new byte[Align(size, file_alignment)], Characteristics = characteristics }; }
internal void ResizeSection(Section section, uint newSize, bool update) { section.VirtualSize = newSize; section.SizeOfRawData = Align (newSize, file_alignment); byte[] newDat = new byte[section.SizeOfRawData]; if (newDat.Length > section.Data.Length) Buffer.BlockCopy(section.Data, 0, newDat, 0, section.Data.Length); else Buffer.BlockCopy(section.Data, 0, newDat, 0, newDat.Length); section.Data = newDat; int sectIndex = sections.IndexOf(section); if (sectIndex != -1 && update) for (int i = sectIndex + 1; i < sections.Count; i++) { sections[i].VirtualAddress = sections[i - 1].VirtualAddress + Align (sections[i - 1].VirtualSize, section_alignment); sections[i].PointerToRawData = sections[i - 1].PointerToRawData + sections[i - 1].SizeOfRawData; } }
void BuildSections() { if (win32_resources != null || win32_resources_directory != null) sections++; text = CreateSection (".text", text_map.GetLength (), null); var previous = text; if (win32_resources != null) { rsrc = CreateSection (".rsrc", (uint) win32_resources.length, previous); PatchWin32Resources (win32_resources); previous = rsrc; } else if (win32_resources_directory != null) { rsrc = CreateSection(".rsrc", previous); WriteWin32ResourcesDirectory(win32_resources_directory); SetSectionSize(rsrc, (uint) win32_resources.length); previous = rsrc; } if (has_reloc) reloc = CreateSection (".reloc", 12u, previous); }
Section CreateSection(string name, uint size, Section previous) { return new Section { Name = name, VirtualAddress = previous != null ? previous.VirtualAddress + Align (previous.VirtualSize, section_alignment) : text_rva, VirtualSize = size, PointerToRawData = previous != null ? previous.PointerToRawData + previous.SizeOfRawData : Align (GetHeaderSize (), file_alignment), SizeOfRawData = Align (size, file_alignment) }; }
Section CreateSection(string name, uint size, Section previous) { var ret = CreateSection(name, previous); SetSectionSize(ret, size); return ret; }
void PrepareSection(Section section) { MoveTo (section.PointerToRawData); const int buffer_size = 4096; if (section.SizeOfRawData <= buffer_size) { Write (new byte [section.SizeOfRawData]); MoveTo (section.PointerToRawData); return; } var written = 0; var buffer = new byte [buffer_size]; while (written != section.SizeOfRawData) { var write_size = System.Math.Min((int) section.SizeOfRawData - written, buffer_size); Write (buffer, 0, write_size); written += write_size; } MoveTo (section.PointerToRawData); }
void SetSectionSize(Section ret, uint size) { ret.VirtualSize = size; ret.SizeOfRawData = Align(size, file_alignment); }
public GuidHeap (Section section, uint start, uint size) : base (section, start, size) { }
protected Heap(Mono.Cecil.PE.Section section, uint offset, uint size) { this.Section = section; this.Offset = offset; this.Size = size; }
public StringHeap (Section section, uint start, uint size) : base (section, start, size) { }
protected Heap(Section section, uint offset, uint size) { this.Section = section; this.Offset = offset; this.Size = size; }
void ReadSectionData(Section section) { var position = BaseStream.Position; MoveTo (section.PointerToRawData); var length = (int) section.SizeOfRawData; var data = new byte [length]; int offset = 0, read; while ((read = Read (data, offset, length - offset)) > 0) offset += read; section.Data = data; BaseStream.Position = position; }
public CodeReader(Section section, MetadataReader reader) : base(section.Data) { this.code_section = section; this.reader = reader; }
public TableHeap(Section section, uint start, uint size) : base(section, start, size) { }
public uint ResolveVirtualAddressInSection(RVA rva, Section section) { return(rva + section.PointerToRawData - section.VirtualAddress); }