Like Share Discussion Bookmark Smile

J.J. Huang   2019-07-31   x64dbg   瀏覽次數:

x64dbg - 第十一章 | 反匯編練習(二) 下

前置作業

這篇延續上兩篇文章,所以請先行觀看x64dbg - 第九章 | 反匯編練習(二) 上x64dbg - 第十章 | 反匯編練習(二) 中

  • 重點:00401340,該函數是計算序列號的地方。
  • 重點:比較的時候是使用ebpeax比較,而ebp為程式計算出來的eax為使用者輸入的。
    1
    2
    3
    0040138D | 55                       | push ebp                                    | ebp:"5075"
    0040138E | 50 | push eax | eax:"12345678"
    0040138F | FF15 04404000 | call dword ptr ds:[<&lstrcmpA>] |

任務目標

  • 找出計算序列號的邏輯。

實際分析

  • 開啟TraceMe.exe

  • 在命令區塊輸入bp 00401340,並按Enter (狀態:已於 00401340 設置中斷點!)

  • F9執行程式

  • 輸入用戶名abcdefg和序列號12345678,並按下Check

  • 斷點在00401340 | 55 | push ebp |

  • F8一步一步過,並持續觀察

  • 第一段分析

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    00401340 | 55                       | push ebp                                    |
    00401341 | 8B6C24 0C | mov ebp,dword ptr ss:[esp+C] |
    00401345 | 56 | push esi |
    00401346 | 57 | push edi |
    00401347 | 8B7C24 18 | mov edi,dword ptr ss:[esp+18] |
    0040134B | B9 03000000 | mov ecx,3 |
    00401350 | 33F6 | xor esi,esi |
    00401352 | 33C0 | xor eax,eax |
    00401354 | 3BF9 | cmp edi,ecx |
    00401356 | 7E 21 | jle traceme.401379 |
  • 該段分析是表示輸入的用戶名長度與3做比較

    註:所以一開始才會有用戶名長度必須大於四個

  • F8繼續步過,並持續觀察

  • 第二段分析

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    // 反匯編視窗:主要計算序列號的核心
    00401358 | 53 | push ebx |
    00401359 | 83F8 07 | cmp eax,7 |
    0040135C | 7E 02 | jle traceme.401360 |
    0040135E | 33C0 | xor eax,eax |
    00401360 | 33D2 | xor edx,edx | edx:"abcdefg"
    00401362 | 33DB | xor ebx,ebx |
    00401364 | 8A1429 | mov dl,byte ptr ds:[ecx+ebp] |
    00401367 | 8A98 30504000 | mov bl,byte ptr ds:[eax+405030] |
    0040136D | 0FAFD3 | imul edx,ebx | edx:"abcdefg"
    00401370 | 03F2 | add esi,edx | edx:"abcdefg"
    00401372 | 41 | inc ecx |
    00401373 | 40 | inc eax |
    00401374 | 3BCF | cmp ecx,edi |
    00401376 | 7C E1 | jl traceme.401359 |

    // 暫存器視窗:以下為尚未進入計算核心的一個暫存器狀態
    EAX : 00000000
    EBX : 00000007
    ECX : 00000003
    EDX : 0018F6D8 "abcdefg"
    EBP : 0018F6D8 "abcdefg"
    ESP : 0018F66C
    ESI : 00000000
    EDI : 00000007
    EIP : 00401359 traceme.00401359

    // 資料視窗:`00405030`記憶體的值
    00405030 0C 0A 13 09 0C 0B 0A 08 D0 F2 C1 D0 BA C5 B4 ED \f\n\t\f\v\n序列号错
  • mov dl,byte ptr ds:[ecx+ebp] 表示抓取用戶名第ecx偏移量的值

    • 所以EDX會是00000064
  • mov bl,byte ptr ds:[eax+405030] 表示抓取00405030的第eax偏移量的值

    • 所以EBX會是0000000C
  • imul edx,ebx 表示兩值相乘

    • 000000640000000C等於000004B0
    • 所以EDX會是000004B0
  • add esi,edx 表示兩值相加

    • 所以ESI會是000004B0
  • inc ecx 表示ECX++

    • 所以ECX會是00000004
  • inc eax 表示EAX++

    • 所以EAX會是00000001
  • cmp ecx,edi 表示兩值比較

    • 因為不同,所以SF = 1、OF = 0
  • jl traceme.401359 表示若低於則跳轉

    • 00000004 < 00000007 所以跳轉到00401359
