After seeing this: Do access modifiers affect reflection also?
I tried using this, but it doesn't work:
How can I prevent reflection from executing my private methods?
After seeing this: Do access modifiers affect reflection also?
I tried using this, but it doesn't work:
How can I prevent reflection from executing my private methods?
If someone can currently use reflection on your private methods, then they already have enough access to sidestep anything else you place in their way. Running with less trust may be an option, but that is only to prevent things like plugins from having too much access - it won't stop a user with (say) admin access to the box, who can simply elevate the access.
If you don't want code running, don't put it in physical reach of the malicious user; keep it at a web-service or similar. Any code available to a user can be used directly, or indirectly by decompiling it (and deobfuscating it if needed). You can use some tricks to get in their way (checking the caller via the stacktrace etc), but that will not stop someone determined.
This is a late answer, but I consider it an update since all the answers were written before the release of .NET 4.6 in mid of 2015 which introduces a new assembly attribute called DisablePrivateReflection.
With that attribute tagged in your AssemblyInfo.cs
, you can disable reflection over private members of that assembly.
Example:
namespace DisablingPrivateReflection
{
public class Singleton
{
private Singleton()
{
}
}
}
And in your AssemblyInfo.cs
add this line:
[assembly: DisablePrivateReflection]
Then in your client assembly that is referencing the above assembly, this code would fail at run-time:
var singleton = Activator.CreateInstance(typeof(Singleton), true);
The exception thrown is of type MethodAccessException with message:
Attempt by method 'Program.Main(System.String[])' to access method 'DisablingPrivateReflection.Singleton..ctor()' failed.
System.MethodAccessException
when I use this with ConfuserEx –
Ouidaouija How can I protect my private funcs against reflection executing?
You can change your security policy so that the code does not have permission to do "private reflection" when you run it.
Of course, that will only affect your machine. If you want to affect someone else's machine, send an email to their machine administrator and ask the administrator to change the user's security policy so that it does not have permission to do "private reflection". That's the person who owns the machine and the network it runs on; obviously you do not have the ability to change the security settings on a network you don't own.
Note of course that rights more powerful than private reflection also have to be restricted. It does no good to set a policy that says, for example "private reflection rights are denied, but the right to change security policy is granted". The user could then just change security policy to re-grant private reflection to themselves.
You'll also have to restrict ability to access the disk. Someone who can access the disk can simply read the code out of the assembly, change the private metadata to public, and load the assembly normally.
So, your mission is to convince all of the machine administrators of the world to not allow their users to access their own disks. I suspect you will be unsuccessful; I suggest that you find a different way to protect your functions from abuse.
Access modifiers are not a security mechanism.
If if you could prevent your function from being called via reflection, the user can just decompile your program, extract that function, put it in a new assembly and execute it.
using System;
using System.Reflection;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
class Person
{
private string SayInternalSecure()
{
if (!PrivacyHelper.IsInvocationAllowed<Person>())
throw new Exception("you can't invoke this private method");
return "Internal Secure";
}
private string SayInternal()
{
return "Internal";
}
public string SaySomething()
{
return "Hi " + this.SayInternal();
}
public string SaySomethingSecure()
{
return "Hi " + this.SayInternalSecure();
}
public void BeingCalledBy()
{
Console.WriteLine("I'm being called by: " + new StackTrace().GetFrame(1).GetMethod().Name);
}
}
public class MethodBaseComparer : IEqualityComparer<MethodBase>
{
private string GetMethodIdentifier(MethodBase mb)
{
return mb.Name + ":" + String.Join(";", mb.GetParameters().Select(paramInfo=>paramInfo.Name).ToArray());
}
public bool Equals(MethodBase m1, MethodBase m2)
{
//we need something more here, comparing just by name is not enough, need to take parameters into account
return this.GetMethodIdentifier(m1) == this.GetMethodIdentifier(m2);
}
public int GetHashCode(MethodBase mb)
{
return this.GetMethodIdentifier(mb).GetHashCode();
}
}
class PrivacyHelper
{
static Dictionary<Type, MethodBase[]> cache = new Dictionary<Type, MethodBase[]>();
public static bool IsInvocationAllowed<T>()
{
Type curType = typeof(T);
if (!cache.ContainsKey(curType))
{
cache[curType] = curType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).ToArray();
}
//StackTrace.GetFrame returns a MethodBase, not a MethodInfo, that's why we're falling back to MethodBody
MethodBase invoker = new StackTrace().GetFrame(2).GetMethod();
return cache[curType].Contains(invoker, new MethodBaseComparer());
}
}
public class App
{
public static void CheckCaller()
{
Person p = new Person();
Console.WriteLine("- calling via delegate");
Action action = p.BeingCalledBy;
action();
Console.WriteLine("- calling via reflection");
MethodInfo method = typeof(Person).GetMethod("BeingCalledBy", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
Console.WriteLine(method.Invoke(p, null));
Console.WriteLine("- calling via delegate again");
action = (Action)(Delegate.CreateDelegate(typeof(Action), p, method));
action();
}
public static void Main()
{
Console.WriteLine("Press key to run");
Console.ReadLine();
CheckCaller();
Person p = new Person();
Console.WriteLine(p.SaySomething());
Console.WriteLine(p.SaySomethingSecure());
MethodInfo privateMethod = typeof(Person).GetMethod("SayInternal", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
Console.WriteLine("invoking private method via Reflection:");
Console.WriteLine(privateMethod.Invoke(p, null));
Console.WriteLine("----------------------");
privateMethod = typeof(Person).GetMethod("SayInternalSecure", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
Console.WriteLine("invoking secured private method via Reflection:");
try
{
Console.WriteLine(privateMethod.Invoke(p, null));
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
There is no way to do that. Why do you want to prevent execution of your private funcs? Usually, if someone uses reflection, he knows what he's doing.
You can not, the modifiers are only for developers to have proper encapsulation. At the runtime it could be sad that everything is on the same level.
The reflection mechanics, is used usually by application that need to call some pre-configured methods (older ORM) or display them (IDE). It wold be really hard if this mechanism would not be able to do that.
Though I absolutely agree with the idea of access modifiers not being a security feature, just for the sake of programming I've been thinking a bit about this, and I've got a simple, not much useful mechanism, fight Reflection with Reflection :-)
Be advised, it's just a silly proof of concept, I'm not taking into account Generic methods, it would need changes for that...
The idea is, at the start of every private method that you want to secure from being "illegally" invoked, you just check via Reflection that you're being invoked from another method in that class, not from outside. So you would use: new StackTrace().GetFrame(1).GetMethod(); to get the MethodBase of your invoker and would compare it against the list of MethodInfos for your class.
You can add it to a helper class (anyway you'll need a IEqualityComparer to compare MethodBases...
One problem is that you would also be preventing some correct invocations, like invoking it through a delegate or through Reflection from another of your methods... so you should be careful with when you use it.
You can my implementation here
I use eazfuscator and it making methods virtual seems to do a good job hiding the method.
Then in methods, I like to protect I will alter the code in release mode to give null pointer exceptions to start a task that will generate a null pointer and execute it without the code having a callstack.
There are not a lot of developers that can work with your production code without debugging...
#if !DEBUG
#pragma warning disable CS8618
[System.Diagnostics.DebuggerStepThrough, System.Diagnostics.DebuggerNonUserCode]
[System.ComponentModel.Browsable(false)]
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
#endif
namespace MyApp.Infrastructure.LicenseManager
{
[Obfuscation(Feature = "apply to member * when method or constructor: virtualization", Exclude = false)]
internal sealed class LicenseManager(ISomeClass parameter, ILoggerFactory? factory = null)
{
//hide the name space for reverse engineering the naming scheme
_logger = factory?.CreateLogger("MyApp.LicenseManager")
#if !DEBUG
if (System.Diagnostics.Debugger.IsAttached)
{
//send computer information for license violation and prosecution then crash
System.Threading.ThreadPool.UnsafeQueueUserWorkItem(SystemCrasher.SendAbuseAndCrash);
//send a log entry, of don't if you wish to give no warning
_logger?.LogWarning(Walter.BOM.LogEvents.FireWall_Warning, "Debugging will cause the developer to generate null pointer exceptions in administration context");
return;
//all class initiolizers will stay null
}
#endif
_myClass= parameter;
}
#if !DEBUG
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
#endif
If your code is consumed by other code in a shared DLL (like in NuGet packages) then the above method will prevent you from being popular with your colleagues, you need a "Debug" friendly method, using a method proxy may do the trick for you in combination with obfuscation.
[Obfuscation(Feature = "virtualization", Exclude = false)]
private void MyMethod(int parameter)
{
MyMethodProxy();
//do some code
}
private void MyMethodProxy([CallerMemberName] string? calledBy = null)
{
if (!string.Equals(nameof(MyMethod), calledBy, StringComparison.Ordinal))
{
throw new LordOfTheRingsException("You shall not pass!!");
}
}
By using the NameOf method you are able to survive the non-printable characters from the Obfuscator's renaming scheme.
I use a few other options but this would limit you automate and use Aspect-oriented frameworks like postsharp
Hope it helpsenter code here
I know this is old, but basically to do what you are asking is relatively imposible in .NET, but there are some things you can do to lessen the surface area, and they generally require more work. Ultimately what you are trying to prevent is a handle to a type, right? Consider the following scenario.
public class OuterView
{
protected internal class HiddenMethods
{
public static void DoMoreWork(string msg)
{
Console.WriteLine(msg);
}
}
public void DoWork(string msg)
{
HiddenMethods.DoMoreWork(msg);
}
}
Assuming this is in a library that you don't want to grant direct access to the underlying methods - Assembly.GetTypes() won't return the nested class, and there is no reference from the HiddenMethods in the class that you do have access to (OuterView). Save the state in the OuterView, and pass it into the HiddenMethods with each static call. Ultimately, anyone with enough access to create a PEReader can still access your HiddenMethods. But the above works for 9 out of 10 scenarios.
I would try to parse stack trace (https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics?redirectedfrom=MSDN&view=netframework-4.7.2) and check for dynamic invocation...
© 2022 - 2025 — McMap. All rights reserved.
[assembly: DisablePrivateReflection]
inAssemblyInfo.cs
: msdn.microsoft.com/en-us/library/… – Terzetto