1. 程式人生 > >【原創】OllyDBG 入門系列(四)-記憶體斷點

【原創】OllyDBG 入門系列(四)-記憶體斷點

還是上次那個cm,不過這次的要求是寫出註冊機

那麼就要先研究註冊碼是怎麼來的,上次我們最開始找到的關鍵位置

00401306  |. /75 6B         jnz     short 00401373
00401308  |. |C1E8 10       shr     eax,0x10
0040130B  |. |66:0BC0       or      ax,ax
0040130E  |. |75 63         jnz     short 00401373
00401310  |. |8B35 9C334000 mov     esi,dword ptr ds:[0x40339C]      ;  這裡就是我們函式中esi的初始值
00401316
|. |6A 28 push 0x28 ; /Count = 28 (40.) 00401318 |. |68 C4334000 push 004033C4 ; |Buffer = CrackHea.004033C4 0040131D |. |FF35 90314000 push dword ptr ds:[0x403190] ; |hWnd = 00FF01AE (class='Edit',parent=000C0126) 00401323 |. |E8 4C010000 call <jmp.&USER32.GetWindowTextA> ; \GetWindowTextA
00401328 |. |E8 A5000000 call 004013D2 ; 關鍵函式 0040132D |. |3BC6 cmp eax,esi ; eax要和esi相等 0040132F |. |75 42 jnz short 00401373 ; 不能跳 00401331 |. |EB 2C jmp short 0040135F 00401333 |. |4E 6F 77 20 7>ascii "Now write a keyg"
00401343 |. |65 6E 20 61 6>ascii "en and tut and y" 00401353 |. |6F 75 27 72 6>ascii "ou're done.",0 0040135F |> |6A 00 push 0x0 ; /Style = MB_OK|MB_APPLMODAL 00401361 |. |68 0F304000 push 0040300F ; |Title = "Crudd's Crack Head" 00401366 |. |68 33134000 push 00401333 ; |Text = "Now write a keygen and tut and you're done." 0040136B |. |FF75 08 push [arg.1] ; |hOwner 0040136E |. |E8 19010000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA

具體位置如下
00401310 |. 8B35 9C334000 mov esi,dword ptr ds:[0x40339C] ; 這裡就是我們函式中esi的初始值
這裡的esi的初始值參與到了我們註冊碼的生成中,

所以這裡我們確定位置,0x40339c ,然後下記憶體斷點,找到初始化的程式碼位置。
這裡有一個要注意的地方,記憶體斷點只能設定一個並且在重啟程式後會自動消失。
在資料視窗 右鍵–>轉到–>表示式 或者用快捷鍵ctrl+g

這裡寫圖片描述

下記憶體寫入斷點

這裡寫圖片描述

執行起程式,發現斷在了ntdll領空 alt+f9 回到使用者領空

找到了關鍵函式

0040140C  /$  60            pushad
0040140D  |.  6A 00         push    0x0                              ; /RootPathName = NULL
0040140F  |.  E8 B4000000   call    <jmp.&KERNEL32.GetDriveTypeA>    ; \GetDriveTypeA
00401414  |.  A2 EC334000   mov     byte ptr ds:[0x4033EC],al        ;  得到磁碟型別 al=3
00401419  |.  6A 00         push    0x0                              ; /pFileSystemNameSize = NULL
0040141B  |.  6A 00         push    0x0                              ; |pFileSystemNameBuffer = NULL
0040141D  |.  6A 00         push    0x0                              ; |pFileSystemFlags = NULL
0040141F  |.  6A 00         push    0x0                              ; |pMaxFilenameLength = NULL
00401421  |.  6A 00         push    0x0                              ; |pVolumeSerialNumber = NULL
00401423  |.  6A 0B         push    0xB                              ; |MaxVolumeNameSize = B (11.)
00401425  |.  68 9C334000   push    0040339C                         ; |VolumeNameBuffer = CrackHea.0040339C
0040142A  |.  6A 00         push    0x0                              ; |RootPathName = NULL
0040142C  |.  E8 A3000000   call    <jmp.&KERNEL32.GetVolumeInformat>; \GetVolumeInformationA
00401431  |.  8D35 9C334000 lea     esi,dword ptr ds:[0x40339C]      ;  得到磁碟資訊 VolumenameBuffer
00401437  |.  0FB60D EC3340>movzx   ecx,byte ptr ds:[0x4033EC]       ;  存放的是磁碟型別
0040143E  |.  33FF          xor     edi,edi                          ;  edi清零
00401440  |>  8BC1          mov     eax,ecx
00401442  |.  8B1E          mov     ebx,dword ptr ds:[esi]           ;  卷標的名稱作為數值送入ebx
00401444  |.  F7E3          mul     ebx                              ;  相乘
00401446  |.  03F8          add     edi,eax                          ;  把值累加在edi中
00401448  |.  49            dec     ecx
00401449  |.  83F9 00       cmp     ecx,0x0
0040144C  |.^ 75 F2         jnz     short 00401440
0040144E  |.  893D 9C334000 mov     dword ptr ds:[0x40339C],edi
00401454  |.  61            popad
00401455  \.  C3            retn

可以直接分析,也可以代入到IDA裡面分析

大體的流程就是 獲得驅動型別和磁碟的卷標,然後把驅動型別的數值和磁碟卷標的名字轉換為數值按4位元組為單位,相乘並累加,最後儲存到0x40339c中。

這樣大體流程清楚了就容易寫註冊機了。