---
# System prepended metadata

title: The return of Anti Debug

---

# The return of Anti Debug

![](https://i.imgur.com/grmhISm.png)

- Bài này mang tên antidebug vì tác giả chỉ cho chúng ta `source code` assembly và `log` lúc chương trình đang chạy, tiếp đến là file `DUMP` binary : 
    - `CODE.TXT` : chứa code assembly được coppy từ IDA.
    - `file DUMP` : Binary data 
    - `LOG.TXT` : Log lúc chạy chương trình 

- File `LOG.txt`:
    ```
    nguyen@nguyen:~/Desktop/test$ ./a.out 
    Oh no, someone leaked something...
    AE 88 89
    ```
    
- Mình sẽ tiến hành đọc file `CODE.TXT` để rõ hơn, như thường lệ mình bắt đầu từ hàm `main`: 
    ```assembly=
                    public main
    main            proc near               ; DATA XREF: _start+21↑o

    var_BC          = dword ptr -0BCh
    var_B8          = dword ptr -0B8h
    var_B4          = dword ptr -0B4h
    stream          = qword ptr -0B0h
    ptr             = qword ptr -0A8h
    s               = byte ptr -0A0h
    var_50          = byte ptr -50h
    var_8           = qword ptr -8

    ; __unwind {
                    endbr64
                    push    rbp
                    mov     rbp, rsp
                    sub     rsp, 0C0h
                    mov     rax, fs:28h
                    mov     [rbp+var_8], rax
                    xor     eax, eax
                    lea     rsi, modes      ; "r"
                    lea     rdi, aSomethingsecre ; "./somethingSecret.txt"
                    call    _fopen
                    mov     [rbp+stream], rax
                    mov     edi, 4Ch ; 'L'  ; size
                    call    _malloc
                    mov     [rbp+ptr], rax
                    mov     rdx, [rbp+stream]
                    mov     rax, [rbp+ptr]
                    mov     rcx, rdx        ; stream
                    mov     edx, 1          ; n
                    mov     esi, 42h ; 'B'  ; size
                    mov     rdi, rax        ; ptr
                    call    _fread
                    mov     rax, [rbp+stream]
                    mov     rdi, rax        ; stream
                    call    _fclose
                    lea     rdi, s          ; "Oh no, someone leaked something..."
                    call    _put
                    ...
    ```

- Đoạn bên trên chương trình đã open file `somethingSecret.txt` và đọc file này nên chắc chắn file này chứa flag chúng ta cần tìm. Chương trình đọc và lưu vào vùng nhớ tên là `ptr`. Lúc này `ptr` sẽ chứa địa chỉ trỏ tới data đã đọc.
- Tiếp đến chúng ta có thể thấy dòng chữ `Oh no, someone leaked something...`, và tiếp đến là những data bị leak.
    ```assembly=
                    lea     rdi, s          ; "Oh no, someone leaked something..."
                    call    _puts
                    lea     rax, [rbp+s]
                    mov     edx, 42h ; 'B'  ; n
                    mov     esi, 0          ; c
                    mov     rdi, rax        ; s
                    call    _memset
                    lea     rax, [rbp+var_50]
                    mov     edx, 42h ; 'B'  ; n
                    mov     esi, 0          ; c
                    mov     rdi, rax        ; s
                    call    _memset
                    mov     edi, 0          ; timer
                    call    _time
                    mov     edi, eax        ; seed
                    call    _srand
                    mov     [rbp+var_BC], 0
                    jmp     short loc_1657
    ```
- chúng ta thấy chương trình gọi `time(0)` làm seed (`srand`) cho hàm random.
- Tiếp theo

    ```assembly=

                    jmp     short loc_1657
    ; ---------------------------------------------------------------------------

    loc_163A:                               ; CODE XREF: main+F7↓j
                    call    _rand
                    mov     edx, eax
                    mov     eax, [rbp+var_BC]
                    cdqe
                    mov     [rbp+rax+s], dl
                    add     [rbp+var_BC], 1

    loc_1657:                               ; CODE XREF: main+D1↑j
                    cmp     [rbp+var_BC], 41h ; 'A'
                    jle     short loc_163A
                    mov     [rbp+var_B8], 0
                    jmp     short loc_16BD

    ```

- Chương trình gọi hàm `rand` liên tục `65 lần` để sinh số ngẫu nhiên sau đó thì lần lượt cho vào vùng nhớ tên `s` : `mov     [rbp+rax+s], dl`.
- Tiếp theo
    ```assembly=
                    jmp     short loc_16BD
    ; ---------------------------------------------------------------------------

    loc_166C:                               ; CODE XREF: main+15D↓j
                    mov     eax, [rbp+var_B8]
                    movsxd  rdx, eax
                    mov     rax, [rbp+ptr]
                    add     rax, rdx
                    movzx   edx, byte ptr [rax]
                    mov     eax, [rbp+var_B8]
                    cdqe
                    movzx   eax, [rbp+rax+s]
                    xor     eax, edx
                    mov     edx, eax
                    mov     eax, [rbp+var_B8]
                    cdqe
                    movzx   eax, [rbp+rax+s]
                    add     eax, edx
                    mov     edx, eax
                    mov     eax, [rbp+var_B8]
                    cdqe
                    mov     [rbp+rax+var_50], dl
                    add     [rbp+var_B8], 1

    loc_16BD:                               ; CODE XREF: main+103↑j
                    cmp     [rbp+var_B8], 41h ; 'A'
                    jle     short loc_166C
                    mov     [rbp+var_B4], 0
                    jmp     short loc_16FF
    ```

- Đoạn code trên khi về code C sẽ như sau : 
    ```C=
    for(int var_B8=0;var_B8<=0x41;var_B8++){
        var_50[var_B8] = ptr[var_B8]^s[var_B8] + s[var_B8];
    }
    ```
- Vậy là chương trình đã encrypt flag của chúng ta và lưu vào trong stack.
- Tiếp theo 
    ```assembly=
                    mov     [rbp+var_B4], 0
                    jmp     short loc_16FF
    ; ---------------------------------------------------------------------------

    loc_16D2:                               ; CODE XREF: main+19F↓j
                    mov     eax, [rbp+var_B4]
                    cdqe
                    movzx   eax, [rbp+rax+var_50]
                    movsx   eax, al
                    movzx   eax, al
                    mov     esi, eax
                    lea     rdi, format     ; "%02X "
                    mov     eax, 0
                    call    _printf
                    add     [rbp+var_B4], 1

    loc_16FF:                               ; CODE XREF: main+169↑j
                    cmp     [rbp+var_B4], 2
                    jle     short loc_16D2
                    mov     edi, 0Ah        ; c
                    call    _putchar
                    mov     eax, 0
                    call    sus
                    mov     eax, 0
                    mov     rcx, [rbp+var_8]
                    xor     rcx, fs:28h
                    jz      short locret_1735
                    call    ___stack_chk_fail
    ; ---------------------------------------------------------------------------

    locret_1735:                            ; CODE XREF: main+1C7↑j
                    leave
                    retn
    ; } // starts at 1567
    main            endp

    ```


- Vậy là chương trình đã in ra 3 byte của cipher ở trong stack và sau đó thì gọi đến hàm `sus` của (`call sus`).
- Phân tích hàm sus thì giống hệt đoạn dump stack trong hint write up của tác giả đã hint. Vậy là luồng của bài này yêu cầu chúng ta phải tìm được những `cipher` có trong stack (file `DUMP` chính là stack) và đồng thời để giải được flag chúng ta phải tìm được cả dãy byte `random`.
- Chúng ta thử tìm dãy byte mà chương trình đã leak bằng vòng for đơn giản : 
```python=
sample = bytes.fromhex("AE 88 89")
dump = open("dump","rb").read()
cipher  = b""
for i in range(len(dump)):
    if dump[i:(i+3)] in sample:
        print(f"Found Cipher in offset: {hex(i)}")
        cipher = dump[i:(i+0x42)]
```
 - Chạy thử : 
    ```powershell 
    Found Cipher in offset: 0x1f330
    cipher: b'\xae\x88\x89n\x97_l\x8d\x95\x8a\x9f\x92\x81\x9f\x8b\x89\x8f\x9fh\x95\x8d_v\x9dy_\x98\x85\x86_\x8dou_{n\x91\x90r\x9f\x8c\x99\x9fb\x85m_zu\x95\x9b_c\x89q\x9f\x88vyp\x92\x9f~\x89\x99\x90'
    ```
- Vậy là cipher ở offset `0x1f330` trong file `DUMP`.
- Còn lại chúng ta cần tìm dãy `random` đã được sinh ra để `encrypt`.
- Kéo lên trên hàm `main` một chút chúng ta có thể thấy: 
    ```assembly=

    ; int __cdecl main(int argc, const char **argv, const char **envp)
                    public main
    main            proc near               ; DATA XREF: _start+21↑o

    var_BC          = dword ptr -0BCh
    var_B8          = dword ptr -0B8h
    var_B4          = dword ptr -0B4h
    stream          = qword ptr -0B0h
    ptr             = qword ptr -0A8h
    s               = byte ptr -0A0h
    var_50          = byte ptr -50h
    var_8           = qword ptr -8
    ```
- `var_50` (địa chỉ của cipher) và `s` (chuỗi random), cách nhau là`0xA0-0x50=0x50` byte.
- Vậy từ base của cipher chúng ta trừ đi `0x50` là chúng ta sẽ tới được địa chỉ của chuỗi `random`.
- Update:
```python= 
sample = bytes.fromhex("AE 88 89")
dump = open("dump","rb").read()
cipher  = b""
rand = b""
for i in range(len(dump)):
    if dump[i:(i+3)] in sample:
        print(f"Found Cipher in offset: {hex(i)}")
        cipher = dump[i:(i+0x42)]
        rand = dump[(i-80):(i-80+0x42)]
```
- Đến đây chúng ta chỉ việc làm ngược lại so với công thức encrypt là ra được flag.
- Script của mình : 
    ```python=
    sample = bytes.fromhex("AE 88 89")
    dump = open("dump","rb").read()
    cipher  = b""
    rand = b""
    for i in range(len(dump)):
        if dump[i:(i+3)] in sample:
            print(f"Found Cipher in offset: {hex(i)}")
            cipher = dump[i:(i+0x42)]
            rand = dump[(i-80):(i-80+0x42)]

    print(f"rand: {rand}")
    print(f"cipher: {cipher}")
    print(f"secret: ",end="")
    for i in range(0x42):
        """cipher = input^rand + rand"""
        tmp = (cipher[i]-rand[i])^rand[i]
        tmp &= 0xff
        print(chr(tmp),end="")
    print("\nDone")


    ```

- Kết quả : 

```powershell= 
Found Cipher in offset: 0x1f330
rand: b'\xbaX\x8f(|\x1c\x05:X\xab\xf8\xb7\xe4jz\xf2\x1b\xa8\x86Z{\xc6m\x9f\x90\xd3\x9e\\\xa9\x96\xf1c\xee\x80\x8ck\x9c\x91\xa5\xf4<\x9d\xab \x08&\x13#\xce\x99~I`\xeb\xe9\xf0\xbe\x87Lg\x1d=\xcb\x0b\xbdW'
cipher: b'\xae\x88\x89n\x97_l\x8d\x95\x8a\x9f\x92\x81\x9f\x8b\x89\x8f\x9fh\x95\x8d_v\x9dy_\x98\x85\x86_\x8dou_{n\x91\x90r\x9f\x8c\x99\x9fb\x85m_zu\x95\x9b_c\x89q\x9f\x88vyp\x92\x9f~\x89\x99\x90'
secret: Nhung_biet_ly_keo_dai_day_dut_moi_chinh_la_bua_tiec_cua_thanh_xuan
Done
```



---
# Baby Apk
![](https://i.imgur.com/9tGBFgg.png)

- Ném vào `jadx` mình biết được `app` viết bằng flutter
- Sau một hồi tìm hiểu và đọc ở `https://cryptax.medium.com/reversing-an-android-sample-which-uses-flutter-23c3ff04b847` mình được biết app được build theo `mode debug` và code gốc vẫn còn nằm trong file `Resources/assets/flutter_assets/kernel_blob.bin`
- Mình tiến hành extract source và `strings` file này để tìm code: 
![](https://i.imgur.com/DUPLzFJ.png)
- Tìm đến package `wannagame_championship` :

![](https://i.imgur.com/CvofCVB.png)
