4

I'm developing a C# application to assist people with reading and writing disabilities - among other things this application provides word prediction.

The word prediction is written in C and runs as a webservice on a Linux server and requires a login to be used. No problem.

Lately, however, several of our customers have expressed interest in an offline version, which is something we would like to provide. As a means to that I've written a wrapper (in C) around the word prediction code and compiled it to a DLL that I can use in my C# application along with our prediction data files.

Problem is, now everyone has access to:

  1. Our data files (not a problem in itself, because the files don't really make sense without the prediction code).
  2. The compiled DLL.
  3. The C# code (which can easily be decompiled to see how the DLL is used).

I know I can't protect the C# code and I am also aware that it is impossible to completely secure the code, as the binaries will always be readable (there are plenty of questions/answers on this topic already, so I'd be grateful if people don't repeat these answers).

I would, however, like to know if it is possible to secure the DLL in a way that it can only be called from my application?

I'm thinking something along the lines of comparing the checksum of the calling EXE file with a checksum compiled into the DLL. Are the other (more elegant) solutions available?

The point isn't to create a DLL that is 100% secured against being used by unintended applications (as it's impossible) - but secure enough that other developers cannot easily copy the data/DLL files and use them in their application (we've had issues with competitors stealing our code on other platforms already).

Clarification of the intended purpose of the question

Based on some of the comments I think some clarification is needed.

The point of the question isn't to find a way that will 100% secure code - we already know that's impossible (here's a good question on the topic: Protect .NET code from reverse engineering?).

The point is to get suggestions on ways to complicate cracking the code (or, as I've learned, now: Security through obscurity).

Some people will argue that it's a waste of time, but by that thinking we might as well hand out all of our source code to everyone for free, because it's going to be cracked eventually anyway, right? Right?

No. It really depends on your target audience.

If you are Microsoft trying to prevent piracy of Windows with its hundreds of thousands of users someone will find a way to crack it - even if just for the "prestige" of being "The guy that cracked Windows". Regardless, it still makes sense to put some anti-piracy measures into place, just to keep the average user from pirating it.

If you're a small business, however, the act of making it more complicated to crack your code may mean that it won't actually be cracked. Why? Because it's all the more unlikely that average Joe (and his developer friends) have the knowledge to crack your code and the people who can crack it will have no interest in it.

Community
  • 1
  • 1
Woodgnome
  • 2,281
  • 5
  • 28
  • 52
  • 1
    So you ask if it's possible, and then later on state that you know it's impossible and all you can do it make it more time consuming to crack. Apparently you've answered your own question. It is indeed impossible. As to how much protection is enough for you, that's a decision you need to make based on how much you think your code is worth to potential crackers, and how much you're willing to invest in protecting it. – Servy Jun 01 '15 at 13:13
  • 1
    Personally, I'd avoid doing this because it is more likely to get in the way of your customers using the software than it is to prevent copying. Instead, I'd periodically get a copy of the competitors software to check if they copied. And for online consumption, add a non-sensical prediction that can be requested to see if the same library is being used. – Jeff Siver Jun 01 '15 at 13:15
  • Really, what you are asking for is advice re: how to do security through obscurity -- answers will tend to mostly opinion based by the usual standards of SO. – Gary Walker Jun 01 '15 at 13:22
  • Maybe you should be re-thinking your entire business model. Provide a billable service instead of a billable software product. If your service is hosted on a hacker-proof server (ha!) then you don't need to worry about obfuscation, etc. – RenniePet Jun 01 '15 at 13:41
  • Your plan re: checking the calling EXE is doomed because there's no reliable way to work out who your caller is. See [Don't trust the return address, no really](http://blogs.msdn.com/b/oldnewthing/archive/2006/08/17/704232.aspx), as one set of examples. – Damien_The_Unbeliever Jun 01 '15 at 13:50

2 Answers2

2

For Direct Security

The simplest approach would be to make your unmanaged C DLL have a built-in licensing mechanism, to essentially render it useless to third-party developers who might otherwise import the library to their own managed or unmanaged code.

There are many techniques to do this, such as reading a license key from the Windows registry or by adding a special ActivateLicense(string key)function to the DLL which gets called from your C# managed application prior to using the other functions of the library.

The specific process of generating and accepting licensing keys is up to you, but in a pure offline environment, there's no such thing as a 100% safe system (How are Software License Keys generated?).

For Extra Security through Obscurity

These remaining options are just extra tips and tricks to make it harder for competitors to reverse engineer, but do not provide much in the way of real security:

  • Embed your unmanaged DLL as a resource within your managed application and load it at runtime from a temporary file
  • Encrypt your unmanaged DLL prior to embedding it, decrypt at runtime, and delete it when unloading the application
  • Use a third-party obfuscation tool for your C# code
Community
  • 1
  • 1
nicholas
  • 2,969
  • 20
  • 39
  • The OP stated right in the question that he knew it was impossible to actually secure the DLL. His question of how to go about securing it as best he could, and you did nothing to help him do that. "Go build a system to do it." isn't an answer. You have explained nothing about how to actually build such a system. – Servy Jun 01 '15 at 14:04
  • Well apparently other people do think that the answer to "how do I build a system to secure my program?" is "build a system to secure your program". So are you guys just trying to troll the OP for giggles, or do you actually think that that's anything but a completely absurd answer? – Servy Jun 01 '15 at 14:10
  • @Servy, an answer doesn't have do describe every minute detail to be useful. nicholas may not have provided a large amount of detail about his suggestions, but nevertheless he did provide usable suggestions, which I can look further into. – Woodgnome Jun 01 '15 at 14:13
  • @Servy - I think what nicholas is trying to say is - check for the presence of something else in the system, which doesn't come along with these files. Like a registry key. My own addition to that would be - make that extra secret be machine-dependant. That way in order to use the DLL on another machine, they'll need to contact you to get the new key. – Vilx- Jun 01 '15 at 14:14
  • @Woodgnome He provided *literally zero* detail. There isn't a single piece of information about securing a dll from execution in this answer that isn't in the question. If "build a security system" actually answers your question, and you didn't need to be told anything else, then you shouldn't have been asking it in the first place. – Servy Jun 01 '15 at 14:15
  • @Vilx- And doing that is *extremely* non-trivial to do in any way that isn't immediately subvertable. All someone needs to do to use the program is add the registry key, or remove the line of code form the program that checks the registry key. Such a poorly implemented system, is providing an illusion of security without providing basically any security whatsoever. Accomplishing this in ways that are, at a minimum, *difficult* to subvert is as a difficult task; one that requires care and a very strong understanding of the systems relied on, and none of which this even recognizes. – Servy Jun 01 '15 at 14:18
  • @Servy, please don't attempt to tell *me (or anyone else)* what an acceptable answer to *my* question is. nicholas mentioned using a license key stored in registry for a license approach, embedding and encrypting the DLL and obfuscating the C# code. While no extra detail is provided those are all valid suggestions to me. – Woodgnome Jun 01 '15 at 14:37
  • @Woodgnome If you now think that just storing a licence key in the registry is a suitable security mechanism to prevent people from using your software without paying for it then not only has the answer not been helpful, it's been *actively harmful*, as you'll end up with a system that's no more secure than you having done nothing, but with you thinking that you actually have some sort of security. All one would need to do to subvert such a system is buy one legitimate copy and then re-package the app using an installer that deploys that one key to the registry. – Servy Jun 01 '15 at 14:43
  • 1
    @Servy I agree with your assessment of the license key in registry approach being insufficient, but it doesn't mean a license key approach is completely useless. In any case - if you had stated this in your first comment (instead of criticising nicholas with no real explanation of why) your comment would actually have been *useful*. – Woodgnome Jun 01 '15 at 14:52
  • @Woodgnome It means that that information alone is basically useless. The hard part about using a licence key is coming up with keys that cannot be easily copied, as well as code that cannot have the licence checks removed easily. Those are both *very* hard problems to solve. The idea of using a key is like .001% of the work. That's functionally useless in my mind. Is the idea of trying to keep track of a key honestly a novel idea to you? (not that it tells you much even if it is, of course.) – Servy Jun 01 '15 at 14:56
  • @Servy why didn't you put this info in your first comment? – Woodgnome Jun 01 '15 at 15:02
  • @Woodgnome I considered it self evident. – Servy Jun 01 '15 at 15:06
  • @Servy - The way I see it, Woodgnome hadn't thought of this approach **at all**, which makes nicholas' answer actually useful, because it opened this line of research. Yes, it's true that it doesn't tell much about what really needs to be done - but it does point in the right direction, and that's useful too. – Vilx- Jun 02 '15 at 08:49
  • @Vilx- You honestly consider providing .01% of the answer to a question to be answering the question? This is *very*, *very* far away from being an actual *answer*. As far as pointing him to further research, doing any research on licencing one's code would have immediately brought up all of this information, so it's not like any of this wasn't already immediately accessible information. But even that isn't an acceptable answer on SO; answers should answer the question, not just point the reader to where they can go for further research. – Servy Jun 02 '15 at 12:49
0

Since you're concerned about just the average users pirating your product, I'd suggest you look into license managers like flexlm. Just make sure the dll itself connects to the license server to make sure the product is licensed, not the exe.

Mustafa Ozturk
  • 812
  • 4
  • 19