# WinAntiDbg0x300

## Deskripsi

<figure><img src="/files/eawhv7X8NtTXwvnC3F8w" alt=""><figcaption></figcaption></figure>

## Walkthrough

Diberikan sebuah file zip yang berisi 3 file berikut:

<figure><img src="/files/TVhlnoEAKq0dgJLWEBkI" alt=""><figcaption></figcaption></figure>

Ketika file `WinAntiDbg0x300.exe` dijalankan, maka akan menghasilkan output berikut:

<figure><img src="/files/tuV4mGaZlTG35aCUCsCB" alt=""><figcaption></figcaption></figure>

Dari deskripsi tersebut bisa diketahui bahwa flag bisa diperoleh dengan menjalankan program ini di debugger.

Seperti biasanya, sebelum melakukan analisis lebih dalam, saya mengecek terlebih dahulu kumpulan string yang ada di program ini dengan perintah: `strings WinAntiDbg0x300.exe` untuk menemukan flagnya.

<figure><img src="/files/LBCW5i1HWFJQtvxWdlII" alt=""><figcaption></figcaption></figure>

Setelah mencari menggunakan grep dan ekplorasi manual dengan `ltrace`, `strace`, dan `strings`, saya tetap tidak menemukan flagnya. Tetapi, saya menemukan bahwa program ini dikompresi dengan UPX, sebuah packer yang digunakan untuk memperkecil ukuran program atau “menyembunyikan” bagian kode aplikasi dari analisis awal di reverse engineering.

<figure><img src="/files/3oJjROZNKjlOPJbHo5n4" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/zas2gQjvzYhslDqPoRON" alt=""><figcaption></figcaption></figure>

### Dekompresi Program

