/// <summary>Dumps a chunk of memory to the given stream.</summary> /// <param name="address">The begin of the chunk.</param> /// <param name="size">The size of the chunk.</param> /// <param name="stream">The stream to dump to.</param> public void DumpRaw(IntPtr address, int size, Stream stream) { Contract.Requires(size >= 0); Contract.Requires(stream != null); var data = process.ReadRemoteMemory(address, size); stream.Write(data, 0, data.Length); }
public static string ReadRemoteStringUntilFirstNullCharacter(this IRemoteMemoryReader reader, IntPtr address, Encoding encoding, int length) { Contract.Requires(encoding != null); Contract.Requires(length >= 0); Contract.Ensures(Contract.Result <string>() != null); var data = reader.ReadRemoteMemory(address, length * encoding.GuessByteCountPerChar()); // TODO We should cache the pattern per encoding. var index = PatternScanner.FindPattern(BytePattern.From(new byte[encoding.GuessByteCountPerChar()]), data); if (index == -1) { index = data.Length; } try { return(encoding.GetString(data, 0, Math.Min(index, data.Length))); } catch { return(string.Empty); } }
public static string ReadRemoteString(this IRemoteMemoryReader reader, IntPtr address, Encoding encoding, int length) { Contract.Requires(encoding != null); Contract.Requires(length >= 0); Contract.Ensures(Contract.Result <string>() != null); var data = reader.ReadRemoteMemory(address, length * encoding.GuessByteCountPerChar()); try { var sb = new StringBuilder(encoding.GetString(data)); for (var i = 0; i < sb.Length; ++i) { if (sb[i] == '\0') { sb.Length = i; break; } if (!sb[i].IsPrintable()) { sb[i] = '.'; } } return(sb.ToString()); } catch { return(string.Empty); } }
/// <summary>Tries to find and disassembles the instruction prior to the given address.</summary> /// <param name="process">The process to read from.</param> /// <param name="address">The address of the code.</param> /// <returns>The prior instruction.</returns> public DisassembledInstruction RemoteGetPreviousInstruction(IRemoteMemoryReader process, IntPtr address) { const int TotalBufferSize = 7 * MaximumInstructionLength; const int BufferShiftSize = 6 * MaximumInstructionLength; var buffer = process.ReadRemoteMemory(address - BufferShiftSize, TotalBufferSize); var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); try { var bufferAddress = handle.AddrOfPinnedObject(); var targetBufferAddress = bufferAddress + BufferShiftSize; var instruction = default(InstructionData); foreach (var offset in new[] { 6 * MaximumInstructionLength, 4 * MaximumInstructionLength, 2 * MaximumInstructionLength, 1 * MaximumInstructionLength, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }) { var currentAddress = targetBufferAddress - offset; coreFunctions.DisassembleCode(currentAddress, offset + 1, address - offset, false, (ref InstructionData data) => { var nextAddress = currentAddress + data.Length; if (nextAddress.CompareTo(targetBufferAddress) > 0) { return(false); } instruction = data; currentAddress = nextAddress; return(true); }); if (currentAddress == targetBufferAddress) { return(new DisassembledInstruction(ref instruction)); } } return(null); } finally { if (handle.IsAllocated) { handle.Free(); } } }
/// <summary>Disassembles the code in the given range (<paramref name="address"/>, <paramref name="maxLength"/>) in the remote process until the first 0xCC instruction.</summary> /// <param name="process">The process to read from.</param> /// <param name="address">The address of the code.</param> /// <param name="maxLength">The maximum maxLength of the code.</param> /// <returns>A list of <see cref="DisassembledInstruction"/> which belong to the function.</returns> public IReadOnlyList <DisassembledInstruction> RemoteDisassembleFunction(IRemoteMemoryReader process, IntPtr address, int maxLength) { Contract.Requires(process != null); Contract.Ensures(Contract.Result <IEnumerable <DisassembledInstruction> >() != null); var buffer = process.ReadRemoteMemory(address, maxLength); return(DisassembleFunction(buffer, address)); }
/// <summary>Disassembles the code in the given range (<paramref name="address"/>, <paramref name="length"/>) in the remote process.</summary> /// <param name="process">The process to read from.</param> /// <param name="address">The address of the code.</param> /// <param name="length">The length of the code in bytes.</param> /// <param name="maxInstructions">The maximum number of instructions to disassemble. If <paramref name="maxInstructions"/> is -1, all available instructions get returned.</param> /// <returns>A list of <see cref="DisassembledInstruction"/>.</returns> public IReadOnlyList <DisassembledInstruction> RemoteDisassembleCode(IRemoteMemoryReader process, IntPtr address, int length, int maxInstructions) { Contract.Requires(process != null); Contract.Ensures(Contract.Result <IList <DisassembledInstruction> >() != null); var buffer = process.ReadRemoteMemory(address, length); return(DisassembleCode(buffer, address, maxInstructions)); }
/// <summary>Dumps a module to the given stream. The section headers of the pe header get fixed to build a valid pe file.</summary> /// <param name="reader">The memory reader to use.</param> /// <param name="module">The module to dump.</param> /// <param name="stream">The stream to dump to.</param> public static void DumpModule(IRemoteMemoryReader reader, Module module, Stream stream) { Contract.Requires(module != null); Contract.Requires(stream != null); var data = reader.ReadRemoteMemory(module.Start, module.Size.ToInt32()); SimplePeHeader.FixSectionHeaders(data); stream.Write(data, 0, data.Length); }
public static double ReadRemoteDouble(this IRemoteMemoryReader reader, IntPtr address) { var data = reader.ReadRemoteMemory(address, sizeof(double)); return(reader.BitConverter.ToDouble(data, 0)); }
public static float ReadRemoteFloat(this IRemoteMemoryReader reader, IntPtr address) { var data = reader.ReadRemoteMemory(address, sizeof(float)); return(reader.BitConverter.ToSingle(data, 0)); }
public static ulong ReadRemoteUInt64(this IRemoteMemoryReader reader, IntPtr address) { var data = reader.ReadRemoteMemory(address, sizeof(ulong)); return(reader.BitConverter.ToUInt64(data, 0)); }
public static int ReadRemoteInt32(this IRemoteMemoryReader reader, IntPtr address) { var data = reader.ReadRemoteMemory(address, sizeof(int)); return(reader.BitConverter.ToInt32(data, 0)); }
public static ushort ReadRemoteUInt16(this IRemoteMemoryReader reader, IntPtr address) { var data = reader.ReadRemoteMemory(address, sizeof(ushort)); return(reader.BitConverter.ToUInt16(data, 0)); }
public static byte ReadRemoteUInt8(this IRemoteMemoryReader reader, IntPtr address) { var data = reader.ReadRemoteMemory(address, sizeof(byte)); return(data[0]); }