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

Mono.Cecil是一个强大的MSIL的注入工具,利用它可以实现动态创建程序集,也可以实现拦截器横向切入动态方法,甚至还可以修改已有的程序集,并且它支持多个运行时框架上例如:.net2.0/3.5/4.0,以及silverlight程序

官方地址:http://www.mono-project.com/Cecil

首先,我先假想有一个这样的商业组件,该组件满足了以下条件:

1. 该程序集的代码被混淆过了

2. 该程序集被强命名签名过了

3. 该程序集的UI界面被加上了版权信息,例如水印等等

这里我引用的是之前写的一篇文章中的用户登录的组件(http://www.cnblogs.com/liping13599168/archive/2010/05/07/1729357.html),并将其进行改造成一个Silverlight组件,项目结构如图:

其中BusinessComponent类库作为选定的”商业组件",这里编写一个CopyRight类,作为水印的打印信息:

internal sealed class Copyright 

    internal void SetRightInfo(TextBlock textBlock) 
    { 
        textBlock.Text = "This is a watermark."; 
    } 
}

运行效果为:

可以看到组件上面附带一个版权信息效果

接着,要对BusinessComponent进行强命名签名,选择项目右键,如下设置:

新建一个snk文件,这个文件利用RSA加密包含着公钥和私钥的信息,对该组件编译会把它编译进去了。

这个snk到底做什么用的呢?一会儿大家看着就知道了。

最后,我要利用Dotfuscator混淆工具,对于BusinessComponent.dll进行代码混淆

由于我这里的Dotfuscator使用的老版本的4.2,所以不支持对于Sliverlight程序集的混淆,有兴趣的朋友可以自己下载试试,官方地址是:http://www.preemptive.com

好了,到这里,一个BusinessComponent商业组件的雏形设计好了。现在拿起手上的工具——Mono.Cecil去改造它了。

首先官方下载了一个mono.cecil的项目,打开工程主动去编译一下,在目录Silverlight_Release就能够获取Mono.Cecil.dll

那么,把它引入到项目中来,在页面中加入一个按钮,点击触发事件程序:

var entryPointPart = Deployment.Current.Parts.First(asmPart => asmPart.Source == "BusinessComponent.dll"); 
var entryPointResourceInfo = Application.GetResourceStream(new Uri(entryPointPart.Source, UriKind.Relative)); 
var module = ModuleDefinition.ReadModule(entryPointResourceInfo.Stream);
var type = module.Types.FirstOrDefault(o => o.Name == "Copyright"); 
var method = type.Methods.FirstOrDefault(o => o.Name == "SetRightInfo"); 
Instruction instruction = method.Body.Instructions[2]; 
instruction.Operand = ""; 
module.Write("C:\\BusinessComponent.dll"); 

其中module获取程序集中的Module模块,module.Types可以得到程序集中的所有类型:

选择Type的类型名称为Copyright,通过type.Methods可以得到该类型得到的所有方法:

选择Method的名称为SetRightInfo,method.Body.Instructions可以得到该方法里面的IL堆栈调用信息:

我们看到索引2这行的信息,ldstr是定义一个字符串常量的方式,而索引3通过索引2行的值,赋值给TextBlock中,请查看Copyright的代码就可以知道。于是:

Instruction instruction = method.Body.Instructions[2]; 
instruction.Operand = "";

这样就可以把该水印信息去除了,是不是很简单呢:)

最后一行module.Write("C:\\BusinessComponent.dll");就是将修改过后的程序集重新写入到一个新的程序集中;

执行程序,在C盘就得到一个BusinessComponent的新程序集了。

现在,我重新引入该新的程序集,看是否水印信息会被去掉,重新编译,发现编译出错:

这是为什么?这就是我上面提到的利用snk的强命名签名了,它的目的是为了防止你的程序集被非法篡改而设置的,而需要破解它就需要它的私钥了,可是作为一个真正的商业组件,我们是没有办法得到它的私钥,那是不是意味着没办法破解了呢。

