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)