1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

How to? File 64 or 32Bit?

Discussion in 'Support' started by MrZebulon, May 12, 2014.

  1. MrZebulon

    Joined:
    May 12, 2014
    Messages:
    3
    Likes Received:
    0
    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
     
  2. thedave

    Joined:
    Nov 13, 2008
    Messages:
    253
    Likes Received:
    2
    Are you talking about executable files?
     
  3. MrZebulon

    Joined:
    May 12, 2014
    Messages:
    3
    Likes Received:
    0
    Hi Dave,
    Yes, exe and dll files.
     
  4. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,935
    Likes Received:
    30
    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
    
     
  5. MrZebulon

    Joined:
    May 12, 2014
    Messages:
    3
    Likes Received:
    0
    Hi Vince.
    Thank you.
    That helped me for the beginning to have a start.
    Have a nice evening.
     
  6. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,935
    Likes Received:
    30
    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. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,935
    Likes Received:
    30
    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:\>
     
  8. keithg1964

    Joined:
    Jul 11, 2008
    Messages:
    49
    Likes Received:
    1
    I am surprised that exetype does not return this info.

    @EXETYPE[filename]:Returns the application type for an executable file:

    Application type
    0 Unknown
    1 DOS app
    2 PIF file
    3 Win16
    4 Win 3.x VxD
    5 OS/2
    6 Win32 GUI
    7 Win32 console
    8 Posix
     
  9. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    Submitted request to report other types in FEEDBACK.
     
  10. keithg1964

    Joined:
    Jul 11, 2008
    Messages:
    49
    Likes Received:
    1
    Thanks I should have done that Steve.
     
  11. vefatica

    Joined:
    May 20, 2008
    Messages:
    7,935
    Likes Received:
    30
    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. Joe Caverly

    Joined:
    Aug 28, 2009
    Messages:
    676
    Likes Received:
    8
    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. Joe Caverly

    Joined:
    Aug 28, 2009
    Messages:
    676
    Likes Received:
    8
    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. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    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.
     
  15. TEA-Time

    Joined:
    Jun 2, 2008
    Messages:
    282
    Likes Received:
    1
    The word "GetBinaryType" in his first sentence is clickable (as is mine).
     
  16. Joe Caverly

    Joined:
    Aug 28, 2009
    Messages:
    676
    Likes Received:
    8
    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
     
  17. Charles Dye

    Charles Dye Super Moderator
    Staff Member

    Joined:
    May 20, 2008
    Messages:
    3,300
    Likes Received:
    39
    Should it work on .DLL files? Here, ECHO %@32BIT[GetBinaryType.dll] returns an empty string.
     
  18. Joe Caverly

    Joined:
    Aug 28, 2009
    Messages:
    676
    Likes Received:
    8
    Nope, the GetBinaryType WinAPI only works on EXE files, just as @EXETYPE only works on EXEs.

    Joe
     
  19. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    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.
     
  20. Charles Dye

    Charles Dye Super Moderator
    Staff Member

    Joined:
    May 20, 2008
    Messages:
    3,300
    Likes Received:
    39
    Oh, well.
     
  21. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    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 Caverly

    Joined:
    Aug 28, 2009
    Messages:
    676
    Likes Received:
    8
    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. Steve Fabian

    Joined:
    May 20, 2008
    Messages:
    3,520
    Likes Received:
    4
    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.
     
  24. tcruver

    Joined:
    Apr 30, 2014
    Messages:
    9
    Likes Received:
    0
  25. Joe Caverly

    Joined:
    Aug 28, 2009
    Messages:
    676
    Likes Received:
    8

Share This Page