0% found this document useful (0 votes)
0 views

Cx.cs

Uploaded by

desafiantevini
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
0 views

Cx.cs

Uploaded by

desafiantevini
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 10

using System;

using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using CXMem;

namespace CXMem
{

public class CX
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess,
[MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);

[DllImport("kernel32.dll", SetLastError = true)]


public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr
lpAddress, uint dwSize, uint flAllocationType, uint flProtect);

[DllImport("kernel32.dll", SetLastError = true)]


public static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress,
out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength);

[DllImport("kernel32.dll", SetLastError = true)]


public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr
lpBaseAddress, [Out] byte[] lpBuffer, IntPtr nSize, out IntPtr
lpNumberOfBytesRead);

[DllImport("kernel32.dll", SetLastError = true)]


public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr
lpBaseAddress, byte[] lpBuffer, IntPtr nSize, IntPtr lpNumberOfBytesWritten);

[DllImport("kernel32.dll")]
public static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool
bInheritHandle, uint dwThreadId);

[DllImport("kernel32.dll")]
public static extern int ResumeThread(IntPtr hThread);

[DllImport("kernel32.dll")]
public static extern int CloseHandle(IntPtr hObject);

[DllImport("kernel32.dll", SetLastError = true)]


public static extern IntPtr GetProcAddress(IntPtr hModule, string
lpProcName);

[DllImport("kernel32.dll", SetLastError = true)]


public static extern IntPtr GetModuleHandle(string lpModuleName);

[DllImport("kernel32.dll", SetLastError = true)]


public static extern uint WaitForSingleObject(IntPtr hHandle, uint
dwMilliseconds);

[DllImport("kernel32.dll")]
public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr
lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter,
uint dwCreationFlags, IntPtr lpThreadId);

[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcessDll(int dwDesiredAccess, bool
bInheritHandle, int dwProcessId);

[DllImport("kernel32.dll", SetLastError = true)]


public static extern bool WriteProcessMemoryDll(IntPtr hProcess, IntPtr
lpBaseAddress, byte[] lpBuffer, uint nSize, out int lpNumberOfBytesWritten);
public struct PatternData
{
public byte[] pattern { get; set; }

public byte[] mask { get; set; }


}
public struct MemoryPage
{
public IntPtr Start;

public int Size;

public MemoryPage(IntPtr start, int size)


{
Start = start;
Size = size;
}
}

private void InjectDll(string DLLPath)


{
Process[] processes = Process.GetProcessesByName("HD-Player");
if (processes.Length > 0)
{
int processId = processes[0].Id;

IntPtr hProcess = OpenProcessDll(0x1F0FFF, false, processId);

if (hProcess != IntPtr.Zero)
{

byte[] buffer = System.Text.Encoding.ASCII.GetBytes(DLLPath);

IntPtr remoteBuffer = VirtualAllocEx(hProcess, IntPtr.Zero,


(uint)buffer.Length, 0x1000, 0x40);

int bytesWritten;

WriteProcessMemoryDll(hProcess, remoteBuffer, buffer,


(uint)buffer.Length, out bytesWritten);

IntPtr loadLibraryAddr =
GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");

IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0,


loadLibraryAddr, remoteBuffer, 0, IntPtr.Zero);

WaitForSingleObject(hThread, 0xFFFFFFFF);

CloseHandle(hProcess);
}
}
}

public struct MEMORY_BASIC_INFORMATION


{
public IntPtr BaseAddress;

public IntPtr AllocationBase;

public uint AllocationProtect;

public UIntPtr RegionSize;

public uint State;

public uint Protect;

public uint Type;


}

public bool isPrivate;

public int processId;

public IntPtr _processHandle;

private bool _enableCheck = true;

public const uint MEM_COMMIT = 4096u;

public const uint MEM_PRIVATE = 131072u;

public const uint PAGE_READWRITE = 4u;

public bool SetProcess(string[] processNames)


{
processId = 0;
Process[] processes = Process.GetProcesses();
foreach (Process process in processes)
{
string processName = process.ProcessName;
if (Array.Exists(processNames, (string name) =>
name.Equals(processName, StringComparison.CurrentCultureIgnoreCase)))
{
processId = process.Id;
break;
}
}
if (processId <= 0)
{
return false;
}
_processHandle = OpenProcess(ProcessAccessFlags.AllAccess,
bInheritHandle: false, processId);
if (_processHandle == IntPtr.Zero)
{
return false;
}
return true;
}
public void CheckProcess()
{
if (!_enableCheck)
{
return;
}
foreach (ProcessThread thread in
Process.GetProcessById(processId).Threads)
{
IntPtr intPtr = OpenThread(ThreadAccess.SUSPEND_RESUME,
bInheritHandle: false, (uint)thread.Id);
if (intPtr != IntPtr.Zero)
{
int num = 0;
do
{
num = ResumeThread(intPtr);
}
while (num > 0);
CloseHandle(intPtr);
}
}
}

