Можно ли полностью контролировать дочерний процесс? У меня нет источников дочернего процесса. Мне нужно увидеть и изменить его переменные. Если да, как я могу сделать это через C # / C ++?
Если это манипуляция с памятью, например: чтение и запись байтовых данных в область памяти другого процесса, то да — вы можете сделать это, предполагая, что родительский процесс запущен с достаточными привилегиями.
Например: как администратор.
Для чего-то более сложного, например, для вызова кода дочернего процесса, вам нужно сделать что-то вроде внедрения DLL. В качестве меры безопасности при разработке программы разрабатываются таким образом, чтобы иметь полный контроль над собственным пространством кода, а другие приложения не предназначены для доступа или вызова методов во внешних приложениях.
Сохранить для API, которые являются общедоступными для использования внешними приложениями.
Чтобы читать и записывать области памяти во внешнем приложении, вы можете сделать следующее в C #
Используйте следующее
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace MemoryManagement
{
public class Memory : IDisposable
{
[DllImport("kernel32.dll")]
static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Boolean bInheritHandle, UInt32 dwProcessId);
[DllImport("kernel32.dll")]
static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
byte[] lpBuffer, UIntPtr nSize, uint lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);public IntPtr Handle;
public Process ProcessHeld = null;
public Memory(string sprocess)
{
Process[] Processes = Process.GetProcessesByName(sprocess);
Process nProcess = Processes[0];
Handle = OpenProcess(0x10, false, (uint)nProcess.Id);
if (Handle != IntPtr.Zero)
{
ProcessLoaded = true;
ProcessHeld = nProcess;
}
else
{
ProcessLoaded = false;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// Free other state (managed objects).
}
// Free your own state (unmanaged objects).
// Set large fields to null.
}
// Use C# destructor syntax for finalization code.
~Memory()
{
Dispose(false);
}//Would use this method below - for the actual writing of the Disable Patch Code
public UIntPtr WriteByteArray(IntPtr hProcess, IntPtr BaseAddress, byte[] NewVal)
{
try
{
// Return Value
bool ReturnVal;
UIntPtr BytesWritten;
// Write Memory Byte Array
ReturnVal = WriteProcessMemory(hProcess, BaseAddress, NewVal, (uint)NewVal.Length, out BytesWritten);
return BytesWritten;
}
catch (Exception e)
{
return (UIntPtr)0x0;
}
}public bool ProcessLoaded = false;
public string ReadString(uint pointer)
{
byte[] bytes = new byte[24];
ReadProcessMemory(Handle, (IntPtr)pointer, bytes, (UIntPtr)24, 0);
return Encoding.UTF8.GetString(bytes);
}
public string ReadString(uint pointer, int length)
{
byte[] bytes = new byte[length];
ReadProcessMemory(Handle, (IntPtr)pointer, bytes, (UIntPtr)length, 0);
return Encoding.UTF8.GetString(bytes);
}
public int ReadOffset(uint pointer, uint offset)
{
byte[] bytes = new byte[24];
uint adress = (uint)ReadPointer(pointer) + offset;
ReadProcessMemory(Handle, (IntPtr)adress, bytes, (UIntPtr)sizeof(int), 0);
return BitConverter.ToInt32(bytes, 0);
}
public int ReadPointer(uint pointer)
{
byte[] bytes = new byte[24];
ReadProcessMemory(Handle, (IntPtr)pointer, bytes, (UIntPtr)sizeof(int), 0);
return BitConverter.ToInt32(bytes, 0);
}
}
}
Вы могли бы тогда использовать
Memory mem = new Memory(Process.GetProcessByName("proc"));
string strVal = mem.ReadString(0x04443);
Примечание. Я использую этот класс для чтения памяти из игры Neverwinter Nights. Если вы можете найти указатель на ячейку памяти, вы можете использовать указатели с методом ReadPointer.
Для более сложной задачи внедрения DLL я рекомендую поискать одну из этих библиотек.
WhiteMagic, BlackMagic или GreyMagic
https://forum.tuts4you.com/topic/23764-blackmagic-managed-memory-manipulation/
Внедрение DLL более сложное, так как вам необходимо иметь общее представление о структурах внутри дочернего процесса. Вам нужно будет использовать что-то вроде IDA для проверки вызовов методов программы, переходов и т. Д.
С помощью другого разработчика я смог использовать IDA и Whitemagic для создания полезной нагрузки внедрения DLL, которая позволила мне открыть новый TCPClient на новом порту из дочернего процесса. По сути, я позволил мне добавить свою собственную функцию onCommand в дочерний процесс.
Я специально пытался сделать так, чтобы мой GameServer мог заставить GameClient сделать скриншот, а затем автоматически загрузить его на страницу facebook для игрового сервера.
В конце концов все получилось, но это было несколько сложно.
Других решений пока нет …