HTMLock 1.9.3破解手記---演算法分析

看雪資料發表於2003-06-27

HTMLock 1.9.3破解手記---演算法分析
作者:newlaos[DFCG][CCG]


檔案大小:668KB
軟體授權:共享軟體
使用平臺:Win9x/Me/NT/2000
下載連結:http://sq.onlinedown.net/down/htl.zip
軟體簡介:幫助您建立基於 javascript 的密碼保護頁面。但對中文不支援。


加密方式:註冊碼
功能限制:日期+功能限制
PJ工具:TRW20001.23註冊版,W32Dasm8.93黃金版,FI2.5
PJ日期:2003-06-24 ~ 6-26
作者newlaos申明:只是學習,請不用於商業用途或是將本文方法制作的序號產生器任意傳播,造成後果,本人一概不負。


一、奇妙的開始

首先我們用常用方法,對軟體進行分析。執行軟體,發現有註冊對話方塊,卻無法擊活“註冊”按鈕。呵呵,我想起了“按鈕突破專家”,果然有效,但只是顯示感謝誰誰誰的註冊,功能上還是受限制,而且重啟後還是顯示沒有註冊。

二、興奮的過程

1、找到第一個註冊碼檢證點。因為沒有關鍵字串可以找,所以只有用bpx hmemcpy(萬能斷點大法),很快你就能定位到下列這斷程式碼段。
經過除錯,你會發現這段程式碼是一個迴圈事件,只要使用者名稱或註冊碼的框內有變化,它就執行一遍,檢查輸入的註冊碼是否符合要求,如果符合這個註冊碼檢證點的要求,“註冊”按鈕就會自動擊活,原來不用“按鈕突破專家”啊!
.......
.......
* Referenced by a CALL at Addresses:
|:00471567   , :0047160F   , :004718C0   , :00471CB8  
|
:00470B80 55                      push ebp
:00470B81 8BEC                    mov ebp, esp
:00470B83 83C4F8                  add esp, FFFFFFF8
:00470B86 53                      push ebx
:00470B87 56                      push esi
:00470B88 33C9                    xor ecx, ecx
:00470B8A 894DF8                  mov dword ptr [ebp-08], ecx
:00470B8D 8BDA                    mov ebx, edx
:00470B8F 8BF0                    mov esi, eax
:00470B91 33C0                    xor eax, eax
:00470B93 55                      push ebp
:00470B94 681A0C4700              push 00470C1A
:00470B99 64FF30                  push dword ptr fs:[eax]
:00470B9C 648920                  mov dword ptr fs:[eax], esp
:00470B9F C645FF00                mov [ebp-01], 00
:00470BA3 8BC3                    mov eax, ebx
:00470BA5 E80E37F9FF              call 004042B8
:00470BAA 83F802                  cmp eax, 00000002  <===註冊名必須長於2位
:00470BAD 7C55                    jl 00470C04  <===這裡跳了就OVER了
:00470BAF 8BC6                    mov eax, esi
:00470BB1 E80237F9FF              call 004042B8
:00470BB6 83F824                  cmp eax, 00000024  <===很明顯,這裡是要求註冊碼必須長於36位
:00470BB9 7C49                    jl 00470C04  <===這裡跳了就OVER了
:00470BBB 33DB                    xor ebx, ebx
:00470BBD 8BC6                    mov eax, esi
:00470BBF E8F436F9FF              call 004042B8 <===求出註冊碼的長度來
:00470BC4 83E802                  sub eax, 00000002 <===這個長度減去2,因為前面部分是用來計算後兩位的
:00470BC7 85C0                    test eax, eax
:00470BC9 7E0F                    jle 00470BDA
:00470BCB BA01000000              mov edx, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00470BD8(C)
|
:00470BD0 8A4C16FF                mov cl, byte ptr [esi+edx-01] <===取字元的ASC值
:00470BD4 02D9                    add bl, cl
:00470BD6 42                      inc edx
:00470BD7 48                      dec eax
:00470BD8 75F6                    jne 00470BD0   <===這裡構成一個迴圈結構,對註冊碼的前面部分運算(不包括後兩位),但不超過255。

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00470BC9(C)
|
:00470BDA 33C0                    xor eax, eax
:00470BDC 8AC3                    mov al, bl   <===BL就是上面迴圈的結果
:00470BDE 33D2                    xor edx, edx
:00470BE0 52                      push edx
:00470BE1 50                      push eax
:00470BE2 8D45F8                  lea eax, dword ptr [ebp-08]
:00470BE5 E85AFEFFFF              call 00470A44   <===一個關鍵CALL,F8跟進
:00470BEA 8B45F8                  mov eax, dword ptr [ebp-08]
:00470BED 8A400E                  mov al, byte ptr [eax+0E]
:00470BF0 3A4622                  cmp al, byte ptr [esi+22]  <===對比輸入假碼的第35位
:00470BF3 750F                    jne 00470C04  <===跳了就OVER了
:00470BF5 8B45F8                  mov eax, dword ptr [ebp-08]
:00470BF8 8A400F                  mov al, byte ptr [eax+0F]
:00470BFB 3A4623                  cmp al, byte ptr [esi+23]  <===對比輸入假碼的第36位,因為這裡的特殊性使得註冊碼只是36位的長度(根據BL的取值決定最後兩位,因為通常情況下我無法將一個值等於這個值做為中間值參與計算後的結果)
:00470BFE 7504                    jne 00470C04  <===跳了就OVER了
:00470C00 C645FF01                mov [ebp-01], 01   <===很明顯,必須經過這裡才能正確註冊

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00470BAD(C), :00470BB9(C), :00470BF3(C), :00470BFE(C)  <===這四處都是錯誤的跳轉了
|
:00470C04 33C0                    xor eax, eax
:00470C06 5A                      pop edx
:00470C07 59                      pop ecx
:00470C08 59                      pop ecx
:00470C09 648910                  mov dword ptr fs:[eax], edx
:00470C0C 68210C4700              push 00470C21

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00470C1F(U)
|
:00470C11 8D45F8                  lea eax, dword ptr [ebp-08]
:00470C14 E8DF33F9FF              call 00403FF8
:00470C19 C3                      ret