public async Task<IEnumerable<long>> AoBScan(string bytePattern)


{
return await AobScan(bytePattern);
}

private async Task<IEnumerable<long>> AobScan(string pattern)


{
PatternData patternData = GetPatternDataFromPattern(pattern);
List<long> addressRet = new List<long>();

await Task.Run(() =>


{
List<MemoryPage> list = new List<MemoryPage>();
IntPtr intPtr = IntPtr.Zero;
MEMORY_BASIC_INFORMATION lpBuffer;

while (VirtualQueryEx(_processHandle, intPtr, out lpBuffer,


(uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION))) ==
(uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION)))
{
if (CanReadPage(lpBuffer))
{
list.Add(new MemoryPage(intPtr,
(int)lpBuffer.RegionSize.ToUInt64()));
}
intPtr = (IntPtr)((long)lpBuffer.BaseAddress + (long)
(ulong)lpBuffer.RegionSize);
}

int patternLength = patternData.pattern.Length;

Parallel.ForEach(list, addresss =>


{
byte[] array = new byte[addresss.Size];
if (ReadProcessMemory(_processHandle, addresss.Start, array,
(IntPtr)addresss.Size, out var lpNumberOfBytesRead))
{
int num = -patternLength;
do
{
num = FindPattern(array, patternData.pattern,
patternData.mask, num + patternLength);
if (num >= 0)
{
lock (addressRet)
{
addressRet.Add((long)addresss.Start + num);
}
}
}
while (num != -1);
}
});
});

return addressRet.OrderBy(c => c).AsEnumerable();


}

public bool CanReadPage(MEMORY_BASIC_INFORMATION page)


{
if (page.State == 4096 && page.Type == 131072)
{
return page.Protect == 4;
}
return false;
}

private PatternData GetPatternDataFromPattern(string pattern)


{
string[] patternParts = pattern.Split(' ');

PatternData patternData = new PatternData


{
pattern = patternParts.Select(s => s.Contains("??") ? (byte)0x00 :
byte.Parse(s, NumberStyles.HexNumber)).ToArray(),
mask = patternParts.Select(s => s.Contains("??") ? (byte)0x00 :
(byte)0xFF).ToArray()
};

return patternData;
}

public bool AobReplace(long address, string bytePattern)


{
try
{
byte[] array = StringToByteArray(bytePattern);
return WriteProcessMemory(_processHandle, (IntPtr)address, array,
(IntPtr)array.Length, IntPtr.Zero);
}
catch (Exception)
{
}
return false;
}

public bool AobReplace(long address, int bytePattern)


{
byte[] bytes = BitConverter.GetBytes(bytePattern);
return WriteProcessMemory(_processHandle, (IntPtr)address, bytes,
(IntPtr)bytes.Length, IntPtr.Zero);
}

public async Task<int> ReadIntAsync(long addressToRead)


{
return await Task.Run(() => ReadInt(addressToRead));
}

public int ReadInt(long addressToRead)


{
byte[] array = new byte[4];
if (ReadProcessMemory(_processHandle, (IntPtr)addressToRead, array,
(IntPtr)array.Length, out var _))
{
return BitConverter.ToInt32(array, 0);
}
return 0;
}

public float ReadFloat(long addressToRead)


{
byte[] array = new byte[4];
if (ReadProcessMemory(_processHandle, (IntPtr)addressToRead, array,
(IntPtr)array.Length, out var _))
{
return BitConverter.ToSingle(array, 0);
}
return 0f;
}
public byte ReadHexByte(long addressToRead)
{
byte[] array = new byte[1];
if (ReadProcessMemory(_processHandle, (IntPtr)addressToRead, array,
(IntPtr)array.Length, out var _))
{
return array[0];
}
return 0;
}

public short ReadInt16(long addressToRead)


{
byte[] array = new byte[2];
if (ReadProcessMemory(_processHandle, (IntPtr)addressToRead, array,
(IntPtr)array.Length, out var _))
{
return BitConverter.ToInt16(array, 0);
}
return 0;
}

public string ReadString(long addressToRead, int size)


{
byte[] buffer = new byte[size];
IntPtr bytesRead;

bool readSuccess = ReadProcessMemory(_processHandle,


(IntPtr)addressToRead, buffer, (IntPtr)size, out bytesRead);

if (readSuccess && bytesRead.ToInt64() == size)


{
return BitConverter.ToString(buffer).Replace("-", " ");
}
return "";
}
private byte[] StringToByteArray(string hexString)
{
return (from hex in hexString.Split(' ')
select byte.Parse(hex, NumberStyles.HexNumber)).ToArray();
}

