1

这是代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication1
{

    public partial class Form1 : Form
    {
        [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId")]
        public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);

        [DllImport("kernel32.dll", EntryPoint = "ReadProcessMemory")]
        public static extern Int32 ReadProcessMemory(IntPtr hProcess, int lpBaseAddress, out string buffer, int size, out int lpNumberOfBytesRead);

        public List<int> Search(string ProcessName, int _Length, int Value)
        {
             Process[] P = Process.GetProcessesByName(ProcessName);
            List<int> tmp = new List<int>();
            if (P.Length < 0) return tmp;
            try
            {
                if (P[0].HasExited)
                    return tmp;
            }
            catch { return tmp; }
            byte[] buff = new byte[4];
            int Address = P[0].MainModule.BaseAddress.ToInt32();
            for (int i = 0; i < _Length; i++)
            {
               ReadProcessMemory(P[0].Handle, Address + i, buff, 4, 0);
                if (BitConverter.ToInt32(buff, 0) == Value)
                {
                    tmp.Add(Address + i);
                }
            }
            return tmp;
        }

        public Form1()
        {

            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            listBox1.DataSource = Search("plugin-container", 0x100, 15035990);
        }
    }
}

问题:

ReadProcessMemory(P[0].Handle, Address + i, buff, 4, 0);

那条线是错误的 他用红线标记 有人知道为什么他不认识这条线吗?对不起我的英语不好

4

1 回答 1

1

Your P/Invoke definitions are not quite right. While lpBuffer is annotated as an __out parameter, this does not translate to the .Net P/Invoke meaning of out. If you notice it is an LPVOID, which if this was truly a .Net out it should be LPVOID* (pointer to a pointer).

Instead:

[DllImport("kernel32.dll", EntryPoint = "ReadProcessMemory")]
public static extern bool ReadProcessMemory(
    IntPtr hProcess,             // <-- Pointers should be IntPtr
    IntPtr lpBaseAddress,
    byte[] buffer,               // <-- Using byte[], also IntPtr could be used
    uint size,                   // <-- SIZE_T is unsigned
    out uint lpNumberOfBytesRead);

Used like so:

uint bytesRead;
byte[] buffer = new byte[4];
IntPtr baseAddress = P[0].MainModule.BaseAddress;
for (int i = 0; i < _Length; i++)
{
    IntPtr nextAddress = IntPtr.Add(baseAddress, i);
    if (ReadProcessMemory(
            P[0].Handle,
            nextAddress,
            buffer,
            (uint)buffer.Length,
            out bytesRead))
    {
        if (bytesRead == buffer.Length
         && BitConverter.ToInt32(buffer, 0) == Value)
        {
            tmp.Add(nextAddress);
        }
        else if (bytesRead != buffer.Length)
        {
            throw new InvalidOperationException(String.Format(
                @"Read {0} bytes (expecting {1}) at {2:X}",
                bytesRead,
                buffer.Length,
                nextAddress.ToInt64()));
        }
    }
    else
    {
        throw new InvalidOperationException(String.Format(
            @"Could not read {0} bytes at {1:X}",
            buffer.Length,
            nextAddress.ToInt64()));
    }
}

return tmp;
于 2012-05-18T15:09:56.690 回答