How to? File 64 or 32Bit?

  • This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.
May 12, 2014
3
0
#1
Hello All,
I am new to TCC.
Is it possible to determine if a file (many files) is a 32- or 64bit version?
Many thanks in advance.

Kind regards
Roland
 
#4
Hello All,
I am new to TCC.
Is it possible to determine if a file (many files) is a 32- or 64bit version?
Many thanks in advance.

Kind regards
Roland
Files, in general, don't have such a property. To determine if a DLL or EXE is built for a particular architecture, Google will turn up a few third party apps (and there's Microsoft's DUMPBIN.EXE).

With TCC, you can read the 75th and 76th bytes of the file (I'm not confident that's foolproof). If they are 0x014C, it's 32-bit. If they're 0x0200, it's 64-bit. I can't test with a 64-bit DLL or EXE, but here's a little BTM that gets it right for a 32-bit DLL and EXE.
Code:
v:\> type 32or64.btm
setlocal
set hFile=%@fileopen[%1,read,b]
set ptr=%@fileseek[%hFile,74,0]
set data=%@filereadb[%hFile,2]
set hFile=%@fileclose[%hFile]
echo 0x%@format[02,%@convert[10,16,%@word[0,%data]]]%@format[02,%@convert[10,16,%@word[1,%data]]]

v:\> 32or64.btm g:\tc16\tcc.exe
0x014C

v:\> 32or64.btm g:\tc16\takecmd.dll
0x014C
 
#6
Hi Vince.
Thank you.
That helped me for the beginning to have a start.
Have a nice evening.
Actually I had it wrong. That gave 0x014C for both. I suppose that describes the machine on which it was built. You must dig a little deeper. Here's one that I think gets it right for DLLs but not for EXEs. I'll keep working on it.
Code:
v:\> type 32or64.btm
setlocal
set hFile=%@fileopen[%1,read,b]
set ptr=%@fileseek[%hFile,60,0]
set data=%@filereadb[%hFile,2]
set peoffset=%@eval[%@word[0,%data] + 16 * %@word[1,%data] + 4]
set prt=%@fileseek[%hFile,%peoffset,0]
set data=%@filereadb[%hFile,2]
set hFile=%@fileclose[%hFile]
echo 0x%@format[02,%@convert[10,16,%@word[0,%data]]]%@format[02,%@convert[10,16,
%@word[1,%data]]]

v:\> 32or64.btm p:\4Utils\release\4utils.dll
0x4C01

v:\> 32or64.btm p:\4Utils\x64\Release\4Utils64.dll
0x6486
 
#7
It needed one little change. This looks better: 0x4C01 is 32-bit. 0x6486 is 64-bit.
Code:
v:\> type 32or64.btm
setlocal
set hFile=%@fileopen[%1,r,b]

REM location of offset of PE header
set ptr=%@fileseek[%hFile,60,0]

REM get offset of PE header
set data=%@filereadb[%hFile,2]

REM go 4 bytes beyond beginning of PE header
set dataoffset=%@eval[%@word[0,%data] + 256 * %@word[1,%data] + 4]
set ptr=%@fileseek[%hFile,%dataoffset,0]

set data=%@filereadb[%hFile,2]
set hFile=%@fileclose[%hFile]
echo 0x%@format[02,%@convert[10,16,%@word[0,%data]]]%@format[02,%@convert[10,16,%@word[1,%data]]]

v:\> 32or64.btm p:\4Utils\release\4utils.dll
0x4C01

v:\> 32or64.btm p:\4Utils\x64\Release\4Utils64.dll
0x6486

v:\> 32or64.btm g:\tc16\tcc.exe
0x4C01

v:\>
 
#11
Here's a more elaborate BTM that also gives the subsystem ... first some examples, then the code.
Code:
v:\> 32or64.btm p:\4Utils\x64\Release\4Utils64.dll
64-bit GUI

v:\> 32or64.btm p:\4Utils\release\4utils.dll
32-bit GUI

v:\> 32or64.btm g:\tc16\tcc.exe
32-bit CUI