那么我重新通过sn.exe进行重新签名:

sn –R BusinessComponent.dll mykey.snk

显示公钥不配对。这个是显然的,因为之前通过VS的Sign标签人工设置business.snk,它采用的是这个文件的公钥,而mykey.snk就要采用它自己的公钥了。

既然无法破解,那我就去改掉它的签名,利用我自定义的公钥和私钥去做签名,而恰恰好,Mono.Cecil就可以满足你的需要。

打开VS2010命令提示窗口,在C盘上输入:

sn -k mykey.snk

这样就随机产生了一条包含公钥和私钥的RSA文件,接着要抽取出它的公钥,输入:

sn –p mykey.snk mykey.PublicKey

紧接着输入:

sn –tp mykey.PublicKey

就可以得到公钥的数据,例如publicKey以及publicKeyToken

得到了两串字符串,把它们都复制出来,继续在刚才的按钮代码中补充:

var entryPointPart = Deployment.Current.Parts.First(asmPart => asmPart.Source == "BusinessComponent.dll"); 
var entryPointResourceInfo = Application.GetResourceStream(new Uri(entryPointPart.Source, UriKind.Relative)); 
var module = ModuleDefinition.ReadModule(entryPointResourceInfo.Stream); 
module.Assembly.Name.PublicKey = this.GetPublicKey(); 
module.Assembly.Name.PublicKeyToken = this.GetPubliKeyToken(); 
private byte[] GetPublicKey() 

    string s = "0024000004800000940000000602000000240000525341310004000001000100c5f2c7d8057257ea3640b93b7a98b1a5501718196589973b09b94cf47fb246c8ad86ae688caa36959d9793702c27ce198a447d69ba0ddac70075fab16748999f066795de472dfb5cd9347a10f967e750ca388aaa9a66619291003345b0176dec0008d3d88986c4605c0d60e3b6563f96984c6d28aeb4bf2d672e8d2d2123c394";
    return this.StrToHexBytes(s); 

private byte[] GetPubliKeyToken() 

    string s = "d2850434514ae5ca"; 
    return this.StrToHexBytes(s); 

private byte[] StrToHexBytes(string hexString) 

    hexString = hexString.Replace(" ", ""); 
    if ((hexString.Length % 2) != 0) 
        hexString += " "; 
    byte[] returnBytes = new byte[hexString.Length / 2]; 
    for (int i = 0; i < returnBytes.Length; i++) 
        returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); 
    return returnBytes; 

其中StrToHexBytes方法,将字符串转换为十六进制的字节数组

重新编译执行,它的公钥信息就已经编译进去了,同样在C盘生成BusinessComponent.dll新程序集

这个时候,先不着急引入程序集,先对新程序集通过私密对其进行重新签名,输入命令:

sn –R BusinessComponent.dll mykey.snk

OK,现在就可以重新引入了,这个时候再重新编译代码:

编译通过了。

现在运行下程序(这里要注意,你必须将SilverlightApp程序切换到OOB模式,才可以修改程序集):

水印信息已经被去除了:)

Mono.Cecil还可以用来做很多东西,比如说可以在一个方法中增加其他代码,能够细到IL中的每一个执行步骤,所以通过它可以做很多有意思的东西,比如说单元测试中的Mock对象以及性能上更佳的反射功能。

