Jump to content
Tuts 4 You

x86 & x64 issues.Do you have the overview?


LCF-AT

Recommended Posts

Hi guys,

so I just have a small question about the SYSTEM_INFO struct and checking the wProcessorArchitecture type to check whether the running OS is x86 or x64 version.So if I read it right then its enough to checking the wProcessorArchitecture type only to get the info about x86 / x64 any "no matter" if I call GetSystemInfo / GetNativeSystemInfo from a x86 or x64 application right?So in this case I dont need to check for IsWow64Process API.

If so then I have a add on question.So I found a code about checking Win versions etc and at the end its also checking for wProcessorArchitecture to send output whether its 32 or 64 bit Win version (all clear so far).....BUT its just checking before the dwMajorVersion >= 6 (whether its 6 or higher).So dwMajorVersion 6 ( Windows Vista or higher).So why isnt it checking from dwMajorVersion 5 ( Windows 2000 / Windows XP / etc)?So there are also 64 bit OS systems to get.So I am just talking about checking the dwMajorVersion alone.So dosent it get always the info for this paramter or whats the reason why the example code I found just starting at dwMajorVersion 6?

Lets say I would like to check for Windows XP Home then the conditions are dwMajorVersion 5 & dwMinorVersion 1 & wSuiteMask = VER_SUITE_PERSONAL but I also want to check for x86 / x64 too and need to check the wProcessorArchitecture type for this and it should work or not?

Here the example schnippel I found...

http://stackoverflow.com/questions/8025074/translating-getversionex-numbers-into-os-name

if ( osvi.dwMajorVersion >= 6 )
      {
         if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
            StringCchCat(pszOS, BUFSIZE, TEXT( ", 64-bit" ));
         else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL )
            StringCchCat(pszOS, BUFSIZE, TEXT(", 32-bit"));
      }

      return TRUE; 

....you see its only checking dwMajorVersion  6 or higher so thats the reason why I ask for.So I would do it so....

	          .if  osvi.dwMajorVersion >= 5
	               .if     SYS.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 || SYS.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64
	                       invoke lstrcat,addr WINTEXTOUT,chr$("64-bit")
	               .elseif SYS.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL 
	                       invoke lstrcat,addr WINTEXTOUT,chr$("32-bit")
	               .endif
	         .endif

....or what do you think?

Next question about IsWow64Process API: Using this API to get diffrent informations about the process I wanna check whether its a x86 or x64 process.

So if I did understand the MSDN description correctly then I get diffrent values back depending from what application version (x32 or x64) I do call this API if present.If the API isnt present then only x86 process can run (clear so far).If the API is present then its first important to check the own application with that API.....so I know my own apps are compiled as x86 versions only = first info I need to know to interpret the next comming results of IsWow64Process API / Wow64Process [out] paramter.

Quote

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.

First I check my own app (I know its 32 bit compiled) and get FALSE back if my process is running also on 32 bit OS.

I get TRUE back if my 32 bit app runs on a 64 bit OS.

Now I know whether my app runs on a 32 or 64 bit OS.If I now check other running processes from my application and get TRUE back into the out paramter then its a 64 bit process and FALSE if 32 bit....right or?And if my compiled app would be a x64 version then I would get FALSE back if the process I do check is a x64  running on x64 OS right?Or exactly else?So if this API dosent depends from my own application (x86) and only depends on the process handle I do check then I should check for FALSE return = x64 process if OS is also x64.

So all in all its a little bit confusing so I am also not really sure about the last part checking the processes whether its a x64 or x86 one.So its easier to check the PE Header of the running file whether its a x86 or x64 file.

Maybe you can tell something about this also if I wrote / understand something wrong.Just wanna be sure how to handle and understand it correctly you know.

Thank you

Link to comment

For checking if a process is running under WOW64 use IsWow64Process. For finding the OS version I use RtlGetVersion. You can use RtlVerifyVersionInfo to compare whether the operating system meets a specific requirement. For finding the bitness of another process fill the IMAGE_FILE_HEADER structure and check the architecture type.

Example PureBasic code I have for RtlGetVersion...

