You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
311 lines
11 KiB
311 lines
11 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Diagnostics;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
using System.IO;
|
|
|
|
namespace AnimeSoftware
|
|
{
|
|
class Memory
|
|
{
|
|
[DllImport("kernel32.dll")]
|
|
private static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
|
|
|
|
[DllImport("Kernel32.dll")]
|
|
internal static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, UInt32 nSize, ref UInt32 lpNumberOfBytesRead);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out IntPtr lpNumberOfBytesRead);
|
|
|
|
[DllImport("kernel32.dll")]
|
|
internal static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, IntPtr nSize, ref UInt32 lpNumberOfBytesWritten);
|
|
|
|
[DllImport("kernel32.dll")]
|
|
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, int size, int lpNumberOfBytesWritten);
|
|
|
|
const int PROCESS_VM_OPERATION = 0x0008;
|
|
const int PROCESS_VM_READ = 0x0010;
|
|
const int PROCESS_VM_WRITE = 0x0020;
|
|
|
|
public static Process process;
|
|
public static IntPtr pHandle;
|
|
|
|
public static Int32 Client;
|
|
public static Int32 ClientSize;
|
|
public static Int32 Engine;
|
|
public static Int32 EngineSize;
|
|
public static Int32 vstdlib;
|
|
public static Int32 vstdlibSize;
|
|
|
|
|
|
|
|
public static bool OpenProcess(string name)
|
|
{
|
|
|
|
try
|
|
{
|
|
process = Process.GetProcessesByName(name)[0];
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
if (Properties.Settings.Default.debug)
|
|
Console.WriteLine("Can't open process.");
|
|
return false;
|
|
}
|
|
}
|
|
public static bool ProcessHandle()
|
|
{
|
|
try
|
|
{
|
|
pHandle = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, false, process.Id);
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
if (Properties.Settings.Default.debug)
|
|
Console.WriteLine("Can't get handle.");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static bool GetModules()
|
|
{
|
|
try
|
|
{
|
|
foreach (ProcessModule module in process.Modules)
|
|
{
|
|
if (module.ModuleName == "client_panorama.dll")
|
|
{
|
|
Client = (Int32)module.BaseAddress;
|
|
ClientSize = (Int32)module.ModuleMemorySize;
|
|
}
|
|
else if (module.ModuleName == "engine.dll")
|
|
{
|
|
Engine = (Int32)module.BaseAddress;
|
|
EngineSize = (Int32)module.ModuleMemorySize;
|
|
}
|
|
else if (module.ModuleName == "vstdlib.dll")
|
|
{
|
|
vstdlib = (Int32)module.BaseAddress;
|
|
vstdlibSize = (Int32)module.ModuleMemorySize;
|
|
}
|
|
}
|
|
if ((IntPtr)Client == IntPtr.Zero || (IntPtr)Engine == IntPtr.Zero || (IntPtr)vstdlib == IntPtr.Zero)
|
|
{
|
|
if (Properties.Settings.Default.debug)
|
|
{
|
|
Console.WriteLine(String.Format("Client: {0}\nEngine: {1}\nvstdlib: {2}\n", Client, Engine, vstdlib));
|
|
Console.WriteLine("Module error");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
if (Properties.Settings.Default.debug)
|
|
Console.WriteLine("Module get error");
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
public static byte[] ReadBytes(Int32 address, int length)
|
|
{
|
|
byte[] buffer = new byte[length];
|
|
UInt32 nBytesRead = UInt32.MinValue;
|
|
bool success = ReadProcessMemory(pHandle, (IntPtr)address, buffer, (UInt32)length, ref nBytesRead);
|
|
return buffer;
|
|
}
|
|
|
|
public static T Read<T>(Int32 address)
|
|
{
|
|
int length = Marshal.SizeOf(typeof(T));
|
|
|
|
if (typeof(T) == typeof(bool))
|
|
length = 1;
|
|
|
|
byte[] buffer = new byte[length];
|
|
UInt32 nBytesRead = UInt32.MinValue;
|
|
ReadProcessMemory(pHandle, (IntPtr)address, buffer, (UInt32)length, ref nBytesRead);
|
|
return GetStructure<T>(buffer);
|
|
}
|
|
|
|
public static void WriteBytes(Int32 address, byte[] value)
|
|
{
|
|
UInt32 nBytesRead = UInt32.MinValue;
|
|
WriteProcessMemory(pHandle, (IntPtr)address, value, (IntPtr)value.Length, ref nBytesRead);
|
|
}
|
|
|
|
public static void Write<T>(Int32 address, T value)
|
|
{
|
|
int length = Marshal.SizeOf(typeof(T));
|
|
byte[] buffer = new byte[length];
|
|
|
|
IntPtr ptr = Marshal.AllocHGlobal(length);
|
|
Marshal.StructureToPtr(value, ptr, true);
|
|
Marshal.Copy(ptr, buffer, 0, length);
|
|
Marshal.FreeHGlobal(ptr);
|
|
|
|
UInt32 nBytesRead = UInt32.MinValue;
|
|
WriteProcessMemory(pHandle, (IntPtr)address, buffer, (IntPtr)length, ref nBytesRead);
|
|
}
|
|
|
|
public static T GetStructure<T>(byte[] bytes)
|
|
{
|
|
var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
|
var structure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
|
|
handle.Free();
|
|
return structure;
|
|
}
|
|
|
|
|
|
public static string ReadString(Int32 address, int bufferSize, Encoding enc)
|
|
{
|
|
byte[] buffer = new byte[bufferSize];
|
|
UInt32 nBytesRead = 0;
|
|
bool success = ReadProcessMemory(pHandle, (IntPtr)address, buffer, (UInt32)bufferSize, ref nBytesRead);
|
|
string text = enc.GetString(buffer);
|
|
if (text.Contains('\0'))
|
|
text = text.Substring(0, text.IndexOf('\0'));
|
|
return text;
|
|
}
|
|
|
|
public static string ReadText(IntPtr hProcess, IntPtr address)
|
|
{
|
|
using (MemoryStream ms = new MemoryStream())
|
|
{
|
|
int offset = 0;
|
|
byte read;
|
|
while ((read = ReadMemory(hProcess, address + offset, 1)[0]) != 0)
|
|
{
|
|
ms.WriteByte(read);
|
|
offset++;
|
|
}
|
|
var data = ms.ToArray();
|
|
return Encoding.UTF8.GetString(data, 0, data.Length);
|
|
}
|
|
}
|
|
|
|
public static byte[] ReadMemory(IntPtr hProcess, IntPtr address, int length)
|
|
{
|
|
byte[] data = new byte[length];
|
|
if (!ReadProcessMemory(hProcess, address, data, data.Length, out IntPtr unused))
|
|
{
|
|
return null;
|
|
}
|
|
return data;
|
|
}
|
|
|
|
public static int FindPattern(byte[] pattern, string mask, int moduleBase, int moduleSize)
|
|
{
|
|
byte[] moduleBytes = new byte[moduleSize];
|
|
uint numBytes = 0;
|
|
|
|
if (ReadProcessMemory(Memory.pHandle, (IntPtr)moduleBase, moduleBytes, (uint)moduleSize, ref numBytes))
|
|
{
|
|
for (int i = 0; i < moduleSize; i++)
|
|
{
|
|
bool found = true;
|
|
|
|
for (int l = 0; l < mask.Length; l++)
|
|
{
|
|
found = mask[l] == '?' || moduleBytes[l + i] == pattern[l];
|
|
|
|
if (!found)
|
|
break;
|
|
}
|
|
|
|
if (found)
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
internal static class Sig
|
|
{
|
|
private static byte[] _dump;
|
|
|
|
private static void Dump(IntPtr module, Int32 moduleSize)
|
|
{
|
|
_dump = Memory.ReadBytes((Int32)module, moduleSize);
|
|
}
|
|
|
|
private static bool CheckSig(int index, Signature signature)
|
|
{
|
|
for (int i = 0; i < signature.ByteArray.Length; i++)
|
|
{
|
|
if (signature.Mask[i] == '?')
|
|
continue;
|
|
|
|
if (signature.ByteArray[i] != _dump[index + i])
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static Int32 COffset(string sig, int offset = 0, int extra = 0)
|
|
{
|
|
return GetOffset(sig, offset, extra, (IntPtr)Memory.Client, Memory.ClientSize);
|
|
}
|
|
|
|
public static Int32 EOffset(string sig, int offset = 0, int extra = 0)
|
|
{
|
|
return GetOffset(sig, offset, extra, (IntPtr)Memory.Engine, Memory.EngineSize);
|
|
}
|
|
|
|
public static Int32 GetOffset(string sig, int offset, int extra, IntPtr module, Int32 moduleSize)
|
|
{
|
|
Dump(module, moduleSize);
|
|
|
|
|
|
Signature signature = new Signature(sig, offset);
|
|
|
|
for (int i = 0; i < moduleSize; i++)
|
|
{
|
|
if (signature.Address == IntPtr.Zero && CheckSig(i, signature))
|
|
{
|
|
var _offset = signature.Offset;
|
|
signature = new Signature(module + i + _offset);
|
|
|
|
if (signature.Address != IntPtr.Zero)
|
|
return BitConverter.ToInt32(Memory.ReadBytes((Int32)signature.Address, 4), 0) + extra - module.ToInt32();
|
|
|
|
}
|
|
}
|
|
Console.WriteLine(String.Format("The Signature {0}\nCouldn't Be Found.", sig));
|
|
return Int32.MinValue;
|
|
}
|
|
|
|
public static Signature GetSignature(Signature sig, IntPtr module, Int32 moduleSize)
|
|
{
|
|
byte[] dumped = Memory.ReadBytes((Int32)module, moduleSize);
|
|
|
|
for (int i = 0; i < moduleSize; i++)
|
|
{
|
|
if (sig.Address == IntPtr.Zero && CheckSig(i, sig))
|
|
{
|
|
var offset = sig.Offset;
|
|
sig = new Signature(module + i + offset);
|
|
|
|
if (sig.Address != IntPtr.Zero)
|
|
{
|
|
return sig;
|
|
}
|
|
}
|
|
}
|
|
return sig;
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
|