I have a program that gets every module loaded into a process and compares them with a database of forbidden DLL files, which works just fine, but it's too simple to circumvent (just change the name of dll file which you want to inject into the process). So I'm asking how can I distinguish DLL files. Is there any unique identifier which can be used in C#? Thanks.
EDIT: I forgot to mention that the program I'm creating checks dll files of another program not created by me which is written in C++.
You can iterate through every module loaded in a process How do I list all loaded assemblies? and see if there is a properly of each module such as ModuleVersionId that does not change when the filename is changed?
I'm not sure if this is even remotely a decent way of handling it, but maybe try hashing the DLL file and check against known trusted hashes of the files? this would require you to already have a trusted list of dll hashes but should safeguard against simply renaming to bypass your current security measure.
Related
I have software from the hardware manufacturer, however I do not want my customers to directly use this software, so I want to call manufacturer's software through my program.
I tried to embed an exe file into a resource, but when I called it, my program had to write the exe to disk and I don't want to expose the .exe file.
I also tried the following:
byte[] bin= Properties.Resources.myPro;
Assembly a = Assembly.Load(bin);
MethodInfo method = a.EntryPoint;
if (method != null)
{
object o = a.CreateInstance(method.Name);
method.Invoke(o, null);
}
but got this error when run to Assembly.Load(bin):
Could not load file or assembly '622592 bytes loaded from meter_config,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format.
What is the problem, and how do I fix it?
Firstly, the error message you're getting:
An attempt was made to load a program with an incorrect format.
This indicates that the .exe file is not a .NET assembly. As such there is basically zero chance that you're going to be able to execute it from memory or directly from resource. You're going to have to put it somewhere on disk in order to get it to run.
Without a lot more information, all I can suggest is that you run it from a temporary or hidden location. Assuming that you are licensed to do so by the hardware manufacturer, of course.
I would suggest that you extract the .exe file to the temporary folder with a random file name, execute it, then delete the file after it has completed its operation. If you want you can add use the MoveFileEx API to delete a file on reboot. There's an example here on StackOverflow on how to do that. It makes sure that the file is removed from the computer at some point.
If you don't want to delete the file then the other option is to extract it into a path deep in the user's AppData hierarchy. Disguise it however you like, maybe put it in a folder with the hidden flag set, etc.
This kind of obfuscation won't stop a determined user from tracking it down, especially if it runs for more than a few seconds and can be easily seen in Task Manager or Process Explorer. Not much you can do about that unless you want your program to be flagged as a rootkit.
The alternative is to see if the manufacturer will supply a .NET library you can use instead of a standard Windows executable.
Since your using C# (which is generally managed code) you can't load as unmanaged assembly, so, if manufacturer's program is developed in C or C++ or something else which works at lower level than C#, be careful whether that code is managed or not. If it's unmanaged, unfortunately you can't do anything, except including a static entry point (if the code of manufacturer's program exports some method) just as this (you can reference here):
[DebuggerHidden, DebuggerStepperBoundary, DllImport("YourAssemblyLocation", SetLastError = true)]
[return: MarshalAs(UnmanagedType.YourPrimitiveType)]
internal static extern YourMethodType YourMethodName();
I hope this can be useful for you and let me know about the question.
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
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! :)
Question:
I'd like to know if I would need to ask for specific permissions and/or do something extra to make it "trustworthy" in case my program copies a dll file multiple times to the temp directory. If I do this, would the program be picked up as malicious software by anti-viruses?
Sample Code:
if (needANewCopyOfTheDll)
{
string fileName = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".dll";
// Here, copy my dll to the new file.
}
But why? I have a static library written in C++, and it has global variables, initialization procedures, and so many other stuff. I'd like to have different instances of that library and I can only load the same dll once in the memory. Thus I was thinking of wrapping the library in an instance class, and when I needed a new instance of it just copy the dll file to the temp directory and get a new handle for it using LoadLibrary() function in kernel32.dll
Copying to the temporary directory does not require any special permissions. You can just do it, it should be no problem. Lots of programs do that.
It's not clear from your question whether your software is picked up as malicious or not. If it is, I suspect it is because you're loading a dll from the temporary directory.
What you do sounds like a pretty big hack anyway. You should rather rewrite your library to not use global variables.
I have a .NET DLL that I register with regasm.exe as a Browser Helper Object. I embedded several Win32 resources in the DLL using .res files and /win32 switch to csc.exe.
image.png HTML "image.png"
I am able to access the resources using the res protocol as long as I include the absolute path of the DLL.
res://C:\Path\To\My\Dll\Assembly.dll/image.png
This is rather unfortunate. I would much rather just reference the assembly name as I have seen in many other examples:
res://Assembly.dll/image.png
But this results in an error because the browser can't find the resource.
Ideas?
I think there are a couple things that can be done. First, I believe your assembly needs to be a part of the global assembly cache if you don't want to be forced to use the full path.
Add assembly to global assembly cache.
It's not pretty and you must also keep in mind that a newer build of the DLL will be different from the version in cache. So it would essentially be another extra step to take which would just lead us back to accepting having to put in the full path in the first place.
Second, another solution I believe that works would be to place the DLL in the same directory as the VS utility or the other resources you're trying to use. This could be applicable to multiple different things that one might want to do, but requires manually moving your files around.
Third, you create some custom environmental variables that represent the path that you desire. So instead of typing the full path in the future, you just type your variable.
The third option is my favorite and something that I use for multiple different things I need to accomplish from the command-line.