Code:
using System;
using System.Collections.Generic;
using System.Text;
using MemoryLib;
namespace ExternalFindPattern
{
class Program
{
static void Main(string[] args)
{
DateTime now = DateTime.Now; //used for testing how long it takes to find the tls pointer
System.Diagnostics.Process.EnterDebugMode(); //gives our program debug permissions
//open wow for read/write
IntPtr hProcess = Memory.OpenProcess(Memory.GetProcessIdByProcessName("wow.exe"));
//if open process was successful
if (hProcess != IntPtr.Zero)
{
//search for the code pattern that we want (in this case, WoW TLS)
uint tlscode = dwFindPattern(hProcess, 0x410000, 0x400000,
"EB 02 33 00 64 8B 15 2C 00 00 00 8B 0D 00 00 00 00 8B 0C 8A",
"xxx?xxxxxxxxx????xxx");
//read Kynox's g_clientConnection from memory
uint g_clientConnection = Memory.ReadUInt(hProcess, Memory.ReadUInt(hProcess, (tlscode + 0x16)));
//first, the offset for the curMgr inside g_clientConnection is read,
//then s_curMgr is read from g_clientConnection + that offset (which may change version to version,
//I honestly don't know)
uint s_curMgr = Memory.ReadUInt(hProcess, (g_clientConnection + Memory.ReadInt(hProcess, tlscode + 0x22)));
//output to console
Console.WriteLine("TLS code: 0x{0:X08}ng_clientConnection: 0x{1:X08}ns_curMgr: 0x{2:X08}", tlscode, g_clientConnection, s_curMgr);
Memory.CloseHandle(hProcess);
}
//tell user how long it took to find and get what we wanted
TimeSpan timer = DateTime.Now.Subtract(now);
Console.WriteLine("nnTime taken: {0}msnnPlease press [ENTER] to continue...", timer.Milliseconds);
Console.ReadLine();
}
#region dwFindPattern
//blatantly adapted/copied from dom1n1k :)
static bool bDataCompare(byte[] data, int index, byte[] pattern, string mask)
{
if (pattern.Length != mask.Length) return false;
for (int i = 0; i < pattern.Length; i++)
if (mask[i] == 'x' && (data[index + i] != pattern[i]))
return false;
return true;
}
//blatantly adapted/copied from dom1n1k :)
static uint dwFindPattern(IntPtr hProcess, uint start, int length, string _pattern, string mask, char delimiter)
{
string[] p = _pattern.Split(delimiter);
byte[] pattern = new byte[p.Length];
for (int i = 0; i < p.Length; i++)
pattern[i] = Convert.ToByte(p[i], 16);
const int bytestoread = 1024;
int index = 0;
byte[] buf;
if (bytestoread > length)
{
buf = new byte[length];
Memory.ReadMemory(hProcess, start, ref buf);
for (int i = 0; i < (buf.Length - pattern.Length); i++)
if (bDataCompare(buf, i, pattern, mask))
return (uint)(start + i);
}
else
{
while (index < length)
{
buf = new byte[bytestoread + pattern.Length];
Memory.ReadMemory(hProcess, start + index, ref buf);
for (int i = 0; i < bytestoread; i++)
if (bDataCompare(buf, i, pattern, mask))
return (uint)(start + index + i);
index += bytestoread;
}
}
return uint.MaxValue;
}
static uint dwFindPattern(IntPtr hProcess, uint start, int length, string _pattern, string mask)
{
return dwFindPattern(hProcess, start, length, _pattern, mask, ' ');
}
#endregion
}
}
Now then, this serves two purposes: