[逆向工程]160個CrackMe入門實戰之Afkayas.1.Exe解析(二)
一、前言
在逆向工程的學習路徑上,CrackMe程序是初學者最好的練手材料。今天我們要分析的是160個CrackMe系列的第二題——Afkayas.1.Exe。這個程序由Afkayas編寫,難度為★(初級),包含了典型的驗證機制。通過本實戰,你將學會:
- 使用x32dbg進行動態調試
- 爆破方法
- 分析算法邏輯并編寫注冊機
- 掌握基本的匯編指令分析技巧
二、環境與工具準備
在開始逆向之前,我們需要準備以下環境:
- 操作系統:Windows 10
- 調試工具:x32dbg
- 目標程序:Afkayas.1.Exe
- 輔助工具:ExeinfoPe(查殼工具,雖然本程序無殼)
三、程序初步分析
3.1 查殼分析
無殼32位vb語言
3.2 運行Afkayas.1.Exe
功能:驗證用戶輸入的用戶名(Name)與序列號(Serial)是否匹配
目的:跳過賬號序列號匹配驗證
四、逆向破解實戰
4.1 驗證爆破
此部分需要同時輸入用戶名和序列號。
4.1.1 爆破方法
-
定位錯誤提示:
x32dbg打開程序,F9運行,搜索字符串“You Get Wrong” 找到關鍵跳轉,直接爆破
將紅色箭頭處代碼直接nop填充,打補丁另存程序
2.結果驗證
4.1.2 算法分析與注冊機編寫
通過動態調試,我們可以發現序列號的生成規律:
1.序列號生成算法
call dword ptr ds:[eax+A0]
cmp eax,edi
jge afkayas.1.4023D2
push A0
push afkayas.1.401B5C
push ebx
push eax
call dword ptr ds:[<__vbaHresultCheckObj>]
push esi
call dword ptr ss:[ebp-C4]
lea edx,dword ptr ss:[ebp-28]
push eax
push edx
call dword ptr ds:[<__vbaObjSet>]
mov ebx,eax
lea ecx,dword ptr ss:[ebp-1C]
push ecx
push ebx
mov eax,dword ptr ds:[ebx]
call dword ptr ds:[eax+A0]
cmp eax,edi
jge afkayas.1.402409
push A0
push afkayas.1.401B5C
push ebx
push eax
call dword ptr ds:[<__vbaHresultCheckObj>]
mov edx,dword ptr ss:[ebp-B0]
mov eax,dword ptr ss:[ebp-1C]
push eax
mov ebx,dword ptr ds:[edx]
call dword ptr ds:[<__vbaLenBstr>]
mov edi,eax
mov ecx,dword ptr ss:[ebp-18]
imul edi,edi,17CFB ;賬號長度乘以0x17cfb
push ecx
jo afkayas.1.4026BE
call dword ptr ds:[<Ordinal#516>] ;獲取輸入賬號字符串首字符ASCII值
movsx edx,ax
add edi,edx ;相加生成字符串 比如 390173
jo afkayas.1.4026BE
push edi
call dword ptr ds:[<__vbaStrI4>]
mov edx,eax
lea ecx,dword ptr ss:[ebp-20]
call dword ptr ds:[<__vbaStrMove>]
vbastrcat函數將AKA-和后邊字符串例如390173拼接在一起從而得到序列號:
AKA-390173
以上序列號是輸入賬號1111得到的,至此算法破解
2.注冊機實現
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main()
{char username[50] = {0};char serial[100] = {0};printf("Enter Username: ");scanf("%s", username);//賬號長度自由發揮if(strlen(username) < 4) {printf("Error: Username must be at least 4 characters!\n");// 添加暫停printf("Press Enter to exit...");getchar(); // 清除輸入緩沖區殘留的換行符getchar(); // 等待用戶按鍵return 1;}int firstChar = username[0];int serialNum = strlen(username) * 0x17CFB + firstChar; //算法賬號長度*固定數+首字符ASCIIsprintf(serial, "AKA-%d", serialNum);printf("Your Serial: %s\n", serial);// 添加暫停printf("Press Enter to exit...");getchar(); // 清除輸入緩沖區殘留的換行符getchar(); // 等待用戶按鍵return 0;
}
//gcc -0 cm.exe cm.c
3.驗證注冊機
如果你覺得本教程對你有幫助,請點贊??、收藏?、關注支持!歡迎在評論區留言交流技術細節!