Code:
internal unsafe class Program
{
private static void ReadRelative(Process proc, IntPtr address, void* buffer, int numBytes)
{
Read(proc, new IntPtr((void*)(proc.MainModule.BaseAddress.ToInt64() + address.ToInt64())), buffer, numBytes);
}
private static void Read(Process proc, IntPtr address, void* buffer, int numBytes)
{
int numRead;
if (!Imports.ReadProcessMemory(proc.Handle, address, buffer, numBytes, out numRead) || numRead != numBytes)
throw new Win32Exception();
}
private static void Main(string[] args)
{
Process proc = Process.GetProcessesByName("wow").FirstOrDefault();
if (proc == null)
return;
IntPtr netClient;
ReadRelative(proc, new IntPtr(0x97DA5C), &netClient, sizeof(IntPtr));
List<Tuple<uint, uint>> found = new List<Tuple<uint, uint>>();
Dictionary<uint, uint> alreadyFound = new Dictionary<uint, uint>();
for (int i = 0; i <= ushort.MaxValue; i++)
{
uint opcode = (uint)i;
if ((opcode & 0x2399) == 769)
{
uint unscrambled = ((opcode & 6 | ((opcode & 0x60 | ((opcode & 0x1C00 | (opcode >> 1) & 0x6000) >> 3)) >> 2)) >> 1);
if (unscrambled - 1 > 509)
continue;
byte index;
ReadRelative(proc, new IntPtr(0x25D4E8 + unscrambled - 1), &index, sizeof(byte));
uint jumpAddr;
ReadRelative(proc, new IntPtr(0x25D1A0 + index * 4), &jumpAddr, sizeof(uint));
if (jumpAddr == proc.MainModule.BaseAddress.ToInt64() + 0x25D193)
continue;
found.Add(Tuple.Create(unscrambled, opcode));
}
else
{
if ((opcode & 0x2322) != 8738 || opcode == 57919 || opcode == 26159)
continue;
uint unscrambled = opcode & 1 | ((opcode & 0x1C | (((opcode & 0xC0) | ((opcode & 0x1C00 | (opcode >> 1) & 0x6000) >> 2)) >> 1)) >> 1);
uint addressCookie;
Read(proc, netClient + 1376 + 4*(int)unscrambled, &addressCookie, sizeof(uint));
if (addressCookie == 0)
continue;
uint address = addressCookie - ((opcode | (opcode << 16)) ^ 0x62A3A31D);
MemoryBasicInformation memBasicInfo;
if (Imports.NtQueryVirtualMemory(proc.Handle, new IntPtr((void*)address), MemoryInformationClass.MemoryBasicInformation, &memBasicInfo, (uint)sizeof(MemoryBasicInformation), null) < 0)
continue;
if (memBasicInfo.Type != 0x1000000 || memBasicInfo.AllocationBase != proc.MainModule.BaseAddress)
continue;
if (!alreadyFound.ContainsKey(unscrambled))
{
alreadyFound.Add(unscrambled, opcode);
found.Add(Tuple.Create(unscrambled, opcode));
}
else
Console.WriteLine("0x{0:X} -> 0x{1:X} (warning: already found as 0x{2:X})", unscrambled, opcode, alreadyFound[unscrambled]);
}
}
foreach (Tuple<uint, uint> t in found.OrderBy(t => t.Item1))
Console.WriteLine("0x{0:X} -> 0x{1:X}", t.Item1, t.Item2);
}
}