; ------------------------------------------------------------------
;
;   PureBasic RtlGetVersion(dwMajor, dwMinor, dwBuild, dwCompare) function to check
;   if the callers operating system is equal to or greater than the selected input
;   values. To check operating system version number set dwCompare flag to #True.
;
;   A #Null value in dwCompare flag ignores version checking and returns version 
;   information about the currently running operating system in the global variable
;   dwVersion as a string value.
;   
;   Return Values:
;
;   If the function succeeds, the return value is a nonzero value.
;   If the function fails, the return value is zero.
;
;   Remarks:
;
;   Refer to RTL_OSVERSIONINFOEXW structure on MSDN for a summary of all supported
;   operating system version numbers.
;
;   https://msdn.microsoft.com/en-us/library/windows/hardware/ff563620%28v=vs.85%29.aspx
;
;   By Teddy Rogers / PureBasic 5.24 LTS
;
; ------------------------------------------------------------------

Procedure RtlGetVersion(dwMajor, dwMinor, dwBuild, dwCompare)
  Protected RTL.OSVERSIONINFOEX                                 ; RTL Structure
  
  RTL\dwOSVersionInfoSize = SizeOf(RTL)                         ; The size, in bytes, of an RTL_OSVERSIONINFOEX structure
  
  If OpenLibrary(ntdll, "ntdll.dll")
    RtlGetVersion = GetFunction(ntdll, "RtlGetVersion")
    
    If RtlGetVersion
      CallFunctionFast(RtlGetVersion, @RTL)

      If dwCompare                                              ; If true compare the version numbers
        If dwMajor => RTL\dwMajorVersion And dwMinor => RTL\dwMinorVersion And dwBuild => RTL\dwBuildNumber
          ProcedureReturn #True
        EndIf
      Else
        Global dwVersion.s = Str(RTL\dwMajorVersion) + "." + Str(RTL\dwMinorVersion) + "." + Str(RTL\dwBuildNumber)
        
        If dwVersion.s
          ProcedureReturn #True
        EndIf
      EndIf
    EndIf
    CloseLibrary(ntdll)
  EndIf
  
  ProcedureReturn #False
EndProcedure

Debug RtlGetVersion(6, 3, 9600, #False)
Debug dwVersion.s

Ted.

  • Like 1
Link to comment

Hi Ted,

thank you for your answer so far but isnt really the answer of my questions I was looking for.

So if I get a filled SYSTEM_INFO struct back after calling it with GetSystemInfo / GetNativeSystemInfo then the question is whether its enough to check now the wProcessorArchitecture for PROCESSOR_ARCHITECTURE_AMD64 or PROCESSOR_ARCHITECTURE_IA64 = Windows x64 is running on that system.Just talking about the OS in this case.Should be right so or?So I did debug CCleaner tool and its also check just for these paramters 9 & 6 = 64 bit.Just wanna know whether this is correctly so or not?Anyway whether I do check this on Windows 2000 or higher.

Now about the processes using IsWow64Process API.

1.) Checking whether IsWow64Process is present or not (GetProcAddress).If not present = no x64 Windows system running and must be lower

2.) If IsWow64Process is present then I can use this API with the condition that I found already out the Win OS bit version via (wProcessorArchitecture check) or I do check it with IsWow64Process API and my own compiled target where I as coder know the bit version of course.

If my app is 32 bit and I call IsWow64Process with my own process handle and I get TRUE back into Wow64Process paramter then the Windows version is x64.

If my app is 32 bit and I call IsWow64Process with my own process handle and I get FALSE back into Wow64Process paramter then the Windows version is x86

If my app is 64 bit and I call IsWow64Process with my own process handle and I get FALSE back into Wow64Process paramter then the Windows version is x64.

There are three possibilities you can check for with that API ONLY if you know already the compiled app x version (normaly you know this for your own codes apps but not if you inject such code somewhere etc).So you can use this IsWow64Process correctly if you know your app x version so without this info isnt working to interpret the TRUE & FALSE correctly.

So now on the other hand it would be more simple just to check the wProcessorArchitecture for x64 Windows version without using IsWow64Process API for that.Lets say you have installed a 32 bit Win version and you do check wProcessorArchitecture then you will not get PROCESSOR_ARCHITECTURE_AMD64 or PROCESSOR_ARCHITECTURE_IA64 back but if you have installed a Win 64 bit version then you get it back.

Thats the reason why I just ask for it to be sure whether my interpretation is right or not.So I cant test it by myself and only have Win 32 bit running.Just need any confirmed info or wrong info.

So lets imagine I am right so far then the code could look something like this....
 

If PROCESSOR_ARCHITECTURE_AMD64 or PROCESSOR_ARCHITECTURE_IA64 = Windows 64 bit running OS

