DataFit V7.0.36註冊過程的分析 (9千字)
軟體簡介:DataFit是一個科學與工程工具,用來對資料進行繪圖、迴歸分析和統計分析。軟體已內建上百個數學模型,並可由使用者自己設定數學模型,對於初學者和專家來說,該軟體都是一個高效率的易於使用的曲線擬合和分析的工具。(本人在10多年前上大學時就對曲線擬合情有獨鍾,使用了一下該軟體,對它的曲線擬合真是印象很深,簡單說就是傻瓜也能把一組複雜的資料擬合出很好的結果――儘管有的曲線擬合得非常好,但又讓我覺得擬合的非常沒有道理)
下載地址:http://www.oakdaleengr.com/download.htm
分析工具:IDA Pro 4.15,SmartCheck 6.60
前言:要想獲得這個軟體的註冊碼相對來說,需要費一番功夫的。去年曾經用SoftICE和SmartCheck追過,追了半天追不出來,最後只好採用暴破的形式使之成為註冊版,很醜。今年經過對幾個VB程式的註冊碼的分析,信心大增,於是又開始跟這個軟體搏鬥,不過還好,終於解決了。這個軟體的註冊碼的生成確實經過該公司軟體設計人員的考慮,因此雖然最後仍然是透過STRCMP這個函式進行比較的,但由於是透過對註冊碼進行變換之後的比較,因此透過中斷STRCMP獲得字串來進行註冊肯定是不行的(即非明碼比較),只有瞭解了該軟體註冊碼的計算過程,才能夠獲得註冊碼,其中的關鍵就是註冊碼的變換過程。不過由於有IDA
Pro和SmartCheck這兩個利器,同時該軟體並沒有採取不可逆演算法,這個程式註冊碼的計算還是分析出來的。
分析過程:啟動SmartCheck,選擇開啟datafit.exe,執行後會顯示評估版(EVALUATION COPY)對話方塊,按“繼續”按鈕後進入主程式。選擇Help選單下的Enter
license命令,會彈出Enter license對話方塊,讓你輸入許可號,經過分析知道,這裡最好輸入16個字母,大小寫無關,如:ABCDEFGHIJKLMNOP(為什麼輸入這樣的字串,摸索出來的嘛,一般來說,分析註冊過程要避免輸入這種字串,但這個軟體是個例外,輸入這種字串後,可以很清楚地知道字串變換後各自的位置,這樣可以在SmartCheck中就可以清楚看出字串的變換過程,減少在IDA中透過觀察反彙編結果來分析程式的過程),輸入後軟體直接退出該對話方塊,不會顯示什麼“註冊碼不正確”之類的容易被人利用的資訊,不過沒關係。退出DataFit,軟體又會顯示評估版對話方塊,單擊“Exit
Datafit”按鈕退出。現在,SmartCheck已經把整個執行Datafit的過程忠實地記錄下來了,結合IDA分析吧。
在SmartCheck中找到Parentfrm_Unload,移動滑鼠向下不遠就是註冊碼的變換過程了。
流程:Parentfrm_Unload
:007DABF3 call sub_51E9C0
;退出是儲存設定
:007DABF8 cmp word_952108, bx
:007DABFF jz short loc_7DAC29
:007DAC01 call sub_56E5C0
;註冊碼的變換及比較過程,call見下面
:007DAC06 mov eax, dword_952104
:007DAC0B mov ecx, dword_952100
:007DAC11 push eax
:007DAC12 push ecx
:007DAC13 call ds:__vbaStrCmp
;字串比較
註冊碼的變換及比較過程
:0056E5C0 push esi
:0056E5C1 mov esi, ds:__vbaStrCopy
:0056E5C7 mov edx, offset dword_455228
;值為1ah
:0056E5CC mov ecx, offset dword_952100
:0056E5D1 call esi ; __vbaStrCopy
:0056E5D3 mov edx, offset dword_455228
:0056E5D8 mov ecx, offset dword_952104
:0056E5DD call esi ; __vbaStrCopy
:0056E5DF mov eax, dword_9520FC
:0056E5E4 push eax
:0056E5E5 call sub_94B400
;註冊碼的變換過程
:0056E5EA mov esi, ds:__vbaStrMove
:0056E5F0 mov edx, eax
:0056E5F2 mov ecx, offset dword_952104
:0056E5F7 call esi ; __vbaStrMove
:0056E5F9 push offset dword_952104
:0056E5FE call sub_5A0E90
;註冊碼的比較過程
:0056E603 mov edx, eax
:0056E605 mov ecx, offset dword_952100
:0056E60A call esi ; __vbaStrMove
:0056E60C pop esi
:0056E60D retn
註冊碼的變換過程:
:0094B463 call sub_94A600
;獲得註冊碼字串的長度並用Mid函式檢測字元
:0094B475 mov edx, [ebp+var_20]
:0094B478 push edx
:0094B479 call sub_94A810
;變換1
:0094B496 mov eax, [ebp+var_20]
:0094B499 push eax
:0094B49A call sub_94AD90
;變換2
:0094B4B2 mov edx, [ebp+var_20]
:0094B4B5 push edx
:0094B4B6 call sub_94AA70
;變換3
:0094B4C2 mov eax, [ebp+var_20]
:0094B4C5 push eax
:0094B4C6 call sub_94AF30
;變換4
:0094B4D2 mov ecx, [ebp+var_20]
:0094B4D5 push ecx
:0094B4D6 call sub_94A810
;變換5
註冊碼的變換過程:
變換1:透過Mid函式取字元,先取偶數位字元放到前面,然後奇數位字元放到後面
結果:ABCDEFGHIJKLMNOP ====> BDFHJLNPACEGIKMO
變換2:字串左邊3個放到最後,然後轉為小寫
結果:BDFHJLNPACEGIKMO ====> hjlnpacegikmobdf
變換3:用Mid函式每次取1個字元,令該字元的ASCII值-61h,如果該值大於19h,則結果為0h,否則用下表變換:
新字元:abcdefghijklmnopqrstuvwxyz 或 新字元:lesiaxkcpgnmvrzfbhjuqdoywt
原字元:eqhvbpjrdsgalkwiuncztmyfxo 原字元:abcdefghijklmnopqrstuvwxyz
結果:hjlnpacegikmobdf ====> cgmrflsakpnvzeix
變換4:用Mid函式每次取1個字元,令該字元的ASCII值-0ch,如果結果不小於61h則不變,如果小於則加上1ah
結果:cgmrflsakpnvzeix ====> quaftzgoydbjnswl
變換5:同變換1
結果:quaftzgoydbjnswl ====> ufzodjslqatgybnw
經過上面5步變換後的字串就是要比較的字串
比較過程:call 5A0E90
:005A0F9E mov [ebp+var_64], 0FFFFFFFFh
;-1
:005A0FB1 call ds:rtcRandomNext
;Rnd(-1)
:005A0FC4 mov word ptr [ebp+var_64],
0Ah ;10
:005A0FD1 call ds:rtcRandomize
;Randomize(10)
:005A0FEC mov eax, 12Ch
;300
:005A0FF1 cmp word ptr [ebp+var_2C],
ax ;是否進行了300次
:005A0FF5 jg loc_5A1126
;是則轉
:005A1009 mov esi, 1
:005A100E mov eax, 10h
;16
:005A1013 cmp si, ax
;是否進行了16次
:005A1016 jg loc_5A10F4
;是則轉而比較變換字串與新“隨機”生成的是否相同
:005A102E call ds:rtcRandomNext
;取隨機數
:005A1034 fstp [ebp+var_260]
;放到[ebp+var_260]中
:005A103A mov eax, 7Ah
:005A103F mov cx, ax
:005A1042 mov eax, 61h
:005A1047 sub cx, ax
:005A104A jo loc_5A234B
:005A1050 add cx, 1
;7ah-61h+1=1ah
:005A105A movsx edx, cx
:005A105D mov [ebp+var_288],
edx
:005A1063 fild [ebp+var_288]
:005A1069 fstp [ebp+var_28C]
:005A106F fld [ebp+var_28C]
:005A1075 fmul [ebp+var_260]
;1ah*隨機數
:005A107B movsx eax, ax
;eax=61h
:005A107E mov [ebp+var_290],
eax
:005A1084 fild [ebp+var_290]
:005A108A fstp [ebp+var_294]
:005A1090 fadd [ebp+var_294]
;61h+1ah*隨機數
:005A10A0 call ds:__vbaR8IntI2
;取整
:005A10B9 call ds:rtcBstrFromAnsi
;根據ASCII值取相應的字元,即VB的chr函式
:005A10CF lea ecx, [ebp+var_3C]
:005A10D2 call ebx ; __vbaStrMove
;放到[ebp+var_3C]
:005A10DD mov eax, 1
:005A10E2 add ax, si
;計數器加1
:005A10EB mov esi, eax
:005A10ED xor edi, edi
:005A10EF jmp loc_5A100E
;取下一個字元
:005A10F4 mov eax, [ebp+arg_0]
:005A10F7 mov ecx, [eax]
:005A10F9 push ecx
:005A10FA mov edx, [ebp+var_3C]
:005A10FD push edx
:005A10FE call ds:__vbaStrCmp
;字串比較
:005A1104 test eax, eax
:005A1106 jz short loc_5A111F
;相等則轉(註冊碼正確)
:005A1108 mov eax, 1
:005A110D add ax, word ptr [ebp+var_2C]
;計數器加1
:005A1117 mov [ebp+var_2C], eax
:005A111A jmp loc_5A0FEC
;取下一組(共300組)
上面的過程用VB表示就是:
Rnd(-1):Randomize(10)
for i=1 to 300:Rand_Code=""
for j=1 to 16:Rand_Code=Rand_Code+Chr(int(&H61+Rnd*&H1A)):next
j
if Rand_Code="ufzodjslqatgybnw" then
註冊碼正確:exit sub
endif
next i
應該注意:上面雖然是隨機生成的300個註冊碼,但由於固定了隨機種子,因此300個註冊碼也是固定的,但不知不同機器的隨機種子值是否相同,從我測試的來看,各機器間的隨機種子值是相同的,因此註冊碼應是通用的。不過有5個肯定是通用的,原因見下面:
從5A1130-5A1EE4將變換字串分別與下面5組固定字串進行比較,如果相同則註冊碼正確:
(1) acllkakiojgoymjg (2) cpnikjlaepkvccfo (3)qhkxakuwdkzuaaol (4) lvzlpckxgecgeunm
(5) mflkssoltlajgjmp
如果與上面的均不相同則生成下列字串:"areaunder"(語句5A1F10-5A2074)並返回
如果註冊碼正確則[ebp+var_44]=-1,否則=0
註冊碼的反推:
設Regcode為最終參與比較的字串(看上面,共305個),Regcode1為反推出的註冊碼
說明:註冊碼的長度為16且均是字母,這裡反推出的註冊碼為小寫的,實際輸入時大小寫無關。
步驟1:for i=1 to 8:Regcode1=Regcode1+mid(Regcode,i+8,1)+mid(Regcode,i,1)
步驟2:for i=1 to 16
if asc(mid(Regcode1,i,1)) <=&H6E then
mid(Regcode,i,1)=chr(asc(mid(Regcode1,i,1))+&HC)
else
mid(Regcode,i,1)=chr(asc(mid(Regcode1,i,1))+&HC-&H1A)
end if
步驟3:for i= to 16
mid(Regcode1,i,1)=mid("eqhvbpjrdsgalkwiuncztmyfxo",(Asc(mid(Regcode,i,1))-&H60),1)
步驟4:Regcode=Right(Regcode1,3)+Left(Regcode1,13)
步驟5:Regcode1="":for i=1 to 8:Regcode1=Regcode1+mid(Regcode,i+8,1)+mid(Regcode,i,1)
註冊器已做成,5個通用的註冊碼中的一個為:OFRETLWUYWWQMQNY,透過隨機種子生成的300個註冊碼中的一個為:CKVVZSTQYVKKJXQB,如果大家下載了這個軟體,請測試並報告一下後面的隨機生成的註冊碼是否可以註冊成功,如果成功則說明那300個隨機生成的註冊碼也是通用的。
補充說明:我分析的這個版本是V7.0.36,目前該網站提供的版本是V7.1.44,我下載回來分析了一下,註冊過程一點沒變,上面的註冊分析過程同樣適用於新的版本。
另外,登錄檔中H.L.M\Software\Oakdale Engineering\DataFit\Version\desckey值表示的是軟體第一次執行的時間,跟序列號無關,註冊成功後,會建立一個License的鍵值,即正確的註冊碼字串。
相關文章
- 原始碼分析 SpringCloud 2020.0.4 版本 EurekaClient 的註冊過程2021-12-29原始碼SpringGCCloudclient
- Spring Cloud Eureka原理分析(一):註冊過程-服務端2019-02-28SpringCloud服務端
- Android Binder原理(三)系統服務的註冊過程2019-11-19Android
- 微服務通訊之feign的註冊、發現過程2020-09-30微服務
- 電子郵件地址註冊過程詳解2023-10-17
- 一次Oracle監聽無法動態註冊處理過程排查分析2023-10-07Oracle
- 原始碼簡析XXL-JOB的註冊和執行過程2021-05-10原始碼
- oracle 12c 新增的LREG程式及其動態註冊的過程2020-01-17Oracle
- Presto 標量函式註冊和呼叫過程簡述2020-09-28REST函式
- ShadowDefender 註冊碼 分析2024-08-17
- window版Sourcetree跳過註冊的方法2018-11-30
- EmEditor 24.4.1 離線註冊分析2024-11-09
- Spring註解驅動開發第28講——為你嘔心瀝血分析建立和註冊AnnotationAwareAspectJAutoProxyCreator的過程,這應該是全網分析的最詳細的了!2020-12-17Spring
- 【Java】NIO中Channel的註冊原始碼分析2019-05-17Java原始碼
- spring通過註解註冊bean的方式+spring生命週期2021-12-02SpringBean
- SourceTree跳過註冊安裝使用2019-11-13
- Dubbo 中 Zookeeper 註冊中心原理分析2023-02-02
- 需求分析案例 - “自動註冊”功能2020-11-02
- nacos註冊中心原始碼流程分析2020-12-23原始碼
- 9.Django之登陸註冊驗證登出2018-05-21Django
- oracle的靜態註冊和動態註冊2024-11-11Oracle
- 9-7 ~ 9-27做論文全過程的反思2020-09-27
- AllenExplorer v6.8 離線註冊分析2024-12-07
- containerd 原始碼分析:啟動註冊流程2024-05-21AI原始碼
- Netty原始碼分析--Channel註冊(中)(六)2019-07-02Netty原始碼
- Netty原始碼分析--Channel註冊(上)(五)2019-07-02Netty原始碼
- @angular/router 原始碼分析之註冊路由2018-07-10Angular原始碼路由
- HDFS寫過程分析2019-04-01
- 註冊中心 Eureka 原始碼解析 —— 應用例項註冊發現(五)之過期2018-05-25原始碼
- 【SpringBoot】服務對註冊中心的註冊時機2024-05-25Spring Boot
- 全面分析全息投影的成像過程2023-04-18
- JavaScript的預編譯過程分析2019-02-16JavaScript編譯
- Glide的load()過程原始碼分析2018-09-28IDE原始碼
- 淺嘗Spring註解開發_AOP原理及完整過程分析(原始碼)2022-05-04Spring原始碼
- 千字分享|自然語言分析NLA2022-05-30
- Nacos 服務註冊與發現原理分析2022-12-08
- Nacos(一)原始碼分析Nacos註冊示例流程2020-12-26原始碼
- 動態註冊和靜態註冊2018-05-21
- 【原始碼分析】XXL-JOB的執行器的註冊流程2023-04-22原始碼