News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Detect if your Windows version is 32- or 64-bit

Started by jj2007, August 23, 2018, 01:20:01 PM

Previous topic - Next topic

jj2007

The Internet seems full of complicated attempts to determine the bitness of Windows, so why not add a solution for Masm32?  ;)

include \masm32\include\masm32rt.inc  ; plain Masm32

Win64 MACRO
  push ebx
  push ecx
  push rv(LoadLibrary, "Kernel32")
  xchg rv(GetProcAddress, eax, "IsWow64Process"), ebx
  call FreeLibrary
  xchg eax, ebx
  test eax, eax
  pop ecx
  pop ebx
  EXITM <!Zero?>
ENDM

.code
start:
  .if Win64()
inkey "64-bit OS detected"
  .else
inkey "not a 64-bit OS"
  .endif
  exit
end start


The problem is: that function exists on 32-bit versions of the OS :(

Raymond Chen's How to detect programmatically whether you are running on 64-bit Windows is not helpful, either.

This works, but it's somehow a hack:
  .if Exist("C:\Windows\SysWow64")
PrintLine "Win-64"
  .else
PrintLine "Win-32"
  .endif


This one:
  PrintLine "Architecture is ", ExpandEnv$("%PROCESSOR_ARCHITEW6432%")
returns Architecture is AMD64 on Win7-64 but Architecture is %PROCESSOR_ARCHITEW6432% on WinXP-32, with 2*% indicating that this environment variable is not set. Could be a solution...

Another almost fool-proof way to check that is to launch a 64-bit hello world proggie. If it runs, the OS is 64-bit. If it doesn't, you need to check the reason.

fearless

I came across this a while back:

is_system64_bit PROTO
.code
; hasherezade - https://gist.github.com/hasherezade/0994447e9d3dc184888fb2afd5a57301
;===============================================================================
; Procedure / Function: is_system64_bit
;===============================================================================
is_system64_bit PROC
    LOCAL flag:DWORD
   
    xor eax, eax
    mov ax, cs
    shr eax, 5
    mov flag, eax
    .IF flag > 0
        mov eax, TRUE
    .ELSE
        mov eax, FALSE
    .ENDIF
    ret
is_system64_bit ENDP

jj2007

#2
Nice but undocumented:
QuoteThis is a trick that I found in Kronos malware

Here is the short version, works like a charm on Win7-64 and XP-32:
include \masm32\include\masm32rt.inc
.code
start:
    mov eax, cs
    shr eax, 5
    .if Zero?
    inkey "32-bit OS"
    .else
inkey "64-bit OS"
    .endif
  exit
end start


Caution, though: There is apparently no documentation why the code segment should have that bit set.

EDIT: In the meantime, I found the solution...
include \masm32\include\masm32rt.inc  ; plain Masm32
.code
start:
  print "let's start with the hack: "
  mov eax, cs
  shr eax, 5
  .if Zero?
print "32-bit OS", 13, 10
  .else
print "64-bit OS", 13, 10
  .endif
  xchg ebx, rv(GetProcAddress, rv(GetModuleHandle, "kernel32") , "IsWow64Process")
  .if ebx
print "IsWow64Process found: retval="
push eax
invoke IsWow64Process, rv(GetCurrentProcess), esp
pop ecx
print str$(ecx), 13, 10, 10
  .else
print "IsWow64Process not found", 13, 10, 10
  .endif
  inkey
  exit
end start


The same but built from a dual 64-/32-bit source:

include \Masm32\MasmBasic\Res\JBasic.inc        ; ## builds in 32- or 64-bit mode with ML, UAsm & AsmC ##
.data?
Is64    dd ?

Init           ; OPT_64 1      ; put 0 for 32 bit, 1 for 64 bit assembly
  PrintLine Chr$("This code was assembled with ", @AsmUsed$(1), " in ", jbit$, "-bit format")
  jinvoke IsWow64Process, rv(GetCurrentProcess), addr Is64
  Inkey Str$("IsWow64Process=%i", Is64)
EndOfCode


Output:
This code was assembled with ml64 in 64-bit format
IsWow64Process=0


If that looks strange, check the logic:
- a 32-bit process on a 32-bit OS does not run on Wow64
- a 32-bit process on a 64-bit OS does run on Wow64
- a 64-bit process on a 64-bit OS does not run on Wow64
- a 64-bit process on a 32-bit OS does not run 8)