v:\> 32or64.btm s:\dmview.ocx
32-bit GUI

v:\> type 32or64.btm
setlocal
set result=N/A
set ext=%@ext[%1]
if "%ext" NE "EXE" .and. "%ext" NE "DLL" .and. "%ext" NE "OCX" goto done

set hFile=%@fileopen[%1,r,b]
if %hFile EQ -1 goto done

REM 4-byte offset of PE header is at file offset 60
set ptr=%@fileseek[%hFile,60,0]

REM get offset of PE header
set data=%@filereadb[%hFile,4]

REM go 4 bytes beyond the beginning of the PE signature
REM and read the 2-byte target architecture
set dataoffset=%@eval[%@word[0,%data] + 256 * %@word[1,%data] + 256**2 * %@word[2,%data] + 256**3 * %@word[3,%data] + 4]
set ptr=%@fileseek[%hFile,%dataoffset,0]
set data=%@trim[%@filereadb[%hFile,2]]

iff "%data" EQ "100 134" then
  set result=64-bit
elseiff "%data" EQ "76 1" then
  set result=32-bit
endiff

if "%result" EQ "N/A" goto close

REM go to the subsystem and read it (2 bytes)
REM 18 bytes to the end of the NT header
REM and 68 bytes into the optional header
set ptr=%@fileseek[%hFile,86,1]
set subsystem=%@trim[%@filereadb[%hFile,2]]

REM there are other (obscure) subsystem alternatives
switch %@word[0,%subsystem]
  case 1
  set ss=Native
  case 2
  set ss=GUI
  case 3
  set ss=CUI
  default
  set ss=Unknown
endswitch

set result=%result %ss

:close
set hFile=%@fileclose[%hFile]
:done
echo %result
 
#12
Hello All,
I am new to TCC.
Is it possible to determine if a file (many files) is a 32- or 64bit version?
Many thanks in advance.

Kind regards
Roland
If you have Cygwin installed on your system, you can wrap the file command in an alias thus;
Code:
file=c:\cygwin\bin\file.exe
As an example;
Code:
file tcc.exe
returns;
Code:
tcc.exe: PE32 executable (console) Intel 80386, for MS Windows
Joe
 
#13
Hello All,
I am new to TCC.
Is it possible to determine if a file (many files) is a 32- or 64bit version?
Many thanks in advance.

Kind regards
Roland
Here's a little plugin I wrote called GetBinaryType, which is simply a wrapper for the GetBinaryType WinAPI.

This is a test batch file that I wrote to demonstrate it;
Code:
::----------------------------------------------------::
:: TEST.BTM  ::
:: Test program for the GetBinaryType plugin  ::
::----------------------------------------------------::
@setlocal
@echo off
iff %# eq 0 then
  echo USAGE: test.btm thefile.exe
  quit
endiff
iff not exist %1 then
  echo %1 does not exist
  quit
endiff
if not plugin GetBinaryType plugin /l GetBinaryType
echo 32BIT %@32bit[%1]
echo DOS  %@dos[%1]
echo WOW  %@wow[%1]
echo PIF  %@pif[%1]
echo POSIX %@posix[%1]
echo OS216 %@os216[%1]
echo 64BIT %@64bit[%1]
if plugin GetBinaryType plugin /u GetBinaryType
endlocal
This plugin is similar to the @EXETYPE Variable function, which is not available in TCC/LE.

Where as @EXETYPE returns a code indicating if an executable file is a certain application type, I chose to create several variable functions that each test for a specific application type.

I would appreciate it if folks would test this plugin on their system, and let me know how it works.

Joe
 
#14
Here's a little plugin I wrote called GetBinaryType, which is simply a wrapper for the GetBinaryType WinAPI.

This is a test batch file that I wrote to demonstrate it;
Code:
::----------------------------------------------------::
:: TEST.BTM  ::
:: Test program for the GetBinaryType plugin  ::
::----------------------------------------------------::
@setlocal
@echo off
iff %# eq 0 then
  echo USAGE: test.btm thefile.exe
  quit
endiff
iff not exist %1 then
  echo %1 does not exist
  quit
