.Net DLL vs C++ DLL - c++

How to differentiate between .NET DLL and C++ dll without looking at the code. Can we identify it by looking at the export table or other section of DLL after looking into DLL from any PE file explorer?

You might be able to use corflags
For a .NET c# DLL I get
Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 4.0.30319.1
Copyright (c) Microsoft Corporation. All rights reserved.
Version : v4.0.30319
CLR Header: 2.5
PE : PE32
CorFlags : 1
ILONLY : 1
32BIT : 0
Signed : 0
For a C++ DLL I get
corflags : error CF008 : The specified file does not have a valid managed header
**** UPDATE ****
I might have misunderstood the question. This is a good SO question on a similar problem. How can I test a Windows DLL file to determine if it is 32 bit or 64 bit?

As a matter of fact, this is clearly indicated by looking at the Image file and is documented by the Portable Executable format specification. Should the Directory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR] be present (not EMPTY), the image is Managed (.NET) otherwise the image is unmanaged.

Related

C++/CLI targetting .NET Core 3.1

.NET Core 3.1 added support for C++/CLI (Announcing .NET Core 3.1). The official announcement lists two new project templates, CLR Class Library (.NET Core) and CLR Empty Project (.NET Core), which we can indeed find and use.
However, there is no additional information about supporting technologies such as WPF or Windows Forms. In a blog posts in September, Microsoft said:
we are committed to supporting C++/CLI for .NET Core to enable easy
interop between C++ codebases and .NET technologies such as WPF and
Windows Forms. This support isn’t going to be ready when .NET Core 3.0
first ships, but it will be available in .NET Core 3.1 which ships
with Visual Studio 2019 16.4
Using Visual Studio 2019 16.4.x and targeting .NET Core 3.1, I have tried to create a demo WinForms app using C++/CLI. However, it does not work.
First of all, C++/CLI projects targeting .NET Core must be DLLs:
error NETSDK1116: C++/CLI projects targeting .NET Core must be dynamic
libraries.
So I tried keeping the Win Forms code in a C++/CLI DLL compiled with /clr:netcore and running it from a native app. However, I get a runtime exception:
Unhandled exception. System.BadImageFormatException: Could not load
file or assembly 'System.Windows.Forms, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089'. An attempt was made
to load a program with an incorrect format. File name:
'System.Windows.Forms, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089' ---> System.BadImageFormatException:
An attempt was made to load a program with an incorrect format.
(0x8007000B)
I have referenced in the C++/CLI project the System.Windows.Forms.dll from c:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.0\, which is the location of the Microsoft.WindowsDesktop.App 3.1.0 runtime.
Is this supposed to work and I'm not doing something right?
I had similar issue with my simple sample of .NET Core C# executable using the C++/CLI (managed C++) .Net Core DLL. Eventually figured out that I needed to explicitly set my C# executable target from Any CPU to x64. Most of the time it comes down to 32 bit / 64 bit mismatch.
I found this document on the microsoft's website.
It explains how to do it, and is accompanied by a github repo you can easily clone and try out yourself:
https://devblogs.microsoft.com/cppblog/porting-a-c-cli-project-to-net-core/

Inexplicable error 193 with LoadLibrary of a C++ DLL using \clr

