Assembler di browser berbasis Keystone dengan WebAssembly

Sebenarnya saat ini saya sedang sibuk dengan banyak hal, tapi karena sedang berduka, saya ingin melakukan sesuatu untuk mengalihkan pikiran. Bapak saya suka membongkar mobil untuk mengalihkan pikiran, sedangkan saya lebih suka memprogram sesuatu yang tidak berhubungan dengan pekerjaan. Hasilnya: hari ini saya mengkompilasi framework Keystone dengan target WebAssembly (Wasm) lalu memberi interface HTML dengan Preact (alternatif React yang ukurannya jauh lebih kecil).

Assembler ini bisa diakses online di https://asm.x32.dev dan sourcenya saya berikan di https://github.com/yohanes/online-assembler . Aplikasinya bisa diakses dengan semua browser modern (Safari, Chrome, Firefix, Edge), termasuk juga mobile browser (sudah ditest di iOS 13 dan Android 10).

WebAssembly (Wasam)

Supaya tidak bingung dengan penjelasan assembler dan webassembly, akan saya jelaskan apa itu WebAssembly (biasa disingkat dengan Wasm). WebAssembly adalah format instruksi biner untuk virtual machine (bisa dibayangkan seperti bytecode Java) . Saat ini target utamanya adalah web browser (saat ini sudah disupport di Firefox, Google Chrome, Safari dan Edge). Di masa depan web assembly ini dihrapkan akan bisa dipakai juga di aplikasi desktop maupun server.

Sekarang ini sudah ada compiler supaya kita bisa mengkompilasi bahasa C, C++, Rust, dsb ke kode WebAssembly. Setelah dikompilasi, kodenya bisa dijalankan di browser. Sayangnya API web browser tidak bisa diakses oleh kode web assembly, jadi diperlukan jembatan berupa kode JavaScript.

Keystone

Keystone merupakan library assembler untuk berbagai arsitektur. Diberikan teks assembly, kita bisa memakai library ini untuk mengubahnya menjadi bahasa mesin. Keystone ini sebenarnya memakai bagian dari libary LLVM, tapi diekstrak bagian assemblernya saja. LLVM sendiri merupakan proyek infrastruktur compiler yang memiliki banyak fitur (parser, optimizer, assembler, linker, debugger, dsb) tapi terlalu kompleks dan terlalu besar jika hanya ingin fitur assemblernya saja.

Untuk keperluan development program dalam assembly, Keystone ini belum terlalu layak pakai karena banyak bugnya dan tidak memiliki fitur macro yang ada di banyak assembler modern. Untuk development, sebaiknya pakai saja assembler dari berbagai compiler yang ada. Keystone ini lebih terpakai untuk riset security, patching program, dan berbagai fungsi kecil lain yang overkill jika memakai assembler lengkap dari sebuah compiler. Contoh pemakaian Keystone adalah untuk menyelesaikan soal CTF semacam yang saya selesaikan dua tahun yang lalu.

Jadi supaya jelas: assembly di WebAssembly tidak berhubungan dengan assembler di library Keystone (saat ini keystone belum mendukung web assembly).

EMSDK

Dengan menggunakan emscripten SDK (emsdk), sekarang kita bisa mengkompilasi banyak library dan program yang ditulis dalam bahasa C/C++ dengan target Web Assembly dengan relatif mudah. Jika program atau library memakai configure, kita bisa menjalankan emconfigure ./configure dan jika memakai cmake, kita bisa menjalankan emcmake cmake. Program emconfigure dan emcmake merupakan wrapper, agar ketika configure/cmake dijalankan, maka compiler dan library yang akan dipakai adalah untuk target WASM.

Tentunya tidak semua program dan library bisa dikompilasi dengan mudah. Contoh kode yang tidak bisa dicompile langsung: kode yang butuh library lain, kode yang butuh akses hardware, kode yang butuh akses layanan sistem operasi tertentu, kode yang memakai kode assembly dalam Intel x86 atau ARM, dan masih banyak lagi kasus khusus lain. Dalam kasus seperti ini, kita perlu melakukan porting manual.

