using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices; // DllImport
using System.Diagnostics; // Process
namespace RwMem
{
// https://www.pinvoke.net/default.aspx
public class AdjPriv // 提升權限
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct TokPriv1Luid
{
public int Count;
public long Luid;
public int Attr;
}
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
[DllImport("kernel32.dll", ExactSpelling = true)]
static extern IntPtr GetCurrentProcess();
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
const int SE_PRIVILEGE_ENABLED = 0x00000002;
const int TOKEN_QUERY = 0x00000008;
const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
const string SE_TIME_ZONE_NAMETEXT = "SeTimeZonePrivilege"; //http://msdn.microsoft.com/en-us/library/bb530716(VS.85).aspx
public bool SetPriv()
{
try
{
bool retVal;
TokPriv1Luid tp;
IntPtr hproc = GetCurrentProcess();
IntPtr htok = IntPtr.Zero;
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
tp.Attr = SE_PRIVILEGE_ENABLED;
retVal = LookupPrivilegeValue(null, SE_TIME_ZONE_NAMETEXT, ref tp.Luid);
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
return retVal;
}
catch (Exception ex)
{
throw;
return false;
}
}
}
class Program
{
static List<IntPtr> liAddr = new List<IntPtr>(); // 記錄查找到的記憶體位址
[StructLayout(LayoutKind.Sequential)]
internal struct SYSTEM_INFO
{
internal ushort wProcessorArchitecture;
internal ushort wReserved;
internal uint dwPageSize;
internal IntPtr lpMinimumApplicationAddress;
internal IntPtr lpMaximumApplicationAddress;
internal IntPtr dwActiveProcessorMask;
internal uint dwNumberOfProcessors;
internal uint dwProcessorType;
internal uint dwAllocationGranularity;
internal ushort wProcessorLevel;
internal ushort wProcessorRevision;
}
[DllImport("kernel32.dll", SetLastError = true)]
static extern void GetSystemInfo(ref SYSTEM_INFO Info); // 取得系統資訊
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName); // 尋找視窗標題
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); // 取得程序ID
private enum ProcessAccessTypes
{
PROCESS_TERMINATE = 0x00000001,
PROCESS_CREATE_THREAD = 0x00000002,
PROCESS_SET_SESSIONID = 0x00000004,
PROCESS_VM_OPERATION = 0x00000008,
PROCESS_VM_READ = 0x00000010,
PROCESS_VM_WRITE = 0x00000020,
PROCESS_DUP_HANDLE = 0x00000040,
PROCESS_CREATE_PROCESS = 0x00000080,
PROCESS_SET_QUOTA = 0x00000100,
PROCESS_SET_INFORMATION = 0x00000200,
PROCESS_QUERY_INFORMATION = 0x00000400,
STANDARD_RIGHTS_REQUIRED = 0x000F0000,
SYNCHRONIZE = 0x00100000,
PROCESS_ALL_ACCESS = PROCESS_TERMINATE | PROCESS_CREATE_THREAD | PROCESS_SET_SESSIONID | PROCESS_VM_OPERATION |
PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE | PROCESS_CREATE_PROCESS | PROCESS_SET_QUOTA |
PROCESS_SET_INFORMATION | PROCESS_QUERY_INFORMATION | STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE
}
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId);
[DllImport("kernel32.dll")]
static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer,
int dwSize, out IntPtr lpNumberOfBytesRead);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer,
Int32 nSize, out IntPtr lpNumberOfBytesWritten);
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
}
[StructLayout(LayoutKind.Sequential)]
public struct MEMORY_BASIC_INFORMATION
{
public IntPtr BaseAddress;
public IntPtr AllocationBase;
public uint AllocationProtect;
public IntPtr RegionSize;
public uint State;
public uint Protect;
public uint Type;
}
[DllImport("kernel32.dll")]
static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, // 查詢記憶體資訊
out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength);
static void ScanMemStep0(IntPtr hProcess, int nSize, int nValue) // 從頭開始尋找記憶體並記錄匹配位址
{
SYSTEM_INFO stSysInfo = new SYSTEM_INFO();
GetSystemInfo(ref stSysInfo);
MEMORY_BASIC_INFORMATION stMemBasicInfo = new MEMORY_BASIC_INFORMATION();
UInt64 BaseAddr = (UInt64)stSysInfo.lpMinimumApplicationAddress;
UInt64 MaxAddr = (UInt64)stSysInfo.lpMaximumApplicationAddress;
liAddr.Clear();
while (BaseAddr < MaxAddr)
{
VirtualQueryEx(hProcess, (IntPtr)BaseAddr, out stMemBasicInfo, (uint)Marshal.SizeOf(stMemBasicInfo));
if (stMemBasicInfo.Protect == (uint)AllocationProtectEnum.PAGE_READWRITE && // 可讀可寫
stMemBasicInfo.State == (uint)StateEnum.MEM_COMMIT)
{
IntPtr bytesRead = IntPtr.Zero;
byte[] buffer = new byte[(UInt64)stMemBasicInfo.RegionSize];
ReadProcessMemory(hProcess, stMemBasicInfo.BaseAddress, buffer, (int)stMemBasicInfo.RegionSize, out bytesRead);
if(nSize == 4)
{
for (int i = 0; i < (int)stMemBasicInfo.RegionSize; i+=4)
if (BitConverter.ToInt32(buffer, i) == nValue)
liAddr.Add(stMemBasicInfo.BaseAddress + i);
}
}
BaseAddr += (UInt64)stMemBasicInfo.RegionSize;
}
}
static void ScanMemStep1(IntPtr hProcess, int nSize, int nValue) // 接續尋找變更資料後的記憶體
{
IntPtr bytesRead = IntPtr.Zero;
byte[] buffer = new byte[nSize];
for (int i = liAddr.Count-1; i >= 0; i--)
{
ReadProcessMemory(hProcess, liAddr[i], buffer, nSize, out bytesRead);
if (nSize == 4)
{
if (BitConverter.ToInt32(buffer, 0) != nValue)
liAddr.RemoveAt(i);
}
}
}
static void WriteMem(IntPtr hProcess, int nSize, int nValue) // 修改記憶體內容
{
IntPtr bytesRead = IntPtr.Zero;
byte[] buffer = BitConverter.GetBytes(nValue);
if (1 != liAddr.Count)
return;
WriteProcessMemory(hProcess, liAddr[0], buffer, nSize, out bytesRead);
}
static void Main(string[] args)
{
AdjPriv ajdPriv = new AdjPriv();
ajdPriv.SetPriv();
IntPtr hWnd = FindWindowByCaption(IntPtr.Zero, "維京碼農");
if(hWnd != IntPtr.Zero)
{
uint dwThreadID = 0;
GetWindowThreadProcessId(hWnd, out dwThreadID);
IntPtr hProcess = OpenProcess((uint)(ProcessAccessTypes.PROCESS_QUERY_INFORMATION |
ProcessAccessTypes.PROCESS_VM_READ |
ProcessAccessTypes.PROCESS_VM_WRITE),
false,
(int)dwThreadID);
while(true)
{
Console.Write("Input Scan Step、Size And Value: ");
string str = Console.ReadLine();
string[] arrStr = str.Split(' ');
if(arrStr[0] == "0")
{
ScanMemStep0(hProcess, Convert.ToInt32(arrStr[1]), Convert.ToInt32(arrStr[2]));
Console.WriteLine("Count Of liAddr = {0}\n", liAddr.Count);
}
else if(arrStr[0] == "1")
{
ScanMemStep1(hProcess, Convert.ToInt32(arrStr[1]), Convert.ToInt32(arrStr[2]));
Console.WriteLine("Count Of liAddr = {0}\n", liAddr.Count);
if(liAddr.Count == 1)
Console.WriteLine("Addr Of Value = {0:X}\n", (int)liAddr[0]);
}
else if(arrStr[0] == "w")
{
WriteMem(hProcess, Convert.ToInt32(arrStr[1]), Convert.ToInt32(arrStr[2]));
}
else if (arrStr[0] == "q")
{
Console.WriteLine("Bye Bye\n", (int)liAddr[0]);
}
}
}
else
{
Console.WriteLine("App Not Found");
}
Console.WriteLine("Press Any Key...");
Console.ReadKey(true); //Pause
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices; // DllImport
using System.Diagnostics; // Process
namespace RwMem
{
// https://www.pinvoke.net/default.aspx
public class AdjPriv // 提升權限
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct TokPriv1Luid
{
public int Count;
public long Luid;
public int Attr;
}
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
[DllImport("kernel32.dll", ExactSpelling = true)]
static extern IntPtr GetCurrentProcess();
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
const int SE_PRIVILEGE_ENABLED = 0x00000002;
const int TOKEN_QUERY = 0x00000008;
const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
const string SE_TIME_ZONE_NAMETEXT = "SeTimeZonePrivilege"; //http://msdn.microsoft.com/en-us/library/bb530716(VS.85).aspx
public bool SetPriv()
{
try
{
bool retVal;
TokPriv1Luid tp;
IntPtr hproc = GetCurrentProcess();
IntPtr htok = IntPtr.Zero;
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
tp.Attr = SE_PRIVILEGE_ENABLED;
retVal = LookupPrivilegeValue(null, SE_TIME_ZONE_NAMETEXT, ref tp.Luid);
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
return retVal;
}
catch (Exception ex)
{
throw;
return false;
}
}
}
class Program
{
static List<IntPtr> liAddr = new List<IntPtr>(); // 記錄查找到的記憶體位址
[StructLayout(LayoutKind.Sequential)]
internal struct SYSTEM_INFO
{
internal ushort wProcessorArchitecture;
internal ushort wReserved;
internal uint dwPageSize;
internal IntPtr lpMinimumApplicationAddress;
internal IntPtr lpMaximumApplicationAddress;
internal IntPtr dwActiveProcessorMask;
internal uint dwNumberOfProcessors;
internal uint dwProcessorType;
internal uint dwAllocationGranularity;
internal ushort wProcessorLevel;
internal ushort wProcessorRevision;
}
[DllImport("kernel32.dll", SetLastError = true)]
static extern void GetSystemInfo(ref SYSTEM_INFO Info); // 取得系統資訊
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName); // 尋找視窗標題
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); // 取得程序ID
private enum ProcessAccessTypes
{
PROCESS_TERMINATE = 0x00000001,
PROCESS_CREATE_THREAD = 0x00000002,
PROCESS_SET_SESSIONID = 0x00000004,
PROCESS_VM_OPERATION = 0x00000008,
PROCESS_VM_READ = 0x00000010,
PROCESS_VM_WRITE = 0x00000020,
PROCESS_DUP_HANDLE = 0x00000040,
PROCESS_CREATE_PROCESS = 0x00000080,
PROCESS_SET_QUOTA = 0x00000100,
PROCESS_SET_INFORMATION = 0x00000200,
PROCESS_QUERY_INFORMATION = 0x00000400,
STANDARD_RIGHTS_REQUIRED = 0x000F0000,
SYNCHRONIZE = 0x00100000,
PROCESS_ALL_ACCESS = PROCESS_TERMINATE | PROCESS_CREATE_THREAD | PROCESS_SET_SESSIONID | PROCESS_VM_OPERATION |
PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE | PROCESS_CREATE_PROCESS | PROCESS_SET_QUOTA |
PROCESS_SET_INFORMATION | PROCESS_QUERY_INFORMATION | STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE
}
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId);
[DllImport("kernel32.dll")]
static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer,
int dwSize, out IntPtr lpNumberOfBytesRead);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer,
Int32 nSize, out IntPtr lpNumberOfBytesWritten);
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
}
[StructLayout(LayoutKind.Sequential)]
public struct MEMORY_BASIC_INFORMATION
{
public IntPtr BaseAddress;
public IntPtr AllocationBase;
public uint AllocationProtect;
public IntPtr RegionSize;
public uint State;
public uint Protect;
public uint Type;
}
[DllImport("kernel32.dll")]
static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, // 查詢記憶體資訊
out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength);
static void ScanMemStep0(IntPtr hProcess, int nSize, int nValue) // 從頭開始尋找記憶體並記錄匹配位址
{
SYSTEM_INFO stSysInfo = new SYSTEM_INFO();
GetSystemInfo(ref stSysInfo);
MEMORY_BASIC_INFORMATION stMemBasicInfo = new MEMORY_BASIC_INFORMATION();
UInt64 BaseAddr = (UInt64)stSysInfo.lpMinimumApplicationAddress;
UInt64 MaxAddr = (UInt64)stSysInfo.lpMaximumApplicationAddress;
liAddr.Clear();
while (BaseAddr < MaxAddr)
{
VirtualQueryEx(hProcess, (IntPtr)BaseAddr, out stMemBasicInfo, (uint)Marshal.SizeOf(stMemBasicInfo));
if (stMemBasicInfo.Protect == (uint)AllocationProtectEnum.PAGE_READWRITE && // 可讀可寫
stMemBasicInfo.State == (uint)StateEnum.MEM_COMMIT)
{
IntPtr bytesRead = IntPtr.Zero;
byte[] buffer = new byte[(UInt64)stMemBasicInfo.RegionSize];
ReadProcessMemory(hProcess, stMemBasicInfo.BaseAddress, buffer, (int)stMemBasicInfo.RegionSize, out bytesRead);
if(nSize == 4)
{
for (int i = 0; i < (int)stMemBasicInfo.RegionSize; i+=4)
if (BitConverter.ToInt32(buffer, i) == nValue)
liAddr.Add(stMemBasicInfo.BaseAddress + i);
}
}
BaseAddr += (UInt64)stMemBasicInfo.RegionSize;
}
}
static void ScanMemStep1(IntPtr hProcess, int nSize, int nValue) // 接續尋找變更資料後的記憶體
{
IntPtr bytesRead = IntPtr.Zero;
byte[] buffer = new byte[nSize];
for (int i = liAddr.Count-1; i >= 0; i--)
{
ReadProcessMemory(hProcess, liAddr[i], buffer, nSize, out bytesRead);
if (nSize == 4)
{
if (BitConverter.ToInt32(buffer, 0) != nValue)
liAddr.RemoveAt(i);
}
}
}
static void WriteMem(IntPtr hProcess, int nSize, int nValue) // 修改記憶體內容
{
IntPtr bytesRead = IntPtr.Zero;
byte[] buffer = BitConverter.GetBytes(nValue);
if (1 != liAddr.Count)
return;
WriteProcessMemory(hProcess, liAddr[0], buffer, nSize, out bytesRead);
}
static void Main(string[] args)
{
AdjPriv ajdPriv = new AdjPriv();
ajdPriv.SetPriv();
IntPtr hWnd = FindWindowByCaption(IntPtr.Zero, "維京碼農");
if(hWnd != IntPtr.Zero)
{
uint dwThreadID = 0;
GetWindowThreadProcessId(hWnd, out dwThreadID);
IntPtr hProcess = OpenProcess((uint)(ProcessAccessTypes.PROCESS_QUERY_INFORMATION |
ProcessAccessTypes.PROCESS_VM_READ |
ProcessAccessTypes.PROCESS_VM_WRITE),
false,
(int)dwThreadID);
while(true)
{
Console.Write("Input Scan Step、Size And Value: ");
string str = Console.ReadLine();
string[] arrStr = str.Split(' ');
if(arrStr[0] == "0")
{
ScanMemStep0(hProcess, Convert.ToInt32(arrStr[1]), Convert.ToInt32(arrStr[2]));
Console.WriteLine("Count Of liAddr = {0}\n", liAddr.Count);
}
else if(arrStr[0] == "1")
{
ScanMemStep1(hProcess, Convert.ToInt32(arrStr[1]), Convert.ToInt32(arrStr[2]));
Console.WriteLine("Count Of liAddr = {0}\n", liAddr.Count);
if(liAddr.Count == 1)
Console.WriteLine("Addr Of Value = {0:X}\n", (int)liAddr[0]);
}
else if(arrStr[0] == "w")
{
WriteMem(hProcess, Convert.ToInt32(arrStr[1]), Convert.ToInt32(arrStr[2]));
}
else if (arrStr[0] == "q")
{
Console.WriteLine("Bye Bye\n", (int)liAddr[0]);
}
}
}
else
{
Console.WriteLine("App Not Found");
}
Console.WriteLine("Press Any Key...");
Console.ReadKey(true); //Pause
}
}
}
0 意見:
張貼留言