Skip to content

Commit

Permalink
messing with aob scans
Browse files Browse the repository at this point in the history
  • Loading branch information
erfg12 committed Jul 20, 2017
1 parent 244df94 commit 01ecdc5
Show file tree
Hide file tree
Showing 4 changed files with 201 additions and 83 deletions.
8 changes: 7 additions & 1 deletion Memory.sln
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.30501.0
VisualStudioVersion = 12.0.40629.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Memory", "Memory\Memory.csproj", "{9ABF5742-7489-455C-B94A-3A85725D939A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9ABF5742-7489-455C-B94A-3A85725D939A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9ABF5742-7489-455C-B94A-3A85725D939A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9ABF5742-7489-455C-B94A-3A85725D939A}.Debug|x64.ActiveCfg = Debug|x64
{9ABF5742-7489-455C-B94A-3A85725D939A}.Debug|x64.Build.0 = Debug|x64
{9ABF5742-7489-455C-B94A-3A85725D939A}.Debug|x86.ActiveCfg = Debug|x86
{9ABF5742-7489-455C-B94A-3A85725D939A}.Debug|x86.Build.0 = Debug|x86
{9ABF5742-7489-455C-B94A-3A85725D939A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9ABF5742-7489-455C-B94A-3A85725D939A}.Release|Any CPU.Build.0 = Release|Any CPU
{9ABF5742-7489-455C-B94A-3A85725D939A}.Release|x64.ActiveCfg = Release|x64
{9ABF5742-7489-455C-B94A-3A85725D939A}.Release|x64.Build.0 = Release|x64
{9ABF5742-7489-455C-B94A-3A85725D939A}.Release|x86.ActiveCfg = Release|x86
{9ABF5742-7489-455C-B94A-3A85725D939A}.Release|x86.Build.0 = Release|x86
EndGlobalSection
Expand Down
252 changes: 170 additions & 82 deletions Memory/Class1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ public static extern IntPtr OpenProcess(
Int32 dwProcessId
);

[DllImport("kernel32.dll", SetLastError = true)]
static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength);

[DllImport("kernel32.dll")]
static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo);

[DllImport("dbghelp.dll")]
static extern bool MiniDumpWriteDump(
IntPtr hProcess,
Expand All @@ -52,6 +58,9 @@ static extern bool WriteProcessMemory(
out IntPtr lpNumberOfBytesWritten
);

[DllImport("kernel32.dll")]
static extern int GetProcessId(IntPtr handle);

[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
static extern uint GetPrivateProfileString(
string lpAppName,
Expand Down Expand Up @@ -136,24 +145,28 @@ out IntPtr lpThreadId
const uint PAGE_READWRITE = 4;
#endregion

/// <summary>
/// The process handle that was opened. (Use OpenProcess function to populate this variable)
/// </summary>
public static IntPtr pHandle;

public Process procs = null;

/// <summary>
/// Open the PC game process with all security and access rights.
/// </summary>
/// <param name="procID">You can use the getProcIDFromName function to get this.</param>
/// <returns></returns>
public bool OpenGameProcess(int procID)
public bool OpenProcess(int procID)
{
if (isAdmin() == false)
{
Debug.Write("WARNING: You are NOT running this program as admin!! Visit https://github.com/erfg12/memory.dll/wiki/Administrative-Privileges");
MessageBox.Show("WARNING: You are NOT running this program as admin!!" + Environment.NewLine + "Visit https://github.com/erfg12/memory.dll/wiki/Administrative-Privileges");
}

/*try
{*/
try
{
Process.EnterDebugMode();
if (procID != 0) //getProcIDFromName returns 0 if there was a problem
procs = Process.GetProcessById(procID);
Expand All @@ -173,7 +186,7 @@ public bool OpenGameProcess(int procID)
mainModule = procs.MainModule;
getModules();
return true;
//} catch { return false; }
} catch { return false; }
}

/// <summary>
Expand Down Expand Up @@ -907,18 +920,17 @@ public void InjectDLL(String strDLLName)
return;
}

byte[] dumpBytes;

/// <summary>
/// Array of Bytes scan to find address. Returns IntPtr address. See https://github.com/erfg12/memory.dll/wiki/sigScan-(AoB-Scanning) for more information.
/// </summary>
/// <param name="min">address to start the scan</param>
/// <param name="length">length of scan</param>
/// <param name="code">array of bytes to look for. Can include partial masks. This can also be a ini file label.</param>
/// <param name="search">array of bytes to look for. Can include partial masks. This can also be a ini file label.</param>
/// <param name="file">path and name of ini file. (OPTIONAL)</param>
/// <returns></returns>
public IntPtr AoBScan(uint min, int length, string code, string file = "")
public IntPtr AoBScan(string search, string file = "")
{
scanSize = length;
string[] stringByteArray = LoadCode(code, file).Split(' ');
string[] stringByteArray = LoadCode(search, file).Split(' ');
byte[] myPattern = new byte[stringByteArray.Length];
string mask = "";
int i = 0;
Expand Down Expand Up @@ -946,37 +958,57 @@ public IntPtr AoBScan(uint min, int length, string code, string file = "")
}
i++;
}
IntPtr pAddr = (IntPtr)0;
//DumpMemory((UIntPtr)min, length);
dumpAddress = (UIntPtr)min;
pAddr = FindPattern(myPattern, mask, 0);
return pAddr;

//DumpMemory(0);
byte[] test = new byte[procs.VirtualMemorySize];
ReadProcessMemory(pHandle, (UIntPtr)0, test, (UIntPtr)procs.PrivateMemorySize, IntPtr.Zero);
File.WriteAllBytes("test.txt", test);
return (IntPtr)FindPattern(test, myPattern, mask);
}