private int FindPattern(byte[] body, byte[] pattern, byte[] masks, int


start = 0)
{
int result = -1;
if (body.Length == 0 || pattern.Length == 0 || start > body.Length -
pattern.Length || pattern.Length > body.Length)
{
return result;
}
for (int i = start; i <= body.Length - pattern.Length; i++)
{
if ((body[i] & masks[0]) != (pattern[0] & masks[0]))
{
continue;
}
bool flag = true;
for (int num = pattern.Length - 1; num >= 1; num--)
{
if ((body[i + num] & masks[num]) != (pattern[num] &
masks[num]))
{
flag = false;
break;
}
}
if (flag)
{
result = i;
break;
}
}
return result;
}
}
#region ProcessAccessFlags
/// <summary>
/// Process access rights list.
/// </summary>
[Flags]
public enum ProcessAccessFlags
{
/// <summary>
/// All possible access rights for a process object.
/// </summary>
AllAccess = 0x001F0FFF,
/// <summary>
/// Required to create a process.
/// </summary>
CreateProcess = 0x0080,
/// <summary>
/// Required to create a thread.
/// </summary>
CreateThread = 0x0002,
/// <summary>
/// Required to duplicate a handle using DuplicateHandle.
/// </summary>
DupHandle = 0x0040,
/// <summary>
/// Required to retrieve certain information about a process, such as its
token, exit code, and priority class (see OpenProcessToken).
/// </summary>
QueryInformation = 0x0400,
/// <summary>
/// Required to retrieve certain information about a process (see
GetExitCodeProcess, GetPriorityClass, IsProcessInJob, QueryFullProcessImageName).
/// A handle that has the PROCESS_QUERY_INFORMATION access right is
automatically granted PROCESS_QUERY_LIMITED_INFORMATION.
/// </summary>
QueryLimitedInformation = 0x1000,
/// <summary>
/// Required to set certain information about a process, such as its
priority class (see SetPriorityClass).
/// </summary>
SetInformation = 0x0200,
/// <summary>
/// Required to set memory limits using SetProcessWorkingSetSize.
/// </summary>
SetQuota = 0x0100,
/// <summary>
/// Required to suspend or resume a process.
/// </summary>
SuspendResume = 0x0800,
/// <summary>
/// Required to terminate a process using TerminateProcess.
/// </summary>
Terminate = 0x0001,
/// <summary>
/// Required to perform an operation on the address space of a process (see
VirtualProtectEx and WriteProcessMemory).
/// </summary>
VmOperation = 0x0008,
/// <summary>
/// Required to read memory in a process using <see
cref="ReadProcessMemory"/>.
/// </summary>
VmRead = 0x0010,
/// <summary>
/// Required to write to memory in a process using WriteProcessMemory.
/// </summary>
VmWrite = 0x0020,
/// <summary>
/// Required to wait for the process to terminate using the wait functions.
/// </summary>
Synchronize = 0x00100000
}
#endregion

[Flags]
public enum ThreadAccess : int
{
TERMINATE = (0x0001),
SUSPEND_RESUME = (0x0002),
GET_CONTEXT = (0x0008),
SET_CONTEXT = (0x0010),
SET_INFORMATION = (0x0020),
QUERY_INFORMATION = (0x0040),
SET_THREAD_TOKEN = (0x0080),
IMPERSONATE = (0x0100),
DIRECT_IMPERSONATION = (0x0200)
}

public enum AllocationProtectEnum : uint


{
PAGE_EXECUTE = 0x00000010,
PAGE_EXECUTE_READ = 0x00000020,
PAGE_EXECUTE_READWRITE = 0x00000040,
PAGE_EXECUTE_WRITECOPY = 0x00000080,
PAGE_NOACCESS = 0x00000001,
PAGE_READONLY = 0x00000002,
PAGE_READWRITE = 0x00000004,
PAGE_WRITECOPY = 0x00000008,
PAGE_GUARD = 0x00000100,
PAGE_NOCACHE = 0x00000200,
PAGE_WRITECOMBINE = 0x00000400
}

public enum StateEnum : uint


{
MEM_COMMIT = 0x1000,
MEM_FREE = 0x10000,
MEM_RESERVE = 0x2000
}
public enum TypeEnum : uint
{
MEM_IMAGE = 0x1000000,
MEM_MAPPED = 0x40000,
MEM_PRIVATE = 0x20000
}
}

You might also like