Can you extract dll version numbers from bundeled dlls - c#

I need to bone up on my CLR compiling knowledge, so i'm going to speak in generalities... Appologies if I'm not being specific enough.
I'm working on an application that references a COM Library dll which has a number of dlls rolled into it. My question is, is it possible using Reflection to get a reference to the sub dll's assembly, namely to obtain the version number?
Or, if this question makes no sense, i'll try to rephrase.

No can do, you've got no way to find out what DLLs the COM server might be using. There isn't anything like Assembly.GetReferencedAssemblies() in unmanaged code. Process.Modules is about as close as you can get but there's no way to find out that the module you'll iterate was actually associated with the server instead of being loaded by, for example, OpenFileDialog or some obscure virus scanner crap.
If you know the DLL names and where they are located then you can use the FileVersionInfo class to obtain their unmanaged version resource info.

Related

Include TFS path in .NET assembly

When troubleshooting our applications, in many situations I cannot be sure what branch the assemblies originally come from, due to an imperfect release cycle and human error.
(We have quite a lot of different bugfix/feature/test/release branches etc. in our TFS).
The PDB-files can help sometimes, in a test environment at least, but sometimes they're missing or outdated / belong to assemblies from another branch.
So, I was trying to think of a way to include the source branch information inside the assembly directly.
Surprisingly, I could not easily find a straight forward way online to accomplish this.
My answer below explains my approach. I would be happy about feedback or alternative solutions.
In short: I created a custom attribute that I put intoAssemblyInfo.cs. Inside the attribute's constructor, the server path for the current assembly is queried from TFS and compiled into it.
It's basically a combination of the following:
Can I add custom version strings to a .net DLL?
How do I get the path of the assembly the code is in?
Get TFS mapped folder of a local sub folder of the solution?
(Note: I cannot post the actual source code due to company restrictions, but I think it's pretty straight forward.)
To get the attribute's value later is unfortunately not as easy as getting the version number from the DLL-file's properties, but at least it is possible now to get the information I need with minimum effort. (I use a small PowerShell script for that.)

Prevent Assembly Reflector and its Access to other client/User

I have created project in Windows Presentation Foundation which use some Assembly created by me and use in other project. But now i don't want others to use it and to reverse engineering ("Assembly to code").
i come to know about Assembly signing. Also i Have use ant try signing but i can easily Open code of Assembly in .Net reflector tool.
So please guide me in right direction.
It all depends on how much work you want to do, and how hard you want to make it.
If all you want is to stop people from being able to quickly decompile your assembly you can compress and/or encrypt the DLL itself, then write a loader for the assembly that brings it into memory, decodes and/or decompresses and loads the assembly in-memory. The compressed/encrypted data can be stored as a resource in another assembly which handles the unpacking if you like, although that makes it simpler to find the code that does the unpack.
This will only prevent casual inspection of your code. It won't slow down a determined reverse engineering attempt by much. Ultimately there isn't much at all that you can do to stop a skilled and determined attempt at reverse engineering.

Intergrate a non-signed assembly into an existing application

I have a problem which I'm pretty sure that I can't solve without going back to the vendor, but I thought I would float the problem here first.
Anyway, I have an assembly from a 3rd party that I have to incorporate into existing applications, but it is not signed. This obviously gives me a load of headaches as all my existing product assemblies are signed, and to reference the new dll from these would require me to not sign them. I really don't want to do that.
Do I have any other options other than a) going back to the vendor to try and get them to sign it or b) not-signing any dll that references it?
Your best bet is to ask the vendor for a properly signed assembly.
Failing that, you do have the dirty option of disassembling the assembly with ILDASM, then reassembling it with your own strong name encryption key. This will require a bit of work. Talk to the vendor first, and perhaps even mention (not threaten) that you'd rather not have to disassemble their assembly.

P/Invoke dynamic DLL search path

I have an existing app which P/Invokes to a DLL residing in the same directory as the app itself.
Now (due to the fact that Canon produces one of the crappiest API's around) I need to support two versions of this API and determine at run-time which one I should use (old or new). Since the DLLs have the same name (the first one loads other DLLs with same names so just renaming the first one won't help me) I must keep them in different directories.
Hence my question: what options do I have to control what directory the DLL given in a DllImport declaration uses?
I guess I can start out by trying any of these two ideas:
1) Use "SetDllDirectory" to set my desired directory before doing the first P/Invoke and then reset it afterwards.
2) Load the desired DLL manually using "LoadLibraryEx" and hope that that will do the trick.
But are there any more ".NET:ish way" to try out first?
UPDATE: I realize that I can stuff all access to the DLLs in two separate .Net assemblies and then place each one of them in a separate directory with the corresponding API files. Then I can load the proper .Net assembly dynamically and the loading of the correct DLL whould happen automatically. Any reason that shouldn't work?
I can think of one: how would I go about debugging this stuff? It is possible to tell Visual Studio that an assembly (contained in my solution) shall be placed in a subdirectory and debugged from there?
My condolences, I've seen one of the APIs and it was indeed shockingly bad. The bigger problem is that you'll need to be able to convince Windows to find the DLL. They won't be in your .exe directory so the default won't work. Using SetDllDirectory() would work, using Environment.CurrentDirectory does too. LoadLibrary cannot work, the P/Invoke marshaller will use LoadLibrary itself.
If it is at all an option, you can use different names for the two P/Invoke declarations, using different arguments for the DllImport() constructor and using the EntryPoint attribute. Doesn't sound like that will fly.
I think 2nd option will work, but it will require to write a lot of code to manage dll loading in .net.
First one might work also, but i either don't like it.
Here is my suggestion: you can specify full path (and may be relative) in DllImport [DllImport(#"C:\dll\a32.dll"]
Your first option (P/Invoke with SetDllDirectory) is the option I personally prefer. Unfortunately, there isn't a ".NETish" way to handle loading native DLLs...which does make sense.
Starting with .NET Core 3.0, and also works with .NET 5 & .NET 6, you can use NativeLibrary.Load(string) to dynamically load DLLs at runtime, and use via P/Invoke normally.
Check this answer for more details: https://stackoverflow.com/a/69958827/211672

Forcing my app to use a specific version of a dll

I have application which needs to use a dll (also written by me) which has be independently verified by a government agency. We plan to modify the dll very rarely due to the re-verification which would be required. I want to prevent inadvertent modifications to this dll being picked up by my application. Is there a way to create a hash code for the dll and set up my application to only use this specific version.
This way if someone modified some of the code for the dll, when we build and run the application the app would fail to load the dll (because it had changed).
Any ideas/suggestions?
Cheers,
James
Using Strong Names does part of this and prevent anyone else tampering with your assembly, but doesn't stop you doing it by accident and then resigning.
We use an independent process to start our main application. Before launching the main app, the start up app MD5's all the assmeblies and compares them against a list of those it expects to see, if something has changed, the MD5 fails and the main app is not loaded.
If you really wanted compile time checking, you could probably write a pre-build step that did the same MD5 comparison and failed the build if it had changed.
I know that if you click on a dll Reference in your project you can select 'Specific Version' in its properties and set it to True, will this not do what you are after?
Phill
As Colin mentioned Strong Naming your assemblies will be the key as this includes both versioning & signing the assembly. The following couple of blog posts may help you with strong naming & versioning:
http://www.csharp411.com/net-assembly-faq-part-3-strong-names-and-signing/ (might be also worth reading the next part of this about the Global Assembly Cache)
http://philippetruche.wordpress.com/2008/08/12/net-assembly-versioning-lifecycle/

Categories

Resources