Way to determine true calling assembly - c#

I have some security built into a client side program that downloads a DLL from the web, and called a function inside that DLL. The DLL is strong-named, and the function in the DLL uses Assembly.GetCallingAssembly() to determine the calling assembly so that I can accurately get a path to the program who called it. From there we do a hash check of the assembly and verify that it is the correct one.
We have people that have gotten themselves attached in full trust mode, and are able to spoof the GetCallingAssembly call to point to the real executable, while they run a modified version of it. Is there something else other then GetCallingAssembly that I can use to get the true caller? Some callstack or something that may provide the real executable since GetCallingAssembly seems to be easily spoofed.

You can't do this while running in full trust mode. Full trust means people can do things like spoofing. Here is a similar discusison:
reflection is possible on obfuscation

I'm not sure how secure it is, but I've used this in the past to get the startup path:
string startup_path =
Path.GetDirectoryName(typeof(SomeClassInDll).Assembly.Location);

Related

How do I know that my Application loads the correct assemblies?

I have an assembly that is used to verify the security of my Application such as the license.
How do I grant that every time my Application calls the verification method, this is being loaded from the correct assembly?
I want to prevent that someone creates a fake assembly to bypass these verifications.
By adding a .snk to get a Strong Named Key, will this solve my problem?
E.g. If my application uses MySecurity.dll, if someone else creates a assembly with the same name and override it in the bin folder, will my application know that this is not the correct assembly?
I am worried because our solution uses two kinds of verification, local using a public certificate for the license file, and online (if has internet connection). But any of these can be bypassed easily.
You can hard code the hash string of that dll file in your code and check it at run-time (maybe in a timer)
Also you need to protect your assemblies with some thing like this Eazfuscator.NET

DLLs searching for DLLs

I've done an extension for Thunderbird. It calls (via js-ctypes) a C++ DLL I've written which in turn references other DLLs which are assemblies written in C# (existing code). If all the files are in the same directory as the Thunderbird executable, it all works fine.
I've now moved my own files to a directory I've made to keep them distinct from the Thunderbird files. The directory is in the path, so my C++ DLL gets loaded when called. However when it starts looking for the referenced assemblies, it fails.
Procmon shows that it is only looking for referenced assemblies in the directory which Thunderbird is running from. Not only is there no path, it's not even looking in the system directories.
What can I do to get my DLL loading its dependencies without dumping everything into Thunderbird's own folder, which as well as being somewhat messy will get silly when I port the extension to other mail programs?
Edit: Added extracts from the JS code.
From my 'init' function, there's;
this._kernel32 = ctypes.open("kernel32.dll");
this._setDLLDir = this._kernel32.declare("SetDllDirectoryA",
ctypes.default_abi,
ctypes.bool,
ctypes.char.ptr);
var ret;
ret = this._setDLLDir("C:\\Program Files (x86)\\AuthentStreamAttacher");
this._lib = ctypes.open("AttacherC.dll");
this._getStr = this._lib.declare("GetPackage",
ctypes.default_abi,
ctypes.char.ptr);
this._freeStr = this._lib.declare("FreePackage",
ctypes.default_abi,
ctypes.void_t,
ctypes.char.ptr);
ret = this._setDLLDir(null);
And where I'm actually making the call to _getStr and search for AttacherC.dll's dependencies is made is;
var ret;
ret = this._setDLLDir("C:\\Program Files (x86)\\AuthentStreamAttacher");
var str = this._getStr();
In each case, ret is true (according to the debugger on stepping through) suggesting the call to SetDllDirectory succeeds. Behaviour is the same whether I use the "A" or "W" version, there being nothing in the JS to simply let me call "SetDllDirectory". It's as if each call is happening in its own isolated context, yet in my DLL "GetPackage" uses malloc to allocate some memory which then needs to be freed in "FreePackage". FreePackage doesn't throw an exception suggesting the fact the memory's been allocated is persisting between the two calls.
More odd behaviour; if I specify a random string as the path in SetDllDirectory ("helloworld" in this case) ret is still true. So either SetDllDirectory isn't actually getting the string correctly via ctypes, or it's not doing any sanity checking on it.
My feeling now is that each js-ctypes call is happening in its own context, in some way, and it's upsetting .net's assembly search mechanism, and the only way to get this to work is to have a seperate native DLL with a single function called from javascript. This then calls SetDllDirectory and LoadLibrary in the same context to call the next wrapper in the chain, which then calls my real C# code. Messy and seems more prone to things going wrong so I'm hoping someone comes along and proves me wrong?
Since nobody else seems to have an answer I'll document what I ended up doing.
When native code calls a dotnet DLL the CLR starts up behind the scenes to run it. Although the native code can search for the DLL in a variety of places- including that specified by SetDllDirectory- the CLR will only look in the directory from which the initial executable has been started, and in the Global Assembly Cache. To access assemblies that your DLL has been linked to by adding references to them in Visual Studio, they have to be in one of these two locations.
Since I didn't want to do either, what's needed is to make a .net DLL that is directly dependent only on framework assemblies, with no references to any of my own. This then gets the CLR up and running my code. I can then load the assembly I want to use via Assembly::LoadFrom() and invoke the method I want to use as documented here.
Of course, loading the assembly this way will still cause any other dependent assemblies to be searched for in the executable dir or in the GAC, if they're not already loaded, and in all but the most trivial case it's too complicated to bother explicitly loading each assembly in order from the most fundamental upwards. So the AssemblyResolve event is registered first. When the CLR can't find an assembly in its two search locations, it raises this event and lets me determine the full path of the assembly and load it, again using Assembly::LoadFrom().
Of course, LoadFrom needs to know the base path- the only information that seems to be available concerns the executable's directory, but there's plenty of ways to resolve that.
You will need to modify the DLL search path.
Make a call to SetDllDirectory before calling ctypes.open() to load your C++ DLL. Pass to SetDllDirectory the directory containing your DLL, and its dependent modules. When the call to ctypes.open() returns, call SetDllDirectory again, passing NULL, to undo the search path modification.

