Recent

Author Topic: [SOLVED] How to tell if dll is 32-bit or 64-bit  (Read 28489 times)

ASerge

  • Hero Member
  • *****
  • Posts: 2222
Re: [SOLVED] How to tell if dll is 32-bit or 64-bit
« Reply #15 on: May 20, 2017, 01:19:49 am »
Test
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$APPTYPE CONSOLE}
  3.  
  4. // Code above paste here
  5.  
  6. function PEBitnessAsText(V: TPEBitness): string;
  7. const
  8.   CValue: array [TPEBitness] of string = (
  9.     'Unknown', '16 bit', '32 bit', '64 bit');
  10. begin
  11.   Result := CValue[V];
  12. end;
  13.  
  14. procedure WritelnBitness(const FileName: WideString);
  15. begin
  16.   Writeln(FileName, ' is ', PEBitnessAsText(GetPEBitness(FileName)));
  17. end;
  18.  
  19. const
  20.   CDlls: array [1..5] of WideString = (
  21.     'c:\Windows\SysWOW64\netmsg.dll',
  22.     'c:\Windows\System32\netmsg.dll',
  23.     'c:\Windows\Sysnative\netmsg.dll',
  24.     'c:\Windows\twain.dll',
  25.     'c:\Windows\twain_32.dll');
  26. var
  27.   i: Integer;
  28. begin
  29.   for i := Low(CDlls) to High(CDlls) do
  30.     WritelnBitness(CDlls[i]);
  31.   Readln;
  32. end.

Result with 64 compiler:
c:\Windows\SysWOW64\netmsg.dll is 32 bit
c:\Windows\System32\netmsg.dll is 64 bit
c:\Windows\Sysnative\netmsg.dll is Unknown
c:\Windows\twain.dll is 16 bit
c:\Windows\twain_32.dll is 32 bit

Result with 32 compiler:
c:\Windows\SysWOW64\netmsg.dll is 32 bit
c:\Windows\System32\netmsg.dll is 32 bit
c:\Windows\Sysnative\netmsg.dll is 64 bit
c:\Windows\twain.dll is 16 bit
c:\Windows\twain_32.dll is 32 bit

balazsszekely

  • Guest
Re: [SOLVED] How to tell if dll is 32-bit or 64-bit
« Reply #16 on: May 20, 2017, 08:09:54 am »
Quote
@Zoran
I'm asking because in the first version (see this post), there was a protective block, and I'm affraid that it was maybe inserted when the function returned 16-bit when it was not a valid 16-bit dll (I don't know, but it just looks like that...).
No, that was a logical error. My original code would fail to detect a 16 bit PE as you correctly pointed out in one of your previous post. I don't think it's a way to detect a corrupted 16/32/64 PE other then checking if a valid  IMAGE_DOS_SIGNATURE,  IMAGE_NT_SIGNATURE, etc... exist. I meant PE_UNKNOWN for special cases when the path to file is invalid or the memory map could not be crated or something else.

Quote
@ASerge
Multiple CloseHandle calls can be excluded.
Yes, your code is more compact, however I prefer a slightly verbose approach. It's much easier this way  to figure out what the code does at a later time. For example instead of:
Code: Pascal  [Select][+][-]
  1. if (Something) then
  2.   if (SomethingElse) then
  3.     DoThis
  4.   else
  5.     DoThat;
I always do:
Code: Pascal  [Select][+][-]
  1. if (Something) then
  2. begin
  3.   if (SomethingElse) then
  4.     DoThis
  5.   else
  6.     DoThat;
  7. end;
Which is code redundancy, but visually is more appealing to me, but I guess is just a personal preference.
« Last Edit: May 20, 2017, 08:12:46 am by GetMem »

Thaddy

  • Hero Member
  • *****
  • Posts: 14201
  • Probably until I exterminate Putin.
Re: [SOLVED] How to tell if dll is 32-bit or 64-bit
« Reply #17 on: May 20, 2017, 09:10:44 am »
That's why I like editors with a line length of at least 1024. So I definitely know that my Pascal code intended to have a linebreak and not white  :o 8-) space, but I guess is just a personal preference.  >:( ;D
Specialize a type, not a var.

ASBzone

  • Hero Member
  • *****
  • Posts: 678
  • Automation leads to relaxation...
    • Free Console Utilities for Windows (and a few for Linux) from BrainWaveCC
Re: [SOLVED] How to tell if dll is 32-bit or 64-bit
« Reply #18 on: February 07, 2019, 02:16:15 am »
Test

Result with 64 compiler:
c:\Windows\SysWOW64\netmsg.dll is 32 bit
c:\Windows\System32\netmsg.dll is 64 bit
c:\Windows\Sysnative\netmsg.dll is Unknown
c:\Windows\twain.dll is 16 bit
c:\Windows\twain_32.dll is 32 bit

Result with 32 compiler:
c:\Windows\SysWOW64\netmsg.dll is 32 bit
c:\Windows\System32\netmsg.dll is 32 bit
c:\Windows\Sysnative\netmsg.dll is 64 bit
c:\Windows\twain.dll is 16 bit
c:\Windows\twain_32.dll is 32 bit


Thanks again for this routine, ASerge.  It has come in very handy.
-ASB: https://www.BrainWaveCC.com/

Lazarus v2.2.7-ada7a90186 / FPC v3.2.3-706-gaadb53e72c
(Windows 64-bit install w/Win32 and Linux/Arm cross-compiles via FpcUpDeluxe on both instances)

My Systems: Windows 10/11 Pro x64 (Current)

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: [SOLVED] How to tell if dll is 32-bit or 64-bit
« Reply #19 on: February 07, 2019, 04:27:10 am »
My original code would fail to detect a 16 bit PE as you correctly pointed out in one of your previous post.
just FYI, there is no such thing as a 16bit PE. 

twain.dll is 16bit but, it is not a PE file.  It is an NE file. 

Also,

In a PE file, the first DWORD of the IMAGE_NT_HEADERS is "PE00" (in string form - $00004550 in binary form).  In an NE file, at the same location, there is a WORD (not a dword) with the signature "NE".  See attached screenshot for a "dump" of twain.dll's header.

It's "risky" to conclude the DLL is 16 bit without checking that its signature is "NE".

It would probably be wise too to ensure that
Code: Pascal  [Select][+][-]
  1. PINTH := PImageNtHeaders(PAnsiChar(PMapView) + PIDH^._lfanew);
is readable before dereferencing it just in case the dll is corrupted.  The same applies to PIDH (after all, if the dll is corrupted, it could have a file size of zero.)

The magic value "IMAGE_ROM_OPTIONAL_HDR_MAGIC  0x107" is known/valid.  For that value the code will return pebUnknown, which is reasonable since it is quite unlikely that an application would want to load such a file but, strictly speaking, it is not "unknown".

The above comments are on sale for $0.02 ;)

ETA:

@Serge:

Do you know why the result is different for c:\Windows\Sysnative\netmsg.dll ?  the 64bit version says "unknown" and the 32bit version says 64 bit.  Do you know if Windows is playing some kind of trick on 32bit executables when they look at files in the Sysnative directory or is there some other reason for the difference ?
« Last Edit: February 07, 2019, 04:36:18 am by 440bx »
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

rvk

  • Hero Member
  • *****
  • Posts: 6110
Re: [SOLVED] How to tell if dll is 32-bit or 64-bit
« Reply #20 on: February 07, 2019, 06:30:56 am »
Do you know why the result is different for c:\Windows\Sysnative\netmsg.dll ?  the 64bit version says "unknown" and the 32bit version says 64 bit.  Do you know if Windows is playing some kind of trick on 32bit executables when they look at files in the Sysnative directory or is there some other reason for the difference ?
The Sysnative doesn't really exist. It's a redirection which is only available in 32 bit processes. So not available in 64 bit.

Also see http://www.samlogic.net/articles/sysnative-folder-64-bit-windows.htm for an explanation.

And
Quote
Note that 64-bit applications cannot use the Sysnative alias as it is a virtual directory not a real one.
https://docs.microsoft.com/nl-nl/windows/desktop/WinProg64/file-system-redirector
« Last Edit: February 07, 2019, 06:36:21 am by rvk »

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: [SOLVED] How to tell if dll is 32-bit or 64-bit
« Reply #21 on: February 07, 2019, 08:25:31 am »
The Sysnative doesn't really exist. It's a redirection which is only available in 32 bit processes. So not available in 64 bit.
Thank you.    :)

I had read the documentation about file system redirection but, I did not encounter a reference to "sysnative" unitl now.  Good to know the tricks MS has pulled out of its sleeve and thrown in the binary bucket.


(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018