:00470C1A E9DD2DF9FF              jmp 004039FC
:00470C1F EBF0                    jmp 00470C11
:00470C21 8A45FF                  mov al, byte ptr [ebp-01]  <===最為關鍵的賦值,要求AL不能為0,(當然這裡也是爆破點,即讓AL始終為1)
:00470C24 5E                      pop esi
:00470C25 5B                      pop ebx
:00470C26 59                      pop ecx
:00470C27 59                      pop ecx
:00470C28 5D                      pop ebp
:00470C29 C3                      ret
.......
.......
-----------:00470BE5 call 00470A44   <===一個關鍵CALL,F8跟進-----------------
:00470A44 55                      push ebp
:00470A45 8BEC                    mov ebp, esp
:00470A47 83C4F8                  add esp, FFFFFFF8
:00470A4A 53                      push ebx
:00470A4B 56                      push esi
:00470A4C 8BF0                    mov esi, eax
:00470A4E 8BC6                    mov eax, esi
:00470A50 BA10000000              mov edx, 00000010
:00470A55 E8EA3BF9FF              call 00404644
:00470A5A 8B4508                  mov eax, dword ptr [ebp+08]
:00470A5D 8945F8                  mov dword ptr [ebp-08], eax
:00470A60 8B450C                  mov eax, dword ptr [ebp+0C]
:00470A63 8945FC                  mov dword ptr [ebp-04], eax
:00470A66 BB10000000              mov ebx, 00000010

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00470AC4(C)
|
:00470A6B 8B45F8                  mov eax, dword ptr [ebp-08]
:00470A6E 8B55FC                  mov edx, dword ptr [ebp-04]
:00470A71 52                      push edx
:00470A72 50                      push eax
:00470A73 6A00                    push 00000000
:00470A75 6A10                    push 00000010
:00470A77 8B45F8                  mov eax, dword ptr [ebp-08]
:00470A7A 8B55FC                  mov edx, dword ptr [ebp-04]
:00470A7D 0FACD004                shrd eax, edx, 04
:00470A81 C1EA04                  shr edx, 04
:00470A84 E84343F9FF              call 00404DCC
:00470A89 290424                  sub dword ptr [esp], eax
:00470A8C 19542404                sbb dword ptr [esp+04], edx
:00470A90 58                      pop eax
:00470A91 5A                      pop edx
:00470A92 83C001                  add eax, 00000001
:00470A95 83D200                  adc edx, 00000000

* Possible StringData Ref from Code Obj ->"HACKERYouMUSTDie"    
                                 |
:00470A98 BAD80A4700              mov edx, 00470AD8
:00470A9D 8A4402FF                mov al, byte ptr [edx+eax-01]
:00470AA1 50                      push eax
:00470AA2 8BC6                    mov eax, esi
:00470AA4 E8673AF9FF              call 00404510
:00470AA9 5A                      pop edx
:00470AAA 885418FF                mov byte ptr [eax+ebx-01], dl
:00470AAE 8B45F8                  mov eax, dword ptr [ebp-08]
:00470AB1 8B55FC                  mov edx, dword ptr [ebp-04]
:00470AB4 0FACD004                shrd eax, edx, 04
:00470AB8 C1EA04                  shr edx, 04
:00470ABB 8945F8                  mov dword ptr [ebp-08], eax
:00470ABE 8955FC                  mov dword ptr [ebp-04], edx
:00470AC1 4B                      dec ebx
:00470AC2 85DB                    test ebx, ebx
:00470AC4 75A5                    jne 00470A6B
:00470AC6 5E                      pop esi
:00470AC7 5B                      pop ebx
:00470AC8 59                      pop ecx
:00470AC9 59                      pop ecx
:00470ACA 5D                      pop ebp
:00470ACB C20800                  ret 0008
上面一段只是註冊碼的合法性,沒有與註冊名發生關係,註冊碼初步定為"1234567890123456789012345678901234eA"
---------------------------------------------------------------------------

2、找第2個註冊碼的檢證點。上面的註冊碼未免太說不過去了,果然一執行生成加密網頁時,立馬報告說未註冊版本,加密的網頁不能大於4KB。在這裡可以用BPX SENDMESSAGE的斷點方法找到下列程式碼段,但我還是推薦用BPX HMEMCPY(提示:雖然有時離關鍵地方很遠,但至少是在註冊校驗的前面,只要注意暫存器裡的資料變化,一但發現自己輸入的假碼,就立馬停下來仔細觀察),這裡的關鍵演算法段是在00472208行的CALL裡。
.......
.......
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004721D5(C)
|
:004721EC 8B45F4                  mov eax, dword ptr [ebp-0C]
:004721EF E8CCE2FFFF              call 004704C0
:004721F4 3D00100000              cmp eax, 00001000   <===0x1000就是10進位制的4096也就是軟體未註冊時4K大小的限制了,改這裡可以實現功能上的爆破
:004721F9 0F9745D7                seta byte ptr [ebp-29]
:004721FD 807DD700                cmp byte ptr [ebp-29], 00
:00472201 7464                    je 00472267   <===這裡是第一點,從這裡跳,就是說所加密的軟體小於4KB
:00472203 A17C7C4700              mov eax, dword ptr [00477C7C]   <===EAX="1234567890123456789012345678901234eA"就是我們輸入的假註冊碼了
:00472208 E8E7ECFFFF              call 00470EF4  <===不用問了,還要F8跟進
:0047220D 84C0                    test al, al    <===要求是返回時AL應該為1,才能正確執行
:0047220F 7556                    jne 00472267   <===這裡必須跳走
:00472211 6A10                    push 00000010
:00472213 8D559C                  lea edx, dword ptr [ebp-64]

* Possible StringData Ref from Code Obj ->"`vG"
                                 |
:00472216 B868174700              mov eax, 00471768
:0047221B E8003AF9FF              call 00405C20
:00472220 8B459C                  mov eax, dword ptr [ebp-64]
:00472223 E89022F9FF              call 004044B8
:00472228 50                      push eax
:00472229 8D5598                  lea edx, dword ptr [ebp-68]

* Possible StringData Ref from Code Obj ->"`vG"
                                 |
:0047222C B818184700              mov eax, 00471818
:00472231 E8EA39F9FF              call 00405C20
:00472236 8B4598                  mov eax, dword ptr [ebp-68]
:00472239 E87A22F9FF              call 004044B8
:0047223E 50                      push eax
:0047223F 6A00                    push 00000000

* Reference To: user32.MessageBoxA, Ord:0000h
                                 |
