Why my 64bit app runs with 32bit DLLs? [duplicate] - c#

I created a project and compiled it as Any CPU. on x64-Windows. As I have trouble to reference that assembly from my code I checked the runtime and the target-plattform:
As you can see the target plattform is x64 when running on an x64-OS (as mine). I checked DumpBin also:
PE signature found
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
14C machine (x86)
3 number of sections
57A49000 time date stamp Fri Aug 05 15:09:20 2016
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
102 characteristics
Executable
32 bit word machine
However when I run CorFlags it´s giving me x64 as plattform for that assembly:
Version : v4.0.30319
CLR Header: 2.5
PE : PE32
CorFlags : 9
ILONLY : 1
32BIT : 0
Signed : 1
As far as I understand when I chose Any CPU as target platform the OS will chose how to execute the assembly. On an 64bit system it´ll run in 64bit, on 32bit-OS as 32bit respectivly.
So my question is: what version am I actually targetting? 32 or 64bit?

That's entirely normal. AnyCPU means that it can run on any cpu so the machine field in the header cannot be relevant. Having to pick something, it just picks x86. Keeps it compatible with ancient Windows versions like Win98 and Win2k.
The special heroics happen on a 64-bit operating system, the OS loader needs help to creating a 64-bit process from a 32-bit executable, that requires patching internal loader structures. The mscoree.dll "loader-shim" gets that job done as described in the linked post.
So you do not target any particular version. It truly is AnyCPU.

Related

System.BadImageFormatException when compiled using any cpu

When I compile the application using "Any CPU" I am getting System.BadImageFormatException whenever I try to open a connection using Firebird embedded dll (don't ask me why I am still using this legacy DB. not my choice)
Then I thought it must be that the dll only supports 32bit mode. So I tried to compile using x86 and indeed it runs fine this time.
However when I compile using x64 the application still runs fine. This confuses me cause it clearly indicates the dll is able to load in 64bit mode.
I made couple more tests and here are the results:
Any CPU: 64 bit process. System.BadImageFormatException
x86: 32 bit process. Runs fine
x64: 64 bit process. Runs fine
Any CPU (prefer 32bit): 32 bit process. Runs fine
I thought the only magic Any CPU does is that it picks whether to launch the process in 32/64 bit mode during startup. If the application runs fine under strict 64 bit mode then I would expect Any CPU to run fine on the same 64bit machine.
I would prefer to use Any CPU (without prefer 32bit flag) still since it makes the distribution easier.
What could be causing the exception and is there a way to deal with it?
Edit:
So I tried to use reflection to get assembly info and this is the error message I got
Exception calling "GetAssemblyName" with "1" argument(s): "Could not
load file or assembly 'fbembed.dll' or one of its dependencies. The
module was expected to contain an assembly manifest." At line:1 char:1
+ [reflection.assemblyname]::GetAssemblyName("${pwd}\fbembed.dll") | fl
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : BadImageFormatException
After examining the dll's header it turns out that Nuget is the one performing the magic. If I set the target to x86/x64 nuget will include the according version of the dll during compile.
But if I target "Any CPU" nuget will pick the x86 version of the dll. Thus if I try to launch my application in 64 bit mode it will throw BIFE.

C# System.BadImageFormatException for 32bit - 64bit

I'm working with an application that uses 2 library, the first is stored outside of my project under c:\windows\system32 folder and it is used with:
[DllImport("FWLIB32.dll", EntryPoint="cnc_settimeout")]
public static extern short cnc_settimeout( ushort FlibHndl, int a );
The second one is imported in the Project references.
I need to use both of them, but if I config Visual studio to compile it with platform: "Any CPU" (and prefer 32bit) the first works and the second doesn't work, id I set platform x86 the second works but not the first.
In both cases it is thrown System.BadImageFormatException.
How to work with both dll? Is it possibile?
This is the first dll details:
PE details
Date compiled: Thu, July 21, 2011, 10:19:34 PM
Linker version: 6.0
Machine type: Intel 386 or later processors and compatible processors
PE format: PE32
Characteristics: Dynamic-link library
DLL Characteristics: None
Subsystem: The Windows graphical user interface (GUI) subsystem
Min OS: Windows 95
Min OS version: 4.0
Subsystem version: 4.0
File version: 0.0
Manifest: No
Images: No
Icons: No
Dialogs: Unknown (Not implemented)
String tables: Unknown (Not implemented)
Accelerators: Unknown (Not implemented)
Cursors: Unknown (Not implemented)
Menu: Unknown (Not implemented)
More details
designedFor: 32-bit Windows
typeOfFile: DLL
fileVersion: 5.9.0.1
productVersion: 5.9.0.1
Comments: DCompanyName
CompanyName: FANUC CORPORATION
FileDescription: Data Window Library for Win32
FileVersion: 5, 9, 0, 1
InternalName: Fwlib32
LegalCopyright: Copyright (C) 1996-2011 FANUC CORPORATION
LegalTrademarks: #OriginalFilename
OriginalFilename: Fwlib32.dll
PrivateBuild: TProductName
ProductName: FANUC Data Window Library
This is the second one details:
PE details
Date compiled: Fri, December 7, 2012, 9:25:47 AM
Linker version: 10.0
Machine type: x64
PE format: PE32+
Characteristics: Application can handle > 2GB addresses (Large address aware); Dynamic-link library
DLL Characteristics: Image is NX compatible (No eXecute)
Subsystem: The Windows graphical user interface (GUI) subsystem
Min OS: Windows XP 64-Bit Edition / Windows Server 2003 / Windows Server 2003 R2
Min OS version: 5.2
Subsystem version: 5.2
File version: 0.0
Manifest: Yes (406 bytes)
Images: No
Icons: Yes (2 icons)
Dialogs: Unknown (Not implemented)
String tables: Unknown (Not implemented)
Accelerators: Unknown (Not implemented)
Cursors: Unknown (Not implemented)
Menu: Unknown (Not implemented)
More details
designedFor: 32-bit Windows on Windows NT
typeOfFile: DLL
fileVersion: 4.0.0.0
productVersion: 4.0.0.0
CompanyName: Siemens
FileDescription: Rpc Sinumerik Assembly
FileVersion: 4.0.0.0
InternalName: Siemens.Sinumerik.Rpc.dll
LegalCopyright: Copyright (C) 2012
OriginalFilename: RpcSinum.dll
For me are both 32bit... but Why the first one works only with "Any CPU" option?

Identify GDR and LDR SOS.dll and mscordacwks.dll

For the first time I have noticed that one of the mscordacwks DLLs in my collection is different (SVN told me). As I did some research I figured out that there are LDR versions and GDR versions of those DLLs.
For the files in question I noticed that one of them is not digitally signed, but the other one is (by Microsoft luckily).
So now I have the following questions:
If I have an LDR and a GDR version, how do I figure out which one is which?
Are both, GDR and LDR version of the DLL, signed by Microsoft?
Since one of them isn't signed, could someone inject malicious code into mscordacwks.dll which then gets executed on my machine with debugging privileges when I use it in WinDbg?
I'll try to find out where I got the unsigned DLL from. It is quite likely that I downloaded it from some some more or less dubious website when I needed that particular version.
FYI: the VirusTotal analysis did not reveal any viruses.
Thanks to the help in the comments I can summarize:
Digital signatures
According to Hans Passant, all Microsoft DLLs should be signed, so we have to be careful with unsigned ones.
Unfortunately this statement is not 100% true which I verified for the Mscordacwks.dll 2.0.50727.312 and SOS.dll 2.0.50727.312. Microsoft has shipped that version with Windows Vista. I tried that by installing Windows Vista from scratch.
This is the output of sigcheck -h on the DLL which come with Windows Vista:
Verified: Unsigned
Link date: 09:05 19.10.2006
Publisher: Microsoft Corporation
Description: Microsoft .NET External Data Access Support
Product: Microsoft« .NET Framework
Prod version: 2.0.50727.312
File version: 2.0.50727.312 (rtmLHS.050727-3100)
MachineType: 32-bit
MD5: 9252D83D169E84A442BB154A79AC2189
SHA1: 63464F337295D689384BAA514F260C54D06291C6
PESHA1: 99D57B38C554FFD4BEC6E6C2FAD7F77B980CB47B
PE256: EF387EF84028497D5F7D231ED3A6F5FB05C02D96BD3B0E470C6BEBFAD6942AC8
SHA256: 5ADB79D39FC8401CB9542B571EEEC82CAFCADAE2F26997C789E14EC8E9635C08
And also see the detailed information from VirusTotal which has the same hash codes. Please note the fact that the website is a bit misleading by listing "Authenticode signature block". In fact that is just the version information of the file. The most important line labelled "Signature verification: Signed file, verified signature" is missing for this DLL.
This is how it should look like if the file was really signed:
The output of sigcheck and Windows Explorer also show that that the file is not signed:
Verified: Unsigned
Link date: 09:05 19.10.2006
Publisher: Microsoft Corporation
Description: Microsoft .NET External Data Access Support
Product: Microsoft« .NET Framework
Prod version: 2.0.50727.312
File version: 2.0.50727.312 (rtmLHS.050727-3100)
MachineType: 32-bit
Screenshot of Windows Explorer where the file does not have a digital signatures tab:
At the end of the VirusTotal report, you find a statement by NIST (National Institute of Standards and Technology) which says that the file is delivered with Windows Vista Ultimate and that it seems to be safe. This is the website I am being led to after I uploaded an unsigned version.
Distinguishing GDR and LDR versions
The SysInternals sigcheck tool displays more information on the version number than Windows Explorer. If it includes "GDR", it is a GDR version. If it does not contain GDR, it is an LDR version.
To get a string for comparison in C#, you can use the following code:
var versionInfo = FileVersionInfo.GetVersionInfo(fullFileName);
var fileVersion = versionInfo.FileVersion;
Affected versions
I checked all my DLLs for signatures and found more unsigned DLLs than expected. However, most files have already been scanned on VirusTotal before. However, none of these versions has a NIST entry.
x86 SOS 1.1.4322.2032 VirusTotal
x86 SOS 2.0.50767.312 VirusTotal
x86 Mscordacwks 2.0.50767.312 VirusTotal
x86 Mscordacwks 2.0.50767.3603 VirusTotal
x86 Mscordacwks 2.0.50727.3623 VirusTotal
x64 SOS 2.0.50767.3074 VirusTotal
x64 Mscordacwks 4.0.30319.1008 VirusTotal
Malicious code injection
As stated by Jeroen Mostert, the DLLMain entry point will be executed, therefore there is the possibility of malicious code injection.

CUDAfy.NET giving Win32Exception: The system cannot find the file specified

I've added a reference to the CUDAfy.NET library via NuGet.
<package id="CUDAfy.NET" version="1.12.4695.21111" targetFramework="net45" />
When I run my program, I hit a Win32Exception:
The system cannot find the file specified
This happens on the first actual line of the program:
CudafyModule km = CudafyTranslator.Cudafy();
There's no indication from the exception object as to what file they're attempting to load.
How can I get past this problem?
EDIT
I see the same exception when running the bundled examples from the Codeplex download in VS2010 using .NET 4.0.
The strack trace is:
at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
at Cudafy.CudafyModule.Compile(eGPUCompiler mode, Boolean deleteGeneratedCode)
at Cudafy.Translator.CudafyTranslator.Cudafy(ePlatform platform, eArchitecture arch, Version cudaVersion, Boolean compile, Type[] types)
at Cudafy.Translator.CudafyTranslator.Cudafy(ePlatform platform, eArchitecture arch, Type[] types)
at Cudafy.Translator.CudafyTranslator.Cudafy()
Setting VS to break on thrown exceptions shows the ProcessStartInfo object at the top of the stack in the locals pane of the debugger.
The relevant properties are:
FileName = nvcc
Arguments = -m64 -arch=sm_12 "c:\<path>\CUDAFYSOURCETEMP.cu" -o "c:\<path>\CUDAFYSOURCETEMP.ptx" --ptx
Some information from this article explains that the CUDA Toolkit must be installed. Fair enough.
Ensure that the C++ compiler (cl.exe) is on the search path. This set-up of NVCC is actually the toughest stage of the whole process, so please persevere. Read any errors you get carefully - most likely they are related to not finding cl.exe or not having either 32-bit or 64-bit CUDA Toolkit.
That article discusses version 4 of the toolkit, but version 5 is available now and supported since CUDAfy v1.1.
Download from https://developer.nvidia.com/cuda-downloads
Note that the 64-bit version of the CUDA Toolkit 5.0 is a 942 MB download. If you install everything you'll need an additional 2815 MB. The toolkit alone requires 928 MB.
EDIT After installing the CUDA Toolkit 5.0, the program failed with a CudafyCompileException at the same source line:
Compilation error: nvcc : fatal error : Cannot find compiler 'cl.exe' in PATH
Searching my system drive:
C:\>dir /s cl.exe
This shows many different versions of the compiler/linker, both from VS 10.0 and 11.0. Apparently only cl.exe versions 9 and 10 are supported, so I opted for the VS10.0 amd64 version, I included the following in my PATH environment variable:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\amd64
Your path may be different, depending upon your CPU. I recommend running the search to see your options.
Note that you will have to restart VS after changing the PATH environment variable if you already have it open.
After taking these steps, my basic program ran successfully.
This may also happen if you had at some point installed CUDA Toolkit v7.5, but realized that the most recent version of CUDAfy supports CUDA 7.0.
On uninstalling CUDA 7.5 from the control panel, some files/folders may still remain. You should delete these manually. You may use CUDAfyViewer to see which version of CUDA Toolkit is being accessed.

mono not load *.so shared library on server-pc

app was complied on windows7, .net4.0
i put the dll: TECIT.TFORMer.dll in the app file
test-pc,i386:
server-pc,amd64:
on test-pc,i debug the app, and got the resut, log:
but on server-pc, throw exception, log:
why test-pc app :DllImport attempting to load: 'libTFORMer6.so'
but server-pc app never show the log?
thanks.
If your mono is 64 bit, you can not load a 32 bit library into it.
While the OS usually supports running 32 bit code, it applies to the whole process.
So you should either make a 64 bit library or run 32 bit mono.
Disclaimer: your question wasn't quite clear whether you are trying to use the same library on both systems.

Categories

Resources