NewsReactor 1.0 Build 5009的序號產生器制分析 (16千字)
NewsReactor 1.0 Build 5009的序號產生器制分析
by Fpc[CCG]&6767[BCG] @2001/08
tools: SI, wdasm, BcB 5.0
Homepage: http://www.daansystems.com
Features: NewsReactor is a tool to download binaries from usenet newsgroups.
NewsReactor scans, combines and downloads files from a selected
newsgroup.
This program is shareware. You can register NewsReactor to
get the full version.
這個軟體的註冊很有意思,分析加除錯用了兩天,巨爽,不是說軟體,而是這個過程。本來要寫crackme,現在不用了,嘿嘿。
1、它的未註冊版在啟動時會有一個幾秒鐘的Nag。單擊按鈕“Enter RegCode”,在開啟的對話方塊中輸入名字:LazyUser和註冊碼:123654;
2、^D切換到SoftIce,下命令:Bpx hMemcpy,按下F5返回到Windows;
3、單擊“OK”,被攔下,因為有兩個輸入框,所以要按一次F5,還會被攔下;
4、按n次F12到程式領空,你會到下面(用wdasm的反彙編結果來表示):
:0040C84C 8D4C2434 lea
ecx, dword ptr [esp+34]
* Reference To: MFC42.Ordinal:09D2, Ord:09D2h
|
:0040C850 E893D50000 Call 00419DE8
:0040C855 83F801
cmp eax, 00000001 <- 返回處
:0040C858 0F85F7010000 jne 0040CA55
<- eax=1表示有輸入,所以不會跳
:0040C85E 8D8C2498000000 lea ecx, dword ptr
[esp+00000098]
:0040C865 51
push ecx
:0040C866 8BCF
mov ecx, edi
* Reference To: MFC42.Ordinal:035A, Ord:035Ah
|
:0040C868 E813D70000 Call 00419F80
<- 這幾個call是按編號來的,不理
:0040C86D 8D942494000000 lea edx, dword ptr
[esp+00000094]
:0040C874 8BCE
mov ecx, esi
:0040C876 52
push edx
* Reference To: MFC42.Ordinal:035A, Ord:035Ah
|
:0040C877 E804D70000 Call 00419F80
:0040C87C 6A0A
push 0000000A
:0040C87E 8BCE
mov ecx, esi
* Reference To: MFC42.Ordinal:1ADA, Ord:1ADAh
|
:0040C880 E899DB0000 Call 0041A41E
:0040C885 6A0D
push 0000000D
:0040C887 8BCE
mov ecx, esi
* Reference To: MFC42.Ordinal:1ADA, Ord:1ADAh
|
:0040C889 E890DB0000 Call 0041A41E
:0040C88E 8B36
mov esi, dword ptr [esi] <- esi取得Irc(Inputed Reg
Code)的地址
:0040C890 395EF8
cmp dword ptr [esi-08], ebx <- 判斷Irc長度是否為0
<- 這種情況常見:[esi]處為某字串,那麼[esi-8]處有可能就是該字串的長度
:0040C893 0F8471010000 je 0040CA0A
<- 跳走就完蛋
:0040C899 A0106D4200 mov al,
byte ptr [00426D10] <- 下面這一小段是對緩衝區清0
:0040C89E B93F000000 mov ecx,
0000003F
:0040C8A3 8884249C000000 mov byte ptr [esp+0000009C],
al
:0040C8AA 33C0
xor eax, eax
:0040C8AC 8DBC249D000000 lea edi, dword ptr
[esp+0000009D]
:0040C8B3 895C2410 mov
dword ptr [esp+10], ebx
:0040C8B7 F3
repz
:0040C8B8 AB
stosd
:0040C8B9 66AB
stosw
:0040C8BB AA
stosb
:0040C8BC 8BFE
mov edi, esi <-
這一小段是經典的取字串長度程式碼
:0040C8BE 83C9FF
or ecx, FFFFFFFF
:0040C8C1 33C0
xor eax, eax
:0040C8C3 895C2414 mov
dword ptr [esp+14], ebx
:0040C8C7 F2
repnz
:0040C8C8 AE
scasb
:0040C8C9 F7D1
not ecx <-
ecx=Len+1
:0040C8CB 2BF9
sub edi, ecx <-
這一段是經典的字串複製程式
:0040C8CD 8D94249C010000 lea edx, dword ptr
[esp+0000019C]
:0040C8D4 8BC1
mov eax, ecx
:0040C8D6 8BF7
mov esi, edi
:0040C8D8 8BFA
mov edi, edx <-
目標地址
:0040C8DA 55
push ebp
:0040C8DB C1E902
shr ecx, 02
:0040C8DE F3
repz
:0040C8DF A5
movsd
:0040C8E0 8BC8
mov ecx, eax
:0040C8E2 8D542414 lea
edx, dword ptr [esp+14]
:0040C8E6 83E103
and ecx, 00000003
:0040C8E9 8D8424A0010000 lea eax, dword ptr
[esp+000001A0]
:0040C8F0 F3
repz
:0040C8F1 A4
movsb
:0040C8F2 8D4C2418 lea
ecx, dword ptr [esp+18]
:0040C8F6 8DAC24A0010000 lea ebp, dword ptr
[esp+000001A0]
:0040C8FD 51
push ecx <-
目標地址二
:0040C8FE 52
push edx <-
目標地址一
* Possible StringData Ref from Data Obj ->"%lu-%lu"
|
:0040C8FF 68C05E4200 push 00425EC0
<- 處理的方式
:0040C904 50
push eax <-
待處理字串的偏移址
* Reference To: MSVCRT.sscanf, Ord:02B5h
|
:0040C905 FF15FCD74100 Call dword ptr
[0041D7FC] <- 對字串格式化處理
:0040C90B 83C410
add esp, 00000010
:0040C90E 85C0
test eax, eax <-
eax為對幾個部分進行了格式化,為0表失敗或完成
:0040C910 0F8492000000 je 0040C9A8
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040C9A2(C)
|
:0040C916 8D4C242C lea
ecx, dword ptr [esp+2C] <- 入口的push其實就是上面的格式化處理結果
:0040C91A 8D542414 lea
edx, dword ptr [esp+14] <-
:0040C91E 51
push ecx
:0040C91F 8B4C2428 mov
ecx, dword ptr [esp+28] <- 註冊碼將生成到這裡
:0040C923 52
push edx
:0040C924 895C2434 mov
dword ptr [esp+34], ebx
:0040C928 895C2438 mov
dword ptr [esp+38], ebx
:0040C92C 895C243C mov
dword ptr [esp+3C], ebx
:0040C930 E84B170000 call 0040E080
<- !!計算註冊碼的核心,下面有介紹
:0040C935 8D7C242C lea
edi, dword ptr [esp+2C]
:0040C939 83C9FF
or ecx, FFFFFFFF
:0040C93C 33C0
xor eax, eax
:0040C93E 8D9424A0000000 lea edx, dword ptr
[esp+000000A0]
:0040C945 F2
repnz
:0040C946 AE
scasb
:0040C947 F7D1
not ecx
:0040C949 2BF9
sub edi, ecx
:0040C94B 6A2D
push 0000002D <-
:0040C94D 8BF7
mov esi, edi
:0040C94F 8BFA
mov edi, edx
:0040C951 8BD1
mov edx, ecx
:0040C953 83C9FF
or ecx, FFFFFFFF
:0040C956 F2
repnz
:0040C957 AE
scasb
:0040C958 8BCA
mov ecx, edx
:0040C95A 4F
dec edi
:0040C95B C1E902
shr ecx, 02
:0040C95E F3
repz
:0040C95F A5
movsd
:0040C960 8BCA
mov ecx, edx
:0040C962 55
push ebp
:0040C963 83E103
and ecx, 00000003
:0040C966 F3
repz
:0040C967 A4
movsb
* Reference To: MSVCRT.strchr, Ord:02B7h
|
:0040C968 8B35F4D74100 mov esi, dword
ptr [0041D7F4]
:0040C96E FFD6
call esi <-
檢查Irc中是否含有‘-’,不是必須的
:0040C970 83C408
add esp, 00000008
:0040C973 3BC3
cmp eax, ebx
:0040C975 7431
je 0040C9A8 <-
如果不含,則跳下去,準備比較了
<- 當只在Irc中輸入一個數,比如:34553
<- 就會直接跳下去
:0040C977 40
inc eax <-
當Irc中含‘-’時,這一段被執行到
:0040C978 6A2D
push 0000002D
:0040C97A 50
push eax
:0040C97B FFD6
call esi
:0040C97D 8BE8
mov ebp, eax <-
:0040C97F 83C408
add esp, 00000008
:0040C982 3BEB
cmp ebp, ebx <-
經測試: ebp=ebx=0
:0040C984 7422
je 0040C9A8 <-
所以跳走, 進行比較
:0040C986 8D442418 lea
eax, dword ptr [esp+18]
:0040C98A 8D4C2414 lea
ecx, dword ptr [esp+14]
:0040C98E 50
push eax
:0040C98F 45
inc ebp
:0040C990 51
push ecx
* Possible StringData Ref from Data Obj ->"%lu-%lu"
|
:0040C991 68C05E4200 push 00425EC0
:0040C996 55
push ebp
* Reference To: MSVCRT.sscanf, Ord:02B5h
|
:0040C997 FF15FCD74100 Call dword ptr
[0041D7FC]
:0040C99D 83C410
add esp, 00000010
:0040C9A0 85C0
test eax, eax
:0040C9A2 0F856EFFFFFF jne 0040C916
<-
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040C910(C), :0040C975(C), :0040C984(C)
|
:0040C9A8 8D9424A0000000 lea edx, dword ptr
[esp+000000A0]
:0040C9AF 52
push edx
* Possible StringData Ref from Data Obj ->"Registered by: %s
"
|
:0040C9B0 68AC5E4200 push 00425EAC
:0040C9B5 E8869A0000 call 00416440
:0040C9BA 83C408
add esp, 00000008
:0040C9BD 8D8424A0000000 lea eax, dword ptr
[esp+000000A0]
:0040C9C4 8D4C2420 lea
ecx, dword ptr [esp+20]
:0040C9C8 50
push eax
* Reference To: MFC42.Ordinal:0219, Ord:0219h
|
:0040C9C9 E8D0D50000 Call 00419F9E
<- 好象是字串複製的呼叫
:0040C9CE 8B7C2428 mov
edi, dword ptr [esp+28]
:0040C9D2 8B00
mov eax, dword ptr [eax]
:0040C9D4 8B0F
mov ecx, dword ptr [edi]
:0040C9D6 50
push eax <-
假碼
:0040C9D7 50
push ecx <-
真碼
* Reference To: MSVCRT._mbscmp, Ord:0159h
|
:0040C9D8 FF15E8D74100 Call dword ptr
[0041D7E8] <- 比較
<- 下面的不用管了,因為如果兩者一致,就成功;不一致則失敗
... ...
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040C893(C)
|
:0040CA0A 53
push ebx
:0040CA0B 6A30
push 00000030
* Possible StringData Ref from Data Obj ->"Registration code invalid!"
|
:0040CA0D 68EC5C4200 push 00425CEC
:0040CA12 EB3C
jmp 0040CA50
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040C9F8(C)
|
... ...
:0040CA48 53
push ebx
:0040CA49 6A30
push 00000030
* Possible StringData Ref from Data Obj ->"Thank you for registering!
Please "
->"restart NewsReactor,"
|
:0040CA4B 68385D4200 push 00425D38
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040CA12(U)
|
* Reference To: MFC42.Ordinal:04B0, Ord:04B0h
|
:0040CA50 E8F9D60000 Call 0041A14E
... ...
:0040CAAB C20400
ret 0004
下面我們來看它是如何計算註冊碼的:
* Referenced by a CALL at Addresses:
|:00404C2F , :0040C204 , :0040C930
|
:0040E080 83EC10
sub esp, 00000010
:0040E083 8B442414 mov
eax, dword ptr [esp+14] <- 格式化處理後數字的位置
:0040E087 53
push ebx <-
儲存暫存器
:0040E088 56
push esi
:0040E089 57
push edi
:0040E08A 8B10
mov edx, dword ptr [eax] <- edx取得數字,因為我輸入的是:123654,所以edx=0x1E306
:0040E08C 8B4804
mov ecx, dword ptr [eax+04] <- 如果我們沒有輸入‘-’,只有一個數字,則ecx=0;
<- 若輸入格式是"數字-數字",
則ecx=
:0040E08F C744240C36A60A02 mov [esp+0C], 020AA636
<- 一個陣列的初始化
:0040E097 C7442410418D9514 mov [esp+10], 14958D41
:0040E09F C744241454D75700 mov [esp+14], 0057D754
:0040E0A7 C7442418C8BD3400 mov [esp+18], 0034BDC8
:0040E0AF B82037EFC6 mov eax,
C6EF3720 <- eax初始化
:0040E0B4 BE20000000 mov esi,
00000020 <- 迴圈次數
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040E0FC(C)
<- 這個迴圈當然是關鍵了
|
<- 這段程式碼極為精練,
肯定是直接用匯編寫成的
:0040E0B9 8BFA
mov edi, edx
:0040E0BB 8BDA
mov ebx, edx
:0040E0BD C1EF05
shr edi, 05
:0040E0C0 C1E304
shl ebx, 04
:0040E0C3 33FB
xor edi, ebx
:0040E0C5 8BD8
mov ebx, eax
:0040E0C7 C1EB0B
shr ebx, 0B
:0040E0CA 83E303
and ebx, 00000003
:0040E0CD 03FA
add edi, edx
:0040E0CF 8B5C9C0C mov
ebx, dword ptr [esp+4*ebx+0C]
:0040E0D3 03D8
add ebx, eax
:0040E0D5 054786C861 add eax,
61C88647
:0040E0DA 33FB
xor edi, ebx
:0040E0DC 2BCF
sub ecx, edi <-
:0040E0DE 8BF9
mov edi, ecx
:0040E0E0 8BD9
mov ebx, ecx
:0040E0E2 C1EF05
shr edi, 05
:0040E0E5 C1E304
shl ebx, 04
:0040E0E8 33FB
xor edi, ebx
:0040E0EA 8BD8
mov ebx, eax
:0040E0EC 83E303
and ebx, 00000003
:0040E0EF 03F9
add edi, ecx
:0040E0F1 8B5C9C0C mov
ebx, dword ptr [esp+4*ebx+0C]
:0040E0F5 03D8
add ebx, eax
:0040E0F7 33FB
xor edi, ebx
:0040E0F9 2BD7
sub edx, edi <-
:0040E0FB 4E
dec esi
:0040E0FC 75BB
jne 0040E0B9
:0040E0FE 8B442424 mov
eax, dword ptr [esp+24] <- 準備存放處理結果
:0040E102 5F
pop edi
:0040E103 5E
pop esi
:0040E104 5B
pop ebx
:0040E105 8910
mov dword ptr [eax], edx <- 結果的第一部分
:0040E107 894804
mov dword ptr [eax+04], ecx <- 結果的第二部分
:0040E10A 83C410
add esp, 00000010
:0040E10D C20800
ret 0008
對於這樣的演算法我們應該怎樣分析呢?
一、將上面這段程式略微整理一下,從0X0開始窮舉,檢測結果是否全部為可顯示字元,如果是,該數就是一個註冊碼;
二、寫出逆演算法,根據姓名生成註冊碼,難度大,有挑戰性。
我想寫逆演算法,不但要在程式碼上實現,還得知道必要的引數。在上面這段程式中,出口值經測試可知eax=0,edx為註冊碼的第一部分,ecx為註冊碼的第二部分,就是說假設我們想以使用者名稱“43214321”來註冊,那麼edx=0x31323334,ecx=0x31323334,以此作為條件來看應該輸入什麼樣的註冊碼才能成功。
根據對上面程式的分析,經過長達幾個小時的除錯,終於證明如下的程式段可實現這個功能(注意:其中的數值以0x開頭,視編譯器的需要而定):
很多引數直接搬過來就能用,注意程式碼的順序和關鍵位置即可。
begin:
sub esp, 00000030
push ebx
push esi
push edi
mov [esp+0x0C], 0x020AA636
mov [esp+0x10], 0x14958D41
mov [esp+0x14], 0x0057D754
mov [esp+0x18], 0x0034BDC8
;初始化
xor eax, eax
mov ecx, 0x31323334
mov edx, 0x31323334
mov esi, 0x20
loop1:
mov edi, ecx
mov ebx, ecx
shr edi, 05
shl ebx, 04
xor edi, ebx
add edi, ecx
mov ebx, eax
and ebx, 0x3
mov ebx, dword ptr [esp+4*ebx+0x0C]
add ebx, eax
xor edi, ebx
add edx, edi
<- 關鍵位置
sub eax, 0x61C88647
<- 關鍵位置
mov edi, edx
mov ebx, edx
shr edi, 05
shl ebx, 04
xor edi, ebx
add edi, edx
mov ebx, eax
shr ebx, 0x0B
and ebx, 0x3
mov ebx, dword ptr [esp+4*ebx+0x0C]
add ebx, eax
xor edi, ebx
add ecx, edi
<- 關鍵位置
dec esi
jnz loop1
exit1:
pop edi
pop esi
pop ebx
add esp, 00000030
OK,經過這個迴圈,edx=705987235,ecx=970065253。好了重新註冊,輸入名字:43214321,註冊碼:705987235-970065253,Coolll!
"Thank you for...."。
其實被這個逆演算法折磨很長時間,一開始想偷懶,只輸入一個數字怎樣都不能成功,原因在於edx的值可知,而ecx相當於是隨機的(就是未知的一個值),後來偶然想到‘-’的用處,才成功。
關於註冊碼:名字可以是為少於、等於8個的任意字元,若長度大於8則會失敗;儲存在同一目錄下的NewsReactor.ini,
[Registration
相關文章
- 序號產生器制分析: (1千字)2001-11-19
- Turbo Note+ V4.4序號產生器制分析 (19千字)2001-11-07
- winzip序號產生器 (1千字)2001-04-12
- IrfanView 序號產生器分析(初級版)
(13千字)2015-11-15View
- 美萍安全衛士V8.45序號產生器制作分析過程,及序號產生器! (11千字)2001-10-28
- winzip的通用序號產生器 (2千字)2001-12-10
- 蒼鷹象棋1.0
註冊演算法分析和序號產生器2004-05-16演算法
- 《DesktopX v1.0》PJ 記錄 + 序號產生器原始碼 (13千字)2015-11-15原始碼
- 用keymake制序號產生器實戰~高手莫入~~ (1千字)2001-09-30
- SAP CRM One Order的事件序號產生器制2020-02-11事件
- 書香門第 V1.30 Build 1732 演算法分析 + 無序號產生器 (18千字)2015-11-15UI演算法
- WinAmp V2.11的序號產生器制分析(一)(初學者必讀) (12千字)2001-04-08
- 序號產生器合集2024-03-17
- supercapture3.0的版序號產生器!
(4千字)2002-04-23APT
- Gif2Swf Ver 2.1 TC20序號產生器 && MASM32序號產生器 (4千字)2001-12-10ASM
- 社群遊戲伴侶
V1.0註冊碼的計算,序號產生器 (30千字)2003-05-09遊戲
- SAP CRM呼叫中心裡的事件序號產生器制2020-03-10事件
- 製作mIRC6.02序號產生器(給別人寫的初學者序號產生器教材) (14千字)2015-11-15
- EmEditor V3.29和它的序號產生器 (12千字)2015-11-15
- 一個PostScript(RoPS)序號產生器分析。初學者看。 (21千字)2001-07-08
- 橋牌軟體Deep Finesse的序號產生器 (1千字)2015-11-15
- SWF探索者XP 1.2(swfexplorer)破解+分析+序號產生器
(18千字)2002-04-14
- Myeclipse 6.5 序號產生器2020-04-06Eclipse
- 另類序號產生器(一MFC程式的改造心得) (3千字)2001-09-10C程式
- Advanced Dialer v2.5演算法分析(附序號產生器) (3千字)2002-04-17演算法
- Kalua Cocktails 1.1完全破解,內附彙編序號產生器(用序號產生器編寫器,並有它的使用教程)
(22千字)2002-02-27AI
- 密碼擷取網路版1.0序號產生器(VB寫的) (345字)2001-04-28密碼
- mIRC
v 6.16序號產生器C語言原始碼2004-08-17C語言原始碼
- 【原創】FileRecoveryAngel 演算法分析+序號產生器2015-11-15演算法
- AlgoLab PtVector的破解及序號產生器的編寫 (17千字)2001-05-04Go
- 一個CrackMe的破解以及序號產生器的製作
(4千字)2001-08-16
- 如何製作VB程式記憶體序號產生器--國內某軟體的序號產生器(隱去軟體資訊)
(14千字)2002-08-04記憶體
- HappyIcon序號產生器TC原始碼 (1千字)2001-04-08APP原始碼
- NetTalk破解與序號產生器(高手勿進) (10千字)2001-09-20
- 分享一個navicat序號產生器2024-04-02
- Universe 1.63註冊碼生成分析及序號產生器原碼(上) (2千字)2001-11-12
- EditPlus 2.01b 序號產生器的製作 (22千字)2001-09-10
- HexDiff V2.51和它的序號產生器(MASM32) (6千字)2015-11-15ASM