:00472241 E85246F9FF              Call 00406898   <===這裡就是出現未註冊對話方塊的資訊
:00472246 A1F4684700              mov eax, dword ptr [004768F4]
:0047224B 8B00                    mov eax, dword ptr [eax]
:0047224D E8B2190000              call 00473C04
:00472252 8B45F4                  mov eax, dword ptr [ebp-0C]
:00472255 E84E10F9FF              call 004032A8
:0047225A 8B45F0                  mov eax, dword ptr [ebp-10]
:0047225D E84610F9FF              call 004032A8
:00472262 E998030000              jmp 004725FF

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00472201(C), :0047220F(C)            <===有兩處可以跳過去了,向上看
|
:00472267 B930750000              mov ecx, 00007530
.......
.......
----------:00472208 call 00470EF4  不用問了,第2個關鍵檢測點,還要F8跟進---------
:00470EF4 55                      push ebp
:00470EF5 8BEC                    mov ebp, esp
:00470EF7 83C4E0                  add esp, FFFFFFE0
:00470EFA 53                      push ebx
:00470EFB 56                      push esi
:00470EFC 33D2                    xor edx, edx
:00470EFE 8955FC                  mov dword ptr [ebp-04], edx
:00470F01 8955F8                  mov dword ptr [ebp-08], edx
:00470F04 8BD8                    mov ebx, eax  <===EBX="1234567890123456789012345678901234eA"
:00470F06 33C0                    xor eax, eax
:00470F08 55                      push ebp
:00470F09 68EA104700              push 004710EA
:00470F0E 64FF30                  push dword ptr fs:[eax]
:00470F11 648920                  mov dword ptr fs:[eax], esp
:00470F14 E8F7F9FFFF              call 00470910
:00470F19 8D45FC                  lea eax, dword ptr [ebp-04]
:00470F1C BA10000000              mov edx, 00000010
:00470F21 E81E37F9FF              call 00404644
:00470F26 8D45FC                  lea eax, dword ptr [ebp-04]
:00470F29 E8E235F9FF              call 00404510
:00470F2E 8A5301                  mov dl, byte ptr [ebx+01]  <===取第2位2
:00470F31 8810                    mov byte ptr [eax], dl
:00470F33 8D45FC                  lea eax, dword ptr [ebp-04]
:00470F36 E8D535F9FF              call 00404510
:00470F3B 8A5303                  mov dl, byte ptr [ebx+03]  <===取第4位4
:00470F3E 885001                  mov byte ptr [eax+01], dl
:00470F41 8D45FC                  lea eax, dword ptr [ebp-04]
:00470F44 E8C735F9FF              call 00404510
:00470F49 8A5304                  mov dl, byte ptr [ebx+04]  <===取第5位5
:00470F4C 885002                  mov byte ptr [eax+02], dl
:00470F4F 8D45FC                  lea eax, dword ptr [ebp-04]
:00470F52 E8B935F9FF              call 00404510
:00470F57 8A5309                  mov dl, byte ptr [ebx+09]  <===取第10位0
:00470F5A 885003                  mov byte ptr [eax+03], dl
:00470F5D 8D45FC                  lea eax, dword ptr [ebp-04]
:00470F60 E8AB35F9FF              call 00404510
:00470F65 8A530A                  mov dl, byte ptr [ebx+0A]  <===取第11位1
:00470F68 885004                  mov byte ptr [eax+04], dl
:00470F6B 8D45FC                  lea eax, dword ptr [ebp-04]
:00470F6E E89D35F9FF              call 00404510
:00470F73 8A530B                  mov dl, byte ptr [ebx+0B]  <===取第12位2
:00470F76 885005                  mov byte ptr [eax+05], dl
:00470F79 8D45FC                  lea eax, dword ptr [ebp-04]
:00470F7C E88F35F9FF              call 00404510
:00470F81 8A530D                  mov dl, byte ptr [ebx+0D]  <===取第14位4
:00470F84 885006                  mov byte ptr [eax+06], dl
:00470F87 8D45FC                  lea eax, dword ptr [ebp-04]
:00470F8A E88135F9FF              call 00404510
:00470F8F 8A530E                  mov dl, byte ptr [ebx+0E]  <===取第15位5
:00470F92 885007                  mov byte ptr [eax+07], dl
:00470F95 8D45FC                  lea eax, dword ptr [ebp-04]
:00470F98 E87335F9FF              call 00404510
:00470F9D 8A530F                  mov dl, byte ptr [ebx+0F]  <===取第16位6
:00470FA0 885008                  mov byte ptr [eax+08], dl
:00470FA3 8D45FC                  lea eax, dword ptr [ebp-04]
:00470FA6 E86535F9FF              call 00404510
:00470FAB 8A5313                  mov dl, byte ptr [ebx+13]  <===取第20位0
:00470FAE 885009                  mov byte ptr [eax+09], dl
:00470FB1 8D45FC                  lea eax, dword ptr [ebp-04]
:00470FB4 E85735F9FF              call 00404510
:00470FB9 8A5314                  mov dl, byte ptr [ebx+14]  <===取第21位1
:00470FBC 88500A                  mov byte ptr [eax+0A], dl
:00470FBF 8D45FC                  lea eax, dword ptr [ebp-04]
:00470FC2 E84935F9FF              call 00404510
:00470FC7 8A5316                  mov dl, byte ptr [ebx+16]  <===取第23位3
:00470FCA 88500B                  mov byte ptr [eax+0B], dl
:00470FCD 8D45FC                  lea eax, dword ptr [ebp-04]
:00470FD0 E83B35F9FF              call 00404510
:00470FD5 8A5319                  mov dl, byte ptr [ebx+19]  <===取第26位6
:00470FD8 88500C                  mov byte ptr [eax+0C], dl
:00470FDB 8D45FC                  lea eax, dword ptr [ebp-04]
:00470FDE E82D35F9FF              call 00404510
:00470FE3 8A531A                  mov dl, byte ptr [ebx+1A]  <===取第27位7
:00470FE6 88500D                  mov byte ptr [eax+0D], dl
:00470FE9 8D45FC                  lea eax, dword ptr [ebp-04]
:00470FEC E81F35F9FF              call 00404510
:00470FF1 8A531B                  mov dl, byte ptr [ebx+1B]  <===取第28位8
:00470FF4 88500E                  mov byte ptr [eax+0E], dl
:00470FF7 8D45FC                  lea eax, dword ptr [ebp-04]
:00470FFA E81135F9FF              call 00404510
:00470FFF 8A531C                  mov dl, byte ptr [ebx+1C]  <===取第29位9,根據不的位置取出註冊碼的值(構成2450124560136789)
:00471002 88500F                  mov byte ptr [eax+0F], dl
:00471005 8B45FC                  mov eax, dword ptr [ebp-04]
:00471008 E8DFFAFFFF              call 00470AEC   <===特殊的處理的CALL(下面還會用到的) ,所有的迷都在這裡面只是F8跟進了:-)
:0047100D 8945F0                  mov dword ptr [ebp-10], eax  <===得出值1,應該為0x2535022E,根據call 00470AEC的功能推出來,EAX的值對應的是取出的註冊碼的後8位在內定字串"HACKERYouMUSTDie"的位置減1,所以: 2535022E
 2+1=3  --->對應"HACKERYouMUSTDie"的第 3位--->"C" --->對應的就是註冊碼的第16位
 5+1=6  --->對應"HACKERYouMUSTDie"的第 6位--->"R" --->對應的就是註冊碼的第20位
 3+1=4  --->對應"HACKERYouMUSTDie"的第 4位--->"K" --->對應的就是註冊碼的第21位
 5+1=6  --->對應"HACKERYouMUSTDie"的第 6位--->"R" --->對應的就是註冊碼的第23位
 0+1=1  --->對應"HACKERYouMUSTDie"的第 1位--->"H" --->對應的就是註冊碼的第26位
 2+1=3  --->對應"HACKERYouMUSTDie"的第 3位--->"C" --->對應的就是註冊碼的第27位
 2+1=3  --->對應"HACKERYouMUSTDie"的第 3位--->"C" --->對應的就是註冊碼的第28位
 E+1=F  --->對應"HACKERYouMUSTDie"的第15位--->"i" --->對應的就是註冊碼的第29位

