Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

[Tutorial] [.NET] Trial Limit Injection

Developer
Developer
Joined
Dec 11, 2010
Messages
2,955
Reaction score
2,688
Hello.

Just screwing around with Mono.Cecil. And I decided to make a 30 day limit check when you run a file through Mono.Cecil, don't judge my code please.

I coded this myself, by creating the function in C# and using a decompiler to locate the correct OpCodes.

You don't have to change to keep it days, you can change the method "FromDays" as you desire.

It calls on the Main(); function the DateVerify, and it will output an injected method such as;

Code:
public static void DateVerify()
{
	DateTime now = DateTime.Now;
	DateTime value = DateTime.Parse("7/03/2013 11:36:00 PM");
	if (now.Subtract(value) >= TimeSpan.FromDays(30.0))
	{
		throw new Exception("The time period has surpassed 30 days!");
	}
}

Code:
private double Time = 30;

  public void RunTask()
  {

    for (var modules = 0; modules < Program.Assembly.Modules.Count; modules++)
    {
    var module = Program.Assembly.Modules[modules];

    for (int types = 0; types < module.Types.Count; types++)
    {
    var type = module.Types[types];

    for (int methods = 0; methods < type.Methods.Count; methods++)
    {
    var method = type.Methods[methods];

    if (method.Name == "Main")
    {
    var methodDateCheck = new MethodDefinition("DateVerify", MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig, Program.Assembly.MainModule.Import(typeof(void)));

    InsertTimeCheck(type, methodDateCheck);

    type.Methods.Add(methodDateCheck);

    var worker = method.Body.GetILProcessor();

    var call = worker.Create(OpCodes.Call, methodDateCheck);
    worker.InsertAfter(method.Body.Instructions[0], call);
    worker.InsertAfter(call, worker.Create(OpCodes.Nop));
    }
    }
    }
    }
  }

  public void InsertTimeCheck(TypeDefinition type, MethodDefinition method)
  {
    var dateNow = DateTime.Now;
    var assembly = Program.Assembly;

    TypeReference declaringType = type;
    ModuleDefinition module = declaringType.Module;
    TypeReference variableType = module.Import(type);

    VariableDefinition result = new VariableDefinition("start", module.Import(typeof(DateTime)));
    method.Body.Variables.Add(result);

    result = new VariableDefinition("oldDate", module.Import(typeof(DateTime)));
    method.Body.Variables.Add(result);

    result = new VariableDefinition(module.Import(typeof(bool)));
    method.Body.Variables.Add(result);

    var worker = method.Body.GetILProcessor();

    worker.Append(worker.Create(OpCodes.Nop));
    worker.Append(worker.Create(OpCodes.Call, assembly.Import(typeof(DateTime).GetMethod("get_Now", Type.EmptyTypes))));
    worker.Append(worker.Create(OpCodes.Stloc_0));
    worker.Append(worker.Create(OpCodes.Ldstr, dateNow.ToString()));
    worker.Append(worker.Create(OpCodes.Call, assembly.Import(typeof(DateTime).GetMethod("Parse", new[] { typeof(string) }))));
    worker.Append(worker.Create(OpCodes.Stloc_1));
    worker.Append(worker.Create(OpCodes.Ldloca_S, (byte)0));
    worker.Append(worker.Create(OpCodes.Ldloc_1));
    worker.Append(worker.Create(OpCodes.Call, assembly.Import(typeof(DateTime).GetMethod("Subtract", new[] { typeof(DateTime) }))));
    worker.Append(worker.Create(OpCodes.Ldc_R8, Time));
    worker.Append(worker.Create(OpCodes.Call, assembly.Import(typeof(TimeSpan).GetMethod("FromDays", new[] { typeof(long) }))));
    worker.Append(worker.Create(OpCodes.Call, assembly.Import(typeof(TimeSpan).GetMethod("op_GreaterThanOrEqual", new[] { typeof(TimeSpan), typeof(TimeSpan) }))));
    worker.Append(worker.Create(OpCodes.Ldc_I4_0));
    worker.Append(worker.Create(OpCodes.Ceq));
    worker.Append(worker.Create(OpCodes.Stloc_2));
    worker.Append(worker.Create(OpCodes.Ldloc_2));

    var last = worker.Create(OpCodes.Ret);

    worker.Append(worker.Create(OpCodes.Brtrue_S, last));
    worker.Append(worker.Create(OpCodes.Nop));
    worker.Append(worker.Create(OpCodes.Ldstr, "The time period has surpassed 30 days!"));
    worker.Append(worker.Create(OpCodes.Newobj, assembly.Import(typeof(Exception).GetConstructor(new[] { typeof(string) }))));
    worker.Append(worker.Create(OpCodes.Throw));
    worker.Append(last);
  }
 
Elite Diviner
Joined
May 30, 2011
Messages
443
Reaction score
95
This is incredibly easy to inline out, just so you know. Emitting IL offers no advantage over doing it normally, but it is a lot more tedious.
 
Developer
Developer
Joined
Dec 11, 2010
Messages
2,955
Reaction score
2,688
This is incredibly easy to inline out, just so you know. Emitting IL offers no advantage over doing it normally, but it is a lot more tedious.

Yeah I know, but if you were to create your own .NET protection program and you'd have a 'free' version, this would be ideal to put this in. :)
 
Elite Diviner
Joined
May 30, 2011
Messages
443
Reaction score
95
Yeah I know, but if you were to create your own .NET protection program and you'd have a 'free' version, this would be ideal to put this in. :)

If you were to create your own packer in .NET, you're doing it wrong period. I mean, I guess it's not protecting state secrets or anything but it takes under a minute to just NOP the function out.
 
Developer
Developer
Joined
Dec 11, 2010
Messages
2,955
Reaction score
2,688
If you were to create your own packer in .NET, you're doing it wrong period. I mean, I guess it's not protecting state secrets or anything but it takes under a minute to just NOP the function out.

Who cares? It's a tutorial how to inject a method with Mono.Cecil - and that was merely an example.
 
Elite Diviner
Joined
May 30, 2011
Messages
443
Reaction score
95
Who cares? It's a tutorial how to inject a method with Mono.Cecil - and that was merely an example.

Well now, that's different. I thought this was about using it as an anti-debug technique. Now you should write a helper class that takes a .NET framework MethodInfo's IL stream and writes it to a Mono.Cecil ILProcessor.
 
Elite Diviner
Joined
Jul 25, 2013
Messages
466
Reaction score
55
Hopefully now on emulators dont come on licensed methods.. LOL!
 
Back
Top