Untuk melakukan dekompresi UPX ini sangatlah mudah, saya hanya perlu mendownload UPX dari [GitHub](https://github.com/upx/upx) dan menjalankan perintah:

`upx -d WinAntiDbg0x300.exe -o WinAntiDbg0x300_unpacked.exe`

<figure><img src="/files/gPCdm8teLJ5TtuAcEIbe" alt=""><figcaption></figcaption></figure>

Setelah melakukan dekompresi, saya kemudian mengecek kembali kumpulan string yang ada di program ini dengan `strings`, `strace`, dan `ltrace`. Namun, tetap saja tidak menemukan flagnya dengan cara ini.

<figure><img src="/files/NUFLSngkhGL8pRog8n9T" alt=""><figcaption></figcaption></figure>

### Analisis Statik

Setelah langkah awal tidak memberikan hasil, saya kemudian melakukan analisis statik lanjutan dengan Ghidra.&#x20;

Jika kalian ingin mempelajari cara menggunakan Ghidra, bisa lihat [tutorial ini](https://www.youtube.com/watch?v=fTGTnrgjuGA).

<figure><img src="/files/sGRhC7rN45kzeHBf8SHU" alt=""><figcaption></figcaption></figure>

Di bawah ini adalah tampilan awal ketika program hasil dekompresi dibuka di Ghidra.&#x20;

<figure><img src="/files/WnKflVieyMCThWOBcjp8" alt=""><figcaption></figcaption></figure>

Di window sebelah kiri paling atas berisi struktur segmentasi dari program yang sedang dianalisis. Ini merepresentasikan layout memori dari file binari. Di window dengan garis warna hijau berisi daftar dependensi yang digunakan oleh file binari. Sedangkan di kotak warna biru adalah daftar fungsi internal yang ditemukan dalam file binari.

Karena ada terlalu banyak fungsi lokal dan saya malas untuk mengecek isi dari setiap fungsi satu persatu :), jadi saya langsung mencoba untuk mencari flagnya melalui fitur `Program Text`.

<figure><img src="/files/FLq3xSXENhVzwHIvQ4ZR" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/Sh9YGRT3OiuRjvHzenB4" alt=""><figcaption></figcaption></figure>

Saya tidak menemukan flag aslinya dari hasil search text ini. Namun, saya menemukan sejumlah string berisi pesan untuk menampilkan flagnya.

<figure><img src="/files/zeli0gGxKARrRps8PD5h" alt=""><figcaption></figcaption></figure>

Saya kemudian langsung mengecek lokasi di mana string flag ini pertama kali ditemukan, ternyata berada di lokasi `0040392b`. Dan setelah menuju ke lokasi tersebut, muncul hasil dekompilasi kode berikut:

```c

/* WARNING: Removing unreachable block (ram,0x004038e0) */
/* WARNING: Removing unreachable block (ram,0x00403911) */
/* WARNING: Removing unreachable block (ram,0x00403929) */

undefined4 FUN_00403740(void)

{
  WCHAR local_384 [260];
  CHAR local_17c [272];
  _STARTUPINFOA local_6c;
  BOOL local_24;
  DWORD local_20;
  _PROCESS_INFORMATION local_1c;
  DWORD local_8;
  
  memset(&local_6c,0,0x44);
  local_6c.cb = 0x44;
  local_1c.hProcess = (HANDLE)0x0;
  local_1c.hThread = (HANDLE)0x0;
  local_1c.dwProcessId = 0;
  local_1c.dwThreadId = 0;
  local_8 = 0;
  local_20 = GetCurrentProcessId();
  GetModuleFileNameW((HMODULE)0x0,local_384,0x104);
  thunk_FUN_00403e50(local_17c,0x110,"%ws %d",(char)local_384);
  thunk_FUN_00402bc0(2);
  do {
    local_24 = CreateProcessA((LPCSTR)0x0,local_17c,(LPSECURITY_ATTRIBUTES)0x0,
                              (LPSECURITY_ATTRIBUTES)0x0,0,0,(LPVOID)0x0,(LPCSTR)0x0,&local_6c,
                              &local_1c);
    if (local_24 == 0) {
      MessageBoxW(DAT_0040c704,
                  L"[FATAL ERROR]  Unable to create the child process. Challenge aborted.",
                  (LPCWSTR)&lpWindowName_0040c3e0,0x10);
      thunk_FUN_00402e00(0xff);
    }
    WaitForSingleObject(local_1c.hProcess,0xffffffff);
    GetExitCodeProcess(local_1c.hProcess,&local_8);
    if (local_8 == 0xff) {
      MessageBoxW(DAT_0040c704,L"Something went wrong. Challenge aborted.",
                  (LPCWSTR)&lpWindowName_0040c3e0,0x10);
      thunk_FUN_00402e00(0xff);
    }
    else if (local_8 == 0xfe) {
      MessageBoxW(DAT_0040c704,
                  L"The debugger was detected but our process wasn\'t able to fight it. Challenge ab orted."
                  ,(LPCWSTR)&lpWindowName_0040c3e0,0x10);
      thunk_FUN_00402e00(0xff);
    }
    else if (local_8 == 0xfd) {
      MessageBoxW(DAT_0040c704,
                  L"Our process detected the debugger and was able to fight it. Don\'t be surprised if the debugger crashed."
                  ,(LPCWSTR)&lpWindowName_0040c3e0,0x10);
    }
    CloseHandle(local_1c.hProcess);
    CloseHandle(local_1c.hThread);
    Sleep(5000);
  } while( true );
}


```

<figure><img src="/files/hK4RHW9EM9yFC4xK2dHD" alt=""><figcaption></figcaption></figure>

Setelah mengecek kode hasil dekompilasi tersebut, ternyata di sana tidak berisi fungsi untuk men-trigger flagnya. Namun, jika dilihat kembali, terdapat dua fungsi yang dieksekusi di awal sebelum perintah looping `Do While`, yaitu `thunk_FUN_00403e50` dan `thunk_FUN_00402bc0`

Namun, setelah mengecek kedua fungsi tersebut dan tidak menemukan clue yang jelas untuk mendapatkan flagnya, saya kemudian melihat flow fungsi `FUN_00403740` melalui graph.

<figure><img src="/files/8a4qzHUa6TuysWOWSGbF" alt=""><figcaption></figcaption></figure>

Dan jika mengikuti flow graph di sebelah kiri, yaitu fungsi `LAB_004038e0` dan melihat isinya, bisa dilihat bahwa fungsi inilah yang sebenarnya akan menampilkan flagnya.

<figure><img src="/files/TOsG2b4En4zZf2LfDbQj" alt=""><figcaption></figcaption></figure>

### Patching

Setelah mengetahui flow untuk mendapatkan flag, kemudian langkah selanjutnya adalah saya perlu memanipulasi flow program ini untuk mendapatkan flagnya.

Supaya fungsi  `LAB_004038e0` dieksekusi dan selanjutnya akan mengeksekusi `LAB_00403929` (flag), maka saya perlu memanipulasi hasil dari instruksi `TEST EAX, EAX` di fungsi `LAB_004037c0` supaya instruksi `JZ LAB_004038e0` dieksekusi dan melompat ke arah flow sebelah kiri yang menuju ke fungsi yang men-trigger flag (`LAB_00403929`).

<figure><img src="/files/wlVKNU6Kj4MmZU9DnpP0" alt=""><figcaption></figcaption></figure>

Di sini, terdapat instruksi `TEST EAX, EAX` yang melakukan operasi bitwise AND pada `EAX`, dan dilanjutkan eksekusi instruksi `JZ LAB_004038e0` yang akan melakukan lompatan ke fungsi `LAB_004038e0` jika hasil `TEST EAX, EAX` adalah `0`.&#x20;

Karena `TEST EAX, EAX` akan selalu menghasilkan output `1`, maka instruksi `JZ LAB_004038e0` tidak akan pernah dieksekusi, dan program akan melanjutkan ke instruksi di flow graph sebelah kanan (looping do while), yang artinya fungsi untuk men-trigger flag (flow sebelah kiri) tidak akan pernah dieksekusi.

Supaya flow di sebelah kiri dieksekui, maka saya perlu memanipulai flow instruksi di fungsi ini supaya instruksi `JZ LAB_004038e0` dieksekusi. Dan untuk melakukan ini sangatlah mudah, saya hanya perlu mengubah instruksi `JZ` (Jump Zero) dengan `JNZ` (Jump Not Zero) melalui `Patch Instruction`:

<figure><img src="/files/4kt2Om9zG0HDfkfSpuC5" alt=""><figcaption></figcaption></figure>

Dan setelah berhasil melakukan patching instruksi dari `JZ` ke `JNZ`, maka hasil dekompilasi dari fungsi yang men-trigger flag akan tampil secara otomatis di window dekompilasi kode:

<figure><img src="/files/q0mbKmQIPgFEJzvPZn77" alt=""><figcaption></figcaption></figure>

Kemudian langkah selanjutnya adalah mengeksport hasil patching dan menjalankan programnya.

<figure><img src="/files/iaS1dlrFEUI3n0rnbTfz" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/PztrIS3RMyiKgkeutxRJ" alt=""><figcaption></figcaption></figure>

Dan saat program hasil patching dijalankan, maka flag akan secara otomatis muncul dalam bentuk pop up alert window.

<figure><img src="/files/DfrBEIDAVrOWKtn87Qaa" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://blog.azizprabowo.com/writeups/winantidbg0x300.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
