Какое второе шестнадцатеричное число возвращается при проверке указателя с помощью GDB? - PullRequest
0 голосов
/ 27 февраля 2020

В настоящее время я пытаюсь выучить низкоуровневое программирование из книги под названием «Искусство эксплуатации». Книга, после написания некоторого кода, исследует его с помощью gdb. Сейчас я нахожусь в разделе об указателях.

Код, которым я сейчас пользуюсь, таков:

#include <string.h>

int main(){
    char str_a[20]; //20 charachters array
    char *pointer;
    char *pointer2;

    strcpy(str_a, "hello world\n");
    pointer = str_a; //set pointer to the start of the array
    printf("%s\n", pointer);

    pointer2 = pointer + 2; 
    printf(pointer2);
    strcpy(pointer2, "y you guys\n");
    printf("%s\n", pointer);
    ...

В GDB я поставил разрыв в строке printf("%s\n", pointer);.

Затем я проверяю указатель *pointer с помощью команды x/xw pointer, и он возвращает 0x7fffffffde20: 0x6c6c6568. Я понимаю, что 0x7fffffffde20 - это память, на которую указывает указатель, но я не понимаю, что такое 0x6c6c6568.

Затем я использую x/xw &pointer, чтобы непосредственно увидеть, где находится память *pointer, и на этот раз он возвращает 0x7fffffffde10: 0xffffde20. Я не понимаю, что такое второй гекс.

Если я попытаюсь проверить его с помощью команды x/xw 0xffffde20, он вернет

0xffffde20: Cannot access memory at address 0xffffde20

Может ли кто-нибудь мне помочь?

Ответы [ 2 ]

6 голосов
/ 27 февраля 2020

Затем я проверяю указатель * указатель с помощью команды x/xw pointer, и он возвращает

0x7fffffffde20: 0x6c6c6568.

Я понимаю, что 0x7fffffffde20 - это память, на которую указывает pointer, но я не понимаю, что такое 0x6c6c6568.

Отладчик просто показывает вам адрес и содержимое, хранящееся по этому адресу.

В вашем коде pointer указывает на ваш массив, в который вы скопировали строку "hello world\n" В памяти это (шестнадцатеричное) 68 65 6C 6C 6F 20 77 6F 72 6C 64 0A

Когда Вы читаете как 32-битное целое число (через x/xw), первые 4 байта интерпретируются как целое число. Предполагая, что ваша машина использует порядок памяти с прямым порядком байтов, это значение принимается 0x6c6c6586. Если вы прочитаете снова по следующему адресу, вы получите целочисленное представление "o wo" и "rld\n".

Затем я использую x/xw &pointer, чтобы увидеть непосредственно, где находится память *pointer, и на этот раз он возвращает

0x7fffffffde10: 0xffffde20

Я не понимаю, что такое второй гекс.

Опять же, вы получаете адрес и некоторый контент. Тип / размер содержимого определяется командой, которую вы используете для его чтения. Вы читаете 32 бита и получаете 32 бита с этого адреса.

Какой результат мы должны ожидать здесь?

В предыдущей команде вы читали память по адресу, на который указывает pointer. На этот раз вы читаете память по адресу, где находится pointer.

Помните: первая команда показала адрес 0x7fffffffde20. Теперь вы видите, что переменная pointer хранится в 0x7fffffffde10, а первые 32 бита - 0xffffde20. Обратите внимание, что это аналогично значению, которое рассматривалось как адрес в первой команде чтения.

Это означает, что 0xffffde20 - это только половина 0x7fffffffde20, а другая половина отсутствует. Вы просто не читали достаточно, чтобы показать их.

Как уже упоминалось в комментарии @jester, вы должны использовать x/xa для отображения адресов.

Если я попытаюсь проверить это с помощью команда x/xw 0xffffde20 возвращает

0xffffde20: Cannot access memory at address 0xffffde20

С выводом выше это не удивительно. Вы указали только часть адреса, и это приводит к недопустимому доступу к памяти.

Из чисел ваш макет и содержимое памяти похожи на это:

0x7fffffffde30 still str_a         xx xx xx xx
0x7fffffffde28 still str_a         72 6C 64 0A 00 xx xx xx
0x7fffffffde20 char str_a[20]      68 65 6C 6C 6F 20 77 6F 
0x7fffffffde18 ...
0x7fffffffde10 char *pointer       0x7fffffffde20  == address of str_a
0x7fffffffde08 char *pointer2
1 голос
/ 27 февраля 2020

Второе число - это содержимое элемента, на которое оно указывает. В этом случае

6c6c6568
= lleh
= hell backwards
= the first 4 characters of hello

Я не знаю ответа на второй вопрос.

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