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

using System;

namespace Victim
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Console.ReadLine();
}
}
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }把上面的程序编译成一个程序集Victim,执行程序,它会在控制台出版Hello,world。

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

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

using System;
using Mono.Cecil;
using Mono.Cecil.Cil;

现在,开始加载程序集

AssemblyDefinition asm= AssemblyFactory.GetAssembly("Victim.exe");

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }添加返回值为void类型的Test方法

//Declare returntype "void"
TypeReference returntype = asm.MainModule.Import(typeof(void));
//Define Methodsignature "private static void Test()"
MethodDefinition testmethod = new MethodDefinition("Test",MethodAttributes.Private|MethodAttributes.Static, returntype);

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }Test方法的访问级别为private,static

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

//Push string onto the stack
Instruction msg = testmethod.Body.CilWorker.Create(OpCodes.Ldstr, "Hello from Test()");
//Import external method reference to Console.WriteLine()
MethodReference writeline = asm.MainModule.Import(typeof(Console).GetMethod("WriteLine",new Type[]{typeof(string)}));

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }加载常量为方法的签名,在控制台上打印出来

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

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

//Generate stack-push
testmethod.Body.CilWorker.Append(msg);
//Generate call to WriteLine()
testmethod.Body.CilWorker.InsertAfter (msg,testmethod.Body.CilWorker.Create(OpCodes.Call,writeline));
//Generate return
testmethod.Body.CilWorker.Append (testmethod.Body.CilWorker.Create (OpCodes.Ret));

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

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

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }最后,修改程序,让它调用被注入的Test方法

  //Get Method reference with Name test,
MethodReference testmethod_ref = null;
foreach (MethodDefinition mdef in asm.MainModule.Types["Victim.Program"].Methods)
{
if (mdef.Name == "Test")
{
testmethod_ref=asm.MainModule.Import(mdef);
} } //Create call to the reference
Instruction call_test = testmethod.Body.CilWorker.Create(OpCodes.Call, testmethod_ref);
//Insert reference
asm.EntryPoint.Body.CilWorker.InsertBefore (asm.EntryPoint.Body.Instructions[0],call_test);

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

保存程序集到磁盘文件中

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

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

using System;

namespace Victim
{
class Program
{
static void Main(string[] args)
{
Test();
Console.WriteLine("Hello World!");
Console.ReadLine();
} private static void Test()
{
Console.WriteLine("Hello from Test()"); }
}
}

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

如果被修改的方法,是许可验证,或是注册算法验证,这一方便可以直接把它的指令清空,另存为一个程序集文件,达到绕过验证的目的。

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

运用Mono.Ceci类库修改.NET程序集 走上破解软件的道路的更多相关文章

  1. 利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习)

    原文 利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习) Mono.Cecil是一个强大的MSIL的注入工具,利用它可以实现动态创建程序集,也可以实现拦截器横向切入动态方法,甚至还 ...

  2. 使用VS中自带的一键打包功能将我们的ASP.NET Core类库打包并将程序包(类库)发布到NuGet平台上进行管理

    本章将和大家简单分享下如何使用VS中自带的一键打包功能将我们的ASP.NET Core类库打包并将程序包(类库)发布到NuGet平台上进行管理. 一.注册并登录NuGet平台 NuGet官网:http ...

  3. 修改MAC地址的方法 破解MAC地址绑定(抄)

    修改MAC地址的方法 破解MAC地址绑定   网卡的MAC地址是固化在网上EPROM中的物理地址,是一块网卡的“身份证”,通常为48位.在平常的应用中,有很多方面与MAC地址相关,如有些软件是和MAC ...

  4. IIS7.5修改asp的文件上传限制方法

    第一.IIS7.5修改asp的文件上传限制方法 1.打开IIS 2.打开面板中的应用程序开发 asp 3.找到最后的限制属性 4.修改其中的最大请求实体主体限制的值:默认为200000字节,等于195 ...

  5. 【文学文娱】《屌丝逆袭》-出任CEO、迎娶白富美、走上人生巅峰

    本文地址:http://www.cnblogs.com/aiweixiao/p/7759790.html 原文地址:(微信公众号) 原创 2017-10-30 微信号wozhuzaisi 程序员的文娱 ...

  6. 修改ASP.NET文件上传大小限制

    转自:http://www.hello-code.com/blog/asp.net/201603/5954.html 要点: 1.web.config中的<httpRuntime maxRequ ...

  7. 数据库最佳实践:DBA小马如何走上升值加薪之路?

    DBA可能是互联网公司里面熬夜最多,背锅最多的岗位之一,腾讯云数据库团队的同学结合自身的成长经历,用漫画的形式为我们分享了一位DBA是如何从菜鸟成长为大神,走上升职加薪,迎娶白富美之路的. 此文已由作 ...

  8. 神户制钢坑了500家企业 百年老店为何走上邪路?(企业经营再艰难,也不能降低产品质量,甚至偷工减料,同样适用于IT行业)

    神户制钢这颗烂萝卜,拔出它之后带出的泥越来越多.上周五社长川崎博也又开了记者会,再次道歉,而受到其数据造假影响的客户数量也从200家飙升到500家. 日本政府给神户制钢两周时间调查,还要在一个月内公布 ...

  9. 是什么让我走上Java之路?

    选择方向,很多人都为根据自己的兴趣爱好和自己的能力所长而作出选择.那么是什么让我走上Java之路? 整个高三我有两门课程没有听过课,一门是数学,一门是物理.当时候物理没有听课的原因很简单,我有一本&l ...

