C#检测特定进程的CPU架构

发布于 2024-10-10 16:47:43 字数 264 浏览 0 评论 0原文

我用 C# 编写代码。 我的代码将在 Any CPU 模式下运行并提升。

我的目标是使用 Process.GetProcesses() 枚举计算机中的所有进程,并为每个进程检测其 CPU 架构:x86x64IA64

我正在 C# 中实现代码注入,需要检测目标进程的体系结构来决定注入哪些操作码。

怎么做呢?

谢谢。

I writing code in C#.
My code gonna run in Any CPU mode and elevated.

My goal is enumerating all processes in the machine with Process.GetProcesses(), and for each process detect its CPU architecture: x86, x64 or IA64.

I'm implementing code injection in C# and need to detect the architecture of the target process to decide what opcodes to inject.

How to do that?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

无妨# 2024-10-17 16:47:43

定义:

    [DllImport("kernel32.dll")]
    internal static extern void GetNativeSystemInfo(ref SystemInfo lpSystemInfo);

    [DllImport("kernel32.dll")]
    internal static extern void GetSystemInfo(ref SystemInfo lpSystemInfo);

    [StructLayout(LayoutKind.Sequential)]
    internal struct SystemInfo
    {
        public ushort wProcessorArchitecture;
        public ushort wReserved;
        public uint dwPageSize;
        public IntPtr lpMinimumApplicationAddress;
        public IntPtr lpMaximumApplicationAddress;
        public UIntPtr dwActiveProcessorMask;
        public uint dwNumberOfProcessors;
        public uint dwProcessorType;
        public uint dwAllocationGranularity;
        public ushort wProcessorLevel;
        public ushort wProcessorRevision;
    }

    internal const ushort ProcessorArchitectureIntel = 0;
    internal const ushort ProcessorArchitectureIa64 = 6;
    internal const ushort ProcessorArchitectureAmd64 = 9;
    internal const ushort ProcessorArchitectureUnknown = 0xFFFF;

GetNativeSystemInfo 将返回有关正在运行的计算机的信息。
GetSystemInfo 将返回有关正在运行的虚拟化环境的信息(如果没有,则与 GetNativeSystemInfo 相同)。

IE:
在 32 位 Windows 上,您将始终拥有 wProcessorArchitecture == ProcessorArchitectureIntel。

在 64 位 Windows 上,如果您作为 32 位进程运行,则 GetSystemInfo 将为 wProcessorArchitecture == ProcessorArchitectureIntel,但 GetNativeSystemInfo 将为 wProcessorArchitecture == ProcessorArchitectureAmd64。

如果您是 64 位 Windows 上的 64 位进程,那么它们显然都是 ProcessorArchitectureAmd64。

Define:

    [DllImport("kernel32.dll")]
    internal static extern void GetNativeSystemInfo(ref SystemInfo lpSystemInfo);

    [DllImport("kernel32.dll")]
    internal static extern void GetSystemInfo(ref SystemInfo lpSystemInfo);

    [StructLayout(LayoutKind.Sequential)]
    internal struct SystemInfo
    {
        public ushort wProcessorArchitecture;
        public ushort wReserved;
        public uint dwPageSize;
        public IntPtr lpMinimumApplicationAddress;
        public IntPtr lpMaximumApplicationAddress;
        public UIntPtr dwActiveProcessorMask;
        public uint dwNumberOfProcessors;
        public uint dwProcessorType;
        public uint dwAllocationGranularity;
        public ushort wProcessorLevel;
        public ushort wProcessorRevision;
    }

    internal const ushort ProcessorArchitectureIntel = 0;
    internal const ushort ProcessorArchitectureIa64 = 6;
    internal const ushort ProcessorArchitectureAmd64 = 9;
    internal const ushort ProcessorArchitectureUnknown = 0xFFFF;

GetNativeSystemInfo will return you info about the machine you're running on.
GetSystemInfo will return you info about the virtualised environment you're running within (which will be the same as GetNativeSystemInfo if there isn't one).

I.e:
On 32 bit Windows, you will have wProcessorArchitecture == ProcessorArchitectureIntel always.

On 64 bit Windows, you will have wProcessorArchitecture == ProcessorArchitectureIntel for GetSystemInfo, but wProcessorArchitecture == ProcessorArchitectureAmd64 for GetNativeSystemInfo, if you are running as a 32 bit process.

They will obviously both be ProcessorArchitectureAmd64 if you're a 64 bit process on 64 bit Windows.

抱猫软卧 2024-10-17 16:47:43

您必须调用 Win32 才能获取此信息:

[System.Runtime.InteropServices.DllImport("kernel32.dll")]
public static extern bool IsWow64Process(System.IntPtr hProcess, out bool lpSystemInfo);

public bool IsWow64Process(System.Diagnostics.Process process)
{
    bool retVal = false;
    IsWow64Process(process.Handle, out retVal);
    return retVal;
}

为每个进程调用 IsWow64Process(process) 将告诉您它是否是 64 位。我还没有遇到过确定进程是 x64 还是 IA64 的方法,只是确定它的“位数”。

You have to call out to Win32 to get this information:

[System.Runtime.InteropServices.DllImport("kernel32.dll")]
public static extern bool IsWow64Process(System.IntPtr hProcess, out bool lpSystemInfo);

public bool IsWow64Process(System.Diagnostics.Process process)
{
    bool retVal = false;
    IsWow64Process(process.Handle, out retVal);
    return retVal;
}

Calling IsWow64Process(process) for each process will tell you whether is it 64-bit or not. I've not come across a method to determine whether a process is x64 or IA64, just its "bitness".

