How can I determine whether a process is 32 or 64 bit?
Asked Answered
K

5

14

Given a Windows process handle, how can I determine, using C++ code, whether the process is 32 bit or 64 bit?

Kirkman answered 6/1, 2013 at 16:27 Comment(11)
maybe this can help? #495744Alvey
I mean process module (HANDLE)Kirkman
@AndyProwl might be useful, is there an api to detect whether the module is 32 or 64?Kirkman
well, the first answer on that page says just that: "You can also use the ImageHelp API to do this - load the DLL with LoadImage and you'll get a LOADED_IMAGE structure which will contain a pointer to an IMAGE_NT_HEADERS structure. Deallocate the LOADED_IMAGE with ImageUnload."Alvey
Did you check this thread? superuser.com/questions/103071/…Perryperryman
@user1824407: He really meant module. Better get used to Windows terminology when commenting on Windows questions.Lucent
@Tim If he meant module, then he got the terms wrong too. The correct term is process.Flavia
@JohnnyPauling If you have a HANDLE to a process, then you are asking how to find out information about processes other than the calling process. In which case you Nawaz's answer, which you accepted does not answer the question.Flavia
@AndyProwl , LoadImage ? you maybe want to say ImageLoad?Dovap
@HarryJohnston if your reopening was justified, please remove the link to the duplicate, otherwise please re-close the Question.Lollis
@Cœur, neither the question as asked nor the accepted answer are the same as the proposed duplicate. But given the ambiguity I'm voting to close as unclear.Furnivall
M
3

If you have handle to the module then you can do this:

IMAGE_NT_HEADERS * headers = ImageNtHeader(handle);

if ( headers->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 )
{
    //module is x86
}
else if  ( headers->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 )
{
    //module is x64
}

I took help from my own answer.

Maunder answered 6/1, 2013 at 16:43 Comment(2)
That's utterly pointless. Since the function only works within the calling process, you are simply trying to determine whether or not the calling process is a 32 or 64 bit process. But you know that when you compiled. Crazy to run code to find out something known at compile time.Flavia
Note that the (handle) to ImageNtHeader is not the same as a windows process HANDLE! ImageNtHeader expects a HMODULE/HINSTANCE, which is a totally different thing than the HANDLE that you might get from OpenProcess or similar.Benedictus
J
49

If you have a process handle, use IsWow64Process().

If IsWow64Process() reports true, the process is 32-bit running on a 64-bit OS.

If IsWow64Process() reports false (or does not exist in kernel32.dll), then the process is either 32-bit running on a 32-bit OS, or is 64-bit running on a 64-bit OS. To know if the OS itself is 32-bit or 64-bit, use GetNativeSystemInfo() (or GetSystemInfo() if GetNativeSystemInfo() is not available in kernel32.dll).

Juicy answered 6/1, 2013 at 20:58 Comment(11)
This is great, I've seen so many answers that forget to check what happens if IsWow64Process is false and assume that the system is 32-bit!Circumflex
Note: better always use GetNativeSystemInfo, because GetSystemInfo returns the architecture the app was built for, if running under WOW64.Baccy
@Baccy GetNativeSystemInfo() is not available on older systems, which is why I put native in parenthesis, to go along with the fact that IsWow64Process() is not always available. I have reworded my answer.Juicy
Since this is now resurrected (irony that I would be seeing it today; I figured this independently so thanks for confirming that I did have the algorithm right), how far back are we talking about by "older systems"? I imagine I don't need to do this if I'm targeting Vista or by coincidence XP, right?Gardol
@Gardol IsWow64Process() was introduced in XP SP2. GetNativeSystemInfo() was introduced in XP, not sure if it was in RTM or a SP.Juicy
@RemyLebeau How does GetSystemInfo() tell you if the OS is 32-bit or 64-bit? All I can see is the processor architecture which is not the same thing.Countershading
@Steiny the processor architecture is exactly how you find out. Some processors are 32bit, others are 64bit. The OS bitness matches the processor bitness.Juicy
What about ARM64 and ARM64EC?Haematoblast
@Haematoblast per github.com/dotnet/runtime/issues/26612: "Seems like we can ... check for IsWOW64Process2 and use it if available, otherwise fallback to using GetNativeSystemInfo" IsWOW64Process2() should report AMD architectures.Juicy
@RemyLebeau does AMD make ARM64 chipsets these days?Haematoblast
@Haematoblast I meant ARM not AMD. IsWow64Process2() has IMAGE_FILE_MACHINE_ARM and IMAGE_FILE_MACHINE_ARM64 output flags defined.Juicy
C
4
BOOL IsWow64(HANDLE process)
{
    BOOL bIsWow64 = FALSE;

    typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
    LPFN_ISWOW64PROCESS fnIsWow64Process;
    fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process");

    if (NULL != fnIsWow64Process)
    {
        if (!fnIsWow64Process(process, &bIsWow64))
        {
            //handle error
        }
    }
    return bIsWow64;
}

bool IsX86Process(HANDLE process)
{
    SYSTEM_INFO systemInfo = { 0 };
    GetNativeSystemInfo(&systemInfo);

    // x86 environment
    if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
        return true;

    // Check if the process is an x86 process that is running on x64 environment.
    // IsWow64 returns true if the process is an x86 process
    return IsWow64(process);
}
Cynar answered 6/12, 2018 at 12:2 Comment(0)
M
3

If you have handle to the module then you can do this:

IMAGE_NT_HEADERS * headers = ImageNtHeader(handle);

if ( headers->FileHeader.Machine == IMAGE_FILE_MACHINE_I386 )
{
    //module is x86
}
else if  ( headers->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 )
{
    //module is x64
}

I took help from my own answer.

Maunder answered 6/1, 2013 at 16:43 Comment(2)
That's utterly pointless. Since the function only works within the calling process, you are simply trying to determine whether or not the calling process is a 32 or 64 bit process. But you know that when you compiled. Crazy to run code to find out something known at compile time.Flavia
Note that the (handle) to ImageNtHeader is not the same as a windows process HANDLE! ImageNtHeader expects a HMODULE/HINSTANCE, which is a totally different thing than the HANDLE that you might get from OpenProcess or similar.Benedictus
S
0

Try

#include <Windows.h>
enum class process_architecture
{
    nun,
    x32,
    x64
};
enum class windows_architecture
{
    x32,
    x64
};
windows_architecture process::get_windows_architecture()
{
#ifdef _WIN64
    return windows_architecture::x64;
#else
    return windows_architecture::x32;
#endif
}

process_architecture get_process_architecture(DWORD id)
{
    BOOL is_wow_64 = FALSE;
    HANDLE h_process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, id);
    if (!h_process) return process_architecture::nun;
    bool result = IsWow64Process(h_process, &is_wow_64);
    CloseHandle(h_process);
    if (!result) return process_architecture::nun;
    if (is_wow_64) return process_architecture::x32;
    else if (get_windows_architecture() == windows_architecture::x32) return process_architecture::x32;
    else return process_architecture::x64;
}
Shoeshine answered 21/10, 2021 at 14:19 Comment(0)
D
-1

If you do not want to use windows API, try:

int main()
{
    const int* pInt = nullptr;
    if (sizeof(pInt) == 8)
    {
        std::cout << "64 bit process";
    }
    else if(sizeof(pInt) == 4)
    {
        std::cout << "32 bit process";
    }
return 0;
}
Distraught answered 31/1, 2022 at 13:39 Comment(1)
This doesn't let you determine the bitness of an arbitrary process.Lucent

© 2022 - 2025 — McMap. All rights reserved.