【发布时间】:2016-05-18 06:09:44
【问题描述】:
我有一个关于根据编译架构将多个结构输入方法的问题, 或者关于正确布置 Thread_Basic_Information 结构,这样我就可以将单个结构用于相同的方法,而不管 x64/x86(参见参考:https://msdn.microsoft.com/en-us/library/windows/desktop/ms684283(v=vs.85).aspx)
我已经确认它在 x86 上工作正常,如果我手动切换结构,它也适用于 x64。 然而,我最近尝试改变我的方法,从仅仅复制粘贴大量函数到尝试回收我的代码。
我很难找到有关结构的精确信息,我可以在 C# 中使用这些信息以使其兼容,无论 x86/x64 是什么,或者根据架构将 2 个不同的结构输入到相同的方法中.
也许是 StructLayout 包大小?但是我不熟悉该属性。
我希望有一种方法可以通用这个,例如如果 IntPtr.Size == 8 则使用 64 位结构,否则使用 32 位结构。不管复制粘贴代码的小重命名如何,我希望有一种方法可以使用泛型来做到这一点?
代码:
用于创建线程的方法:
public IRemoteThread Create(IntPtr address, bool isStarted = true)
{
//Create the thread
var thr = ThreadHelper.CreateRemoteThread(Process.Handle, address, IntPtr.Zero, ThreadCreationFlags.Suspended)
//Acquire desired information from the thread
var ret = ThreadHelper.NtQueryInformationThread(thr);
// Do other stuff
return result;
}
支持查询我们想要的线程信息的方法:
public static ThreadBasicInformation NtQueryInformationThread(SafeMemoryHandle threadHandle)
{
// Check if the handle is valid
HandleManipulator.ValidateAsArgument(threadHandle, "threadHandle");
// Create a structure to store thread info
var info = new ThreadBasicInformation();
// Get the thread info
var ret = Nt.NtQueryInformationThread(threadHandle, 0, ref info, MarshalType<ThreadBasicInformation>.Size,
IntPtr.Zero);
// If the function succeeded
if (ret == 0)
return info;
// Else, couldn't get the thread info, throws an exception
throw new ApplicationException($"Couldn't get the information from the thread, error code '{ret}'.");
}
上述方法中使用的32位结构体:
[StructLayout(LayoutKind.Sequential)]
public struct ThreadBasicInformation
{
public uint ExitStatus;
public IntPtr TebBaseAdress;
public int ProcessId;
public int ThreadId;
public uint AffinityMask;
public uint Priority;
public uint BasePriority;
}
同一个结构的x64变体
[StructLayout(LayoutKind.Explicit)]
public struct ThreadBasicInformation64
{
[FieldOffset(0)]
public uint ExitStatus;
[FieldOffset(8)]
public IntPtr TebBaseAdress;
[FieldOffset(16)]
public int ProcessId;
[FieldOffset(24)]
public int ThreadId;
[FieldOffset(32)]
public uint AffinityMask;
[FieldOffset(40)]
public uint Priority;
[FieldOffset(44)]
public uint BasePriority;
}
编辑:
我找到的C声明:
typedef LONG KPRIORITY;
typedef struct _CLIENT_ID {
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID;
typedef CLIENT_ID *PCLIENT_ID;
typedef struct _THREAD_BASIC_INFORMATION
{
NTSTATUS ExitStatus;
PVOID TebBaseAddress;
CLIENT_ID ClientId;
KAFFINITY AffinityMask;
KPRIORITY Priority;
KPRIORITY BasePriority;
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
【问题讨论】:
-
我不认为您需要不同的结构 32 和 64,而是系统。亲和力肯定是 IntPtr 。结构的 C 声明在哪里。
-
提交了一个编辑,其中包含我在几个小时的搜索后发现的唯一有用的 C 声明。