GNU/Linux >> Linux の 問題 >  >> Linux

楽しいLinuxウイルスプログラムを使用して説明された13の基本的なLinuxシステムコール

Linux システム プログラミングの作成に興味がある場合は、すべての基本的なライブラリ/システム コールを学習する必要があります。この記事には、これらの基本的なライブラリ呼び出しの使用法を理解するのに役立つ一連のシステム コールを扱う C プログラムの例があります。

以下に示す C コードの例は、次のことを行います:

  • 一部の端末を自動的に開きます
  • セッションがルートまたは非ルートとして実行されているというメッセージを表示します
  • 開いているすべての端末で上記のメッセージを表示する

以下は、以下のサンプル コードでカバーされている 13 の重要なライブラリまたはシステム コールです。

<オール>
  • memset() :この関数は、s が指すメモリ領域の最初の n バイトを定数バイト c で埋めます。
  • fopen() :この関数は、最初の引数が指す文字列と同じ名前のファイルを開き、ストリームを関連付けます。
  • getcwd() :この関数は、呼び出しプロセスの現在の作業ディレクトリである絶対パス名を含む null で終わる文字列を返します
  • getuid() :この関数は、呼び出しプロセスの実際のユーザー ID を返します
  • snprintf() :この関数は、フォーマットに従って出力を生成し、出力をバッファに書き込みます。
  • fwrite() :この関数は、データをストリームに書き込むために使用されます
  • fflush() :この関数は、すべてのユーザー空間のバッファリングされたデータを特定のストリームに強制的に書き込みます
  • fclose() :この関数は、関連付けられたストリームをフラッシュし、基になるファイル記述子を閉じます。
  • system() :この関数はコマンドを実行します
  • sleep() :この 関数 は、指定された秒数が経過するか、無視されないシグナルが到着するまで、呼び出しプロセスをスリープ状態にします。
  • opendir() :この関数はディレクトリ ストリームを開きます
  • readdir() :この関数は、ストリームとして開かれたディレクトリを読み取ります
  • atoi() :この関数は ascii 引数を整数に変換します。
  • 以下は、上記の 13 のシステム コールすべての使用方法を示す C コードです。

    #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;
    }

    上記のコード自体は、これらのシステム コールが何を行うかを説明する適切なコメントが含まれているため、一目瞭然です。 Linux システム プログラミングに慣れていない場合は、このコードでこれらすべての重要な機能の使用法を十分に理解できます。詳細と高度な使用方法については、man ページを注意深くお読みください。

    このコードは、楽しい基本的なウイルス プログラムのシミュレーションです。上記の c プログラムをコンパイルして実行すると、次のようになります。このコードは Linux mint でテストされました。ただし、すべての ubuntu 派生物で動作するはずです。

    • 5 つの端末が 1 秒ごとに 1 つずつ開くのが表示されます。
    • ユーザーは何が起こったのか不思議に思うでしょうが、開いているすべての端末は、ログインが root または非 root であるという情報を繰り返し取得し始めます。
    • 学習目的でコード内でデバッグ ログが有効になっていることに注意してください。楽しみたい場合は、デバッグの printf をコメント アウトしてから実行してください。

    Linux
    1. Linux –新しいカーネルのシステムコール呼び出しメソッド?

    2. Linux でのパフォーマンスの問題をトラブルシューティングするための基本的なコマンド

    3. Linux の cat に比べて、システム コールを使用した cat 関数が遅いのはなぜですか?

    1. straceを使用したLinuxでのシステムコールの理解

    2. Linux で C++ を使用してシステムの日付と時刻を設定する

    3. Linux 待ち行列システム

    1. Rsyncを使用してLinuxシステム全体をバックアップする方法

    2. Linux –ライブラリ関数への呼び出しのシステム全体の監視?

    3. Linux で Cron を使用してシステム ジョブを定義する