国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
CRC計(jì)算(續(xù))
CRC計(jì)算(續(xù))
[ xiwang 發(fā)表于 2005-12-6 9:58:00 ]

主題       :CRC原理及其逆向分析方法.              
作者       : Anarchriz/DREAD.
發(fā)布日期   :29 april 1999 (最后更改 30 april 1999).
目的       :CRC 算法.
使用工具   :QEdit 2.1 (The best!) &Wordpad & some CRC progs.
figure       :CRC教程與c001的CRC逆向分析方法.        
翻譯:arbin     

 


CRC原理及其逆向破解方法:

介紹:

  這篇短文包含CRC原理介紹和其逆向分析方法,很多程序員和破解者不是很清楚了解
CRC的工作原理,而且?guī)缀鯖]人知道如何逆向分析它的方法,事實(shí)上它是非常有用的.
首先,這篇教程教你一般如何計(jì)算CRC,你可以將它用在數(shù)據(jù)代碼保護(hù)中.第二,主要是
介紹如何逆向分析CRC-32,你可以以此來(lái)分析程序中的CRC保護(hù)(象反病毒編碼).當(dāng)然
有很多有效的工具用來(lái)對(duì)付CRC,但我懷疑它是否會(huì)說(shuō)明原理.
  我要告訴你,這篇短文里中應(yīng)用了很多數(shù)學(xué)知識(shí),這不會(huì)影響一些人,而且會(huì)被一般的
程序員與逆向分析者很好理解.為什么?那么如果你不知道數(shù)學(xué)是如何被應(yīng)用在CRC中,
我建議你可以停止繼續(xù)學(xué)習(xí)了.所以我假定你們(讀者)都是具備二進(jìn)制算術(shù)知識(shí)的.

第一部分:CRC 介紹,CRC是什么和計(jì)算CRC的方法. 


循環(huán)冗余碼 CRC

  我們都知道CRC.甚至你沒有印象,但當(dāng)你想到那些來(lái)自諸如RAR,ZIP等壓縮軟件發(fā)給你
由于錯(cuò)誤連接和其他一些意外原因?qū)е碌奈募e(cuò)誤的惱人的消息時(shí),你就會(huì)知道.CRC是塊
數(shù)據(jù)的計(jì)算值,比如對(duì)每一個(gè)文件進(jìn)行壓縮.在一個(gè)解壓縮過(guò)程中,程序會(huì)從新計(jì)算解壓文件
的CRC值,并且將之與從文件中讀取的CRC值進(jìn)行比對(duì),如果值相同,那么正確.在CRC-32中,
會(huì)有1/2^32的可能性發(fā)生對(duì)確認(rèn)數(shù)據(jù)更改的校驗(yàn)錯(cuò)誤.
  很多人認(rèn)為CRC就是循環(huán)冗余校驗(yàn),假如CRC真的就是循環(huán)冗余校驗(yàn),那么很多人都錯(cuò)用了
這個(gè)術(shù)語(yǔ).你不能說(shuō)"這個(gè)程序的CRC是12345678".人們也常說(shuō)某一個(gè)程序有CRC校驗(yàn),而不
說(shuō)是 "循環(huán)冗余校驗(yàn)" 校驗(yàn).結(jié)論:CRC 代表循環(huán)冗余碼,而不是循環(huán)冗余校驗(yàn).
  計(jì)算是如何完成的呢?好,主要的想法就是將一個(gè)文件看成一個(gè)被一些數(shù)字分割的很長(zhǎng)的
位字串,這里會(huì)有一個(gè)余數(shù)---CRC!你總會(huì)有一個(gè)余數(shù)(可以是0),它至多比除數(shù)小一.
(9/3=3 余數(shù)=0 ; (9+2)/3=3 余數(shù)=2)
(或者它本身就包含一個(gè)除數(shù)在其中).
  在這里CRC計(jì)算方法與除法有一點(diǎn)點(diǎn)區(qū)別,除法就是將被減數(shù)重復(fù)的減去除數(shù)X次,然后留下
