zoukankan      html  css  js  c++  java
  • C# Read/Write another Process' Memory

    https://codingvision.net/security/c-read-write-another-process-memory

    Today’s tutorial is about…processes’ memory! In this article I’ll show you how to read/write a process’ memory using C#. This is a good way to learn a part of WinAPI and also understand the basics of memory allocation.

    Before starting, we need a “target” - I choose notepad.exe.

    1.Finding the Memory Address

    As you might probably know, applications store each variable’s value at a specific memory address, we need to know that memory adress in order to edit anything. Since there’s not other way around (or I’m not aware of it?) the only solution is to start searching, using a debugger.

    To get that memory address, I used OllyDbg - don’t worry, all the steps are written below.

    First, open notepad.exe, type some text (like “hello world”) and attach OllyDbg (File->Attach). Press F9 and then ALT+M to open the Memory Map.

    对应的Unicode的字节数组是68 00 65 00 6C 00 6C 00 6F 00 20 00 77 00 6F 00 72 00 6C 00 64 00

    It should look like this:

     

    Press CTRL+B and it will open the Binary Search Window. Now, because the value is stored in memory as Unicode, you have to type the string you’re looking for in the 2nd textbox:

     

    Once you hit Ok another window will pop up - the Memory Dump. Here, look at the very first memory address (on the left) - from that address we’ll start reading. In the image below, the highlighted part contains the message I typed in Notepad.

    Note: don’t use the memory address from the image - it’s not the same memory address every time

     

    We got the memory address, now…don’t close/restart the application. If you restart it, the memory for the text will be reallocated, so the address will most likely be changed.

    复制出地址000000B9A6B78542,然后通过菜单的detach

     

    2.Read Process’ Memory

    In order to read the value from that memory address, we need to import 2 functions into C#: OpenProcess() and ReadProcessMemory() from kernel32.dll.

    [DllImport("kernel32.dll")]
    public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
    
    [DllImport("kernel32.dll")]
    public static extern bool ReadProcessMemory(int hProcess, int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);

    When a process is opened, you must also specify the desired access (this time, you request access for reading the memory), so this constant is needed:

    const int PROCESS_WM_READ = 0x0010;

    Since the whole code is self explanatory, I’ll just add short comments where they’re needed:

    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Text;
    
    public class MemoryRead
    {
        const int PROCESS_WM_READ = 0x0010;
    
        [DllImport("kernel32.dll")]
        public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
    
        [DllImport("kernel32.dll")]
        public static extern bool ReadProcessMemory(int hProcess, int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);
    
        public static void Main()
        {
    
            Process process = Process.GetProcessesByName("notepad")[0]; 
            IntPtr processHandle = OpenProcess(PROCESS_WM_READ, false, process.Id); 
    
            int bytesRead = 0;
            byte[] buffer = new byte[24]; //'Hello World!' takes 12*2 bytes because of Unicode 
    
            // 0x0046A3B8 is the address where I found the string, replace it with what you found
            ReadProcessMemory((int)processHandle, 0x0046A3B8, buffer, buffer.Length, ref bytesRead);
    
            Console.WriteLine(Encoding.Unicode.GetString(buffer) + " (" + bytesRead.ToString() + "bytes)");
            Console.ReadLine();
        }
    }

    3.Write Process’ Memory

    Writing to a memory address is a little bit different: you’ll need OpenProcess() and WriteProcessMemory().

    [DllImport("kernel32.dll")]
    public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool WriteProcessMemory(int hProcess, int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesWritten);

    However, special permissions are required: while opening the process request the following privileges: PROCESS_VM_WRITE | PROCESS_VM_OPERATION.

    const int PROCESS_VM_WRITE = 0x0020;
    const int PROCESS_VM_OPERATION = 0x0008;

    Note: notepad’s textbox is storing the number of bytes it has to read from the memory - that value is updated only when the text is changed by user. If you write to the memory address a longer string, it will be truncated.

    The complete code is available below:

    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Text;
    
    public class MemoryRead
    {
        const int PROCESS_ALL_ACCESS = 0x1F0FFF;
    
        [DllImport("kernel32.dll")]
        public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
    
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool WriteProcessMemory(int hProcess, int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesWritten);
    
        public static void Main()
        {
    
            Process process = Process.GetProcessesByName("notepad")[0];
            IntPtr processHandle = OpenProcess(PROCESS_ALL_ACCESS, false, process.Id); 
    
            int bytesWritten = 0;
            byte[] buffer = Encoding.Unicode.GetBytes("It works!"); // '' marks the end of string
    
            // replace 0x0046A3B8 with your address
            WriteProcessMemory((int)processHandle, 0x0046A3B8, buffer, buffer.Length, ref bytesWritten);
            Console.ReadLine();
        }
    }
  • 相关阅读:
    词汇小助手V1.0——一款跨平台词频统计和外语学习工具
    穿越狙击V1.0
    词汇小助手V1.4——加入单词测试功能
    词汇小助手V1.2——可以显示英语单词的国际音标
    词汇小助手官方网站发布了
    强大的云存储与应用管理工具DzzOffice1.0 Beta(大桌子办公)发布下载 大桌子
    <!DOCTYPE>前加有<! xxx >注释在IE中引发的bug
    去笔试腾讯的前端实习生,题目太尼玛坑爹了
    IE中的布局BUG和一些可以避开的BUG
    removeClass,addClass的原生JS代码
  • 原文地址:https://www.cnblogs.com/chucklu/p/11376514.html
Copyright © 2011-2022 走看看