Monday, January 23, 2017

How to detect windows os is 32 bit or 64 bit using c++?

This is one of the questions asked by budding programmers in many technical forums. Not just for legit purpose, even malware authors used these strategies in their programs to find out whether 32 bit or 64 bit. In this post we going to discuss various ways to determine whether it is 32 bit or 64 bit.

The popular answers are
"The function to call is IsWow64Process. It tells your 32-bit application if it is running on a 64 bit Windows."
According to Microsoft, IsWow64process( ) is to determine the specific process is running under WOW64.
Syntax: 
BOOL WINAPI IsWow64Process(
  _In_  HANDLE hProcess,
  _Out_ PBOOL  Wow64Process
);

Sample program given by Microsoft:
#include <windows.h>
#include <tchar.h>

typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);

LPFN_ISWOW64PROCESS fnIsWow64Process;

BOOL IsWow64()
{
    BOOL bIsWow64 = FALSE;

    //IsWow64Process is not available on all supported versions of Windows.
    //Use GetModuleHandle to get a handle to the DLL that contains the function
    //and GetProcAddress to get a pointer to the function if available.

    fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
        GetModuleHandle(TEXT("kernel32")),"IsWow64Process");

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

int main( void )
{
    if(IsWow64())
        _tprintf(TEXT("The process is running under WOW64.\n"));
    else
        _tprintf(TEXT("The process is not running under WOW64.\n"));

    return 0;
}


There is another way to do this via program:
bool getWindowsBit(bool & isWindows64bit)
{
#if _WIN64

    isWindows64bit =  true;
    return true;

#elif _WIN32

    BOOL isWow64 = FALSE;

    //IsWow64Process is not available on all supported versions of Windows.
    //Use GetModuleHandle to get a handle to the DLL that contains the function
    //and GetProcAddress to get a pointer to the function if available.

    LPFN_ISWOW64PROCESS fnIsWow64Process  = (LPFN_ISWOW64PROCESS) 
GetProcAddress(GetModuleHandle(TEXT("kernel32")),"IsWow64Process");

    if(fnIsWow64Process)
    {
        if (!fnIsWow64Process(GetCurrentProcess(), &isWow64))
            return false;

        if(isWow64)
            isWindows64bit =  true;
        else
            isWindows64bit =  false;

        return true;
    }
    else
        return false;

#else

    assert(0);
    return false;

#endif
}

 GetSystemWow64Directory Method:
In this method, the function returns the path of system directory if it is 64 bit os.
Otherwise, it is understood that 32 bit os.

Syntax:
UINT WINAPI GetSystemWow64Directory(
  _Out_ LPTSTR lpBuffer,
  _In_  UINT   uSize
);
Novel Method used by malware:
A recent malware called Shamoon malware, it is disk wiper malware, targets the
power sector in gulf region.
This malware using a novel technique to find the os is 32 bit or 64 bit.
It was quoted from the security researcher's analysis:
"To identify 64Bit OS, first you open "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" using RegOpenKey API. Then by calling RegQueryValue API you read "PROCESSOR_ARCHITECTURE" value inside. Now using wcscmp function, you once compare it to "amd64" once and with another wcscmp call, you compare it against "AMD64" string. So for this purpose you store "amd64" and "AMD64" strings separately in the code, encrypt them separately with separate keys, decrypt each one individually in runtime and use all these information and around 7 function and API calls to identify 64 bit OS. Because as old C++ saying goes, "never trust wcsicmp as case-insensitive string compare, it doesn't work". Here is the genius code snippet:
char Detect64BitOSNovelMethod()
{
  char v0; // bl@1
  unsigned int v1; // esi@3
  DWORD Type; // [sp+4h] [bp-DCh]@2
  DWORD cbData; // [sp+8h] [bp-D8h]@2
  HKEY phkResult; // [sp+Ch] [bp-D4h]@1
  BYTE Data; // [sp+10h] [bp-D0h]@2
  __int16 v7[52]; // [sp+74h] [bp-6Ch]@4
 
  v0 = 0;
  if ( !RegOpenKeyExW(HKEY_LOCAL_MACHINE, EnvironmentRegPath, 0, 0x20019u, &phkResult) )
  {
    Type = 0;
    cbData = 100;
    if ( !RegQueryValueExW(phkResult, PROCESSOR_ARCHITECTURE_STR, 0, &Type, &Data, &cbData) )
    {
      v1 = cbData;
      if ( cbData > 0 )
      {
        memcpy_0(v7, &Data, cbData);
        v7[v1 >> 1] = 0;
        if ( !wcscmp((const unsigned __int16 *)AMD64_STR, (const unsigned __int16 *)v7)
          || !wcscmp((const unsigned __int16 *)amd64_lower_str, (const unsigned __int16 *)v7) )
        {
          v0 = 1;
        }
      }
    }
    RegCloseKey(phkResult);
  }
  return v0;
}

 Plenty of techniques are available and still we need to explore more on this. 
Post created by newWorld

No comments:

Operating system - Part 1:

 In our blog, we published several articles on OS concepts which mostly on the perspective for malware analysis/security research. In few in...