余數(shù).如果你希望得到原值,那么你就要把除數(shù)乘上X次,然后加上余數(shù).
  CRC計(jì)算使用特殊的減法與加法完成的.也就是一種新的"算法".計(jì)算中每一位計(jì)算的進(jìn)位值
被"遺忘"了. 
看如下兩個(gè)例子,1是普通減法,2和3是特殊的.
     -+
(1) 1101  (2) 1010  1010  (3) 0+0=0  0-0=0
    1010-     1111+ 1111-     0+1=1 *0-1=1
    ----      ----  ----      1+0=1  1-0=1
    0011      0101  0101     *1+1=0  1-1=0
  在(1)中,右數(shù)第二列可以看成是0-1=-1,因此要從高位借1,就變成(10+0)-1=1.(這就象普通
的‘by-paper‘十進(jìn)制減法).特例(2,3)中,1+1會(huì)有正常的結(jié)果10,‘1‘是計(jì)算后的進(jìn)位.這個(gè)值
被忽略了.特殊情況0-1應(yīng)該有正常結(jié)果‘-1‘就要退到下一位.這個(gè)值也被忽略了.假如你對(duì)編程
有一定了解,這就象,XOR 操作或者更好.
  現(xiàn)在來(lái)看一個(gè)除法的例子:

在普通算法中:
1001/1111000\1101 13            9/120\13
     1001    -                    09  -|
     ----                         --   |
      1100                         30  |
      1001    -                    27  -
      ----                         --
       0110                         3 -> 余數(shù)
       0000    -
       ----
        1100
        1001    -
        ----
         011 -> 3, 余數(shù)

在CRC算法中:
1001/1111000\1110               9/120\14 余數(shù)為 6
     1001    -
     ----
      1100
      1001    -
      ----
       1010
       1001    -
       ----
        0110
        0000    -
        ----
         110 -> 余數(shù)
(例 3)

  這個(gè)除法的商并不重要,也沒必要去記住,因?yàn)樗麄儍H僅是一組無(wú)關(guān)緊要的位串.真正
重要的是余數(shù)!它就是這個(gè)值,可以說(shuō)比原文件還重要的值,他就是基本的CRC.


過(guò)度到真正的CRC碼計(jì)算.

  進(jìn)行一個(gè)CRC計(jì)算我們需要選則一個(gè)除數(shù),從現(xiàn)在起我們稱之為"poly".寬度W就是最高位
的位置,所以這個(gè)poly 1001的W 是3,而不是4.注意最高位總是1,當(dāng)你選定一個(gè)寬度,那么你只
需要選擇低W各位的值. 
  假如我們想計(jì)算一個(gè)位串的CRC碼,我們想確定每一個(gè)位都被處理過(guò),因此,我們要在目標(biāo)
位串后面加上W個(gè)0位.在此例中,我們假設(shè)位串為1111.請(qǐng)仔細(xì)分析下面一個(gè)例子:

Poly                = 10011, 寬度 W=4
位串                Bitstring
Bitstring + W zeros = 110101101 + 0000

10011/1101011010000\110000101 (我們不關(guān)心此運(yùn)算的商)
      10011|||||||| -
      -----||||||||
       10011|||||||
       10011|||||||  -
       -----|||||||
        00001||||||
        00000||||||   -
        -----||||||
         00010|||||
         00000|||||    -
         -----|||||
          00101||||
          00000||||     -
          -----||||
           01010|||
           00000|||      -
           -----|||
            10100||
            10011||       -
            -----||
             01110|
             00000|        -
             -----|
              11100
              10011         -
              -----
               1111 -> 余數(shù) -> the CRC!
(例 4)

重要兩點(diǎn)聲明如下:
1.只有當(dāng)Bitstring的最高位為1,我們才將它與poly做XOR運(yùn)算,否則我們只是將
  Bitstring左移一位.
