C #: поиск массива byte [] в памяти другого процесса - PullRequest
5 голосов
/ 23 апреля 2009

Как можно найти массив байтов [] в памяти другого процесса, а затем получить адрес в том месте, где расположен массив байтов []?

Я хочу записать байтовый массив в память другого процесса (WriteProcessMemory ()). Одним из параметров этого вызова является uint Address.Well Я хочу получить адрес путем поиска байтового массива в процессе.

Например, я ищу {0xEB, 0x20,0x68,0x21,0x27,0x65, ??, 0x21,0x64,0xA1}

Мы предполагаем, что этот массив помещен только в одно место в памяти процесса, в который я хотел бы записать память.

Чтобы получить этот адрес, мне нужно найти этот байтовый массив.

Возможно ли это сделать в C #?

РЕДАКТИРОВАТЬ: Это для собственных приложений, а не .NET. Не нужно понижать мой вопрос, есть компоненты для C ++, которые делают это, я просто хочу сделать это на C #.

Спасибо за понимание!

Ответы [ 5 ]

16 голосов
/ 24 сентября 2011

Возможно ли это сделать в C #? Everithing возможен в C # (или любом другом языке), вам просто нужно найти, как;

Жесткое кодирование здесь:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
        [DllImport("kernel32.dll", SetLastError = true)]
          static extern bool ReadProcessMemory(
          IntPtr hProcess,
          IntPtr lpBaseAddress,
          [Out] byte[] lpBuffer,
          int dwSize,
          out int lpNumberOfBytesRead
        );

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

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool CloseHandle(IntPtr hObject);
    static void Main(string[] args)
    {
        Process[] procs = Process.GetProcessesByName("explorer");
        if (procs.Length <= 0)  //proces not found
            return; //can replace with exit nag(message)+exit;
        IntPtr p = OpenProcess(0x10 | 0x20, true, procs[0].Id); //0x10-read 0x20-write

        uint PTR = 0x0; //begin of memory
        byte[] bit2search1 = {0xEB ,0x20,0x68,0x21,0x27,0x65}; //your bit array until ??
        int k = 1;  //numer of missing array (??)
        byte[] bit2search2 = {0x21,0x64,0xA1};//your bit array after ??
        byte[] buff = new byte[bit2search1.Length+1+bit2search2.Length];    //your array lenght;
        int bytesReaded;
        bool finded = false;

        while (PTR != 0xFF000000)   //end of memory // u can specify to read less if u know he does not fill it all
        {
            ReadProcessMemory(p, (IntPtr)PTR, buff, buff.Length, out bytesReaded);
            if (SpecialByteCompare(buff, bit2search1,bit2search2,k))
            {
                //do your stuff
                finded = true;
                break;
            }
            PTR += 0x1;
        }
        if (!finded)
            Console.WriteLine("sry no byte array found");
    }

    private static bool SpecialByteCompare(byte[] b1, byte[] b2, byte[] b3, int k)  //readed memory, first byte array, second byte array, number of missing byte's
    {
        if (b1.Length != (b2.Length + k + b3.Length))
            return false;
        for (int i = 0; i < b2.Length; i++)
        {
            if (b1[i] != b2[i])
                return false;
        }

        for (int i = 0; i < b3.Length; i++)
        {
            if (b1[b2.Length + k + i] != b3[i])
                return false;
        }
        return true;
    }
}

}

6 голосов
/ 23 апреля 2009

Полагаю, вы могли бы использовать ReadProcessMemory вызов Windows API. Для этого есть даже готовая подпись P / Invoke , так что вам не нужно беспокоиться о ее ручной обработке. Вы просматриваете память процесса, ищите в ней свой шаблон, и все готово.

3 голосов
/ 21 июня 2011

Вы хотите использовать эти API:

    [DllImport("Kernel32.Dll")]
    public static extern uint VirtualQueryEx(IntPtr ProcessHandle, uint Address, ref MEMORY_BASIC_INFORMATION MemInfo, int MemInfoLength);
    [DllImport("Kernel32.Dll")]
    public static extern bool ReadProcessMemory(IntPtr ProcessHandle, uint Address, byte[] Buffer, uint Size, ref uint BytesRead);
    [DllImport("Kernel32.Dll")]
    public static extern bool WriteProcessMemory(IntPtr ProcessHandle, uint Address, byte[] Buffer, uint Size, ref uint BytesRead);

pinvoke.net - отличный ресурс для вызовов Windows API. Я написал инструктор для GTA: Vice City, который использует эти звонки, если вы хотите проверить код на sourceforge. Код не очень красивый, это было давно, и я просто собрал его вместе, но есть вспомогательные классы для перечисления областей памяти для процесса и поиска определенных байтов или строк.

1 голос
/ 22 сентября 2009

Это может помочь вам найти правильный путь:

private static int GetMemoryAddressOfString(byte[] searchedBytes, Process p)
{
    //List<int> addrList = new List<int>();
    int addr = 0;
    int speed = 1024*64;
    for (int j = 0x400000; j < 0x7FFFFFFF; j+= speed)
    {
        ManagedWinapi.ProcessMemoryChunk mem = new ProcessMemoryChunk(p, (IntPtr)j, speed + searchedBytes.Length);

        byte[] bigMem = mem.Read();

        for (int k = 0; k < bigMem.Length - searchedBytes.Length; k++)
        {
            bool found = true;
            for (int l = 0; l < searchedBytes.Length; l++)
            {
                if(bigMem[k+l] != searchedBytes[l])
                {
                    found = false;
                    break;
                }
            }
            if(found)
            {
                addr = k+j;
                break;
            }
        }
        if (addr != 0)
        {
            //addrList.Add(addr);
            //addr = 0;
            break;
        }
    }
    //return addrList;
    return addr;
}
0 голосов
/ 23 апреля 2009

Возможно ли это сделать в C #?

Да. Но очень тяжело. Это трудно из собственного приложения, в котором нет импеданса, не соответствующего неуправляемому представлению процессов и их карт памяти, которые вам нужно будет использовать.

Вопросы:

  • Вам потребуется разрешение, чтобы открыть процесс, чтобы получить дескриптор.
  • Хотя размер виртуальной памяти 32-битного процесса составляет от двух до четырех ГБ (в зависимости от операционной системы хоста и параметра / 3 ГБ), большая часть этого диапазона адресов не будет выделена, и чтение этого файла приведет к ошибке страницы. Вам действительно нужно выяснить, какие страницы выделены и для чего нужно избегать множества недопустимых обращений к страницам.

Предложения:

  • Вам действительно нужно это сделать? Серьезно, это будет сложно.
  • Рассмотрите возможность создания нативного приложения, это позволит избежать работы через нативный / управляемый забор (это может включать нативную библиотеку с приложением управляемого драйвера).
  • Вам действительно нужно это сделать?
  • Рассмотрите возможность выполнения работы внутри целевого процесса. Это потребует некоторой хитрости (задокументированной) для внедрения потока, но тогда должно быть намного быстрее.
  • Начните с чтения в Windows того, как работает память процесса (начните с Windows Internals и (не могу вспомнить его имя в последней редакции) книгу Джеффри Рихтера по разработке приложений для Win32.
  • Тебе действительно нужно это сделать? Должно быть что-то попроще ... Вы могли бы автоматизировать отладчик?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...