Пишите для обработки памяти в C#
Я хочу записать смещение в некоторый адрес памяти процесса, но я не могу выделить память или изменить тип адреса памяти, чтобы он был "доступным для записи". поэтому я не могу записать какое-либо смещение или значение в мою память процесса. Я не уверен, но я думаю, что моя память процесса просто читаема! Пожалуйста, помогите мне решить эту проблему.
Вот что я попробовал:
#region dll import
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle,
uint dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
byte[] lpBuffer, uint nSize, out int lpNumberOfBytesWritten);
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint dwProcessId);
[DllImport("kernel32.dll")]
public static extern bool CloseHandle(IntPtr handle);
[DllImport("kernel32.dll")]
public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress,
uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")]
public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress,
uint dwSize, uint dwFreeType);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress,
int dwSize, uint flNewProtect, out uint lpflOldProtect);
#endregion
public const int
PAGE_READWRITE = 0x40,
PROCESS_VM_OPERATION = 0x0008,
PROCESS_VM_READ = 0x0010,
PROCESS_VM_WRITE = 0x0020;
internal static bool write(IntPtr whWnd)
{
uint pid;
GetWindowThreadProcessId(whWnd, out pid);
if (pid != 0)
{
IntPtr hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE |
PROCESS_VM_READ, false, pid);
const int
MEM_COMMIT = 0x1000,
MEM_RELEASE = 0x800,
MEM_RESERVE = 0x2000;
byte[] data = System.Text.Encoding.UTF8.GetBytes
("write string to hex offset of memLoc");
uint lpflOldProtect;
int bytesWritten;
IntPtr memLoc = (IntPtr)0x001D7AB4;
IntPtr lpRemoteBuffer = IntPtr.Zero;
VirtualProtectEx(hProcess, memLoc, 160, PAGE_READWRITE,
out lpflOldProtect);
IntPtr cave = VirtualAllocEx(hProcess, IntPtr.Zero, 16, MEM_COMMIT |
MEM_RESERVE, PAGE_READWRITE);
if (lpRemoteBuffer == IntPtr.Zero)
{
MessageBox.Show("can't VirtualAlloc");
return false;
}
else
{
MessageBox.Show("VirtualAlloc ok");
VirtualAllocEx(hProcess, memLoc, 4096, MEM_COMMIT, PAGE_READWRITE);
VirtualFreeEx(hProcess, memLoc, 4096, MEM_RELEASE);
WriteProcessMemory(hProcess, memLoc, data, 16, out bytesWritten);
CloseHandle(hProcess);
return true;
}
}
else
{
MessageBox.Show("can't find the windows");
return false;
}
}
private void button1_Click(object sender, EventArgs e)
{
IntPtr whWnd = FindWindow(null, "the windows name");
write( whWnd);
}
}
}
1 ответ
Прочитайте ваш код еще раз. Вы создаете переменную со значением и проверяете несколько строк после, если значение остается прежним. Конечно, это то же самое, потому что ваш код не меняет его.
IntPtr lpRemoteBuffer = IntPtr.Zero;
// [...]
if (lpRemoteBuffer == IntPtr.Zero)
{
MessageBox.Show("can't VirtualAlloc");
return false;
}
Я уверен, что вы хотели проверить вар cave
в твоем состоянии.:)
Кроме того, чтобы проверить, правильно ли ваш вопрос изменяет память процесса, используйте программу типа Cheat Engine. Это позволяет вам просматривать защиту области памяти и быть уверенным, что ваша область памяти существует.
Вы также можете использовать библиотеку инъекций, такую как MemorySharp (я автор), чтобы выполнить то, что вы хотите.
// Set the address to edit
var address = new IntPtr(0x001D7AB4);
// Open the process with MemorySharp
using (var m = new MemorySharp(Process.GetCurrentProcess()))
{
// Edit the address
m[address].WriteString("write string to hex offset of memLoc");
}