2.XOR運(yùn)算的結(jié)果就是被操作位串bitstring與低W位進(jìn)行XOR運(yùn)算,因?yàn)樽罡呶豢倿?.

算法設(shè)計(jì):

  你們都應(yīng)知道基于位運(yùn)算的算法是非常慢的而且效率低下.但如果將計(jì)算放在每一字節(jié)上
進(jìn)行,那么效率將大大提高.不過(guò)我們只能接受poly的寬度是8的倍數(shù)(一個(gè)字節(jié);).可以形
象的看成這樣一個(gè)寬度為32的poly(W=32):

          3   2   1   0    byte
        +---+---+---+---+
Pop! <--|   |   |   |   |<-- bitstring with W zero bits added, in this case 32
        +---+---+---+---+
       1<--- 32 bits ---> this is the poly, 4*8 bits

(figure 1)
  這是一個(gè)你用來(lái)存放暫時(shí)CRC結(jié)果的記存器,現(xiàn)在我稱它為CRC記存器或者記存器.你從右
至左移動(dòng)位串,當(dāng)從左邊移出的位是1,則整個(gè)記存器被與poly的低W位進(jìn)行XOR運(yùn)算.(此例
中為32).事實(shí)上,我們精確的完成了上面除法所做的事情.


移動(dòng)前記存器值為:10110100
當(dāng)從右邊移入4位時(shí),左邊的高4位將被移出,此例中1011將被移出,而1101被移入.

情況如下:
當(dāng)前8位CRC記存器      : 01001101
剛剛被移出的高4位     : 1011
我們用此poly          : 101011100, 寬度 W=8

現(xiàn)在我們用如前介紹的方法來(lái)計(jì)算記存器的新值.
頂部  記存器
---- --------
1011 01001101  高四位和當(dāng)前記存器值
1010 11100   + (*1) Poly 放在頂部最高位進(jìn)行XOR運(yùn)算 (因?yàn)槟抢锸?)
-------------
0001 10101101 運(yùn)算結(jié)果

現(xiàn)在我們?nèi)杂幸晃?在高4位:
0001 10101101  上一步結(jié)果
   1 01011100+ (*2) Poly 放在頂部的最低位進(jìn)行XOR運(yùn)算 (因?yàn)槟抢锸?)
-------------
0000 11110001 第二步運(yùn)算結(jié)果
^^^^
現(xiàn)在頂部所有位均為0,所以我們不需要在與poly進(jìn)行XOR運(yùn)算

你可以得到相同的結(jié)果如果你先將(*1)與(*2)做XOR然后將結(jié)果與記存器值做XOR.
這就是標(biāo)準(zhǔn)XOR運(yùn)算的特性:
(a XOR b) XOR c = a XOR (b XOR c)  由此,推出如下的運(yùn)算順序也是正確的.

1010 11100       poly  (*1)    放在頂部最高位
   1 01011100+   polys (*2)    放在頂部最低位
-------------
1011 10111100  (*3) XOR運(yùn)算結(jié)果

The result (*3)   將(*3)與記存器的值做XOR運(yùn)算
1011 10111100
1011 01001101+    如右:
-------------
0000 11110001

你看到了嗎?得到一樣的結(jié)果!現(xiàn)在(*3)變的重要了,因?yàn)轫敳繛?010則(3)的值總是等于
10111100(當(dāng)然是在一定的條件之下)這意味著你可以預(yù)先計(jì)算出任意頂部位結(jié)合的XOR值.
注意,頂部結(jié)果總是0,這就是組合XOR操作導(dǎo)致的結(jié)果.(翻譯不準(zhǔn)確,保留原文)

  現(xiàn)在我們回到figure 1,對(duì)每一個(gè)頂部字節(jié)的值都做移出操作,我們可以預(yù)先計(jì)算出一個(gè)值.
