Я работаю в программе, использующей информацию DWARF и ELF. Я подключен к другой программе, используя инструмент под названием Pin. У меня есть адреса из глобальных переменных, объявленных в программе «Y», и я подключаю их к своему модулю Pin, который я назову «X».
Я получаю кучу адресов для этих глобальных переменных. К сожалению, у меня возникают проблемы, когда я пытаюсь разыменовать их. Например (сейчас я делаю вещи вручную, чтобы посмотреть, делает ли он то, что должен делать):
char * limit, * address1;
for(address1 = (char *) 0x804A040, limit = address1 + bytesize; address1 < limit; address1++)
cout << *(address1) << "\n";
Я должен получить переменную, которая хранится в этом адресе, который является char *
к слову. Нужно ли разыменовывать два указателя в этом случае? Адрес, а затем char *
хранится в этом адресе?
Это прекрасно работает, когда я хочу разыменовать int
переменная, но всякий раз, когда я пытаюсь разыменовать указатель на символ или переменную, я получаю non-ASCII
ценности…
Думайте так: если вы хотите разыменовать int
, ты используешь int *
:
int *addr = (int *)0x12345678;
printf("%d\n", *addr);
Но строка уже является указателем, поэтому, если вы сделаете это:
char *addr = (char *)0x12345678;
Вам не нужно разыменовывать его, чтобы распечатать, поэтому вы получите это так:
printf("%s\n", addr);
Кроме того, предположим, у вас есть эта память:
00000001: 0x12345678
...
12345678: 'A'
12345679: 'B'
1234567A: '\0'
...
Давайте получим доступ к адресу 0x00000001
и посмотрим, что мы можем сделать:
unsigned int *addr = (unsigned int *)0x00000001;
Сейчас *addr
содержит целое число, которое является адресом первого символа нашей строки. Функции, которые принимают строковый аргумент, обычно запрашивают строковый адрес, то есть указатель на него, поэтому *addr
это также строка, на которой мы должны напечатать cout
или же printf
например.
// This should print "AB"printf("%s\n", (char *)(*addr));
Теперь, если вы разыграете нашу ценность (0x12345678
), мы получили бы первый символ строки, и только его, как char
, Так что, если вы используете его неправильно и разыменовываете его char *
, printf
будет пытаться найти память «А», которая 0x00000041
и, вероятно, получит ошибку сегментации.
Итак, правильный способ разыменования его значения, чтобы получить первый символ, был бы таким:
// This should print "A"printf("%c\n", (char)(**addr));
Итак, в заключение, если вы все еще получаете значения не ASCII, это, вероятно, проблема с такой иерархией между адресами, и я бы порекомендовал вам строго отлаживать память и посмотреть, является ли создание указателя на указатель правильным путь к вашей строке.
Да, вам нужно разыменовать два указателя. Сначала нужно получить адрес переменной, содержащей char *, а затем разыменовать char *.