Question

This may be a daft question as I can see the security reason for it to happen the way it does...

I have a licensing c# project, this has a class which has a method which generates my license keys. I have made this method private as I do not want anybody else to be able to call my method for obvious reasons

The next thing I want to do is to have my user interface, which is in another c# project which is referencing the licensing dll to be the only other 'thing' which can access this method outside of itself, is this possible or do i need to move it into the same project so that it all compiles to the same dll and I can access its members?

LicensingProject
-LicensingClass
--Private MethodX (GeneratesLicenseKeys)

LicensingProject.UI
-LicensingUiClass
--I want to be able to be the only class to be able to access MethodX

There is a reason why the license Key Generator is not just in the UI, that is because the licensing works by generating a hash on itself and compares it to the one generated by the License Generator.

I would prefer not to all compile to the dll as my end users do not need the UI code.

I know that by common sense a private method, is just that. I am stumped.

Was it helpful?

Solution

You could make it an internal method, and use InternalsVisibleToAttribute to give LicensingProject.UI extra access to LicensingProject.

Merhdad's point about enforcement is right and wrong at the same time. If you don't have ReflectionPermission, the CLR will stop you from calling things you shouldn't - but if you're using reflection from a fully trusted assembly, you can call anything. You should assume that a potential hacker is able to run a fully trusted assembly on his own machine :)

None of this will stop someone from using Reflector to decompile your code. In other words, making it private isn't really adding a significant amount of security to your licensing scheme. If anyone actually puts any effort into breaking it, they'll probably be able to.

OTHER TIPS

This is really a comment, in response to Mehrdad's point about the runtime not performing access checks; here, you can see the JIT (it transpires) performing the access check - not reflection, and not the C# compiler.

To fix the code, make Foo.Bar public. Interestingly, it also verifies that Foo is accessible - so make Foo internal to see more fireworks:

using System;
using System.Reflection;
using System.Reflection.Emit;
static class Program {
    static void Main() {
        MethodInfo bar = typeof(Foo).GetMethod("Bar",
            BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
        var method = new DynamicMethod("FooBar", null, new[] {typeof(Foo)});
        var il = method.GetILGenerator();
        il.Emit(OpCodes.Ldarg_0);
        il.EmitCall(OpCodes.Callvirt, bar, null);
        il.Emit(OpCodes.Ret);

        Action<Foo> action = (Action<Foo>) method.CreateDelegate(typeof(Action<Foo>));
        Foo foo = new Foo();
        Console.WriteLine("Created method etc");
        action(foo); // MethodAccessException
    }
}

public class Foo {
    private void Bar() {
        Console.WriteLine("hi");
    }
}

public, private, ... stuff are just enforced by the compiler. You can use reflection to access them pretty easily (assuming the code has required permissions, which is a reasonable assumption as he has complete control on the machine). Don't rely on that assuming nobody can call it.

Foo.Bar may stay private... To fix the code above, add one parameter at end of DynamicMethod constructor:

var method = new DynamicMethod("FooBar", null, new[] {typeof(Foo)}, true);

Add true to skip JIT visibility checks on types and members accessed by the MSIL of the dynamic method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top