C# DLL from VBScript, no regasm

Is it possible to access a C# DLL's method from VBScript without registering it with regasm? I will be creating the DLL so pretty much any exotic requirement to make it visible to VBScript, I can do...
I have read here that it might be possible to use GetObject from VBScript to achieve this, but I have tried that with no success... Is there anything else I need to do aside from making the DLL "COM visible" to make this work?
The reason why I need to avoid regasm is that it requires admin rights, and I need to deploy this DLL "silently" to many clients that may or may not have admin rights.
No, registration is required, the only way that the script interpreter can find the DLL that contains the ProgId that you use in the script's CreateObject() call. Isolated COM with a manifest doesn't work, you can't modify the manifest for the script interpreter.
There is a technical solution, you can write registry keys in the HKCU registry hive without acquiring UAC elevation. The Regasm.exe tool always writes them in the HKLM hive. That registers the assembly as well, but only for the user that runs Regasm.exe. It is however pretty painful and easy to get wrong, you have to write your own registration method and apply the [ComRegisterFunction] attribute. It is now your job to use the RegistryKey class to set the keys. Same for the [ComUnregisterFunction], it should delete the keys again. There are a lot of bad examples out on the interwebs, best way to get this right is to use SysInternals' ProcMon to observe the registry keys that get written when you use Regasm.exe normally, then reproduce that in your own code, using HKCU instead.
Do note the other side of that medal, you are in fact making configuration changes to the machine that allows arbitrary code to run. Trying to hide that doesn't do the user any favors and should never be considered if you honor the user's desire to keep the machine safe and predictable. UAC is not there to stop you from making changes, it is only there to inform the user about it.
The accepted answer is incorrect that registration is required to use a DLL. You can use the GetObject() method instead of the CreateObject() method as shown in my answer to this question.
Using DLLs in VBScript

Is there an API for verifying the MSIL of a dynamic assembly at runtime?

