使用C#的SymFromAddr [英] SymFromAddr using C#

查看:114
本文介绍了使用C#的SymFromAddr的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图查看如何使用C#中的SymFromAddr.这就是我所得到的. 问题是,DbgHelp.SymFromAddr(processHandle, (ulong)threadAddress, ref displacement, ref symbolInfo)返回错误87.我在做什么错? *做了一个轻微的mod.现在已填充SizeOfStruct.但没有结果.

I was trying to see how could I use SymFromAddr from C#. Here is what I have got. The problem is, DbgHelp.SymFromAddr(processHandle, (ulong)threadAddress, ref displacement, ref symbolInfo) returns error 87. What am I doing wrong? *Made a slight mod. The SizeOfStruct has now been populated. But no fruit.

static void GetThreadList(int processId, IntPtr processHandle)
{
    Console.WriteLine(string.Format("Process Id: {0:X4}", processId));
    var threadCollection = Process.GetProcessById(processId).Threads.OfType<ProcessThread>();
    foreach (ProcessThread processThread in threadCollection)
    {
        ulong dwAddress = (ulong)ThreadStartAddress(processThread.Id, processHandle);
        Console.WriteLine("  Thread Id: {0:X4}, Start Address: {1:X16}",
                          processThread.Id, dwAddress);
    }
}

static IntPtr ThreadStartAddress(int threadId, IntPtr processHandle)
{
    var threadHandle = DbgHelp.OpenThread(DbgHelp.ThreadAccess.QueryInformation, false, threadId);
    if (threadHandle == IntPtr.Zero)
        throw new Win32Exception();

    IntPtr threadAddress = IntPtr.Zero;
    var buf = Marshal.AllocHGlobal(IntPtr.Size);
        try
        {
            var result = DbgHelp.NtQueryInformationThread(threadHandle,
                             DbgHelp.ThreadInfoClass.ThreadQuerySetWin32StartAddress,
                             buf, IntPtr.Size, IntPtr.Zero);
            if (0 != result)
                throw new Win32Exception(string.Format("NtQueryInformationThread failed; NTSTATUS = {0:X8}", result));
            threadAddress = Marshal.ReadIntPtr(buf);

            unsafe
            {
                ulong displacement = 0;
                uint symsetOptStatus = DbgHelp.SymSetOptions(DbgHelp.SymOpt.UNDNAME | DbgHelp.SymOpt.DEFERRED_LOADS); // Returns 6.
                if (!DbgHelp.SymInitialize(threadHandle, null, true))
                {
                    // SymInitialize failed with error C000000B.
                    Console.WriteLine("SymInitialize returned error : {0:X16}.\n", Marshal.GetLastWin32Error());
                }
                DbgHelp.SYMBOL_INFO symbolInfo = new DbgHelp.SYMBOL_INFO();
                //symbolInfo.SizeOfStruct = (uint)Marshal.SizeOf(symbolInfo);
                //symbolInfo.MaxNameLen = DbgHelp.MAX_SYM_NAME;
                //const int maxNameLen = 512;
                //int bufferSize = Marshal.SizeOf(typeof(DbgHelp.SYMBOL_INFO)) + (DbgHelp.MAX_SYM_NAME * 2);
                //var buffer = Marshal.AllocHGlobal(bufferSize);
                //DbgHelp.SYMBOL_INFO symbolInfo = (DbgHelp.SYMBOL_INFO)buffer;
                symbolInfo.SizeOfStruct = (uint)Marshal.SizeOf(typeof(DbgHelp.SYMBOL_INFO));
                symbolInfo.MaxNameLen = DbgHelp.MAX_SYM_NAME -1;

                if (DbgHelp.SymFromAddr(processHandle, (ulong)threadAddress, ref displacement, ref symbolInfo))
                {
                    // SymFromAddr returned success.
                    return threadAddress;
                }
                else
                {
                    // SymFromAddr failed with error 87.
                    Console.WriteLine("SymFromAddr returned error : {0}.\n", Marshal.GetLastWin32Error());
                    return threadAddress;
                }
            }
        }
        finally
        {
            DbgHelp.CloseHandle(threadHandle);
            Marshal.FreeHGlobal(buf);
        }
}

推荐答案

我看到的唯一方法是编写一个不受管理的c ++包装器来读取符号信息.

The only way I see is writing an unmanaged c++ wrapper for reading symbol info.

这篇关于使用C#的SymFromAddr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