韓夢飛沙 韓亞飛 313134555@qq.com yue31313 han_meng_fei_sha
逆向 黑客 破解 學習 論壇
http://bbs.pediy.com/thread-218199.htm
[原創][原創]看雪CTF2017第一題分析-『CrackMe』-看雪安全論壇
IDA
交互式反匯編器專業版(Interactive Disassembler Professional),人們常稱其為IDA Pro,或簡稱為IDA,是總部位於比利時列日市(Liège)的Hex-Rayd公司的一款產品。開發IDA的是一位編程天才,名叫Ilfak Guilfanov。十年前誕生時,IDA還是一個基於控制台的MS-DOS應用程序,這一點很重要,因為它有助於我們理解IDA用戶界面的本質。除其他內容外,IDA的非Windows和非GUI版本仍然繼續采用源於最初DOS版本的控制台形式的界面。
就其本質而言,IDA是一種遞歸下降反匯編器。但是,為了提高遞歸下降過程的效率,IDA的開發者付出了巨大的努力,來為這個過程開發邏輯。為了克服遞歸下降的一個最大的缺點,IDA在區分數據與代碼的同時,還設法確定這些數據的類型。雖然你在IDA中看到的是匯編語言形式的代碼,但IDA的主要目標之一,在於呈現盡可能接近源代碼的代碼。此外,IDA不僅使用數據類型信息,而且通過派生的變量和函數名稱來盡其所能地注釋生成的反匯編代碼。這些注釋將原始十六進制代碼的數量減到最少,並顯著增加了向用戶提供的符號化信息的數量。 IDA PRO簡稱IDA(Interactive Disassembler) ,是一個世界頂級的交互式反匯編工具,有兩種可用版本。標准版(Standard)支持二十多種處理器。高級版(Advanced)支持50多種處理器。
=====
一道普通的CrackMe,Windows 32位程序,無殼、無VM、無密碼學的三無CrackMe,祝大家六一laugh Out Loud。
由於嚴重多解,聯系作者限制了一下多解(原來的提交仍有效),歡迎大家積極參加。
請提交分析文章(writeup)至:http://bbs.pediy.com/thread-create-122.htm
文件地址:
========
找到文本輸入點
輸入“123456”可以看到“error!”的錯誤提示。

在OD中正好可以查找到“error!”字符串。

定位到調用“Messagebox”函數的位置。
上推到“GetDlgItemTextA”函數即為文本輸入點。
2、分析數據處理過程
由文本輸入點往下跟蹤輸入文本的處理,大概如下:
首先判斷輸入文本長度是否為“0x4”,若不是則跳轉到錯誤提示。 cmp 就是比較的意思。 jnz 是 如果不相等 跳轉到。
其次判斷每個字符ASCII碼是否為“0x30”(48)即數字0,若是則跳轉到錯誤提示,之后判斷第一二個字符是否分別為“0x31”(49)和“0x35”(53)即數字1和5,若不是則跳轉到錯誤提示。
je是 如果相等,跳轉到。 綠色字符 是變量。 白色 是 一個跳轉地址。 黃色是 某種方法。 深藍色 是 棧的進出,push是進棧,pop是出棧。 褐色 是 常量。
然后對四個字符進行計算,將第三四個字符表示為x和y,同時將16進制數字轉換為10進制,則過程得到的結果為[(x-48)-(49-48)/(53-48)]*(y-48)*16
1C,1B,1A,19 是1到4位的對應號。 f開頭是 浮點數。 mul 是乘以。 fild是將整數轉化為長雙精FP80壓棧。fidiv 浮點除整數。fimul浮點乘整數。fmul浮點乘。fstp浮點保存出棧。
可以百度查 匯編指令。 mov 傳送,movsx符號傳送。sub 減。

