public void ChangeByte(FileStream fs, PEFile file, int codeIndex, byte newByte) { int fileOffset = file.RVAToFileOffset(RVA + Method.HeaderSizeInDWords * 4 + codeIndex); fs.Seek(fileOffset, SeekOrigin.Begin); fs.WriteByte(newByte); }
public void Populate(FileStream fs, MetaDataStream Strings, PEFile file) { this.Name = Utils.ReadString((byte[])Strings.Data, NameIndex); if (RVA != 0) { int offset = file.FindSectionForRVA(RVA).CalculateFileOffset(RVA); fs.Seek(offset, SeekOrigin.Begin); Method = new Method(fs); } }
public CLRDirectory(FileStream fs, PEFile parent) { // Find the .NET metadata and load it PEDataDirectory clrDir = parent.OptionalHeader.DataDirectories.FirstOrDefault( p => p.DirectoryName == PEOptionalHeader.CLR_RUNTIME_HEADER); PESection section = parent.FindSectionForRVA(clrDir.VirtualAddress); MetaDataOffset = section.CalculateFileOffset(clrDir.VirtualAddress); // Skip to the start of the structure fs.Seek(MetaDataOffset, SeekOrigin.Begin); fs.Seek(8, SeekOrigin.Current); MetDataDirectory = new PEDataDirectory(fs, "MetaData"); MetaDataHeaderRVF = parent.FindSectionForRVA(MetDataDirectory.VirtualAddress) .CalculateFileOffset(MetDataDirectory.VirtualAddress); fs.Seek(MetaDataHeaderRVF,SeekOrigin.Begin); // load the metadata itself MetaDataHeader = new MetaDataHeader(fs); MetaDataStreams = new List<MetaDataStream>(); for(int i =0; i< MetaDataHeader.NumberOfStreams; i++) { MetaDataStreams.Add(new MetaDataStream(fs)); } // we should now be aligned at the start of the first section foreach (MetaDataStream ms in MetaDataStreams) { fs.Seek(ms.Offset + MetaDataHeaderRVF, SeekOrigin.Begin); if (ms.Name == "#~") { ms.Data = new PoundTildeStream(fs); Tables = ms; } else { if (ms.Name == "#Strings") Strings = ms; ms.Data = new byte[ms.Size]; fs.Read((byte[])ms.Data, 0, ms.Size); } } ((PoundTildeStream)Tables.Data).FillMethods(fs, Strings, parent); }
public void FillMethods(FileStream fs,MetaDataStream Strings, PEFile file) { // now fill in the methods foreach (MethodDef md in Methods) md.Populate(fs, Strings,file ); }
public int GetByteOffset(PEFile file, int codeOffset) { return RVA + Method.HeaderSizeInDWords * 4 + codeOffset; }
private static void performMemoryPatch(PEFile file, MethodDef def, int patternIndex, ProcessMemoryReader pmr,DllBaseNativeEvent ev) { IntPtr address = Utils.VirtualAllocEx(ev.Process.UnsafeHandle, IntPtr.Zero, (uint)Encoding.Unicode.GetBytes(FileManager.MergedPath).Length, AllocationType.Reserve | AllocationType.Commit | AllocationType.TopDown, MemoryProtection.ReadWrite); int fileAddress = address.ToInt32(); // set the location for our new filename string int offset = ev.Module.BaseAddress.ToInt32() + def.GetByteOffset(file, patternIndex); newCode[2] = getByte(fileAddress, 0); newCode[3] = getByte(fileAddress, 1); newCode[4] = getByte(fileAddress, 2); newCode[5] = getByte(fileAddress, 3); int writtenBytes; pmr.WriteProcessMemory(new IntPtr(offset), newCode, out writtenBytes); // write the new filename string pmr.WriteProcessMemory(new IntPtr(fileAddress), Encoding.Unicode.GetBytes(FileManager.MergedPath), out writtenBytes); }
private static void performDiskPatch(PEFile file, MethodDef def, int patternIndex, int fileAddress) { CopyIfNecessary(); // read the int, shift off the table number int fieldNum = BitConverter.ToInt32(def.Method.Code, patternIndex + 6) << 8 >> 8; using (FileStream sw = new FileStream(LOADED_FILE, FileMode.Open, FileAccess.Write, FileShare.Read)) { // change the push 1 to a push 0 int RVA = def.GetByteOffset(file, patternIndex) + 10; byte[] data = new byte[] { 0x16 }; sw.Position = file.FindSectionForRVA(RVA).CalculateFileOffset(RVA); sw.Write(data, 0, data.Length); // write the new location to the metadata folder data = new byte[] { getByte(fileAddress, 0), getByte(fileAddress, 1), getByte(fileAddress, 2), getByte(fileAddress, 3) }; FieldDef fd = file.GetField(fieldNum); RVA = file.FindSectionForFileOffset((int)fd.MetaDataFileLocation) .CalculateRVA((int)fd.MetaDataFileLocation); sw.Position = file.FindSectionForRVA(RVA).CalculateFileOffset(RVA); sw.Write(data, 0, data.Length); // write the string to an empty file location RVA = fileAddress; data = Encoding.Unicode.GetBytes(FileManager.MergedPath); sw.Position = file.FindSectionForRVA(RVA).CalculateFileOffset(RVA); sw.Write(data, 0, data.Length); } }
private static void patch(Action<PEFile,MethodDef,MethodDef,int> performPatch) { PEFile file = new PEFile(LOADED_FILE); MethodDef def = file.FindCodeForMethodName("D20RulesEngine.LoadRulesDatabase"); MethodDef def2 = file.FindCodeForMethodName("D20RulesEngine.LoadRulesFile"); // We're going to replace the arguments from Loadrulesdatabase to loadrulesfile // the 2nd arg will be the filename we injected into memory // the 3rd arg will be changed from true to false Array.ConstrainedCopy(file.GetMetaDataToken(def2), 0, pattern, 12, 4); int patternIndex = findPatternIndex(def, pattern); // if we found it, patch. Otherwise, assume we've already patched if (patternIndex > -1) { performPatch(file, def, def2, patternIndex); } else Log.Debug("Could Not patch file: It is likely already patched."); }
public int GetByteOffset(PEFile file, int codeOffset) { return(RVA + Method.HeaderSizeInDWords * 4 + codeOffset); }