此例中,它將是一個(gè)包含256個(gè)double word(32 bit)雙字的表.(附錄中CRC-32的表).
(翻譯不準(zhǔn)確,保留原文)
用偽語(yǔ)言表示我們的算法如下:

While (byte string is not exhausted)
    Begin
    Top = top_byte of register ;
    Register = Register shifted 8 bits left ORred with a new byte from string ;
    Register = Register XORred by value from precomputedTable at position Top ;
    End

direct table算法:
  上面提到的算法可以被優(yōu)化.字節(jié)串中的字節(jié)在被用到之前沒有必要經(jīng)過(guò)整個(gè)記村器.用
這個(gè)新的算法,我們可以直接用一個(gè)字節(jié)去XOR一個(gè)字節(jié)串通過(guò)將此字節(jié)移出記存器.結(jié)果
指向預(yù)先計(jì)算的表中的一個(gè)值,這個(gè)值是用來(lái)被記存器的值做XOR運(yùn)算的. 
  我不十分確切的知道為什么這會(huì)得到同樣的結(jié)果(這需要了解XOR運(yùn)算的特性),但是這又
極為便利,因?yàn)槟銦o(wú)須在你的字節(jié)串后填充0字節(jié)/位.(如果你知道原理,請(qǐng)告訴我:)
  讓我們來(lái)實(shí)現(xiàn)這個(gè)算法:
 
  +----< byte string  (or file)  字節(jié)串,(或是文件)
  |
  v       3   2   1   0    byte  字節(jié)
  |     +---+---+---+---+
 XOR---<|   |   |   |   |  Register  記存器
  |     +---+---+---+---+
  |             |
  |            XOR
  |             ^
  v     +---+---|---+---+
  |     |   |   |   |   |  Precomputed table 值表(用來(lái)進(jìn)行操作)
  |     +---+---+---+---+
  +--->-:   :   :   :   :
        +---+---+---+---+
        |   |   |   |   |
        +---+---+---+---+
(figure 2)

‘reflected‘ direct Table 算法:

  由于這里有這樣一個(gè)與之相對(duì)應(yīng)的‘反射‘算法,事情顯得復(fù)雜了.一個(gè)反射的值/記存器
就是將它的每一位以此串的中心位為標(biāo)準(zhǔn)對(duì)調(diào)形成的.例如:0111011001就是1001101110
的反射串. 
  他們提出‘反射‘是因?yàn)閁ART(一種操作IO的芯片)發(fā)送每一個(gè)字節(jié)時(shí)是先發(fā)最沒用的0位,
最后再發(fā)最有意義的第七位.這與正常的位置是相逆的. 
  除了信息串不做反射以外,在進(jìn)行下一步操作前,要將其于的數(shù)據(jù)都做反射處理.所以在
計(jì)算值表時(shí),位向右移,且poly也是作過(guò)反射處理的.當(dāng)然,在計(jì)算CRC時(shí),記存器也要向右
移,而且值表也必須是反射過(guò)的. 

  byte string (or file) -->---+
                              |    1. 表中每一個(gè)入口都是反射的.
    byte  3   2   1   0       V    2. 初始化記存器也是反射的.
        +---+---+---+---+     |    3. 但是byte string中的數(shù)據(jù)不是反射的,
        |   |   |   |   |>---XOR      因?yàn)槠渌亩甲鲞^(guò)反射處理了.
        +---+---+---+---+     |
                |             |
               XOR            V
                ^             |
        +---+---|---+---+     |
        |   |   |   |   |     |     值表
        +---+---+---+---+     |
        :   :   :   :   : <---+
        +---+---+---+---+
        |   |   |   |   |
        +---+---+---+---+
(figure 3)

我們的算法如下:
1. 將記存器向右移動(dòng)一個(gè)字節(jié).
2. 將剛移出的哪個(gè)字節(jié)與byte string中的新字節(jié)做XOR運(yùn)算,
   得出一個(gè)指向值表table[0..255]的索引
