Jika Anda tertarik untuk menulis pemrograman sistem Linux, Anda harus mempelajari semua pustaka/panggilan sistem dasar. Artikel ini memiliki contoh program C yang mencakup serangkaian panggilan sistem yang akan membantu Anda memahami penggunaan panggilan pustaka dasar ini.
Contoh kode C yang diberikan di bawah ini melakukan hal berikut:
- Otomatis membuka beberapa terminal
- Menampilkan pesan bahwa sesi berjalan sebagai root atau non-root
- Tampilkan pesan di atas pada semua terminal yang terbuka
Berikut ini adalah 13 perpustakaan penting atau panggilan sistem yang tercakup dalam kode contoh di bawah ini.
- memset() :Fungsi ini mengisi n byte pertama dari area memori yang ditunjuk oleh s dengan konstanta byte c.
- fopen() :Fungsi ini membuka file yang namanya adalah string yang ditunjuk oleh argumen pertamanya dan mengaitkan aliran dengannya.
- getcwd() :Fungsi ini mengembalikan string yang diakhiri null yang berisi nama path absolut yang merupakan direktori kerja saat ini dari proses pemanggilan
- getuid() :Fungsi ini mengembalikan ID pengguna sebenarnya dari proses pemanggilan
- snprintf() :Fungsi ini menghasilkan output sesuai dengan format dan menulis output ke buffer.
- fwrite() :Fungsi ini digunakan untuk menulis data ke stream
- fflush() :Fungsi ini memaksa penulisan semua data buffer ruang pengguna ke aliran tertentu
- fclose() :Fungsi ini menghapus aliran terkait dan menutup deskriptor file yang mendasarinya.
- system() :Fungsi ini menjalankan perintah
- sleep() :Fungsi ini membuat proses pemanggilan tidur hingga detik yang ditentukan telah berlalu atau sinyal datang yang tidak diabaikan.
- opendir() :Fungsi ini membuka aliran direktori
- readdir() :Fungsi ini membaca direktori yang dibuka sebagai aliran
- atoi() :Fungsi ini mengubah argumen ascii menjadi integer.
Berikut adalah kode C yang menunjukkan cara menggunakan semua 13 panggilan sistem di atas.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<dirent.h>
#include<sys/types.h>
#include<pwd.h>
// A buffer to hold current working directory
char cwd[512];
void inform(char *path, char *binary_name)
{
// Declare variables for file operations
FILE *fp = NULL;
// A counter to be used in loop
unsigned int counter = 0;
// A buffer to hold the information message
char msg[1024];
// memset function initializes the bytes
// in the buffer 'msg' with NULL characters
memset(msg, '\0', sizeof(msg));
memset(cwd, '\0', sizeof(cwd));
// Check for the path to be non NULL
if(NULL== path)
{
printf("\n NULL path detected\n");
return;
}
// fopen will open the file represented
// by 'path' in read write mode.
fp = fopen(path,"r+");
if(!fp)
{
printf("\n Failed to open %s\n",path);
return;
}
else
{
printf("\n Successfully opened %s\n",path);
}
// getcwd() gives us the current working directory
// of the environemt from which this binary was
// executed
if(NULL == getcwd(cwd,sizeof(cwd)))
{
printf("\n Failed to get current directory\n");
return;
}
// getuid() returns the real user ID of the calling
// process.
// getuid() returns 0 for root and non zero for
// any other user.
if( 0 != getuid())
{
// This functions fills the buffer 'msg' with the formatted string by replacing %s in the harcoded string with the appropriate values
snprintf(msg,sizeof(msg),"\n\n\nYOU ARE NOT ROOT!!!!!");
}
else
{
snprintf(msg, sizeof(msg),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nYOU ARE ROOT!!!!!!!!!!!!!!");
}
// Make sure the information8 is printed 25 times on each
// open terminal
for(counter=0;counter<25;counter++)
{
printf("\n fwrite()\n");
// Write the information message on to the terminal
fwrite(msg, strlen(msg), 1, fp);
// Flush the message to the stdout of the terminal
fflush(fp);
// Wait for one second.
sleep(1);
}
// close the file representing the terminal
fclose(fp);
}
int main(int argc, char *argv[])
{
// Since we will do some directory operations
// So declare some variables for it.
DIR *dp = NULL;
struct dirent *ptr = NULL;
// This variable will contain the path to
// terminal
char *path = NULL;
// Used as a counter in loops
int i =0;
// Step1 :
// Open 5 terminals each after 2 seconds
// of delay.
for(;i<5;i++)
{
// The system API executes a shell command
// We try to execute two commands here
// Both of these commands will open up
// a terminal. We have used two commands
// just in case one of them fails.
system("gnome-terminal");
system("/usr/bin/xterm");
// This call is used to cause a delay in
// program execution. The argument to this
// function is the number of seconds for
// which the delay is required
sleep(2);
}
// Give user some 60 seconds before issuing
// a information message.
sleep(60);
// Now, open the directory /dev/pts which
// corresponds to the open command terminals.
dp = opendir("/dev/pts");
if(NULL == dp)
{
printf("\n Failed to open /dev/pts\n");
return 0;
}
// Now iterate over each element in the
// directory untill all the elements are
// iterated upon.
while ( NULL != (ptr = readdir(dp)) )
{
// ptr->d_name gives the current device
// name or the terminal name as a device.
// All the numeric names correspond to
// open terminals.
// To check the numeric values we use
// atoi().
// Function atoi() converts the ascii
// value into integer
switch(atoi(ptr->d_name))
{
// Initialize 'path' accordingly
case 0:path = "/dev/pts/0";
break;
case 1:
path = "/dev/pts/1";
break;
case 2:
path = "/dev/pts/2";
break;
case 3:
path = "/dev/pts/3";
break;
case 4:
path = "/dev/pts/4";
break;
case 5:
path = "/dev/pts/5";
break;
case 6:
path = "/dev/pts/6";
break;
case 7:
path = "/dev/pts/8";
break;
case 9:
path = "/dev/pts/9";
break;
default:
break;
}
if(path)
{
// Call this function to throw some information.
// Pass the path to terminal where the information
// is to be sent and the binary name of this
// program
inform(path, argv[0]);
// Before next iteration, make path point to
// NULL
path = NULL;
}
}
sleep(60);
return 0;
} Kode di atas sendiri sudah cukup jelas karena berisi komentar yang memadai yang menjelaskan apa yang dilakukan oleh panggilan sistem tersebut. Jika Anda baru mengenal pemrograman sistem Linux, kode ini memberikan paparan yang cukup untuk penggunaan semua fungsi penting ini. Untuk detail lebih lanjut dan penggunaan lanjutan, harap baca halaman manual mereka dengan cermat.
Kode ini adalah simulasi program virus dasar yang menyenangkan. Setelah Anda mengkompilasi dan menjalankan program c di atas, ia akan melakukan hal berikut. Kode ini telah diuji pada Linux mint. Tapi, itu harus bekerja pada semua turunan ubuntu.
- Pengguna akan melihat 5 terminal terbuka satu per satu masing-masing setelah 1 detik.
- Sementara pengguna akan bertanya-tanya apa yang baru saja terjadi, semua terminalnya yang terbuka perlahan-lahan akan mulai mendapatkan informasi berulang tentang login sebagai root atau non-root.
- Harap diperhatikan bahwa debug logging diaktifkan dalam kode untuk tujuan pembelajaran Anda, beri komentar pada printf debug dan kemudian jalankan jika Anda ingin bersenang-senang.