NOP破解
輸入姓名,序列號,先輸入一個假的看看效果。
好的,注意這串字符串,說明我們的序列號錯誤,
由程序給的直觀的一目,跟輸入賬號密碼一樣,一個判斷,之後你懂。
載入OD,搜這串字符串,再查看反彙編。
直觀可見,上邊有一個JNZ跳轉,把它NOP,就成功破解了。
序列號生成分析
查看JNZ上邊的CALL
發現是一個比較,第一個PUSH是我們輸入的序列號,第二個PUSH正確的序列號
那這些數據是從哪裏來的呢,繼續查看上邊的CALL
查看壓進去的參數,可以斷定這個CALL是生成序列號的,那這些數據又是從哪裏來的呢,繼續查看上邊的操作。
這樣的循環操作,就不羅嗦了,直接定位到開始生成的位置。
0042FA79 |> \8D55 F0 lea edx,[local.4]
0042FA7C |. 8B83 DC010000 mov eax,dword ptr ds:[ebx+0x1DC]
0042FA82 |. E8 D1AFFEFF call Acid_bur.0041AA58 ; 獲取用戶名長度
0042FA87 |. 8B45 F0 mov eax,[local.4] ; 獲取用戶名首地址
0042FA8A |. 0FB600 movzx eax,byte ptr ds:[eax] ; 獲取第一個字符的編碼數字
0042FA8D |. F72D 50174300 imul dword ptr ds:[0x431750] ; 將獲取的數字乘以29
0042FA93 |. A3 50174300 mov dword ptr ds:[0x431750],eax
0042FA98 |. A1 50174300 mov eax,dword ptr ds:[0x431750]
0042FA9D |. 0105 50174300 add dword ptr ds:[0x431750],eax ; 將乘以後的數據 乘以2
0042FAA3 |. 8D45 FC lea eax,[local.1]
0042FAA6 |. BA ACFB4200 mov edx,Acid_bur.0042FBAC ; CW
0042FAAB |. E8 583CFDFF call Acid_bur.00403708 ; 將CW放在ebp-4位置
0042FAB0 |. 8D45 F8 lea eax,[local.2]
0042FAB3 |. BA B8FB4200 mov edx,Acid_bur.0042FBB8 ; CRACKED
0042FAB8 |. E8 4B3CFDFF call Acid_bur.00403708 ; 將CRACKED放在ebp-8位置
0042FABD |. FF75 FC push [local.1] ; Acid_bur.0042FBAC
0042FAC0 |. 68 C8FB4200 push Acid_bur.0042FBC8 ; -
0042FAC5 |. 8D55 E8 lea edx,[local.6]
0042FAC8 |. A1 50174300 mov eax,dword ptr ds:[0x431750]
0042FACD |. E8 466CFDFF call Acid_bur.00406718 ; 將上邊運算的16進制值轉換爲10進制 然後轉成字符串
0042FAD2 |. FF75 E8 push [local.6]
0042FAD5 |. 68 C8FB4200 push Acid_bur.0042FBC8 ; -
0042FADA |. FF75 F8 push [local.2] ; Acid_bur.0042FBB8
0042FADD |. 8D45 F4 lea eax,[local.3]
0042FAE0 |. BA 05000000 mov edx,0x5
0042FAE5 |. E8 C23EFDFF call Acid_bur.004039AC ; 密碼生成
0042FAEA |. 8D55 F0 lea edx,[local.4]
0042FAED |. 8B83 E0010000 mov eax,dword ptr ds:[ebx+0x1E0]
0042FAF3 |. E8 60AFFEFF call Acid_bur.0041AA58
0042FAF8 |. 8B55 F0 mov edx,[local.4] ; 輸入的密碼
0042FAFB |. 8B45 F4 mov eax,[local.3] ; 正確的密碼
0042FAFE |. E8 F93EFDFF call Acid_bur.004039FC ; 密碼比較
0042FB03 75 1A jnz short Acid_bur.0042FB1F
翻譯成的C語言如下:
#include "stdafx.h"
int main(int argc, char* argv[])
{
char buf[MAX_PATH];
printf("請輸入用戶名(自動生成密碼):");
scanf("%s", buf);
int num = (int)buf[0];
num = num * 0x29;
num = num * 2;
printf("CW-%d-CRACKED\n", num);
return 0;
}
多的廢話就沒有囉嗦了,做這些主要是爲了練習反彙編能力。