揭开.NET程序保护的秘密

news/2024/5/19 13:55:08
.NET程序保护主要有如下几种形式
1.  混淆
2.  编译到本地代码
3.  把代码隐藏在资源中

1.  混淆
这部分的保护软件以Dotfuscator和XenoCode为代表。Dotfuscator是比较初级的混淆器,采取的主要策略是名字混淆,通过把类名、方法名、变量名改成很短的形式,目的是破坏有意义的变量命名。

 
WebCombo.NET 2.0,采用Dotfuscator进行变量名混淆

名字混淆的缺点在于
a. 名字长度虽短,但是依然容易进行代码分析。对于熟悉汇编语言的逆向工程师,改成短的变量名对阅读代码基本不存在任何难度。
b. 在应用反射(Reflector)机制的程序中不能很好的工作。

XenoCode是稍微高级的混淆器,它采用的技术除了变量名字混淆外,还加入流程混淆。目的是阻止.NET Reflector对其直接进行反编译。大部分采用了混淆器的.NET软件都是使用该混淆器进行保护。

尽管.NET Reflector不能直接反编译为c#,但是我们在语言栏把它切换到IL,依然可以看到中间语言!

.NET Reflector 之所以不能反编译,是因为XenoCode把中间语言拆成若干段,每段用br或者br.s(相当于jmp)衔接起来。至于为什 么.NET Reflector不会解释成goto,我也不太清楚,估计是因为与一条完整的C#语句等价的IL程序段被拆开两半。(哪位大侠知 道请指教一下)。反混淆的方法也非常直接,把代码段重新排序就可以了,反混淆的结果如图:

用ida pro分析的流程图,未进行反混淆处理前:

反混淆处理后:

对 一个几M甚至几十M的il源文件进行反混淆不是一件轻松的事情,因此写了一个用于重新排序的小程序,正式做法类似编译原理的语句优化步骤,先把每个 method分块,每个块的第一个语句是入口点,最后一个语句必须是无条件的控制转移语句(br、leave、ret等)。然后把转跳点合并。这里遇到一 个问题,遇到入口被method内部多处引用时,只能随机选择一个。因此部分函数还需要人手调整。但毕竟顺序结构还是占绝大多数,所以人手调整的比例还是 很少的。我在转换一个几百个类的dll时,需要调整的类也只有10多个,是可以接受的。

显然,如果在有辅助工具的帮助下,XenoCode流程混淆下的程序也不难做到反混淆。加上Reflector的FileDisassembler插件,完全可以把整个assembly的源码导出到本地目录下,再用IDE环境把项目源码导入后进行分析。

2.编译到本地代码
保 护软件以RemoteSoft Protector为代表,应用该保护方法的软件较少,因为正版的 RemoteSoft Protector需要几千美金。其中代表软件为WebGrid.NET 3.5。在发布的dll里面包 括.NET assembly以及一个名为rscoree.dll的一般Win32 PE文件。查看rscoree.dll可以发现 导出表仅有_RSDllMain, _RSEEStartup, _RSEEUpdate, _RSExeMain四项, 用Ollydbg打开发现并没加密。用Reflector打开.NET assembly,无论是用C#语言查看还是直接查看IL,所有 method都只看到空的函数体。只有发现<PrivateImplementationDetails>中存在对rscoree.dll的 引用信息。
.class private auto ansi <PrivateImplementationDetails>
      extends object
{
      .method assembly hidebysig static void $$method-1() cil managed noinlining
      {
      }

      .method assembly hidebysig static void $$method-2() cil managed noinlining
      {
      }

      .method private static pinvokeimpl("rscoree.dll" ansi nomangle) void _RSEEStartup(int32 A_0) cil forwardref managed
      {
      }

      .method private static pinvokeimpl("rscoree.dll" ansi nomangle) void _RSEEUpdate(native int A_0) cil forwardref managed
      {
      }


      .field private static bool $$started-1

      .field private static bool $$started-2

}
另 外听说有一款国产的保护软件MaxtoCode,分普及版和专业版,普及版可以免费使用。看软件的介绍信息疑也是采用类似技术。缺点是代码编译成了 naïve code,所以只能在windows平台运行。逆向人员需要同时懂得.NET虚拟机的知识和Win32汇编,要求较高。

3.这是一种很另类的保护方法(也许是我孤陋寡闻),目前只知道Reflector本身是采用这种方法来保护自身的核心代码库。暂时还没时间去研究
















本文转自周金桥51CTO博客,原文链接: http://blog.51cto.com/zhoufoxcn/163947,如需转载请自行联系原作者




http://www.niftyadmin.cn/n/2521327.html

相关文章

SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column

当遇到这个问题的时候&#xff0c;有两个方面去解决 1、mysql 配置的问题 找到 my.cnf 在my.ini里找到sql-mode”STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION” 把其中的STRICT_TRANS_TABLES,去掉,或者把sqlmodeSTRICT_TRANS_TABLES,NO_AUTO_CREATE_USE…

Quartz Cron 表达式

Cron 表达式包括以下 7 个字段 格式: [秒] [分] [小时] [日] [月] [周] [年] 说明 是否必填 允许填写的值 允许的通配符 秒 是 0-59 , - * / 分 是 0-59 , - * / 时 是 …

nginx 配置 按日期输出 日志

listen 80;server_name _;if ($time_iso8601 ~ (\d{4}-\d{2}-\d{2})) {set $day $1;}access_log /data/wwwlogs/sms_nginx_$day.log combined;

说明你们已经不再是普通的朋友

人活着&#xff0c;除了亲人的爱&#xff0c;还有真心朋友的爱。因为缘分&#xff0c;我们相遇、相知、相惜&#xff0c;相互尊重。当一个人与你没有了距离&#xff0c;说明你们已经不再是普通的朋友&#xff0c;而是走进了心里的人&#xff0c;也是在乎你的人。别觉得黏着你&a…

利用Servlet在客户端输出PDF文件

在学习编程的过程中&#xff0c;我觉得不止要获得课本的知识&#xff0c;更多的是通过学习技术知识提高解决问题的能力&#xff0c;这样我们才能走在最前方&#xff0c;本文主要讲述利用Servlet在客户端输出PDF文件&#xff0c;更多Java专业知识&#xff0c;广州疯狂java培训为…

用定时器处理数组 setTimeout()

1 // 用定时器处理数组2 var items [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18];3 4 function processArray(items, process, callback){5 var todo items.concat(); // 克隆原数组6 7 setTimeout(function(){8 process(todo.sh…

nginx 配置错误日志输出

listen 80; server_name _; error_log /data/wwwlogs/sms_error.log [error_level];错误级别 error_level: 常见的错误日志级别有[debug | info | notice | warn | error | crit | alert | emerg]&#xff0c;级别越高记录的信息越少。 生产场景一般是 warn | error | crit 这…

mysql ERROR 1018

有一段时间我打开mysql的链接发现报错 ERROR 1018 (HY000): Cant read dir of ./test/ (errno: 13 - Permission denied) 错误1018 (HY000):不能读取目录。(errno: 13 -拒绝许可) 原因是因为&#xff1a;你的mysql 数据目录权限被修改了 找到 my.cnf 搜索 datadir 找到你的d…