EasyBoot(7千字)

看雪資料發表於2015-11-15

寫在前面的話:

  如果在讀本文的時候不瞭解RSA,那麼建議先學習了以後再來,因為文中不會分析RSA的具體實現。

EasyBoot由Borland C++ Builder寫成,典型的啟動驗證。

當註冊資訊輸入完畢後,會把註冊碼一定程度的加密存放到登錄檔中:
[HKEY_CURRENT_USER\Software\EasyBoot Systems\EasyBoot\3.0]

所以對RegQueryValueExA下斷,當讀取'UserName'和'Registration'的時候,我們要留心了。

首先是機械的把註冊碼解密,所以我們不用關心他的加密過程了,因為。。。

然後呢可以看到使用者名稱和註冊碼入棧,說明要計算了,來到這裡:
00401670  55                    push    ebp

00401692  6A05                  push    $05            ;空間大小
00401694  6A30                  push    $30            ;初始值
00401696  8D4DE4                lea    ecx, [ebp-$1C]
00401699  51                    push    ecx
0040169A  E821480A00            call    004A5EC0        ;分配一片空間,並且附初值'00000'

004016A2  C645E431              mov    byte ptr [ebp-$1C], $31
004016A6  C645E831              mov    byte ptr [ebp-$18], $31
004016AA  C645E900              mov    byte ptr [ebp-$17], $00        ;到這裡得到了'10001',記做e

004016AE  6A10                  push    $10
004016B0  6A41                  push    $41
004016B2  8D85CCFCFFFF          lea    eax, [ebp+$FFFFFCCC]
004016B8  50                    push    eax
004016B9  E802480A00            call    004A5EC0        ;和上面一樣,'AAAAAAAAAAAAAAAA'
004016BE  83C40C                add    esp, +$0C
004016C1  C685DBFCFFFF31        mov    byte ptr [ebp+$FFFFFCDB], $31
004016C8  C685DAFCFFFF44        mov    byte ptr [ebp+$FFFFFCDA], $44
004016CF  C685CEFCFFFF30        mov    byte ptr [ebp+$FFFFFCCE], $30
004016D6  C685CFFCFFFF46        mov    byte ptr [ebp+$FFFFFCCF], $46
004016DD  C685D1FCFFFF46        mov    byte ptr [ebp+$FFFFFCD1], $46
004016E4  C685D0FCFFFF38        mov    byte ptr [ebp+$FFFFFCD0], $38
004016EB  C685D3FCFFFF32        mov    byte ptr [ebp+$FFFFFCD3], $32
004016F2  C685D6FCFFFF36        mov    byte ptr [ebp+$FFFFFCD6], $36
004016F9  C685D2FCFFFF36        mov    byte ptr [ebp+$FFFFFCD2], $36
00401700  C685D7FCFFFF45        mov    byte ptr [ebp+$FFFFFCD7], $45
00401707  C685D8FCFFFF39        mov    byte ptr [ebp+$FFFFFCD8], $39
0040170E  C685D9FCFFFF37        mov    byte ptr [ebp+$FFFFFCD9], $37
00401715  C685CDFCFFFF37        mov    byte ptr [ebp+$FFFFFCCD], $37
0040171C  C685DCFCFFFF00        mov    byte ptr [ebp+$FFFFFCDC], $00        ;得到'A70F8F62AA6E97D1',記做n

00401726  52                    push    edx
00401727  FF750C                push    dword ptr [ebp+$0C]        ;儲存的是註冊碼的字串
0040172A  E8995E0200            call    004275C8                  ;字串轉換成某種大數的方式儲存

00401740  8D85CCFCFFFF          lea    eax, [ebp+$FFFFFCCC]      ;n
00401746  50                    push    eax
00401747  E87C5E0200            call    004275C8                  ;把n轉換儲存

00401753  8D4DE4                lea    ecx, [ebp-$1C]            ;e
00401756  51                    push    ecx
00401757  E86C5E0200            call    004275C8                  ;把e轉換儲存

00401763  FF75FC                push    dword ptr [ebp-$04]        ;e的大數形式
00401766  FF75F8                push    dword ptr [ebp-$08]        ;n的大數形式
00401769  FF75F4                push    dword ptr [ebp-$0C]        ;註冊碼的大數形式
0040176C  E8B74C0200            call    00426428                  ;RSA_EN的函式,不相信可以進去看哦