Selain mengkompilasi file C menjadi WASM, emsdk juga menghasilkan file Javascript yang gunanya menjadi jembatan antara Javascript dan WASM. Jembatan ini dua arah: kode C yang memanggil fungsi library standar seperti printf akan memanggil kode JavaScript (misalnya kita arahkan menjadi memanggil console.log), dan kita bisa memanggil kode C dari Javascript.

Optimasi ukuran

Saat ini kode yang dihasilkan dari EMSDK masih belum efisien. Library Keystone ketika dicompile dengan target Web Assembly, hasilnya menjadi file 9.7 megabyte. Saat ini ada proyek lain bernama binaryen yang merupakan infrastruktur compiler untuk WebAssembly. Salah satu toolnya adalah wasm-opt yang dapat digunakan untuk mengoptimasi bytecode WASM. Tool yang lain adalah disassembler Web Assembly (disassembler ini saya pakai untuk menyelesaikan soal CTF).

Setelah dioptimasi, library Keystone yang berukuran 9.7 megabyte berkurang menjadi 5.7 megabyte saja. Ketika didistribusikan, file ini masih akan dikompresi dengan gzip dan hasilnya menjadi 1.5 megabyte. Ukurannya memang tidak kecil, tapi kebanyakan foto dan video ukurannya juga sudah ratusan kilobyte.

User Interface

Bagian berikutnya yang perlu dilakukan adalah membuat user interface yang bagus untuk library yang kita compile tersebut. Untuk program yang memakai Simple DirectMedia Layer (SDL) dan OpenGL, kadang kita bisa langsung menjalankannya karena emsdk sudah menyediakan wrapper untuk API HTML Canvas dan WebGL. Sedangkan untuk aplikasi lain, kita perlu membuat interface HTML dan menggunakan JavaScript untuk memanggil kode C.

Alasan saya memporting Keystone agar bisa memakai assembler keystone terbaru dari browser. Sudah ada yang membuat keystone.js tapi sudah lama tidak diupdate.

Tadinya saya hanya ingin memakai HTML + Javascript murni saja untuk user interfacenya. Tapi setelah saya pertimbangkan lagi, memakai library Javascript akan membuat kodenya jadi lebih terstruktur. Tadinya saya akan memakai React, tapi aplikasi kecil dalam React butuh ratusan kilobyte (terutama karena bagian ReactDOM). Jadi saya memakai Preact yang memakai API yang (hampir) sama dengan React tapi ukurannya hanya 9 kilobyte saja (bahkan hanya 4 kilobyte setelah dikompres).

Development JavaScript Modern biasanya dilakukan dengan menggunakan build system, tapi sebenarnya tidak wajib. Karena program saya ini sangat kecil, saya putuskan untuk tidak memakai build system. Semua kode langsung masuk ke file HTML dan JS. Karena saya memakai WASM, browser harus cukup modern, jadi saya bisa memakai berbagai fitur HTML/JS terbaru tanpa butuh berbagai library polyfill.

Penutup

Salah satu cara belajar teknologi Web Assembly adalah dengan memporting berbagai library dan program ke browser dan membuat atau menyesuaikan user interface agar berjalan di browser. Bahasa C/C++ sudah ada sejak lama, dan sudah banyak hal menarik yang dibuat dalam C, berbagai kode yang sudah ada ini bisa dibawa ke browser dan dieksekusi langsung tanpa butuh server (server hanya sekedar untuk menyimpan file saja, tidak untuk eksekusinya).

Semoga artikel singkat ini berguna untuk memulai eksplorasi Web Assembly, dan semoga assembler onlinenya juga bisa terpakai di masa depan, baik untuk saya sendiri maupun orang lain.

2 thoughts on “Assembler di browser berbasis Keystone dengan WebAssembly

  1. Jimmy Saputra

    Bang mau tanya klau mau ambil data dri screenshot activeXobject file js sesuai parameter xxx lalu kirim balik ke bot telegram gmn ya caranya? Terima kasih

    Reply
    1. admin Post author

      kalau melibatkan activeX object kayanya agak ribet karena setahu saya hanya browser lama yang tidak support tools modern yang masih support ActiveX. Sepertinya harus manual start browser, inject click dst, lalu capture windownya.

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.