【原創】菜鳥也演算法分析 -- 區域網檢視工具(LanSee V1.52
菜鳥也演算法分析 -- 區域網檢視工具(LanSee V1.52)註冊演算法分析
軟體說明:
區域網檢視工具(LanSee)是一款主要用於對區域網(Internet上也適用)上的各種資訊進行檢視的工具。採用多執行緒技術,搜尋速度很快。它將區域網上比較實用的功能完美地融合在一起,比如搜尋計算機(包括計算機名,IP地址,MAC地址,所在工作組,使用者),搜尋共享資源,搜尋共享檔案,多執行緒複製檔案(支援斷點傳輸),發短訊息,高速埠掃描,捕獲指定計算機上的資料包,檢視本地計算機上活動的埠,遠端重啟/關閉計算機等,功能十分強大。該軟體是一款綠色軟體,解壓後直接開啟執行,無需安裝。
軟體資訊:
未加殼,用Delphi編譯器編寫。
平臺:Windows XP SP1
工具:W32Dasm 8.93,OLLYDBG1.10
分析說明:
僅僅分析演算法,進行技術交流,不做商業用途。如果你條件允許並喜歡這個軟體的話,請支援正版。
Cracker: prince
E-mail : Cracker_prince@163.com
V1.52版下載地址:http://www.yqdown.com/soft/7854.htm
W32Dasm載入反彙編,根據提示資訊很容易找到爆破點。根據提示來到這裡(然後用OD下斷00492307,F9執行除錯,輸入使用者名稱prince,註冊碼:987654321012):
................................................
:00492307 55 push ebp
:00492308 68FD234900 push 004923FD
:0049230D 64FF30 push dword ptr fs:[eax]
:00492310 648920 mov dword ptr fs:[eax], esp
:00492313 8D55FC lea edx, dword ptr [ebp-04]
:00492316 8B83FC020000 mov eax, dword ptr [ebx+000002FC]
:0049231C E83B14FBFF call 0044375C <--- 獲得使用者輸入的註冊碼個數
:00492321 8B45FC mov eax, dword ptr [ebp-04] <--- [ebp-04]中是使用者輸入的註冊碼
:00492324 E82FFFFFFF call 00492258 <--- 像這種下面比較完就跳的CALL最可疑,跟進
:00492329 84C0 test al, al
:0049232B 0F84A7000000 je 004923D8 <--- 這裡跳到錯誤提示(爆破點之一)
:00492331 8D55F8 lea edx, dword ptr [ebp-08]
:00492334 8B830C030000 mov eax, dword ptr [ebx+0000030C]
:0049233A E81D14FBFF call 0044375C <--- 得到使用者名稱的長度
:0049233F 8B45F8 mov eax, dword ptr [ebp-08]
:00492342 E8CDFDFFFF call 00492114 <--- 關鍵CALL,跟進
:00492347 84C0 test al, al
:00492349 0F8489000000 je 004923D8 <--- 這裡跳到錯誤提示(爆破點之一)
:0049234F B201 mov dl, 01
:00492351 A1AC014700 mov eax, dword ptr [004701AC]
...................................................................
根據省力不蠻幹的原則,前幾遍跟蹤都是粗跟,不是十分可疑的CALL都F8帶過,但是要注意CALL過之後暫存器的變化,尤其是EAX暫存器的值,必要時把值註釋在旁邊。這個軟體檢測註冊的地方互動呼叫很多,如果上來就都F7跟進的話,呵呵,很快你就會暈了。繼續分析上面的程式碼,在0049231C這個CALL時,F8帶過,看EAX暫存器,變成了多少?0XC,嘿嘿,0XC不就是十進位制的12嗎?我們“恰好”也輸入了12個字元作為註冊碼,明白了吧?這個CALL就是用來計算使用者輸入的註冊碼個數的。執行完下面那一句,EAX中就是我們輸入的假碼了。再往下又是一個CALL,而且下面比較完會跳到出錯的地方,足夠可疑!跟進!來到這裡:
...................................................................
:00492258 55 push ebp
:00492259 8BEC mov ebp, esp
:0049225B 83C4F8 add esp, FFFFFFF8
:0049225E 53 push ebx
:0049225F 33D2 xor edx, edx
:00492261 8955F8 mov dword ptr [ebp-08], edx
:00492264 8945FC mov dword ptr [ebp-04], eax
:00492267 8B45FC mov eax, dword ptr [ebp-04]
:0049226A E85527F7FF call 004049C4 <--- 這個CALL是幹什麼的?不管它,先F8帶過
:0049226F 33C0 xor eax, eax
:00492271 55 push ebp
:00492272 68E1224900 push 004922E1
:00492277 64FF30 push dword ptr fs:[eax]
:0049227A 648920 mov dword ptr fs:[eax], esp
:0049227D 33DB xor ebx, ebx
:0049227F 8D55F8 lea edx, dword ptr [ebp-08]
:00492282 8B45FC mov eax, dword ptr [ebp-04]
:00492285 E84E68F7FF call 00408AD8 <--- 未知,先帶過
:0049228A 8B45F8 mov eax, dword ptr [ebp-08]
:0049228D E84A25F7FF call 004047DC <--- 未知,同樣帶過,但是注意EAX變成了0XC,也就是使用者輸入的註冊碼的個數
:00492292 83F80C cmp eax, 0000000C <--- 個數同0XC(12)進行比較,
:00492295 7C2F jl 004922C6 <--- 小於12個就跳走,哈哈,這下知道為什麼輸入12個字元作為註冊碼了吧?
:00492297 8B45F8 mov eax, dword ptr [ebp-08] <--- [ebp-8]為假碼
:0049229A 80780131 cmp byte ptr [eax+01], 31 <--- 將假碼的第2位同ASCII碼0X31(數字1)進行比較
:0049229E 7526 jne 004922C6 <--- 不等就失敗啦!
:004922A0 8B45F8 mov eax, dword ptr [ebp-08]
:004922A3 80780439 cmp byte ptr [eax+04], 39 <--- 將假碼的第5位同ASCII碼0X39(數字9)進行比較
:004922A7 751D jne 004922C6
:004922A9 8B45F8 mov eax, dword ptr [ebp-08]
:004922AC 80780639 cmp byte ptr [eax+06], 39 <--- 將假碼的第7位同ASCII碼0X39(數字9)進行比較
:004922B0 7514 jne 004922C6
:004922B2 8B45F8 mov eax, dword ptr [ebp-08]
:004922B5 80780737 cmp byte ptr [eax+07], 37 <--- 將假碼的第8位同ASCII碼0X37(數字7)進行比較
:004922B9 750B jne 004922C6
:004922BB 8B45F8 mov eax, dword ptr [ebp-08]
:004922BE 80780935 cmp byte ptr [eax+09], 35 <--- 將假碼的第10位同ASCII碼0X35(數字5)進行比較
:004922C2 7502 jne 004922C6
:004922C4 B301 mov bl, 01
...................................................................
看到這裡你可能感到奇怪:怎麼不用根據使用者名稱計算註冊碼嗎?怎麼直接就比較使用者輸入的註冊碼了?呵呵,其實這個軟體的註冊碼比較部分到這就全部結束了。別急,00492342處還有一個CALL呢,下面也會跳到錯誤提示的地方啊!讓我們繼續跟。0049233A這個CALL同樣用F8帶過,EAX變成了6,有了上一次的經驗,你應該知道了吧?這個是得到使用者名稱的長度。接下來來到00492342第2個關鍵CALL,F7跟進,來到這裡:
...................................................................
首先不要被這麼長的程式碼嚇到,很多是我們不需要了解的,如果你看到程式碼很長就放棄的話,你就永遠也不會有提高。
|:00492342
|
:00492114 55 push ebp <--- 保護現場原來的EBP指標
:00492115 8BEC mov ebp, esp <--- 設定新的EBP指標,指向棧頂ESP
:00492117 83C4D4 add esp, FFFFFFD4 <--- 在堆疊中留出空間放區域性變數,這三句都是子程式的老套路了,如果不懂,記住也行。
:0049211A 53 push ebx
:0049211B 33D2 xor edx, edx <--- EDX清零
:0049211D 8955F4 mov dword ptr [ebp-0C], edx <--- [EBP-0C]清零
:00492120 8955D4 mov dword ptr [ebp-2C], edx <--- [EBP-2C]清零
:00492123 8955F0 mov dword ptr [ebp-10], edx <--- [EBP-10]清零
:00492126 8955F8 mov dword ptr [ebp-08], edx <--- [EBP-08]清零
:00492129 8945FC mov dword ptr [ebp-04], eax <--- 使用者名稱寫入[EBP-04]
:0049212C 8B45FC mov eax, dword ptr [ebp-04] <--- 這句很奇怪,EAX本來就是使用者名稱,幹嗎寫進寫出的?
:0049212F E89028F7FF call 004049C4 <--- 這個CALL很短,你也可以跟進去看看。它是計算出使用者名稱地址-8的記憶體資料然後放到EDX中
:00492134 33C0 xor eax, eax
:00492136 55 push ebp
:00492137 683A224900 push 0049223A
:0049213C 64FF30 push dword ptr fs:[eax]
:0049213F 648920 mov dword ptr fs:[eax], esp
:00492142 33DB xor ebx, ebx
:00492144 8D55F8 lea edx, dword ptr [ebp-08]
:00492147 8B45FC mov eax, dword ptr [ebp-04] <--- 使用者名稱放入EAX中,準備給下面的CALL用
:0049214A E88969F7FF call 00408AD8 <--- 可以帶過,它是用來檢查使用者名稱中是否含有非法字元(ASCII碼小於等於20h的它就認為是非法字元)
:0049214F 8B45F8 mov eax, dword ptr [ebp-08] <--- 使用者名稱放入EAX中,準備給下面的CALL用
:00492152 E88526F7FF call 004047DC <--- 帶過,看暫存器,EAX變化了,變成了6(我的使用者名稱長度),對了,就是用來得到使用者名稱長度的
:00492157 83F804 cmp eax, 00000004 <--- 這句很明顯吧,使用者名稱長度同4比較
:0049215A 0F8CB7000000 jl 00492217 <--- 小於4就沒的玩了
:00492160 8D45EC lea eax, dword ptr [ebp-14] <--- 儲存返回地址
:00492163 8B55F8 mov edx, dword ptr [ebp-08] <--- 使用者名稱送至EDX
:00492166 8A12 mov dl, byte ptr [edx] <--- 將使用者名稱的第1個字元存入DL
:00492168 885001 mov byte ptr [eax+01], dl <--- 將DL寫入記憶體[EAX+01]中
:0049216B C60001 mov byte ptr [eax], 01 <--- 把1寫入記憶體[EAX]中
:0049216E 8D55EC lea edx, dword ptr [ebp-14]
:00492171 8D45E8 lea eax, dword ptr [ebp-18]
:00492174 E85B0DF7FF call 00402ED4 <--- 先帶過,這種下面還要經常呼叫的CALL通常都是“大戰之前的準備”,不要在無謂的地方浪費時間,大不了回頭再跟。 :)
:00492179 8D45E4 lea eax, dword ptr [ebp-1C]
:0049217C 8B55F8 mov edx, dword ptr [ebp-08] <--- 使用者名稱送至EDX
:0049217F 8A5201 mov dl, byte ptr [edx+01] <--- 將使用者名稱的第2個字元送入DL
:00492182 885001 mov byte ptr [eax+01], dl <--- DL寫入記憶體[EAX+01]處
:00492185 C60001 mov byte ptr [eax], 01 <--- 1寫入[EAX]所指的記憶體中
:00492188 8D55E4 lea edx, dword ptr [ebp-1C]
:0049218B 8D45E8 lea eax, dword ptr [ebp-18]
:0049218E B102 mov cl, 02 <--- 注意這裡,執行下面CALL之前CL賦值為2
:00492190 E80F0DF7FF call 00402EA4 <--- 先帶過,因為下面還要呼叫,走幾遍再猜
:00492195 8D55E8 lea edx, dword ptr [ebp-18] <--- 這裡執行完,EDX裡是什麼?哈,“02,"pr" (使用者名稱的前兩位)”
:00492198 8D45E0 lea eax, dword ptr [ebp-20]
:0049219B E8340DF7FF call 00402ED4 <--- 這個CALL上面已經呼叫過了,不妨再帶過,因為下面還有嘛,但是注意,EAX有變化,EAX=3
:004921A0 8D45E4 lea eax, dword ptr [ebp-1C]
:004921A3 8B55F8 mov edx, dword ptr [ebp-08] <--- 使用者名稱存至EDX
:004921A6 8A5202 mov dl, byte ptr [edx+02] <--- 熟悉吧?將使用者名稱的第3個字元送到DL中
:004921A9 885001 mov byte ptr [eax+01], dl <--- 寫入記憶體[EAX+01]中
:004921AC C60001 mov byte ptr [eax], 01 <--- 記憶體[EAX]寫入1
:004921AF 8D55E4 lea edx, dword ptr [ebp-1C]
:004921B2 8D45E0 lea eax, dword ptr [ebp-20]
:004921B5 B103 mov cl, 03 <--- 好象見過?對了,上面呼叫CALL 00402EA4之前CL送入的值是2,這次是3,呵呵,明白了吧?下面這個CALL就是用來取使用者名稱的CL個字元的
:004921B7 E8E80CF7FF call 00402EA4 <--- 現在知道了,取使用者名稱的某些字元
:004921BC 8D55E0 lea edx, dword ptr [ebp-20] <--- 這裡執行完EDX內容為:03,"pri"
:004921BF 8D45D8 lea eax, dword ptr [ebp-28]
:004921C2 E80D0DF7FF call 00402ED4 <--- 又是它!帶過看EAX,EAX=4,結合上面看看,哦,原來它是用來取它需要的第EAX個字元的!
:004921C7 8D45E4 lea eax, dword ptr [ebp-1C]
:004921CA 8B55F8 mov edx, dword ptr [ebp-08] <--- 使用者名稱送至EDX
:004921CD 8A5205 mov dl, byte ptr [edx+05] <--- 注意這裡,上面取的是使用者名稱的第3個字元,這裡沒有繼續按順序往下取,而是取使用者名稱的第6個字元!
:004921D0 885001 mov byte ptr [eax+01], dl <--- 第6個字元寫入記憶體[EAX+01]
:004921D3 C60001 mov byte ptr [eax], 01 <--- 1寫入[EAX]
:004921D6 8D55E4 lea edx, dword ptr [ebp-1C]
:004921D9 8D45D8 lea eax, dword ptr [ebp-28] <--- 執行完EAX是:03, "pri"
:004921DC B104 mov cl, 04 <--- 看,又來了吧!取它需要的第4個字元啦!
:004921DE E8C10CF7FF call 00402EA4 <--- 取它需要的第4個字元,注意是它需要的,不是使用者名稱的第4個字元
:004921E3 8D55D8 lea edx, dword ptr [ebp-28] <--- 果然吧,EDX:04, "prie",因為它取了使用者名稱的第6個字元,所以這裡是"e"
:004921E6 8D45F0 lea eax, dword ptr [ebp-10]
:004921E9 E89225F7FF call 00404780 <--- 這個CALL沒見過,省力原則先帶過,EDX被清零
:004921EE 8B45F0 mov eax, dword ptr [ebp-10] <--- 將它需要的四個字元"prie"送入EAX
:004921F1 8D55F4 lea edx, dword ptr [ebp-0C]
:004921F4 E88F66F7FF call 00408888 <--- 這個是幹什麼的呢?看到下面還要呼叫,先帶過
:004921F9 8B45F4 mov eax, dword ptr [ebp-0C] <--- 執行完,EAX= ASCII "PRIE",哈哈,原來是小寫轉大寫用的
:004921FC 50 push eax <--- 準備工作做完了,壓棧準備“開戰”了,呵呵
:004921FD 8D55D4 lea edx, dword ptr [ebp-2C]
* Possible StringData Ref from Code Obj ->"lane"
|
:00492200 B850224900 mov eax, 00492250 <--- 將字串常量"lane"送至EAX
:00492205 E87E66F7FF call 00408888 <--- 上面用過的,小寫轉大寫
:0049220A 8B55D4 mov edx, dword ptr [ebp-2C] <--- 轉換結果送至EDX
:0049220D 58 pop eax <--- EAX出棧,哼哼,危險訊號,EAX就是已經取完的使用者名稱啊!
:0049220E E80D27F7FF call 00404920 <--- 上面這麼敏感,下面又有跳轉!還不夠關鍵嗎?跟進!
:00492213 7502 jne 00492217
:00492215 B301 mov bl, 01
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0049215A(C), :00492213(C)
|
:00492217 33C0 xor eax, eax
:00492219 5A pop edx
:0049221A 59 pop ecx
:0049221B 59 pop ecx
:0049221C 648910 mov dword ptr fs:[eax], edx
:0049221F 6841224900 push 00492241
...................................................................
只是粗跟就已經得到這麼多有用的資訊了,對於不是很複雜的演算法來說有時就足夠了!我們接著看,0049220E處的關鍵CALL跟進來到這裡:
...................................................................
大概看一下,恩,沒有呼叫了,更可疑!說明是比較判斷的關鍵部分了!
:00404920 53 push ebx
:00404921 56 push esi
:00404922 57 push edi
:00404923 89C6 mov esi, eax <--- EAX是什麼來著?"PRIE"
:00404925 89D7 mov edi, edx <--- EDX: "LANE"
:00404927 39D0 cmp eax, edx <--- 比較是否相等
:00404929 0F848F000000 je 004049BE <--- 相等就跳了!不過跳了是好事還是壞事呢?試試看才知道嘛。雙擊Z flag改變跳轉標誌,F9執行,看到什麼了?嘿嘿,感謝註冊!好,先高興會兒,等下回頭總結。
:0040492F 85F6 test esi, esi
:00404931 7468 je 0040499B
:00404933 85FF test edi, edi
:00404935 746B je 004049A2
:00404937 8B46FC mov eax, dword ptr [esi-04]
:0040493A 8B57FC mov edx, dword ptr [edi-04]
:0040493D 29D0 sub eax, edx
:0040493F 7702 ja 00404943
:00404941 01C2 add edx, eax
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040493F(C)
|
:00404943 52 push edx
:00404944 C1EA02 shr edx, 02
:00404947 7426 je 0040496F
...................................................................
剛拿到這個軟體的時候看到沒有加殼,爆破點又清晰明瞭,就想他肯定是明碼比較註冊碼,就搜記憶體,堆疊,結果不行。於是我以為是非明碼比較的註冊演算法,所以拿出OD...可是沒想到,“演算法”竟然是這樣的。
總結:
判斷條件1:
使用者名稱不得少於4個字元(程式裡這麼寫的),但我想應該是不能少於6個字元吧?其中前三個字元必須為:lan, 隨後兩個字元隨便填,第6個字元必須為e,然後就隨便填了。
判斷條件2:
註冊碼不得少於12個字元,其中第2,5,7,8,10個字元必須分別為:1,9,9,7,5,其他字元就隨便填了。
只要以上兩個條件都滿足,註冊成功!簡單清晰明瞭,序號產生器就不用寫了吧?
注:最新版V1.59註冊演算法已經更改,如果你有興趣可以自己分析。
V1.59版下載地址: http://www1.skycn.com/soft/14357.html
菜鳥寫菜文,歡迎高手指正。
prince 2005.01.13
相關文章
- Image
to PDF演算法分析(菜鳥文章)2004-05-07演算法
- 菜鳥也裝Linux(轉)2022-03-23Linux
- 打造自己的網路電視(菜鳥級)2015-11-15
- SuperCleaner演算法分析----菜鳥級
(12千字)2015-11-15演算法
- 菜鳥脫文 ASProtect 1.23 RC4 ―― DVDFab
v1.52,高手免進了2015-11-15
- 菜鳥也想學習JSON解析2020-09-30JSON
- 菜鳥處女作--飛翔鳥衛星網路電視機2005-01-08
- 如何檢視區域網內電腦網路流量2016-11-22
- HotkeyMaster演算法分析----菜鳥級
(4千字)2015-11-15AST演算法
- 菜鳥理解的區塊鏈2019-01-16區塊鏈
- win10檢視區域網電腦的方法_win10怎麼檢視區域網內的其他電腦2020-07-06Win10
- LanSee 註冊演算法2015-11-15演算法
- 一個區域網工具的註冊演算法分析
(5千字)2015-11-15演算法
- 蟻群演算法 matlab程式詳細解答-菜鳥也能看懂2017-05-30演算法Matlab
- 原創文章檢測工具,原創文章檢測軟體,檢測文章相似度2020-06-15
- 菜鳥、大牛、教主的區別(轉)、、、、2013-02-02
- 菜鳥學習寫的Ioc工具2013-03-27
- 菜鳥也玩mysql之學習筆記篇2017-11-08MySql筆記
- 原創文章檢測工具,檢測原創文章,過不了原創賬號的原因在這2020-06-29
- 菜鳥裹裹App分析系列-產品分析2018-07-26APP
- 重磅! flutter檢視區域性更新2019-09-22Flutter
- 【演算法】演算法菜鳥的爛筆頭2019-03-30演算法
- [演算法] 演算法菜鳥的爛筆頭2019-03-30演算法
- 區域網上傳工具2011-11-29
- [原創]破解-分析Crackme演算法2009-06-13演算法
- (原創)叮咚極品網路電視電影III
V3.92-----演算法分析2004-05-28演算法
- 文章相似度檢測,相似度檢測工具,原創度檢測工具2020-06-10
- 免費文章原創度檢測工具2020-06-23
- 菜鳥也談js(一)——ES6解構物件篇2018-12-08JS物件
- 菜鳥裹裹App分析系列-UI框架設計分析2019-03-04APPUI框架
- 註冊碼演算法入門!----菜鳥篇2015-11-15演算法
- JVM菜鳥進階高手之路十四:分析篇2017-11-27JVM
- 【菜鳥筆記|機器學習】神經網路2020-10-29筆記機器學習神經網路
- 和菜鳥一起學linux之linux效能分析工具oprofile移植2013-11-07Linux
- 菜鳥破解錄自之 Dialup Constructor 及演算法分析
(6千字)2000-09-11Struct演算法
- Linux“菜鳥”到“菜鳥的一些建議2020-10-15Linux
- 原創-XNview v1.65演算法分析2015-11-15View演算法
- IP檢視器V6.1版的演算法淺析(原創)--MD5演算法2015-11-15演算法