3. 將索引所指的表值與記存器做XOR運(yùn)算.
4. 如數(shù)據(jù)沒有全部處理完,則跳到步驟1.


下面是這個(gè)算法的簡(jiǎn)單的可執(zhí)行匯編源碼:

完整的CRC-32標(biāo)準(zhǔn)所包含的內(nèi)容:
Name            : "CRC-32"
Width           : 32
Poly            : 04C11DB7
Initial value   : FFFFFFFF
Reflected       : True
XOR out with    : FFFFFFFF

作為對(duì)你好奇心的獎(jiǎng)勵(lì), 這里是CRC-16標(biāo)準(zhǔn): :)
Name            : "CRC-16"
Width           : 16
Poly            : 8005
Initial value   : 0000
Reflected       : True
XOR out with    : 0000

‘XOR out with‘ 是為了最終得到CRC而用來(lái)與記存器最后結(jié)果做XOR運(yùn)算的值.
假如你想了解一些關(guān)于‘reversed‘逆向CRC poly的話,請(qǐng)看我的參考文章.
 
  我是在16位DOS模式下用的32位編碼,因此你會(huì)在這個(gè)程序中看到很多32位與16位混合
的編碼...當(dāng)然這是很容易轉(zhuǎn)換成純32位編碼的.注意這個(gè)程序是經(jīng)過(guò)完整測(cè)試并且能夠
正常運(yùn)行的.下面的Java 和 C 代碼都是由這個(gè)匯編代碼而來(lái)的. 
底下的這段程序就是用來(lái)計(jì)算CRC-32 table的:

        xor     ebx, ebx   ;ebx=0, 將被用做一個(gè)指針.
InitTableLoop:
        xor     eax, eax   ;eax=0 為計(jì)算新的entry.
        mov     al, bl     ;al<-bl

        ;生成入口.
        xor     cx, cx
 entryLoop:
        test    eax, 1
        jz     no_topbit
        shr     eax, 1
        xor     eax, poly
        jmp    entrygoon
 no_topbit:
        shr     eax, 1
 entrygoon:
        inc     cx
        test    cx, 8
        jz     entryLoop

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

注釋:  - crctable 是一個(gè)包含256個(gè)dword的數(shù)組.
       - 由于使用反射算法,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;
}

下面的匯編代碼是用來(lái)計(jì)算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 指向?qū)⒁惶幚淼腷yte string信息流.
       - cx 信息流的長(zhǎng)度.
       - eax 是當(dāng)前的CRC.
       - crctable是用來(lái)計(jì)算CRC的值表.
       - 此例中記存器的初始值為: FFFFFFFF.
       - 要將中間值與FFFFFFFFh做XOR才能得到CRC
面是Java和C寫的代碼:

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

  現(xiàn)在我們已經(jīng)完成了本文的第一部分:CRC原理部分,所以如果你希望能夠?qū)RC做更深
的研究,那么我建議你去讀在本文最后給出連接上的資料,我讀了.好了,終于到了本文最
有意思的部分,CRC的逆向分析!


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

  我遇到了很多障礙,當(dāng)我思考如何破解CRC時(shí).我試圖使用一些特殊順序的字節(jié)使CRC無(wú)效.
但我沒有做到...后來(lái)我意識(shí)到這種方法是行不同的,因?yàn)镃RC內(nèi)建了一些處理過(guò)程,無(wú)論你
改變?nèi)魏挝凰疾粫?huì)出問題,真正的CRC就是在不斷變化的,總是在變化的.找一些CRC程序,
你可以自己嘗試一下. 
  現(xiàn)在我知道我只能‘糾正‘在CRC后面的那些我想改變的字節(jié).所以我要構(gòu)造一個(gè)字節(jié)序列,
它可以將CRC轉(zhuǎn)化成任何我想要的樣子! 

具體實(shí)現(xiàn)這個(gè)想法

一個(gè)字節(jié)串?     01234567890123456789012345678901234567890123456789012
You want to change from  ^  this byte to  ^  this one.