:00471010 8955F4                  mov dword ptr [ebp-0C], edx  <===得出值2  (下面將用到),從下面推出結果應該為0x354310AC,再根據call 00470AEC的功能推出來,EDX的值對應的是取出的註冊碼的前8位在內定字串"HACKERYouMUSTDie"的位置減1,所以: 354310AC
 3+1=4  --->對應"HACKERYouMUSTDie"的第 4位--->"K" --->對應的就是註冊碼的第 2位
 5+1=6  --->對應"HACKERYouMUSTDie"的第 6位--->"R" --->對應的就是註冊碼的第 4位
 4+1=5  --->對應"HACKERYouMUSTDie"的第 5位--->"E" --->對應的就是註冊碼的第 5位
 3+1=4  --->對應"HACKERYouMUSTDie"的第 4位--->"K" --->對應的就是註冊碼的第10位
 1+1=2  --->對應"HACKERYouMUSTDie"的第 2位--->"A" --->對應的就是註冊碼的第11位
 0+1=1  --->對應"HACKERYouMUSTDie"的第 1位--->"H" --->對應的就是註冊碼的第12位
 A+1=B  --->對應"HACKERYouMUSTDie"的第11位--->"U" --->對應的就是註冊碼的第14位
 C+1=D  --->對應"HACKERYouMUSTDie"的第13位--->"T" --->對應的就是註冊碼的第15位

推出註冊碼前34位就是"1K3RE6789KAH3UTC789RK2R45HCCi01234"
再根據00470BF0和00470BFB行,得出最後兩位oU

:00471013 8D45F8                  lea eax, dword ptr [ebp-08]
:00471016 BA10000000              mov edx, 00000010
:0047101B E82436F9FF              call 00404644
:00471020 BE01000000              mov esi, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047103C(C)
|
:00471025 8D45F8                  lea eax, dword ptr [ebp-08]
:00471028 E8E334F9FF              call 00404510

* Possible StringData Ref from Code Obj ->"HACKERYouMUSTDie"
                                 |
:0047102D BA04114700              mov edx, 00471104
:00471032 8A12                    mov dl, byte ptr [edx]
:00471034 885430FF                mov byte ptr [eax+esi-01], dl <===暈,這個迴圈無非就是給出16個H
:00471038 46                      inc esi
:00471039 83FE11                  cmp esi, 00000011  <===共迴圈16次
:0047103C 75E7                    jne 00471025    <===從這裡向上跳構成迴圈結構
:0047103E 8D45F8                  lea eax, dword ptr [ebp-08]  <==="HHHHHHHHHHHHHHHH"
:00471041 E8CA34F9FF              call 00404510
:00471046 8A531F                  mov dl, byte ptr [ebx+1F]  <===取第32位2
:00471049 88500D                  mov byte ptr [eax+0D], dl  <===放入H串的第14位"HHHHHHHHHHHHH2HH"
:0047104C 8D45F8                  lea eax, dword ptr [ebp-08]
:0047104F E8BC34F9FF              call 00404510
:00471054 8A5320                  mov dl, byte ptr [ebx+20]  <===取第33位3
:00471057 88500E                  mov byte ptr [eax+0E], dl  <===放入H串的第15位"HHHHHHHHHHHHH23H"
:0047105A 8D45F8                  lea eax, dword ptr [ebp-08]
:0047105D E8AE34F9FF              call 00404510
:00471062 8A5321                  mov dl, byte ptr [ebx+21]  <===取第34位4
:00471065 88500F                  mov byte ptr [eax+0F], dl  <===放入H串的第16位"HHHHHHHHHHHHH234"
:00471068 8B45F8                  mov eax, dword ptr [ebp-08]  
:0047106B E87CFAFFFF              call 00470AEC  <===又是這個特殊處理的CALL,這次處理的是"HHHHHHHHHHHHH234"
:00471070 8945E8                  mov dword ptr [ebp-18], eax <===得出值3 為0  
  ******經過仔細觀察這裡的EAX的值就是後三位字元在"HACKERYouMUSTDie"中的位置減1,例如:後三位為Die,那麼這裡的EAX=DEF,如果是ACK,那麼EAX=123(也就是說EAX對應的只是"HHHHHHHHHHHHH234"的後8位)
:00471073 8955EC                  mov dword ptr [ebp-14], edx <===得出值4 為0 ,這裡EDX始終為0(對應"HHHHHHHHHHHHH234"中的前8位,因為都是H,所以EDX必定等於0)
:00471076 33DB                    xor ebx, ebx
:00471078 8B45F0                  mov eax, dword ptr [ebp-10] <===取出值1 為0,要想正確註冊碼則[ebp-10]=0x2535022E,向上看0047100D行
:0047107B 8B55F4                  mov edx, dword ptr [ebp-0C] <===取出值2 為0,[ebp-0C]就應該為0x354310AC,再向上看00471010行
:0047107E 2B45E8                  sub eax, dword ptr [ebp-18] <===由於註冊碼的第32、33、34為234,所以[ebp-18]=0,那麼EAX=0x2535022E,再向上看00471078
:00471081 1B55EC                  sbb edx, dword ptr [ebp-14] <===由於[ebp-14]始終為0,所以EDX應該為0x354310AC,向上看0047107B行
:00471084 8945F0                  mov dword ptr [ebp-10], eax <===算出的結果又放入特殊位1,則EAX應該為0x2535022E
:00471087 8955F4                  mov dword ptr [ebp-0C], edx <===算出的結果又放入特殊位2,則EDX應該為0x354310AC
:0047108A FF35D4674700            push dword ptr [004767D4]   <===內定值? 為0
:00471090 FF35D0674700            push dword ptr [004767D0]   <===內定值? 為0x31EC0A2
:00471096 6A00                    push 00000000
:00471098 6A01                    push 00000001
:0047109A FF35DC674700            push dword ptr [004767DC]   <===內定值? 為0
:004710A0 FF35D8674700            push dword ptr [004767D8]   <===內定值? 為0x12C05687
:004710A6 E8B5F8FFFF              call 00470960  <===進行處理後,得出不同的EAX和EDX值
:004710AB 8945E0                  mov dword ptr [ebp-20], eax <===得出值5  為031EC0A2   (因為是內定值,所以這裡也是固定的)
:004710AE 8955E4                  mov dword ptr [ebp-1C], edx <===得出值6  為0          (因為是內定值,所以這裡也是固定的)
:004710B1 8B45F0                  mov eax, dword ptr [ebp-10]
:004710B4 8B55F4                  mov edx, dword ptr [ebp-0C]  
:004710B7 3345E0                  xor eax, dword ptr [ebp-20]  <===[ebp-20]=0x31EC0A2(定值),推出EAX為0x2535022E,向上看00471084行
:004710BA 3355E4                  xor edx, dword ptr [ebp-1C]  <===[ebp-1C]因為是定值為0,所以EDX應該為0x354310AC,向上看471087行
:004710BD 3B15E4674700            cmp edx, dword ptr [004767E4] <===這裡也必須相等,而[004767E4]卻為0x354310AC,所以EDX也應該為0x354310AC,向上看
:004710C3 7506                    jne 004710CB
:004710C5 3B05E0674700            cmp eax, dword ptr [004767E0] <===要想成功,則這裡必須兩等(兩處都必須相等),[004767E0]為0x262BC28C,那麼EAX也應該為0x262BC28C,向上看004710B7行

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004710C3(C)
|
:004710CB 7502                    jne 004710CF <===這裡不能跳了
:004710CD B301                    mov bl, 01   <===世上最高興的事莫於經過此處

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004710CB(C)
|
:004710CF 33C0                    xor eax, eax
:004710D1 5A                      pop edx
:004710D2 59                      pop ecx
:004710D3 59                      pop ecx
:004710D4 648910                  mov dword ptr fs:[eax], edx
:004710D7 68F1104700              push 004710F1

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004710EF(U)
|
:004710DC 8D45F8                  lea eax, dword ptr [ebp-08]
:004710DF BA02000000              mov edx, 00000002
:004710E4 E8332FF9FF              call 0040401C
:004710E9 C3                      ret


