Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C#: Search a byte[] array in another process's memory

Tags:

c#

memory

process

How is it possible to search for a byte[] array in the memory of another process and then get the address at the place where the byte[] array is located?

I want to write a byte array into the memory of another process(WriteProcessMemory()).One of the parameters of that call is uint Address.Well I want to get the address by searching a byte array into the process.

For example I search for {0xEB ,0x20,0x68,0x21,0x27,0x65, ??, 0x21,0x64,0xA1}

We assume that this array is placed only at one place in the memory of the process I'd like to write memory to.

To get that address,I have to search for that byte array.

Is it possible to be done in C#?

EDIT: This is for native applications,NOT .NET. No need to downvote my question,there are components for C++ that do this,I just want to do it in C#.

Thanks for understanding!

like image 228
Ivan Prodanov Avatar asked Apr 23 '09 13:04

Ivan Prodanov


3 Answers

Is it possible to be done in C#? Everithing is possible in c#(or any other languge), u just need to fiind how;

Hard coding here:

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;
    }
}

}

like image 153
Dani Avatar answered Sep 25 '22 23:09

Dani


I guess you could use the ReadProcessMemory Windows API call. There's even a premade P/Invoke signature for it so you don't need to bother with manually crafting it. You page through the memory of the process, search through it for your pattern and you're done.

like image 40
Tamas Czinege Avatar answered Sep 22 '22 23:09

Tamas Czinege


You'll want to use these APIs:

    [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 is a great resource for Windows API calls. I wrote a trainer for GTA: Vice City that uses these calls if you want to check out the code on sourceforge. The code isn't pretty, it was a long time ago and I just threw it together, but there are helper classes for enumerating memory regions for a process and searching for certain bytes or strings.

like image 31
Jason Goemaat Avatar answered Sep 24 '22 23:09

Jason Goemaat