最后與ds:[0x407118]中的常數384比較,若相同則彈出“Registration successful!”的正確提示。
3、解出注冊碼
根據計算過程求出方程:
[(x-48)-(49-48)/(53-48)]*(y-48)*16=384
x和y在可輸入ASCII碼范圍內的整數解即可,則可如下求解
|
1
2
3
4
5
6
7
|
for
i
in
range
(
126
):
for
j
in
range
(
126
):
if
(((i
-
48
)
-
0.2
)
*
(j
-
48
)
=
=
24
):
print
(i)
print
(j)
print
(
"15"
+
"%s"
%
(
chr
(i))
+
"%s"
%
(
chr
(j)))
print
(
"------"
)
|
解得:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
47
28
15
/
-
-
-
-
49
78
151N
-
-
-
-
53
53
1555
-
-
-
-
|
其中第一個的ASCII碼”28“為文件分割符,注冊碼則為“151N”和“1555”。
==========
| 使用環境 |
備注 |
|
| 操作系統 |
Windows xp |
簡體中文版 |
| 虛擬機 |
VMware Workstation |
版本號:12.1.1 build |
| 調試器 |
Immunity Debugger |
版本號:V1.73 |
| 調試器 |
IDA |
版本號:V6.5.140116 |
0x02 分析調試過程
用ImmunityDebugger打開WannaLOL2.exe,F9執行,經過幾次試探輸入,初步定位0x00401494處的CALL WannaLOL.00401096為調用驗證序列號的主函數,在此按F2下斷點。

再次運行,按F9運行到斷點處,按F7單步進入00401096函數。在獲取輸入對話框內容的GetDlgItemTextA函數處下斷點。再次運行,輸入試探序列號后,程序執行到0x0040120B。

通過分析和調試得知,WannaLOL.00401300函數返回輸入序列號的長度。
通過IDA靜態分析,以下代碼為確定序列號長度及特殊要求的關鍵代碼:
.text:00401225 cmp eax, 4
.text:00401228 pop ecx
.text:00401229 jnz loc_4012CF
.text:0040122F push 30h
.text:00401231 pop ecx
.text:00401232 cmp [ebp-1Ch], cl
.text:00401235 jz loc_4012CF
.text:0040123B cmp [ebp-1Bh], cl
.text:0040123E jz loc_4012CF
.text:00401244 cmp [ebp-1Ah], cl
.text:00401247 jz loc_4012CF
.text:0040124D cmp [ebp-19h], cl
.text:00401250 jz short loc_4012CF
.text:00401252 cmp byte ptr [ebp-1Ch], 31h
.text:00401256 jnz short loc_4012CF
.text:00401258 cmp byte ptr [ebp-1Bh], 35h
.text:0040125C jnz short loc_4012CF
.text:0040125E jz short near ptr loc_401262+1
.text:00401260 jnz short near ptr loc_401262+1
通過調試和分析得知,序列號長度為4位,不能包含0,第一位必須為1,第二位必須為5,即15s(3)s(4)( s(n)為序列號第n位,s(3)!=0, s(4)!=0)。緊接下來的代碼為浮點運算代碼:
.text:00401267 xor ax, 7
.text:0040126B movsx eax, byte ptr [ebp-1Ah]
.text:0040126F sub eax, ecx
.text:00401271 mov [ebp-4], eax
.text:00401274 movsx eax, byte ptr [ebp-1Ch]
.text:00401278 fild dword ptr [ebp-4]
.text:0040127B sub eax, ecx
.text:0040127D mov [ebp-4], eax
.text:00401280 movsx eax, byte ptr [ebp-1Bh]
.text:00401284 fild dword ptr [ebp-4]
.text:00401287 sub eax, ecx
.text:00401289 mov [ebp-4], eax
.text:0040128C fidiv dword ptr [ebp-4]
.text:0040128F movsx eax, byte ptr [ebp-19h]
.text:00401293 sub eax, ecx
.text:00401295 mov [ebp-4], eax
.text:00401298 fsubp st(1), st
.text:0040129A fimul dword ptr [ebp-4]
.text:0040129D fmul ds:flt_40711C
.text:004012A3 fstp dword ptr [ebp-4]
.text:004012A6 jz short near ptr loc_4012AA+1
.text:004012A8 jnz short near ptr loc_4012AA+1
.text:004012AA call near ptr 48CB15h
.text:004012AF xor ax, 7
.text:004012B3 fld dword ptr [ebp-4]
.text:004012B6 fcomp ds:flt_407118
.text:004012BC push 0
.text:004012BE push offset aCrackme2017Ctf ;
.text:004012C3 fnstsw ax
.text:004012C5 sahf
.text:004012C6 jnz short loc_4012D6
.text:004012C8 push offset aRegistrationSu ;
.text:004012CD jmp short loc_4012DB
通過分析調試得出,浮點運算過程為序列號的第三位減去第一位和第二位的商,得到的減法結果再乘以第四位,最后再乘以DS:[0040711C]內存處的值0x41800000(十進制數字16的浮點表示法),以上乘法結果再與DS:[00407118]內存處的值0x43C00000(十進制數字384的浮點表示法)進行比較,如果相等則序列號正確,否則錯誤。


