как изменить аргументы основной функции перед ее запуском - PullRequest
0 голосов
/ 20 июня 2019

В следующем коде я хочу изменить аргументы основной функции без изменения основной функции.

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

Я пытался использовать канал для перенаправления стандартного ввода и записи параметров в стандартный ввод, но это не работает.

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

__attribute__((constructor))
void __start() {
    static unsigned char tmp[4];
    int count = 0;
    pid_t pid;
    int status;
    while(count < 3){
        pid = fork();
        if(pid < 0) _exit(1);
        if(!pid){
            //how to pass "hello" to main without modfiying main function.
            return;
        }

        count++;
        if(count == 3) _exit(1);
    }
    //_exit(0);

}

int main(int argc, char** argv){
  for(int i = 0; i < argc; i++){
    printf("%d %s\n", i, argv[i]);
  }
  return 0;
}

Если в argv "привет", argc должно быть 2, а на выходе должно быть "1 привет".

1 Ответ

1 голос
/ 20 июня 2019

Изменение счетчика аргументов int argc среды выполнения C до вызова метода C int main(int argc, char **argv).,,- - - = = = (; НАСТОЯЩИЙ ХАК;) = = = - - -.,.


Я использую:

  • Последний компилятор C ++, доступный в настоящее время для OS X High Sierra,
  • Установлен текущийстандартным способом, используя brew.

Чтобы воспроизвести приведенные ниже результаты argc.cpp список кодов , либо:


argc.cpp:

    #include <stdio.h>

    __attribute__((constructor)) void start(int argc, char **argv)
    {
        int * pc = (int *) argv - 2; // NASTY HACK TO GET C RUNTIME argc * ;)
        printf("argc = %d \n", *pc); // the original argc, on most systems ;)
        int NUMBER_OF_PARAMETERS_NEEDED_FOR_FUZZING = 1; // Replace this line 
        // with the simple/complex logic needed for fuzz testing (fuzzing)
        if(!(argc > NUMBER_OF_PARAMETERS_NEEDED_FOR_FUZZING)){ 
            argc = NUMBER_OF_PARAMETERS_NEEDED_FOR_FUZZING + 1;
            *pc = argc; // NASTY HACK TO OVERWRITE C RUNTIME argc ;)
        } 
        // *pc = 2; // uncomment this to see that you can also reduce argc
        argv[1] = "hello"; // Example setting of a fuzzy argument
        // Add more lines, a loop, etc... here to set more fuzzy arguments 
        for (int i = 0; i < argc; i++) {
            printf("%s: argv[%d] = '%s'\n", __FUNCTION__, i, argv[i]);
        }
        printf("argc = %d \n", argc); // the possibly modified argc
    }

    int main(int argc, char **argv)
    {
        for (int i = 0; i < argc; i++) {
            printf("%s: argv[%d] = '%s'\n", __FUNCTION__, i, argv[i]);
        }
        printf("argc = %d \n", argc); // the possibly modified argc
        return 0;
    }

Терминал Mac OS:


Компиляция:

    $ /usr/local/bin/c++-9 argc.cpp -o argc

Работает с 0 аргументами, оригинал int argc = 1:

    $ ./argc
    argc = 1 
    start: argv[0] = './argc'
    start: argv[1] = 'hello'
    argc = 2 
    main: argv[0] = './argc'
    main: argv[1] = 'hello'
    argc = 2 

Запуск с 3 аргументами, оригинал int argc = 4:

    $ ./argc 1 2 3
    argc = 4 
    start: argv[0] = './argc'
    start: argv[1] = 'hello'
    start: argv[2] = '2'
    start: argv[3] = '3'
    argc = 4 
    main: argv[0] = './argc'
    main: argv[1] = 'hello'
    main: argv[2] = '2'
    main: argv[3] = '3'
    argc = 4 

Запуск , чтобы продемонстрировать возможность сокращения argc,

  • после раскомментирования строки 13 и перекомпиляции (с жесткими кодами argc = 2):
        *pc = 2; // uncomment this to see that you can also reduce argc

с теми же 3 аргументами, как и выше, оригинал int argc = 4:

    $ ./argc 1 2 3
    argc = 4 
    start: argv[0] = './argc'
    start: argv[1] = 'hello'
    start: argv[2] = '2'
    start: argv[3] = '3'
    argc = 4 
    main: argv[0] = './argc'
    main: argv[1] = 'hello'
    argc = 2 

Если среда выполнения C is not , инициализированный в вашей системе аналогично списку:

. Вам может потребоваться:

  • Исследуйте разницу, сравнив локальную C Runtime Environment с примером GNU, приведенным выше, и / или
  • Экспериментально измените мой код, пока он не будет работать для вас.Например: пройдитесь по указателям int до , а также ! After! до местоположения argv и посмотрите, что вы там найдете...

Если вы обнаружите, что взламываете текущую C Среду выполнения слишком сложно, попробуйте:


Вот как / почему этот хак работает:

  1. Функция C Runtime Environment, применимая для вашей настройки (есть несколько возможностей), сохраняет аргументы int argc, char **argv, char **envp в некоторых местах памяти - они удачно соседствуют в случае моей настройки.
  2. В моей системе 64 bit из-заВ правилах выравнивания памяти адрес int argc будет на 1 sizeof(int) больше, чем память, на которую указывает char **argv, поэтому - 2 в строке: int * pc = (int *) argv - 2; не - 1.

╦ ╦  ╔═╗  ╔═╗  ╔═╗  ╦ ╦       ╦ ╦  ╔═╗  ╔═╗  ╦╔═  ╦  ╔╗╔  ╔═╗ ╦ ╦ ╦
╠═╣  ╠═╣  ╠═╝  ╠═╝  ╚╦╝  ───  ╠═╣  ╠═╣  ║    ╠╩╗  ║  ║║║  ║ ╦ ║ ║ ║
╩ ╩  ╩ ╩  ╩    ╩     ╩        ╩ ╩  ╩ ╩  ╚═╝  ╩ ╩  ╩  ╝╚╝  ╚═╝ o o o
...