Как программа шифрования оболочки может использовать меньше пользовательского времени? - PullRequest
2 голосов
/ 26 апреля 2009

Update2:

Портировано на автоинструменты и загружено на SourceForge .

Обновление:

Я собираюсь провести несколько более строгих тестов по этому вопросу, но я считаю, что проблема связана с кэшированием, и порядок двух тестовых случаев может быть значительным. Также я знаю, что шифрование жалкое, продублировано в двух файлах, а код хуже первого чернового качества. Я также знаю, что я должен использовать make-файлы и т. Д. Я не предлагаю использовать это где-либо. Я собрал все вместе и упростил, чтобы получить наилучшую информацию от других, какую только смог.

Оригинальный вопрос:

Я полностью в тупике. Я создал оболочку для шифрования сценариев оболочки на основе этого предыдущего вопроса , и она хорошо работает; однако при определении проблем с производительностью шифрованные сценарии занимают меньше времени пользователя! Можете ли вы помочь мне это объяснить? Я просто не понимаю Я разобрал все до основ и максимально упростил. Если вы заберете мои файлы, у вас должны быть права на запись в файл / usr / bin / shelldecrypt.


    ojblass@XXXXX:~/source/shellcrypt>./build
    ojblass@XXXXX:~/source/shellcrypt>./run 

    example.sh.bin is encrypted run it to view output
    ojblass@XXXXX:~/source/shellcrypt>./profile
    example.sh
    real    0m0.107s 
    user    0m0.048s 
    sys     0m0.052s 

    example.sh.bin
    real    0m0.118s 
    user    0m0.036s
    sys     0m0.068s
    ojblass@XXXXX:~/source/shellcrypt>

[строительство]


    gcc shellencrypt.c
    mv a.out shellencrypt
    gcc shelldecrypt.c
    mv a.out shelldecrypt
    cp shelldecrypt /usr/bin

[example.sh]


    #!/bin/bash
    ls -lt  >> /dev/null
    ls -lt  >> /dev/null
    ls -lt  >> /dev/null
    ls -lt  >> /dev/null
    ls -lt  >> /dev/null
    ls -lt  >> /dev/null
    ls -lt  >> /dev/null
    ls -lt  >> /dev/null
    ls -lt  >> /dev/null
    ls -lt  >> /dev/null
    ls -lt  >> /dev/null
    ls -lt  >> /dev/null
    ls -lt  >> /dev/null
    ls -lt  >> /dev/null
    ls -lt  >> /dev/null
    ls -lt  >> /dev/null
    ls -lt  >> /dev/null
    ls -lt  >> /dev/null

[профиль]


    echo example.sh
    time example.sh
    echo example.sh.bin
    time example.sh.bin

[пробег]


    rm -rf example.sh.bin
    ./shellencrypt example.sh
    chmod 755 example.sh.bin
    echo example.sh.bin is encrypted run it to view output

[shelldecrypt.c]

#include        <stdio.h>
#include        <stdlib.h>
#include        <string.h>
#include        <limits.h>
#include        <unistd.h>
/* #define DEBUG */
static int    flip( int a)
{
        int b;
        b = a;
        b ^= 0x000C;
        return b;
}

static void    trace ( char * szMessage )
{
#ifdef DEBUG
     if (szMessage != NULL)
     {
       printf("DEBUG Message %s\n",szMessage);
     }
#endif
    return;
}

int     main(int argc, char     *argv[]) {

        FILE    *fp = NULL;
        int     ch=(char) 0;
        int     foundnl=0;
        char    shellpath[4096]; /* what happened to PATH_MAX? */
        char    *ptest;
        FILE    *pipe = NULL;

        /* TODO REMOVE memset(bangline, 0, sizeof(bangline)); */

        trace("STARTING");
        trace(argv[0]);
        trace("ARGUMENT");

        /* get the shell environment variable */
        ptest = getenv("SHELL");
        if (ptest == NULL)
        {
            trace("could not get shell environment variable");
            return (EXIT_FAILURE);
        }
        else
        {
            strcpy(shellpath, getenv("SHELL"));
            trace(shellpath);
        }

        if ((argc >=1) && (argv[1]!=NULL))
        {
            trace(argv[1]);
        }
        else
        {
            trace("(null)");
        }

        if (argc == 2) {
                fp = fopen(argv[1],"r");
                if (fp == NULL) {
                        fprintf(stderr,"Unable to open file %s. Exiting.\n",argv[1]);
                        exit(EXIT_FAILURE);
                }
        }
        else
        {
               printf("Usage: %s <filename>\n",argv[0]);
               exit (EXIT_SUCCESS);
        }

        /* strip out the bangline which is not encryped */
        while ((ch = fgetc(fp)) != EOF) {
              if (ch == 10)
              {
                 foundnl = 1;
                 break;
              }
        }


        if (foundnl!=1)
        {
           (void) fclose(fp);
           trace("FOUND NO NEWLINE BEFORE END OF FIRST LINE");
           return (EXIT_SUCCESS);
        }


        pipe = popen(shellpath, "w");
        if (pipe == NULL)
        {
            trace("popen failed");
            (void) fclose(fp);
            return (EXIT_FAILURE);
        }
        else
        {
            trace("writing string to pipe");

            while ((ch = fgetc(fp)) != EOF) {
               (void) fputc(flip(ch),pipe);
            }
/*            (void) fputc(EOF,pipe); */
        }

        if (pipe != NULL)
           (void) pclose(pipe);
        if (fp != NULL)
           (void) fclose(fp);
        exit (EXIT_SUCCESS);
}

