13

I'm implementing an automatic "evaluator" for a course I'm currently teaching. The overall idea is that every student delivers a DLL with some algorithms implemented. My evaluator loads all these DLLs using Reflection, finds the student implementations and evaluates them in a tournament. All these algorithms are black-box optimizers, which implement the following interface

public interface IContinuousMetaheuristic
{
    // ... Some unimportant properties
    Vector Evaluate(Function function, int maxEvaluations, ...);
}

The class definition for Function (at least the relevant part) is:

public class Function:
{
    private Vector xopt; // The optimum point
    private double fopt; // The optimum value

    public double Evaluate(Vector x);
}

As you can see, I need to pass a Function instance to these metaheuristics. These functions are implemented by myself. Most of them are in some sense random, that is, I choose a random optimum point in the function constructor. That is why you can see an xopt field in the class. The problem is, I don't want my students to be able to access the xopt or fopt fields by Reflection or any other technique, since that would be cheating, or at least, find out if they do it so I can punish them accordingly ;).

So, the general question is: Is there any way to disallow the use of Reflection in a piece of code I have dynamically loaded, or in any other sense disallow this code from accessing private fields (cheating).

Thanks in advance.

Alejandro Piad
  • 1,827
  • 1
  • 16
  • 23
  • 3
    Does the `optimum point` **have to** be in the `Function` class, or could you not just store it in another data structure not available in the reference dll you give your students? – Klaus Byskov Pedersen Jun 22 '12 at 12:43
  • 2
    Wouldn't it be simpler to just decouple the vector-evaluating-function from the optimum values? If you only pass them a `Func` they're going to have a hard time stealing the optimum answers. – Rawling Jun 22 '12 at 12:43
  • 3
    Also possible duplicate http://stackoverflow.com/questions/4447939/is-it-possible-to-disable-reflection-from-a-net-assembly – Rawling Jun 22 '12 at 12:45
  • 1
    Make `Function` a remoting proxy. – leppie Jun 22 '12 at 12:45
  • I think the `Func` solution works for this particular case. Thanks everyone. However, I still want to disable Reflection because in a general sense, I don't want any chance of cheating. I think the question link from @Rawling covers this ground too, but I don't find the answer very enlightening, as the whole CAS seems rather complex for what I want to achieve here. Is there a simpler way in .NET 4? Remember that only finding out about the cheating works for me too... – Alejandro Piad Jun 22 '12 at 12:57
  • 2
    I think the easiest, most foolproof way to prevent such cheating would be to require your students to provide their source code, so that you can check it for any reflection (look for `typeof(T)` or `GetType()`). – Tim S. Jun 22 '12 at 13:01
  • You could check `Assembly.GetReferencedAssemblies` to check they're not referencing the Reflection assembly? – Rawling Jun 22 '12 at 13:03
  • Its not Reflection in the mscorlib assembly? – Alejandro Piad Jun 22 '12 at 13:52
  • Ah, maybe, I'm not paying much attention. – Rawling Jun 22 '12 at 14:03
  • @AlejandroPiad: If you are capturing variables with that `Func`, it will also be visible in the debugger. – leppie Jun 22 '12 at 14:10
  • I don't really mind that they can see it in the debugger. First because the functions are randomly generated, and second because there is a part where I give the students this code so that they can train their algorithms. Its just in the moment of the competition that I want to disallow these cheating stuff. In fact, during the "testing" phase I can even provide public `XOpt` and `FOpt` properties, that in the tournament phase would throw exception or something. – Alejandro Piad Jun 22 '12 at 14:21

3 Answers3

2

Do they give you the source code? Write a separate tool that finds "using System.Reflection" and "System.Reflection." in the source. If they come up with a clever trick to avoid that, maybe they deserve the extra points they get by cheating. :)

Also, what about this in the code they use:

private double FakeOptimumPointWithAConvincingName{ get { return 12.07; } }

Then change that to this when you run your evaluator:

private double FakeOptimumPointWithAConvincingName{ get { throw new SomeoneCheatedException(); } }

There's a lot of other clever things to do along that line; point is you can use trickiness instead of technology to thwart them. And if they come up with better tricks, kudos. :)

tallseth
  • 3,635
  • 1
  • 23
  • 24
  • I would prefer not going through the source-code. I like the faking though, except because I need to keep changing the code back and forth whenever I need to give them the evaluator so that they can train. You get my up-vote anyway for the cleverness. – Alejandro Piad Jun 22 '12 at 14:16
  • Thanks. You don't have to keep rebuilding though, you just use a different build than them always. If you don't want them to have full access to your code, you should give them something that is slightly different. – tallseth Jun 22 '12 at 17:02
  • I like the two different builds option. I think i'll stick to this approach, given that I'm running out of time. Thanks @tallseth and everyone else for their useful answers. – Alejandro Piad Jun 27 '12 at 13:13
1

The short answer is that as long as the caller has full trust, until .Net 4.0 (see this for how to create sandboxed applications up to .Net. 3.5), you cannot avoid reflection discovery of private or internal methods.

For .Net 4, have you read Security Considerations for Reflection for .Net 4.0 on the MSDN?

aledeniz
  • 431
  • 3
  • 13
1

If you load the optimum values from a configfile the moment you need them it will be hard to reflect them before that time

IvoTops
  • 3,463
  • 17
  • 18
  • But the thing is that at the moment of evaluating the function in the user code that value is already loaded, and then they can reflect it at that specific time. – Alejandro Piad Jun 27 '12 at 13:11
  • 1
    Not if you make the loading of the variables lazy. Meaning they are retrieved only just before the code needs them and you zero the values again right after using them. In that case the window in which they can reflect will be very short. – IvoTops Jun 28 '12 at 09:58
  • You're right @IvoTops. It could be a good idea. I'm not so sure though on how to avoid them to do the same as me: loading that config file. If the config path is fixed then is a piece of cake, if its stored, they could reflect it, and so on. – Alejandro Piad Jun 29 '12 at 15:26