.net软件保护方式大观

最近调试一个运行于.net 2.0下的软件,发现该软件使用的保护方式很具有代表性,基本囊括了现在.net下的所有保护措施。实践证明,这些保护措施就像全真七子,单打独斗功力差了点儿,但结合起来应用还是有一定强度的。下面做以说明,供.net开发者参考。

1.加壳
    该软件使用MaxtoCode加壳,该壳会生成本地dll文件,在运行时通过动态挂钩.net内核解密,并且是each method解密,所以不会在内存中出现完整的assembly,使得传统的内存dump方法失效。类似的壳还有国外的Remotesoft Protector、XHEO CodeVeil、.Net Reactor。这类壳本身就提供了反调试功能,再加上壳的本地dll也被加壳,因此这一步便可以挡住80%的逆向分析者。
但是rick(http://rick.cnblogs.com)已经做出了脱壳机,所以对于这种保护的程序第一步仍是dump。脱壳后,便可利用ildasm将程序集反编译,将所有的引用本地dll的代码删除,再次编译后便可正常运行:
  .method private specialname rtspecialname static 
          void  .cctor() cil managed
  {
    // Code size       6 (0x6)
    .maxstack  8
    IL_0000:  //call       void InFaceMaxtoCode::Startup()
    IL_0005:  ret
  } // end of method xebd220b94e14b2d7::.cctor

为了减肥,也可将InFaceMaxtoCode的代码删除,这些代码还是占据了一些体积的。

2.混淆
    该软件使用了Xenocode Postbuild进行混淆,xenocode的保护包括了名称混淆和流程混淆。其中名称通常被改为如下形式:x485ea7930f0abd9a xdc0a6303c9bfe8dd。这样,代码的名称就无法代表原来的意义。
    除了名称混淆,该软件还使用了流程混淆,加入了许多垃圾代码,比如:
(1)永远为“true”或“false”的跳转判断
    IL_0086:  ldc.i4.0
    IL_0087:  brtrue.s   IL_0032

IL_0089:  ldc.i4.0
    IL_008a:  brfalse.s  IL_00e6

(2)将代码分块并添加多个跳转,所以在每个方法尾部会看到如下类似跳转表的代码
    IL_0296:  br.s       IL_029d

IL_0298:  br         IL_022c

IL_029d:  ldc.i4.0
    IL_029e:  brfalse.s  IL_026f

IL_02a0:  ldc.i4     0x3
    IL_02a5:  brtrue     IL_0227

IL_02aa:  br         IL_0204

IL_02af:  br         IL_0032

混淆过的方法在反编译为高级语言时已经非常难以分析,如下:
            if (Field34_4.Columns.Count != 0)
                goto label_11;
            bool flag2 = (flag1 - i) > 0xFFFFFFFF;
            if (!flag2)
                goto label_10;
            while (true)
            {
                if (!0)
                    goto label_4;
                Field34_1.Fill(Field34_4, Field34_2);
                return true;
            label_1:
                flag2 = (flag1 + flag1) > 0xFFFFFFFF;
                if (!flag2 && true)
                    goto label_7;
            label_2:
                Field34_4.Clear();
            }

3.字符串加密
    在win32下用wdasm查找字符串参考可能是逆向分析的第一步,.net中也是这样,一些敏感字符串会暴露程序作者的意图。不过现在的混淆程序都提供了源代码加密,比如:
    IL_0086:  ldstr      "bppkcahlaaolhafmbllmhpcnopjnikaogohoapoopjfpbpmpho"
    + "daiokainbbhnibgnpbnngclnncjmeddnlddmcepljeihafilhfbmofplfgfmmghhdh"
    IL_008b:  ldc.i4     0x3c9baf9d
    IL_0090:  call       string xb9d8bb5e6df032aa.x7841ead83ad1c299::_bc25ec13a5229081(string,int32)

这段代码解密出的字符是“This is an unregistered copy”,这样便有效地防止了程序在第一时间被定位至关键代码。开发者也可以在自己的程序中自行加入解码方法。

4.anti-deubg
    反调试就是当检测到有解密软件运行时,让程序自动退出。见如下代码:
  .method private static pinvokeimpl("user32" lasterr winapi) 
          bool  EnumWindows(class CodeLib.x41a6f5dc72fea230/xdd2ea1989d3fc452 xa479061352f99870,
                            native int x7a5eebe5d933ebbc) cil managed preservesig
  {
  }

IL_0114:  ldloc.2
    IL_0115:  ldstr      "agnhoheigglificjphjjbiakpghkkgokihflahmlahdm"//DeProtector
    IL_011a:  ldc.i4     0x50e67d1c
    IL_011f:  call       string xb9d8bb5e6df032aa.x7841ead83ad1c299::_bc25ec13a5229081(string,
                                                                                       int32)
    IL_0124:  call       string [mscorlib]System.String::Intern(string)
    IL_0129:  callvirt   instance int32 [mscorlib]System.String::IndexOf(string)
    IL_012e:  ldc.i4.m1
    IL_012f:  bgt        IL_009f

IL_0134:  br         IL_0010

IL_0139:  br         IL_01e4

IL_013e:  ldloc.2
    IL_013f:  ldstr      "mkbbemibanpbljgcimnceledjlldllcenljehgafikhfalofclfgpimgkkdhgjkhfjbiejii"//JetBrains dotTrace
    IL_0144:  ldc.i4     0x43ee1162
    IL_0149:  call       string xb9d8bb5e6df032aa.x7841ead83ad1c299::_bc25ec13a5229081(string,
                                                                                       int32)
    IL_014e:  call       string [mscorlib]System.String::Intern(string)
    IL_0153:  callvirt   instance int32 [mscorlib]System.String::IndexOf(string)
    IL_0158:  ldc.i4.m1
    IL_0159:  bgt        IL_009f

IL_015e:  ldloc.2
    IL_015f:  ldstr      "iofohpmojpdpmmkphobajoia"//WinDbg
    IL_0164:  ldc.i4     0xdd4e591
    IL_0169:  call       string xb9d8bb5e6df032aa.x7841ead83ad1c299::_bc25ec13a5229081(string,
                                                                                       int32)
    IL_016e:  call       string [mscorlib]System.String::Intern(string)
    IL_0173:  callvirt   instance int32 [mscorlib]System.String::IndexOf(string)
    IL_0178:  ldc.i4.m1
    IL_0179:  bgt        IL_009f

程序从user32.dll中调用EnumWindows枚举当前所有窗口并取得名称,和解码过的敏感字符串进行对比。虽然这种方法“层次较高”,但仍不失为一种自我保护的手段。再就是当软件要进行敏感操作,比如在注册表中保存信息,从某个文件中读取信息时,也可以使用这些手段。
    IL_0000:  ldnull
    IL_0001:  ldstr      "Registry Monitor - Sysinternals: www.sysinternals.com"
    IL_0006:  call       native int [CodeLibWin]CodeLib.Win32.WindowsAPI::FindWindow(string, string)

IL_0101:  ldnull
    IL_0102:  ldstr      "File Monitor - Sysinternals: www.sysinternals.com"
    IL_0107:  call       native int [CodeLibWin]CodeLib.Win32.WindowsAPI::FindWindow(string,string)

利用系统方法也可以进行检测是否有调试器:
    IL_002d:  call       bool [mscorlib]System.Diagnostics.Debugger::get_IsAttached()
    IL_0032:  ldc.i4.0
    IL_0033:  ceq

5.时间验证
    在关键代码处,如果进行单步跟踪调试,则从一句代码到另一句代码会运行较长时间。因此可以预估计一下正常的执行时间,然后进行对比,若超过这个时间界限,则认为被调试。代码如下:
    IL_22df:  ldloca.s   V_51
    IL_22e1:  ldloc.s    V_14
    IL_22e3:  call       instance valuetype [mscorlib]System.TimeSpan [mscorlib]System.DateTime::Subtract(valuetype [mscorlib]System.DateTime)
    IL_22e8:  stloc.s    V_52
    IL_22ea:  ldloca.s   V_52
    IL_22ec:  call       instance int32 [mscorlib]System.TimeSpan::get_Seconds()
    IL_22f1:  ldc.i4.3
    IL_22f2:  cgt

分别取两次系统时间,算出秒数差,和3秒进行对比,若大于3秒则跳转。

6.程序员自身的安全意识
    无论什么保护手段,都需要程序作者会熟练运用,并且加强自身的安全意识。不过个人觉得该软件的作者有点过了,后期基本没更新软件本身的什么功能,全用于加强保护了。汗!(另:好像还有网络验证,还没看到)

.net程序保护方式大观的更多相关文章

  1. 【.net 深呼吸】细说CodeDom(1):结构大观

    CodeDom 是啥东东?Html Dom听过吧,XML Dom听过吧.DOM一般可翻译为 文档对象模型,那 Code + DOM呢,自然是指代码文档模型了.如果你从来没接触过 CodeDom,你大概 ...

  2. PHP程序的常见漏洞攻击分析

    综述:PHP程序也不是固若金汤,随着PHP的广泛运用,一些黑客们也在无时不想找PHP的麻烦,通过PHP程序漏洞进行攻击就是其中一种.在节,我们将从全局变量,远程文件,文件上载,库文件,Session文 ...

  3. 如何保护java程序不被反编译

    Java是一种 跨平台的.解释型语言 Java 源代码编译中间“字节码”存储于class文件中.Class文件是一种字节码形式的中间代码,该字节码中包括了很多源代码的信息,例如变量名.方法名 等.因此 ...

  4. Java程序版权保护解决方案

    通常C.C++等编程语言开发的程序都被编译成目标代码,这些目标代码都是本机器的二进制可执行代码.通常所有的源文件被编译.链接成一个可执行文件.在这些可执行文件中,编译器删除了程序中的变量名称.方法名称 ...

  5. .net 程序加密

    .net 程序加密,一般是对生成的exe文件或者dll直接进行加壳,配合加密锁或者许可进行授权控制,既能保证安全性,又控制软件的使用. 加壳工具的选择 一般要考虑几点,第一是加壳的安全性,不能被轻易脱 ...

  6. 微信小程序省市区选择器对接数据库

    前言,小程序本身是带有地区选着器的(网站:https://mp.weixin.qq.com/debug/wxadoc/dev/component/picker.html),由于自己开发的程序的数据是很 ...

  7. DOS程序员手册(五)

    第8章磁           盘       学习编程语言,常常是从基本的输入和输出入手的(正如第5.6和第7章曾介绍的一 样).到目前为止,我们不仅学习了怎样输入和输出数据,还学习了如何进行数据操作 ...

  8. x86 保护方式 简介 一

    80386   三种工作方式   实模式    保护模式和虚拟86模式   只有在保护方式下  全部32条地址线才有效   可以寻址高达4g字节的物理地址空间 超过1m的内存空间  被成为扩展的内存空 ...

  9. 反混淆:恢复被OLLVM保护的程序

    译者序: OLLVM作为代码混淆的优秀开源项目,在国内主流app加固应用中也经常能看到它的身影,但是公开的分析研究资料寥寥.本文是Quarkslab团队技术博客中一篇关于反混淆的文章,对OLLVM项目 ...

随机推荐

  1. 报错:/application/zabbix/sbin/zabbix_server: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object file: No such file or directory

    启动zabbix_server时报错: /application/zabbix/sbin/zabbix_server: error while loading shared libraries: li ...

  2. Denoise Autoencoder简单理解

    自编码器通过学习隐含特征来表达原始数据,那什么是denoise autoencoder呢? 关于Autoencoder参考:http://blog.csdn.net/on2way/article/de ...

  3. Java学习(一)Scanner报错java.util.NoSuchElementException

    我在一个方法A中使用了Scanner的 Scanner input=new Scanner(System.in),随后又将其关闭了,因为Eclipse里面你若不关闭,他会有一个warning:Reso ...

  4. 458. Poor Pigs

    There are 1000 buckets, one and only one of them contains poison, the rest are filled with water. Th ...

  5. day6 os模块

    OS模块 提供对操作系统进行调用的接口     (1)os.getcwd()   获取当前工作目录,即当前python脚本工作的目录路径 >>> os.getcwd()     获取 ...

  6. umask相关内容

    umask权限过滤符新创建的文件的权限为666,即- rw- rw- rw-新创建的目录的权限为777,即d rwxrwxrwx如umask值为0022,后三位022,即 --- -w- -w-上述默 ...

  7. SQL 如何查找一个表里,每个班级各个学科的最高分?

    SQL 如何查找一个表里,每个班级各个学科的最高分? 学生表:STUDENT(S#,SNAME,SAGE,SSEX,CLASSNO) 班级表:CLASS(CLASSNO,CLASSNAME) 课程表: ...

  8. sublimetext3-实用快捷键整理

    实用快捷键 Ctrl+Shift+P:打开命令面板Ctrl+P:搜索项目中的文件Ctrl+G:跳转到第几行Ctrl+W:关闭当前打开文件Ctrl+Shift+W:关闭所有打开文件Ctrl+Shift+ ...

  9. 长沙理工大学第十二届ACM大赛-重现赛 L - 选择困难症

    题目描述 小L有严重的选择困难症. 早上起床后,需要花很长时间决定今天穿什么出门. 假设一共有k类物品需要搭配选择,每类物品的个数为Ai,每个物品有一个喜欢值Vj,代表小L对这件物品的喜欢程度. 小L ...

  10. 应用服务攻击工具clusterd

    应用服务攻击工具clusterd   clusterd是一款Python语言编写的开源应用服务攻击工具.该工具支持七种不同的应用服务平台,如JBoss.ColdFusion.WebLogic.Tomc ...