UIntPtr dumpAddress = (UIntPtr)0x00000000;
int scanSize = 0;

private byte[] DumpMemory(UIntPtr addr, Int32 size)
/// <summary>
/// Quickly scans only a section of memory, instead of the entire thing like AoBScan does.
/// </summary>
/// <param name="start">starting address</param>
/// <param name="length">length to scan</param>
/// <param name="search">array of bytes to look for. Can include partial masks. This can also be a ini file label.</param>
/// <param name="file">path and name of ini file. (OPTIONAL)</param>
/// <returns></returns>
public IntPtr AoBScanFast(int start, int length, string search, string file = "")
{
scanSize = size;
dumpAddress = addr;
/*try
{*/
byte[] dumpRegion = new byte[size];
IntPtr numBytes = (IntPtr)0;
UIntPtr theSize = (UIntPtr)size;
Debug.Write("[DEBUG] AoB scan starts at 0x" + String.Format("{0:x8}", Convert.ToUInt32(dumpAddress.ToString())) + Environment.NewLine);
Debug.Write("[DEBUG] AoB scan length is 0x" + String.Format("{0:x8}", Convert.ToUInt32(theSize.ToString())) + Environment.NewLine);
Debug.Write("[DEBUG] AoB scan ends at 0x" + String.Format("{0:x8}", Convert.ToUInt32(UIntPtr.Add(dumpAddress, size).ToString())) + Environment.NewLine);
ReadProcessMemory(pHandle, dumpAddress, dumpRegion, (UIntPtr)size, numBytes);
Debug.Write("[DEBUG] AoB scan dumpRegion length is " + dumpRegion.Length.ToString() + Environment.NewLine);
Debug.Write("[DEBUG] AoB scan number of bytes read is " + numBytes.ToString() + Environment.NewLine);
return dumpRegion;
/*}
catch (Exception)
string[] stringByteArray = LoadCode(search, file).Split(' ');
byte[] myPattern = new byte[stringByteArray.Length];
string mask = "";
int i = 0;
foreach (string ba in stringByteArray)
{
return false;
}*/
if (ba == "??")
{
myPattern[i] = 0xFF;
mask += "?";
}
else if (Char.IsLetterOrDigit(ba[0]) && ba[1] == '?') //partial match
{
myPattern[i] = Encoding.ASCII.GetBytes("0x" + ba[0] + "F")[0];
mask += "?"; //show it's still a wildcard of some kind
}
else if (Char.IsLetterOrDigit(ba[1]) && ba[0] == '?') //partial match
{
myPattern[i] = Encoding.ASCII.GetBytes("0xF" + ba[1])[0];
mask += "?"; //show it's still a wildcard of some kind
}
else
{
myPattern[i] = Byte.Parse(ba, NumberStyles.HexNumber);
mask += "x";
}
i++;
}