; Now I need to use IsWow64Process to check running processes whether they 32 or 64 bit ones.

.......

          IsWow64Process (ProcessHandle all processes),Wow64Process

          if Wow64Process == FALSE

          The checked processhandle is a 64 bit process

         .else

          The checked processhandle is a 32 bit process

         .endif

Else = lower than 64 bit Windows version.

mov IsWOW, False  ; Now I dont need use IsWow64Process to check all running processes whether its 32 or 64 bit ones.
                  ; So they are lower than 64 bit
Endif

...right?I think so but I cant test it of course.As I said I just need any info whether I am right or wrong if I wanna check this on that way as I wrote above.

greetz

Link to comment

IsWow64Process is not supported in all OS versions so it is not the best method to use to detect the bitness of a running process.

A way to detect for process bitness the way you have described above, only for operating systems that support IsWow64Process...

Declare.l IsProcess64(hWnd, lParam)

Kernel32 = OpenLibrary(#PB_Any, "kernel32.dll")

If Kernel32
  Prototype.i GetNativeSystemInfo(lpSystemInfo.i)
  GetNativeSystemInfo.GetNativeSystemInfo 
  
  GetNativeSystemInfo = GetFunction(Kernel32, "GetNativeSystemInfo")
  
  Prototype.i IsWow64Process(hProcess.i, Wow64Process.i)
  Global IsWow64Process.IsWow64Process 
  
  IsWow64Process = GetFunction(Kernel32, "IsWow64Process")
  
  If GetNativeSystemInfo
    GetNativeSystemInfo(@lpSystemInfo.SYSTEM_INFO)
    
    Select lpSystemInfo\wProcessorArchitecture
      Case 0
        Debug "PROCESSOR_ARCHITECTURE_INTEL"
      Case 5
        Debug "PROCESSOR_ARCHITECTURE_ARM"
      Case 6
        Debug "PROCESSOR_ARCHITECTURE_IA64"
      Case 9
        Debug "PROCESSOR_ARCHITECTURE_AMD64"
      Default
        Debug "PROCESSOR_ARCHITECTURE_UNKNOWN"
    EndSelect
    
    If IsWow64Process
      EnumDesktopWindows_(#Null, @IsProcess64(), #False)
    Else
      Debug "IsWow64Process not supported."
    EndIf
  EndIf
EndIf

CloseLibrary(Kernel32)

Procedure.l IsProcess64(hWnd, lParam)
  Protected lpdwProcessId, handle
  #PROCESS_QUERY_LIMITED_INFORMATION = $1000
  
  If IsWindowVisible_(hWnd)
    If GetWindowLongPtr_(hWnd, #GWL_EXSTYLE) & #WS_EX_TOOLWINDOW <> #WS_EX_TOOLWINDOW

      lpString.s = Space(80)
      GetWindowText_(hWnd, @lpString, 80)
      
      Debug lpString      
      
      GetWindowThreadProcessId_(hWnd, @lpdwProcessId)
      
      handle = OpenProcess_(#PROCESS_QUERY_LIMITED_INFORMATION, #False, lpdwProcessId)
      
      If handle
        
        IsWow64Process(handle, @Wow64Process)

        If Wow64Process
          Debug "Process is 32bit."
          Debug ""
        Else
          Debug "Process is 64bit."
          Debug ""
        EndIf
        
        CloseHandle_(handle)
        ProcedureReturn #True
      EndIf
      
      Debug "Failed to obtain handle."
      ProcedureReturn #False
    EndIf
  EndIf
  
  ProcedureReturn #True
EndProcedure

Ted.

  • Like 1
Link to comment

Hi again,

so now I made a little check app for testing to whether my method is right or not.So it would be nice if some of you could test it to see what results you get about x86 & x64 running processes.Below a pic I made for my system...

wPA.png

...just have a look into last comlumn IsWow.....It does call the IsWow64Process API just if the wPA is also 64 (systeminfo struct) and then it checks for FALSE resiult = is a x64 process.Below you can see the wPA info and more I did add to check for.Just check it with your system (especially if you use a 64 Bit OS) and maybe you can post also a pic etc so that would be nice.Just wanna be sure if I am right or not before I code go on etc.

Checking.rar

Thank you

Link to comment

Hello NOP,

thank you for testing and posting some pics. :) So it seems everyhing is working right and did confirmed my method.Coolio. :)

Thanks again

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...