Skip to content

Instantly share code, notes, and snippets.

@KirillOsenkov
Created April 27, 2020 02:56
Show Gist options
  • Save KirillOsenkov/1b12d8cca60e6dc1c13f6859451a2aab to your computer and use it in GitHub Desktop.
Save KirillOsenkov/1b12d8cca60e6dc1c13f6859451a2aab to your computer and use it in GitHub Desktop.
var virtualStream = new ReadVirtualStream((ulong address, byte[] buffer, int byteCount, out int bytesRead) =>
{
process.ReadMemory(address, (uint)byteCount, buffer, out var bytesReadIntPtr);
bytesRead = bytesReadIntPtr.ToInt32();
return true;
}, module.BaseAddress, module.Size);
var moduleDefinition = ModuleDefinition.ReadModule(virtualStream, new ReaderParameters(ReadingMode.Deferred)
{
InMemory = true,
AssemblyResolver = assemblyResolutionService.CreateCecilResolver(),
ImageLayoutInMemory = true
});
return moduleDefinition;
====================================
public delegate bool ReadMemory(ulong address, byte[] buffer, int byteCount, out int readBytes);
public class ReadVirtualStream : Stream
{
private byte[] _buffer;
private long _position;
private long _displacement;
private long _length;
private ReadMemory _dataReader;
public ReadVirtualStream(ReadMemory dataReader, long displacement, long length)
{
_dataReader = dataReader;
_displacement = displacement;
_length = length;
}
public override bool CanRead => true;
public override bool CanSeek => true;
public override bool CanWrite => true;
public override void Flush()
{
}
public override long Length => int.MaxValue;
public override long Position
{
get => _position;
set
{
_position = value;
if (_position > _length)
{
_position = _length;
}
}
}
public override int Read(byte[] buffer, int offset, int count)
{
if (offset == 0)
{
if (Read(buffer, count, out int read))
{
return read;
}
return 0;
}
else
{
if (_buffer == null || _buffer.Length < count)
{
_buffer = new byte[count];
}
if (!Read(_buffer, count, out int read))
{
return 0;
}
Buffer.BlockCopy(_buffer, 0, buffer, offset, read);
return read;
}
}
private bool Read(byte[] buffer, int count, out int read)
{
if (_dataReader((ulong)(_position + _displacement), buffer, count, out read))
{
_position += read;
return true;
}
return false;
}
public override long Seek(long offset, SeekOrigin origin)
{
switch (origin)
{
case SeekOrigin.Begin:
_position = offset;
break;
case SeekOrigin.End:
_position = _length + offset;
if (_position > _length)
_position = _length;
break;
case SeekOrigin.Current:
_position += offset;
if (_position > _length)
_position = _length;
break;
}
return _position;
}
public override void SetLength(long value) => _length = value;
public override void Write(byte[] buffer, int offset, int count) => throw new InvalidOperationException();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment