Recent

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

ASerge

  • Hero Member
  • *****
  • Posts: 1396
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

GetMem

  • Hero Member
  • *****
  • Posts: 3495
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: 8688
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
Most people that want to use threading should learn to patch their jeans first: use a needle.

ASBzone

  • Full Member
  • ***
  • Posts: 241
  • Automation leads to relaxation...
    • BrainWaveCC Utilities
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.0.5 r61666 / FPC v3.2.0-beta-r42593 (via FpcUpDeluxe) -- Windows 64-bit install w/32-bit cross-compile
Primary System: Windows 10 Pro x64, Version 1903 (Build 18362.295)
Other Systems: Windows 10 Pro x64, Version 1809 or greater

440bx

  • Hero Member
  • *****
  • Posts: 1089
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 »
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

rvk

  • Hero Member
  • *****
  • Posts: 3813
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: 1089
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.


using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.