endiff
if not plugin GetBinaryType plugin /l GetBinaryType
echo 32BIT %@32bit[%1]
echo DOS  %@dos[%1]
echo WOW  %@wow[%1]
echo PIF  %@pif[%1]
echo POSIX %@posix[%1]
echo OS216 %@os216[%1]
echo 64BIT %@64bit[%1]
if plugin GetBinaryType plugin /u GetBinaryType
endlocal
This plugin is similar to the @EXETYPE Variable function, which is not available in TCC/LE.

Where as @EXETYPE returns a code indicating if an executable file is a certain application type, I chose to create several variable functions that each test for a specific application type.

I would appreciate it if folks would test this plugin on their system, and let me know how it works.

Joe
1/ Since it is a batch file, I would accept multiple files for evaluation. No parameter would be interpreted as all files.
2/ Having a multitude of plugin functions is your favorite style, but why do you test each and every possible type one after another for the file? Do you expect the WinAPI to report more than one to be true? Though I am not familiar with the API documentation, I doubt it can happen. Or do you had a different concept?
3/ You ought to provide the URL to find the plugins in your post.
 
#16
1/ Since it is a batch file, I would accept multiple files for evaluation. No parameter would be interpreted as all files.
2/ Having a multitude of plugin functions is your favorite style, but why do you test each and every possible type one after another for the file? Do you expect the WinAPI to report more than one to be true? Though I am not familiar with the API documentation, I doubt it can happen. Or do you had a different concept?
3/ You ought to provide the URL to find the plugins in your post.
1/ It is just a generic test program, to show what the variable functions do.

2/ It is just a generic test program, to show what the variable functions do. Only one of the variable functions will return 1, depending on the EXE being tested. The link is in my original post. Place your mouse over the GetBinaryType WinAPI in the first sentence of my post for the link.

3/ The link is in my original post. Place your mouse over the first GetBinaryType for the link.

Joe
 
#19
My point is GetBinaryType is not a link to the plugin, it is a link to another copy the file already in the post, which adds only one thing, the link to the plugin. The GetBinaryType WinAPI is also a link, to the MS code. BTW, even back at 4nt5 and continuing to this day a different API must be used for @EXETYPE, because it has more return choices then GetBinaryType. Nevertheless, I congratulate you on rolling your own function which Rex had stripped from LE.
 
#21
Nope, the GetBinaryType WinAPI only works on EXE files, just as @EXETYPE only works on EXEs.
There is a good question what kind of files qualify as executable, which is not identical with .EXE files (except as defined in the MS documentation of the GetBinaryType WinAPI. In particular, @exetype reports code 6, Windows GUI, for UIstuff.dll, and code 7, Windows console, for 4console.dll, consistently with the documentation. PIFs and VxDs are also not .EXE files, but all these are executable.

Joe, you may be perfectly happy with your new plug in that has a different set of classification. because it matches you requirements better. Otherwise you might to search more API entries. I think that Rex might have combined the results of multiple API emtries.
 
#22
Joe, you may be perfectly happy with your new plug in that has a different set of classification. because it matches you requirements better. Otherwise you might to search more API entries. I think that Rex might have combined the results of multiple API emtries.
Vince's @EXEBITS is similar, and does more, than the GetBinaryType API.

I had read the MSKB Article "How To Determine whether an Application is Console or GUI" which seems to go beyond what the GetBinaryType API does, but again, only for EXE files.

@EXEBITS also checks EXEs, DLLs, and OCXs.

It showed me that a DLL file can be a 32-bit CUI, something which I never realized before.

The SYSUTILS and GETBINARYTYPE plugins work on TCC/LE, which fills my need for now.

Joe
 
#23
It seems that there are several, mutually orthogonal classifications, which may be detected (though not always). At different occasions one may be interested in different one of thses, as the OP was.

Word size: currently supported 32b and 64b; obsolete (but still developed for embedded systems): 8b and 16b; likely future: 128b.

User interface:
graphical, textual, none (or internal).

Usage: compiled and linked program, dynamic link library, device driver (including VxD), access (shortcut) to program, etc.