轉載地址:http://blog.csdn.net/qs_hud/article/details/8884867算法
註冊機及軟件下載地址:http://download.csdn.net/detail/huhu1544/5330869 數組
效果截圖:函數
上幾周灰春哥說在試着破解Source Insight 3.5,一直拿CrackMe作實驗的俺也難免手癢來練練手(順便拿去吾愛混個邀請碼),剛拖進OD裏就看見了GetTickCount函數,還覺得裏面 有反調試呢(如今想一想估計是檢查試用天數用的),當時反反調試還沒怎麼修煉,就擱置了幾天,後來看了幾天脫殼經常使用的反調試手段就開始動手了,廢話不說了, 看分析吧。優化
首先運行查看錯誤提示:spa
用OD的字符串搜索來查一下「You typed」:.net
很明顯,雙擊查看代碼,向上翻找到關鍵Call(00408BD9):指針
進去這個Call裏瞅一下:調試
先看00448f3a處的第一個Call 00448e53(事實證實這裏極可能是一個大坑呀!!!,被坑了N個小時纔出去),直接上IDA看流程圖,比較明瞭(我已經加上了註釋):blog
到底跳到哪個呢?原本想eax最終應該返回1的,大體看了幾眼sub_449030的內容,跟真的似的,就讓sub_448e53返回1進入 sub_449030跟蹤看看,怎麼讓sub_448e53函數返回1呢?看代碼:字符串
還要繼續看sub_1602,沒辦法,繼續看sub_1602吧(雖然這裏是個坑,可是這個函數後面用到的多,能夠看一下代碼):
這段代碼很簡單,ES3US是參數,輸入的前五個字符和ES3US的大寫相同的話就返回EAX=1,就輸入前五個是ES3US的假碼進入上面提到的 sub_449030看看(最初是在OD裏看的,花費了不少時間才意識到多是進坑了,只截取部分代碼大體看看就好了):
執行完sub_448e7e以後返回值應該爲0才能繼續下面的驗證,可是最後剩餘的其它函數執行完畢後返回1才註冊成功,這個sub_448e7e函數內容裏是對輸入的字符串的各類驗證,符合驗證的返回值纔是1,與這個函數要求的返回值0矛盾呀,也就是說能夠說若是輸入任何不知足sub_448e7e函數裏面驗證的假驗證碼均可以返回0,繼續下面的剩下的幾個函數的驗證,還有好多呢,要經過後面的驗證用隨意構造的假碼就難了,因此估計這整個函數就是個坑(隨意構造的註冊碼能經過sub_448e7e,返回0,可是後面的驗證估計過不去了,若是有不一樣看法,歡迎討論交流哈),這條路估計行不通了,因此繼續回去看第一幅圖中的函數:
既然不能走sub_449030這條道,那就看00448f5c處的sub_448f5c吧,其實這個函數和sub_449030函數的驗證差很少,可是關鍵之處不同呀,進去看看:
是否是有點熟悉呢,就是判斷前五位的大寫是否是SI3US而已,輸入前五位是SI3US的假碼的話就讓其跳轉到Loc_448f89:
又是函數sub_448e7e,上面的提到的坑裏的驗證函數,不過此次是符合函數裏的各類驗證才能返回1才能繼續下面的驗證,進去看看裏面的驗證吧(仍是用IDA的流程圖看吧,OD的圖太長了很差截):
首先要存在」-」字符才能繼續,OD直接修改本身的假碼這一位爲」-」就好了,不過仍是推薦重來一次,畢竟後面的路還很長,很麻煩額(⊙o⊙)…,繼續:
判斷剛纔的尋找的」-」位置是否是和SI3US挨着(PS:真折騰,直接調用返回具體位置的函數就好了唄,還非要strchr()再減去基址,莫非是編譯器優化了???不肯定額)才行,繼續:
又是這玩意,,截取」-」字符第二次出現的位置,判斷中間那段註冊碼長度是否是6,中間用了and XX 0指令把」-」字符第二次出現的位置置爲0,至關於把字符截斷了(最後又補回去了),就只剩餘中間的那一段部分(最前面的SI3US已經用指針偏移處理掉了,這裏只剩下中間的6位註冊碼),輸入相似SI3US-XXXXXX-XXX的註冊碼再繼續看:
具體拷貝的啥不記得了,忘記註釋了,如今就不記得了,就記得strlen是求的最後的註冊碼長度,看長度是否是5,到此註冊碼的格式就明瞭了,就是SI3US-XXXXXX-XXXXX類型,繼續看呀,真折騰:
後五位註冊碼轉化成整型值(存進了eax,最終保存進了arg_8的空間裏),因爲atoi函數處理字符串時存在非數字型的字符就中止轉化了,第一個字符不是數字返回0,爲了保險,仍是把後五位字符串全輸入成數字型的,讓它所有轉化成數字,」12345」就轉化成12345,看它還有神馬招數,終於返回1了,別急,後面還有驗證呢,畢竟還沒驗證中間及最後的註冊碼正確性呀,執行到函數結束,繼續Go:
執行到紅框處又跳到00449075,接着執行sub_428e8a,跟進去:
這段代碼其實沒啥用,挺無語的,就是驗證中間的六位註冊碼第一位是否是和後五位相等,注意紅線處的代碼挺有意思的,不少編譯器在優化選擇語句時,尤爲是類 似a>b?b:c的語句時常常用到相似的代碼(有興趣的能夠看看《C++反彙編與逆向揭祕》,裏面不少講了不少編譯器優化的規則)再繼續說這段代碼 的含義呀,猜想是否是一個小坑,預防像我這種懶人輸入中間6位相同的假註冊碼,過小瞧人了,騙人也來一個稍微高級點的,6位全相等能騙得了我輸入的假碼中 間6位是」123456」的嗎?
(下面緊接着的一個還真是稍微高級點的坑,個人」123456」還真被坑了╮(╯_╰)╭)
繼續看,不閒扯了,上面返回eax爲1以後跳轉到了448fc1:
看00408fea處有1E=30次比較,比較啥呢?53c468處向上30個4字節數據,實際上是將註冊碼中間6位由atoi轉成的整型值與30個值依次比較,有相等的話就調走返 回0,最後致使驗證失敗,在OD裏看53c468處的數據只能看到些16進制數值,使用IDA的計算器能夠計算出這些十進制數,其中第二次與輸入的中間6 位註冊碼比較的就是我輸入的」123456」的整型值……中招了,真是猥瑣的驗證,(不過不要緊,把標誌位改一下不讓它跳走就得了,可是最後寫算法註冊機 時就要注意了,萬一輩子成的註冊碼裏真的落在了這30個數之中或是6位全相同的就註冊不成了)進行30次比較以後,跳進了紅框中最後一個驗證的函數,最後一 把了,返回值爲1就OK了,跟進去:
(截圖美化排版啥的俺真心不擅長,湊合看吧。)
別看代碼有點亂,實際上驗證的算法好水的,寫成的僞代碼的除去變量定義就剩下幾行計算的代碼,拿我輸入的SI3US-123456-54321來講吧,令K=123456(數值),再將」123456」(字符查)與存放的幾個常量(代碼中的Temp數組,有10個,只用到6個)異或下,結果和K*4相加的結果再存進K裏,進行6次而已,(好水,算法簡單不說,邏輯清楚點也行呀,一共就六次循環,004f3ed3處的循環變量還考慮超過10時從新賦值成0,瞎搞!)。
算法明瞭了,編寫註冊機吧,看代碼:
隨便寫的,生成6位隨機數,計算出後5位(有時候求後面幾位時結果可能不是五位,不能用,就重來直到結果是5位的),最後Si3US、中間的6位,結果的 5位拼接就完了,固然還有不少小問題,好比隨機數生成的沒有很大的數,通常沒有超過130000,這樣也好,結果就很難在那30個比較的數和全相等的數範 圍內了,功能差很少就好了,註冊機寫完恰好12點鐘,原本打算把破文寫完就睡呢,結果,呵呵……
O(∩_∩)O。