Изменение счетчика аргументов 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 Среду выполнения слишком сложно, попробуйте:
Вот как / почему этот хак работает:
- Функция
C Runtime Environment
, применимая для вашей настройки (есть несколько возможностей), сохраняет аргументы int argc, char **argv, char **envp
в некоторых местах памяти - они удачно соседствуют в случае моей настройки. - В моей системе
64 bit
из-заВ правилах выравнивания памяти адрес int argc
будет на 1 sizeof(int)
больше, чем память, на которую указывает char **argv
, поэтому - 2
в строке: int * pc = (int *) argv - 2;
не - 1
.
╦ ╦ ╔═╗ ╔═╗ ╔═╗ ╦ ╦ ╦ ╦ ╔═╗ ╔═╗ ╦╔═ ╦ ╔╗╔ ╔═╗ ╦ ╦ ╦
╠═╣ ╠═╣ ╠═╝ ╠═╝ ╚╦╝ ─── ╠═╣ ╠═╣ ║ ╠╩╗ ║ ║║║ ║ ╦ ║ ║ ║
╩ ╩ ╩ ╩ ╩ ╩ ╩ ╩ ╩ ╩ ╩ ╚═╝ ╩ ╩ ╩ ╝╚╝ ╚═╝ o o o