00401777  8D95E0FEFFFF          lea    edx, [ebp+$FFFFFEE0]      ;計算的結果,按照大數形式存放的
0040177D  52                    push    edx
0040177E  E865600200            call    004277E8                  ;還原成為字串s,然後開始檢查

第一步,檢查常數:
00401786  C705A8D34B0030000000  mov    dword ptr [$004BD3A8], $00000030        ;把[$004BD3A8]記做變數x = $30
00401790  0FBE8DE0FEFFFF        movsx  ecx, byte ptr [ebp+$FFFFFEE0]
00401797  83F934                cmp    ecx, +$34
0040179A  7506                  jnz    004017A2
0040179C  FF05A8D34B00          inc    dword ptr [$004BD3A8]                  ;if s[1]='4' then inc(x)
004017A2  0FBE85E1FEFFFF        movsx  eax, byte ptr [ebp+$FFFFFEE1]
004017A9  83F835                cmp    eax, +$35
004017AC  7506                  jnz    004017B4
004017AE  FF05A8D34B00          inc    dword ptr [$004BD3A8]                  ;if s[2]='5' then inc(x)
004017B4  0FBE95E6FEFFFF        movsx  edx, byte ptr [ebp+$FFFFFEE6]
004017BB  83FA32                cmp    edx, +$32
004017BE  7C0C                  jl      004017CC
004017C0  0FBE8DE6FEFFFF        movsx  ecx, byte ptr [ebp+$FFFFFEE6]
004017C7  83F932                cmp    ecx, +$32
004017CA  7E06                  jle    004017D2
004017CC  FF0DA8D34B00          dec    dword ptr [$004BD3A8]                  ;if s[7]<>'2' then dec(x)
004017D2  0FBE85E8FEFFFF        movsx  eax, byte ptr [ebp+$FFFFFEE8]
004017D9  83F835                cmp    eax, +$35
004017DC  7506                  jnz    004017E4
004017DE  FF05A8D34B00          inc    dword ptr [$004BD3A8]                  ;if s[9]='5' then inc(x)
004017E4  0FBE95E9FEFFFF        movsx  edx, byte ptr [ebp+$FFFFFEE9]
004017EB  83FA61                cmp    edx, +$61
004017EE  7506                  jnz    004017F6
004017F0  FF05A8D34B00          inc    dword ptr [$004BD3A8]                  ;if s[10]='a' then inc(x)
004017F6  0FBE8DE7FEFFFF        movsx  ecx, byte ptr [ebp+$FFFFFEE7]
004017FD  83F961                cmp    ecx, +$61
00401800  7C0C                  jl      0040180E
00401802  0FBE85E7FEFFFF        movsx  eax, byte ptr [ebp+$FFFFFEE7]
00401809  83F861                cmp    eax, +$61
0040180C  7E06                  jle    00401814
0040180E  FF0DA8D34B00          dec    dword ptr [$004BD3A8]                  ;if s[8]<>'a' then dec(x)
00401814  0FBE95EEFEFFFF        movsx  edx, byte ptr [ebp+$FFFFFEEE]
0040181B  83FA34                cmp    edx, +$34
0040181E  7506                  jnz    00401826
00401820  FF05A8D34B00          inc    dword ptr [$004BD3A8]                  ;if s[15]='4' then inc(x)
00401826  0FBE8DEFFEFFFF        movsx  ecx, byte ptr [ebp+$FFFFFEEF]
0040182D  83F932                cmp    ecx, +$32
00401830  7506                  jnz    00401838
00401832  FF05A8D34B00          inc    dword ptr [$004BD3A8]                  ;if s[16]='2' then inc(x)
00401838  A1A8D34B00            mov    eax, dword ptr [$004BD3A8]              ;EAX = x
0040183D  83F836                cmp    eax, +$36                              ;x<>$36就失敗了
00401840  0F8532010000          jnz    00401978

那麼這裡如何讓x=$36呢,上面一共有8個條件,實際上就是8個等式,全部滿足就對了,所以這裡是常數的檢查。

第二步是變數的檢查,也就是和註冊名相關了,和上面一樣的,就不多說了。

最後的結論,計算註冊碼的時候首先根據註冊名得到RSA的密文,然後解密即可,RSA的引數如下:

n = $A70F8F62AA6E97D1
e = $10001
d = $A7CAD9177AE95A9

相關文章