The MASM Forum

General => The Campus => Topic started by: jj2007 on August 23, 2018, 01:20:01 PM

Title: Detect if your Windows version is 32- or 64-bit
Post by: jj2007 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 (https://support.microsoft.com/en-us/help/2060044/how-to-detect-the-bitness-of-an-operating-system) 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.
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: fearless 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
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: jj2007 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 (https://www.freebasic.net/forum/viewtopic.php?f=6&t=26951&p=250991#p250989) for helping me to understand the logic :icon14:
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: P1 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
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: jj2007 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
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: P1 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
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: Vortex on August 25, 2018, 04:54:36 AM
Retrieving Windows OS Version (http://masm32.com/board/index.php?topic=6299.0)
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: jj2007 on August 25, 2018, 05:25:24 AM
Hi Erol,
That was a nice thread indeed, but the Windows version (e.g. as MbWinVersion() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1344)) doesn't tell us whether the OS is 64- or 32-bit :(
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: hutch-- 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.
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: felipe 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:
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: jj2007 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.
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: felipe 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:
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: mineiro 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.
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: daydreamer on August 25, 2018, 05:18:30 PM
I always run 128bit or more since the dawn of SSE :P
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: blue_devil 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
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: blue_devil on September 09, 2018, 04:51:54 PM
i am sorry
i have find this after asking the question in the macros/macros.asm

Code: [Select]
  ; -----------------------
  ; test if file exists
  ; return values
  ; 1 = file exists
  ; 0 = file does not exist
  ; -----------------------
    fexist MACRO name_of_file
      IFNDEF __UNICODE__
        EXITM <rv(exist,name_of_file)>
      ELSE
        EXITM <rv(existW,name_of_file)>
      ENDIF
    ENDM
  ; -----------------------

And works nicely!
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: jj2007 on September 09, 2018, 08:04:55 PM
@jochen
how does your "Exist Macro" run on masm32
...
This is from MasmBasic.inc, but i cant find "MbExistP"

It's in \Masm32\MasmBasic\MasmBasic.lib
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: blue_devil on September 09, 2018, 09:05:32 PM
It's in \Masm32\MasmBasic\MasmBasic.lib

I know it is in MasmBasic.lib but there is no MasmBasic.asm :icon_redface: right?
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: blue_devil on September 11, 2018, 07:24:39 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

@jj .SYSTEM_INFO.wProcessorArchitecture returns the bitness of processor not the operating system right? Or am i missing something?

from MSDN network - SYSTEM_INFO (https://msdn.microsoft.com/en-us/library/windows/desktop/ms724958(v=vs.85).aspx)
Quote
wProcessorArchitecture

    The processor architecture of the installed operating system. This member can be one of the following values.
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: jj2007 on September 11, 2018, 09:16:43 AM
@jj .SYSTEM_INFO.wProcessorArchitecture returns the bitness of processor not the operating system right? Or am i missing something?

Good question! And precise answer:
Quote
wProcessorArchitecture

    The processor architecture of the installed operating system. This member can be one of the following values.
::)
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: blue_devil on September 12, 2018, 12:49:10 AM
Last night i have worked too much late. Then, i couldn't understand what i have read. :icon_redface:

Quote
wProcessorArchitecture

    The processor architecture of the installed operating system. This member can be one of the following values.

I already have given answer to my question :icon_eek:
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: blue_devil on September 13, 2018, 10:05:22 AM
So we have 4 approaches to get bitness of windows

1.Hasherezade dedected an approach from the malware kronos. Interestingly cs returns 5 bit value when OS is 32bit and 6bit when OS is 64bit. So by checking the 6th bit from right to left you can dedect the bitness of operating system.
Code: [Select]
;hasherezade's apprach from kronos malware:
invoke StdOut, chr$("[ 1 ] hasherezade's apprach from kronos malware:",13,10)
invoke is_system64_bit
.if Zero?
print chr$("[ + ] 32-bit",13,10)
.else
print chr$("[ + ] 64-bit",13,10)
.endif
invoke StdOut, chr$(13,10,)


is_system64_bit PROC
; _______________________________________________________________________________
; Is your OS 64bit or not procedure
; Author    : hasherezade - https://gist.github.com/hasherezade/0994447e9d3dc184888fb2afd5a57301
; Receives  :
; Returns   : eax > 0 = 64-bit
; ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
    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

2. Checking the existance of  C:\Windows\SysWow64 we can dedect the bit level  of windows.
Code: [Select]
; Check if there is C:\Windows\SysWow64 directory:
print chr$("[ 2 ] SysWow64 directory exists?",13,10)
.if fexist("C:\Windows\SysWow64")
print chr$("[ + ] 64-bit",13,10)
.else
print chr$("[ + ] 32-bit",13,10)
.endif
invoke StdOut, chr$(13,10)

3. IsWow64ProcessAPI return value if the OS is running WOW64 or not.
Code: [Select]
; IsWow64ProcessAPI checks our OS runs WOW64:
print cfm$("[ 3 ] Query bitness with IsWow64Process APIs:\n")
xchg ebx, rv(GetProcAddress, rv(GetModuleHandle, "kernel32") , "IsWow64Process")
.if ebx
print "[ + ] IsWow64Process found: retval="
push eax
invoke IsWow64Process, rv(GetCurrentProcess), esp
pop ecx
mov bayrakIsWow64,cl
print str$(ecx),13,10
.if bayrakIsWow64==1
print chr$("[ + ] 64-bit",13,10)
.else
print chr$("[ + ] 32-bit",13,10)
.endif
.else
print "[ + ] IsWow64Process not found", 13, 10, 10
.endif
invoke StdOut, chr$(13,10)

4. Using GetNativeSystemInfo API with SYSTEM_INFO structure we can dedect our "installed operating systems processor type"
Code: [Select]
;05 GetNativeSystemInfo returns info to SYSTEM_INFO structure:
print cfm$("[ 4 ] Query bitness of OS with GetNativeSystemInfo API:\n")
mov ebx, offset sysinf
invoke GetNativeSystemInfo,ebx
cmp [ebx.SYSTEM_INFO.wProcessorArchitecture], PROCESSOR_ARCHITECTURE_AMD64
.if Zero?
print chr$("[ + ] 64-bit",13,10)
.else
print chr$("[ + ] 32-bit",13,10)
.endif

I add my sources; tested positive on vm/rm win10 x64 and vm win7 x86

@jj2007
You had shared 2 macros, but i have used the functions inside the macros in my sources. How can we use these macros inside the code as macros? I got error :/
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: jj2007 on September 13, 2018, 10:25:58 AM
@jj2007
You had shared 2 macros, but i have used the functions inside the macros in my sources. How can we use these macros inside the code as macros? I got error :/

Sorry, tonight my crystal ball is not working properly :(
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: blue_devil on September 13, 2018, 02:45:21 PM
@jj2007
You had shared 2 macros, but i have used the functions inside the macros in my sources. How can we use these macros inside the code as macros? I got error :/

Sorry, tonight my crystal ball is not working properly :(

 ::) :(
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: jj2007 on September 13, 2018, 05:16:58 PM
a) which macros?
b) how did you use them?
c) how do you want to use them?
d) which errors?
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: blue_devil on September 13, 2018, 06:46:55 PM
a) which macros?
b) how did you use them?
c) how do you want to use them?
d) which errors?
@jj sorry to bother you.
Macros are working, i just forgot to put paranthesis  :icon_redface: :(
wrong -> Win64
true -> Win64()
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: felipe on September 19, 2018, 01:01:48 PM
I have do it this in my little free time, i thought is not worthed to put this in a separete thread. Is just another bloated, but maybe effective too, way of get the bitness of the os. The .exe and .asm are attached. Here an explanation for those without the time to see the code:

Basically: 1) Run the systeminfo command from cmd redirecting the output to a .txt file.
                2) Scan the file for the string x32 or x64. This are unique strings in this output.
                3) And that's all folks.  :P