浮點運算過程
用數學公式表示為(s(3)-s(1)/s(2))*s(4)*16=384,即:
(s(3)-0.2)* s(4)=24
推算出:s(3)=5,s(4)=5,即序列號為1555
輸入序列號1555,運行結果為:

=========
| 指令 | 功能 |
|---|---|
| AAA | 調整加 |
| AAD | 調整除 |
| AAM | 調整乘 |
| AAS | 調整減 |
| ADC | 進位加 |
| ADD | 加 |
| AND | 與 |
| ARPL | 調整優先級 |
| BOUND | 檢查數組 |
| BSF | 位右掃描 |
| BSR | 位左掃描 |
| BSWAP | 交換字節 |
| BT | 位測試 |
| BTC | 位測試求反 |
| BTR | 位測試清零 |
| BTS | 位測試置一 |
| CALL | 過程調用 |
| CBW | 轉換字節 |
| CDQ | 轉換雙字 |
| CLC | 進位清零 |
| CLD | 方向清零 |
| CLI | 中斷清零 |
| CLTS | 任務清除 |
| CMC | 進位求反 |
| CMOVA | 高於傳送 |
| CMOVB | 低於傳送 |
| CMOVE | 相等傳送 |
| CMOVG | 大於傳送 |
| CMOVL | 小於傳送 |
| CMOVNA | 不高於傳送 |
| CMOVNB | 不低於傳送 |
| CMOVNE | 不等傳送 |
| CMOVNG | 不大於傳送 |
| CMOVNL | 不小於傳送 |
| CMOVNO | 不溢出傳送 |
| CMOVNP | 非奇偶傳送 |
| CMOVNS | 非負傳送 |
| CMOVO | 溢出傳送 |
| CMOVP | 奇偶傳送 |
| CMOVS | 負號傳送 |
| CMP | 比較 |
| CMPSB | 比較字節串 |
| CMPSD | 比較雙字串 |
| CMPSW | 比較字串 |
| CMPXCHG | 比較交換 |
| CMPXCHG486 | 比較交換486 |
| CMPXCHG8B | 比較交換8字節 |
| CPUID | CPU標識 |
| CWD | 轉換字 |
| CWDE | 擴展字 |
| DAA | 調整加十 |
| DAS | 調整減十 |
| DEC | 減一 |
| DIV | 除 |
| ENTER | 建立堆棧幀 |
| HLT | 停 |
| IDIV | 符號整除 |
| IMUL | 符號乘法 |
| IN | 端口輸入 |
| INC | 加一 |
| INSB | 端口輸入字節串 |
| INSD | 端口輸入雙字串 |
| INSW | 端口輸入字串 |
| JA | 高於跳轉 |
| JB | 低於跳轉 |
| JBE | 不高於跳轉 |
| JCXZ | 計數一六零跳轉 |
| JE | 相等跳轉 |
| JECXZ | 計數三二零跳轉 |
| JG | 大於跳轉 |
| JL | 小於跳轉 |
| JMP | 跳轉 |
| JMPE | 跳轉擴展 |
| JNB | 不低於跳轉 |
| JNE | 不等跳轉 |
| JNG | 不大於跳轉 |
| JNL | 不小於跳轉 |
| JNO | 不溢出跳轉 |
| JNP | 非奇偶跳轉 |
| JNS | 非負跳轉 |
| JO | 溢出跳轉 |
| JP | 奇偶跳轉 |
| JS | 負號跳轉 |
| LAHF | 加載標志低八 |
| LAR | 加載訪問權限 |
| LDS | 加載數據段 |
| LEA | 加載有效地址 |
| LEAVE | 清除過程堆棧 |
| LES | 加載附加段 |
| LFS | 加載標志段 |
| LGDT | 加載全局描述符 |
| LGS | 加載全局段 |
| LIDT | 加載中斷描述符 |
| LMSW | 加載狀態字 |
| LOADALL | 加載所有 |
| LOADALL286 | 加載所有286 |
| LOCK | 鎖 |
| LODSB | 加載源變址字節串 |
| LODSD | 加載源變址雙字串 |
| LODSW | 加載源變址字串 |
| LOOP | 計數循環 |
| LOOPE | 相等循環 |
| LOOPNE | 不等循環 |
| LOOPNZ | 非零循環 |
| LOOPZ | 為零循環 |
| LSL | 加載段界限 |
| LSS | 加載堆棧段 |
| LTR | 加載任務 |
| MONITOR | 監視 |
| MOV | 傳送 |
| MOVSB | 傳送字節串 |
| MOVSD | 傳送雙字串 |
| MOVSW | 傳送字串 |
| MOVSX | 符號傳送 |
| MOVZX | 零傳送 |
| MUL | 乘 |
| MWAIT | |
| NEG | 求補 |
| NOP | 空 |
| NOT | 非 |
| OR | 或 |
| OUT | 端口輸出 |
| OUTSB | 端口輸出字節串 |
| OUTSD | 端口輸出雙字串 |
| OUTSW | 端口輸出字串 |
| POP | 出棧 |
| POPA | 全部出棧 |
| POPF | 標志出棧 |
| PUSH | 壓棧 |
| PUSHA | 全部壓棧 |
| PUSHF | 標志壓棧 |
| RCL | 進位循環左移 |
| RCR | 進位循環右移 |
| RDMSR | 讀專用模式 |
| RDPMC | 讀執行監視計數 |
| RDSHR | |
| RDTSC | 讀時間戳計數 |
| REP | 重復 |
| REPE | 相等重復 |
| REPNE | 不等重復 |
| RET | 過程返回 |
| RETF | 遠過程返回 |
| RETN | 近過程返回 |
| ROL | 循環左移 |
| ROR | 循環右移 |
| RSM | 恢復系統管理 |
| SAHF | 恢復標志低八 |
| SAL | 算術左移 |
| SALC | |
| SAR | 算術右移 |
| SBB | 借位減 |
| SCASB | 掃描字節串 |
| SCASD | 掃描雙字串 |
| SCASW | 掃描字串 |
| SETA | 高於置位 |
| SETB | 低於置位 |
| SETE | 相等置位 |
| SETG | 大於置位 |
| SETL | 小於置位 |
| SETNA | 不高於置位 |
| SETNB | 不低於置位 |
| SETNE | 不等置位 |
| SETNG | 不大於置位 |
| SETNL | 不小於置位 |
| SETNO | 不溢出置位 |
| SETNP | 非奇偶置位 |
| SETNS | 非負置位 |
| SETO | 溢出置位 |
| SETP | 奇偶置位 |
| SETS | 負號置位 |
| SGDT | 保存全局描述符 |
| SHL | 邏輯左移 |
| SHLD | 雙精度左移 |
| SHR | 邏輯右移 |
| SHRD | 雙精度右移 |
| SIDT | 保存中斷描述符 |
| SLDT | 保存局部描述符 |
| SMI | |
| SMINT | |
| SMINTOLD | |
| SMSW | 保存狀態字 |
| STC | 進位設置 |
| STD | 方向設置 |
| STI | 中斷設置 |
| STOSB | 保存字節串 |
| STOSD | 保存雙字串 |
| STOSW | 保存字串 |
| STR | 保存任務 |
| SUB | 減 |
| SYSCALL | 系統調用 |
| SYSENTER | 系統進入 |
| SYSEXIT | 系統退出 |
| SYSRET | 系統返回 |
| TEST | 數測試 |
| UD0 | 未定義指令0 |
| UD1 | 未定義指令1 |
| UD2 | 未定義指令2 |
| UMOV | |
| VERW | 校驗寫 |
| WAIT | 等 |
| WBINVD | 回寫無效高速緩存 |
| WRMSR | 寫專用模式 |
| WRSHR | |
| XADD | 交換加 |
| XBTS | |
| XCHG | 交換 |
| XLAT | 換碼 |
| XOR | 異或 |
| XSTORE |
| 指令 | 功能 |
|---|---|
| EMMS | 媒體空MMX狀態 |
| F2XM1 | 浮點棧頂絕對值 |
| FADD | 浮點加 |
| FADDP | 浮點加出棧 |
| FBLD | 浮點加載十數 |
| FBSTP | 浮點保存十數出棧 |
| FCHS | 浮點正負求反 |
| FCLEX | 浮點檢查錯誤清除 |
| FCMOVB | 浮點低於傳送 |
| FCMOVBE | 浮點不高於傳送 |
| FCMOVE | 浮點相等傳送 |
| FCMOVNB | 浮點不低於傳送 |
| FCMOVNBE | 浮點高於傳送 |
| FCMOVNE | 浮點不等傳送 |
| FCMOVNU | 浮點有序傳送 |
| FCMOVU | 浮點無序傳送 |
| FCOM | 浮點比較 |
| FCOMI | 浮點比較加載標志 |
| FCOMIP | 浮點比較加載標志出棧 |
| FCOMP | 浮點比較出棧 |
| FCOMPP | 浮點比較出棧二 |
| FCOS | 浮點余弦 |
| FDECSTP | 浮點棧針減一 |
| FDISI | 浮點檢查禁止中斷 |
| FDIV | 浮點除 |
| FDIVP | 浮點除出棧 |
| FDIVR | 浮點反除 |
| FDIVRP | 浮點反除出棧 |
| FENI | 浮點檢查禁止中斷二 |
| FFREE | 浮點釋放 |
| FFREEP | 浮點釋放出棧 |
| FIADD | 浮點加整數 |
| FICOM | 浮點比較整數 |
| FICOMP | 浮點比較整數出棧 |
| FIDIV | 浮點除整數 |
| FIDIVR | 浮點反除 |
| FILD | 浮點加載整數 |
| FIMUL | 浮點乘整數 |
| FINCSTP | 浮點棧針加一 |
| FINIT | 浮點檢查初始化 |
| FIST | 浮點保存整數 |
| FISTP | 浮點保存整數出棧 |
| FISTTP | |
| FISUB | 浮點減整數 |
| FISUBR | 浮點反減整數 |
| FLD | 浮點加載數 |
| FLD1 | 浮點加載一 |
| FLDCW | 浮點加載控制器 |
| FLDENV | 浮點加載環境 |
| FLDL2E | 浮點加載L2E |
| FLDL2T | 浮點加載L2T |
| FLDLG2 | 浮點加載LG2 |
| FLDLN2 | 浮點加載LN2 |
| FLDPI | 浮點加載PI |
| FLDZ | 浮點加載零 |
| FMUL | 浮點乘 |
| FMULP | 浮點乘出棧 |
| FNCLEX | 浮點不檢查錯誤清除 |
| FNDISI | 浮點不檢查禁止中斷 |
| FNENI | 浮點不檢查禁止中斷二 |
| FNINIT | 浮點不檢查初始化 |
| FNOP | 浮點空 |
| FNSAVE | 浮點不檢查保存狀態 |
| FNSTCW | 浮點不檢查保存控制器 |
| FNSTENV | 浮點不檢查保存環境 |
| FNSTSW | 浮點不檢查保存狀態器 |
| FPATAN | 浮點部分反正切 |
| FPREM | 浮點部分余數 |
| FPREM1 | 浮點部分余數二 |
| FPTAN | 浮點部分正切 |
| FRNDINT | 浮點舍入求整 |
| FRSTOR | 浮點恢復狀態 |
| FSAVE | 浮點檢查保存狀態 |
| FSCALE | 浮點比例運算 |
| FSETPM | 浮點設置保護 |
| FSIN | 浮點正弦 |
| FSINCOS | 浮點正余弦 |
| FSQRT | 浮點平方根 |
| FST | 浮點保存 |
| FSTCW | 浮點檢查保存控制器 |
| FSTENV | 浮點檢查保存環境 |
| FSTP | 浮點保存出棧 |
| FSTSW | 浮點檢查保存狀態器 |
| FSUB | 浮點減 |
| FSUBP | 浮點減出棧 |
| FSUBR | 浮點反減 |
| FSUBRP | 浮點反減出棧 |
| FTST | 浮點比零 |
| FUCOM | 浮點無序比較 |
| FUCOMI | 浮點反比加載標志 |
| FUCOMIP | 浮點反比加載標志出棧 |
| FUCOMP | 浮點無序比較出棧 |
| FUCOMPP | 浮點無序比較出棧二 |
| FWAIT | 浮點等 |
| FXAM | 浮點檢查 |
| FXCH | 浮點交換 |
| FXTRACT | 浮點分解 |
| FYL2X | 浮點求L2X |
| FYL2XP1 | 浮點求L2XP1 |
| MOVED | 媒體雙字傳送 |
| MOVEQ | 媒體四字傳送 |
| PACKSSDW | 媒體符號雙字壓縮 |
| PACKSSWB | 媒體符號字壓縮 |
| PACKUSWB | 媒體無符號字壓縮 |
| PADDB | 媒體截斷字節加 |
| PADDD | 媒體截斷雙字加 |
| PADDSB | 媒體符號飽和字節加 |
| PADDSIW | |
| PADDSW | 媒體符號飽和字加 |
| PADDUSB | 媒體無符號飽和字節加 |
| PADDUSW | 媒體無符號飽和字加 |
| PADDW | 媒體截斷字加 |
| PAND | 媒體與 |
| PANDN | 媒體與非 |
| PAVEB | |
| PCMPEQB | 媒體字節比等 |
| PCMPEQD | 媒體雙字比等 |
| PCMPEQW | 媒體字比等 |
| PCMPGTB | 媒體字節比大 |
| PCMPGTD | 媒體雙字比大 |
| PCMPGTW | 媒體字比大 |
| PDISTIB | |
| PMACHRIW | |
| PMADDWD | |
| PMAGW | |
| PMULHRIW | |
| PMULHRWC | |
| PMULHW | |
| PMVGEZB | |
| PMVLZB | |
| PMVNZB | |
| PMVZB | |
| POR | 媒體或 |
| PSLLD | 媒體雙字左移 |
| PSLLQ | 媒體四字左移 |
| PSLLW | 媒體字左移 |
| PSRAD | 媒體雙字算術右移 |
| PSRAW | 媒體字算術右移 |
| PSRLD | 媒體雙字右移 |
| PSRLQ | 媒體四字右移 |
| PSRLW | 媒體字右移 |
| PSUBB | 媒體截斷字節減 |
| PSUBSB | 媒體符號飽和字節減 |
| PSUBSIW | |
| PSUBSW | 媒體符號飽和字減 |
| PSUBUSB | 媒體無符號飽和字節減 |
| PSUBUSW | 媒體無符號飽和字減 |
| PSUBW | 媒體截斷字減 |
| PUNPCKHBW | 媒體字節高位解壓 |
| PUNPCKHDQ | 媒體雙字高位解壓 |
| PUNPCKHWD | 媒體字高位解壓 |
| PUNPCKLBW | 媒體字節低位解壓 |
| PUNPCKLDQ | 媒體雙字低位解壓 |
| PUNPCKLWD | 媒體字低位解壓 |



