more additions

git-svn-id: svn://svn.code.sf.net/p/processhacker/code@1352 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
wj32
2009-05-30 11:21:27 +00:00
parent ae5432f7cd
commit 6ff1e03e15
9 changed files with 349 additions and 62 deletions
@@ -132,6 +132,12 @@ namespace ProcessHacker.Native.Api
#region Files
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetFileSizeEx(
[In] IntPtr FileHandle,
[Out] out long FileSize
);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern int QueryDosDevice(
[In] [Optional] string DeviceName,
@@ -296,8 +296,19 @@ namespace ProcessHacker.Native.Api
[In] SectionAccess DesiredAccess,
[In] [Optional] ref ObjectAttributes ObjectAttributes,
[In] [Optional] ref long MaximumSize,
[In] int PageAttributes,
[In] int SectionAttributes,
[In] MemoryProtection PageAttributes,
[In] SectionAttributes SectionAttributes,
[In] [Optional] IntPtr FileHandle
);
[DllImport("ntdll.dll")]
public static extern NtStatus NtCreateSection(
[Out] out IntPtr SectionHandle,
[In] SectionAccess DesiredAccess,
[In] [Optional] ref ObjectAttributes ObjectAttributes,
[In] [Optional] IntPtr MaximumSize,
[In] MemoryProtection PageAttributes,
[In] SectionAttributes SectionAttributes,
[In] [Optional] IntPtr FileHandle
);
@@ -59,6 +59,11 @@ namespace ProcessHacker.Native
return Increment(ptr, -value);
}
public static IntPtr Decrement(this IntPtr ptr, long value)
{
return Increment(ptr, -value);
}
public static T ElementAt<T>(this IntPtr ptr, int index)
{
var offset = Marshal.SizeOf(typeof(T)) * index;
@@ -77,6 +82,17 @@ namespace ProcessHacker.Native
}
}
public static IntPtr Increment(this IntPtr ptr, long value)
{
unchecked
{
if (IntPtr.Size == sizeof(Int32))
return new IntPtr(ptr.ToInt32() + value);
else
return new IntPtr(ptr.ToInt64() + value);
}
}
public static IntPtr Increment(this IntPtr ptr, IntPtr ptr2)
{
unchecked
@@ -102,6 +102,35 @@ namespace ProcessHacker.Native
this.Dispose(false);
}
public MemoryAllocStream GetStream()
{
return new MemoryAllocStream(this);
}
public byte[] ReadBytes(int length)
{
return this.ReadBytes(0, length);
}
public byte[] ReadBytes(int offset, int length)
{
byte[] buffer = new byte[length];
this.ReadBytes(offset, buffer, 0, length);
return buffer;
}
public void ReadBytes(byte[] buffer, int startIndex, int length)
{
this.ReadBytes(0, buffer, startIndex, length);
}
public void ReadBytes(int offset, byte[] buffer, int startIndex, int length)
{
Marshal.Copy(_memory.Increment(offset), buffer, startIndex, length);
}
/// <summary>
/// Reads a signed integer.
/// </summary>
@@ -219,7 +248,7 @@ namespace ProcessHacker.Native
public void WriteBytes(int offset, byte[] b)
{
Marshal.Copy(b, 0, new IntPtr(this + offset), b.Length);
Marshal.Copy(b, 0, _memory.Increment(offset), b.Length);
}
public void WriteInt16(int offset, short i)
@@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
namespace ProcessHacker.Native
{
public class MemoryAllocStream : Stream
{
private MemoryAlloc _memory;
private long _position = 0;
public MemoryAllocStream(MemoryAlloc memory)
{
_memory = memory;
}
public override bool CanRead
{
get { return true; }
}
public override bool CanSeek
{
get { return true; }
}
public override bool CanTimeout
{
get { return false; }
}
public override bool CanWrite
{
get { return true; }
}
public override void Flush()
{
// Do nothing
}
public override long Length
{
get { return _memory.Size; }
}
public override long Position
{
get { return _position; }
set { _position = value; }
}
public override int Read(byte[] buffer, int offset, int count)
{
Marshal.Copy(_memory.Memory.Increment(_position += count), buffer, offset, count);
return count;
}
public override int ReadByte()
{
return Marshal.ReadByte(_memory.Memory.Increment(_position++));
}
public override long Seek(long offset, SeekOrigin origin)
{
if (origin == SeekOrigin.Begin)
_position = offset;
else if (origin == SeekOrigin.Current)
_position += offset;
else if (origin == SeekOrigin.End)
_position = _memory.Size + offset;
return _position;
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
Marshal.Copy(buffer, offset, _memory.Memory.Increment(_position += count), count);
}
public override void WriteByte(byte value)
{
Marshal.WriteByte(_memory.Memory.Increment(_position++), value);
}
}
}
@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Text;
using ProcessHacker.Native.Api;
using ProcessHacker.Native.Objects;
using ProcessHacker.Native.Security;
namespace ProcessHacker.Native
{
public class Section : NativeObject<SectionHandle>
{
private MemoryProtection _originalProtection;
public Section(FileHandle fileHandle)
: this(fileHandle, MemoryProtection.ReadWrite)
{ }
public Section(FileHandle fileHandle, MemoryProtection protection)
: this(fileHandle, false, protection)
{ }
public Section(FileHandle fileHandle, bool image, MemoryProtection protection)
: this(null, fileHandle, image, protection)
{ }
public Section(string name, FileHandle fileHandle, bool image, MemoryProtection protection)
{
_originalProtection = protection;
this.Handle = SectionHandle.Create(
SectionAccess.All,
fileHandle.GetSize(),
image ? SectionAttributes.Image : 0,
protection,
fileHandle
);
}
public Section(long maximumSize)
: this(maximumSize, MemoryProtection.ReadWrite)
{ }
public Section(long maximumSize, MemoryProtection protection)
: this(null, maximumSize, protection)
{ }
public Section(string name, long maximumSize, MemoryProtection protection)
{
_originalProtection = protection;
this.Handle = SectionHandle.Create(
SectionAccess.All,
maximumSize,
SectionAttributes.Commit,
protection
);
}
public void Extend(long newSize)
{
this.Handle.Extend(newSize);
}
public SectionView MapView(int size)
{
return this.MapView(size, _originalProtection);
}
public SectionView MapView(int size, MemoryProtection protection)
{
return this.Handle.MapView(size, protection);
}
}
}
@@ -31,9 +31,26 @@ namespace ProcessHacker.Native.Objects
/// </summary>
public class FileHandle : NativeHandle<FileAccess>
{
public static FileHandle FromHandle(IntPtr handle)
{
return new FileHandle(handle, false);
}
protected FileHandle()
{ }
private FileHandle(IntPtr handle, bool owned)
: base(handle, owned)
{ }
public FileHandle(string fileName, FileAccess desiredAccess)
: this(fileName, desiredAccess, FileShareMode.Exclusive)
{ }
public FileHandle(string fileName, FileAccess desiredAccess, FileShareMode shareMode)
: this(fileName, desiredAccess, shareMode, FileCreationDisposition.OpenExisting)
{ }
public FileHandle(string fileName, FileAccess desiredAccess, FileShareMode shareMode,
FileCreationDisposition creationDisposition)
{
@@ -43,13 +60,15 @@ namespace ProcessHacker.Native.Objects
Win32.ThrowLastError();
}
public FileHandle(string fileName, FileAccess desiredAccess, FileShareMode shareMode)
: this(fileName, desiredAccess, shareMode, FileCreationDisposition.OpenExisting)
{ }
public long GetSize()
{
long fileSize;
public FileHandle(string fileName, FileAccess desiredAccess)
: this(fileName, desiredAccess, FileShareMode.Exclusive)
{ }
if (!Win32.GetFileSizeEx(this, out fileSize))
Win32.ThrowLastError();
return fileSize;
}
/// <summary>
/// Sends an I/O control message to the device's associated driver.
@@ -127,6 +146,20 @@ namespace ProcessHacker.Native.Objects
return isb.Information.ToInt32();
}
/// <summary>
/// Reads data from the file.
/// </summary>
/// <param name="length">The length to read.</param>
/// <returns>The read data.</returns>
public byte[] Read(int length)
{
byte[] buffer = new byte[length];
this.Read(buffer);
return buffer;
}
/// <summary>
/// Reads data from the file.
/// </summary>
@@ -142,20 +175,6 @@ namespace ProcessHacker.Native.Objects
return bytesRead;
}
/// <summary>
/// Reads data from the file.
/// </summary>
/// <param name="length">The length to read.</param>
/// <returns>The read data.</returns>
public byte[] Read(int length)
{
byte[] buffer = new byte[length];
this.Read(buffer);
return buffer;
}
/// <summary>
/// Writes data to the file.
/// </summary>
@@ -38,7 +38,28 @@ namespace ProcessHacker.Native.Objects
FileHandle fileHandle
)
{
return Create(access, null, 0, sectionAttributes, pageAttributes, fileHandle);
return Create(access, 0, sectionAttributes, pageAttributes, fileHandle);
}
public static SectionHandle Create(
SectionAccess access,
long maximumSize,
SectionAttributes sectionAttributes,
MemoryProtection pageAttributes,
FileHandle fileHandle
)
{
return Create(access, null, maximumSize, sectionAttributes, pageAttributes, fileHandle);
}
public static SectionHandle Create(
SectionAccess access,
long maximumSize,
SectionAttributes sectionAttributes,
MemoryProtection pageAttributes
)
{
return Create(access, null, maximumSize, sectionAttributes, pageAttributes, null);
}
public static SectionHandle Create(
@@ -70,15 +91,32 @@ namespace ProcessHacker.Native.Objects
try
{
if ((status = Win32.NtCreateSection(
out handle,
access,
ref oa,
ref maximumSize,
(int)pageAttributes,
(int)sectionAttributes,
fileHandle)) >= NtStatus.Error)
Win32.ThrowLastError(status);
if (maximumSize != 0)
{
if ((status = Win32.NtCreateSection(
out handle,
access,
ref oa,
ref maximumSize,
pageAttributes,
sectionAttributes,
fileHandle != null ? fileHandle : IntPtr.Zero
)) >= NtStatus.Error)
Win32.ThrowLastError(status);
}
else
{
if ((status = Win32.NtCreateSection(
out handle,
access,
ref oa,
IntPtr.Zero,
pageAttributes,
sectionAttributes,
fileHandle != null ? fileHandle : IntPtr.Zero
)) >= NtStatus.Error)
Win32.ThrowLastError(status);
}
}
finally
{
@@ -156,6 +194,35 @@ namespace ProcessHacker.Native.Objects
return sii;
}
public SectionView MapView(int size, MemoryProtection protection)
{
return this.MapView(IntPtr.Zero, new IntPtr(size), protection);
}
public SectionView MapView(IntPtr baseAddress, IntPtr size, MemoryProtection protection)
{
return this.MapView(ProcessHandle.GetCurrent(), baseAddress, size, protection);
}
public SectionView MapView(
ProcessHandle processHandle,
IntPtr baseAddress,
IntPtr size,
MemoryProtection protection
)
{
return this.MapView(
processHandle,
baseAddress,
size,
0,
size,
SectionInherit.ViewShare,
0,
protection
);
}
public SectionView MapView(
ProcessHandle processHandle,
IntPtr baseAddress,
@@ -185,34 +252,5 @@ namespace ProcessHacker.Native.Objects
return new SectionView(baseAddress, commitSize);
}
public SectionView MapView(
ProcessHandle processHandle,
IntPtr baseAddress,
IntPtr size,
MemoryProtection protection
)
{
return this.MapView(
processHandle,
baseAddress,
size,
0,
size,
SectionInherit.ViewShare,
0,
protection
);
}
public SectionView MapView(IntPtr baseAddress, IntPtr size, MemoryProtection protection)
{
return this.MapView(ProcessHandle.GetCurrent(), baseAddress, size, protection);
}
public SectionView MapView(int size, MemoryProtection protection)
{
return this.MapView(IntPtr.Zero, new IntPtr(size), protection);
}
}
}
@@ -49,6 +49,8 @@
<Compile Include="Api\NativeStructs.cs" />
<Compile Include="Api\NtStatus.cs" />
<Compile Include="Cryptography.cs" />
<Compile Include="Memory\MemoryAllocStream.cs" />
<Compile Include="Memory\Section.cs" />
<Compile Include="Threading\CurrentThread.cs" />
<Compile Include="Threading\Event.cs" />
<Compile Include="ExtensionAttribute.cs" />