:004710EA E90D29F9FF              jmp 004039FC
:004710EF EBEB                    jmp 004710DC
:004710F1 8BC3                    mov eax, ebx  <===最後一處關鍵的賦值,向上看EBX的值
:004710F3 5E                      pop esi
:004710F4 5B                      pop ebx
:004710F5 8BE5                    mov esp, ebp
:004710F7 5D                      pop ebp
:004710F8 C3                      ret


-----------所有的迷都在這裡面只是F8跟進了:-)------------------------------
:00470AEC 53                      push ebx
:00470AED 56                      push esi
:00470AEE 57                      push edi
:00470AEF 55                      push ebp
:00470AF0 83C4F8                  add esp, FFFFFFF8
:00470AF3 8BF8                    mov edi, eax
:00470AF5 BDE07B4700              mov ebp, 00477BE0
:00470AFA C7042400000000          mov dword ptr [esp], 00000000
:00470B01 C744240400000000        mov [esp+04], 00000000
:00470B09 BE10000000              mov esi, 00000010

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00470B53(C)       *****************外部迴圈*****************
|
:00470B0E BB01000000              mov ebx, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00470B4E(C)    *****************內部迴圈*****************
|
:00470B13 8A4437FF                mov al, byte ptr [edi+esi-01]  <===依次反向取2450124560136789的字元

* Possible StringData Ref from Code Obj ->"HACKERYouMUSTDie"
                                 |
:00470B17 BA6C0B4700              mov edx, 00470B6C
:00470B1C 3A441AFF                cmp al, byte ptr [edx+ebx-01]  <===依次取HACKERYouMUSTDie的字元
:00470B20 7528                    jne 00470B4A   <===如果不相等就跳出不做任何處理
:00470B22 8BC3                    mov eax, ebx
:00470B24 48                      dec eax
:00470B25 99                      cdq
:00470B26 52                      push edx
:00470B27 50                      push eax
:00470B28 B811000000              mov eax, 00000011
:00470B2D 2BC6                    sub eax, esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00470AE0(C)
|
:00470B2F 8B54C5FC                mov edx, dword ptr [ebp+8*eax-04] <===有個列表每隔8位一個數字<對應下面碼錶的高4位>
:00470B33 8B44C5F8                mov eax, dword ptr [ebp+8*eax-08] <===每隔8位一個數字<對應下面碼錶的低4位>
---------------碼錶(這是一個極有意思的碼錶)(共16行)---------------------------
00477BE0  01 00 00 00 00 00 00 00  .......        
00477BE8  10 00 00 00 00 00 00 00  .......
00477BF0  00 01 00 00 00 00 00 00  .......
00477BF8  00 10 00 00 00 00 00 00  .......
00477C00  00 00 01 00 00 00 00 00  .......
00477C08  00 00 10 00 00 00 00 00  .......
00477C10  00 00 00 01 00 00 00 00  .......
00477C18  00 00 00 10 00 00 00 00  .......
00477C20  00 00 00 00 01 00 00 00  .......
00477C28  00 00 00 00 10 00 00 00  .......
00477C30  00 00 00 00 00 01 00 00  .......
00477C38  00 00 00 00 00 10 00 00  .......
00477C40  00 00 00 00 00 00 01 00  .......
00477C48  00 00 00 00 00 00 10 00  .......
00477C50  00 00 00 00 00 00 00 01  .......
00477C58  00 00 00 00 00 00 00 10  .......
----------------------------------------------
:00470B37 E89042F9FF              call 00404DCC   <===一個小變換的CALL
:00470B3C 030424                  add eax, dword ptr [esp]
:00470B3F 13542404                adc edx, dword ptr [esp+04]
:00470B43 890424                  mov dword ptr [esp], eax
:00470B46 89542404                mov dword ptr [esp+04], edx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00470B20(C)
|
:00470B4A 43                      inc ebx
:00470B4B 83FB11                  cmp ebx, 00000011
:00470B4E 75C3                    jne 00470B13
       *****************內部迴圈結束*****************
:00470B50 4E                      dec esi
:00470B51 85F6                    test esi, esi
:00470B53 75B9                    jne 00470B0E
       *****************外部迴圈結束*****************
:00470B55 8B0424                  mov eax, dword ptr [esp]
:00470B58 8B542404                mov edx, dword ptr [esp+04]
:00470B5C 59                      pop ecx
:00470B5D 5A                      pop edx
:00470B5E 5D                      pop ebp
:00470B5F 5F                      pop edi
:00470B60 5E                      pop esi
:00470B61 5B                      pop ebx
:00470B62 C3                      ret
.......
.......

3、找到第3個註冊碼校驗點。按照上面的步驟得到1K3RE6789KAH3UTC789RK2R45HCCi01234oU看起來還真有點像,但很快你會發現,每次退出軟體後,這個註冊資訊就會被刪除。呵呵,說明還有問題,想想正確的註冊資訊總不會這樣吧。如何來找到它呢?因為是在退出時刪除,所以肯定要對登錄檔進行操作吧,所用字串參考找到"NOBODY"(每次退出時就被改成這個),有兩個地方,乾脆用trw2000在這兩個地方都設上斷點。然後退出HTMLock,很快就會斷在00471D97,上下看看,有門了:

