讓他變成自己的序號產生器!財智家庭理財2001加強版(v3.2)的破解 (7千字)

看雪資料發表於2001-11-05

財智家庭理財2001加強版(v3.2),個人理財的好軟體。。。
又見到老朋友了,(想當初,我第一次下手就是對付它)這次出的是加強版,功能加強了否,我不清楚,只是註冊碼判斷還是用的老方法,一點也沒加強,:-)
這個軟體沒有難度,Easy類的!用wdsm也很容易靜態分析它。(可是想當初,我可是用了整整兩天的時間去破它的,那時真的不太懂,根本沒入門,全憑毅力,當然還有興趣和想“合法”用這個軟體的慾望,才硬啃掉它的,##%%@#!多少事,都付笑談中。。。)
下面是簡單的過程:
輸入註冊碼後,Ctrl+N調出trw2000,下斷點
bpx hmemcpy
再F5回到程式,點註冊按鈕,程式被中斷
bd
pmodule
F12按7次
F10若干次。很容易看到下面的程式碼,再下面是跟進51e6df處那個call裡的程式碼
==================================================================================
016F:0051E6DC  MOV      EAX,[EBP-04]
016F:0051E6DF  CALL    0051DF34 ....>>>>關鍵的Call
016F:0051E6E4  TEST    AL,AL  ....>>>>判斷標誌
016F:0051E6E6  JZ      0051E737 ....>>>>跳則OVER!
016F:0051E6E8  MOV      EAX,[0064FF98]
016F:0051E6ED  MOV      EAX,[EAX]
016F:0051E6EF  MOV      EDX,[EBP-04] ....>>>>這裡把你輸入的註冊碼
016F:0051E6F2  CALL    004BDDD0   ....>>>>存入登錄檔裡
====================================================================================
016F:0051DF6A 8B45F8          MOV      EAX,[EBP-08] ....>>>> d eax,可以看到正確的註冊碼
016F:0051DF6D E8FAFCFFFF      CALL    0051DC6C
016F:0051DF72 8BD8            MOV      EBX,EAX   .....>>>>計算後得到一個值,存在ebx中
016F:0051DF74 8B45FC          MOV      EAX,[EBP-04] ....>>>> d eax,可以看到你輸入的錯誤的註冊碼
016F:0051DF77 E8F0FCFFFF      CALL    0051DC6C
016F:0051DF7C 85C0            TEST    EAX,EAX  ....>>>>錯誤的註冊碼得到eax=0,不跳
016F:0051DF7E 7504            JNZ      0051DF84
016F:0051DF80 33DB            XOR      EBX,EBX  ...>>>>ebx清零,玩完
016F:0051DF82 EB0A            JMP      SHORT 0051DF8E
016F:0051DF84 3BC3            CMP      EAX,EBX   ....>>>>兩次計算結果相同嗎?
016F:0051DF86 7504            JNZ      0051DF8C  ....>>>>不同,說明註冊碼錯誤,跳到玩完
016F:0051DF88 B301            MOV      BL,01    ...>>>>哦,是正確的註冊碼呀
016F:0051DF8A EB02            JMP      SHORT 0051DF8E ....>>>>跳到後面,避開ebx清零的這一句
016F:0051DF8C 33DB            XOR      EBX,EBX
016F:0051DF8E 33C0            XOR      EAX,EAX  ....>>>>公共的結束部分
016F:0051DF90 5A              POP      EDX
016F:0051DF91 59              POP      ECX
016F:0051DF92 59              POP      ECX
016F:0051DF93 648910          MOV      [FS:EAX],EDX
016F:0051DF96 68B0DF5100      PUSH    DWORD 0051DFB0
016F:0051DF9B 8D45F4          LEA      EAX,[EBP-0C]
016F:0051DF9E BA03000000      MOV      EDX,03
016F:0051DFA3 E83860EEFF      CALL    00403FE0
016F:0051DFA8 C3              RET   
=======================
改就很好改了,把51df74那行改成mov eax,[ebp-08]就得了。用程式自己算出的註冊碼放進去計算,這兩次計算結果一定相同的,呵呵呵。。。
  這不是我今天想要重點說明的。這樣改跟暴破沒什麼兩樣,9個月前我就是這樣了,難道現在還這樣?他不改變註冊判斷的方法,難道我也跟他一樣,不改破它的方法???
  現在讓我完成我以前沒實現的願望,讓他(程式自己)變成自己的序號產生器吧!
  其實從DF6A到DF8C這一段空間,都是程式自己想要做而我們不一定想要他做的事,把這一段空間裡的程式碼改了,改成我們希望他做的事,不就得了???
  從失敗講起,希望大家有耐心看下去。
  我們想到上面的改法,是用程式自己算出的註冊碼放進去計算來欺騙這個判斷功能塊,可“註冊成功”後程式會在登錄檔裡寫入你的註冊資訊,這裡放入的是你輸入的錯誤註冊碼!!!有什麼辦法能讓他放入正確的註冊碼嗎?一是修改指標,讓他去找註冊碼的時候找到的不是我們輸入的錯誤註冊碼,而是程式自己算出的註冊碼。二是修改字串,把正確的註冊碼存入錯誤註冊碼在記憶體中的儲存空間裡。
  第一種簡單一些。可是分析後知道是不成功的。失敗!!!
  原因如下:
  在DF6A前一句中正確註冊碼的存放地址的指標才出來,到DFA3這個Call後又被沖掉了,也就是說,等你判斷完成後就找不到指向正確註冊碼的存放地址的指標了!
  如果我們把51E6EF處的指標(也就是ebp-08裡的內容)在前一個CALL裡面就改成指向正確註冊碼的存放地址的指標行不行呢?也不行。為什麼不行?實踐嘛。改了會出錯的。另外,要注意,在CALL裡面的EBP值和在外面的不一樣,改的時候要計算清楚。到底改的是哪的。改的時候多看看EBP前16個位元組以後的內容是怎麼變化的。
  那就考慮第二種方法吧。經實踐,改成了以下的內容:
==================================
016F:0051DF6A 8B45F8          MOV      EAX,[EBP-08]
016F:0051DF6D E8FAFCFFFF      CALL    0051DC6C
016F:0051DF72 8BD8            MOV      EBX,EAX      ....>>>>前三行不想去動它,為什麼?儘量保持程式在這個CALL的返回時的各個值,所以讓他得到ebx的值。
016F:0051DF74 8B55FC          MOV      EDX,[EBP-04] ....>>>>把你要寫入的地址找到
016F:0051DF77 85D2            TEST    EDX,EDX  ....>>>>如果是0就別寫,硬要往裡寫會出錯的
016F:0051DF79 7411            JZ      0051DF8C ....>>>>不寫就跳走
016F:0051DF7B 8B45F8          MOV      EAX,[EBP-08] ....>>>>把存放正確的註冊碼的地址找到
016F:0051DF7E 8A0401          MOV      AL,[ECX+EAX] ....>>>>把第'ecx+1'個字元取出,放入AL中
016F:0051DF81 880411          MOV      [ECX+EDX],AL ....>>>>再把它存進要寫入的地址中
016F:0051DF84 41              INC      ECX   ....>>>>ecx加1,為什麼前面不加初始化ecx的指令呢?因為經過51DF6D處的CALL後,ECX的值就已經是0了,不用自己去初始化,這就是不動前三行的好處了。。。
016F:0051DF85 80F90A          CMP      CL,0A  ....>>>>9個字元+1個“字串結束標誌”(也就是00,TC裡的'\0'了),共10位,所以。。。
016F:0051DF88 75F1            JNZ      0051DF7B ....>>>>沒傳完?繼續
016F:0051DF8A EB02            JMP      SHORT 0051DF8E ....>>>>跳到公共的結束部分
016F:0051DF8C 31DB            XOR      EBX,EBX  ....>>>>出錯時的處理,也就是ebx清清零而已
016F:0051DF8E 33C0            XOR      EAX,EAX  ....>>>>這就是公共的結束部分
016F:0051DF90 5A              POP      EDX
016F:0051DF91 59              POP      ECX    ....>>>> ********
016F:0051DF92 59              POP      ECX
016F:0051DF93 648910          MOV      [FS:EAX],EDX
016F:0051DF96 68B0DF5100      PUSH    DWORD 0051DFB0
016F:0051DF9B 8D45F4          LEA      EAX,[EBP-0C]
016F:0051DF9E BA03000000      MOV      EDX,03
016F:0051DFA3 E83860EEFF      CALL    00403FE0
016F:0051DFA8 C3              RET
======================================
細心一點的朋友會發現,ECX在累加後並我並沒有恢復他的初值,原因:1。我沒地方能放下xor ecx,ecx或mov cl,0這樣的語句了;2。注意到上面的標著********的那行嗎?程式會從堆疊中取出ECX的值,而你在累加後的ECX的值會被沖掉。不需要你去恢復他的初值。
再細心一點的朋友會發現,我修改的比原來的程式少了一條mov bl,01這條語句。但根據我觀察,沒這條語句也沒什麼大不了,只是程式的這個CALL的返回時的EBX的值比原來的程式中的小1而已。好像沒什麼關係。其實我也是沒地方放這條語句了。就差兩個位元組!如果上天再給我一次機會的話,我會說,我想要。如果非要給我的要的位元組數加上一個限制的話,我希望是:Only TWO!
  如果還可以放兩個位元組的話,就在51DF8A處放入mov bl,01,後面的順沿兩個位元組。這樣就可以和原來的程式的這個CALL的返回時的各個值一模一樣了。。。不過沒關係,修改後的程式只是在第一次註冊完後退出的時候有機會發生點小錯誤。不一定會發生哦。在某種特定的條件下可能會發生,比如輸入的註冊碼長度不夠時就有可能會出錯。但僅限第一次,以後就再不出錯了。。。我也不知道為什麼,但重申一次:只在第一次時,在特定條件下有可能出錯!以後就絕不出錯了!!所以。。。不要緊,呵呵呵。。。
  在你隨便註冊成功後,程式會把正確的註冊碼存入登錄檔裡。其實這時候,你就可以用原來的程式而不用修改後的程式了,如果你怕修改後的程式有什麼不清楚的後遺症的話。。。其實我覺得是沒有後遺症的。但你可以只把修改後的程式當個序號產生器用!呵呵呵,本來我就是想讓他變成自己的序號產生器,不過光是作為序號產生器的話,有點太大了的感覺,3M呀!媽媽咪。。。
  好了,大功告成,打個Kiss!
                                    hsf0214於2001-11-05 AM11:21:10

相關文章