crackme2(簡單算法)

crackme2來自/看雪/2007精華版CrackMe/序列號/逍遙風大牛
【詳細過程】
無殼,用OD載入這個CRACKME,根據字符串提示信息很容易找到關鍵代碼
來到關鍵代碼處

0040124C . 6A 28 PUSH 28 ; /Count = 28 (40.)
0040124E . 68 06214000 PUSH crcme1.00402106 ; |Buffer = crcme1.00402106
00401253 . 68 E9030000 PUSH 3E9 ; |ControlID = 3E9 (1001.)
00401258 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
0040125B . E8 10020000 CALL ; \GetDlgItemTextA
00401260 . 83F8 05 CMP EAX,5 ; 註冊名位數與5比較
00401263 . 0F82 BD000000 JB crcme1.00401326 ; 小於5位就跳向失敗

註冊名位數不得小於5位

00401269 . 6A 28 PUSH 28 ; /Count = 28 (40.)
0040126B . 68 2E214000 PUSH crcme1.0040212E ; |Buffer = crcme1.0040212E
00401270 . 68 EA030000 PUSH 3EA ; |ControlID = 3EA (1002.)
00401275 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
00401278 . E8 F3010000 CALL ; \GetDlgItemTextA
0040127D . BF 06214000 MOV EDI,crcme1.00402106 ; 取輸入的註冊碼
00401282 . 33DB XOR EBX,EBX ; EBX清零
00401284 . 33C0 XOR EAX,EAX ; EAX清零
00401286 > 8A1F MOV BL,BYTE PTR DS:[EDI] ; 取註冊名每一位的ASCII碼
00401288 . 80FB 20 CMP BL,20 ; 格式驗證
0040128B . 0F82 95000000 JB crcme1.00401326
00401291 . 03C3 ADD EAX,EBX ; 註冊名每一位的 ASCII碼累加
00401293 . 47 INC EDI ; 每計算一次EDI中的值加1
00401294 . 803F 00 CMP BYTE PTR DS:[EDI],0 ; 累加完了嗎
00401297 .^ 75 ED JNZ SHORT crcme1.00401286 ; 循環計算
00401299 . C1C0 03 ROL EAX,3 ; 累加的結果設爲A,ROL(A,3)得到B
0040129C . 35 A5150500 XOR EAX,515A5 ; XOR(B,0x515A5),得到的結果設爲C

到這裏對註冊名的計算就完成了.

004012A1 . 50 PUSH EAX
004012A2 . 33C0 XOR EAX,EAX
004012A4 . 33DB XOR EBX,EBX
004012A6 . 33FF XOR EDI,EDI ; 個寄存器清零
004012A8 . BE 2E214000 MOV ESI,crcme1.0040212E ; 使ESI等於輸入的註冊碼
004012AD > B8 0A000000 MOV EAX,0A ; 令EAX等於定值0xA
作者:逍遙風
004012B2 . 8A1E MOV BL,BYTE PTR DS:[ESI] ; 取註冊碼的每一位進行轉換
004012B4 . 85DB TEST EBX,EBX
004012B6 . 74 15 JE SHORT crcme1.004012CD
004012B8 . 80FB 30 CMP BL,30 ; 格式驗證
004012BB . 72 69 JB SHORT crcme1.00401326
004012BD . 80FB 39 CMP BL,39 ; 格式驗證
004012C0 . 7F 64 JG SHORT crcme1.00401326
004012C2 . 83EB 30 SUB EBX,30
004012C5 . 0FAFF8 IMUL EDI,EAX
004012C8 . 03FB ADD EDI,EBX
004012CA . 46 INC ESI
004012CB .^ EB E0 JMP SHORT crcme1.004012AD ; 循環計算

在注意這裏,這個循環的作用是將輸入的註冊碼轉換成對應的16進制形式

004012CD > 81F7 CA870000 XOR EDI,87CA ; XOR(註冊碼的16進制,0x87CA),得到的結果設爲D
004012D3 . 8BDF MOV EBX,EDI

以上代碼是對輸入的註冊碼進行的計算.

主要步驟是將註冊碼的16進制與定值0x87CA)進行XOR運算

004012D5 . 58 POP EAX
004012D6 . 03C3 ADD EAX,EBX ; 將註冊名和註冊碼的計算結果相加,得到的和設爲E

將註冊名的計算結果與註冊碼的計算結果相加

004012D8 . 35 E7970700 XOR EAX,797E7 ; XOR(E,0x797E7)
004012DD . 85C0 TEST EAX,EAX ; 檢驗是否等於零

從這裏可以得知,最後的計算結果必須等於0x797E7
就是說:
F (註冊名) + G (註冊碼) = 定值0x797E7

004012DF . 75 45 JNZ SHORT crcme1.00401326 ; 不等於零就跳向失敗
004012E1 . 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
004012E3 . 68 1B204000 PUSH crcme1.0040201B ; |-=acg=- t h e b e s t -=acg=-
004012E8 . 68 77204000 PUSH crcme1.00402077 ; |Text = "Yeah You Did It!!!
Czyli nareszczie ci si?uda硂
Teraz mo縠sz przy徹czy?si?do ACG"
004012ED . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hOwner
004012F0 . E8 5D010000 CALL ; \MessageBoxA

【算法總結】
由於註冊信息必須滿足
F(註冊名) + G(註冊碼) = 定值
所以要進行逆推.已知定值等於0x797E7
很容易得出:G(註冊碼) = 定值0x797E7 - F(註冊名)
根據分析的結論,以註冊名lonelykin爲例,
F(註冊名) = 0x50B0D
所以: G(註冊碼) = 定值0x797E7 - F(註冊名) = 0x797E7 - 0x50B0D= 0x28CDA
因爲
G(註冊碼) = XOR(註冊碼的16進制,0x87CA),
所以:註冊碼的16進制就等於XOR(0x28CDA,0x87CA)
即::註冊碼的16進制 = XOR(0x28CDA,0x87CA) = 0x20B10
所以註冊碼就應該等於133904

算法很簡單,用python寫了註冊機,貼上來 大牛誤噴

import binascii
import os,sys
#獲取用戶輸入內容
Regname = raw_input(" please input you registered name: ");
#求字符串長度
Leg = len( Regname );
#判斷字符串是否符合條件
if (Leg <= 5):
    print " your registered name is too short! ";
elif (Leg >= 51):
    print " your registered name is too long! ";
else:
    print " \nyour registered name is: " + Regname;
#列表求和
l = list( Regname );
h = [];
y = [];

#逐個轉換16進制並存放在h列表中
for i in l:
    z = binascii.b2a_hex( i );
    h.append( z );

#逐個轉換10進制並存放在y列表中
for i in h:
    Dec = int( i, 16 );
    y.append( Dec );

#十進制累計求和
ret = sum(y);
#結果循環左移3位
result = ret << 3;
fixed1 = 333221;
fixed2 = 497639;
fixed3 = 34762;
#確定用戶名
lname = result^fixed1
pwd = fixed2 -lname
#確定註冊碼
realpwd = pwd^fixed3
print "your Serial is:" + str(realpwd)
發佈了53 篇原創文章 · 獲贊 9 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章