//DumpMemory(0);
byte[] test = new byte[procs.VirtualMemorySize];
ReadProcessMemory(pHandle, (UIntPtr)0x10000, test, (UIntPtr)2, IntPtr.Zero);
return (IntPtr)FindPattern(test, myPattern, mask, start, length);
}

private bool MaskCheck(int nOffset, byte[] btPattern, string strMask, byte[] dumpRegion)
Expand Down Expand Up @@ -1005,20 +1037,10 @@ private bool MaskCheck(int nOffset, byte[] btPattern, string strMask, byte[] dum
}
}
}
//Debug.Write("[DEBUG] AoB scan comparing " + String.Format("0x{0:x2}", Convert.ToUInt32(btPattern[x].ToString())) + " and " + String.Format("0x{0:x2}", Convert.ToUInt32(dumpRegion[nOffset + x].ToString())) + " at " + String.Format("0x{0:x8}", Convert.ToUInt32((nOffset + x).ToString())) + " nOffset:" + nOffset.ToString() + " x:" + x.ToString() + Environment.NewLine);

//if ((nOffset + x) < btPattern.Length) //prevent going out of index range
//{
// If the mask char is not a wildcard, ensure a match is made in the pattern.
if ((strMask[x] == 'x') && (btPattern[x] != dumpRegion[nOffset + x]))
{
Debug.Write("[DEBUG] AoB scan comparing " + String.Format("0x{0:x2}", Convert.ToUInt32(btPattern[x].ToString())) + " and " + String.Format("0x{0:x2}", Convert.ToUInt32(dumpRegion[nOffset + x].ToString())) + " at " + String.Format("0x{0:x8}", Convert.ToUInt32((dumpAddress + nOffset + x).ToString())) + " nOffset:" + nOffset.ToString() + " x:" + x.ToString() + Environment.NewLine);
return false;
}
//}
//else
//{
//return false; //we are attempting to go outside of the range, so that means we didn't find it.
//}
if ((strMask[x] == 'x') && (btPattern[x] != dumpRegion[nOffset + x]))
return false;
}

// The loop was successful so we found 1 pattern match.
Expand All @@ -1038,6 +1060,11 @@ public static string ByteArrayToString(byte[] ba)
return hex.ToString();
}

/// <summary>
/// Convert a byte array to hex values in a string.
/// </summary>
/// <param name="ba">your byte array to convert</param>
/// <returns></returns>
public static string ByteArrayToHexString(byte[] ba)
{
StringBuilder hex = new StringBuilder(ba.Length * 2);
Expand All @@ -1056,48 +1083,109 @@ public static string ByteArrayToHexString(byte[] ba)
return hex.ToString();
}

public static void DumpToFile(String fileToDump)
public int FindPattern(byte[] haystack, byte[] needle, string strMask, int start = 0, int length = 0)
{
if (length == 0)
length = (haystack.Length - start);

Debug.Write("[DEBUG] starting AoB scan at " + start + " and going " + length + " length.");
Debug.Write("[DEBUG] AoB mask is " + strMask + Environment.NewLine);
Debug.Write("[DEBUG] AoB pattern is " + ByteArrayToString(needle) + Environment.NewLine);
Debug.Write("[DEBUG] memory dump (" + haystack.Length + ")");

for (int x = start; x < (start + length); x++)
{
if (MaskCheck(x, needle, strMask, haystack))
{
//string total = (x + diff).ToString("x8");
Debug.Write("[DEBUG] base address is " + procs.MainModule.BaseAddress.ToString("x8") + " and resulting offset is " + x.ToString("x8") + " min address is " + getMinAddress().ToString("x8") + Environment.NewLine);
return (x);
}
}

return 0;
}

