⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chap6-2-4.htm.primary

📁 加密与解密,软件加密保护技术与解决方案,看雪文档!
💻 PRIMARY
📖 第 1 页 / 共 3 页
字号:
<html>
<head>
<title>Crack Tutorial</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<link rel="stylesheet" href="style/css.css" type="text/css">
<link rel="stylesheet" href="../STYLE/Css.css" type="text/css">
</head>

<body bgcolor="white" text="#000000" link="#004080" vlink="#004080" background="../image/Back.gif">
<p><a href="../catalog.htm">目录</a>>>第6章</p>
<p align="center" class="shadow1Copy"><b class="p3">第6章 软件保护技术</b></p>
<table width="80%" border="0" cellspacing="0" cellpadding="3" align="center" bgcolor="#bcbcbc" bordercolor="#111111" class="shadow1">
  <tr> 
    <td class="shadow1" width="25%"> 
      <div align="center"><a href="Chap6-1.htm"><font color="#FFFFFF">第一节 常见保护技巧</font></a></div>
    </td>
    <td class="shadow1" width="25%"> 
      <div align="center"><a href="Chap6-2.htm"><font color="#FFFFFF">第二节 反跟踪技术</font></a></div>
    </td>
    <td class="shadow1" width="25%"> 
      <div align="center"><a href="Chap6-3.htm"><font color="#FFFFFF">第三节 加密算法</font></a></div>
    </td>
    <td class="shadow1" width="25%"> 
      <div align="center"><a href="Chap6-4.htm"><font color="#FFFFFF">第四节 软件保护建议</font></a></div>
    </td>
  </tr>
</table>
<p align="center"><span class="p9"><b>第二节 反跟踪技术</b></span></p>
<table border="1" width="80%" cellpadding="5" bordercolor="#111111" bgcolor="#efefef" align="center" cellspacing="0">
  <tr> 
    <td width="33%" valign="middle" align="center" class="p9" height="23"> 
      <div align="left" class="p"><span class="p9"><span class="p9">   <span class="p9">1、<a href="Chap6-2-1.htm">Anti-Debug</a></span></span></span></div>
    </td>
    <td width="33%" valign="middle" align="center" class="p9" height="23"> 
      <div align="left"><span class="p9"><span class="p9">   </span>2、<a href="Chap6-2-2.htm">Anti-静态分析</a></span></div>
    </td>
    <td width="34%" valign="top" class="p9" height="23"> 
      <div align="left"><span class="p9"><span class="p9">  <font color="#000000"> </font></span>3、<a href="Chap6-2-3.htm">Anti-Dump</a><font color="#000000"></font></span></div>
    </td>
  </tr>
  <tr> 
    <td width="33%" valign="middle" align="center" class="p9" height="23"> 
      <div align="left"><span class="p9"><span class="p9">   </span>4、<a href="Chap6-2-4.htm">CRC简介</a></span></div>
    </td>
    <td width="33%" valign="middle" align="center" class="p9" height="23"> 
      <div align="left"><span class="p9"><span class="p9">  <font color="#000000"> </font></span>5、<a href="Chap6-2-5.htm">SEH技术</a></span></div>
    </td>
    <td width="34%" valign="top" class="p9" height="23"> 
      <div align="left"></div>
    </td>
  </tr>
</table>
<p align="center"><span class="p9"><span class="p9"><span class="p9"><b>4、CRC简介</b></span></span></span></p>
<blockquote>
  <p> 主题 :CRC原理及其逆向分析方法. <br>
    作者 : Anarchriz/DREAD.<br>
    发布日期 :29 april 1999 (最后更改 30 april 1999).<br>
    目的 :CRC 算法.<br>
    使用工具 :QEdit 2.1 (The best!) &amp;Wordpad &amp; some CRC progs.<br>
    figure :CRC教程与c001的CRC逆向分析方法. <br>
    翻译:arbin </p>
