如何在应用程序的内存中查找所有字符串

时间:2017-12-07 22:22:27

标签: c#

我试图找到java应用程序内存中的所有字符串。 (就像黑客一样)。但是,当我使用进程黑客时,我会得到我的程序无法检测到的字符串。

另外,我非常确定我一次循环遍历这一个字符,有没有办法解决这个问题,同时防止ReadProccessMemory返回字符串片段? (即如果记忆就像oiuwlkme MySting lkjalkwj我想确保 MyString 没有分成两个不同的字符串(如oiuwlkme MySti ng lkjalkwj)

到目前为止,这是我的代码:

        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,
      Int64 lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);

    static void Main(string[] args)
    {
        //doMemorySharp();
        //Console.ReadLine();
        //return;

        Process process = Process.GetProcessesByName("javaw")[0];
        IntPtr processHandle = OpenProcess(PROCESS_WM_READ, false, process.Id);
        IntPtr startOffset = process.MainModule.BaseAddress;
        IntPtr endOffset = IntPtr.Add(startOffset, process.MainModule.ModuleMemorySize);
        int bytesRead = 0;
        byte[] buffer = new byte[48];

        for (int i = 0 ; i < process.MainModule.ModuleMemorySize; i++)
        {
            bytesRead = 0;
            buffer = new byte[48];
            if (!ReadProcessMemory((int)processHandle, IntPtr.Add(startOffset, i).ToInt64(), buffer, buffer.Length, ref bytesRead))
            {
                Console.WriteLine("false");
            }

            string s = Encoding.Default.GetString(buffer);
            if (s.Contains("MyString"))
            {
                Console.WriteLine("Yay!");
            }
            Console.WriteLine(s);
            Console.WriteLine(fromByteArray(buffer));
            Console.ReadLine();
        }
        Console.WriteLine("Finished");
        Console.WriteLine("Memory:" + process.MainModule.ModuleMemorySize.ToString());
        Console.ReadLine();
    }

1 个答案:

答案 0 :(得分:0)

实际上,你应该做的第一件事是增加缓冲区大小,使你的扫描仪更健康,更快。这不会阻止问题的发生,但它仍然有用:

byte[] buffer = new byte[4096];

如果进程不是太大(从内存消耗的角度来看),你可以通过单个ReadProcessMemory调用转储它们的整个内存,然后在转储上执行快速二进制扫描。

另一种方法是继续按照你正在做的块扫描他们的记忆,并且一旦发现一段与你的字符串开头部分匹配的文本:

  • 将当前偏移量恢复到该段文本的开头
  • 读取OffsetBeginOffsetBegin + TargetStringLength
  • 之间的小内存区域
  • 检查缓冲区的内容是否与目标字符串匹配