When using Reflection.Emit to build an assembly at runtime, I'd like to verify the assembly MSIL before saving to disc. Like PEVerify but at runtime. Is there such an API?
It seems that peverify.exe is a front-end to c:\Windows\Microsoft.NET\Framework\v4.0.30319\peverify.dll (or c:\Windows\Microsoft.NET\Framework\v2.0.50727\peverify.dll for CLR 2.0), which is a native DLL (actually, peverify.exe is also native)
I don't see this documented anywhere so it's probably not a public API. You may be able to figure out the exported functions from that DLL using something like Dependency Walker, but I think it would be simpler to just call peverify.exe.
EDIT: anecdotal evidence:
In a compiler step, Boo actually calls peverify.exe.
Nemerle calls peverify.exe in its tests.
Castle.DynamicProxy calls peverify.exe in its tests.
Instead of using PEVerify you could use the ILSpy's decompiler for an in-process solution, as described here: http://www.codeproject.com/Tips/659692/Automated-MSIL-PE-verification-using-ILSpy
A summary of the article is:
Collect the relevant DLLs to reference from your test project, or
runtime IL checker in this case
Iterate through the methods to verify using Mono.Cecil
For each method, add it to the AstBuilder defined in ICSharpCode.Decompiler which performs the validation. Eg.
var context = new DecompilerContext(method.Module) { CurrentType = method.DeclaringType };
var astBuilder = new AstBuilder(context);
astBuilder.AddMethod(method);
Performance-wise I have not checked which method is faster. Although this method is in-proc it may be slower since the Abstract Syntax Tree is built as the IL is validated (I'll have to setup a performance test to check this theory).
I found the ILSpy decompiler to be more reliable than PEVerify as pointed out in the above article, in one instance PEVerify declared one assembly to be valid, while ILSpy correctly gave a beautiful stack trace indicating my error in generation.
Debugging LCG allows you to debug the generated code at runtime using Windbg.
Maybe it can help you.
Calling peverify is indeed probably the best approach, but peverify is located in many different directories depending on the running version of .NET. You can try to enumerate all these paths and check for the latest one, but this was at least 6 different paths at last count IIRC, and isn't cross-platform, ie. doesn't include Mono.
I recently found that I could just link to the Microsoft.Build.Tasks assembly, and then create an instance of Microsoft.Build.Tasks.GetFrameworkSdkPath and call the Path property. One weird behaviour I noticed is that accessing the path the first time throws an exception, but if you just swallow that exception you can access the path from then on.
Peverify.exe is then Path.Combine(new GetFrameworkSdkPath().Path, "bin\peverify").

Best way to only perform a function if a (.NET) DLL is loaded?

I am not sure the best way to explain this so please leave comments if you do not understand.
Basically, I have a few libraries for various tasks to work with different programs - notification is just one example.
Now, I am building a new program, and I want it to be as lightweight as possible. Whilst I would like to include my notification engine, I do not think many people would actually use its functionality, so, I would rather not include it by default - just as an optional download.
How would I program this?
With unmanaged Dlls and P/Invoke, I can basically wrap the whole lot in a try/catch loop, but I am not sure about the managed version.
So far, the best way I can think of is to check if the DLL file exists upon startup then set a field bool or similar, and every time I would like a notification to be fired, I could do an if/check the bool and fire...
I have seen from the debug window that DLL files are only loaded as they are needed. The program would obviously compile as all components will be visible to the project, but would it run on the end users machine without the DLL?
More importantly, is there a better way of doing this?
I would ideally like to have nothing about notifications in my application and somehow have it so that if the DLL file is downloaded, it adds this functionality externally. It really is not the end of the world to have a few extra bytes calling notification("blabla"); (or similar), but I am thinking a lot further down the line when I have much bigger intentions and just want to know best practices for this sort of thing.
I do not think many people would
actually use its functionality, so, I
would rather not include it by default
- just as an optional download.
Such things are typically described as plugins (or add-ons, or extensions).
Since .NET 4, the standard way to do that is with the Managed Exensibility Framework. It is included in the framework as the System.ComponentModel.Composition assembly and namespace. To get started, it is best to read the MSDN article and the MEF programming guide.
You can use System.Reflection.Assembly and its LoadFile method to dynamically load a DLL. You can then use the methods in Assembly to get Classes, types etc. embedded in the DLL and call them.
If you just check if the .dll exists or load every .dll in a plugin directory you can get what you want.
To your question if the program will run on the user's machine without the dlls already being present - yes , the program would run. As long as you dont do something that needs the runtime to load the classes defined in the dll , it does not matter if the dll is missing from the machine. To the aspect you are looking for regarding loading the dll on demand , I think you are well of using some sort of a configuration and Reflection ( either directly or by some IoC strategy. )
Try to load the plugin at startup.
Instead of checking a boolean all over the place, you can create a delegate field for the notification and initialize it to a no-op function. If loading the plugin succeeds, assign the delegate to the plugin implementation. Then everywhere the event occurs can just call the delegate, without worrying about the fact that the plugin might or might not be available.

Categories