首页 > 解决方案 > 如何在内存中找到另一个进程的某个变量值(在 /proc//mem )(在 C# 中,在 Linux 中)?

问题描述

程序 S 应该对程序 V 的某个变量进行一些日志和统计。两者都需要用 C# 编写并在 Linux 上运行。变量名及其父类名和函数名对于程序 V 是已知的。但不能更改它来做一些日志本身。程序 S 需要从外部访问 V 的内存区域。如何在那里找到某个变量?

由于回答了类似的问题,我想我得到了一些从外部读取内存的代码:这里有一些示例代码。对于这个测试用例,S 和 V 组合在一个程序中。这意味着程序应该通过内存访问来读取它自己的变量之一的值。

using System;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;

namespace MemReadTest42
{
    class MainClass
    {
        public class TestClass42
        {
            public int randomVar42 { get; set; }
            public TestClass42()
            {
                //for example set it to a easy to search number
                randomVar42 = 12342000; //<--- Question: How to get this number from outside
            }
            public void incr()
            {
                //example function which  has impact at the variable
                randomVar42 = randomVar42 + 1;
            }
        }

        public static void Main(string[] args)
        {
            // example variable
            Int32 myvari = 8777778; //<--- Question: How to get this number from outside

            TestClass42 exampObj = new TestClass42();

            Process process = Process.GetCurrentProcess(); //(its this program itself)

            System.IO.StreamReader file = new System.IO.StreamReader(@"/proc/" + process.Id + "/maps");
            string line;
            while ((line = file.ReadLine()) != null)
            {             

                string pattern = @"([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])";
                Match m = Regex.Match(line, pattern);
                if (m.Success)
                {
                    string[] startend = (m.Value.Split(' '))[0].Split('-');
                    long start = Convert.ToInt64(startend[0], 16);
                    long end = Convert.ToInt64(startend[1], 16);
                    long len = end - start;

                    if (len > 0 && end > 0 && start > 0)
                    {
                        Console.WriteLine(line);
                        using (FileStream fs = new FileStream(@"/proc/"+ process.Id+"/mem", FileMode.Open, FileAccess.Read))
                        {
                            fs.Seek(start, SeekOrigin.Begin);
                            byte[] b = new byte[end - start];
                            try {
                                fs.Read(b, 0, (int)(end - start));
                                string s = System.Text.Encoding.UTF8.GetString(b);
                                exampObj.incr();//some example var update
                                Console.WriteLine(s.Length + " " + s);
                            }
                            catch {
                                Console.WriteLine("FAILED");
                            }
                        }
                    }
                }

            }
            file.Close();   
            //use the example variables at the end
            Console.WriteLine(" end " + myvari + " " + exampObj.randomVar42);
        }
    }
}

1.) 但是我在哪里可以找到这些变量 'randomVar42' 或 'myvari' ?我将整个内存输出存储在一个文件中,但它既不包含变量名也不包含它们的值。

2.) 缩小范围,应将它们存储在哪个地图部分?在[堆],[堆栈]或具有程序路径的那个?[vvar] 在我的测试期间无法读取

更新:Patrick Beynio 在表扬中回答了问题 2。但是,在这两个中我都找不到变量名或值。

标签: c#linuxmemory

解决方案


推荐阅读