C# DLL from VBScript, no regasm - c#

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

Related

Is there any way for converting reference dll to non-reference dll in visual studio

I have a DLL file (cf.dll) in my project.
It has some methods for encrypting and decrypting a string To/From a file.
My "cf.dll" have some methods for:
write "mystring" ---to-->> new encrypted dll
and
read encrypted dll ---to--->> "mystring"
Now i want publish my project, but if end user use my dll in his/her visual studio (by reference to dll), he/she can decrypt my encrypted files.
Another hand i need this dll in my published project because my project use theirs methods some times.
Now my question is:
How can i change this published dll (cf.dll) to a none-reference dll, for prevent any hack by it.
Edit (more details):
What i want to do:
I want encrypt some connection strings (as a DataTable) to a file and read this file agin.
I have a dll file for doing this work. it is cf.dll. it has some methods for encrypting and decrypting.
Encryption workflow>
DatatTable ------to------>> Xml as String ------by cf.dll methods to------>> enc.dll
Decryption workflow
enc.dll ------by cf.dll methods to------>> Xml as String ------to------>> DataTable
Everything is working properly and encrypted file (enc.dll) is created.
But if the end user use my magic DLL (cf.dll) in a new project in the visual studio (by reference to it), he/she can decrypt my encrypted file (enc.dll) and hack my program.
So, i want to prevent this hack by changing my DLL (cf.dll) to a none-reference DLL OR use another safe solution.
Edit:
My Table Columns for keeping connection string data:
Server DbName DbUser DbPass FileName
But may i ask save another DataTable by this encryption mechanism. so please help me by a solution for saving any string, not only a ConnectionString.
I want a very secure encrypted file from any data. in my solution i conver each object to a string then use my dll methods for save it as a encrypted file (i can do it nice, my problem described above).
You cannot make your dll "non-reference dll", but you can hide all your classes/methods with "internal" keyword (instead of public). This means that this classes/methods can be used only inside of current dll or in DLL/EXE which were specified with InternalVisibleTo attribute. So nobody can use them directly, but you should know that this is managed code, so anybody can take a look inside of your DLL and extract your keys for decryption and write the same code as you have in your dll.
Surprisingly you can not archieve your goal by using a .NET Assembly.
You could even obfuscate your code and it would still be decompilable and reusable.
There's nothing which can prevent that. You can rise the bar, but someone - if she want's - will be able to get the information you are trying to hide.
(Have you seen copy-protection mechanisms that really work besides doing something crucial online?)
Always think of the following:
If you want to hide information from a user DO NOT DELIVER that information. Everything else is just protection through obfuscation, wich can be cracked with more or less effort.
That's a really nice question RAM.
Some solutions to your problem:
1) Don't make a separate assembly (DLL), but put the code of your DLL in your EXE and make the encryption/decryption function of your DLL "internal" (so that no-one can use it from outside the EXE). Then use a free tool like Eazfuscator to obfuscate your EXE (because, if you don't, your code will be easy to decompile and read).
2) You could put the DLL in your EXE's resources (perhaps encrypted too). Then perhaps you can find a way to get it from there and load it into memory for your app to use. But this is quite complex thing to do if you are a beginner and I'm not 100% sure if it's doable in .NET (I haven't done it myself). However, I think it's doable.
3) The fact is that, if your code executes on the client's machine, there's not much you can do to prevent people from analysing it. The best you can do is to make it a little (or much) difficult for them to do it. E.g. you can add a lock mechanism in your DLL that requires the caller to respond to a random question. If he responds correctly, you execute the decryption. If not, throw an exception, return null or, even better, return a wrong output. The random question could be an integer that your DLL will generate on initialization and the EXE should process this integer to generate a new integer based on some "secret" algorithm. Then the EXE will "feed" this into the DLL somehow and it's functionality would be "unlocked".
4) Perhaps you could use reflection to analyse the caller assembly in order to find characteristics or even the author signature (if you put one in your EXE). That way, you could execute the decryption if the EXE is signed by your private key and the signature is valid. But that's a bit complex too.
5) I think there are tools called "EXE packers" that pack your EXE and DLLs into one EXE file and protect them at some degree. I haven't used one of those yet.
6) You can move the encryption/decryption process on a web site that will ask for authentication in a complex manner, similar to the one described in (3) for the DLL. This may keep your encryption algorithm safe, but the authentication process could still be analysed and hacked.
I would suggest the 3rd solution since it's the most easy to implement. The 4th (using signed code) is the most secure one but it takes a lot of knowledge to implement it (knowledge that even I don't have right now).
Have a nice coding! :)

How to prevent access to local file system

I have a situation in which my (C#) application can load external DLLs (not written by me) and execute code from those libraries. The libraries can be C# or CPP.
I need to make sure this external code won't access any files in my local file system (read and write) except from a specific folder.
How can i do that?
I've seen third-party code that does this; for example, Jint lets you write JavaScript scripts that manipulate CLR objects, but it prevents any JavaScript-originated code paths from accessing the filesystem, Reflection, etc. by using permissions.
You can read Jint's documentation and poke through their source code for more details, but the essence of it seems to be this:
PermissionSet myPermissionSet = new PermissionSet(PermissionState.None);
// or some other permission set, depending on your requirements
try {
myPermissionSet.PermitOnly();
// run untrusted code
} finally {
CodeAccessSecurity.RevertPermitOnly();
}
A lot of things I've read say you need to create a sandboxed Appdomain (something I've never had much success with), but Jint's approach seems to work pretty well. You might have to watch out for the third-party code hooking static events that would fire later, though -- then they could escape the PermitOnly scope.
Run the application as a restricted user account and only grant the user access to that specific folder.
Secure the files through the OS facilities (filesystem privs), create an account that can access only those files and use this account to run the application
It depends on your framework, but you can use Caspol (Code Access Security Policy) up to .Net 3.5 (and I think C++ DLLs also) to specify security privileges including IO access.
Hope that helps :)
Take a look at Molebox, maybe it will fit your needs. Molebox lets you wrap modules to sandbox them.

Way to determine true calling assembly

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);

Is there a way to fake registry entry in C#?

I am trying to execute an .exe file from my C# code. The .exe file requires some key to exist in the registry. Now I have two options:
1. Either I can add the key, execute the file, and then delete what I added from registry.
2. OR If possible, I can fake the key in registry so that .exe can execute and I don't have to modify the registry.
Can someone please tell me if #2 is possible? If not then is there any other better way to deal with this situation (perhapds undo changes I made from registry)? or do I have to stick with #1?
Please guide me on this.
Thanks
Intercepting registry reads is not for the faint of heart and will almost certainly require several orders of magnitude more work than option 1.
There is a function for that, but it only affects the process which calls it. So you would have to use DLL injection. C# (or any type of managed code) would not be my choice for accomplishing this.
If you must intercept the read, then start developing a driver in C/C++ that calls CmRegisterCallback to hook system-wide calls and filter out the ones you need. But I think you'll seriously regret even starting the project... just go with option 1 instead.
It's technically possible to intercept calls to the registry using something like Detours. However, the intercept code cannot be written in C# and must be in C++ (or C, I suppose). Not to mention, doing this in a robust manner is going to be a lot of work.

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