1
2
3
4
5
6
7
8
9
10
11
12
13
// 暫存器視窗:第一次計算後狀態
EAX : 00000001
EBX : 0000000C
ECX : 00000004
EDX : 000004B0 L'Ұ'
EBP : 0018F6D8 "abcdefg"
ESP : 0018F66C
ESI : 000004B0 L'Ұ'
EDI : 00000007
EIP : 00401359 traceme.00401359

// 資料視窗:`00405030`記憶體的值
00405030 0C 0A 13 09 0C 0B 0A 08 D0 F2 C1 D0 BA C5 B4 ED \f\n\t\f\v\n序列号错
  • 上面已經針對每一行指令去做說明,經過運算過後最終會得到ebp的序列號
  • 至於會迴圈幾次取決於輸入的用戶名長度

分析總結

  • 根據輸入的用戶名,從第四個字元開始做序列號的計算
  • 序列號的計算是透過00405030記憶體中0C 0A 13 09 0C 0B 0A 08 \f\n\t\f值來做乘法、相加的計算

額外補充

  • [ ]包起來的記憶體位址,表示會取該位址裡面的
    • 例:mov edi,dword ptr ss:[0018F6D8],會將0018F6D8裡面的值存到EDI裡面

  • mov dl,byte ptr ds:[ecx+ebp]如何知道他是修改EDX暫存器的?
  • mov bl,byte ptr ds:[eax+405030]如何知道他是修改EBX暫存器的?
    • 請參考下圖;dl表示8-bitEDX
    • 請參考下圖;bl表示8-bitEBX


  • C/C++資料長度
    • BYTE = 8 BIT
    • CHAR = 1 BYTE
    • INT = 4 BYTE
    • DOUBLE = 8 BYTE
    • LONG = 4 BYTE
    • SHORT = 2 BYTE
    • WORD = 2 BYTE
    • DWORD = 4 BYTE = 32 BIT

  • mov dl,byte ptr ds:[ecx+ebp]為何只有儲存64EDXds表示什麼?
  • mov bl,byte ptr ds:[eax+405030]為何只有儲存0CEBXds表示什麼?
    • byte定義了儲存的容器大小,所以假設ecx:00000003ebp:0018F6D8相加後0x18F6DB,而0x18F6DB中的值為64
    • 請參考下圖;ds表示資料區段暫存器


經驗分享

  • 計算記憶位址的四則運算,可以用x64dbg提供的計算機做運算
    • 00000003+0018F6D8 或是 00000064*0000000C

  • 每次在看會異動暫存器的指令時,往往無法第一時間知道來源暫存器和會被異動的暫存器哪個;其實只要注意暫存器視窗的標示即可。
  • 請參考下圖,當滑鼠點擊到mov dl,byte ptr ds:[ecx+ebp],然後注意右邊的暫存器視窗。
    • ECXEBP有綠色底線,表示來源
    • EDX有紅色底線,表示會被異動的暫存器

  • 請參考下圖,當滑鼠點擊到imul edx,ebx,然後注意右邊的暫存器視窗。
    • EBX有綠色底線,表示來源
    • EDX有咖啡色底線,表示儲存的暫存器


註:以上參考了
x64dbg
x64dbg’s documentation!
CSDN billvsme的专栏OllyDbg 使用笔记 (二)