.......
.......
--------------------------
:00471D54 53                      push ebx
:00471D55 DD05907C4700            fld qword ptr [00477C90]
:00471D5B D81DCC1D4700            fcomp dword ptr [00471DCC]
:00471D61 DFE0                    fstsw ax
:00471D63 9E                      sahf
:00471D64 7661                    jbe 00471DC7
:00471D66 E8D5FFFFFF              call 00471D40  <===這裡一個關鍵CALL,F8跟進
:00471D6B 84C0                    test al, al  <===要想正確註冊,AL必須為1
:00471D6D 7558                    jne 00471DC7 <===這裡必須跳走
:00471D6F B201                    mov dl, 01

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00471D13(C)
|
:00471D71 A180D64200              mov eax, dword ptr [0042D680]
:00471D76 E805BAFBFF              call 0042D780
:00471D7B 8BD8                    mov ebx, eax
:00471D7D BA02000080              mov edx, 80000002
:00471D82 8BC3                    mov eax, ebx
:00471D84 E897BAFBFF              call 0042D820
:00471D89 B101                    mov cl, 01

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00471D1C(C)            <===呵呵,到這裡就意味著登錄檔的資訊要被清空了。向上看
|   :00471D1C這裡一個跳轉,也應該向上看

* Possible StringData Ref from Code Obj ->"SOFTWARE\Atrise\HTMLock 1.9.3"
                                 |
:00471D8B BAD81D4700              mov edx, 00471DD8
:00471D90 8BC3                    mov eax, ebx
:00471D92 E8EDBAFBFF              call 0042D884

* Possible StringData Ref from Code Obj ->"NOBODY"
                                 |
:00471D97 B9001E4700              mov ecx, 00471E00

* Possible StringData Ref from Code Obj ->"UserName"
                                 |
:00471D9C BA101E4700              mov edx, 00471E10
:00471DA1 8BC3                    mov eax, ebx
:00471DA3 E878BCFBFF              call 0042DA20

* Possible StringData Ref from Code Obj ->"NOKEY"
                                 |
:00471DA8 B9241E4700              mov ecx, 00471E24

* Possible StringData Ref from Code Obj ->"RegKey"
                                 |
:00471DAD BA341E4700              mov edx, 00471E34
:00471DB2 8BC3                    mov eax, ebx
:00471DB4 E867BCFBFF              call 0042DA20
:00471DB9 8BC3                    mov eax, ebx
:00471DBB E830BAFBFF              call 0042D7F0
:00471DC0 8BC3                    mov eax, ebx
:00471DC2 E8E114F9FF              call 004032A8

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00471D64(C), :00471D6D(C)
|
:00471DC7 5B                      pop ebx
:00471DC8 C3                      ret


---------:00471D66 call 00471D40  <===這裡一個關鍵CALL,F8跟進----------
:00471D40 8B15787C4700            mov edx, dword ptr [00477C78]  <===這裡就是我們的註冊名newlaos
:00471D46 A17C7C4700              mov eax, dword ptr [00477C7C]  <===註冊碼1K3RE6789KAH3UTC789RK2R45HCCi01234oU
:00471D4B E8ECF3FFFF              call 0047113C   <===很明顯,F8再跟進
:00471D50 C3                      ret
-----------------------------------------------------------
:0047113C 8078062D                cmp byte ptr [eax+06], 2D  <===呵呵,註冊碼的第7位應為-,否則就認為是這個暗樁好深呀
:00471140 0F94C0                  sete al
:00471143 C3                      ret

最後,真正的註冊碼就是1K3RE6-89KAH3UTC789RK2R45HCCi01234oH(注:最後兩位也有所變化)


三、無奈的結局

原以為可以收工了,但發現生成的加密的檔案不正確,就是說更本沒有加密。還是在生成加密網頁的地方,用BPX HMEMCPY設斷點,繞過上面第2個檢測點,我又發現了第4個檢測點。這也是最讓我無奈的地方,因為如果要透過第2個檢測點,就無法透過這個檢測點。請看:
.......
.......
:00472267 B930750000              mov ecx, 00007530

* Possible StringData Ref from Code Obj ->"//Page Begin"
                                 |
:0047226C BA6C264700              mov edx, 0047266C
:00472271 8B45F0                  mov eax, dword ptr [ebp-10]
:00472274 E8BBE5FFFF              call 00470834
:00472279 84C0                    test al, al
:0047227B 754A                    jne 004722C7  <===這裡跳走,不跳走,就報告臨時檔案生成錯誤
:0047227D 8B45F4                  mov eax, dword ptr [ebp-0C]
.......
.......
:004722E6 E849E5FFFF              call 00470834
:004722EB 84C0                    test al, al
:004722ED 754A                    jne 00472339  <===這裡跳走,不跳走,就報告臨時檔案生成錯誤
:004722EF 8B45F4                  mov eax, dword ptr [ebp-0C]
.......
.......
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004722ED(C)
|
:00472339 8B45F0                  mov eax, dword ptr [ebp-10]
:0047233C 8B8014080000            mov eax, dword ptr [eax+00000814]
:00472342 8945D8                  mov dword ptr [ebp-28], eax
:00472345 8D45EC                  lea eax, dword ptr [ebp-14]
:00472348 E8AB1CF9FF              call 00403FF8
:0047234D 33DB                    xor ebx, ebx
:0047234F 8B450C                  mov eax, dword ptr [ebp+0C]  <===我們輸入的78787878(網頁檔案解鎖密碼)
:00472352 E8611FF9FF              call 004042B8
:00472357 8BF0                    mov esi, eax
:00472359 85F6                    test esi, esi
:0047235B 7E10                    jle 0047236D
.......
.......(網頁加密的程式碼段,有興趣的朋友可以研究一下)
* Possible StringData Ref from Code Obj ->"4096"
                                 |