就是位置9->26.
同時(shí)我們需要額外的4個(gè)字節(jié)用來(lái)在最后恢復(fù)原始字節(jié)串.

  當(dāng)你計(jì)算CRC-32時(shí),從0-8都沒有問題,直到第9位,修補(bǔ)過(guò)的字節(jié)串會(huì)使CRC發(fā)生根本的改變.
即使當(dāng)走過(guò)了第26位,以后的字節(jié)都沒有改變,你也不可能在得到原始的CRC了,不可能了!你讀
過(guò)后面的段落時(shí)就會(huì)明白為什么.間而言之,當(dāng)你修改一個(gè)字節(jié)串時(shí),要保證CRC不變. 

1. 計(jì)算并保存從1~9位的CRC.
2. 繼續(xù)計(jì)算直到第27位還有額外的4字節(jié)并保存結(jié)果.
3. 用1的值來(lái)計(jì)算新的字節(jié)串和額外4字節(jié)的CRC(對(duì)應(yīng)patch后的新的CRC值),并將之保存.
4. 現(xiàn)在我們得到了一個(gè)新的CRC,但是我們希望將它還原成原先的CRC,所以我們用逆向算法
   來(lái)計(jì)算那額外的4字節(jié).

1~3就是實(shí)際的情況,下面你將學(xué)到最關(guān)鍵的部分4.


‘反轉(zhuǎn)‘CRC-16

  我想,先來(lái)介紹計(jì)算逆CRC-16對(duì)于你來(lái)說(shuō)會(huì)簡(jiǎn)單些.好的,我們現(xiàn)在處在一個(gè)恰當(dāng)?shù)奈恢?
在以修改代碼后面,就是你想將CRC還原的地方.我們知道原始的CRC(是在patch代碼之前計(jì)
算出來(lái)的)還有這個(gè)當(dāng)前的記存器值.現(xiàn)在我們的目的就是計(jì)算可以改變當(dāng)前記存器值到原
始記存器值的兩個(gè)字節(jié).首先,我們用正常的方法計(jì)算這兩個(gè)未知字節(jié)的CRC.我們?cè)O(shè)他們?yōu)?br>X,Y.設(shè)記存器為a1,a0,只有0不能用來(lái)作為變量(00).:)在來(lái)看一下我們的CRC算法,figure
3,更好的理解下面我要做的.

好,我們開始:

用這兩字節(jié)串‘X Y‘ 字節(jié)是從左邊開始被處理的.
記存器現(xiàn)在是a1 a0.
用‘+‘來(lái)表示XOR運(yùn)算(和第一部分中用的一樣)

處理第一個(gè)字節(jié), X:
a0+X            這是頂部字節(jié)的計(jì)算結(jié)果 (1)
b1 b0           這是(1)在表中索引對(duì)象.
00 a1           向右移動(dòng)記存器.
00+b1 a1+b0     上面兩行對(duì)應(yīng)位做XOR運(yùn)算.

現(xiàn)在記存器為: (b1) (a1+b0)

處理第二個(gè)字, Y:
(a1+b0)+Y       此輪頂部字節(jié)的計(jì)算結(jié)果(2)
c1 c0           這是(2)在表中的索引對(duì)象.
00 b1           向右移動(dòng)記存器.
00+c1 b1+c0     上面兩行對(duì)應(yīng)位做XOR運(yùn)算.

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

我用一點(diǎn)不同的方法來(lái)表示:

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

Wow! 請(qǐng)大家暫時(shí)記住上面的信息:)
別著急, 下面給出一個(gè)有具體值的例子.
 
  如果你想要的記存器的值是d1 d0(是原始的CRC),而且你知道在變換之前的記存器的值
(a1 a0)...那么你將要送如什么樣的2個(gè)字節(jié)進(jìn)記存器來(lái)做CRC計(jì)算呢? 
  好了,現(xiàn)在我們的工作應(yīng)該從幕后走到臺(tái)前來(lái)了.d0一定是bi+c0,并且d1一定是c1...
