论文网
English Papers
万事OK网
发表论文
 
 首页 > IT文章 > 程序设计 >
CRC算法原理及C语言实现

[科技论文网] http://www.scipapers.com    2007-12-01  

            mov     dword ptr[ebx*4 + crctable], eax
            inc     bx
            test    bx, 256
            jz     InitTableLoop

    注释:  - crctable 是一个包含256个dword的数组.
           - 由于使用反射算法,EAX被向右移.
           - 因此最低的8位被处理了.

    用Java和C写的代码如下(int is 32 bit):

    for (int bx=0; bx<256; bx++){
      int eax=0;
      eax=eax&0xFFFFFF00+bx&0xFF;      // 就是 'mov al,bl' 指令
      for (int cx=0; cx<8; cx++){
        if (eax&&0x1) {
          eax>>=1;
          eax^=poly;
        }
        else eax>>=1;
      }
      crctable[bx]=eax;
    }

    下面的汇编代码是用来计算CRC-32的:

    computeLoop:
            xor     ebx, ebx
            xor     al, [si]
            mov     bl, al
            shr     eax, 8
            xor     eax, dword ptr[4*ebx+crctable]
            inc     si
            loop   computeLoop

            xor     eax, 0FFFFFFFFh

    注释:  - ds:si 指向将要被处理的byte string信息流.
           - cx 信息流的长度.
           - eax 是当前的CRC.
           - crctable是用来计算CRC的值表.
           - 此例中记存器的初始值为: FFFFFFFF.
           - 要将中间值与FFFFFFFFh做XOR才能得到CRC

    下面是Java和C写的代码:

    for (int cx=0; cx>=8;
       eax^=crcTable[ebx];
    }
    eax^=0xFFFFFFFF;

      现在我们已经完成了本文的第一部分:CRC原理部分,所以如果你希望能够对CRC做更深
    的研究,那么我建议你去读在本文最后给出连接上的资料,我读了.好了,终于到了本文最
    有意思的部分,CRC的逆向分析!


    ------------------------------------------------------------------------------------
    第二部分 CRC的逆向分析:

      我遇到了很多障碍,当我思考如何破解CRC时.我试图使用一些特殊顺序的字节使CRC无效.
    但我没有做到...后来我意识到这种方法是行不同的,因为CRC内建了一些处理过程,无论你
    改变任何位它都不会出问题,真正的CRC就是在不断变化的,总是在变化的.找一些CRC程序,
    你可以自己尝试一下. 
      现在我知道我只能'纠正'在CRC后面的那些我想改变的字节.所以我要构造一个字节序列,
    它可以将CRC转化成任何我想要的样子! 

    具体实现这个想法

    一个字节串?     01234567890123456789012345678901234567890123456789012
    You want to change from  ^  this byte to  ^  this one.

    就是位置9->26.
    同时我们需要额外的4个字节用来在最后恢复原始字节串.

      当你计算CRC-32时,从0-8都没有问题,直到第9位,修补过的字节串会使CRC发生根本的改变.
    即使当走过了第26位,以后的字节都没有改变,你也不可能在得到原始的CRC了,不可能了!你读
    过后面的段落时就会明白为什么.间而言之,当你修改一个字节串时,要保证CRC不变. 

    1. 计算并保存从1~9位的CRC.
    2. 继续计算直到第27位还有额外的4字节并保存结果.
    3. 用1的值来计算新的字节串和额外4字节的CRC(对应patch后的新的CRC值),并将之保存.
    4. 现在我们得到了一个新的CRC,但是我们希望将它还原成原先的CRC,所以我们用逆向算法
       来计算那额外的4字节.

    1~3就是实际的情况,下面你将学到最关键的部分4.


    '反转'CRC-16

      我想,先来介绍计算逆CRC-16对于你来说会简单些.好的,我们现在处在一个恰当的位置,
    在以修改代码后面,就是你想将CRC还原的地方.我们知道原始的CRC(是在patch代码之前计
    算出来的)还有这个当前的记存器值.现在我们的目的就是计算可以改变当前记存器值到原
    始记存器值的两个字节.首先,我们用正常的方法计算这两个未知字节的CRC.我们设他们为
    X,Y.设记存器为a1,a0,只有0不能用来作为变量(00).:)在来看一下我们的CRC算法,figure
    3,更好的理解下面我要做的.

    好,我们开始:

    用这两字节串'X Y' 字节是从左边开始被处理的.
    记存器现在是a1 a0.
    用'+'来表示XOR运算(和第一部分中用的一样)

    处理第一个字节, X:
    a0+X            这是顶部字节的计算结果 (1)
    b1 b0           这是(1)在表中索引对象.
    00 a1           向右移动记存器.
    00+b1 a1+b0     上面两行对应位做XOR运算.

    现在记存器为: (b1) (a1+b0)

    处理第二个字, Y:
    (a1+b0)+Y       此轮顶部字节的计算结果(2)
    c1 c0           这是(2)在表中的索引对象.
    00 b1           向右移动记存器.
    00+c1 b1+c0     上面两行对应位做XOR运算.

    最后记存器就是: (c1) (b1+c0)

    我用一点不同的方法来表示:

    a0 + X      =(1)  在表中指向b1 b0.
    a1 + b0 + Y =(2)  在表中指向c1 c0.
         b1 + c0=d0   记存器中新的低位字节.
              c1=d1   记存器中新的高位字节.
        (1)  (2)

    Wow! 请大家暂时记住上面的信息:)
    别着急, 下面给出一个有具体值的例子.
     
      如果你想要的记存器的值是d1 d0(是原始的CRC),而且你知道在变换之前的记存器的值
    (a1 a0)...那么你将要送如什么样的2个字节进记存器来做CRC计算呢? 
      好了,现在我们的工作应该从幕后走到台前来了.d0一定是bi+c0,并且d1一定是c1...
    但是这到底是怎么回事,我听到你这样问了,你能知道b1和c0的值吗???你还记得哪个值表
    吗?你只需要在表中查找c0 c1这个字的值就可以了因为你知道c1.所以你需要编写一个查
    找程序.假如你找到了这个值,一定要记住这个值的索引,因为这就是找出未知的两个顶部
    字节,举例来说:(1)和(2)!
      所以,现在你找到了c1 c0,那么如何来得到b1 b0呢?如果b1+c0=d0那么b1=d0+c0!如前所
    述,现在你用哪个查找程序在表中查b1 b0的值.现在我们得到了所有计算X和Y所需要的值.
    Cool huh? 
    a1+b0+Y=(2) so Y=a1+b0+(2)
    a0+X=(1)    so X=a0+(1)


    实例.

    让我们来看看这个具体值的例子:
    -register before: (a1=)DE (a0=)AD
    -wanted register: (d1=)12 (d0=)34
    在附录的CRC-16的表中查找以12开头值的入口.这里入口38h的值为12C0.试这找一找是否还
    有以12开头的值的入口.你不可能在找到的,因为我们计算每一中顶部字节组合而得的值的
    入口,一共是256个值,记住!
    现在我们知道(2)=38,c1=12,c0=C0,所以b1=C0+34=F4,现在查找以F4开头的b1的入口.这里
    入口4Fh的值是F441.
    我们还知道  (1)=4F,b1=F4,b0=41,现在所有我们需要的都已经清楚了,接下来我们计算X,Y.

    Y=a1+b0+(2)=DE+41+38=A7
    X=a0+(1)   =AD+4F   =E2

    结论:将CRC 记存器的值从 DEAD 变为 1234 我们需要这两个字节 E2 A7 (以此顺序).

      你看,破解CRC校验你需要反向计算,还有要记住的就是计算过程中的值.当你在用汇编编写
    查找表程序时,要注意intel在小模式中是反向存储值的.现在你可能已经明白如何去破解这个
    CRC-16了...下面介绍如何在CRC-32中实现.


    破解 CRC-32

    现在我们来看CRC-32,和CRC-16是一样容易的(可能一样的不容易你认为).这里你操作的对象
    是4个字节的而不是2字节的.继续向下看,将它与上面CRC-16版本做对比.

    设4字节串 X  Y  Z  W  , 从左边开始处理.
    设记存器为  a3 a2 a1 a0
    注意a3是MSB,而a0是LSB

    处理第一个字节, X:
    a0+X                    这是顶部字节的计算结果(1).    来源:

