Вложенный фильтр на объекте передачи данных с использованием OData Web Api

Ключ должен вызвать функцию NtQueryInformationThread . Это не полностью «официальная» функция (возможно, недокументированная в прошлом?), Но в документации нет альтернативы для получения начального адреса потока.

Я завернул его в .NET. -другой вызов, который принимает идентификатор потока и возвращает начальный адрес как IntPtr. Этот код был протестирован в режиме x86 и x64, а в последнем он был протестирован как на 32-битном, так и на 64-битном целевом процессе.

Одна вещь, которую я не тестировал, выполняла это с низким привилегии; Я бы ожидал, что этот код требует, чтобы вызывающий абонент имел SeDebugPrivilege.

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;

class Program
{
    static void Main(string[] args)
    {
        PrintProcessThreads(Process.GetCurrentProcess().Id);
        PrintProcessThreads(4156); // some other random process on my system
        Console.WriteLine("Press Enter to exit.");
        Console.ReadLine();
    }

    static void PrintProcessThreads(int processId)
    {
        Console.WriteLine(string.Format("Process Id: {0:X4}", processId));
        var threads = Process.GetProcessById(processId).Threads.OfType();
        foreach (var pt in threads)
            Console.WriteLine("  Thread Id: {0:X4}, Start Address: {1:X16}",
                              pt.Id, (ulong) GetThreadStartAddress(pt.Id));
    }

    static IntPtr GetThreadStartAddress(int threadId)
    {
        var hThread = OpenThread(ThreadAccess.QueryInformation, false, threadId);
        if (hThread == IntPtr.Zero)
            throw new Win32Exception();
        var buf = Marshal.AllocHGlobal(IntPtr.Size);
        try
        {
            var result = NtQueryInformationThread(hThread,
                             ThreadInfoClass.ThreadQuerySetWin32StartAddress,
                             buf, IntPtr.Size, IntPtr.Zero);
            if (result != 0)
                throw new Win32Exception(string.Format("NtQueryInformationThread failed; NTSTATUS = {0:X8}", result));
            return Marshal.ReadIntPtr(buf);
        }
        finally
        {
            CloseHandle(hThread);
            Marshal.FreeHGlobal(buf);
        }
    }

    [DllImport("ntdll.dll", SetLastError = true)]
    static extern int NtQueryInformationThread(
        IntPtr threadHandle,
        ThreadInfoClass threadInformationClass,
        IntPtr threadInformation,
        int threadInformationLength,
        IntPtr returnLengthPtr);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, int dwThreadId);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool CloseHandle(IntPtr hObject);

    [Flags]
    public enum ThreadAccess : int
    {
        Terminate = 0x0001,
        SuspendResume = 0x0002,
        GetContext = 0x0008,
        SetContext = 0x0010,
        SetInformation = 0x0020,
        QueryInformation = 0x0040,
        SetThreadToken = 0x0080,
        Impersonate = 0x0100,
        DirectImpersonation = 0x0200
    }

    public enum ThreadInfoClass : int
    {
        ThreadQuerySetWin32StartAddress = 9
    }
}

Вывод в моей системе:

Process Id: 2168    (this is a 64-bit process)
  Thread Id: 1C80, Start Address: 0000000001090000
  Thread Id: 210C, Start Address: 000007FEEE8806D4
  Thread Id: 24BC, Start Address: 000007FEEE80A74C
  Thread Id: 12F4, Start Address: 0000000076D2AEC0
Process Id: 103C    (this is a 32-bit process)
  Thread Id: 2510, Start Address: 0000000000FEA253
  Thread Id: 0A0C, Start Address: 0000000076F341F3
  Thread Id: 2438, Start Address: 0000000076F36679
  Thread Id: 2514, Start Address: 0000000000F96CFD
  Thread Id: 2694, Start Address: 00000000025CCCE6

, кроме материала в круглых скобках, поскольку это требует


Что касается ошибки SymFromAddress «модуль не найден», я просто хотел упомянуть, что нужно называть SymInitialize с fInvadeProcess = true ИЛИ загружать модуль вручную, , как описано в MSDN .

Я знаю, что вы говорите, что это не так в вашей ситуации, но я оставлю это в интересах любого, кто находит этот вопрос через те ключевые слова.

16
задан emreturan 20 September 2013 в 08:34
поделиться