但是這到底是怎么回事,我聽到你這樣問了,你能知道b1和c0的值嗎???你還記得哪個(gè)值表
嗎?你只需要在表中查找c0 c1這個(gè)字的值就可以了因?yàn)槟阒纁1.所以你需要編寫一個(gè)查
找程序.假如你找到了這個(gè)值,一定要記住這個(gè)值的索引,因?yàn)檫@就是找出未知的兩個(gè)頂部
字節(jié),舉例來(lái)說(shuō):(1)和(2)!
  所以,現(xiàn)在你找到了c1 c0,那么如何來(lái)得到b1 b0呢?如果b1+c0=d0那么b1=d0+c0!如前所
述,現(xiàn)在你用哪個(gè)查找程序在表中查b1 b0的值.現(xiàn)在我們得到了所有計(jì)算X和Y所需要的值.
Cool huh? 
 a1+b0+Y=(2) so Y=a1+b0+(2)
 a0+X=(1)    so X=a0+(1)


實(shí)例.

讓我們來(lái)看看這個(gè)具體值的例子:
-register before: (a1=)DE (a0=)AD
-wanted register: (d1=)12 (d0=)34
在附錄的CRC-16的表中查找以12開頭值的入口.這里入口38h的值為12C0.試這找一找是否還
有以12開頭的值的入口.你不可能在找到的,因?yàn)槲覀冇?jì)算每一中頂部字節(jié)組合而得的值的
入口,一共是256個(gè)值,記住!
現(xiàn)在我們知道(2)=38,c1=12,c0=C0,所以b1=C0+34=F4,現(xiàn)在查找以F4開頭的b1的入口.這里
入口4Fh的值是F441.
我們還知道  (1)=4F,b1=F4,b0=41,現(xiàn)在所有我們需要的都已經(jīng)清楚了,接下來(lái)我們計(jì)算X,Y.

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

結(jié)論:將CRC 記存器的值從 DEAD 變?yōu)?1234 我們需要這兩個(gè)字節(jié) E2 A7 (以此順序).

  你看,破解CRC校驗(yàn)?zāi)阈枰聪蛴?jì)算,還有要記住的就是計(jì)算過(guò)程中的值.當(dāng)你在用匯編編寫
查找表程序時(shí),要注意intel在小模式中是反向存儲(chǔ)值的.現(xiàn)在你可能已經(jīng)明白如何去破解這個(gè)
CRC-16了...下面介紹如何在CRC-32中實(shí)現(xiàn).


破解 CRC-32

現(xiàn)在我們來(lái)看CRC-32,和CRC-16是一樣容易的(可能一樣的不容易你認(rèn)為).這里你操作的對(duì)象
是4個(gè)字節(jié)的而不是2字節(jié)的.繼續(xù)向下看,將它與上面CRC-16版本做對(duì)比.

設(shè)4字節(jié)串 X  Y  Z  W  , 從左邊開始處理.
設(shè)記存器為  a3 a2 a1 a0
注意a3是MSB,而a0是LSB

處理第一個(gè)字節(jié), X:
a0+X                    這是頂部字節(jié)的計(jì)算結(jié)果(1).
b3    b2    b1    b0    這是(1)在表中索引對(duì)象序列.
00    a3    a2    a1    右移記存器.
00+b3 a3+b2 a2+b1 a1+b0 上面兩行對(duì)應(yīng)位做XOR運(yùn)算.

現(xiàn)在記存器是: (b3) (a3+b2) (a2+b1) (a1+b0)

Processing second byte, Y:
(a1+b0)+Y                       這是頂部字節(jié)的計(jì)算結(jié)果(2).
c3    c2    c1       c0         這是(2)在表中索引對(duì)象序列.
00    b3    a3+b2    a2+b1      右移記存器.
00+c3 b3+c2 a3+b2+c1 a2+b1+c0   上面兩行對(duì)應(yīng)位做XOR運(yùn)算.