附上本文源代码:SilverlightMonoCecilDemo.rar

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

  1. 利用催眠技巧绕开 OpenAI 的内容政策限制(仅供研究使用)

    利用催眠技巧绕开 OpenAI 的内容政策限制(仅供研究使用) 技巧: 生成示例: 声明:请仅作研究之用,不要违规使用! 在破解成功后,通过屏蔽moderetions的api请求,可以绕过OpenAI ...

  2. 利用催眠技巧绕开OpenAI的内容政策限制(仅供研究使用)

    fork的仓库:https://github.com/JanYork/chatgpt-chinese-prompt-hack 声明:请仅作研究之用,不要违规使用! 在hack成功后,通过屏蔽moder ...

  3. Android 开发中动态修改StatusBar 的字体颜色(仅可以黑白)

    在开发中,产品要实现一个点击搜索,然后改变statusbar的字体颜色,百度了一通,发现,有一个比较好的blog 可以实现该效果 ,正好可以实现该效果,不论如何先上效果图: 将工具类代码贴上来 这个方 ...

  4. Mono.Cecil使用示例之使指定程序集成为UnityEditor.dll的友元程序集

    Mono.Cecil使用示例之使指定程序集成为UnityEditor.dll的友元程序集 Mono.Cecil是一个开源的库,使用Mono.Cecil可以非常方便的在代码中修改C#程序集.在Unity ...

  5. 编译时MSIL注入--实践Mono Cecil(1)

    紧接上两篇浅谈.NET编译时注入(C#-->IL)和浅谈VS编译自定义编译任务-MSBuild Task(csproject),在第一篇中我们简单研究了c#语法糖和PostSharp的MSIl注 ...

  6. 使用Mono.Cecil辅助ASP.NET MVC使用dynamic类型Model

    使用Mono.Cecil辅助ASP.NET MVC使用dynamic类型Model 2011-09-06 00:21 by 老赵, 8645 visits 这也是之前在珠三角技术沙龙上的示例之一,解决 ...

  7. C#利用反射实现动态加载程序集简单案例

    反射可以不但用来读取元数据,还可以使用反射从编译时还不清楚的类型中动态创建程序集,此案例摘自C#高级编程. 首先先创建一个控制台应用程序,然后添加一个类库,类库名称为CalculatorLib,如下图 ...

  8. 运用Mono.Cecil 反射读取.NET程序集元数据

    CLR自带的反射机智和API可以很轻松的读取.NET程序集信息,但是不能对程序集进行修改.CLR提供的是只读的API,但是开源项目Mono.Cecil不仅仅可以读取.NET程序集的元数据,还可以进行修 ...

  9. 利用反射动态修改 EasyPoi 导出Excel表格标题名称

    EasyPoi 动态修改表格标题名称 需求 代码实现 1.实体类 @Data @Accessors(chain = true) public class AccountVO implements Se ...

最新文章

  1. UE5使用MetaHuman构建超现实的角色
  2. SQLDMO- (数据备份与恢复篇)
  3. IJCV2021 人脸关键点检测器PIPNet
  4. Android将数据库数据导出成excel格式的文本(CSV)
  5. Go工程化 - 手摸手带你理解依赖注入
  6. mail函数 开启php,PHP mail函数使用详解
  7. python重新安装_重新安装python
  8. [NVIDIA] Ubuntu 16.04 安装 nvidia-384 + cuda-9.0
  9. struts2的优缺点
  10. Sublime Text 使用记录汇总
  11. pscp新机器提示Store key in cache? 重装后提示Update cached key?的解决方案
  12. Java程序崩溃原因分析:错误日志分析及解决(Cannot allocate memory)
  13. 详解区块链(很详很长)
  14. hiredis-vip
  15. 超详细易理解的HTTPS(易上手哦)
  16. vmware storage -2
  17. 【Web开发】纯前端实现科技企业官网首页
  18. 万向节死锁_欧拉角的奇异问题和万向节死锁问题,会对实际的哪些应用带来什么问题?...
  19. 信息流优化师以后的路在哪里?
  20. 仓库物品领用吉度PDA出入库盘点扫码方案

热门文章

  1. 精准钓鱼***,只有榜上有名的人才会被***
  2. PPPOE/PPPOA白皮书小结
  3. javascript onmouseout问题解决方案
  4. 使用 Artifactory 1分钟搭建 CocoaPod 私服
  5. python添加模块搜索路径
  6. consul agent的一个故障
  7. 【转载】浅谈缺陷截图处理
  8. 网页中PNG透明背景图片的完美应用
  9. Kmeans聚类算法分析(转帖)
  10. PL/SQL 操作数据库常见脚本