某國產軟體 - XX E-mail 郵差 的演算法分析,感興趣者請進! (32千字)
某國產軟體 - XX E-mail 郵差 的演算法分析
這篇文章可以說是受人之託,基本上可以有所交待了。不過看過了ppp621等大俠寫的文章後,發表得有點心虛,和那些文章相比,這片太小兒科了!:)
該軟體無殼無反無防,是典型的“三無產品”,這東西分析起來簡直是太爽了。:)跟蹤流程基本上沒費多大勁,主要是寫序號產生器時想了好一會兒.....
由 fi 得知是採用 delphi 編寫,那麼理所當然的就用 DeDe 嘍。
我的機器碼為572463 =
$8BC2F
假定我們填的註冊碼為 WWWWW-XXXXX-YYYYY-ZZZZZ (至於為什麼這麼填,跟到後面就全知道了)
我們很 EZ 地來到這裡:
* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer;
|
0048ED3D E8E2A0F7FF
call 00408E24
0048ED42 8BD0
mov edx, eax
0048ED44
B98D000000 mov ecx, $0000008D
0048ED49 8B45FC
mov eax, [ebp-$04]
* Reference to : TRegisterDlg._PROC_0048E36C()
|
0048ED4C E81BF6FFFF
call 0048E36C //關鍵Call。跟蹤時要注意註冊標誌 bl 的賦值情況
0048ED51 8BD8
mov ebx, eax
* Reference to pointer to GlobalVar_0049D9A8
|
0048ED53 A148CB4900
mov eax, dword ptr [$0049CB48]
* Reference to field GlobalVar_0049D9A8.OFFS_0054
|
0048ED58 885854
mov [eax+$54], bl
* Reference to pointer to GlobalVar_0049D9A8
|
0048ED5B A148CB4900
mov eax, dword ptr [$0049CB48]
0048ED60 84DB
test bl, bl
0048ED62 752C
jnz 0048ED90 //這意味著什麼大家都清楚吧?
*^_^*
0048ED64 8D45F8
lea eax, [ebp-$08]
* Possible String Reference to:
'無效的註冊碼! '
|
0048ED67 BA04EE4800
mov edx, $0048EE04
* Reference to: system.@LStrLAsg;
|
0048ED6C E8AF4FF7FF
call 00403D20
0048ED71 6A30
push $30
0048ED73 8B45F8
mov eax, [ebp-$08]
於是乎,又很 EZ 地來到這裡:
////////////////////////////////////////////////////////////////////////////////
//////////////// 0048E36C call
Start ////////////////
////////////////////////////////////////////////////////////////////////////////
0048E36C 55
push ebp
0048E36D 8BEC
mov ebp, esp
0048E36F
51 push
ecx
0048E370 B90E000000
mov ecx, $0000000E
0048E375 6A00
push $00
0048E377 6A00
push $00
0048E379 49
dec ecx
0048E37A 75F9
jnz 0048E375
0048E37C
874DFC xchg
[ebp-$04], ecx
0048E37F 53
push ebx
0048E380 56
push
esi
0048E381 57
push edi
0048E382 894DF4
mov [ebp-$0C], ecx
0048E385
8955F8 mov
[ebp-$08], edx
0048E388 8945FC
mov [ebp-$04], eax
0048E38B 8B45FC
mov eax, [ebp-$04]
* Reference to: system.@LStrAddRef;
|
0048E38E E8295DF7FF
call 004040BC
0048E393
33C0 xor
eax, eax
0048E395 55
push ebp
* Possible String Reference
to: 'nN?脛E_^[]?
|
0048E396 6829E84800
push $0048E829
***** TRY
|
0048E39B
64FF30 push
dword ptr fs:[eax]
0048E39E 648920
mov fs:[eax], esp
0048E3A1 C645F300
mov byte ptr [ebp-$0D],
$00
0048E3A5 8B45FC
mov eax, [ebp-$04]
* Reference to: system.@LStrLen:Integer;
|
0048E3A8 E85B5BF7FF
call 00403F08
0048E3AD 83F814
cmp eax, +$14
//註冊碼是否填寫完整(20位)
0048E3B0 0F8543040000
jnz 0048E7F9
0048E3B6 8D45DC
lea eax, [ebp-$24]
0048E3B9
8B55FC mov
edx, [ebp-$04]
* Reference to: system.@LStrLAsg;
|
0048E3BC
E85F59F7FF call 00403D20
-----------------------------------------------------------------------------
* Reference to: sysutils.Now:System.TDateTime;
//有一點反跟蹤意思。但太簡單,故不算在反跟蹤裡面。:)
|
0048E3C1 E8BABAF7FF
call 00409E80
0048E3C6
83C4F8 add
esp, -$08
0048E3C9 DD1C24
fstp qword ptr [esp]
0048E3CC 9B
wait
0048E3CD
8D55CC lea
edx, [ebp-$34]
* Possible String Reference to: 'hhnnss'
//取得系統時間 20:00:35 --> 200035
|
0048E3D0
B844E84800 mov eax, $0048E844
* Reference to: Unit_00407C78.Proc_0040AAC0
|
0048E3D5
E8E6C6F7FF call 0040AAC0
0048E3DA 8B45CC
mov eax, [ebp-$34]
* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer;
|
0048E3DD E842AAF7FF
call 00408E24
0048E3E2 8BF0
mov esi, eax
0048E3E4
BB01000000 mov ebx, $00000001
0048E3E9 83FE0A
cmp esi, +$0A
0048E3EC 7C59
jl 0048E447
0048E3EE 8B45DC
mov eax, [ebp-$24]
* Reference to: system.@LStrLen:Integer;
|
0048E3F1 E8125BF7FF
call 00403F08
0048E3F6 85C0
test eax, eax
0048E3F8
7E2E jle
0048E428
* Reference to: sysutils.Now:System.TDateTime;
|
0048E3FA E881BAF7FF call
00409E80
0048E3FF 83C4F8
add esp, -$08
0048E402 DD1C24
fstp qword ptr [esp]
0048E405 9B
wait
0048E406 8D55C8
lea edx, [ebp-$38]
* Possible String Reference
to: 'hhnnss' //再次取得系統時間 20:00:37 -->
200037
|
0048E409 B844E84800
mov eax, $0048E844
* Reference to: Unit_00407C78.Proc_0040AAC0
|
0048E40E E8ADC6F7FF
call 0040AAC0
0048E413 8B45C8
mov eax, [ebp-$38]
* Reference
to: sysutils.StrToInt(System.AnsiString):System.Integer;
|
0048E416
E809AAF7FF call 00408E24
0048E41B 2BC6
sub eax, esi
0048E41D 83F80A
cmp eax, +$0A
//計算執行時間,不得大於 10 秒
0048E420 0F8FD3030000
jnle 0048E7F9 //這是絕對不能跳的
0048E426
EB1F jmp
0048E447
0048E428 8B45DC
mov eax, [ebp-$24]
* Reference to: system.@LStrLen:Integer;
|
0048E42B E8D85AF7FF
call 00403F08
0048E430 3BD8
cmp ebx, eax
0048E432
7D13 jnl
0048E447
0048E434 8D45D8
lea eax, [ebp-$28]
0048E437 50
push eax
0048E438
B901000000 mov ecx, $00000001
0048E43D 8BD3
mov edx, ebx
0048E43F 8B45DC
mov eax, [ebp-$24]
*
Reference to: system.@LStrCopy;
|
0048E442 E8C95CF7FF
call 00404110
0048E447 43
inc
ebx
0048E448 81FBF5010000 cmp
ebx, $000001F5 //將以上時間比較過程重複 500 次
0048E44E 7599
jnz 0048E3E9
//可 r fl z 跳過
0048E450 BB01000000
mov ebx, $00000001
---------------------
註冊碼應在 'A' - 'Z' 範圍內 ---------------------
0048E455 8D45C4
lea eax, [ebp-$3C]
0048E458 50
push eax
0048E459 B901000000
mov ecx, $00000001
0048E45E 8BD3
mov edx,
ebx
0048E460 8B45DC
mov eax, [ebp-$24]
* Reference to: system.@LStrCopy;
|
0048E463 E8A85CF7FF
call 00404110
0048E468 8B45C4
mov eax, [ebp-$3C]
0048E46B
BA54E84800 mov edx, $0048E854
* Reference to: system.@LStrCmp;
|
0048E470 E8A35BF7FF
call 00404018
0048E475
0F877E030000 jnbe 0048E7F9
0048E47B 8D45C0 lea
eax, [ebp-$40]
0048E47E 50
push eax
0048E47F B901000000
mov ecx, $00000001
0048E484
8BD3 mov
edx, ebx
0048E486 8B45DC
mov eax, [ebp-$24]
* Reference to: system.@LStrCopy;
|
0048E489 E8825CF7FF
call 00404110
0048E48E 8B45C0
mov eax, [ebp-$40]
0048E491
BA60E84800 mov edx, $0048E860
* Reference to: system.@LStrCmp;
|
0048E496 E87D5BF7FF
call 00404018
0048E49B
0F8258030000 jb 0048E7F9
0048E4A1 43
inc ebx
0048E4A2 83FB15
cmp ebx, +$15
0048E4A5
75AE jnz
0048E455
0048E4A7 8D45D8
lea eax, [ebp-$28]
0048E4AA 8B55FC
mov edx, [ebp-$04]
* Reference to: system.@LStrLAsg;
|
0048E4AD E86E58F7FF
call 00403D20
0048E4B2
8D45DC lea
eax, [ebp-$24]
* Reference to: system.@LStrClr(String);
|
0048E4B5 E8CE57F7FF call
00403C88
0048E4BA BB01000000
mov ebx, $00000001
-------------------- 將註冊碼倒置
----------------------
最終效果: WWWWWXXXXXYYYYYZZZZZ --> ZZZZZYYYYYXXXXXWWWWW
0048E4BF 8D45BC
lea eax, [ebp-$44]
0048E4C2 50
push eax
0048E4C3
BA14000000 mov edx, $00000014
0048E4C8 2BD3
sub edx, ebx
0048E4CA 42
inc edx
0048E4CB
B901000000 mov ecx, $00000001
0048E4D0 8B45D8
mov eax, [ebp-$28]
* Reference to: system.@LStrCopy;
|
0048E4D3 E8385CF7FF call
00404110
0048E4D8 8B55BC
mov edx, [ebp-$44]
0048E4DB 8D45DC
lea eax, [ebp-$24]
* Reference to: system.@LStrCat;
|
0048E4DE E82D5AF7FF
call 00403F10
0048E4E3
43 inc
ebx
0048E4E4 83FB15
cmp ebx, +$15
0048E4E7 75D6
jnz 0048E4BF
0048E4E9 8D45D8 lea
eax, [ebp-$28]
0048E4EC 8B55DC
mov edx, [ebp-$24]
* Reference to:
system.@LStrLAsg;
|
0048E4EF E82C58F7FF
call 00403D20
0048E4F4 8D45DC
lea eax, [ebp-$24]
* Reference to: system.@LStrClr(String);
|
0048E4F7 E88C57F7FF
call 00403C88
0048E4FC
BB01000000 mov ebx, $00000001
-------------------- 將字串首尾交叉 ----------------------
最終效果:
ZZZZZYYYYYXXXXXWWWWW --> ZXZXZXZXZXYWYWYWYWYW
如果填入的字母都不相同,效果會更強烈些。
:-)
0048E501 FF75DC
push dword ptr [ebp-$24]
0048E504 8D45B8
lea eax, [ebp-$48]
0048E507 50
push eax
0048E508 B901000000
mov ecx, $00000001
0048E50D
8BD3 mov
edx, ebx
0048E50F 8B45D8
mov eax, [ebp-$28]
* Reference to: system.@LStrCopy;
|
0048E512 E8F95BF7FF
call 00404110
0048E517 FF75B8
push dword ptr [ebp-$48]
0048E51A
8D45B4 lea
eax, [ebp-$4C]
0048E51D 50
push eax
0048E51E 8D530A
lea edx, [ebx+$0A]
0048E521 B901000000 mov
ecx, $00000001
0048E526 8B45D8
mov eax, [ebp-$28]
* Reference to:
system.@LStrCopy;
|
0048E529 E8E25BF7FF
call 00404110
0048E52E FF75B4
push dword ptr [ebp-$4C]
0048E531 8D45DC
lea eax, [ebp-$24]
0048E534 BA03000000
mov edx, $00000003
* Reference to:
system.@LStrCatN;
|
0048E539 E88A5AF7FF
call 00403FC8
0048E53E 43
inc ebx
0048E53F
83FB0B cmp
ebx, +$0B
0048E542 75BD
jnz 0048E501
0048E544 8D45D8
lea eax, [ebp-$28]
* Reference to: system.@LStrClr(String);
|
0048E547 E83C57F7FF
call 00403C88
0048E54C
BB01000000 mov ebx, $00000001
------------ Sorry,我不知道該怎麼概括,只好細說了 ---------------
最終效果:ZXZXZXZXZXYWYWYWYWYW
--> '2522232021181916171414111291078212219'
0048E551 8D7B40
lea edi, [ebx+$40]
0048E554 83FF51
cmp edi, +$51
0048E557 7E03
jle 0048E55C
0048E559
83EF10 sub
edi, +$10
0048E55C 8D45D4
lea eax, [ebp-$2C]
0048E55F 50
push eax
0048E560 B901000000 mov
ecx, $00000001
0048E565 8BD3
mov edx, ebx
0048E567 8B45DC
mov eax, [ebp-$24]
* Reference to: system.@LStrCopy;
//下面這個Call是從字串裡取出一個字元
|
0048E56A E8A15BF7FF
call 00404110
0048E56F 8B45D4
mov eax, [ebp-$2C]
0048E572 8A00
mov al, byte ptr [eax]
0048E574 8BF0
mov esi, eax
0048E576 81E6FF000000 and
esi, $000000FF //得到字元的ASCII值
0048E57C 8D55B0
lea edx, [ebp-$50]
0048E57F 8BC6
mov eax, esi
0048E581 2BC7
sub eax, edi
// 這裡注意 EDI 的變化規律:
從 $41 - $51 依次迴圈
* Reference to: sysutils.IntToStr(System.Integer):System.AnsiString;overload;
//數字變字元
|
0048E583 E830A8F7FF
call 00408DB8
0048E588 8B55B0
mov edx, [ebp-$50]
0048E58B
8D45D8 lea
eax, [ebp-$28]
* Reference to: system.@LStrCat;
//看看名字就知道,下面的這個Call是連線字串的
|
0048E58E
E87D59F7FF call 00403F10
0048E593 43
inc ebx
0048E594 83FB15
cmp ebx, +$15
// 迴圈取完字串的每一位
0048E597 75B8
jnz 0048E551
0048E599 8D45DC
lea eax, [ebp-$24]
0048E59C 8B55D8
mov edx, [ebp-$28]
* Reference to: system.@LStrLAsg;
|
0048E59F E87C57F7FF call
00403D20
0048E5A4 BB01000000
mov ebx, $00000001
---------------- 連線後的字串每一位應在
'0' - '9' 範圍內 ----------------------
這就要求我們輸入的註冊碼為了減少麻煩應該都取靠後的字母。
如果比較靠前,則字串可能會含有負數,導致無法透過檢測。
0048E5A9 8D45AC
lea eax, [ebp-$54]
0048E5AC 50
push eax
0048E5AD
B901000000 mov ecx, $00000001
0048E5B2 8BD3
mov edx, ebx
0048E5B4 8B45DC
mov eax, [ebp-$24]
*
Reference to: system.@LStrCopy;
|
0048E5B7 E8545BF7FF
call 00404110
0048E5BC 8B45AC
mov eax, [ebp-$54]
0048E5BF BA6CE84800 mov
edx, $0048E86C
* Reference to: system.@LStrCmp;
|
0048E5C4
E84F5AF7FF call 00404018
0048E5C9 0F872A020000 jnbe
0048E7F9 //一跳就玩完了
0048E5CF 8D45A8 lea
eax, [ebp-$58]
0048E5D2 50
push eax
0048E5D3 B901000000
mov ecx, $00000001
0048E5D8
8BD3 mov
edx, ebx
0048E5DA 8B45DC
mov eax, [ebp-$24]
* Reference to: system.@LStrCopy;
|
0048E5DD E82E5BF7FF
call 00404110
0048E5E2 8B45A8
mov eax, [ebp-$58]
0048E5E5
BA78E84800 mov edx, $0048E878
* Reference to: system.@LStrCmp;
|
0048E5EA E8295AF7FF
call 00404018
0048E5EF
0F8204020000 jb 0048E7F9
0048E5F5 43
inc ebx
0048E5F6 83FB15
cmp ebx, +$15
//只取前 20 個字元
0048E5F9 75AE
jnz 0048E5A9
0048E5FB
33F6 xor
esi, esi
0048E5FD BB01000000
mov ebx, $00000001
0048E602 8D45A4 lea eax, [ebp-$5C]
0048E605 50 push eax
0048E606 B901000000 mov ecx, $00000001
0048E60B 8BD3 mov edx, ebx
0048E60D 8B45DC mov eax, [ebp-$24]
* Reference to: system.@LStrCopy;
|
0048E610 E8FB5AF7FF call 00404110
0048E615 8B45A4 mov eax, [ebp-$5C]
* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer; //字元變數字
|
0048E618 E807A8F7FF call 00408E24
0048E61D 03F0 add esi, eax //將前18個字元累加至ESI
0048E61F 43 inc ebx
0048E620 83FB13 cmp ebx, +$13
0048E623 75DD jnz 0048E602
0048E625 8BDE mov ebx, esi
0048E627 81E301000080 and ebx, $80000001 //除極端情況(數字字元全為0)外,EBX大都等於1
0048E62D 7905 jns 0048E634
0048E62F 4B dec ebx
0048E630 83CBFE or ebx, -$02
0048E633 43 inc ebx
0048E634 8D45A0 lea eax, [ebp-$60]
0048E637 50 push eax
0048E638 B901000000 mov ecx, $00000001 //傳入 Lstrcopy 的三個引數
0048E63D BA13000000 mov edx, $00000013
0048E642 8B45DC mov eax, [ebp-$24]
* Reference to: system.@LStrCopy;
|
0048E645 E8C65AF7FF call 00404110
0048E64A 8B45A0 mov eax, [ebp-$60]
* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer;
|
0048E64D E8D2A7F7FF call 00408E24
0048E652 3BD8 cmp ebx, eax //這一句也就基本上要求了數字串的第19位'1'
0048E654 0F859F010000 jnz 0048E7F9
0048E65A 33F6 xor esi, esi
0048E65C BB01000000 mov ebx, $00000001
---------------- 將數字串中前 18 位每個數字 3 倍的個位數進行累加 ----------------------
最終效果:'2522232021181916171414111291078212219' --> '252223202118191617' -->
(2 * 3) mod 10 + (5 * 3) mod 10 +(2 * 3) mod 10 + .... + (7 * 3) mod 10 = 85
0048E661 8D459C lea eax, [ebp-$64]
0048E664 50 push eax
0048E665 B901000000 mov ecx, $00000001
0048E66A 8BD3 mov edx, ebx
0048E66C 8B45DC mov eax, [ebp-$24]
* Reference to: system.@LStrCopy;
|
0048E66F E89C5AF7FF call 00404110
0048E674 8B459C mov eax, [ebp-$64]
* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer;
|
0048E677 E8A8A7F7FF call 00408E24
0048E67C 8D0440 lea eax, [eax+eax*2] // X * 3
0048E67F B90A000000 mov ecx, $0000000A
0048E684 99 cdq
0048E685 F7F9 idiv ecx
0048E687 03F2 add esi, edx // 個位數相加
0048E689 43 inc ebx
0048E68A 83FB13 cmp ebx, +$13 // 取前18位
0048E68D 75D2 jnz 0048E661
------------------------ 再求累加和的個位數 --------------------------
最終效果:85 mod 10 = 5
0048E68F 8BC6 mov eax, esi
0048E691 B90A000000 mov ecx, $0000000A
0048E696 99 cdq
0048E697 F7F9 idiv ecx
0048E699 8BDA mov ebx, edx
0048E69B 8D4598 lea eax, [ebp-$68]
0048E69E 50 push eax
0048E69F B901000000 mov ecx, $00000001
0048E6A4 BA14000000 mov edx, $00000014
0048E6A9 8B45DC mov eax, [ebp-$24]
* Reference to: system.@LStrCopy;
|
0048E6AC E85F5AF7FF call 00404110
0048E6B1 8B4598 mov eax, [ebp-$68]
* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer;
|
0048E6B4 E86BA7F7FF call 00408E24
0048E6B9 3BD8 cmp ebx, eax //累加和的個位數('5')應和數字串的第20位相等
0048E6BB 0F8538010000 jnz 0048E7F9
0048E6C1 8D45E0 lea eax, [ebp-$20]
0048E6C4 50 push eax
0048E6C5 B903000000 mov ecx, $00000003
0048E6CA BA10000000 mov edx, $00000010
0048E6CF 8B45DC mov eax, [ebp-$24]
* Reference to: system.@LStrCopy; // Lstrcopy(string,10,3) = '617'
| 不過根據後來的跟蹤,
0048E6D2 E8395AF7FF call 00404110 好像這次取出的字串無關緊要
0048E6D7 8D45EC lea eax, [ebp-$14]
* Reference to: system.@LStrClr(String);
|
0048E6DA E8A955F7FF call 00403C88
0048E6DF 8D45E8 lea eax, [ebp-$18]
* Reference to: system.@LStrClr(String);
|
0048E6E2 E8A155F7FF call 00403C88
0048E6E7 8D45E4 lea eax, [ebp-$1C]
* Reference to: system.@LStrClr(String);
|
0048E6EA E89955F7FF call 00403C88
0048E6EF BB01000000 mov ebx, $00000001
------------ Sorry,我又不知道該怎麼說了,看最終效果吧 ---------------
最終效果:'2522232021181916171414111291078212219' -->
'252' + '223' + '202' + '118' + '191' -->
'22211'(第一位) + '52019'(第二位) + '23281' (第三位)
0048E6F4 8D4594 lea eax, [ebp-$6C]
0048E6F7 50 push eax
0048E6F8 8BC3 mov eax, ebx
0048E6FA 48 dec eax
0048E6FB 8D3440 lea esi, [eax+eax*2]
0048E6FE 8BD6 mov edx, esi
0048E700 42 inc edx
0048E701 B901000000 mov ecx, $00000001
0048E706 8B45DC mov eax, [ebp-$24]
* Reference to: system.@LStrCopy;
|
0048E709 E8025AF7FF call 00404110
0048E70E 8B5594 mov edx, [ebp-$6C]
0048E711 8D45EC lea eax, [ebp-$14]
* Reference to: system.@LStrCat;
|
0048E714 E8F757F7FF call 00403F10
0048E719 8D4590 lea eax, [ebp-$70]
0048E71C 50 push eax
0048E71D 8BD6 mov edx, esi
0048E71F 83C202 add edx, +$02
0048E722 B901000000 mov ecx, $00000001
0048E727 8B45DC mov eax, [ebp-$24]
* Reference to: system.@LStrCopy;
|
0048E72A E8E159F7FF call 00404110
0048E72F 8B5590 mov edx, [ebp-$70]
0048E732 8D45E8 lea eax, [ebp-$18]
* Reference to: system.@LStrCat;
|
0048E735 E8D657F7FF call 00403F10
0048E73A 8D458C lea eax, [ebp-$74]
0048E73D 50 push eax
0048E73E 8BD6 mov edx, esi
0048E740 83C203 add edx, +$03
0048E743 B901000000 mov ecx, $00000001
0048E748 8B45DC mov eax, [ebp-$24]
* Reference to: system.@LStrCopy;
|
0048E74B E8C059F7FF call 00404110
0048E750 8B558C mov edx, [ebp-$74]
0048E753 8D45E4 lea eax, [ebp-$1C]
* Reference to: system.@LStrCat;
|
0048E756 E8B557F7FF call 00403F10
0048E75B 43 inc ebx
0048E75C 83FB06 cmp ebx, +$06 //共迴圈5次,每次取出3個字元
0048E75F 7593 jnz 0048E6F4
0048E761 8B45E0 mov eax, [ebp-$20]
* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer;
|
0048E764 E8BBA6F7FF call 00408E24
0048E769 BEE7030000 mov esi, $000003E7
0048E76E 2BF0 sub esi, eax // 999 - 617 = 382 = $17E
0048E770 8B45EC mov eax, [ebp-$14]
* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer;
|
0048E773 E8ACA6F7FF call 00408E24
0048E778 BF9F860100 mov edi, $0001869F
0048E77D 2BF8 sub edi, eax // 99999 - 22211 = 77788 = $12FDC
0048E77F 8B45E8 mov eax, [ebp-$18]
* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer;
|
0048E782 E89DA6F7FF call 00408E24
0048E787 BB9F860100 mov ebx, $0001869F
0048E78C 2BD8 sub ebx, eax // 99999 - 52019 = 47980 = $BB6C
0048E78E 8B45E4 mov eax, [ebp-$1C]
* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer;
|
0048E791 E88EA6F7FF call 00408E24
0048E796 BA9F860100 mov edx, $0001869F
0048E79B 2BD0 sub edx, eax // 99999 - 23281 = 76718 = $12BAE
0048E79D 8955D0 mov [ebp-$30], edx
0048E7A0 8BC3 mov eax, ebx
0048E7A2 B964000000 mov ecx, $00000064
0048E7A7 99 cdq
0048E7A8 F7F9 idiv ecx
0048E7AA 8BCA mov ecx, edx
0048E7AC 2BF1 sub esi, ecx
0048E7AE 8BC3 mov eax, ebx
0048E7B0 BE64000000 mov esi, $00000064
0048E7B5 99 cdq
0048E7B6 F7FE idiv esi // 47980 ÷ 100 = 479 ... 80
0048E7B8 8BF0 mov esi, eax
0048E7BA 8BC6 mov eax, esi
0048E7BC 2BC1 sub eax, ecx
0048E7BE 7906 jns 0048E7C6 // 若商小於餘數,則商+1000(反正不能出現負數)
0048E7C0 81C6E8030000 add esi, $000003E8
0048E7C6 2BF1 sub esi, ecx
0048E7C8 3B75F4 cmp esi, [ebp-$0C] //關鍵判斷:比較399(= 479 - 80)和$8D(常量)
0048E7CB 752C jnz 0048E7F9 //跳則死,不跳則活。
0048E7CD 8BF7 mov esi, edi
0048E7CF 8BC6 mov eax, esi
0048E7D1 2BC3 sub eax, ebx // $12FDC - $BB6C = $7470
0048E7D3 7906 jns 0048E7DB // 若商小於餘數,則商+100000(反正不能出現負數)
0048E7D5 81C6A0860100 add esi, $000186A0
0048E7DB 2BF3 sub esi, ebx
0048E7DD 8B45F8 mov eax, [ebp-$08]
0048E7E0 B90A000000 mov ecx, $0000000A
0048E7E5 99 cdq
0048E7E6 F7F9 idiv ecx
0048E7E8 8945F8 mov [ebp-$08], eax //機器碼:572463 idiv 10 = 57246 =$DF9E
0048E7EB 3B75F8 cmp esi, [ebp-$08] //關鍵判斷:比較$7470(= $12FDC - $BB6C)和$DF9E
0048E7EE 7509 jnz 0048E7F9 //跳則死,不跳則活。
0048E7F0 8B45D0 mov eax, [ebp-$30]
0048E7F3 2BC7 sub eax, edi
0048E7F5 C645F301 mov byte ptr [ebp-$0D], $01 //到此處寫入註冊成功標誌
0048E7F9 33C0 xor eax, eax
0048E7FB 5A pop edx
0048E7FC 59 pop ecx
0048E7FD 59 pop ecx
0048E7FE 648910 mov fs:[eax], edx
****** FINALLY //異常處理,釋放單元,不去管它。
|
* Possible String Reference to: 'E_^[]?
|
0048E801 6830E84800 push $0048E830
0048E806 8D458C lea eax, [ebp-$74]
0048E809 BA11000000 mov edx, $00000011
* Reference to: system.@LStrArrayClr;
|
0048E80E E89954F7FF call 00403CAC
0048E813 8D45D4 lea eax, [ebp-$2C]
0048E816 BA07000000 mov edx, $00000007
* Reference to: system.@LStrArrayClr;
|
0048E81B E88C54F7FF call 00403CAC
0048E820 8D45FC lea eax, [ebp-$04]
* Reference to: system.@LStrClr(String);
|
0048E823 E86054F7FF call 00403C88
0048E828 C3 ret
0048E829 E96E4EF7FF jmp 0040369C
0048E82E EBD6 jmp 0048E806
****** END
|
0048E830 8A45F3 mov al, byte ptr [ebp-$0D] //將註冊標誌賦予AL,返回供後面呼叫
0048E833 5F pop edi
0048E834 5E pop esi
0048E835 5B pop ebx
0048E836 8BE5 mov esp, ebp
0048E838 5D pop ebp
0048E839 C3 ret
-------------------------0048E36C call End-----------------------------------------
寫得挺長,但分析的確是比較快的。現在總結一下注冊碼比較流程:
機器碼:572463 =$8BC2F
註冊碼:WWWWW-XXXXX-YYYYY-ZZZZZ
WWWWWXXXXXYYYYYZZZZZ ---> ZZZZZYYYYYXXXXXWWWWW ---> ZXZXZXZXZXYWYWYWYWYW --->
'2522232021181916171414111291078212219' ---> '252223202118191617' --->
'252' + '223' + '202' + '118' + '191' ---> '22211' + '52019' + '23281' --->
1、99999 - 52019 = 47980 ÷ 100 = 479 ... 80 ---> 要求 479 - 80 等於常量 141 = &8D
99999 - 85798 = 14201
2、99999 - 22211 = 77788 - 47980 = 29808 ---> 要求與機器碼:572463 idiv 10 = 57246相等
下面該寫序號產生器了:
首先應該知道,對註冊碼的 20 位進行窮舉是不太現實的。那麼我們是不是有辦法減少窮舉的位數呢。我想了一些辦法,去掉了些無關緊要的
位數,但還是比較大,效率很低,估計軟體的作者是不會使用的。:)我們必須另闢蹊徑。
由上面的註冊流程可知,最重要的部分是那個數字串('2522232021181916171414111291078212219')。一般情況下,該串的長度是大於20位的,
除非在極端情況(比如'11111111111111111111',此時註冊碼反轉交叉後應該是類似這個樣子:'BCDEFGHIJKLMNOPQRSTU')下。而最核心的只
有15位數字,用7、8位註冊碼就可產生。這就意味著註冊碼的某些位數可以忽略不計。而在這15位數字中,又有5位沒有參與關鍵判斷(指的是
0048E7C8、0048E7EB兩處判斷),這樣我們又可捨棄 5 位數字。
假設我們需要的兩個 5 位數分別為 M(對應例子中的22211) 和 N(對應例子中的52019)。由流程我們可以看到,真正的註冊碼要求:(
99999 - N ) ÷ 100 = P ... Q , P - Q = 141 ,
∴ P = Q + 141
∴ 99999 - N = 100 * P + Q = 101 * Q + 14100
∴ N = 99999 - ( 101 * Q + 14100 ) = 85899 - 101 * Q
又∵ 99999 - M - (99999 - N) = 99999 - 14100 - 101 * Q - M = 57246
∴ M = 99999 - 14100 - 101 * Q - 57246 = 28653 - 101 * Q
這樣,我們用一位變數和機器碼便表示出了兩個 5 位數。第三個 5 位數由於沒起什麼作用,所以我們不妨設它為 11111。
例如:
令Q = 1,則
N = 85899 - 101 * 1 = 85798
M = 28653 - 101 * 1 = 28552
於是15位的字串就是 281851571591281;
又∵ 第16-18位沒有什麼限制,所以就取隨便取個212;
第19位通常狀況下為1(見0048E627);
第20位的值等於數字串前18位('281851571591281212')每個數字三倍和的個位數(∵((a mod n) +(b mod n)) mod n = (a+b) mod n),此
時為7;
∴該數字串為 '28185157159128121217'
然後,我們對數字分組。分組的原則就是,讓後面的數儘量的小。因為 'Z' 的 ASCII 值為90,而到後面加上的數會很大(比如83、84等),
容易超出界限。不夠20 組可再補齊。補齊原則同上。再分別對每一組數字一次加上65、66、67、……、85,如下:
2 8 18 5 15 7 15 9 12 8 12 12 1 7 1 1 1 1 1 1
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
67 74 85 73 84 77 86 81 85 82 87 88 78 85 80 81 82 83 84 85
C J U I T M V Q U R W X N U P Q R S T U
這樣,CJUITMVQURWXNUPQRSTU ---> CUTVUWNPRTJIMQRXUQSU ---> USQUX-RQMIJ-TRPNW-UVTUC
再附上序號產生器原始碼(Delphi 6 + WinXP Pro 下除錯透過),一切OK。
procedure TForm1.Button1Click(Sender: TObject);
var
Machinecode,N,Tmp,i:Integer;
Tmpstr,tmpstr1,tmpstr2:Str
相關文章
- 某國產彩票V3.0軟體的演算法分析
(22千字)2015-11-15演算法
- 漢化輔助軟體---有誰感興趣? (38字)2000-07-18
- 興趣愛好——IOS興趣感的磨練2017-08-01iOS
- 推薦5款小眾軟體,感興趣自行下載2023-10-13
- HTTP總有你感興趣的2018-01-07HTTP
- 其他感興趣的程式碼庫2024-04-15
- 一個遊戲系統,向Banq大哥,以及感興趣的朋友請教!2008-03-28遊戲
- 對WebUI技術感興趣的說 (轉)2007-08-16WebUI
- Bazaarvoice:一半的消費者對增強購物體驗的技術感興趣2022-02-02
- matlab感興趣區域處理2020-12-28Matlab
- 對於某東平臺XX娃娃的使用者體驗進行(嚴肅、限速)資料分析2020-10-20
- 某軟體公司國產分析型資料庫選型方法論2023-11-24資料庫
- Bizrate:只有28%的消費者對使用智慧音響購物感興趣2019-09-03
- 給對linux感興趣的初學者的文章2010-01-20Linux
- 興趣愛好【演算法】2017-08-09演算法
- 分析破解某個軟體公司出的理財東東!
(14千字)2015-11-15
- Appcelerator:37%的開發者對WP平臺感興趣2013-06-29APP
- 給對linux感興趣的初學者的文章 (轉)2008-01-22Linux
- Prismatic:用機器學習分析使用者興趣只需10秒鐘2013-01-03機器學習
- GfK:中國使用者對蘋果支付系統最感興趣 比例達54%2014-10-15蘋果
- 大家對 Laravel 的原始碼和架構感興趣麼?2019-11-15Laravel原始碼架構
- 有沒有人對郵件系統有興趣2003-04-06
- 軟體諮詢和編碼,興趣與發展的對話2008-03-18
- I've got it!有興趣的看過來! (3千字)2001-02-17Go
- 趣文:TCP/IP 之 大明王朝郵差2016-05-14TCP
- YouGov:調查稱美國近半消費者對摺疊屏手機感興趣2021-04-27Go
- [阿里DIEN] 深度興趣進化網路原始碼分析 之 Keras版本2021-01-26阿里原始碼Keras
- 邦芒簡歷:HR對哪些工作經驗感興趣?2024-02-19
- 一旦感興趣,早晚都要入坑的Linux系統!2020-09-10Linux
- 谷歌:報告指出只有16%的手遊玩家對NFT遊戲感興趣2022-06-12谷歌遊戲
- Sequence:只有23%的視訊遊戲玩家對VR裝置感興趣2016-10-17遊戲VR
- Bernstein:調查顯示48%蘋果使用者對iPhone X感興趣 25%計劃購買2017-10-26蘋果iPhone
- AIP:超過7成中國和印度消費者對乘坐無人駕駛汽車感興趣2017-10-16AI
- [阿里DIN] 深度興趣網路原始碼分析 之 如何建模使用者序列2020-10-20阿里原始碼
- UltraEdit-32
10註冊碼演算法分析 (19千字)2003-05-17演算法
- 為你的舊智慧手機再續命10年,你感興趣嗎?2020-04-30
- Interpret:56%的NFT和加密遊戲玩家對賺取NFT感興趣2022-02-14加密遊戲
- 聽說大家很感興趣瑋子的學習心得,採訪來了2023-02-27