Thanks to marpon on the FB forum for helping me to understand the logic :icon14:

P1

invoke GetNativeSystemInfo, addr lp_SYSTEM_INFO

Test for the ARCHITECTURE desired.

All my programming is Windows based, so I have learned to trust the OS.

Regards,  Michael

jj2007

Quote from: P1 on August 24, 2018, 11:32:01 PM
invoke GetNativeSystemInfo, addr lp_SYSTEM_INFO

Thanks, Michael - that's what I use already:
Win64 MACRO
  pushad
  ifndef SysInfo
.DATA?
SysInfo SYSTEM_INFO <>
.CODE
  endif
  mov ebx, offset SysInfo
  invoke GetNativeSystemInfo, ebx
  cmp [ebx.SYSTEM_INFO.wProcessorArchitecture], PROCESSOR_ARCHITECTURE_AMD64
  popad
  EXITM <Zero?>
ENDM

P1

Quote from: jj2007 on August 25, 2018, 12:03:42 AM
Quote from: P1 on August 24, 2018, 11:32:01 PM
invoke GetNativeSystemInfo, addr lp_SYSTEM_INFO
Thanks, Michael - that's what I use already:
I would have not pointed it out, if I saw it in the thread.

Regards,  Michael


jj2007

Hi Erol,
That was a nice thread indeed, but the Windows version (e.g. as MbWinVersion()) doesn't tell us whether the OS is 64- or 32-bit :(

hutch--

I have never had to bother with it but is there something that is 32 bit in 64 bit Windows versions that is not in any 32 bit version ?

If so you could use LoadLibrary() just to see if its there. GetModuleHandle could also be used.

felipe

A bloated solution  :idea::
1)You create 2 programs: 1 is 32 bits and the other 64 bits.
2)You run the 32 bits program, this one should create a process and run the second one (as a child process probably).
3)Inmediately after this it should get the processID of this second program.
4)Then you check if did run or not and determine if the system is 32 or 64 bits...

Yes, is the bloated solution, but fun too...  :greensml:

jj2007

Quote from: hutch-- on August 25, 2018, 05:48:13 AMis there something that is 32 bit in 64 bit Windows versions that is not in any 32 bit version ?

There is (the SysWow64 folder, for example), but GetNativeSystemInfo is shorter and a lot easier to use.

felipe

If just one function does what it's needed, so it's probably the best option. :bgrin:

mineiro

why not just open ntvdm (something like this, after some beers I forgot now) or others essentials windows startup files and check if thats a pe or pe+? Well, a screen driver, or mouse driver just to be sure, even explorer.exe.
This is some type of cognitive parallax? I think not.
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

daydreamer

I always run 128bit or more since the dawn of SSE :P
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

bluedevil

@jochen
how does your "Exist Macro" run on masm32
i have found two of your macro samples but i cant make them work on masm32:
1. This is from 2008
EXIST MACRO fname:REQ, DiscardHandle:=<1>
invoke FindFirstFile, reparg(<fname>), addr wfd
.if eax==INVALID_HANDLE_VALUE
xor eax, eax
.elseif DiscardHandle
invoke FindClose, eax
.endif
EXITM <eax>
ENDM


This is from MasmBasic.inc, but i cant find "MbExistP"
Exist MACRO fname:REQ, DiscardHandle:=<1>
LOCAL tmp$
  ifidn <fname>, <( EdX)>
tmp$ CATSTR <## Warning line >, %@Line, <: use wRes$ with Unicode resources ##>
% echo tmp$
push DiscardHandle or 2
  else
push DiscardHandle or 0
  endif
  if afnUC
afnUC=0
LastFileDosName$ EQU offset wfd.cAlternateFileName
  else
LastFileDosName$ EQU offset wfd[WIN32_FIND_DATA.cAlternateFileName]
  endif
  if @InStr(1, <fname>, <+>)
push Cat$(fname)
  else
push repargA(fname)
  endif
  call MbExistP
  EXITM  <!Zero?>
ENDM
..Dreams make the future
But the past never lies..
BlueDeviL // SCT
My Code Site:
BlueDeviL Github