Изменение значения в памяти через SO в C

Asked
Viewd126

-1

Я пишу .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

Переключено!

Завершение попытки дампа…

Начало попытки дампа…

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

Завершение попытки дампа…

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

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

  • Почему именно вы хотите это сделать?Использование постоянного адреса памяти таким образом неправильно на многих уровнях ... Чего вы пытаетесь достичь?

    viraptor26 октября 2009, 22:11
  • Известно ли вам, что в зависимости от вашей операционной системы один и тот же логический адрес может встречаться более одного раза?Почти все ОС выполняют отображение памяти, и та, которую вы используете, вероятно, тоже подойдет, по крайней мере, я не знаю 64-битную ОС без MM.Таким образом, у вас будет «7f793db70040» для каждого запускаемого вами процесса, и он, вероятно, всегда будет отображаться в другое место физической памяти.И если ваш процесс завершится, память будет переназначена, и ваши изменения исчезнут.

    Gunther Piez27 октября 2009, 10:00

2 ответов

3

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

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

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

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

  • @Antonio, в этом случае вы можете попробовать вызвать dlsym ().или просто объявив переменную extern и получив доступ к ней по имени, как и к любой другой переменной.

    asveikau27 октября 2009, 01:07
  • Это не произвольный указатель, я знаю, в какую структуру отображается это значение.Я не знаю, как читать, где это значение находится за пределами таблицы символов, думаю, это мой второй вопрос.У меня есть структура, которая начинается с этого адреса, и я хочу изменить первый байт на 1 во время выполнения.Я использовал отладчик, потому что не знаю, как найти, где находится эта переменная во время выполнения. Я знаю функцию, которая имеет этот параметр в подписи, поэтому я получил это значение, заглянув в запись активации этой функции изаписывая адрес.Жаль, что он меняется каждый раз.

    Antonio Pires26 октября 2009, 22:54
4

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

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

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

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

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

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

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

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

  • Адрес не произвольный, я обнаружил, что это указатель на мою структуру .. Но мне пришлось «очистить» память вручную с помощью отладчика.Я не верю, что это значение где-либо сбрасывается, но опять же, я не знаю кода, так что это вполне может быть проблемой.Нет ничего, кроме приложения, проталкивающего старое значение в этот адрес, IE glibc применяет какой-то тип «защиты» от изменения данных в стеке с помощью dlopen или чего-то подобного?Я пытаюсь перевернуть логическое значение, которое считывается, чтобы определить, должна ли отображаться внутренняя отладочная информация для приложения.

    Antonio Pires26 октября 2009, 22:59
  • Я добавил несколько конкретных предложений для вашего случая.

    bdonlan26 октября 2009, 23:11