x64dbg - 第十三章 | 反匯編練習(三) 下
前置作業
這篇延續上一篇文章,所以請先行觀看x64dbg - 第十二章 | 反匯編練習(三) 上
- 重點:
0040106E | 68 79204000 | push reverseme.402079 | 402079:"Keyfile.dat"
- 重點:可以發現這一大段在做驗證,失敗則跳轉至
004010F7
成功則跳轉至00401205
。
任務目標
- 找出正確的驗證機制並驗證通過。
實際分析
開啟
reverseMe.exe
F8
一步一步過,並持續觀察步過到下方指令時
1
2
3
4
5
6
7
8
9
100040105C | 6A 00 | push 0 |
0040105E | 68 6F214000 | push reverseme.40216F |
00401063 | 6A 03 | push 3 |
00401065 | 6A 00 | push 0 |
00401067 | 6A 03 | push 3 |
00401069 | 68 000000C0 | push C0000000 |
0040106E | 68 79204000 | push reverseme.402079 | 402079:"Keyfile.dat"
00401073 | E8 0B020000 | call <JMP.&CreateFileA> |
00401078 | 83F8 FF | cmp eax,FFFFFFFF |
0040107B | 75 1D | jne reverseme.40109A |總共傳入七個參數
調用了
CreateFileA
,回傳的eax=FFFFFFFF
00401063 | 6A 03 | push 3 |
是該函數的第五個參數
(3 = OPEN_EXISTING
,表示僅在文件或設備存在時打開它;如果指定的文件或設備不存在,則該函數將失敗)註:函數:CreateFileA
cmp eax,FFFFFFFF
未實現jne reverseme.40109A
跳轉在此可以確認,程式開啟時會需要打開名為
Keyfile.dat
的檔案
在
reverseMe.exe
相同目錄下建立Keyfile.dat
的檔案回到
x64dbg
Ctrl + F2
重新啟動(S)F8
一步一步過,並持續觀察會發現
jne reverseme.40109A
跳轉實現F8
繼續步過,並持續觀察步過到下方指令時
1
2
3
4
5
6
7
8
90040109A | 6A 00 | push 0 |
0040109C | 68 73214000 | push reverseme.402173 |
004010A1 | 6A 46 | push 46 |
004010A3 | 68 1A214000 | push reverseme.40211A |
004010A8 | 50 | push eax |
004010A9 | E8 2F020000 | call <JMP.&ReadFile> |
004010AE | 85C0 | test eax,eax |
004010B0 | 75 02 | jne reverseme.4010B4 |
004010B2 | EB 43 | jmp reverseme.4010F7 |總共傳入五個參數
調用了
ReadFile
,回傳的eax=00000001
0040109C | 68 73214000 | push reverseme.402173 |
是該函數的第四個參數
(指向變量的指針,該變量接收使用同步hFile
參數時讀取的字節數。)004010A3 | 68 1A214000 | push reverseme.40211A |
是該函數的第二個參數
(指向緩衝區的指針,該緩衝區接收從文件或設備讀取的資料。)註:函數:ReadFile
test eax,eax
測試EAX
暫存器是否為空,用於確認讀取檔案沒有異常。在此可以知道
402173
存放讀取到的文字長度,40211A
存放讀取到的文字內容F8
繼續步過,並持續觀察步過到下方指令時
1
2
3
4004010B4 | 33DB | xor ebx,ebx |
004010B6 | 33F6 | xor esi,esi |
004010B8 | 833D 73214000 10 | cmp dword ptr ds:[402173],10 |
004010BF | 7C 36 | jl reverseme.4010F7 |jl reverseme.4010F7
跳轉實現(jl = 若低於則跳越
),會跳轉到keyfile is not valid. Sorry.
向上觀察
cmp dword ptr ds:[402173],10
,表示抓取讀取到的檔案長度與10
做比較可以知道
Keyfile.dat
的檔案內容,必須要大於等於10
(請注意這邊10
)
編輯
Keyfile.dat
的內容,輸入ABCDEFGHIJ
,總共10個字回到
x64dbg
Ctrl + F2
重新啟動(S)移除所有中斷點
004010B8
設定中斷點F9
執行程式jl reverseme.4010F7
跳轉實現(jl = 若低於則跳越
),會跳轉到keyfile is not valid. Sorry.
為什麼?
因為
cmp dword ptr ds:[402173],10
比較的10
是十六進制的,所以表示為十進制的16
這邊可以確認
Keyfile.dat
的檔案內容,必須要大於等於16
個字
編輯
Keyfile.dat
的內容,輸入ABCDEFGHIJKLMNOP
,總共16個字回到
x64dbg
Ctrl + F2
重新啟動(S)F9
執行程式jl reverseme.4010F7
跳轉未實現,不會跳轉到keyfile is not valid. Sorry.
F8
一步一步過,並持續觀察步過到下方指令時
1
2
3
4
5
6
7
8
9
10
11004010C1 | 8A83 1A214000 | mov al,byte ptr ds:[ebx+40211A] |
004010C7 | 3C 00 | cmp al,0 |
004010C9 | 74 08 | je reverseme.4010D3 |
004010CB | 3C 47 | cmp al,47 | 47:'G'
004010CD | 75 01 | jne reverseme.4010D0 |
004010CF | 46 | inc esi |
004010D0 | 43 | inc ebx |
004010D1 | EB EE | jmp reverseme.4010C1 |
004010D3 | 83FE 08 | cmp esi,8 |
004010D6 | 7C 1F | jl reverseme.4010F7 |
004010D8 | E9 28010000 | jmp reverseme.401205 |首次
ebx:00000000
40211A
為存放讀取到的內容ABCDEFGHIJKLMNOP
mov al,byte ptr ds:[ebx+40211A]
表示,取得內容的第一個字元,也就是A
cmp al,0
十六進制的0
表示為空字元(0 = ASCII 的 空字元(Null)
),用取到的字元去做比較- 如實現則跳轉到
4010D3
- 如實現則跳轉到
cmp al,47
十六進制的47
表示為G
(47 = ASCII 的 G
),用取到的字元去做比較- 如實現則不跳轉,繼續執行
inc esi
- 如實現則不跳轉,繼續執行
inc esi
如果讀取的字元為G
則esi + 1
inc ebx
用於取讀取內容的位置ebx + 1
cmp esi,8
比較esi
與8
,jl reverseme.4010F7
條件(jl = 若低於則跳越
)jmp reverseme.401205
跳轉到彈出成功訊息視窗註:ASCII參考
根據上面的指令分析,可以知道會迴圈每個讀取到的字,如字為
G
則esi
暫存器會加1
,讀取到的字元如果為空字元,則跳到cmp esi,8
,如果低於則跳錯誤,所以G
字元要大於等於8個字。
分析總結
- 必須要有
Keyfile.dat
的檔案。 Keyfile.dat
的內容 >= 十六個字。Keyfile.dat
的內容包含G
>= 八個。
實際驗證
Keyfile.dat
檔案
內容 | 總長度 | G計數 | 結果 | 原因 |
---|---|---|---|---|
GGGGGGGGGG | 10 | 10 | 失敗 | 長度不足16 |
AAAAAAAAAAAAAAAA | 16 | 0 | 失敗 | G不足8 |
AAAAAAAAAGGGGGGG | 16 | 7 | 失敗 | G不足8 |
AAAGAAAAAGGGGGGG | 16 | 8 | 成功 | 成功 |
GGGGGGGGGGGGGGG | 15 | 15 | 失敗 | 長度不足16 |
GGGGGGGGGGGGGGGG | 16 | 16 | 成功 | 成功 |
註:以上參考了
x64dbg
x64dbg’s documentation!
CSDN billvsme的专栏 的 OllyDbg 使用笔记 (三)