現(xiàn)在記存器是: (c3) (b3+c2) (a3+b2+c1) (a2+b1+c0)

Processing third byte, Z:
(a2+b1+c0)+Z                     這是頂部字節(jié)的計(jì)算結(jié)果(3).
d3    d2    d1       d0          這是(3)在表中索引對(duì)象序列.
00    c3    b3+c2    a3+b2+c1    右移記存器.
00+d3 c3+d2 b3+c2+d1 a3+b2+c1+d0 上面兩行對(duì)應(yīng)位做XOR運(yùn)算.

現(xiàn)在記存器是: (d3) (c3+d2) (b3+c2+d1) (a3+b2+c1+d0)

Processing fourth byte, W:
(a3+b2+c1+d0)+W                  這是頂部字節(jié)的計(jì)算結(jié)果(4).
e3    e2    e1       e0          這是(4)在表中索引對(duì)象序列.
00    d3    c3+d2    b3+c2+d1    右移記存器.
00+e3 d3+e2 c3+d2+e1 b3+c2+d1+e0 上面兩行對(duì)應(yīng)位做XOR運(yùn)算.

最后,記存器為: (e3) (d3+e2) (c3+d2+e1) (b3+c2+d1+e0)

我用一個(gè)不同一點(diǎn)的方法來(lái)表示:
a0 + X                  =(1)  在表中指向 b3 b2 b1 b0 
a1 + b0 + Y             =(2)  在表中指向 c3 c2 c1 c0 
a2 + b1 + c0 + Z        =(3)  在表中指向 d3 d2 d1 d0 
a3 + b2 + c1 + d0 + W   =(4)  在表中指向 e4 e3 e2 e1 
     b3 + c2 + d1 + e0  =f0
          c3 + d2 + e1  =f1
               d3 + e2  =f2
                    e3  =f3
    (1)  (2)  (3)  (4)
(figure 4)


這里是用的與CRC-16同樣的方法來(lái)實(shí)現(xiàn)的,我會(huì)給出一個(gè)具體值的例子.查找用附錄中
CRC-32的值表.

Take for CRC register before, a3 a2 a1 a0 -> AB CD EF 66
Take for CRC register after,  f3 f2 f1 f0 -> 56 33 14 78 (wanted value)

我們開始:

First byte of entries            entry   value
e3=f3                     =56 -> 35h=(4) 56B3C423 for e3 e2 e1 e0
d3=f2+e2      =33+B3      =E6 -> 4Fh=(3) E6635C01 for d3 d2 d1 d0
c3=f1+e1+d2   =14+C4+63   =B3 -> F8h=(2) B3667A2E for c3 c2 c1 c0
b3=f0+e0+d1+c2=78+23+5C+66=61 -> DEh=(1) 616BFFD3 for b3 b2 b1 b0

Now we have all needed values, then
X=(1)+         a0=         DE+66=B8
Y=(2)+      b0+a1=      F8+D3+EF=C4
Z=(3)+   c0+b1+a2=   4F+2E+FF+CD=53
W=(4)+d0+c1+b2+a3=35+01+7A+6B+AB=8E
(final computation)

結(jié)論:要將 CRC-32 的記存器的值從 ABCDEF66 改變到 56331478 我們需要這樣一個(gè)字節(jié)
序列: B8 C4 53 8E

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
CRC算法原理及C語(yǔ)言實(shí)現(xiàn)(轉(zhuǎn)載)
我學(xué)習(xí)CRC32、CRC16、CRC原理和算法的總結(jié)(與WINRAR結(jié)果一致)
矛與盾的較量(2)——CRC原理篇
c語(yǔ)言CRC校驗(yàn)
哪位大哥熟悉CRC16 CRC32,能幫掃掃盲么?
一個(gè)簡(jiǎn)單的算法Crackme
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服