:004725B1 BA08274700              mov edx, 00472708
:004725B6 A17C7C4700              mov eax, dword ptr [00477C7C]
:004725BB E86CE6FFFF              call 00470C2C   <===呵呵,第4個檢測點CALL,F8跟進
:004725C0 84C0                    test al, al     <===AL必須為1
:004725C2 7516                    jne 004725DA    <===這裡必須跳走  
:004725C4 8B45F4                  mov eax, dword ptr [ebp-0C]
:004725C7 E8DC0CF9FF              call 004032A8
:004725CC 8B45F0                  mov eax, dword ptr [ebp-10]
:004725CF E8D40CF9FF              call 004032A8
:004725D4 C645FB01                mov [ebp-05], 01
:004725D8 EB25                    jmp 004725FF

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004725AF(C), :004725C2(C)
|
:004725DA 8B4DD8                  mov ecx, dword ptr [ebp-28]
.......
.......
-----------004725BB call 00470C2C   <===呵呵,第4個註冊碼檢測點,F8跟進-----------------
:00470C2C 55                      push ebp
:00470C2D 8BEC                    mov ebp, esp
:00470C2F 83C4E4                  add esp, FFFFFFE4
:00470C32 53                      push ebx
:00470C33 33C9                    xor ecx, ecx
:00470C35 894DFC                  mov dword ptr [ebp-04], ecx
:00470C38 894DE4                  mov dword ptr [ebp-1C], ecx
:00470C3B 8BD8                    mov ebx, eax       <===1K3RE6-89KAH3UTC789RK2R45HCCi01234oH
:00470C3D 33C0                    xor eax, eax
:00470C3F 55                      push ebp
:00470C40 683C0E4700              push 00470E3C
:00470C45 64FF30                  push dword ptr fs:[eax]
:00470C48 648920                  mov dword ptr fs:[eax], esp
:00470C4B 8D45E4                  lea eax, dword ptr [ebp-1C]
:00470C4E 8BD3                    mov edx, ebx
:00470C50 E83B34F9FF              call 00404090
:00470C55 8D45E4                  lea eax, dword ptr [ebp-1C]
:00470C58 BA1E000000              mov edx, 0000001E
:00470C5D E8E239F9FF              call 00404644
:00470C62 E8A9FCFFFF              call 00470910
:00470C67 8D45FC                  lea eax, dword ptr [ebp-04]
:00470C6A BA10000000              mov edx, 00000010
:00470C6F E8D039F9FF              call 00404644
:00470C74 8D45FC                  lea eax, dword ptr [ebp-04]
:00470C77 E89438F9FF              call 00404510
:00470C7C 8B55E4                  mov edx, dword ptr [ebp-1C]
:00470C7F 8A5201                  mov dl, byte ptr [edx+01]   <===取註冊碼的第2位K
:00470C82 8810                    mov byte ptr [eax], dl
:00470C84 8D45FC                  lea eax, dword ptr [ebp-04]
:00470C87 E88438F9FF              call 00404510
:00470C8C 8B55E4                  mov edx, dword ptr [ebp-1C]
:00470C8F 8A5203                  mov dl, byte ptr [edx+03]   <===取註冊碼的第4位R
:00470C92 885001                  mov byte ptr [eax+01], dl
:00470C95 8D45FC                  lea eax, dword ptr [ebp-04]
:00470C98 E87338F9FF              call 00404510
:00470C9D 8B55E4                  mov edx, dword ptr [ebp-1C]
:00470CA0 8A5204                  mov dl, byte ptr [edx+04]   <===取註冊碼的第5位E
:00470CA3 885002                  mov byte ptr [eax+02], dl
:00470CA6 8D45FC                  lea eax, dword ptr [ebp-04]
:00470CA9 E86238F9FF              call 00404510
:00470CAE 8B55E4                  mov edx, dword ptr [ebp-1C]
:00470CB1 8A5209                  mov dl, byte ptr [edx+09]   <===取註冊碼的第10位K
:00470CB4 885003                  mov byte ptr [eax+03], dl
:00470CB7 8D45FC                  lea eax, dword ptr [ebp-04]
:00470CBA E85138F9FF              call 00404510
:00470CBF 8B55E4                  mov edx, dword ptr [ebp-1C]
:00470CC2 8A520A                  mov dl, byte ptr [edx+0A]   <===取註冊碼的第11位A
:00470CC5 885004                  mov byte ptr [eax+04], dl
:00470CC8 8D45FC                  lea eax, dword ptr [ebp-04]
:00470CCB E84038F9FF              call 00404510
:00470CD0 8B55E4                  mov edx, dword ptr [ebp-1C]
:00470CD3 8A520B                  mov dl, byte ptr [edx+0B]   <===取註冊碼的第12位H
:00470CD6 885005                  mov byte ptr [eax+05], dl
:00470CD9 8D45FC                  lea eax, dword ptr [ebp-04]
:00470CDC E82F38F9FF              call 00404510
:00470CE1 8B55E4                  mov edx, dword ptr [ebp-1C]
:00470CE4 8A520D                  mov dl, byte ptr [edx+0D]   <===取註冊碼的第14位U
:00470CE7 885006                  mov byte ptr [eax+06], dl
:00470CEA 8D45FC                  lea eax, dword ptr [ebp-04]
:00470CED E81E38F9FF              call 00404510
:00470CF2 8B55E4                  mov edx, dword ptr [ebp-1C]
:00470CF5 8A520E                  mov dl, byte ptr [edx+0E]   <===取註冊碼的第15位T
:00470CF8 885007                  mov byte ptr [eax+07], dl
:00470CFB 8D45FC                  lea eax, dword ptr [ebp-04]
:00470CFE E80D38F9FF              call 00404510
:00470D03 8B55E4                  mov edx, dword ptr [ebp-1C]
:00470D06 8A520F                  mov dl, byte ptr [edx+0F]   <===取註冊碼的第16位C
:00470D09 885008                  mov byte ptr [eax+08], dl
:00470D0C 8D45FC                  lea eax, dword ptr [ebp-04]
:00470D0F E8FC37F9FF              call 00404510
:00470D14 8B55E4                  mov edx, dword ptr [ebp-1C]
:00470D17 8A5213                  mov dl, byte ptr [edx+13]   <===取註冊碼的第20位R
:00470D1A 885009                  mov byte ptr [eax+09], dl
:00470D1D 8D45FC                  lea eax, dword ptr [ebp-04]
:00470D20 E8EB37F9FF              call 00404510
:00470D25 8B55E4                  mov edx, dword ptr [ebp-1C]
:00470D28 8A5214                  mov dl, byte ptr [edx+14]   <===取註冊碼的第21位K
:00470D2B 88500A                  mov byte ptr [eax+0A], dl
:00470D2E 8D45FC                  lea eax, dword ptr [ebp-04]
:00470D31 E8DA37F9FF              call 00404510
:00470D36 8B55E4                  mov edx, dword ptr [ebp-1C]
:00470D39 8A5216                  mov dl, byte ptr [edx+16]   <===取註冊碼的第23位R
:00470D3C 88500B                  mov byte ptr [eax+0B], dl
:00470D3F 8D45FC                  lea eax, dword ptr [ebp-04]
:00470D42 E8C937F9FF              call 00404510
:00470D47 8B55E4                  mov edx, dword ptr [ebp-1C]
:00470D4A 8A5219                  mov dl, byte ptr [edx+19]   <===取註冊碼的第26位H
:00470D4D 88500C                  mov byte ptr [eax+0C], dl
:00470D50 8D45FC                  lea eax, dword ptr [ebp-04]
:00470D53 E8B837F9FF              call 00404510
:00470D58 8B55E4                  mov edx, dword ptr [ebp-1C]
:00470D5B 8A521A                  mov dl, byte ptr [edx+1A]   <===取註冊碼的第27位C
:00470D5E 88500D                  mov byte ptr [eax+0D], dl
:00470D61 8D45FC                  lea eax, dword ptr [ebp-04]
:00470D64 E8A737F9FF              call 00404510
:00470D69 8B55E4                  mov edx, dword ptr [ebp-1C]
:00470D6C 8A521B                  mov dl, byte ptr [edx+1B]   <===取註冊碼的第28位C
:00470D6F 88500E                  mov byte ptr [eax+0E], dl
:00470D72 8D45FC                  lea eax, dword ptr [ebp-04]
:00470D75 E89637F9FF              call 00404510
:00470D7A 8B55E4                  mov edx, dword ptr [ebp-1C]
:00470D7D 8A521C                  mov dl, byte ptr [edx+1C]   <===取註冊碼的第29位i
:00470D80 88500F                  mov byte ptr [eax+0F], dl
:00470D83 8B45FC                  mov eax, dword ptr [ebp-04]  <===EAX=KREKAHUTCRKRHCCi
:00470D86 E861FDFFFF              call 00470AEC            <===這裡的CALL和上面是一樣的
:00470D8B 8945F0                  mov dword ptr [ebp-10], eax   <===eax=0x2535022E
:00470D8E 8955F4                  mov dword ptr [ebp-0C], edx   <===edx=0x354310AC
:00470D91 837DF400                cmp dword ptr [ebp-0C], 00000000
:00470D95 7508                    jne 00470D9F   <===這裡跳走
:00470D97 837DF000                cmp dword ptr [ebp-10], 00000000
:00470D9B 7317                    jnb 00470DB4
:00470D9D EB02                    jmp 00470DA1

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00470D95(C)
|
:00470D9F 7D13                    jge 00470DB4   <===到這裡再跳

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00470D9D(U)
|
:00470DA1 8B45F0                  mov eax, dword ptr [ebp-10]  
:00470DA4 8B55F4                  mov edx, dword ptr [ebp-0C]  
:00470DA7 F7D8                    neg eax
:00470DA9 83D200                  adc edx, 00000000
:00470DAC F7DA                    neg edx
:00470DAE 8945F0                  mov dword ptr [ebp-10], eax
:00470DB1 8955F4                  mov dword ptr [ebp-0C], edx

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00470D9B(C), :00470D9F(C)
|
:00470DB4 C745E802000000          mov [ebp-18], 00000002   <===跳到這裡
:00470DBB C745EC00000000          mov [ebp-14], 00000000
:00470DC2 B301                    mov bl, 01               <===一個關鍵的賦值

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00470E15(C), :00470E1A(C)
|
:00470DC4 FF75EC                  push [ebp-14]    <===0
:00470DC7 FF75E8                  push [ebp-18]    <===2
:00470DCA FF75EC                  push [ebp-14]    <===0
:00470DCD FF75E8                  push [ebp-18]    <===2
:00470DD0 FF75EC                  push [ebp-14]    <===0
:00470DD3 FF75E8                  push [ebp-18]    <===2
:00470DD6 8B45E8                  mov eax, dword ptr [ebp-18]  <===EAX=2
:00470DD9 8B55EC                  mov edx, dword ptr [ebp-14]  <===EDX=0
:00470DDC E8EB3FF9FF              call 00404DCC  
:00470DE1 E8E63FF9FF              call 00404DCC
:00470DE6 E8E13FF9FF              call 00404DCC  <===進行3次同樣的計算,等效於EAX的值*2*2*2=0x10
:00470DEB 3B55F4                  cmp edx, dword ptr [ebp-0C]  <===[ebp-0C]=0x354310AC (要透過第2個檢測點,則這裡只可能是這個值,不可能有其它值),EDX=0
:00470DEE 7507                    jne 00470DF7   <===這裡肯定要跳走了
:00470DF0 3B45F0                  cmp eax, dword ptr [ebp-10]  <===eax=0x2535022E(這裡可以有一些變化,但又影響不到大局)
:00470DF3 7604                    jbe 00470DF9
:00470DF5 EB27                    jmp 00470E1E   <===如果能這裡跳走自然就成功了

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00470DEE(C)
|
:00470DF7 7F25                    jg 00470E1E    <===什麼時候從這裡跳走呢?(我試了一下如果將0x354310AC改為0xF54310AC的話,就可以透過了,但要透過第2個檢測點的話,就不可能有其它值)

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00470DF3(C)
|
:00470DF9 8345E801                add dword ptr [ebp-18], 00000001
:00470DFD 8355EC00                adc dword ptr [ebp-14], 00000000
:00470E01 FF75EC                  push [ebp-14]       <===0
:00470E04 FF75E8                  push [ebp-18]       <===3
:00470E07 8B45F0                  mov eax, dword ptr [ebp-10]  <===eax=0x2535022E
:00470E0A 8B55F4                  mov edx, dword ptr [ebp-0C]  <===edx=0x354310AC
:00470E0D E85A40F9FF              call 00404E6C
:00470E12 83FA00                  cmp edx, 00000000
:00470E15 75AD                    jne 00470DC4   <===向上跳,構成一個迴圈結構
:00470E17 83F800                  cmp eax, 00000000
:00470E1A 75A8                    jne 00470DC4   <===向上跳,構成一個迴圈結構
:00470E1C 33DB                    xor ebx, ebx   <===世上最痛苦的事莫於經過此處(也就是說當EAX和EDX都為0時就OVER了)

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00470DF5(U), :00470DF7(C)
|
:00470E1E 33C0                    xor eax, eax
:00470E20 5A                      pop edx
:00470E21 59                      pop ecx
:00470E22 59                      pop ecx
:00470E23 648910                  mov dword ptr fs:[eax], edx
:00470E26 68430E4700              push 00470E43

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00470E41(U)
|
:00470E2B 8D45E4                  lea eax, dword ptr [ebp-1C]
:00470E2E E8C531F9FF              call 00403FF8
:00470E33 8D45FC                  lea eax, dword ptr [ebp-04]
:00470E36 E8BD31F9FF              call 00403FF8
:00470E3B C3                      ret


:00470E3C E9BB2BF9FF              jmp 004039FC
:00470E41 EBE8                    jmp 00470E2B
:00470E43 8BC3                    mov eax, ebx   <===EAX必須為1
:00470E45 5B                      pop ebx
:00470E46 8BE5                    mov esp, ebp
:00470E48 5D                      pop ebp
:00470E49 C3                      ret
.......
.......

已經到了最後一關,卻出現這個無奈的結局! 不知是我的水平有限,某個地方沒有分析正確,還是作者就是故意留下的陷井,自相矛盾無法註冊(當你匯去款後,再給你正式版。)

不能得到完全正確的註冊演算法,寫序號產生器也就沒有意思了。乾脆來個完美爆破版
00470C21 8A45FF      mov al, byte ptr [ebp-01] ------>改為B00190   mov al,01      nop
0047220F 7556        jne 00472267         ------>改為7456   je 00472267
004725C2 7516        jne 004725DA         ------>改為7416   je 004725DA
00471D6D 7558        jne 00471DC7         ------>改為7458   je 00471DC7


相關文章