[shellencrypt.c]

#include        <stdio.h>
#include        <stdlib.h>
#include        <string.h>

static int    flip( int a)
{
        int b;
        b = a;
        b ^= 0x000C;
        return b;
}

int     main(int argc, char     *argv[]) {

        FILE    *fp = NULL, *fpOut=NULL;
        int             ch;

        char szOutputFileName[2000];
        strcpy(szOutputFileName,"");


        if (argc == 2) {
                fp = fopen(argv[1],"r");
                if (fp == NULL) {
                        fprintf(stderr,"Unable to open file %s. Exiting.\n",argv[1]);
                        exit(EXIT_FAILURE);
                }
        }
        else
        {
               printf("Usage: %s <filename>\n",argv[0]);
               exit (EXIT_SUCCESS);
        }

        strcpy(szOutputFileName, argv[1]);
        strcat(szOutputFileName, ".bin");

        fpOut = fopen(szOutputFileName,"wt");
        if (fpOut == NULL)
        {
             fprintf(stderr,"Unable to open file %s.  Exiting.\n",szOutputFileName);
             if (fp)
                 (void) fclose(fp);
             exit(EXIT_FAILURE);
        }

        /* print the header */
        fprintf(fpOut,"#!/usr/bin/shelldecrypt\n");

        /* read until the end of file, encrypting characters and writing them out to target file */
        while ((ch = fgetc(fp)) != EOF) {
              (void) fputc(flip(ch),fpOut);
        }
        if (fp)
           (void) fclose(fp);
        if (fpOut)
           (void) fclose(fpOut);

        return(EXIT_SUCCESS);
}

Ответы [ 2 ]

4 голосов
/ 26 апреля 2009

Это не достаточно существенная разница, и я бы пришел к выводу, что есть какой-либо эффект. Лучший "профиль" это:

#!/bin/bash

echo example.sh
/usr/bin/time sh -c 'for i in $(seq 1 1000); do ./example.sh; done'

echo example.sh.bin
/usr/bin/time sh -c 'for i in $(seq 1 1000); do ./example.sh.bin; done'

На моей машине я получил:

example.sh
39.46user 33.22system 1:16.92elapsed 94%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+8547221minor)pagefaults 0swaps
example.sh.bin
42.33user 42.13system 1:33.98elapsed 89%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+9376313minor)pagefaults 0swaps

Этого недостаточно, чтобы показать окончательно , что «зашифрованный» медленнее (хотя я, очевидно, думаю, что это так), но это определенно показывает, что зашифрованный не последовательно займет меньше времени пользователя в простом тесте.

Кроме того, существуют некоторые другие серьезные проблемы с вашим кодом. Очевидно, это не близко к звуковому шифрованию. Как говорили другие люди, вы неправильно подходите к проблеме. Алгоритм шифрования, который вы придумали «в считанные часы», не заменяет разрешения на звук.

Кроме того, вам нужно использовать make-файлы вместо распространения ненужных сценариев оболочки. Изучите элементарные параметры gcc, например -o. Не пытайтесь копировать в / usr / bin /, если пользователь не запускает цель установки (в этом случае / usr / local / bin все равно будет лучше).

2 голосов
/ 26 апреля 2009

Я подозреваю, что это в основном показывает, что шифрование не является существенной частью производительности этого конкретного сценария.

Однако получение файловой системой для загрузки содержимого каталога в первый раз имеет значение. Как только он загружен, он, вероятно, будет кэширован. Это объясняет, почему в первый раз вы запустите оба, какой из них будет выполнен первым, будет медленнее. После этого они, вероятно, будут очень похожи, используя кеш файловой системы.

Если вы перезагрузитесь (чтобы быть абсолютно уверенным, что очищаете кеш) и запустите его наоборот, я ожидаю, что зашифрованная версия займет больше времени, просто потому, что она будет идти на диск вместо кеша .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...