随机推荐

  1. [转] 在Linux平台使用mhVTL虚拟化磁带库

    原文来自:LIUBINGLIN ---- http://blog.itpub.net/23135684/viewspace-1307626/ <在Linux平台安装mhVTL虚拟化磁带库> ...

  2. java读取properties配置文件方法(一)

    为了修改项目参数方便,需要使用properties配置文件: 首先是需要三个jar包(不同的jar包,读取配置文件的方式会有所不同,这里使用的是2.6版本的jar包) commons configur ...

  3. iOS.StaticLibrary.1-avoid-duplicate-symbol-in-static-library[draft]

    Avoid duplicate symbol in static library and its customer 发布static library给使用者使用.在实际的工程实践中,iOS静态库一般会 ...

  4. 谈谈Linux下动态库查找路径的问题

    学习到了一个阶段之后,就需要不断的总结.沉淀.清零,然后才能继续"上路".回想起自己当年刚接触Linux时,不管是用源码包编译程序,还是程序运行时出现的和动态库的各种恩恩怨怨,心里 ...

  5. DIV布局-高度不同DIV,自动换行并对齐

    最近弄了一个动态添加div框,每个div框内容有多有少,要支持div高度自适应,还要添加的div自动追加,并且换行还要保持每行对齐. 刚开始的效果: 要改啊,搞不定,问了UI高手,终于给出了完美解决方 ...

  6. apktool更新,JDK升级配置

    最近使用apktool反编译apk中的xml文件总是失败. Exception in thread "main" brut.androlib.AndrolibException: ...

  7. win2008server系统下文件替换权限

    因为那里的文件默认只有系统才有修改权限.选中要替换的文件(一次只能选一个),属性->安全->高级->所有者(选更改)->高级->立即查找->选择 Everyone, ...

  8. Oracle每天自学一点点 常用Oracle

    创建表空间:create tablespace crmtb datafile 'F:\Oracle\oradata\crmtb.dbf' size 100M;删除表空间:DROP TABLESPACE ...

  9. HDU 1885 Key Task (BFS + 状态压缩)

    题意:给定一个n*m的矩阵,里面有门,有钥匙,有出口,问你逃出去的最短路径是多少. 析:这很明显是一个BFS,但是,里面又有其他的东西,所以我们考虑状态压缩,定义三维BFS,最后一维表示拿到钥匙的状态 ...

  10. 12.我们不是在真空里谈软件工程, 软件要运行在硬件芯片上面, 下面看看一个计算机芯片的发展历史: http://perspectives.mvdirona.com/2014/09/august-21-2014-computer-history-museum-presentation/ http://mvdirona.com/jrh/TalksAndPapers/DileepBhandar

    电脑芯片的诞生和发展是20世纪最伟大的发明之一,芯片技术决定了计算机升级换代的速度,决定了计算机小型化实现的程度,决定了计算机智能化的程度,决定了计算机普及化的应用深度. 1971年11月15日,英特 ...