We have an user interface developped in C++ using Boost 1.54.0 and QT 4.8.6.
This interface can call computation module. Each module must implement a (non pure) abstract class and be linked to a given .lib generated during interface compilation. After launching the interface, we indicate the path of the module dll which is loaded using QLibrary.
Everything worked perfectly with native C++ module but recently we started developping new modules using .NET 3.5 (C#). We want the interface can call this module so we decided to create an intermediate c++ project using \clr : this project implements the abstract class and can call managed .NET code thanks to \clr mode.
Now we have a big problem : we cannot achieve to load correctly the intermediate C++ problem. We tried with the kernel32 method LoadLibrary and we obtained an error code 193 (ERROR_BAD_EXE_FORMAT). It is very surprising because all the projects are compiled for Win32/x86 and the computer is using a Windows Vista 32 bits.
Everything seems normal with dependancy walker :
We used dumpbin but everything seemed normal :
Microsoft (R) COFF/PE Dumper Version 9.00.30729.01 Copyright (C)
Microsoft Corporation. All rights reserved.
Dump of file Lien.dll
PE signature found
File Type: DLL
FILE HEADER VALUES
14C machine (x86)
6 number of sections
53CF72B5 time date stamp Wed Jul 23 10:30:45 2014
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
2102 characteristics
Executable
32 bit word machine
DLL
Thank you for the link Patrice Pezillier.
The issue was resolved by using your link : boost was the culprit.

MSI - Conditionally register DLL

I'm working on a .NET profiler (my project output is a DLL). I have built 2 DLLs (written in c++) : one will be loaded by x86 .NET processes and the other by x64 ones. I want to generate a single MSI (targetting x86 patforms) that checks whether the OS is 64bits or 32bits. and then registers the correct DLL i.e :
- Project output : - the_x64.DLL
- the_x86.DLL
- A single MSI that targets x86 machines : contains the 2 DLLs
- if the OS is 64 bits then both of the DLLs are registered
- if the OS is 32 bits then only the x86 dll is registered
Is that possible?
The MSI platform does not support mixed 32/64 bit installers. There are hacks to create 'hybrid' MSI's but it's not officially supported. The approach recommended by Microsoft is to create 2 or more MSI's ( common, 32bit provider, 64bit provider ) and then use a bootstrapper such as WiX Burn or InstallShield Suite Installers to provide a single install experience to the end user.

SidBySide: 3rd Party Dll refers to two versions of MSVCR80.DLL

We include a 3rd Party lib+DLL that recently causes a lot of trouble on installations. Using dependencywalker, we found that the dll itself refers to two different Versions of
MSVCR80.DLL:
Version 8.0.50727.4053 and
Version 8.0.50727.42
alt text http://img101.imageshack.us/img101/1734/dependencywalk2.jpg
In MOST cases installation makes no problems, even if we distribute none of both versions. But in a number of cases our installation just does not start. We then find messages in the windows system event log from the SideBySide manger: "Version of DLL does not match". In most cases again this problem can be resolved, by installing the .NET framework (although we do not use this). But now we have a case where this does not help.
I know that a solution would be, to install both versions as a shared assembly, but that seems not to be easy, and besides that i would prefer a much simpler solution. Does anybody know a workaround?
Can i somehow use only one version of the Dll?
EDIT:
I now tried cristians advice:
D:\Develop\LEADTOOLS15\patch_maifest>mt.exe -inputresource:ltkrn15u.dll;#1 -out:old.manifest
Microsoft (R) Manifest Tool version 5.2.3790.2075
Copyright (c) Microsoft Corporation 2005.
All rights reserved.
mt.exe : general error c101008c: Failed to read the manifest from the resource of file "ltkrn15u.dll". Ressource not found.
If i view the dlls dependencies with full paths, i see the following:
alt text http://img340.imageshack.us/img340/4122/dependencywalk3.jpg
The lower MSVCR80.DLL is the one withe Version ...42. I dont understand this. Why does MSVCP80.DLL refer to a different Version of MSVCR80.DLL than the one besides it. Is that maybe a problem of the dependencywalker ?
Your best option is to ship the needed DLLs within your applications installer package. Use at least the version that your 3rd party DLL depends on.
Microsoft offers standalone installers for its runtime DLLs (vcredits_*). The latest version for VisualStudio 2005 can be downloaded here. That is also the version that your DLL is linked against. You can silently launch the redistributable package from your installer.
As a manual workaround for already installed systems, simply apply the redist installer on the target machine.
If you choose this method, you don't need to be afraid of version conflicts, as applications depending on an older versions will be redirected to always use the most recent one.
For a better understanding you have look at this MSDN articles.
You have to change / update the manifest resource from the dlls.
mt.exe -inputresource:dll_with_manifest.dll;#1 -out:old.manifest
mt.exe -manifest new.manifest -outputresource:dll_with_manfiest.dll;#1
Sometimes the RT_MANIFEST (type 24) resource type doesn't have the #1 index in resource table, you should use a Resource Viewer (ResourceHacker, or ResEdit) and find out the index number. I have seen cases when the manifest has the #2 index number.

Windows API commctrl.h using application doesn't work on machines without the Platform SDK

I have written something that uses the following includes:
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <commctrl.h>
This code works fine on 2 machines with the Platform SDK installed, but doesn't run (neither debug nor release versions) on clean installs of windows (VMs of course). It dies with the quite familiar:
---------------------------
C:\Documents and Settings\Someone\Desktop\DesktopRearranger.exe
---------------------------
C:\Documents and Settings\Someone\Desktop\DesktopRearranger.exe
This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.
---------------------------
OK
---------------------------
How can I make it run on clean installs? Which dll is it using which it can't find? My bet is on commctrl, but can someone enlighten me on why it's isn't with every windows?
Further more, if anyone has tips on how to debug such a thing, as my CPP is already rusty, as it seems :)
Edit - What worked for me is downloading the Redistributable for Visual Studio 2008. I don't think it's a good solution - downloading a 2MB file and an install to run a simple 11K tool. I think I'll change the code to use LoadLibrary to get the 2 or 3 functions I need from comctl32.dll. Thanks everyone :)
Use Dependency Walker. Download and install from http://www.dependencywalker.com/ (just unzip to install). Then load up your executable. The tool will highlight which DLL is missing. Then you can find the redistributable pack which you need to ship with your executable.
If you use VS2005, most cases will be covered by http://www.microsoft.com/downloads/details.aspx?FamilyId=32BC1BEE-A3F9-4C13-9C99-220B62A191EE&displaylang=en which includes everything needed to run EXEs created with VS2005. Using depends.exe you may find a more lightweight solution, though.
Common controls is a red herring. Your problem is that the Visual C++ 8.0 runtime - I assume you're using Visual Studio 2005 - isn't installed. Either statically link to the C/C++ runtime library, or distribute the runtime DLL.
You will have this problem with any C or C++ program that uses the DLL. You could get away with it in VS 6.0 as msvcrt.dll came with the OS from Windows 2000 up, and in VS.NET 2003 as msvcr71.dll came with .NET Framework 1.1. No more. Visual Studio 2005 and later use side-by-side assemblies to prevent DLL Hell, but that means you can't rely even on .NET 2.0 installing the exact version of C runtime that your program's built-in manifest uses. .NET 2.0's mscorwks.dll binds to version 8.0.50608.0 in its manifest; a VS-generated application binds to 8.0.50727.762 as of VS2005 SP1. My recollection is it used some pre-release version in the original (RTM) release of VS2005, which meant you had to deploy a Publisher Policy merge module if you were using the merge modules, to redirect the binding to the version actually in the released C run-time merge module.
See also Redistributing Visual C++ Files on MSDN.
I suspect it is trying to find a version of common controls that isn't installed. You may need a manifest file to map the version of common controls to your target operating system. Also, you may need to make sure you have installed the same VC runtimes that you were linked to.
Chris Jackson blog
EDIT: A little searching and I've confirmed (mostly) that it is the version of your VC++ runtimes that is to blame. You need to distribute the versions that you built with. The platform SDK usually includes a merge module of these for that purpose, but there is often a VCRedist.exe for them as well. Try looking Microsoft's downloads.
KB94885