Author Topic: Detect if your Windows version is 32- or 64-bit  (Read 16978 times)

jj2007

  • Member
  • *****
  • Posts: 13945
  • Assembly is fun ;-)
    • MasmBasic
Detect if your Windows version is 32- or 64-bit
« on: August 23, 2018, 01:20:01 PM »
The Internet seems full of complicated attempts to determine the bitness of Windows, so why not add a solution for Masm32?  ;)

Code: [Select]
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:
Code: [Select]
  .if Exist("C:\Windows\SysWow64")
PrintLine "Win-64"
  .else
PrintLine "Win-32"
  .endif

This one:
Code: [Select]
  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

  • Member
  • ****
  • Posts: 577
    • Github
Re: Detect if your Windows version is 32- or 64-bit
« Reply #1 on: August 23, 2018, 02:19:59 PM »
I came across this a while back:

Code: [Select]
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
fearless

ASUS Crosshair 8 Hero, AMD 5950X, 32GB, MSI 5700XT, NZXT Kraken Z73, Seasonic 1000W PSU

Github Twitter Mastodon Gitbook

jj2007

  • Member
  • *****
  • Posts: 13945
  • Assembly is fun ;-)
    • MasmBasic
Re: Detect if your Windows version is 32- or 64-bit
« Reply #2 on: August 23, 2018, 02:37:13 PM »
Nice but undocumented:
Quote
This is a trick that I found in Kronos malware

Here is the short version, works like a charm on Win7-64 and XP-32:
Code: [Select]
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...
Code: [Select]
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:
Code: [Select]
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:
« Last Edit: August 24, 2018, 03:32:08 AM by jj2007 »

P1

  • Global Moderator
  • Member
  • *****
  • Posts: 66
Re: Detect if your Windows version is 32- or 64-bit
« Reply #3 on: August 24, 2018, 11:32:01 PM »
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

  • Member
  • *****
  • Posts: 13945
  • Assembly is fun ;-)
    • MasmBasic
Re: Detect if your Windows version is 32- or 64-bit
« Reply #4 on: August 25, 2018, 12:03:42 AM »
invoke GetNativeSystemInfo, addr lp_SYSTEM_INFO

Thanks, Michael - that's what I use already:
Code: [Select]
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

  • Global Moderator
  • Member
  • *****
  • Posts: 66
Re: Detect if your Windows version is 32- or 64-bit
« Reply #5 on: August 25, 2018, 03:54:36 AM »
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

Vortex

  • Member
  • *****
  • Posts: 2790

jj2007

  • Member
  • *****
  • Posts: 13945
  • Assembly is fun ;-)
    • MasmBasic
Re: Detect if your Windows version is 32- or 64-bit
« Reply #7 on: August 25, 2018, 05:25:24 AM »
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--

  • Administrator
  • Member
  • ******
  • Posts: 10583
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Detect if your Windows version is 32- or 64-bit
« Reply #8 on: August 25, 2018, 05:48:13 AM »
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.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

felipe

  • Member
  • *****
  • Posts: 1381
Re: Detect if your Windows version is 32- or 64-bit
« Reply #9 on: August 25, 2018, 06:43:37 AM »
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

  • Member
  • *****
  • Posts: 13945
  • Assembly is fun ;-)
    • MasmBasic
Re: Detect if your Windows version is 32- or 64-bit
« Reply #10 on: August 25, 2018, 06:53:28 AM »
is 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

  • Member
  • *****
  • Posts: 1381
Re: Detect if your Windows version is 32- or 64-bit
« Reply #11 on: August 25, 2018, 07:22:12 AM »
If just one function does what it's needed, so it's probably the best option. :bgrin:

mineiro

  • Member
  • ****
  • Posts: 947
Re: Detect if your Windows version is 32- or 64-bit
« Reply #12 on: August 25, 2018, 10:30:34 AM »
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

  • Member
  • *****
  • Posts: 2397
  • my kind of REAL10 Blonde
Re: Detect if your Windows version is 32- or 64-bit
« Reply #13 on: August 25, 2018, 05:18:30 PM »
I always run 128bit or more since the dawn of SSE :P
my none asm creations
http://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

  • Member
  • **
  • Posts: 207
  • Binary Grinder
    • SCTZine
Re: Detect if your Windows version is 32- or 64-bit
« Reply #14 on: September 09, 2018, 04:48:28 PM »
@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
Code: [Select]
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"
Code: [Select]
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