I have tested successfully in just 1 64 bit os (of course a windows one). It will be nice if someone can test it in a 32 bit system too. Ok bye.  :icon14:

Btw this is a 32 bits version, maybe if i have the time i will do it in a 64 bit one.  :icon14:
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: felipe on September 23, 2018, 08:07:13 AM
Here it is the same program that i uploaded above, but this is the 64 bit version (files .asm and .exe attached).  :icon14:
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: Raistlin on September 26, 2018, 10:17:38 PM
Don't we know 32 bit code runs on 64?
Don't we know 32 bit code is currently
faster than 64? Why the double effort?
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: felipe on September 27, 2018, 12:23:25 AM
Raistlin: If you are asking me why two versions of a program (32 and 64 bits) i think is worth the effort if you like to learn... :icon14:
If i had the time, i would learn even the itanium architecture (IA64)... :biggrin:
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: Raistlin on September 27, 2018, 08:39:34 PM
HEY I am all for learning  :t There's just a small
problem with the detection logic, which I wont
share here. PM me please when you have time.
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: felipe on September 28, 2018, 04:42:16 AM
I already pm you Raistlin  :icon14:...but why you don't want to share the error? is a security critical thing?  :shock:
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: Raistlin on September 28, 2018, 03:56:59 PM
No nothing serious  ;) PM'ed you back .... no security issues - don't worry.
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: HSE on September 28, 2018, 11:59:53 PM
is a security critical thing?  :shock:

Take care Felipe  :icon_eek:

A search in most dark servers return this:

Raistlin's ponderings (https://www.youtube.com/watch?v=v-xrnIXQ3iQ)
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: Raistlin on October 08, 2018, 02:44:49 AM
Erm...I am not quite so nefarious.
But thanks for the thought. I have
supplied Felipe with the required
thought processes. Its up to him
to decide to share his outcomes.
No conspiracy theories required  :t
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: felipe on October 08, 2018, 03:46:02 AM
Well the issue in the 64 bit app was that if this app runs in a 32 bit system it will crash...  :exclaim:
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: 2B||!2B on November 06, 2018, 03:43:52 PM
Hi jj2007,

Nice work there.

My version is similar to what fearless pointed out

Code: [Select]
MOV DX, CS
 .if DL == 1Bh
      ;32Bit System
.elseif DL == 23h
      ;64Bit System (WoW)
.else
      ;33h value for 64Bit Native (Exe + System)
.endif
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: rsala on November 07, 2018, 04:49:46 AM
Hi,

Please try the attached file.

Thanks!
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: jj2007 on November 07, 2018, 05:23:32 AM
Windows 7 v6.1 64-bit Service Pack 1

(with next version, please offer option to copy the string to the clipboard ;))
Title: Re: Detect if your Windows version is 32- or 64-bit
Post by: rsala on November 08, 2018, 07:12:37 AM
I will, thanks!
 :t