</blockquote>
<p></p>
<blockquote>
  <p><br>
    CRC原理及其逆向破解方法:</p>
  <p>介绍:</p>
  <p> 这篇短文包含CRC原理介绍和其逆向分析方法,很多程序员和破解者不是很清楚了解<br>
    CRC的工作原理,而且几乎没人知道如何逆向分析它的方法,事实上它是非常有用的.<br>
    首先,这篇教程教你一般如何计算CRC,你可以将它用在数据代码保护中.第二,主要是<br>
    介绍如何逆向分析CRC-32,你可以以此来分析程序中的CRC保护(象反病毒编码).当然<br>
    有很多有效的工具用来对付CRC,但我怀疑它是否会说明原理.<br>
    我要告诉你,这篇短文里中应用了很多数学知识,这不会影响一些人,而且会被一般的<br>
    程序员与逆向分析者很好理解.为什么?那么如果你不知道数学是如何被应用在CRC中,<br>
    我建议你可以停止继续学习了.所以我假定你们(读者)都是具备二进制算术知识的.</p>
  <p>第一部分:CRC 介绍,CRC是什么和计算CRC的方法. </p>
  <p><br>
    循环冗余码 CRC</p>
  <p> 我们都知道CRC.甚至你没有印象,但当你想到那些来自诸如RAR,ZIP等压缩软件发给你<br>
    由于错误连接和其他一些意外原因导致的文件错误的恼人的消息时,你就会知道.CRC是块<br>
    数据的计算值,比如对每一个文件进行压缩.在一个解压缩过程中,程序会从新计算解压文件<br>
    的CRC值,并且将之与从文件中读取的CRC值进行比对,如果值相同,那么正确.在CRC-32中,<br>
    会有1/2^32的可能性发生对确认数据更改的校验错误. <br>
    很多人认为CRC就是循环冗余校验,假如CRC真的就是循环冗余校验,那么很多人都错用了<br>
    这个术语.你不能说&quot;这个程序的CRC是12345678&quot;.人们也常说某一个程序有CRC校验,而不<br>
    说是 &quot;循环冗余校验&quot; 校验.结论:CRC 代表循环冗余码,而不是循环冗余校验. <br>
    计算是如何完成的呢?好,主要的想法就是将一个文件看成一个被一些数字分割的很长的<br>
    位字串,这里会有一个余数---CRC!你总会有一个余数(可以是0),它至多比除数小一.<br>
    (9/3=3 余数=0 ; (9+2)/3=3 余数=2)<br>
    (或者它本身就包含一个除数在其中). <br>
    在这里CRC计算方法与除法有一点点区别,除法就是将被减数重复的减去除数X次,然后留下<br>
    余数.如果你希望得到原值,那么你就要把除数乘上X次,然后加上余数.<br>
    CRC计算使用特殊的减法与加法完成的.也就是一种新的&quot;算法&quot;.计算中每一位计算的进位值<br>
    被&quot;遗忘&quot;了. <br>
    看如下两个例子,1是普通减法,2和3是特殊的.<br>
    -+<br>
    (1) 1101 (2) 1010 1010 (3) 0+0=0 0-0=0<br>
    1010- 1111+ 1111- 0+1=1 *0-1=1<br>
    ---- ---- ---- 1+0=1 1-0=1<br>
    0011 0101 0101 *1+1=0 1-1=0<br>
    在(1)中,右数第二列可以看成是0-1=-1,因此要从高位借1,就变成(10+0)-1=1.(这就象普通<br>
    的'by-paper'十进制减法).特例(2,3)中,1+1会有正常的结果10,'1'是计算后的进位.这个值<br>
    被忽略了.特殊情况0-1应该有正常结果'-1'就要退到下一位.这个值也被忽略了.假如你对编程<br>
    有一定了解,这就象,XOR 操作或者更好.<br>
    现在来看一个除法的例子:</p>
  <p>在普通算法中:<br>
    1001/1111000\1101 13 9/120\13<br>
    1001 - 09 -|<br>
    ---- -- |<br>
    1100 30 |<br>
    1001 - 27 -<br>
    ---- --<br>
    0110 3 -&gt; 余数<br>
    0000 -<br>
    ----<br>
    1100<br>
    1001 -<br>
    ----<br>
    011 -&gt; 3, 余数</p>
  <p>在CRC算法中:<br>
    1001/1111000\1110 9/120\14 余数为 6<br>
    1001 -<br>
    ----<br>
    1100<br>
    1001 -<br>
    ----<br>
    1010<br>
    1001 -<br>
    ----<br>
    0110<br>
    0000 -<br>
    ----<br>
    110 -&gt; 余数<br>
    (例 3)</p>
  <p> 这个除法的商并不重要,也没必要去记住,因为他们仅仅是一组无关紧要的位串.真正<br>
    重要的是余数!它就是这个值,可以说比原文件还重要的值,他就是基本的CRC.</p>
  <p><br>
    过度到真正的CRC码计算.</p>
  <p> 进行一个CRC计算我们需要选则一个除数,从现在起我们称之为&quot;poly&quot;.宽度W就是最高位<br>
    的位置,所以这个poly 1001的W 是3,而不是4.注意最高位总是1,当你选定一个宽度,那么你只<br>
    需要选择低W各位的值. <br>
    假如我们想计算一个位串的CRC码,我们想确定每一个位都被处理过,因此,我们要在目标<br>
    位串后面加上W个0位.在此例中,我们假设位串为1111.请仔细分析下面一个例子:</p>
  <p>Poly = 10011, 宽度 W=4<br>
    位串 Bitstring <br>
    Bitstring + W zeros = 110101101 + 0000</p>
  <p>10011/1101011010000\110000101 (我们不关心此运算的商)<br>
    10011|||||||| -<br>
    -----||||||||<br>
    10011|||||||<br>
    10011||||||| -<br>
    -----|||||||<br>
    00001||||||<br>
    00000|||||| -<br>
    -----||||||<br>
    00010|||||<br>
    00000||||| -<br>
    -----|||||<br>
    00101||||<br>
    00000|||| -<br>
    -----||||<br>
    01010|||<br>
    00000||| -<br>
    -----|||<br>
    10100||<br>
    10011|| -<br>
    -----||<br>
    01110|<br>
    00000| -<br>
    -----|<br>
    11100<br>
    10011 -<br>
    -----<br>
    1111 -&gt; 余数 -&gt; the CRC!<br>
    (例 4)</p>
  <p>重要两点声明如下:<br>
    1.只有当Bitstring的最高位为1,我们才将它与poly做XOR运算,否则我们只是将<br>
    Bitstring左移一位.<br>
    2.XOR运算的结果就是被操作位串bitstring与低W位进行XOR运算,因为最高位总为0.</p>
  <p>算法设计:</p>
  <p> 你们都应知道基于位运算的算法是非常慢的而且效率低下.但如果将计算放在每一字节上<br>
    进行,那么效率将大大提高.不过我们只能接受poly的宽度是8的倍数(一个字节;).可以形<br>
    象的看成这样一个宽度为32的poly(W=32):</p>
  <p> 3 2 1 0 byte<br>
    +---+---+---+---+<br>
    Pop! &lt;--| | | | |&lt;-- bitstring with W zero bits added, in this case 
    32<br>
    +---+---+---+---+<br>
    1&lt;--- 32 bits ---&gt; this is the poly, 4*8 bits</p>
  <p>(figure 1)<br>
    这是一个你用来存放暂时CRC结果的记存器,现在我称它为CRC记存器或者记存器.你从右<br>
    至左移动位串,当从左边移出的位是1,则整个记存器被与poly的低W位进行XOR运算.(此例<br>
    中为32).事实上,我们精确的完成了上面除法所做的事情.</p>
  <p><br>
    移动前记存器值为:10110100<br>
    当从右边移入4位时,左边的高4位将被移出,此例中1011将被移出,而1101被移入.</p>
  <p>情况如下:<br>
    当前8位CRC记存器 : 01001101<br>
    刚刚被移出的高4位 : 1011<br>
    我们用此poly : 101011100, 宽度 W=8</p>
  <p>现在我们用如前介绍的方法来计算记存器的新值.<br>
    顶部 记存器<br>
    ---- --------<br>
    1011 01001101 高四位和当前记存器值<br>
    1010 11100 + (*1) Poly 放在顶部最高位进行XOR运算 (因为那里是1)<br>
    -------------<br>
    0001 10101101 运算结果</p>
  <p>现在我们仍有一位1在高4位:<br>
    0001 10101101 上一步结果<br>
    1 01011100+ (*2) Poly 放在顶部的最低位进行XOR运算 (因为那里是1)<br>
    -------------<br>
    0000 11110001 第二步运算结果<br>
    ^^^^<br>
    现在顶部所有位均为0,所以我们不需要在与poly进行XOR运算</p>
  <p>你可以得到相同的结果如果你先将(*1)与(*2)做XOR然后将结果与记存器值做XOR.<br>
    这就是标准XOR运算的特性:<br>
    (a XOR b) XOR c = a XOR (b XOR c) 由此,推出如下的运算顺序也是正确的.</p>
  <p>1010 11100 poly (*1) 放在顶部最高位<br>
    1 01011100+ polys (*2) 放在顶部最低位<br>
    -------------<br>
    1011 10111100 (*3) XOR运算结果</p>
  <p>The result (*3) 将(*3)与记存器的值做XOR运算<br>
    1011 10111100<br>
    1011 01001101+ 如右:<br>
    -------------<br>
    0000 11110001</p>
  <p>你看到了吗?得到一样的结果!现在(*3)变的重要了,因为顶部为1010则(3)的值总是等于<br>
    10111100(当然是在一定的条件之下)这意味着你可以预先计算出任意顶部位结合的XOR值.<br>
    注意,顶部结果总是0,这就是组合XOR操作导致的结果.(翻译不准确,保留原文)</p>
  <p> 现在我们回到figure 1,对每一个顶部字节的值都做移出操作,我们可以预先计算出一个值.<br>
    此例中,它将是一个包含256个double word(32 bit)双字的表.(附录中CRC-32的表).<br>
    (翻译不准确,保留原文) </p>
  <p>用伪语言表示我们的算法如下: </p>
  <p>While (byte string is not exhausted)<br>
    Begin<br>
    Top = top_byte of register ;<br>
    Register = Register shifted 8 bits left ORred with a new byte from string 
    ;<br>
    Register = Register XORred by value from precomputedTable at position Top 
    ;<br>
    End</p>
  <p>direct table算法:<br>
    上面提到的算法可以被优化.字节串中的字节在被用到之前没有必要经过整个记村器.用<br>
    这个新的算法,我们可以直接用一个字节去XOR一个字节串通过将此字节移出记存器.结果<br>
    指向预先计算的表中的一个值,这个值是用来被记存器的值做XOR运算的. <br>
    我不十分确切的知道为什么这会得到同样的结果(这需要了解XOR运算的特性),但是这又<br>
    极为便利,因为你无须在你的字节串后填充0字节/位.(如果你知道原理,请告诉我:) <br>
    让我们来实现这个算法: <br>
    <br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -