Код для печати стека в C, возвращающий только «1» - PullRequest
1 голос
/ 17 марта 2012

Я учусь о безопасности. Вот пример кода, который мне дали:

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

char *j; /* use to dump the stack in function cat */

/* Strings to be copied into buffer in function cat */
char str1[] = "";
char str2[] = "";

int main() {

void cat(int *parm) {
   char buffer[8];

   /* Dump the stack for function cat */
   for (j=buffer; j<((char *)&parm); j++)
      printf("%p: 0x%x\n", j, *(unsigned char *)j);

   /* copy str1 followed by str2 into buffer */
   /* note that a \0 remains between str1 and str2 in buffer */
   strcpy(buffer, str1);
   strcpy(&buffer[strlen(str1)+1], str2);

}

   int *arg; /* dummy argument for call to function cat */
   int x;
   x = 0;
   cat(arg);
   x = 1;
   printf("%d\n",x);

}

Я компилирую с GCC. Все, что я получаю, это "1", хотя. Есть идеи почему?

Кроме того, моя цель состоит в том, чтобы в итоге заставить программу выводить «0», и добиться этого, просто добавив код в cat (). Я уже ничего не могу там изменить, просто добавлю. Любая помощь, чтобы начать меня в правильном направлении.

Ответы [ 3 ]

1 голос
/ 17 марта 2012

Я компилирую с GCC.Все, что я получаю, это "1", хотя.Любые идеи почему?

Мы можем видеть

   x = 1;
   printf("%d\n",x);

, так что вполне вероятно, что оператор печати only действительно выполняется.

ИтакЯ предполагаю, что for (j=buffer; j<((char *)&parm); j++) никогда не вводится.Что немного странно.Я ожидаю, что стек будет расти вниз, поэтому я ожидаю, что адрес параметра parm будет выше, чем buffer.

Какую машину вы используете?Попробуйте напечатать значения буфера и & parm, например

void cat(int *parm) {
   char buffer[8];

   printf("buffer=%p\n", buffer);
   printf("&parm=%p\n", &parm);

...

0 голосов
/ 17 марта 2012

Я получаю те же результаты с gcc 4.6.2 на 64-битном Linux, независимо от того, использую ли я 64-битную компиляцию или создаю 32-битный исполняемый файл с -m32.Если посмотреть на код сборки, созданный gcc -S, проблема в том, что gcc создает локальную копию parm в кадре стека cat с адресом ниже buffer.

.в случае 64-битного кода gcc не имеет выбора в этой точке, поскольку аргумент передается в регистр ЦП, и не было бы другого способа дать parm адрес для операции &parm.Однако по какой-то причине gcc делает локальную копию parm даже в 32-битном коде, где она будет иметь идеально точную копию уже в стеке.

В любом случае я думаю, что все это является сторонойпроблема для домашней работы: вы можете получить лучшую верхнюю границу для цикла, передав что-то полезное в parm, а затем используйте parm вместо &parm в грани цикла в cat.

0 голосов
/ 17 марта 2012

Ваш батутный код прекрасно скомпилирован для меня: gcc -o tramp tramp в Linux 2.6.24, $ gcc --version gcc (GCC) 4.3.4 20090804 (выпуск) 1

Мой вывод:

jim @ jim-HP ~ $ cc tramp.c -o tramp

jim @ jim-HP ~ $ tramp

0x28ccf0: 0x4
0x28ccf1: 0x6f
0x28ccf2: 0x24
0x28ccf3: 0x61
0x28ccf4: 0x6
0x28ccf5: 0x6f
0x28ccf6: 0x24
0x28ccf7: 0x61
0x28ccf8: 0x28
0x28ccf9: 0xcd
0x28ccfa: 0x28
0x28ccfb: 0x0
0x28ccfc: 0xa8
0x28ccfd: 0x11
0x28ccfe: 0x40
0x28ccff: 0x0
1

Это то, что вы имели в виду под «всемполучил был 1 '?

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