Изменение значения в памяти через SO в C - PullRequest
0 голосов
/ 27 октября 2009

Я пишу .SO, который вызывается другой программой, и я хочу иметь возможность перевернуть значение в памяти через функцию в .SO

То, что я имею до сих пор:

int 
axptrace( int numArguments, char* pMessageBuffer, int* pMessageBufferSize,
  char* pData[], int* pDataLength[] )  
{  
printf("Beginning dump attempt..\n");  
unsigned int* wkptr =(int*)0x7f793db70040;  
printf("At %llx, the value was %d\n\n",(long long)wkptr,*wkptr);  
if(*wkptr == 1){  
    printf("Switching the value.\n");  
    *wkptr = 0;  
    printf("At %llx, the value is now %d\n\n",(long long)wkptr,*wkptr);  
    printf("Switched!\n\n");   
}  
    printf("Ending dump attempt..\n");  
}

При запуске программы я получаю ожидаемые сообщения:

Начало попытки сброса ..
На 7f793db70040 значение было 1

Переключение значения.
На 7f793db70040 значение теперь равно 0

Switched!

Завершение попытки сброса ..

Начало попытки сброса ..

На 7f793db70040 значение было 0

Завершение попытки сброса ..

Если я снова запусту ту же функцию, вместо того, чтобы увидеть значение 0 в первой части, я снова увижу значение 1. Я думал, что это изменило значение в 0x7f793db70040, но, очевидно, оно вернулось к старому значению.

Кроме того, 0xf793db70040 был получен через отладчик. Есть ли способ увидеть, указывает ли «символ» или что-то подобное на этот адрес, и способ использовать это в моем коде?

Ответы [ 2 ]

4 голосов
/ 27 октября 2009

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

Теперь, учитывая высокое значение, это, вероятно, значение в стеке, что означает, что оно будет:

  1. Часто меняются
  2. Используется для нескольких целей
  3. Используется для одних и тех же целей по разным адресам

Если для адреса памяти был символ (не будет адресов в стеке или куче), и он был экспортирован (маловероятно для исполняемых файлов), его можно получить с помощью dlsym - если не экспортируется, и исполняемый файл не удален, вы могли бы иметь возможность анализировать заголовки ELF, чтобы найти его (это очень сложно. По сути, вы бы реализовали отладчик).

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

Редактировать: если вы хотите установить переменную отладки, есть два лучших варианта:

  1. Поместите отладочную переменную global в .so. Получите доступ к нему как обычно (то есть основное приложение имеет только extern int foo;, .so имеет действительное int foo;)
  2. сделать обратное; поместите переменную отладки global в exe, используйте extern int foo; в .so и (важно!) передать -Wl,-E в gcc или g++, чтобы связать исполняемый файл (это позволит исполняемый файл для экспорта символов в обратном порядке).
  3. Пусть исполняемый файл вызывает функцию из .so, передавая адрес переменной. .so может затем сохранить адрес где-нибудь, чтобы найти его позже. Эта опция не требует, чтобы переменная была глобальной.

Не использовать адрес, полученный от отладчика. Это может быть неправильный адрес, и даже если это правильный адрес, изменится , если вы что-нибудь перекомпилируете. Это может даже измениться между двумя запусками одних и тех же двоичных файлов в одной системе, благодаря ASLR . Вы просто не можете положиться на эту работу.

3 голосов
/ 27 октября 2009

Это так неправильно, что болит мои почки.

Не изменяйте жестко запрограммированные значения в памяти. Не разыменовывайте 0xf793db70040. Вы понятия не имеете, на что это указывает, и, безусловно, наиболее вероятным результатом изменения жестко закодированного указателя, подобного этому, будет огненный сбой. Если повезет. Если вам не повезло, вы испортите свою программу тонким способом, который вызовет сбой или потерю данных через несколько секунд, минут или часов.

Выясните, какое значение вы хотите изменить , и измените его напрямую через указатель данных. Ваше последнее предложение стремится к правильному пути: найдите «символ», которому соответствует это значение, и проверьте это значение.

Реальный вопрос в том, что вы пытаетесь сделать, и почему вы пробирались через отладчик, чтобы найти значение, которое вы хотите изменить?

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