破解Ghost多媒體視訊點播系統全過程 (9千字)

看雪資料發表於2002-07-29

文章題目:破解Ghost多媒體視訊點播系統全過程
攢寫:仙劍太郎
網頁:http://cnokweb.yeah.net
宣告:若需轉載本文,請保持文章的原整性。商業用途請聯絡仙劍太郎(dqjun@21cn.com)。


今天收到一位網友的QQ訊息,要我破解Ghost多媒體視訊點播系統V1.0,還說這個2M多的程式(包括執行庫和控制元件)的註冊費竟索要2000大洋!!!我暈~~立即down下來看個究竟,安裝後一看,我倒!!!什麼點播系統嘛,其實就是個HTTP伺服器,再搞點HTML自動生成罷了,剛學程式設計的也能做出這樣的東東!竟然要我們給他¥2000註冊費,真是太過份了!不行,一定要搞定它,好出出氣!(我也很體量作者的辛苦成果,不過¥2000的鉅額註冊費實在有點讓人費解,這其實只是個幾百K的軟體嘛,我以前做的軟體一個也不要錢的!)
好了,廢話不說太多,下面開始啦!

準備工具:SmartCheck 6.03 、  Ghost多媒體視訊點播系統(下載地址:http://download.tzinfo.net/it/2002418185913b.exe )2,867KB (安裝完後它會提示重啟,但可以不重啟直接執行)

開工±戲椒ǎ紫扔FileInfo檢視一下GhostVOD.exe的殼和編譯器的相關資訊,唔,很好,沒有加殼,用VB6寫的,這裡大夥兒肯定想到了除錯VB的老大哥SmartCheck了吧!因為VB是解釋執行的語言,用普通反彙編和動態除錯的方法難以應付複雜演算法的VB程式,不說了,這些東西不是主要的,我們先要設定好SmartCheck,照看雪教程的那篇關於SmartCheck的文章設定,然後我們開啟Ghost多媒體視訊點播系統的主程式GhostVOD.exe,然後點選start或按F5開始載入程式,稍等片刻,主介面彈出了,點選“幫助”->“註冊”,然後隨便輸入使用者ID和序列號,例如ID為 cnokweb.yeah.net 序列號為 78787878 。接著點選“確定”,提示說“序列號非法!”,理解一下這句話,會不會序列號有一定格式順序的呢?帶著這個疑問,我們回到SmartCheck介面,下拉滾動條,展開_Click,我們再展開下一層的_Click,可以看到:

  _Click
    Trim
    Mid$
    Mid$
    MsgBox

其中第一個Mid$的內容為:
  String  str = 004B0D4C
        = "78787878"
  Long  start = 10 0x0000000A
  length (variant)
      Integer  .iVal = 1 0x0001
表示從字串“78787878”中取第10位起的一個字元。
第二個Mid$內容為:
  String  str = 004AC5E8
        = "78787878"
  Long  start = 5 0x00000005
  length (variant)
      Integer  .iVal = 1 0x0001
表示從字元
表示從字串“78787878”中取第5位起的一個字元。

看到這裡我們要想想為什麼要取5位和10的那個字元呢?接下來我們要解開迷底了,先把游標停在MsgBox裡,然後我們點選SmartCheck的“View”->“Show All Events”顯示所有事件。稍等片刻,這時多了很多資訊,我們從MsgBox向上看,來到下面時,你在右邊視窗看到了什麼?

        Mid$
        __vbaStrMove returns DWORD:4B427C

        __vbaStrCmp returns DWORD:FFFFFFFF  //就是這裡
        Mid$
        __vbaStrMove returns DWORD:4976D4

        __vbaStrCmp returns DWORD:1        //還有這裡
        __vbaFreeStrList returns DWORD:1C
        __vbaFreeObjList

        __vbaVarDup returns DWORD:6BE990
        MsgBox


我們點選上面的__vbaStrCmp returns DWORD:FFFFFFFF和__vbaStrCmp returns DWORD:1,我們可以在右邊看到類似這樣的資訊:
  unsigned short * string1 = 0040BF8C
        = "-"
  unsigned short * string2 = 004976D4
        = "7"

這下明白了嗎,原來前面所說的第5和10個字元原來是判別是否是“-”的,明白了這點,我們來研究一下序列號的排列順序:
程式判斷第5位為“-”,第10位為“-”那麼中間必然是“xxxx-xxxx-”,不過看起來好象不怎麼順眼,因為一般來說註冊碼都不會以“-”結尾,到這裡我們可以想到後面應該還有一串數字,會不會和前面兩個一樣是四位的呢?即“xxxx-xxxx-xxxx”呢?我們隨便編造一個可以試一試,使用者ID依然是填cnokweb.yeah.net 序列號改填: abcd-0123-4567 ,點確定,提示“序列號非法”。看到這裡我們想到了什麼?序列號格式依然不對耶,回到SmartCheck,我們看到了和上面不同的情況:
            _Click
                Trim
                Mid$
                Mid$
                OnError
                Len returns LONG:14  //多了這一句
                MsgBox returns Integer:1

點選上面多了的那一句,看看右邊視窗出現什麼?出現了我們剛才輸入的序列號!那一句的意思為計算我們輸入序列號的字元數。發現問題了吧,原來是要檢測序列號長度的。我們要猜想一下究竟多少個字元才附合序列號格式,我們先在序列號後多加一位數,變為“xxxx-xxxx-xxxxx”。我們再試一試,在序列號裡填入abcd-0123-45678 ,點選確定,提示說“使用者ID與序列號非法!”,咦,這次怎麼不同了!Yeah!我們之前猜的序列號格式對了,現在只是ID與序列號不匹配,也就是進入比較階段了,註冊碼離我們不遠了。。。。
OK,現在回到SmartCheck裡,和上面一樣展開_Click,這次我們看到的資訊比之前多了吧,下面一句句解釋,讓我們完全瞭解作者的註冊碼演算法:

            _Click
                Trim
                Mid$                      //判斷第10位是否為“-”
                Mid$                      //判斷第5位是否為“-”
                OnError
                Len returns LONG:15        //計算輸入序列號長度,這裡返回值為15

                Right                      //取序列號最後5位
                Sqr returns double:213.724 (displayed as single-precision floating point)
                                          //上面一句是將最後5位轉換成雙精度浮點型資料
                Double (1.82461e+007) --> Long (18246056) //將雙精度型+7後轉為長整型
                Long (18246056) --> String ("18246056")  //再轉成字串,這時我們得到了一個字串“18246056”,這和註冊碼有什麼關係呢?繼續看下去。
                Len returns LONG:8                  //計算“18246056”長度為8
                Len returns LONG:8                  //同上

                Long (8) --> Integer (8)            //將上面的長度8轉為整數
                Mid$                                //取“18246056”第8位的1個字元,即取6
                String ("6") --> Integer (6)

                Mid$                                //取“18246056”第7位的1個字元,即取5     
                String ("5") --> Integer (5)
                Mid$                                //取“18246056”第6位的1個字元,即取0

                String ("0") --> Integer (0)
                Mid$                                //....同上類推....
                String ("6") --> Integer (6)

                Mid$                                //....同上類推....
                String ("4") --> Integer (4)
                Mid$                                //....同上類推....

                String ("2") --> Integer (2)        //....同上類推....
                Mid$
                String ("8") --> Integer (8)

                Mid$                                //...同上類推...直到最後一位“1”
                String ("1") --> Integer (1)
                Integer (5) --> String ("5")        //為什麼有“5”呢?

看懂上面的序列號計算過程了嗎?其實演算法非常的簡單,不過有一點不知大家有沒有留意,一般軟體計算註冊碼都是能過使用者名稱計算註冊碼,然後和你輸入的註冊碼比較,相等則註冊碼成功。不過現在從上面看來,它並沒有用到我們輸入的使用者ID:cnokweb.yeah.net ,哈哈,好奇怪吧。其實這和普通註冊碼演算法差不多,只是它倒過來罷了,這裡是先通過運算使用者輸入的序列號,然後與使用者輸入的ID作比較。現在想明白了嗎,這就是說,上面那段字串“18246056”有可能是通過我們編造出來的“假”序列號運算出來的使用者ID!不過先別開心,我們還沒完全找到註冊碼(其實是使用者ID),不信你把它用作使用者ID註冊,也會告訴你非法。現在要深入想一想了,上面為什麼會出現一個“5”呢?為了詳細瞭解,我們點選SmartCheck的“View”->“Show All Events”顯示所有事件。稍等片刻,我們由MsgBox向上,來到如下地方:

                Integer (5) --> String ("5")            //神祕的“5”
                __vbaStrMove returns DWORD:4B427C

                __vbaStrCat returns DWORD:4976D4      //關鍵!
                __vbaStrMove returns DWORD:4976D4
                __vbaStrCopy returns DWORD:4AC5C0

                      ...........省略............

                MultiByteToWideChar returns INT:17
                SysAllocStringLen returns LPVOID:4CB10C
                MultiByteToWideChar returns INT:17

                HeapFree returns BOOL:1
                __vbaStrCmp returns DWORD:FFFFFFFF  //使用者ID的比較就在這兒!
                __vbaFreeStr returns DWORD:30

                __vbaFreeObj
                __vbaVarDup returns DWORD:6BE990
                MsgBox

上面出現神祕的“5”之後,出現一系列字串的操作,這裡應該內有乾坤了。我們來到__vbaStrCat returns DWORD:4976D4  時,右邊視窗出現如下:

    unsigned short * string1 = 004B427C
          = "5"
    unsigned short * string2 = 004B0D4C
          = "18246056"

意思是說,把“5”與“18246056”連線起來,再到下一行__vbaStrCopy returns DWORD:4AC5C0 就可以看到連線後變成的字串:“182460565”,繼續往下看,我們到了__vbaStrCmp returns DWORD:FFFFFFFF 關鍵比較的地方,在右邊視窗我們也看到它和我們之前輸入的使用者ID:cnokweb.yeah.net進行比較:

    unsigned short * string1 = 004CB10C
          = "cnokweb.yeah.net"
    unsigned short * string2 = 004AC5C0
          = "182460565"

到這裡,我們終於弄出序列了,序列號就是我們前面所編造的15位數: abcd-0123-45678  使用者ID就是上面那串數字:182460565  好了,終於搞定了!可以喝杯茶,坐下來,體息一下了~~

雖然上面轉了很多彎,而且有些是靠猜的,做Cracker就要有這樣的不怕錯誤精神,錯了至多再來一次!現在要坐下來總結一下了,這個程式應該說是比較新鮮型別的倒轉比較型,其實最終還是一樣的。程式的演算法也很簡單,流程用VB程式碼表示大致如下:
text1.text為使用者ID,text2.text為序列號:

if mid(text2.text,10,1)="-" and mid(text2.text,5,1)="-" then
  if len(text2.text)=15 then
      sn=right(text2.text,5)
      **轉換sn為雙精度+7,最後轉為string
      num=len(sn)
      **中間一連串的字元轉移過程(好象沒什麼用)
      x=cstr(5)  神祕的5,也許是其它,如6
      **把sn與5或6等連線起來,形成使用者ID
      if sn=text1.text then
          msgbox "註冊成功!"
      else
          msgbox "使用者ID與序列號非法!"
    else
      msgbox "序列號非法!"
    end if
    msgbox "序列號非法!"
end if
     
總的來說,我們自己編造的序列號前10位除了“-”外,其餘可以是任意英文或數字,最後5位才與使用者ID有直接關係。另外,那神祕的5我現在也搞不懂是怎麼冒出來的,有時不是5而是6等等,哪位能回答這個疑問?
本人尚是菜鳥,能力有限,文章難免有錯漏之處,懇請高手提點!

相關文章