public struct SYSTEM_INFO
{
public ushort processorArchitecture;
ushort reserved;
public uint pageSize;
public IntPtr minimumApplicationAddress; // minimum address
public IntPtr maximumApplicationAddress; // maximum address
public IntPtr activeProcessorMask;
public uint numberOfProcessors;
public uint processorType;
public uint allocationGranularity;
public ushort processorLevel;
public ushort processorRevision;
}

public struct MEMORY_BASIC_INFORMATION
{
public ulong BaseAddress;
public ulong AllocationBase;
public int AllocationProtect;
public ulong RegionSize;
public int State;
public ulong Protect;
public ulong Type;
}

public ulong getMinAddress()
{
SYSTEM_INFO SI;
GetSystemInfo(out SI);
return (ulong)SI.minimumApplicationAddress;
}

int diff = 0;

/// <summary>
/// dumps process memory to file
/// </summary>
/// <param name="type">0 = dump to variable dumpBytes, 1 = raw dump file, 2 = hex in text file, 3 = both raw dump and hex in text</param>
public void DumpMemory(int type = 0)
{
int procID = GetProcessId(pHandle);
var str = "";
string rawFile = Process.GetProcessById(procID).ProcessName + ".DMP";
string txtFile = Process.GetProcessById(procID).ProcessName + ".TXT";
//Debug.Write("[DEBUG] Now dumping process ID:" + procID.ToString() + " (" + Process.GetProcessById(procID).ProcessName + ")" + Environment.NewLine);

FileStream fsToDump = null;
if (File.Exists(fileToDump))
fsToDump = File.Open(fileToDump, FileMode.Append);
if (File.Exists(rawFile))
fsToDump = File.Open(rawFile, FileMode.Append);
else
fsToDump = File.Create(fileToDump);
fsToDump = File.Create(rawFile);

//Debug.Write("[DEBUG] writing raw values to dump file.." + Environment.NewLine);
Process thisProcess = Process.GetCurrentProcess();
MiniDumpWriteDump(thisProcess.Handle, thisProcess.Id, fsToDump.SafeFileHandle.DangerousGetHandle(), 0x00000000, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
MiniDumpWriteDump(pHandle, procID, fsToDump.SafeFileHandle.DangerousGetHandle(), 0x001fffff, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
fsToDump.Close();
byte[] bytes = File.ReadAllBytes(fileToDump);
var str = ByteArrayToHexString(bytes);
File.Delete(fileToDump);
File.WriteAllText(fileToDump, str);
}

public IntPtr FindPattern(byte[] btPattern, string strMask, int nOffset)
{
/*try
{*/
if (strMask.Length != btPattern.Length)
return IntPtr.Zero;
if (type == 0)
{
dumpBytes = File.ReadAllBytes(rawFile);
diff = Convert.ToInt32(procs.WorkingSet) - dumpBytes.Length;
MessageBox.Show(diff.ToString() + " 0x" + diff.ToString("x8"));
}

Debug.Write("[DEBUG] AoB mask is " + strMask + Environment.NewLine);
Debug.Write("[DEBUG] AoB pattern is " + ByteArrayToString(btPattern) + Environment.NewLine);
if (type == 1)
{
//Debug.Write("[DEBUG] converting raw values to hex string values, this can take a while..." + Environment.NewLine);
byte[] bytes = File.ReadAllBytes(rawFile);
str = ByteArrayToHexString(bytes);
}

//Debug.Write("[DEBUG] memory dump (" + dumpRegion.Length + ") = " + ByteArrayToString(dumpRegion));
byte[] dumpRegion = DumpMemory(dumpAddress, scanSize);
if (type < 2)
File.Delete(rawFile);

for (int x = 0; x < scanSize; x++)
{
if (MaskCheck(x, btPattern, strMask, dumpRegion))
{
return new IntPtr((int)dumpAddress + (x + nOffset));
}
}
return IntPtr.Zero;
/*}
catch (Exception)
if (type == 1)
{
return IntPtr.Zero;
}*/
//Debug.Write("[DEBUG] deleting raw dump file and writing hex string values to text file..." + Environment.NewLine);
File.WriteAllText(txtFile, str);
}
}
}
}
Loading

0 comments on commit 01ecdc5

Please sign in to comment.