您的位置:首页 > 其它

运用Mono.Ceci类库修改.NET程序集 走上破解软件的道路

2013-07-02 23:12 375 查看

运用Mono.Ceci类库修改.NET程序集走上破解软件的道路

代码注入在C++时代很流行,主要是对现有的程序做一些修改,以达到预期的目的。一部分的破解程序,注册机也是借助于此方法,让被注入的程序绕过验证,达到破解的目录。在.NET中,借助于Mono.Cecil程序集,注入代码也相当容易。请看下面的代码,将要被注入的程序:

usingSystem;

namespaceVictim
{
classProgram
{
staticvoidMain(string[]args)
{
Console.WriteLine("HelloWorld!");
Console.ReadLine();
}
}
}

把上面的程序编译成一个程序集Victim,执行程序,它会在控制台出版Hello,world。

下面我做一个新的程序,它修改上面的程序集,在Program类型中定义一个新的Test方法,修改Main方法调用我注入的Test方法。

先添加对程序Mono.cecil的引用。

usingSystem;
usingMono.Cecil;
usingMono.Cecil.Cil;

现在,开始加载程序集

AssemblyDefinitionasm=AssemblyFactory.GetAssembly("Victim.exe");

添加返回值为void类型的Test方法

//Declarereturntype"void"
TypeReferencereturntype=asm.MainModule.Import(typeof(void));
//DefineMethodsignature"privatestaticvoidTest()"
MethodDefinitiontestmethod=newMethodDefinition("Test",MethodAttributes.Private|MethodAttributes.Static,returntype);

Test方法的访问级别为private,static

给Test方法增加方法体,参考下面的代码写法

//Pushstringontothestack
Instructionmsg=testmethod.Body.CilWorker.Create(OpCodes.Ldstr,"HellofromTest()");
//ImportexternalmethodreferencetoConsole.WriteLine()
MethodReferencewriteline=asm.MainModule.Import(typeof(Console).GetMethod("WriteLine",newType[]{typeof(string)}));

加载常量为方法的签名,在控制台上打印出来

这种写法,与MSIL代码一致,C#代码被翻译成MSIL,生成的代码就是这样的。

最后生成Test方法,代码如下

//Generatestack-push
testmethod.Body.CilWorker.Append(msg);
//GeneratecalltoWriteLine()
testmethod.Body.CilWorker.InsertAfter(msg,testmethod.Body.CilWorker.Create(OpCodes.Call,writeline));
//Generatereturn
testmethod.Body.CilWorker.Append(testmethod.Body.CilWorker.Create(OpCodes.Ret));

asm.MainModule.Inject(testmethod,asm.MainModule.Types["Victim.Program"]);

最后,修改程序,让它调用被注入的Test方法

//GetMethodreferencewithNametest,
MethodReferencetestmethod_ref=null;
foreach(MethodDefinitionmdefinasm.MainModule.Types["Victim.Program"].Methods)
{
if(mdef.Name=="Test")
{
testmethod_ref=asm.MainModule.Import(mdef);
}

}

//Createcalltothereference
Instructioncall_test=testmethod.Body.CilWorker.Create(OpCodes.Call,testmethod_ref);
//Insertreference
asm.EntryPoint.Body.CilWorker.InsertBefore(asm.EntryPoint.Body.Instructions[0],call_test);

保存程序集到磁盘文件中

AssemblyFactory.SaveAssembly(asm,"patched.exe");


现在,最初始的程序集代码看起来是这样的

usingSystem;

namespaceVictim
{
classProgram
{
staticvoidMain(string[]args)
{
Test();
Console.WriteLine("HelloWorld!");
Console.ReadLine();
}

privatestaticvoidTest()
{
Console.WriteLine("HellofromTest()");

}
}
}

可以用Reflector来查看生成的Patched.exe,应该与这里的一致。

如果被修改的方法,是许可验证,或是注册算法验证,这一方便可以直接把它的指令清空,另存为一个程序集文件,达到绕过验证的目的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: