sigScan C# Implementation - Written by atom0s [aka Wiccaan]
Необходимые "ссылки"
Код:
using System.Diagnostics;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
Сам класс:
Код:
public class SigScan
{
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool ReadProcessMemory(IntPtr hProcess,IntPtr lpBaseAddress,[Out()] byte[] lpBuffer,int dwSize,out int lpNumberOfBytesRead);
/// m_vDumpedRegion
private byte[] m_vDumpedRegion;
/// m_vProcess
private Process m_vProcess;
private IntPtr m_vAddress;
/// m_vSize
private Int32 m_vSize;
#region "sigScan Class Construction"
/// SigScan
public SigScan()
{
this.m_vProcess = null;
this.m_vAddress = IntPtr.Zero;
this.m_vSize = 0;
this.m_vDumpedRegion = null;
}
/// SigScan
/// <param name="proc">The process to dump the memory from.</param>
/// <param name="addr">The started address to begin the dump.</param>
/// <param name="size">The size of the dump.</param>
public SigScan(Process proc, IntPtr addr, int size)
{
this.m_vProcess = proc;
this.m_vAddress = addr;
this.m_vSize = size;
}
#endregion
#region "sigScan Class Private Methods"
/// DumpMemory
/// <returns>Boolean based on RPM results and valid properties.</returns>
private bool DumpMemory()
{
try
{
// Checks to ensure we have valid data.
if (this.m_vProcess == null) return false;
if (this.m_vProcess.HasExited == true) return false;
if (this.m_vAddress == IntPtr.Zero) return false;
if (this.m_vSize == 0) return false;
// Create the region space to dump into.
this.m_vDumpedRegion = new byte[this.m_vSize];
bool bReturn = false;
int nBytesRead = 0;
// Dump the memory.
bReturn = ReadProcessMemory( this.m_vProcess.Handle, this.m_vAddress, this.m_vDumpedRegion, this.m_vSize, out nBytesRead);
// Validation checks.
if (bReturn == false || nBytesRead != this.m_vSize)return false;
return true;
}
catch (Exception ex)
{
return false;
}
}
/// MaskCheck
/// <param name="nOffset">Offset in the dump to start at.</param>
/// <param name="btPattern">Pattern to scan for.</param>
/// <param name="strMask">Mask to compare against.</param>
/// <returns>Boolean depending on if the pattern was found.</returns>
private bool MaskCheck(int nOffset, byte[] btPattern, string strMask)
{
// Loop the pattern and compare to the mask and dump.
for (int x = 0; x < btPattern.Length; x++)
{
// If the mask char is a wildcard, just continue.
if (strMask[x] == '?')
continue;
// If the mask char is not a wildcard, ensure a match is made in the pattern.
if ((strMask[x] == 'x') && (btPattern[x] != this.m_vDumpedRegion[nOffset + x]))
return false;
}
// The loop was successful so we found the pattern.
return true;
}
#endregion
#region "sigScan Class Public Methods"
/// FindPattern
/// <param name="btPattern">Byte pattern to look for in the dumped region.</param>
/// <param name="strMask">The mask string to compare against.</param>
/// <param name="nOffset">The offset added to the result address.</param>
/// <returns>IntPtr - zero if not found, address if found.</returns>
public IntPtr FindPattern(byte[] btPattern, string strMask, int nOffset)
{
try
{
// Dump the memory region if we have not dumped it yet.
if (this.m_vDumpedRegion == null || this.m_vDumpedRegion.Length == 0)
{
if (!this.DumpMemory())return IntPtr.Zero;
}
// Ensure the mask and pattern lengths match.
if (strMask.Length != btPattern.Length) return IntPtr.Zero;
for (int x = 0; x < this.m_vDumpedRegion.Length; x++)
{
if (this.MaskCheck(x, btPattern, strMask))
{
// The pattern was found, return it.
return new IntPtr((int)this.m_vAddress + (x + nOffset));
}
}
// Pattern was not found.
return IntPtr.Zero;
}
catch (Exception ex)
{
return IntPtr.Zero;
}
}
public void ResetRegion()
{
this.m_vDumpedRegion = null;
}
#endregion
#region "sigScan Class Properties"
public Process Process
{
get { return this.m_vProcess; }
set { this.m_vProcess = value; }
}
public IntPtr Address
{
get { return this.m_vAddress; }
set { this.m_vAddress = value; }
}
public Int32 Size
{
get { return this.m_vSize; }
set { this.m_vSize = value; }
}
#endregion
}