瞄了个咪的 2024-10-17 16:47:43

您可以 p/invoke QueryFullProcessImageNameGetProcessImageFileName,然后读取 .exe 文件的 PE 标头。

You could p/invoke QueryFullProcessImageName or GetProcessImageFileName and then read the PE header of the .exe file.

春风十里 2024-10-17 16:47:43

Alastair 是对的,您不能只调用 IsWow64Process,但也不需要直接调用另一个 WinApi 函数。这是一个更短的解决方案。

    /// <summary>
    /// TRUE if the process is running under WOW64. That is if it is a 32 bit process running on 64 bit Windows.
    /// If the process is running under 32-bit Windows, the value is set to FALSE. 
    /// If the process is a 64-bit application running under 64-bit Windows, the value is also set to FALSE.
    /// </summary>
    [DllImport( "kernel32.dll" )]
    static extern bool IsWow64Process( System.IntPtr aProcessHandle, out bool lpSystemInfo );

    /// <summary>
    /// Indicates if the process is 32 or 64 bit.
    /// </summary>
    /// <param name="aProcessHandle">process to query</param>
    /// <returns>true: process is 64 bit; false: process is 32 bit</returns>
    public static bool Is64BitProcess( System.IntPtr aProcessHandle )
    {
        bool lIs64BitProcess = false;
        if ( System.Environment.Is64BitOperatingSystem ) {
            IsWow64Process( aProcessHandle, out lIs64BitProcess );
        }
        return lIs64BitProcess;
    }

Alastair is right in that you cannot just call IsWow64Process, but you also dont need to call another WinApi function directly. Here's a shorter solution.

    /// <summary>
    /// TRUE if the process is running under WOW64. That is if it is a 32 bit process running on 64 bit Windows.
    /// If the process is running under 32-bit Windows, the value is set to FALSE. 
    /// If the process is a 64-bit application running under 64-bit Windows, the value is also set to FALSE.
    /// </summary>
    [DllImport( "kernel32.dll" )]
    static extern bool IsWow64Process( System.IntPtr aProcessHandle, out bool lpSystemInfo );

    /// <summary>
    /// Indicates if the process is 32 or 64 bit.
    /// </summary>
    /// <param name="aProcessHandle">process to query</param>
    /// <returns>true: process is 64 bit; false: process is 32 bit</returns>
    public static bool Is64BitProcess( System.IntPtr aProcessHandle )
    {
        bool lIs64BitProcess = false;
        if ( System.Environment.Is64BitOperatingSystem ) {
            IsWow64Process( aProcessHandle, out lIs64BitProcess );
        }
        return lIs64BitProcess;
    }
满栀 2024-10-17 16:47:43

您可以尝试 P/Invoke:

BOOL WINAPI IsWow64Process(  __in   HANDLE hProcess, __out  PBOOL Wow64Process);

You can try to P/Invoke:

BOOL WINAPI IsWow64Process(  __in   HANDLE hProcess, __out  PBOOL Wow64Process);
落叶缤纷 2024-10-17 16:47:43

我认为你们都在正确的轨道上,但返回值缺少一个非运算符。如果您使用的是 64 位计算机并且进程是 WOW64,那么它就是 32 位进程(请参阅 IsWow64Process 上面的注释)。此外,IsWow64Process 返回错误的可能性也没有得到处理。这是一个固定版本:

/// <summary>
/// TRUE if the process is running under WOW64. That is if it is a 32 bit process running on 64 bit Windows.
/// If the process is running under 32-bit Windows, the value is set to FALSE. 
/// If the process is a 64-bit application running under 64-bit Windows, the value is also set to FALSE.
/// </summary>
[DllImport("kernel32.dll", SetLastError=true)]
static extern bool IsWow64Process(System.IntPtr aProcessHandle, out bool isWow64Process);

/// <summary>
/// Indicates if the process is 32 or 64 bit.
/// </summary>
/// <param name="aProcessHandle">process to query</param>
/// <returns>true: process is 64 bit; false: process is 32 bit</returns>
public static bool Is64BitProcess(System.IntPtr aProcessHandle)
{
    if (!System.Environment.Is64BitOperatingSystem)
        return false;

    bool isWow64Process;
    if (!IsWow64Process(aProcessHandle, out isWow64Process))
        throw new Win32Exception(Marshal.GetLastWin32Error());

    return !isWow64Process;
}

I think y'all are on the right track, but the return value is missing a not operator. If you're on a 64-bit machine and the process is WOW64, then it's a 32-bit process (see comments above IsWow64Process). Also, the possibility of IsWow64Process returning an error is not being handled. Here's a fixed version:

/// <summary>
/// TRUE if the process is running under WOW64. That is if it is a 32 bit process running on 64 bit Windows.
/// If the process is running under 32-bit Windows, the value is set to FALSE. 
/// If the process is a 64-bit application running under 64-bit Windows, the value is also set to FALSE.
/// </summary>
[DllImport("kernel32.dll", SetLastError=true)]
static extern bool IsWow64Process(System.IntPtr aProcessHandle, out bool isWow64Process);

/// <summary>
/// Indicates if the process is 32 or 64 bit.
/// </summary>
/// <param name="aProcessHandle">process to query</param>
/// <returns>true: process is 64 bit; false: process is 32 bit</returns>
public static bool Is64BitProcess(System.IntPtr aProcessHandle)
{
    if (!System.Environment.Is64BitOperatingSystem)
        return false;

    bool isWow64Process;
    if (!IsWow64Process(aProcessHandle, out isWow64Process))
        throw new Win32Exception(Marshal.GetLastWin32Error());

    return !isWow64Process;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文