声明:本文由网友推荐或作者提交,版权归原作者所有,刊登此文仅为传播知识,展示研究成果,提高文章引用率。未经原作者授权,禁止用于任何形式的商业行为。科技论文网倡导尊重知识、尊重劳动、保护原创、知识共享。由于部分论文文章来于网络,文章作者不祥,请相关的原创作者与我们联系,以便加上您的署名。

上一页 1 2 3 4 5 6 7 8 9 下一页  
CRC算法原理及C语言实现
下面没有链接了     欧几里德算法及其实现
最新论文
·[程序设计]CRC算法原理及C语言实现
·[程序设计]欧几里德算法及其实现
·[程序设计]蚁群算法Python实现
·[程序设计]图像二值化算法源码
·[程序设计]经典面试问题:12小球问题算法2
·[程序设计]经典面试问题:12小球问题算法
·[程序设计]图像几何变换插值算法
·[程序设计]C算法—堆排序
·[程序设计]人机博弈程序实现
·[程序设计]A*算法Python实现
 
 

搜索论文

Google
论文分类

论文网 论文发表网 论文 免费论文网 找论文网 毕业论文 中国论文网 英语论文 百度论文 聘教网 易搜
 免费发布论文    中国论文网 2008版权所有  业务联系:pinjiao@126.com