2

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

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);
        }
}
4

2 回答 2

0

尝试:

        const int maxNameLen = 512;
        int bufferSize = sizeof(SYMBOL_INFO) + maxNameLen*2;
        buffer = (byte*)Marshal.AllocHGlobal(bufferSize);
        symbolInfo = (SYMBOL_INFO*)buffer;
        symbolInfo->SizeOfStruct = (uint)sizeof(SYMBOL_INFO);
        symbolInfo->MaxNameLen   = maxNameLen - 1;
于 2012-08-26T19:03:20.397 回答
0

我看到的唯一方法是编写一个非托管 C++ 包装器来读取符号信息。

于 2012-09-02T07:33:46.377 回答